From d3216b34e015a5463938d642c723730dbb1a1e05 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Mon, 26 Aug 2013 06:44:20 -0400 Subject: [PATCH 001/172] Datepicker: Initial commit of widget rewrite work from old branch. History is on the datepicker-dead branch. --- demos/datepicker/default.html | 5 + external/date.js | 197 +++ external/localization.js | 436 +++++ tests/unit/date/all.html | 30 + tests/unit/date/date.html | 40 + tests/unit/date/date_core.js | 223 +++ themes/base/jquery.ui.datepicker.css | 15 +- ui/jquery.ui.datepicker.js | 2459 ++++++-------------------- 8 files changed, 1441 insertions(+), 1964 deletions(-) create mode 100644 external/date.js create mode 100644 external/localization.js create mode 100644 tests/unit/date/all.html create mode 100644 tests/unit/date/date.html create mode 100644 tests/unit/date/date_core.js diff --git a/demos/datepicker/default.html b/demos/datepicker/default.html index 2d66a6ea2ad..a70b495371e 100644 --- a/demos/datepicker/default.html +++ b/demos/datepicker/default.html @@ -5,9 +5,14 @@ jQuery UI Datepicker - Default functionality + + + + + + + + + + + + + + + + +

jQuery UI Datepicker Test Suite

+

+
+

+
    +
    + +
    + + \ No newline at end of file diff --git a/tests/unit/date/date.html b/tests/unit/date/date.html new file mode 100644 index 00000000000..e3454a55b83 --- /dev/null +++ b/tests/unit/date/date.html @@ -0,0 +1,40 @@ + + + + + jQuery UI Date Test Suite + + + + + + + + + + + + + + +

    jQuery UI Date Test Suite

    +

    +
    +

    +
      +
      + +
      +

      + +
      + + \ No newline at end of file diff --git a/tests/unit/date/date_core.js b/tests/unit/date/date_core.js new file mode 100644 index 00000000000..f8f34abfc78 --- /dev/null +++ b/tests/unit/date/date_core.js @@ -0,0 +1,223 @@ + + +var PROP_NAME = 'date'; + + +module('date: core'); + +test('Check Date Setup', 2, function(){ + ok(true,'First Test Always Passes'); + ok($.date(), 'Load JQuery Date'); +}); +test('Check Sets and Gets', 6, function(){ + var date = $.date(); + equal(date.setYear(2012).year(), 2012, 'Set year and retrieve'); + equal(date.setMonth(9).month(), 9, 'Set month and retrieve'); + equal(date.setDay(15).day(), 15, 'Set day and retrieve'); + equal(date.setFullDate(2012,9,15).year(), 2012, 'Set full date and retrieve year'); + equal(date.month(), 9, 'Set full date and retrieve month'); + equal(date.day(), 15, 'Set full date and retrieve day'); +}); +test('Date Adjustments - Normal Use Cases', 10, function(){ + var date = $.date(); + //Use October 15, 2012 + date.setFullDate(2012,9,15); + equal(date.adjust('D',1).day(),16,'Add 1 day'); + equal(date.adjust('D',-1).day(),15,'Subtract 1 day'); + equal(date.adjust('M',1).month(),10,'Add 1 month'); + equal(date.adjust('M',-1).month(),9,'Subtract 1 month'); + equal(date.adjust('Y',1).year(),2013,'Add 1 year'); + equal(date.adjust('Y',-1).year(),2012,'Subtract 1 year'); + //Check changing one value impact another. Ex: Day impacts month + //Use April 30th 2012 + date.setFullDate(2012,3,30); + equal(date.adjust('D',1).month(),4,'Add 1 day to change month from April to May'); + equal(date.adjust('D',-1).month(),3,'Subtract 1 day to change month from May to April'); + //Use December 31st 2012 + date.setFullDate(2012,11,31); + equal(date.adjust('D',1).year(),2013,'Add 1 day to change year from 2012 to 2013'); + equal(date.adjust('D',-1).year(),2012,'Subtract 1 day to change month from 2013 to 2012'); + +}); + +test('Date Adjustments - Month Overflow Edge Cases', 2, function(){ + var date = $.date(); + //Use May 31 2012 + date.setFullDate(2012,4,31); + equal(date.adjust('M',1).day(),30,'Add 1 month from May to June sets days to 30, last day in June (prevent Overflow)'); + equal(date.adjust('M',-1).day(),30,'Subtract 1 month from June to May sets days to 30 in May'); +}); + +test('Date Adjustments - Leap Year Edge Cases', 1, function(){ + var date = $.date(); + //Use February 29 2012 a Leap year + date.setFullDate(2012,1,29); + equal(date.adjust('Y',1).day(),28,'Feb 29 2012, add a year to convert to Feb 28, 2013'); +}); + +test('List days of Week', 2, function(){ + var date = $.date(); + var offset0 = [ + { 'fullname': 'Sunday', 'shortname': 'Su' }, + { 'fullname': 'Monday', 'shortname': 'Mo' }, + { 'fullname': 'Tuesday', 'shortname': 'Tu' }, + { 'fullname': 'Wednesday', 'shortname': 'We' }, + { 'fullname': 'Thursday', 'shortname': 'Th' }, + { 'fullname': 'Friday', 'shortname': 'Fr' }, + { 'fullname': 'Saturday', 'shortname': 'Sa' } ]; + var offset1 = [ + { 'fullname': 'Montag', 'shortname': 'Mo' }, + { 'fullname': 'Dienstag', 'shortname': 'Di' }, + { 'fullname': 'Mittwoch', 'shortname': 'Mi' }, + { 'fullname': 'Donnerstag', 'shortname': 'Do' }, + { 'fullname': 'Freitag', 'shortname': 'Fr' }, + { 'fullname': 'Samstag', 'shortname': 'Sa' }, + { 'fullname': 'Sonntag', 'shortname': 'So' } ]; + deepEqual(date.weekdays(), offset0, 'Get weekdays with start of day on 0 (English)'); + Globalize.culture( 'de-DE' ); + date.refresh(); + deepEqual(date.weekdays(), offset1, 'Get weekdays with start of day on 1 (Germany)'); + //Revert Globalize changes back to English + Globalize.culture('en-EN'); +}); + +test('Leap Year Check', 8, function(){ + var date = $.date(); + ok(date.setYear( 2008 ).isLeapYear(), '2008 is a Leap Year'); + ok(!date.setYear( 2009 ).isLeapYear(), '2009 is not a Leap Year'); + ok(!date.setYear( 2010 ).isLeapYear(), '2010 is not a Leap Year'); + ok(!date.setYear( 2011 ).isLeapYear(), '2011 is not a Leap Year'); + ok(date.isLeapYear( 2012 ), '2012 is a Leap Year'); + ok(!date.isLeapYear( 2013 ), '2013 is not a Leap Year'); + ok(!date.isLeapYear( 2014 ), '2014 is not a Leap year'); + ok(!date.isLeapYear( 2015 ), '2015 is not a Leap year'); +}); + +test('Days in Month', 3, function(){ + var date = $.date(); + date.setFullDate( 2012, 1, 1 ); + equal(date.daysInMonth(), 29, 'Leap Year implicit check for 29 days'); + equal(date.daysInMonth( 2012, 1 ), 29, 'Leap Year explicit check for 29 days'); + equal(date.daysInMonth( 2011, 3 ), 30, 'April has 30 days'); +}); + +test('Month Name', 2, function(){ + var date = $.date(); + equal(date.setMonth(3).monthName(), 'April', 'Month name return April (English)'); + Globalize.culture( 'de-DE' ); + date.refresh(); + equal(date.setMonth(2).monthName(), 'März', 'Month name return March (German)'); + Globalize.culture('en-EN'); + +}); + +test('Clone', 2, function(){ + var date = $.date(); + var date2 = date.clone(); + ok(date2, 'Created cloned object'); + notEqual(date.adjust('Y',1).year(), date2.year(), 'Object manipulated independently'); +}); + +test('Days', 1, function(){ + //TODO needs work + var date = $.date(); + date.eachDay = function( day ) { + if ( day.lead && day.date > 20 ) { + day.selectable = false; + day.render = true; + day.title = "These are the days of last month"; + day.extraClasses = "ui-state-disabled"; + } + if ( day.lead && day.date < 3 ) { + day.selectable = true; + day.render = true; + day.extraClasses = "ui-state-disabled"; + } + if ( day.date == 1 ) { + day.extraClasses = "ui-state-error"; + day.title = "Something bad explaining the error highlight"; + } + if ( day.today ) { + day.title = "A good day!"; + } + }; + ok(date.days(), 'Date days() returns'); +}); + +test( "Months", 5, function(){ + var date = $.date(), + firstMonth = date.months( 1 )[ 0 ], + lastMonth = date.months( 1 )[ 1 ]; + + ok( firstMonth.first ); + ok( !lastMonth.first ); + ok( lastMonth.last ); + ok( !lastMonth.first ); + + ok( firstMonth.month() == ( lastMonth.month() - 1 ) ); +}); + +test('iso8601Week', 2, function(){ + var date = $.date(); + //date.setFullDate(2012, 0, 8); + equal(date.iso8601Week(new Date(2012, 0, 8)), 1, 'Test first week is 1'); + equal(date.iso8601Week(new Date(2012, 11, 31)), 1, 'Test last week is 1 in next year'); +}); + +test('Equal', 4, function(){ + var date = $.date(); + date.setFullDate(2012, 9, 16); + ok(date.equal(new Date(2012, 9, 16)), 'Does date equal provide date'); + ok(!date.equal(new Date(2011, 9, 16)), 'Does date year not equal provide date'); + ok(!date.equal(new Date(2012, 8, 16)), 'Does date month not equal provide date'); + ok(!date.equal(new Date(2012, 9, 15)), 'Does date day not equal provide date'); +}); + +test('Date', 1, function(){ + var date = $.date(); + ok(date.date() instanceof Date, 'Date returned'); +}); + +test('Format', 4, function(){ + var date = $.date(); + date.setFullDate(2012, 9, 16); + equal(date.format(), '10/16/2012', 'Checking default US format'); + equal(date.format('yyyy/MM/dd'), '2012/10/16', 'Checking yyyy/MM/dd format'); + equal(date.format('yy/dd/MM'), '12/16/10', 'Checking yy/dd/MM format'); + equal(date.format('MMMM dd, yyyy'), 'October 16, 2012', 'Checking MMMM dd, yyyy format'); +}); + +test('Calendar', 3, function(){ + var date = $.date(); + ok(date.calendar(), 'Calendar type returned') + var de_cal = {calendars: { + standard: { + "/": ".", + firstDay: 1, + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: null, + PM: null, + eras: [{"name":"n. Chr.","start":null,"offset":0}], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + t: "HH:mm", + T: "HH:mm:ss", + f: "dddd, d. MMMM yyyy HH:mm", + F: "dddd, d. MMMM yyyy HH:mm:ss", + M: "dd MMMM", + Y: "MMMM yyyy" + } + } + }}; + ok(date.calendar(de_cal), 'Calendar type changed'); + deepEqual(date.calendar(), de_cal, 'Calendar change verified'); +}); \ No newline at end of file diff --git a/themes/base/jquery.ui.datepicker.css b/themes/base/jquery.ui.datepicker.css index 9538bce8fc2..00c61cbc2db 100644 --- a/themes/base/jquery.ui.datepicker.css +++ b/themes/base/jquery.ui.datepicker.css @@ -21,8 +21,13 @@ .ui-datepicker .ui-datepicker-next { position: absolute; top: 2px; - width: 1.8em; - height: 1.8em; + width: 19px; + height: 18px; +} +.ui-datepicker .ui-datepicker-prev:not(.ui-state-hover):not(.ui-state-focus), +.ui-datepicker .ui-datepicker-next:not(.ui-state-hover):not(.ui-state-focus) { + background: none; + border: none; } .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { @@ -40,8 +45,8 @@ .ui-datepicker .ui-datepicker-next-hover { right: 1px; } -.ui-datepicker .ui-datepicker-prev span, -.ui-datepicker .ui-datepicker-next span { +.ui-datepicker .ui-datepicker-prev .ui-icon, +.ui-datepicker .ui-datepicker-next .ui-icon { display: block; position: absolute; left: 50%; @@ -172,4 +177,4 @@ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width: 0; border-left-width: 1px; -} +} \ No newline at end of file diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index b433cb79b31..6c3e013dc05 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -10,2051 +10,592 @@ * * Depends: * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.button.js + * jquery.ui.position.js */ (function( $, undefined ) { -$.extend($.ui, { datepicker: { version: "@VERSION" } }); - -var PROP_NAME = "datepicker", - instActive; - -function getZindex( elem ) { - var position, value; - while ( elem.length && elem[ 0 ] !== document ) { - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - //
      - value = parseInt( elem.css( "zIndex" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - - return 0; -} -/* Date picker manager. - Use the singleton instance of this class, $.datepicker, to interact with the date picker. - Settings for (groups of) date pickers are maintained in an instance object, - allowing multiple different settings on the same page. */ - -function Datepicker() { - this._curInst = null; // The current instance in use - this._keyEvent = false; // If the last event was a key event - this._disabledInputs = []; // List of date picker inputs that have been disabled - this._datepickerShowing = false; // True if the popup picker is showing , false if not - this._inDialog = false; // True if showing within a "dialog", false if not - this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division - this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class - this._appendClass = "ui-datepicker-append"; // The name of the append marker class - this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class - this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class - this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class - this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class - this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class - this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class - this.regional = []; // Available regional settings, indexed by language code - this.regional[""] = { // Default regional settings - closeText: "Done", // Display text for close link - prevText: "Prev", // Display text for previous month link - nextText: "Next", // Display text for next month link - currentText: "Today", // Display text for current month link - monthNames: ["January","February","March","April","May","June", - "July","August","September","October","November","December"], // Names of months for drop-down and formatting - monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting - dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting - dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting - dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday - weekHeader: "Wk", // Column header for week of the year - dateFormat: "mm/dd/yy", // See format options on parseDate - firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... - isRTL: false, // True if right-to-left language, false if left-to-right - showMonthAfterYear: false, // True if the year select precedes month, false for month then year - yearSuffix: "" // Additional text to append to the year in the month headers - }; - this._defaults = { // Global defaults for all the date picker instances - showOn: "focus", // "focus" for popup on focus, - // "button" for trigger button, or "both" for either - showAnim: "fadeIn", // Name of jQuery animation for popup - showOptions: {}, // Options for enhanced animations - defaultDate: null, // Used when field is blank: actual date, - // +/-number for offset from today, null for today - appendText: "", // Display text following the input box, e.g. showing the format - buttonText: "...", // Text for trigger button - buttonImage: "", // URL for trigger button image - buttonImageOnly: false, // True if the image appears alone, false if it appears on a button - hideIfNoPrevNext: false, // True to hide next/previous month links - // if not applicable, false to just disable them - navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links - gotoCurrent: false, // True if today link goes back to current selection instead - changeMonth: false, // True if month can be selected directly, false if only prev/next - changeYear: false, // True if year can be selected directly, false if only prev/next - yearRange: "c-10:c+10", // Range of years to display in drop-down, - // either relative to today's year (-nn:+nn), relative to currently displayed year - // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) - showOtherMonths: false, // True to show dates in other months, false to leave blank - selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable - showWeek: false, // True to show week of the year, false to not show it - calculateWeek: this.iso8601Week, // How to calculate the week of the year, - // takes a Date and returns the number of the week for it - shortYearCutoff: "+10", // Short year values < this are in the current century, - // > this are in the previous century, - // string value starting with "+" for current year + value - minDate: null, // The earliest selectable date, or null for no limit - maxDate: null, // The latest selectable date, or null for no limit - duration: "fast", // Duration of display/closure - beforeShowDay: null, // Function that takes a date and returns an array with - // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", - // [2] = cell title (optional), e.g. $.datepicker.noWeekends - beforeShow: null, // Function that takes an input field and - // returns a set of custom settings for the date picker - onSelect: null, // Define a callback function when a date is selected - onChangeMonthYear: null, // Define a callback function when the month or year is changed - onClose: null, // Define a callback function when the datepicker is closed - numberOfMonths: 1, // Number of months to show at a time - showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) - stepMonths: 1, // Number of months to step back/forward - stepBigMonths: 12, // Number of months to step back/forward for the big links - altField: "", // Selector for an alternate field to store selected dates into - altFormat: "", // The date format to use for the alternate field - constrainInput: true, // The input is constrained by the current date format - showButtonPanel: false, // True to show button panel, false to not show it - autoSize: false, // True to size the input for the date format, false to leave as is - disabled: false // The initial disabled state - }; - $.extend(this._defaults, this.regional[""]); - this.dpDiv = bindHover($("
      ")); -} - -$.extend(Datepicker.prototype, { - /* Class name added to elements to indicate already configured with a date picker. */ - markerClassName: "hasDatepicker", - - //Keep track of the maximum number of rows displayed (see #7043) - maxRows: 4, - - // TODO rename to "widget" when switching to widget factory - _widgetDatepicker: function() { - return this.dpDiv; - }, - - /* Override the default settings for all instances of the date picker. - * @param settings object - the new settings to use as defaults (anonymous object) - * @return the manager object - */ - setDefaults: function(settings) { - extendRemove(this._defaults, settings || {}); - return this; - }, - - /* Attach the date picker to a jQuery selection. - * @param target element - the target input field or division or span - * @param settings object - the new settings to use for this date picker instance (anonymous) - */ - _attachDatepicker: function(target, settings) { - var nodeName, inline, inst; - nodeName = target.nodeName.toLowerCase(); - inline = (nodeName === "div" || nodeName === "span"); - if (!target.id) { - this.uuid += 1; - target.id = "dp" + this.uuid; - } - inst = this._newInst($(target), inline); - inst.settings = $.extend({}, settings || {}); - if (nodeName === "input") { - this._connectDatepicker(target, inst); - } else if (inline) { - this._inlineDatepicker(target, inst); - } - }, - - /* Create a new instance object. */ - _newInst: function(target, inline) { - var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars - return {id: id, input: target, // associated target - selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection - drawMonth: 0, drawYear: 0, // month being drawn - inline: inline, // is datepicker inline or not - dpDiv: (!inline ? this.dpDiv : // presentation div - bindHover($("
      ")))}; - }, - - /* Attach the date picker to an input field. */ - _connectDatepicker: function(target, inst) { - var input = $(target); - inst.append = $([]); - inst.trigger = $([]); - if (input.hasClass(this.markerClassName)) { - return; - } - this._attachments(input, inst); - input.addClass(this.markerClassName).keydown(this._doKeyDown). - keypress(this._doKeyPress).keyup(this._doKeyUp); - this._autoSize(inst); - $.data(target, PROP_NAME, inst); - //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) - if( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - }, - - /* Make attachments based on settings. */ - _attachments: function(input, inst) { - var showOn, buttonText, buttonImage, - appendText = this._get(inst, "appendText"), - isRTL = this._get(inst, "isRTL"); - - if (inst.append) { - inst.append.remove(); - } - if (appendText) { - inst.append = $("" + appendText + ""); - input[isRTL ? "before" : "after"](inst.append); - } - - input.unbind("focus", this._showDatepicker); - - if (inst.trigger) { - inst.trigger.remove(); - } - - showOn = this._get(inst, "showOn"); - if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field - input.focus(this._showDatepicker); - } - if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked - buttonText = this._get(inst, "buttonText"); - buttonImage = this._get(inst, "buttonImage"); - inst.trigger = $(this._get(inst, "buttonImageOnly") ? - $("").addClass(this._triggerClass). - attr({ src: buttonImage, alt: buttonText, title: buttonText }) : - $("").addClass(this._triggerClass). - html(!buttonImage ? buttonText : $("").attr( - { src:buttonImage, alt:buttonText, title:buttonText }))); - input[isRTL ? "before" : "after"](inst.trigger); - inst.trigger.click(function() { - if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { - $.datepicker._hideDatepicker(); - } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { - $.datepicker._hideDatepicker(); - $.datepicker._showDatepicker(input[0]); - } else { - $.datepicker._showDatepicker(input[0]); +// TODO use uniqueId, if possible +var idIncrement = 0, + // TODO move this to the instance + suppressExpandOnFocus = false; + +$.widget( "ui.datepicker", { + options: { + appendTo: null, + // TODO review + eachDay: $.noop, + numberOfMonths: 1, + position: { + my: "left top", + at: "left bottom" + }, + showWeek: false, + show: true, + hide: true, + + // callbacks + close: null, + open: null, + select: null + }, + _create: function() { + var that = this; + this.date = $.date(); + this.date.eachDay = this.options.eachDay; + this.id = "ui-datepicker-" + idIncrement; + idIncrement++; + if ( this.element.is( "input" ) ) { + this._createPicker(); + } else { + this.inline = true; + this.picker = this.element; + } + this._on( this.picker, { + "click .ui-datepicker-prev": function( event ) { + event.preventDefault(); + this.date.adjust( "M", -this.options.numberOfMonths ); + this.refresh(); + }, + "click .ui-datepicker-next": function( event ) { + event.preventDefault(); + this.date.adjust( "M", this.options.numberOfMonths ); + this.refresh(); + }, + "click .ui-datepicker-current": function( event ) { + event.preventDefault(); + this.select( event, new Date().getTime() ); + }, + "click .ui-datepicker-close": function( event ) { + event.preventDefault(); + this.close( event ); + }, + "mousedown .ui-datepicker-calendar a": function( event ) { + event.preventDefault(); + // TODO exclude clicks on lead days or handle them correctly + // TODO store/read more then just date, also required for multi month picker + this.select( event, $( event.currentTarget ).data( "timestamp" ) ); + if ( this.inline ) { + this.grid.focus( 1 ); } - return false; - }); - } - }, - - /* Apply the maximum length for the date format. */ - _autoSize: function(inst) { - if (this._get(inst, "autoSize") && !inst.inline) { - var findMax, max, maxI, i, - date = new Date(2009, 12 - 1, 20), // Ensure double digits - dateFormat = this._get(inst, "dateFormat"); - - if (dateFormat.match(/[DM]/)) { - findMax = function(names) { - max = 0; - maxI = 0; - for (i = 0; i < names.length; i++) { - if (names[i].length > max) { - max = names[i].length; - maxI = i; - } - } - return maxI; - }; - date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? - "monthNames" : "monthNamesShort")))); - date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? - "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); - } - inst.input.attr("size", this._formatDate(inst, date).length); - } - }, - - /* Attach an inline date picker to a div. */ - _inlineDatepicker: function(target, inst) { - var divSpan = $(target); - if (divSpan.hasClass(this.markerClassName)) { - return; - } - divSpan.addClass(this.markerClassName).append(inst.dpDiv); - $.data(target, PROP_NAME, inst); - this._setDate(inst, this._getDefaultDate(inst), true); - this._updateDatepicker(inst); - this._updateAlternate(inst); - //If disabled option is true, disable the datepicker before showing it (see ticket #5665) - if( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements - // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height - inst.dpDiv.css( "display", "block" ); - }, - - /* Pop-up the date picker in a "dialog" box. - * @param input element - ignored - * @param date string or Date - the initial date to display - * @param onSelect function - the function to call when a date is selected - * @param settings object - update the dialog date picker instance's settings (anonymous object) - * @param pos int[2] - coordinates for the dialog's position within the screen or - * event - with x/y coordinates or - * leave empty for default (screen centre) - * @return the manager object - */ - _dialogDatepicker: function(input, date, onSelect, settings, pos) { - var id, browserWidth, browserHeight, scrollX, scrollY, - inst = this._dialogInst; // internal instance - - if (!inst) { - this.uuid += 1; - id = "dp" + this.uuid; - this._dialogInput = $(""); - this._dialogInput.keydown(this._doKeyDown); - $("body").append(this._dialogInput); - inst = this._dialogInst = this._newInst(this._dialogInput, false); - inst.settings = {}; - $.data(this._dialogInput[0], PROP_NAME, inst); - } - extendRemove(inst.settings, settings || {}); - date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); - this._dialogInput.val(date); - - this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); - if (!this._pos) { - browserWidth = document.documentElement.clientWidth; - browserHeight = document.documentElement.clientHeight; - scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; - scrollY = document.documentElement.scrollTop || document.body.scrollTop; - this._pos = // should use actual width/height below - [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; - } - - // move input on screen for focus, but hidden behind dialog - this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); - inst.settings.onSelect = onSelect; - this._inDialog = true; - this.dpDiv.addClass(this._dialogClass); - this._showDatepicker(this._dialogInput[0]); - if ($.blockUI) { - $.blockUI(this.dpDiv); - } - $.data(this._dialogInput[0], PROP_NAME, inst); - return this; - }, - - /* Detach a datepicker from its control. - * @param target element - the target input field or division or span - */ - _destroyDatepicker: function(target) { - var nodeName, - $target = $(target), - inst = $.data(target, PROP_NAME); - - if (!$target.hasClass(this.markerClassName)) { - return; - } - - nodeName = target.nodeName.toLowerCase(); - $.removeData(target, PROP_NAME); - if (nodeName === "input") { - inst.append.remove(); - inst.trigger.remove(); - $target.removeClass(this.markerClassName). - unbind("focus", this._showDatepicker). - unbind("keydown", this._doKeyDown). - unbind("keypress", this._doKeyPress). - unbind("keyup", this._doKeyUp); - } else if (nodeName === "div" || nodeName === "span") { - $target.removeClass(this.markerClassName).empty(); - } - }, - - /* Enable the date picker to a jQuery selection. - * @param target element - the target input field or division or span - */ - _enableDatepicker: function(target) { - var nodeName, inline, - $target = $(target), - inst = $.data(target, PROP_NAME); + }, + "keydown .ui-datepicker-calendar": "_handleKeydown" + }); - if (!$target.hasClass(this.markerClassName)) { - return; - } + // TODO use hoverable (no delegation support)? convert to _on? + this.picker.delegate( ".ui-datepicker-header a, .ui-datepicker-calendar a", "mouseenter.datepicker mouseleave.datepicker", function() { + $( this ).toggleClass( "ui-state-hover" ); + }); - nodeName = target.nodeName.toLowerCase(); - if (nodeName === "input") { - target.disabled = false; - inst.trigger.filter("button"). - each(function() { this.disabled = false; }).end(). - filter("img").css({opacity: "1.0", cursor: ""}); - } else if (nodeName === "div" || nodeName === "span") { - inline = $target.children("." + this._inlineClass); - inline.children().removeClass("ui-state-disabled"); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - prop("disabled", false); - } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value === target ? null : value); }); // delete entry + this._createTmpl(); }, - - /* Disable the date picker to a jQuery selection. - * @param target element - the target input field or division or span - */ - _disableDatepicker: function(target) { - var nodeName, inline, - $target = $(target), - inst = $.data(target, PROP_NAME); - - if (!$target.hasClass(this.markerClassName)) { + _handleKeydown: function( event ) { + if ( jQuery.inArray( event.keyCode, [ 13, 33, 34, 35, 36, 37, 38, 39, 40 ] ) === -1 ) { + //only interested navigation keys return; } - - nodeName = target.nodeName.toLowerCase(); - if (nodeName === "input") { - target.disabled = true; - inst.trigger.filter("button"). - each(function() { this.disabled = true; }).end(). - filter("img").css({opacity: "0.5", cursor: "default"}); - } else if (nodeName === "div" || nodeName === "span") { - inline = $target.children("." + this._inlineClass); - inline.children().addClass("ui-state-disabled"); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - prop("disabled", true); - } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value === target ? null : value); }); // delete entry - this._disabledInputs[this._disabledInputs.length] = target; - }, - - /* Is the first field in a jQuery collection disabled as a datepicker? - * @param target element - the target input field or division or span - * @return boolean - true if disabled, false if enabled - */ - _isDisabledDatepicker: function(target) { - if (!target) { - return false; - } - for (var i = 0; i < this._disabledInputs.length; i++) { - if (this._disabledInputs[i] === target) { - return true; + event.preventDefault(); + + var activeCell = $( "#" + this.grid.attr( "aria-activedescendant" ) ), + oldMonth = this.date.month(), + oldYear = this.date.year(); + + // TODO: Handle for pickers with multiple months + switch ( event.keyCode ) { + case $.ui.keyCode.ENTER: + activeCell.children( "a:first" ).mousedown(); + return; + case $.ui.keyCode.PAGE_UP: + this.date.adjust( event.altKey ? "Y" : "M", 1 ); + break; + case $.ui.keyCode.PAGE_DOWN: + this.date.adjust( event.altKey ? "Y" : "M", -1 ); + break; + case $.ui.keyCode.END: + this.date.setDay( this.date.daysInMonth() ); + break; + case $.ui.keyCode.HOME: + this.date.setDay( 1 ); + break; + case $.ui.keyCode.LEFT: + this.date.adjust( "D", -1 ); + break; + case $.ui.keyCode.UP: + this.date.adjust( "D", -7 ); + break; + case $.ui.keyCode.RIGHT: + this.date.adjust( "D", 1 ); + break; + case $.ui.keyCode.DOWN: + this.date.adjust( "D", 7 ); + break; + default: + return; + } + + if ( this.date.month() != oldMonth || this.date.year() != oldYear ) { + this.refresh(); + this.grid.focus( 1 ); + } + else { + var newId = this.id + "-" + this.date.day(), + newCell = $("#" + newId); + + // TODO unnecessary optimization? is it really needed? + if ( !newCell.length ) { + return; } - } - return false; - }, - - /* Retrieve the instance data for the target control. - * @param target element - the target input field or division or span - * @return object - the associated instance data - * @throws error if a jQuery problem getting data - */ - _getInst: function(target) { - try { - return $.data(target, PROP_NAME); - } - catch (err) { - throw "Missing instance data for this datepicker"; - } - }, - - /* Update or retrieve the settings for a date picker attached to an input field or division. - * @param target element - the target input field or division or span - * @param name object - the new settings to update or - * string - the name of the setting to change or retrieve, - * when retrieving also "all" for all instance settings or - * "defaults" for all global defaults - * @param value any - the new value for the setting - * (omit if above is an object or to retrieve a value) - */ - _optionDatepicker: function(target, name, value) { - var settings, date, minDate, maxDate, - inst = this._getInst(target); - - if (arguments.length === 2 && typeof name === "string") { - return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : - (inst ? (name === "all" ? $.extend({}, inst.settings) : - this._get(inst, name)) : null)); - } - - settings = name || {}; - if (typeof name === "string") { - settings = {}; - settings[name] = value; - } - - if (inst) { - if (this._curInst === inst) { - this._hideDatepicker(); - } - - date = this._getDateDatepicker(target, true); - minDate = this._getMinMaxDate(inst, "min"); - maxDate = this._getMinMaxDate(inst, "max"); - extendRemove(inst.settings, settings); - // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided - if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { - inst.settings.minDate = this._formatDate(inst, minDate); - } - if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { - inst.settings.maxDate = this._formatDate(inst, maxDate); - } - if ( "disabled" in settings ) { - if ( settings.disabled ) { - this._disableDatepicker(target); - } else { - this._enableDatepicker(target); - } - } - this._attachments($(target), inst); - this._autoSize(inst); - this._setDate(inst, date); - this._updateAlternate(inst); - this._updateDatepicker(inst); - } - }, - - // change method deprecated - _changeDatepicker: function(target, name, value) { - this._optionDatepicker(target, name, value); - }, - - /* Redraw the date picker attached to an input field or division. - * @param target element - the target input field or division or span - */ - _refreshDatepicker: function(target) { - var inst = this._getInst(target); - if (inst) { - this._updateDatepicker(inst); - } - }, - - /* Set the dates for a jQuery selection. - * @param target element - the target input field or division or span - * @param date Date - the new date - */ - _setDateDatepicker: function(target, date) { - var inst = this._getInst(target); - if (inst) { - this._setDate(inst, date); - this._updateDatepicker(inst); - this._updateAlternate(inst); - } - }, - - /* Get the date(s) for the first entry in a jQuery selection. - * @param target element - the target input field or division or span - * @param noDefault boolean - true if no default date is to be used - * @return Date - the current date - */ - _getDateDatepicker: function(target, noDefault) { - var inst = this._getInst(target); - if (inst && !inst.inline) { - this._setDateFromField(inst, noDefault); - } - return (inst ? this._getDate(inst) : null); - }, - - /* Handle keystrokes. */ - _doKeyDown: function(event) { - var onSelect, dateStr, sel, - inst = $.datepicker._getInst(event.target), - handled = true, - isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); - - inst._keyEvent = true; - if ($.datepicker._datepickerShowing) { - switch (event.keyCode) { - case 9: $.datepicker._hideDatepicker(); - handled = false; - break; // hide on tab out - case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + - $.datepicker._currentClass + ")", inst.dpDiv); - if (sel[0]) { - $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); - } - - onSelect = $.datepicker._get(inst, "onSelect"); - if (onSelect) { - dateStr = $.datepicker._formatDate(inst); - - // trigger custom callback - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); - } else { - $.datepicker._hideDatepicker(); - } - - return false; // don't submit the form - case 27: $.datepicker._hideDatepicker(); - break; // hide on escape - case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, "stepBigMonths") : - -$.datepicker._get(inst, "stepMonths")), "M"); - break; // previous month/year on page up/+ ctrl - case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, "stepBigMonths") : - +$.datepicker._get(inst, "stepMonths")), "M"); - break; // next month/year on page down/+ ctrl - case 35: if (event.ctrlKey || event.metaKey) { - $.datepicker._clearDate(event.target); - } - handled = event.ctrlKey || event.metaKey; - break; // clear on ctrl or command +end - case 36: if (event.ctrlKey || event.metaKey) { - $.datepicker._gotoToday(event.target); - } - handled = event.ctrlKey || event.metaKey; - break; // current on ctrl or command +home - case 37: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); - } - handled = event.ctrlKey || event.metaKey; - // -1 day on ctrl or command +left - if (event.originalEvent.altKey) { - $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, "stepBigMonths") : - -$.datepicker._get(inst, "stepMonths")), "M"); - } - // next month/year on alt +left on Mac + this.grid.attr("aria-activedescendant", newId); + + activeCell.children("a").removeClass("ui-state-focus"); + newCell.children("a").addClass("ui-state-focus"); + } + }, + _createPicker: function() { + this.picker = $( "
      " ) + .addClass( "ui-front" ) + // TODO add a ui-datepicker-popup class, move position:absolte to that + .css( "position", "absolute" ) + .uniqueId() + .hide(); + this._setHiddenPicker(); + this.picker.appendTo( this._appendTo() ) + + this.element + .attr( "aria-haspopup", "true" ) + .attr( "aria-owns", this.picker.attr( "id" ) ); + + this._on({ + keydown: function( event ) { + switch ( event.keyCode ) { + case $.ui.keyCode.TAB: + // Waiting for close() will make popup hide too late, which breaks tab key behavior + this.picker.hide(); + this.close( event ); break; - case 38: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, -7, "D"); + case $.ui.keyCode.ESCAPE: + if ( this.isOpen ) { + this.close( event ); } - handled = event.ctrlKey || event.metaKey; - break; // -1 week on ctrl or command +up - case 39: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); - } - handled = event.ctrlKey || event.metaKey; - // +1 day on ctrl or command +right - if (event.originalEvent.altKey) { - $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, "stepBigMonths") : - +$.datepicker._get(inst, "stepMonths")), "M"); - } - // next month/year on alt +right break; - case 40: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, +7, "D"); + case $.ui.keyCode.DOWN: + case $.ui.keyCode.UP: + clearTimeout( this.closeTimer ); + this._delay(function() { + this.open( event ); + this.grid.focus( 1 ); + }, 1); + break; + } + }, + mousedown: function( event ) { + if (this.isOpen) { + suppressExpandOnFocus = true; + this.close(); + return; + } + this.open( event ); + clearTimeout( this.closeTimer ); + }, + focus: function( event ) { + if ( !suppressExpandOnFocus ) { + this._delay( function() { + if ( !this.isOpen ) { + this.open( event ); } - handled = event.ctrlKey || event.metaKey; - break; // +1 week on ctrl or command +down - default: handled = false; - } - } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home - $.datepicker._showDatepicker(this); - } else { - handled = false; - } - - if (handled) { - event.preventDefault(); - event.stopPropagation(); - } - }, - - /* Filter entered characters - based on date format. */ - _doKeyPress: function(event) { - var chars, chr, - inst = $.datepicker._getInst(event.target); - - if ($.datepicker._get(inst, "constrainInput")) { - chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); - chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); - return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); - } - }, - - /* Synchronise manual entry and field/alternate field. */ - _doKeyUp: function(event) { - var date, - inst = $.datepicker._getInst(event.target); - - if (inst.input.val() !== inst.lastVal) { - try { - date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), - (inst.input ? inst.input.val() : null), - $.datepicker._getFormatConfig(inst)); - - if (date) { // only if valid - $.datepicker._setDateFromField(inst); - $.datepicker._updateAlternate(inst); - $.datepicker._updateDatepicker(inst); + }, 1); } + this._delay( function() { + suppressExpandOnFocus = false; + }, 100); + }, + blur: function( event ) { + suppressExpandOnFocus = false; } - catch (err) { - } - } - return true; - }, - - /* Pop-up the date picker for a given input field. - * If false returned from beforeShow event handler do not show. - * @param input element - the input field attached to the date picker or - * event - if triggered by focus - */ - _showDatepicker: function(input) { - input = input.target || input; - if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger - input = $("input", input.parentNode)[0]; - } - - if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here - return; - } - - var inst, beforeShow, beforeShowSettings, isFixed, - offset, showAnim, duration; - - inst = $.datepicker._getInst(input); - if ($.datepicker._curInst && $.datepicker._curInst !== inst) { - $.datepicker._curInst.dpDiv.stop(true, true); - if ( inst && $.datepicker._datepickerShowing ) { - $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); - } - } - - beforeShow = $.datepicker._get(inst, "beforeShow"); - beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; - if(beforeShowSettings === false){ - return; - } - extendRemove(inst.settings, beforeShowSettings); - - inst.lastVal = null; - $.datepicker._lastInput = input; - $.datepicker._setDateFromField(inst); - - if ($.datepicker._inDialog) { // hide cursor - input.value = ""; - } - if (!$.datepicker._pos) { // position below input - $.datepicker._pos = $.datepicker._findPos(input); - $.datepicker._pos[1] += input.offsetHeight; // add the height - } - - isFixed = false; - $(input).parents().each(function() { - isFixed |= $(this).css("position") === "fixed"; - return !isFixed; }); - offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; - $.datepicker._pos = null; - //to avoid flashes on Firefox - inst.dpDiv.empty(); - // determine sizing offscreen - inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); - $.datepicker._updateDatepicker(inst); - // fix width for dynamic number of date pickers - // and adjust position before showing - offset = $.datepicker._checkOffset(inst, offset, isFixed); - inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? - "static" : (isFixed ? "fixed" : "absolute")), display: "none", - left: offset.left + "px", top: offset.top + "px"}); - - if (!inst.inline) { - showAnim = $.datepicker._get(inst, "showAnim"); - duration = $.datepicker._get(inst, "duration"); - inst.dpDiv.css( "z-index", getZindex( $( input ) ) + 1 ); - $.datepicker._datepickerShowing = true; - - if ( $.effects && $.effects.effect[ showAnim ] ) { - inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); - } else { - inst.dpDiv[showAnim || "show"](showAnim ? duration : null); - } - - if ( $.datepicker._shouldFocusInput( inst ) ) { - inst.input.focus(); - } - - $.datepicker._curInst = inst; - } - }, - - /* Generate the date picker content. */ - _updateDatepicker: function(inst) { - this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) - instActive = inst; // for delegate hover events - inst.dpDiv.empty().append(this._generateHTML(inst)); - this._attachHandlers(inst); - inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); - - var origyearshtml, - numMonths = this._getNumberOfMonths(inst), - cols = numMonths[1], - width = 17; - - inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); - if (cols > 1) { - inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); - } - inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + - "Class"]("ui-datepicker-multi"); - inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + - "Class"]("ui-datepicker-rtl"); - - if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { - inst.input.focus(); - } - - // deffered render of the years select (to avoid flashes on Firefox) - if( inst.yearshtml ){ - origyearshtml = inst.yearshtml; - setTimeout(function(){ - //assure that inst.yearshtml didn't change. - if( origyearshtml === inst.yearshtml && inst.yearshtml ){ - inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); + this._on( this.picker, { + focusout: function( event ) { + // use a timer to allow click to clear it and letting that + // handle the closing instead of opening again + // also allows tabbing inside the calendar without it closing + this.closeTimer = this._delay( function() { + this.close( event ); + }, 150); + }, + focusin: function( event ) { + clearTimeout( this.closeTimer ); + }, + mouseup: function( event ) { + clearTimeout( this.closeTimer ); + }, + // TODO on TAB (or shift TAB), make sure it ends up on something useful in DOM order + keyup: function( event ) { + if ( event.keyCode === $.ui.keyCode.ESCAPE && this.picker.is( ":visible" ) ) { + this.close( event ); + this._focusTrigger(); } - origyearshtml = inst.yearshtml = null; - }, 0); - } - }, - - // #6694 - don't focus the input if it's already focused - // this breaks the change event in IE - // Support: IE and jQuery <1.9 - _shouldFocusInput: function( inst ) { - return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); - }, - - /* Check positioning to remain on screen. */ - _checkOffset: function(inst, offset, isFixed) { - var dpWidth = inst.dpDiv.outerWidth(), - dpHeight = inst.dpDiv.outerHeight(), - inputWidth = inst.input ? inst.input.outerWidth() : 0, - inputHeight = inst.input ? inst.input.outerHeight() : 0, - viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), - viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); - - offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); - offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; - offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; - - // now check if datepicker is showing outside window viewport - move to a better place if so. - offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? - Math.abs(offset.left + dpWidth - viewWidth) : 0); - offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? - Math.abs(dpHeight + inputHeight) : 0); - - return offset; - }, - - /* Find an object's position on the screen. */ - _findPos: function(obj) { - var position, - inst = this._getInst(obj), - isRTL = this._get(inst, "isRTL"); - - while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { - obj = obj[isRTL ? "previousSibling" : "nextSibling"]; - } - - position = $(obj).offset(); - return [position.left, position.top]; - }, - - /* Hide the date picker from view. - * @param input element - the input field attached to the date picker - */ - _hideDatepicker: function(input) { - var showAnim, duration, postProcess, onClose, - inst = this._curInst; - - if (!inst || (input && inst !== $.data(input, PROP_NAME))) { - return; - } - - if (this._datepickerShowing) { - showAnim = this._get(inst, "showAnim"); - duration = this._get(inst, "duration"); - postProcess = function() { - $.datepicker._tidyDialog(inst); - }; - - // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed - if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { - inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); - } else { - inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : - (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); - } - - if (!showAnim) { - postProcess(); - } - this._datepickerShowing = false; - - onClose = this._get(inst, "onClose"); - if (onClose) { - onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); } + }); - this._lastInput = null; - if (this._inDialog) { - this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); - if ($.blockUI) { - $.unblockUI(); - $("body").append(this.dpDiv); + this._on( this.document, { + click: function( event ) { + if ( this.isOpen && !$( event.target ).closest( this.element.add( this.picker ) ).length ) { + this.close( event ); } } - this._inDialog = false; - } - }, - - /* Tidy up after a dialog display. */ - _tidyDialog: function(inst) { - inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); + }); }, + _appendTo: function() { + var element = this.options.appendTo; - /* Close date picker if clicked elsewhere. */ - _checkExternalClick: function(event) { - if (!$.datepicker._curInst) { - return; - } - - var $target = $(event.target), - inst = $.datepicker._getInst($target[0]); - - if ( ( ( $target[0].id !== $.datepicker._mainDivId && - $target.parents("#" + $.datepicker._mainDivId).length === 0 && - !$target.hasClass($.datepicker.markerClassName) && - !$target.closest("." + $.datepicker._triggerClass).length && - $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || - ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { - $.datepicker._hideDatepicker(); + if ( element ) { + element = element.jquery || element.nodeType ? + $( element ) : + this.document.find( element ).eq( 0 ); } - }, - /* Adjust one of the date sub-fields. */ - _adjustDate: function(id, offset, period) { - var target = $(id), - inst = this._getInst(target[0]); - - if (this._isDisabledDatepicker(target[0])) { - return; + if ( !element ) { + element = this.element.closest( ".ui-front" ); } - this._adjustInstDate(inst, offset + - (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning - period); - this._updateDatepicker(inst); - }, - - /* Action for current link. */ - _gotoToday: function(id) { - var date, - target = $(id), - inst = this._getInst(target[0]); - if (this._get(inst, "gotoCurrent") && inst.currentDay) { - inst.selectedDay = inst.currentDay; - inst.drawMonth = inst.selectedMonth = inst.currentMonth; - inst.drawYear = inst.selectedYear = inst.currentYear; - } else { - date = new Date(); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); + if ( !element.length ) { + element = this.document[0].body; } - this._notifyChange(inst); - this._adjustDate(target); - }, - - /* Action for selecting a new month/year. */ - _selectMonthYear: function(id, select, period) { - var target = $(id), - inst = this._getInst(target[0]); - inst["selected" + (period === "M" ? "Month" : "Year")] = - inst["draw" + (period === "M" ? "Month" : "Year")] = - parseInt(select.options[select.selectedIndex].value,10); - - this._notifyChange(inst); - this._adjustDate(target); + return element; }, + _createTmpl: function() { + this.date.refresh(); - /* Action for selecting a day. */ - _selectDay: function(id, month, year, td) { - var inst, - target = $(id); + this._createDatepicker(); + this.picker.find( "button" ).button(); - if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { - return; + if ( this.inline ) { + this.picker.children().addClass( "ui-datepicker-inline" ); } - - inst = this._getInst(target[0]); - inst.selectedDay = inst.currentDay = $("a", td).html(); - inst.selectedMonth = inst.currentMonth = month; - inst.selectedYear = inst.currentYear = year; - this._selectDate(id, this._formatDate(inst, - inst.currentDay, inst.currentMonth, inst.currentYear)); + // against display:none in datepicker.css + this.picker.find( ".ui-datepicker" ).css( "display", "block" ); + this.grid = this.picker.find( ".ui-datepicker-calendar" ); }, + _createDatepicker: function() { + var multiClasses = [], + pickerHtml = ""; - /* Erase the input field and hide the date picker. */ - _clearDate: function(id) { - var target = $(id); - this._selectDate(target, ""); - }, - - /* Update the input field with the selected date. */ - _selectDate: function(id, dateStr) { - var onSelect, - target = $(id), - inst = this._getInst(target[0]); - - dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); - if (inst.input) { - inst.input.val(dateStr); - } - this._updateAlternate(inst); - - onSelect = this._get(inst, "onSelect"); - if (onSelect) { - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback - } else if (inst.input) { - inst.input.trigger("change"); // fire the change event - } - - if (inst.inline){ - this._updateDatepicker(inst); + if (this.options.numberOfMonths === 1 ) { + pickerHtml = this._buildHeader() + this._buildGrid() + this._buildButtons(); } else { - this._hideDatepicker(); - this._lastInput = inst.input[0]; - if (typeof(inst.input[0]) !== "object") { - inst.input.focus(); // restore focus + pickerHtml = this._buildMultiplePicker(); + multiClasses.push( "ui-datepicker-multi" ); + multiClasses.push( "ui-datepicker-multi-" + this.options.numberOfMonths ); + } + + $( "
      " ) + .addClass( "ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" ) + .addClass( multiClasses.join( " " ) ) + .attr({ + role: "region", + "aria-labelledby": this.id + "-title" + }) + .html( pickerHtml ) + .appendTo( this.picker ); + }, + _buildMultiplePicker: function() { + var headerClass, + html = "", + currentDate = this.date, + months = this.date.months( this.options.numberOfMonths - 1 ), + i = 0; + + for ( i; i < months.length; i++ ) { + this.date = months[ i ]; + headerClass = months[ i ].first ? "ui-corner-left" : + months[ i ].last ? "ui-corner-right" : ""; + + html += "
      " + + "
      "; + if ( months[i].first ) { + html += this._buildPreviousLink(); + } + if ( months[i].last ) { + html += this._buildNextLink(); } - this._lastInput = null; - } - }, - - /* Update any alternate field to synchronise with the main field. */ - _updateAlternate: function(inst) { - var altFormat, date, dateStr, - altField = this._get(inst, "altField"); - if (altField) { // update alternate field too - altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); - date = this._getDate(inst); - dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); - $(altField).each(function() { $(this).val(dateStr); }); + html += this._buildTitlebar(); + html += "
      "; + html += this._buildGrid(); + html += "
      "; } - }, - - /* Set as beforeShowDay function to prevent selection of weekends. - * @param date Date - the date to customise - * @return [boolean, string] - is this date selectable?, what is its CSS class? - */ - noWeekends: function(date) { - var day = date.getDay(); - return [(day > 0 && day < 6), ""]; - }, - - /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. - * @param date Date - the date to get the week for - * @return number - the number of the week within the year that contains this date - */ - iso8601Week: function(date) { - var time, - checkDate = new Date(date.getTime()); - // Find Thursday of this week starting on Monday - checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); + html += "
      "; + html += this._buildButtons(); - time = checkDate.getTime(); - checkDate.setMonth(0); // Compare with Jan 1 - checkDate.setDate(1); - return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; + this.date = currentDate; + return html; }, - - /* Parse a string value into a date object. - * See formatDate below for the possible formats. - * - * @param format string - the expected format of the date - * @param value string - the date in the above format - * @param settings Object - attributes include: - * shortYearCutoff number - the cutoff year for determining the century (optional) - * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - * dayNames string[7] - names of the days from Sunday (optional) - * monthNamesShort string[12] - abbreviated names of the months (optional) - * monthNames string[12] - names of the months (optional) - * @return Date - the extracted date value or null if value is blank - */ - parseDate: function (format, value, settings) { - if (format == null || value == null) { - throw "Invalid arguments"; - } - - value = (typeof value === "object" ? value.toString() : value + ""); - if (value === "") { - return null; - } - - var iFormat, dim, extra, - iValue = 0, - shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, - shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : - new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), - dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, - dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, - monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, - monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, - year = -1, - month = -1, - day = -1, - doy = -1, - literal = false, - date, - // Check whether a format character is doubled - lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); - if (matches) { - iFormat++; - } - return matches; - }, - // Extract a number from the string value - getNumber = function(match) { - var isDoubled = lookAhead(match), - size = (match === "@" ? 14 : (match === "!" ? 20 : - (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), - digits = new RegExp("^\\d{1," + size + "}"), - num = value.substring(iValue).match(digits); - if (!num) { - throw "Missing number at position " + iValue; - } - iValue += num[0].length; - return parseInt(num[0], 10); - }, - // Extract a name from the string value and convert to an index - getName = function(match, shortNames, longNames) { - var index = -1, - names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { - return [ [k, v] ]; - }).sort(function (a, b) { - return -(a[1].length - b[1].length); - }); - - $.each(names, function (i, pair) { - var name = pair[1]; - if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { - index = pair[0]; - iValue += name.length; - return false; - } - }); - if (index !== -1) { - return index + 1; - } else { - throw "Unknown name at position " + iValue; - } - }, - // Confirm that a literal character matches the string value - checkLiteral = function() { - if (value.charAt(iValue) !== format.charAt(iFormat)) { - throw "Unexpected literal at position " + iValue; - } - iValue++; - }; - - for (iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) { - if (format.charAt(iFormat) === "'" && !lookAhead("'")) { - literal = false; - } else { - checkLiteral(); - } + _buildHeader: function() { + return "
      " + + this._buildPreviousLink() + + this._buildNextLink() + + this._buildTitlebar() + + "
      "; + }, + _buildPreviousLink: function() { + var labels = Globalize.localize( "datepicker" ); + return ""; + }, + _buildNextLink: function() { + var labels = Globalize.localize( "datepicker" ); + return ""; + }, + _buildTitlebar: function() { + var labels = Globalize.localize( "datepicker" ); + return "
      " + + "
      " + + this._buildTitle() + + "
      " + + ", " + labels.datePickerRole + "" + + "
      "; + }, + _buildTitle: function() { + return "" + + this.date.monthName() + + " " + + "" + + this.date.year() + + ""; + }, + _buildGrid: function() { + return "" + + this._buildGridHeading() + + this._buildGridBody() + + "
      "; + }, + _buildGridHeading: function() { + var cells = "", + i = 0, + labels = Globalize.localize( "datepicker" ); + + if ( this.options.showWeek ) { + cells += "" + labels.weekHeader + ""; + } + for ( i; i < this.date.weekdays().length; i++ ) { + cells += this._buildGridHeaderCell( this.date.weekdays()[i] ); + } + return "" + + "" + cells + "" + + ""; + }, + _buildGridHeaderCell: function( day ) { + return "" + + "" + + day.shortname + + "" + + ""; + }, + _buildGridBody: function() { + var rows = "", + i = 0; + for ( i; i < this.date.days().length; i++ ) { + rows += this._buildWeekRow( this.date.days()[i] ); + } + return "" + rows + ""; + }, + _buildWeekRow: function( week ) { + var cells = "", + i = 0; + + if ( this.options.showWeek ) { + cells += "" + week.number + ""; + } + for ( i; i < week.days.length; i++ ) { + cells += this._buildDayCell( week.days[i] ); + } + return "" + cells + ""; + }, + _buildDayCell: function( day ) { + var contents = ""; + idAttribute = day.render ? ( "id=" + this.id + "-" + day.date ) : "", + ariaSelectedAttribute = "aria-selected=" + ( day.current ? "true" : "false" ), + ariaDisabledAttribute = day.selectable ? "" : "aria-disabled=true"; + + if ( day.render ) { + if ( day.selectable ) { + contents = this._buildDayLink( day ); } else { - switch (format.charAt(iFormat)) { - case "d": - day = getNumber("d"); - break; - case "D": - getName("D", dayNamesShort, dayNames); - break; - case "o": - doy = getNumber("o"); - break; - case "m": - month = getNumber("m"); - break; - case "M": - month = getName("M", monthNamesShort, monthNames); - break; - case "y": - year = getNumber("y"); - break; - case "@": - date = new Date(getNumber("@")); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "!": - date = new Date((getNumber("!") - this._ticksTo1970) / 10000); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "'": - if (lookAhead("'")){ - checkLiteral(); - } else { - literal = true; - } - break; - default: - checkLiteral(); - } + contents = this._buildDayDisplay( day ); } } - if (iValue < value.length){ - extra = value.substr(iValue); - if (!/^\s+/.test(extra)) { - throw "Extra/unparsed characters found in date: " + extra; - } - } + return "" + + contents + + ""; + }, + _buildDayLink: function( day ) { + var link, + classes = [ "ui-state-default" ], + labels = Globalize.localize( "datepicker" ); - if (year === -1) { - year = new Date().getFullYear(); - } else if (year < 100) { - year += new Date().getFullYear() - new Date().getFullYear() % 100 + - (year <= shortYearCutoff ? 0 : -100); + if ( day.date == this.date.day() ) { + classes.push( "ui-state-focus" ) } - - if (doy > -1) { - month = 1; - day = doy; - do { - dim = this._getDaysInMonth(year, month - 1); - if (day <= dim) { - break; - } - month++; - day -= dim; - } while (true); + if ( day.current ) { + classes.push( "ui-state-active" ); } - - date = this._daylightSavingAdjust(new Date(year, month - 1, day)); - if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { - throw "Invalid date"; // E.g. 31/02/00 + if ( day.today ) { + classes.push( "ui-state-highlight" ); } - return date; - }, - - /* Standard date formats. */ - ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) - 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", // RFC 822 - TICKS: "!", - TIMESTAMP: "@", - W3C: "yy-mm-dd", // ISO 8601 - - _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + - Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), - - /* Format a date object into a string value. - * The format can be combinations of the following: - * d - day of month (no leading zero) - * dd - day of month (two digit) - * o - day of year (no leading zeros) - * oo - day of year (three digit) - * D - day name short - * DD - day name long - * m - month of year (no leading zero) - * mm - month of year (two digit) - * M - month name short - * MM - month name long - * y - year (two digit) - * yy - year (four digit) - * @ - Unix timestamp (ms since 01/01/1970) - * ! - Windows ticks (100ns since 01/01/0001) - * "..." - literal text - * '' - single quote - * - * @param format string - the desired format of the date - * @param date Date - the date value to format - * @param settings Object - attributes include: - * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - * dayNames string[7] - names of the days from Sunday (optional) - * monthNamesShort string[12] - abbreviated names of the months (optional) - * monthNames string[12] - names of the months (optional) - * @return string - the date in the above format - */ - formatDate: function (format, date, settings) { - if (!date) { - return ""; + if ( day.extraClasses ) { + classes.push( day.extraClasses.split( "" ) ); } - var iFormat, - dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, - dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, - monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, - monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, - // Check whether a format character is doubled - lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); - if (matches) { - iFormat++; - } - return matches; - }, - // Format a number, with leading zero if necessary - formatNumber = function(match, value, len) { - var num = "" + value; - if (lookAhead(match)) { - while (num.length < len) { - num = "0" + num; - } - } - return num; - }, - // Format a name, short or long as requested - formatName = function(match, value, shortNames, longNames) { - return (lookAhead(match) ? longNames[value] : shortNames[value]); - }, - output = "", - literal = false; - - if (date) { - for (iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) { - if (format.charAt(iFormat) === "'" && !lookAhead("'")) { - literal = false; - } else { - output += format.charAt(iFormat); - } - } else { - switch (format.charAt(iFormat)) { - case "d": - output += formatNumber("d", date.getDate(), 2); - break; - case "D": - output += formatName("D", date.getDay(), dayNamesShort, dayNames); - break; - case "o": - output += formatNumber("o", - Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); - break; - case "m": - output += formatNumber("m", date.getMonth() + 1, 2); - break; - case "M": - output += formatName("M", date.getMonth(), monthNamesShort, monthNames); - break; - case "y": - output += (lookAhead("y") ? date.getFullYear() : - (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); - break; - case "@": - output += date.getTime(); - break; - case "!": - output += date.getTime() * 10000 + this._ticksTo1970; - break; - case "'": - if (lookAhead("'")) { - output += "'"; - } else { - literal = true; - } - break; - default: - output += format.charAt(iFormat); - } - } - } + link = "" + + day.date + ""; + if ( day.today ) { + link += ", " + labels.currentText + ""; } - return output; + return link; }, - - /* Extract all possible characters from the date format. */ - _possibleChars: function (format) { - var iFormat, - chars = "", - literal = false, - // Check whether a format character is doubled - lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); - if (matches) { - iFormat++; - } - return matches; - }; - - for (iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) { - if (format.charAt(iFormat) === "'" && !lookAhead("'")) { - literal = false; - } else { - chars += format.charAt(iFormat); - } - } else { - switch (format.charAt(iFormat)) { - case "d": case "m": case "y": case "@": - chars += "0123456789"; - break; - case "D": case "M": - return null; // Accept anything - case "'": - if (lookAhead("'")) { - chars += "'"; - } else { - literal = true; - } - break; - default: - chars += format.charAt(iFormat); - } - } + _buildDayDisplay: function( day ) { + var classes = []; + if ( day.current ) { + classes.push( "ui-state-active" ); } - return chars; - }, - - /* Get a setting value, defaulting if necessary. */ - _get: function(inst, name) { - return inst.settings[name] !== undefined ? - inst.settings[name] : this._defaults[name]; - }, - - /* Parse existing date and initialise date picker. */ - _setDateFromField: function(inst, noDefault) { - if (inst.input.val() === inst.lastVal) { - return; + if ( day.today ) { + classes.push( "ui-state-highlight" ); } - - var dateFormat = this._get(inst, "dateFormat"), - dates = inst.lastVal = inst.input ? inst.input.val() : null, - defaultDate = this._getDefaultDate(inst), - date = defaultDate, - settings = this._getFormatConfig(inst); - - try { - date = this.parseDate(dateFormat, dates, settings) || defaultDate; - } catch (event) { - dates = (noDefault ? "" : dates); + if ( day.extraClasses ) { + classes.push( day.extraClasses.split( "" ) ); } - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - inst.currentDay = (dates ? date.getDate() : 0); - inst.currentMonth = (dates ? date.getMonth() : 0); - inst.currentYear = (dates ? date.getFullYear() : 0); - this._adjustInstDate(inst); - }, - /* Retrieve the default date shown on opening. */ - _getDefaultDate: function(inst) { - return this._restrictMinMax(inst, - this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); + return "" + + day.date + ""; }, - - /* A date may be specified as an exact value or a relative one. */ - _determineDate: function(inst, date, defaultDate) { - var offsetNumeric = function(offset) { - var date = new Date(); - date.setDate(date.getDate() + offset); - return date; - }, - offsetString = function(offset) { - try { - return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), - offset, $.datepicker._getFormatConfig(inst)); - } - catch (e) { - // Ignore - } - - var date = (offset.toLowerCase().match(/^c/) ? - $.datepicker._getDate(inst) : null) || new Date(), - year = date.getFullYear(), - month = date.getMonth(), - day = date.getDate(), - pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, - matches = pattern.exec(offset); - - while (matches) { - switch (matches[2] || "d") { - case "d" : case "D" : - day += parseInt(matches[1],10); break; - case "w" : case "W" : - day += parseInt(matches[1],10) * 7; break; - case "m" : case "M" : - month += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); - break; - case "y": case "Y" : - year += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); - break; - } - matches = pattern.exec(offset); - } - return new Date(year, month, day); - }, - newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : - (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); - - newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); - if (newDate) { - newDate.setHours(0); - newDate.setMinutes(0); - newDate.setSeconds(0); - newDate.setMilliseconds(0); - } - return this._daylightSavingAdjust(newDate); + _buildButtons: function() { + var labels = Globalize.localize( "datepicker" ); + return "
      " + + "" + + "" + + "
      "; }, - - /* Handle switch to/from daylight saving. - * Hours may be non-zero on daylight saving cut-over: - * > 12 when midnight changeover, but then cannot generate - * midnight datetime, so jump to 1AM, otherwise reset. - * @param date (Date) the date to check - * @return (Date) the corrected date - */ - _daylightSavingAdjust: function(date) { - if (!date) { - return null; - } - date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); - return date; + _focusTrigger: function( event ) { + suppressExpandOnFocus = true; + this.element.focus(); }, + // Refreshing the entire datepicker during interaction confuses screen readers, specifically + // because the grid heading is marked up as a live region and will often not update if it's + // destroyed and recreated instead of just having its text change. Additionally, interacting + // with the prev and next links would cause loss of focus issues because the links being + // interacted with will disappear while focused. + refresh: function() { + //determine which day gridcell to focus after refresh + //TODO: Prevent disabled cells from being focused + this.date.refresh(); - /* Set the date(s) directly. */ - _setDate: function(inst, date, noChange) { - var clear = !date, - origMonth = inst.selectedMonth, - origYear = inst.selectedYear, - newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); - - inst.selectedDay = inst.currentDay = newDate.getDate(); - inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); - inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); - if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { - this._notifyChange(inst); - } - this._adjustInstDate(inst); - if (inst.input) { - inst.input.val(clear ? "" : this._formatDate(inst)); + if ( this.options.numberOfMonths === 1 ) { + this.grid = $( this._buildGrid() ); + $( ".ui-datepicker-title", this.picker ).html( this._buildTitle() ); + $( ".ui-datepicker-calendar", this.picker ).replaceWith( this.grid ); + } else { + this._refreshMultiplePicker(); } }, + _refreshMultiplePicker: function() { + var currentDate = this.date, + i = 0; - /* Retrieve the date(s) directly. */ - _getDate: function(inst) { - var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : - this._daylightSavingAdjust(new Date( - inst.currentYear, inst.currentMonth, inst.currentDay))); - return startDate; - }, - - /* Attach the onxxx handlers. These are declared statically so - * they work with static code transformers like Caja. - */ - _attachHandlers: function(inst) { - var stepMonths = this._get(inst, "stepMonths"), - id = "#" + inst.id.replace( /\\\\/g, "\\" ); - inst.dpDiv.find("[data-handler]").map(function () { - var handler = { - prev: function () { - $.datepicker._adjustDate(id, -stepMonths, "M"); - }, - next: function () { - $.datepicker._adjustDate(id, +stepMonths, "M"); - }, - hide: function () { - $.datepicker._hideDatepicker(); - }, - today: function () { - $.datepicker._gotoToday(id); - }, - selectDay: function () { - $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); - return false; - }, - selectMonth: function () { - $.datepicker._selectMonthYear(id, this, "M"); - return false; - }, - selectYear: function () { - $.datepicker._selectMonthYear(id, this, "Y"); - return false; - } - }; - $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); - }); - }, - - /* Generate the HTML for the current state of the date picker. */ - _generateHTML: function(inst) { - var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, - controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, - monthNames, monthNamesShort, beforeShowDay, showOtherMonths, - selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, - cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, - printDate, dRow, tbody, daySettings, otherMonth, unselectable, - tempDate = new Date(), - today = this._daylightSavingAdjust( - new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time - isRTL = this._get(inst, "isRTL"), - showButtonPanel = this._get(inst, "showButtonPanel"), - hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), - navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), - numMonths = this._getNumberOfMonths(inst), - showCurrentAtPos = this._get(inst, "showCurrentAtPos"), - stepMonths = this._get(inst, "stepMonths"), - isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), - currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : - new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), - minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - drawMonth = inst.drawMonth - showCurrentAtPos, - drawYear = inst.drawYear; - - if (drawMonth < 0) { - drawMonth += 12; - drawYear--; - } - if (maxDate) { - maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), - maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); - maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); - while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { - drawMonth--; - if (drawMonth < 0) { - drawMonth = 11; - drawYear--; - } - } + for ( ; i < this.options.numberOfMonths; i++ ) { + $( ".ui-datepicker-title", this.picker ).eq( i ).html( this._buildTitle() ); + $( ".ui-datepicker-calendar", this.picker ).eq( i ).html( this._buildGrid() ); + this.date.adjust( "M", 1 ); } - inst.drawMonth = drawMonth; - inst.drawYear = drawYear; - - prevText = this._get(inst, "prevText"); - prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), - this._getFormatConfig(inst))); - - prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? - "" + prevText + "" : - (hideIfNoPrevNext ? "" : "" + prevText + "")); - - nextText = this._get(inst, "nextText"); - nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), - this._getFormatConfig(inst))); - - next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? - "" + nextText + "" : - (hideIfNoPrevNext ? "" : "" + nextText + "")); - - currentText = this._get(inst, "currentText"); - gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); - currentText = (!navigationAsDateFormat ? currentText : - this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); - - controls = (!inst.inline ? "" : ""); - - buttonPanel = (showButtonPanel) ? "
      " + (isRTL ? controls : "") + - (this._isInRange(inst, gotoDate) ? "" : "") + (isRTL ? "" : controls) + "
      " : ""; - - firstDay = parseInt(this._get(inst, "firstDay"),10); - firstDay = (isNaN(firstDay) ? 0 : firstDay); - - showWeek = this._get(inst, "showWeek"); - dayNames = this._get(inst, "dayNames"); - dayNamesMin = this._get(inst, "dayNamesMin"); - monthNames = this._get(inst, "monthNames"); - monthNamesShort = this._get(inst, "monthNamesShort"); - beforeShowDay = this._get(inst, "beforeShowDay"); - showOtherMonths = this._get(inst, "showOtherMonths"); - selectOtherMonths = this._get(inst, "selectOtherMonths"); - defaultDate = this._getDefaultDate(inst); - html = ""; - dow; - for (row = 0; row < numMonths[0]; row++) { - group = ""; - this.maxRows = 4; - for (col = 0; col < numMonths[1]; col++) { - selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); - cornerClass = " ui-corner-all"; - calender = ""; - if (isMultiMonth) { - calender += "
      "; - } - calender += "
      " + - (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + - (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + - this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, - row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers - "
      " + - ""; - thead = (showWeek ? "" : ""); - for (dow = 0; dow < 7; dow++) { // days of the week - day = (dow + firstDay) % 7; - thead += "= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + - "" + dayNamesMin[day] + ""; - } - calender += thead + ""; - daysInMonth = this._getDaysInMonth(drawYear, drawMonth); - if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { - inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); - } - leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; - curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate - numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) - this.maxRows = numRows; - printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); - for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows - calender += ""; - tbody = (!showWeek ? "" : ""); - for (dow = 0; dow < 7; dow++) { // create date picker days - daySettings = (beforeShowDay ? - beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); - otherMonth = (printDate.getMonth() !== drawMonth); - unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || - (minDate && printDate < minDate) || (maxDate && printDate > maxDate); - tbody += ""; // display selectable date - printDate.setDate(printDate.getDate() + 1); - printDate = this._daylightSavingAdjust(printDate); - } - calender += tbody + ""; - } - drawMonth++; - if (drawMonth > 11) { - drawMonth = 0; - drawYear++; - } - calender += "
      " + this._get(inst, "weekHeader") + "
      " + - this._get(inst, "calculateWeek")(printDate) + "" + // actions - (otherMonth && !showOtherMonths ? " " : // display for other months - (unselectable ? "" + printDate.getDate() + "" : "" + printDate.getDate() + "")) + "
      " + (isMultiMonth ? "
      " + - ((numMonths[0] > 0 && col === numMonths[1]-1) ? "
      " : "") : ""); - group += calender; - } - html += group; - } - html += buttonPanel; - inst._keyEvent = false; - return html; + this.date.adjust( "M", -this.options.numberOfMonths ); }, - - /* Generate the month and year header. */ - _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort) { - - var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, - changeMonth = this._get(inst, "changeMonth"), - changeYear = this._get(inst, "changeYear"), - showMonthAfterYear = this._get(inst, "showMonthAfterYear"), - html = "
      ", - monthHtml = ""; - - // month selection - if (secondary || !changeMonth) { - monthHtml += "" + monthNames[drawMonth] + ""; - } else { - inMinYear = (minDate && minDate.getFullYear() === drawYear); - inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); - monthHtml += ""; + open: function( event ) { + if ( this.inline || this.isOpen ) { + return; } - if (!showMonthAfterYear) { - html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); - } + // TODO explain this + this.date = $.date( this.element.val() ); + this.date.eachDay = this.options.eachDay; + this.date.select(); + this.refresh(); - // year selection - if ( !inst.yearshtml ) { - inst.yearshtml = ""; - if (secondary || !changeYear) { - html += "" + drawYear + ""; - } else { - // determine range of years to display - years = this._get(inst, "yearRange").split(":"); - thisYear = new Date().getFullYear(); - determineYear = function(value) { - var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : - (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : - parseInt(value, 10))); - return (isNaN(year) ? thisYear : year); - }; - year = determineYear(years[0]); - endYear = Math.max(year, determineYear(years[1] || "")); - year = (minDate ? Math.max(year, minDate.getFullYear()) : year); - endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); - inst.yearshtml += ""; + var position = $.extend( {}, { + of: this.element + }, this.options.position ); - html += inst.yearshtml; - inst.yearshtml = null; - } - } + this.picker + .attr( "aria-hidden", "false" ) + .attr( "aria-expanded", "true" ) + .show() + .position( position ) + .hide(); - html += this._get(inst, "yearSuffix"); - if (showMonthAfterYear) { - html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; - } - html += "
      "; // Close datepicker_header - return html; - }, + this._show( this.picker, this.options.show ); - /* Adjust one of the date sub-fields. */ - _adjustInstDate: function(inst, offset, period) { - var year = inst.drawYear + (period === "Y" ? offset : 0), - month = inst.drawMonth + (period === "M" ? offset : 0), - day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), - date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); + // take trigger out of tab order to allow shift-tab to skip trigger + // TODO does this really make sense? related bug: tab-shift moves focus to last element on page + this.element.attr( "tabindex", -1 ); + this.isOpen = true; - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - if (period === "M" || period === "Y") { - this._notifyChange(inst); - } + this._trigger( "open", event ); }, - - /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function(inst, date) { - var minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - newDate = (minDate && date < minDate ? minDate : date); - return (maxDate && newDate > maxDate ? maxDate : newDate); - }, - - /* Notify change of month/year. */ - _notifyChange: function(inst) { - var onChange = this._get(inst, "onChangeMonthYear"); - if (onChange) { - onChange.apply((inst.input ? inst.input[0] : null), - [inst.selectedYear, inst.selectedMonth + 1, inst]); + close: function( event ) { + if ( this.inline ) { + return; } - }, - /* Determine the number of months to show. */ - _getNumberOfMonths: function(inst) { - var numMonths = this._get(inst, "numberOfMonths"); - return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); - }, + this._setHiddenPicker(); + this._hide( this.picker, this.options.hide ); - /* Determine the current maximum date - ensure no time components are set. */ - _getMinMaxDate: function(inst, minMax) { - return this._determineDate(inst, this._get(inst, minMax + "Date"), null); - }, + this.element.attr( "tabindex" , 0 ); - /* Find the number of days in a given month. */ - _getDaysInMonth: function(year, month) { - return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); + this.isOpen = false; + this._trigger( "close", event ); }, - - /* Find the day of the week of the first of a month. */ - _getFirstDayOfMonth: function(year, month) { - return new Date(year, month, 1).getDay(); + _setHiddenPicker: function() { + this.picker + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); }, - - /* Determines if we should allow a "next/prev" month display change. */ - _canAdjustMonth: function(inst, offset, curYear, curMonth) { - var numMonths = this._getNumberOfMonths(inst), - date = this._daylightSavingAdjust(new Date(curYear, - curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); - - if (offset < 0) { - date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); + select: function( event, time ) { + this.date.setTime( time ).select(); + this.refresh(); + if ( !this.inline ) { + this.element.val( this.date.format() ); + this.close(); + this._focusTrigger(); } - return this._isInRange(inst, date); - }, - - /* Is the given date in the accepted range? */ - _isInRange: function(inst, date) { - var yearSplit, currentYear, - minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - minYear = null, - maxYear = null, - years = this._get(inst, "yearRange"); - if (years){ - yearSplit = years.split(":"); - currentYear = new Date().getFullYear(); - minYear = parseInt(yearSplit[0], 10); - maxYear = parseInt(yearSplit[1], 10); - if ( yearSplit[0].match(/[+\-].*/) ) { - minYear += currentYear; - } - if ( yearSplit[1].match(/[+\-].*/) ) { - maxYear += currentYear; - } - } - - return ((!minDate || date.getTime() >= minDate.getTime()) && - (!maxDate || date.getTime() <= maxDate.getTime()) && - (!minYear || date.getFullYear() >= minYear) && - (!maxYear || date.getFullYear() <= maxYear)); - }, - - /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function(inst) { - var shortYearCutoff = this._get(inst, "shortYearCutoff"); - shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - return {shortYearCutoff: shortYearCutoff, - dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), - monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; + this._trigger( "select", event, { + // TODO replace with value option to initialise and read + date: this.date.format() + }); }, - - /* Format the given date for display. */ - _formatDate: function(inst, day, month, year) { - if (!day) { - inst.currentDay = inst.selectedDay; - inst.currentMonth = inst.selectedMonth; - inst.currentYear = inst.selectedYear; + _destroy: function() { + if ( !this.inline ) { + this.picker.remove(); + this.element + .removeAttr( "aria-haspopup" ) + .removeAttr( "aria-owns" ); } - var date = (day ? (typeof day === "object" ? day : - this._daylightSavingAdjust(new Date(year, month, day))) : - this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); + }, + widget: function() { + return this.picker; } }); -/* - * Bind hover events for datepicker elements. - * Done via delegate so the binding only occurs once in the lifetime of the parent div. - * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. - */ -function bindHover(dpDiv) { - var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; - return dpDiv.delegate(selector, "mouseout", function() { - $(this).removeClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).removeClass("ui-datepicker-prev-hover"); - } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).removeClass("ui-datepicker-next-hover"); - } - }) - .delegate(selector, "mouseover", function(){ - if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { - $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); - $(this).addClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).addClass("ui-datepicker-prev-hover"); - } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).addClass("ui-datepicker-next-hover"); - } - } - }); -} - -/* jQuery extend now ignores nulls! */ -function extendRemove(target, props) { - $.extend(target, props); - for (var name in props) { - if (props[name] == null) { - target[name] = props[name]; - } - } - return target; -} - -/* Invoke the datepicker functionality. - @param options string - a command, optionally followed by additional parameters or - Object - settings for attaching new datepicker functionality - @return jQuery object */ -$.fn.datepicker = function(options){ - - /* Verify an empty collection wasn't passed - Fixes #6976 */ - if ( !this.length ) { - return this; - } - - /* Initialise the date picker. */ - if (!$.datepicker.initialized) { - $(document).mousedown($.datepicker._checkExternalClick); - $.datepicker.initialized = true; - } - - /* Append datepicker main container to body if not exist. */ - if ($("#"+$.datepicker._mainDivId).length === 0) { - $("body").append($.datepicker.dpDiv); - } - - var otherArgs = Array.prototype.slice.call(arguments, 1); - if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); - } - if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); - } - return this.each(function() { - typeof options === "string" ? - $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this].concat(otherArgs)) : - $.datepicker._attachDatepicker(this, options); - }); -}; - -$.datepicker = new Datepicker(); // singleton instance -$.datepicker.initialized = false; -$.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "@VERSION"; - -})(jQuery); +}( jQuery )); From b85057304867d6766d7946e51fcfae1a929b5c65 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 30 Aug 2013 08:27:19 -0400 Subject: [PATCH 002/172] Datepicker: Get datepicker's test suite to at least run. It fails horribly, but at least it loads with its dependencies. --- tests/unit/datepicker/datepicker.html | 9 ++++++++- tests/unit/datepicker/datepicker_core.js | 10 ---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 8ef2de5a4c6..162748b7ef3 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -5,6 +5,9 @@ jQuery UI Datepicker Test Suite + + + @@ -14,10 +17,14 @@ css: [ "ui.core", "ui.datepicker" ], js: [ "ui/jquery.ui.core.js", + "ui/jquery.ui.widget.js", + "ui/jquery.ui.button.js", "ui/jquery.ui.datepicker.js", + "ui/jquery.ui.position.js" + /* TODO: Replace with Globalize cultures "ui/i18n/jquery.ui.datepicker-fr.js", "ui/i18n/jquery.ui.datepicker-he.js", - "ui/i18n/jquery.ui.datepicker-zh-CN.js" + "ui/i18n/jquery.ui.datepicker-zh-CN.js"*/ ] }); diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 0bc5723ec8c..2312e482e27 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -8,16 +8,6 @@ module("datepicker: core"); TestHelpers.testJshint( "datepicker" ); -test("initialization - Reinitialization after body had been emptied.", function() { - expect( 1 ); - var bodyContent = $("body").children(), inp = $("#inp"); - $("#inp").datepicker(); - $("body").empty().append(inp); - $("#inp").datepicker(); - ok( $("#"+$.datepicker._mainDivId).length===1, "Datepicker container added" ); - $("body").empty().append(bodyContent); // Returning to initial state for later tests -}); - test( "widget method - empty collection", function() { expect( 1 ); $( "#nonExist" ).datepicker(); // should create nothing From bf19f755fe1da66a07df1c515a3df09ee7473d31 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 30 Aug 2013 08:31:33 -0400 Subject: [PATCH 003/172] Datepicker: Updating/fixing the animation demo. --- demos/datepicker/animation.html | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/demos/datepicker/animation.html b/demos/datepicker/animation.html index da8193e53e3..a8020ed32b8 100644 --- a/demos/datepicker/animation.html +++ b/demos/datepicker/animation.html @@ -5,6 +5,9 @@ jQuery UI Datepicker - Animations + + + @@ -14,13 +17,17 @@ + + @@ -40,7 +47,7 @@ - +

      From 632aa2b5c9bff7a257411e293de8d0d619887acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rn=20Zaefferer?= Date: Wed, 11 Sep 2013 16:40:53 +0200 Subject: [PATCH 004/172] Datepicker: Fix the build. Exclude broken datepicker units from running with phantomjs. Fix various jshint warnings in date_core tests and datepicker src --- Gruntfile.js | 2 +- tests/unit/date/date_core.js | 259 +++++++++++++++++------------------ ui/jquery.ui.datepicker.js | 33 +++-- 3 files changed, 146 insertions(+), 148 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index b35a4514d20..a5ced942df2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -204,7 +204,7 @@ grunt.initConfig({ files: expandFiles( "tests/unit/**/*.html" ).filter(function( file ) { // disabling everything that doesn't (quite) work with PhantomJS for now // TODO except for all|index|test, try to include more as we go - return !( /(all|index|test|dialog|tooltip)\.html$/ ).test( file ); + return !( /(all|index|test|dialog|datepicker|tooltip)\.html$/ ).test( file ); }) }, jshint: { diff --git a/tests/unit/date/date_core.js b/tests/unit/date/date_core.js index f8f34abfc78..b75ef8087eb 100644 --- a/tests/unit/date/date_core.js +++ b/tests/unit/date/date_core.js @@ -1,124 +1,121 @@ +module("date: core"); - -var PROP_NAME = 'date'; - - -module('date: core'); - -test('Check Date Setup', 2, function(){ - ok(true,'First Test Always Passes'); - ok($.date(), 'Load JQuery Date'); +test("Check Date Setup", 2, function(){ + ok(true,"First Test Always Passes"); + ok($.date(), "Load JQuery Date"); }); -test('Check Sets and Gets', 6, function(){ +test("Check Sets and Gets", 6, function(){ var date = $.date(); - equal(date.setYear(2012).year(), 2012, 'Set year and retrieve'); - equal(date.setMonth(9).month(), 9, 'Set month and retrieve'); - equal(date.setDay(15).day(), 15, 'Set day and retrieve'); - equal(date.setFullDate(2012,9,15).year(), 2012, 'Set full date and retrieve year'); - equal(date.month(), 9, 'Set full date and retrieve month'); - equal(date.day(), 15, 'Set full date and retrieve day'); -}); -test('Date Adjustments - Normal Use Cases', 10, function(){ + equal(date.setYear(2012).year(), 2012, "Set year and retrieve"); + equal(date.setMonth(9).month(), 9, "Set month and retrieve"); + equal(date.setDay(15).day(), 15, "Set day and retrieve"); + equal(date.setFullDate(2012,9,15).year(), 2012, "Set full date and retrieve year"); + equal(date.month(), 9, "Set full date and retrieve month"); + equal(date.day(), 15, "Set full date and retrieve day"); +}); +test("Date Adjustments - Normal Use Cases", 10, function(){ var date = $.date(); //Use October 15, 2012 date.setFullDate(2012,9,15); - equal(date.adjust('D',1).day(),16,'Add 1 day'); - equal(date.adjust('D',-1).day(),15,'Subtract 1 day'); - equal(date.adjust('M',1).month(),10,'Add 1 month'); - equal(date.adjust('M',-1).month(),9,'Subtract 1 month'); - equal(date.adjust('Y',1).year(),2013,'Add 1 year'); - equal(date.adjust('Y',-1).year(),2012,'Subtract 1 year'); + equal(date.adjust("D",1).day(),16,"Add 1 day"); + equal(date.adjust("D",-1).day(),15,"Subtract 1 day"); + equal(date.adjust("M",1).month(),10,"Add 1 month"); + equal(date.adjust("M",-1).month(),9,"Subtract 1 month"); + equal(date.adjust("Y",1).year(),2013,"Add 1 year"); + equal(date.adjust("Y",-1).year(),2012,"Subtract 1 year"); //Check changing one value impact another. Ex: Day impacts month //Use April 30th 2012 date.setFullDate(2012,3,30); - equal(date.adjust('D',1).month(),4,'Add 1 day to change month from April to May'); - equal(date.adjust('D',-1).month(),3,'Subtract 1 day to change month from May to April'); + equal(date.adjust("D",1).month(),4,"Add 1 day to change month from April to May"); + equal(date.adjust("D",-1).month(),3,"Subtract 1 day to change month from May to April"); //Use December 31st 2012 date.setFullDate(2012,11,31); - equal(date.adjust('D',1).year(),2013,'Add 1 day to change year from 2012 to 2013'); - equal(date.adjust('D',-1).year(),2012,'Subtract 1 day to change month from 2013 to 2012'); + equal(date.adjust("D",1).year(),2013,"Add 1 day to change year from 2012 to 2013"); + equal(date.adjust("D",-1).year(),2012,"Subtract 1 day to change month from 2013 to 2012"); }); -test('Date Adjustments - Month Overflow Edge Cases', 2, function(){ +test("Date Adjustments - Month Overflow Edge Cases", 2, function(){ var date = $.date(); //Use May 31 2012 date.setFullDate(2012,4,31); - equal(date.adjust('M',1).day(),30,'Add 1 month from May to June sets days to 30, last day in June (prevent Overflow)'); - equal(date.adjust('M',-1).day(),30,'Subtract 1 month from June to May sets days to 30 in May'); + equal(date.adjust("M",1).day(),30,"Add 1 month from May to June sets days to 30, last day in June (prevent Overflow)"); + equal(date.adjust("M",-1).day(),30,"Subtract 1 month from June to May sets days to 30 in May"); }); -test('Date Adjustments - Leap Year Edge Cases', 1, function(){ +test("Date Adjustments - Leap Year Edge Cases", 1, function(){ var date = $.date(); //Use February 29 2012 a Leap year date.setFullDate(2012,1,29); - equal(date.adjust('Y',1).day(),28,'Feb 29 2012, add a year to convert to Feb 28, 2013'); + equal(date.adjust("Y",1).day(),28,"Feb 29 2012, add a year to convert to Feb 28, 2013"); }); -test('List days of Week', 2, function(){ - var date = $.date(); - var offset0 = [ - { 'fullname': 'Sunday', 'shortname': 'Su' }, - { 'fullname': 'Monday', 'shortname': 'Mo' }, - { 'fullname': 'Tuesday', 'shortname': 'Tu' }, - { 'fullname': 'Wednesday', 'shortname': 'We' }, - { 'fullname': 'Thursday', 'shortname': 'Th' }, - { 'fullname': 'Friday', 'shortname': 'Fr' }, - { 'fullname': 'Saturday', 'shortname': 'Sa' } ]; - var offset1 = [ - { 'fullname': 'Montag', 'shortname': 'Mo' }, - { 'fullname': 'Dienstag', 'shortname': 'Di' }, - { 'fullname': 'Mittwoch', 'shortname': 'Mi' }, - { 'fullname': 'Donnerstag', 'shortname': 'Do' }, - { 'fullname': 'Freitag', 'shortname': 'Fr' }, - { 'fullname': 'Samstag', 'shortname': 'Sa' }, - { 'fullname': 'Sonntag', 'shortname': 'So' } ]; - deepEqual(date.weekdays(), offset0, 'Get weekdays with start of day on 0 (English)'); - Globalize.culture( 'de-DE' ); +test("List days of Week", 2, function(){ + var date = $.date(), + offset0 = [ + { "fullname": "Sunday", "shortname": "Su" }, + { "fullname": "Monday", "shortname": "Mo" }, + { "fullname": "Tuesday", "shortname": "Tu" }, + { "fullname": "Wednesday", "shortname": "We" }, + { "fullname": "Thursday", "shortname": "Th" }, + { "fullname": "Friday", "shortname": "Fr" }, + { "fullname": "Saturday", "shortname": "Sa" } + ], + offset1 = [ + { "fullname": "Montag", "shortname": "Mo" }, + { "fullname": "Dienstag", "shortname": "Di" }, + { "fullname": "Mittwoch", "shortname": "Mi" }, + { "fullname": "Donnerstag", "shortname": "Do" }, + { "fullname": "Freitag", "shortname": "Fr" }, + { "fullname": "Samstag", "shortname": "Sa" }, + { "fullname": "Sonntag", "shortname": "So" } + ]; + deepEqual(date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)"); + Globalize.culture( "de-DE" ); date.refresh(); - deepEqual(date.weekdays(), offset1, 'Get weekdays with start of day on 1 (Germany)'); + deepEqual(date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)"); //Revert Globalize changes back to English - Globalize.culture('en-EN'); + Globalize.culture("en-EN"); }); -test('Leap Year Check', 8, function(){ +test("Leap Year Check", 8, function(){ var date = $.date(); - ok(date.setYear( 2008 ).isLeapYear(), '2008 is a Leap Year'); - ok(!date.setYear( 2009 ).isLeapYear(), '2009 is not a Leap Year'); - ok(!date.setYear( 2010 ).isLeapYear(), '2010 is not a Leap Year'); - ok(!date.setYear( 2011 ).isLeapYear(), '2011 is not a Leap Year'); - ok(date.isLeapYear( 2012 ), '2012 is a Leap Year'); - ok(!date.isLeapYear( 2013 ), '2013 is not a Leap Year'); - ok(!date.isLeapYear( 2014 ), '2014 is not a Leap year'); - ok(!date.isLeapYear( 2015 ), '2015 is not a Leap year'); + ok(date.setYear( 2008 ).isLeapYear(), "2008 is a Leap Year"); + ok(!date.setYear( 2009 ).isLeapYear(), "2009 is not a Leap Year"); + ok(!date.setYear( 2010 ).isLeapYear(), "2010 is not a Leap Year"); + ok(!date.setYear( 2011 ).isLeapYear(), "2011 is not a Leap Year"); + ok(date.isLeapYear( 2012 ), "2012 is a Leap Year"); + ok(!date.isLeapYear( 2013 ), "2013 is not a Leap Year"); + ok(!date.isLeapYear( 2014 ), "2014 is not a Leap year"); + ok(!date.isLeapYear( 2015 ), "2015 is not a Leap year"); }); -test('Days in Month', 3, function(){ +test("Days in Month", 3, function(){ var date = $.date(); date.setFullDate( 2012, 1, 1 ); - equal(date.daysInMonth(), 29, 'Leap Year implicit check for 29 days'); - equal(date.daysInMonth( 2012, 1 ), 29, 'Leap Year explicit check for 29 days'); - equal(date.daysInMonth( 2011, 3 ), 30, 'April has 30 days'); + equal(date.daysInMonth(), 29, "Leap Year implicit check for 29 days"); + equal(date.daysInMonth( 2012, 1 ), 29, "Leap Year explicit check for 29 days"); + equal(date.daysInMonth( 2011, 3 ), 30, "April has 30 days"); }); -test('Month Name', 2, function(){ +test("Month Name", 2, function(){ var date = $.date(); - equal(date.setMonth(3).monthName(), 'April', 'Month name return April (English)'); - Globalize.culture( 'de-DE' ); + equal(date.setMonth(3).monthName(), "April", "Month name return April (English)"); + Globalize.culture( "de-DE" ); date.refresh(); - equal(date.setMonth(2).monthName(), 'März', 'Month name return March (German)'); - Globalize.culture('en-EN'); + equal(date.setMonth(2).monthName(), "März", "Month name return March (German)"); + Globalize.culture("en-EN"); }); -test('Clone', 2, function(){ - var date = $.date(); - var date2 = date.clone(); - ok(date2, 'Created cloned object'); - notEqual(date.adjust('Y',1).year(), date2.year(), 'Object manipulated independently'); +test("Clone", 2, function(){ + var date = $.date(), + date2 = date.clone(); + ok(date2, "Created cloned object"); + notEqual(date.adjust("Y",1).year(), date2.year(), "Object manipulated independently"); }); -test('Days', 1, function(){ +test("Days", 1, function(){ //TODO needs work var date = $.date(); date.eachDay = function( day ) { @@ -133,7 +130,7 @@ test('Days', 1, function(){ day.render = true; day.extraClasses = "ui-state-disabled"; } - if ( day.date == 1 ) { + if ( day.date === 1 ) { day.extraClasses = "ui-state-error"; day.title = "Something bad explaining the error highlight"; } @@ -141,7 +138,7 @@ test('Days', 1, function(){ day.title = "A good day!"; } }; - ok(date.days(), 'Date days() returns'); + ok(date.days(), "Date days() returns"); }); test( "Months", 5, function(){ @@ -154,70 +151,72 @@ test( "Months", 5, function(){ ok( lastMonth.last ); ok( !lastMonth.first ); - ok( firstMonth.month() == ( lastMonth.month() - 1 ) ); + ok( firstMonth.month() === lastMonth.month() - 1 ); }); -test('iso8601Week', 2, function(){ +test("iso8601Week", 2, function(){ var date = $.date(); //date.setFullDate(2012, 0, 8); - equal(date.iso8601Week(new Date(2012, 0, 8)), 1, 'Test first week is 1'); - equal(date.iso8601Week(new Date(2012, 11, 31)), 1, 'Test last week is 1 in next year'); + equal(date.iso8601Week(new Date(2012, 0, 8)), 1, "Test first week is 1"); + equal(date.iso8601Week(new Date(2012, 11, 31)), 1, "Test last week is 1 in next year"); }); -test('Equal', 4, function(){ +test("Equal", 4, function(){ var date = $.date(); date.setFullDate(2012, 9, 16); - ok(date.equal(new Date(2012, 9, 16)), 'Does date equal provide date'); - ok(!date.equal(new Date(2011, 9, 16)), 'Does date year not equal provide date'); - ok(!date.equal(new Date(2012, 8, 16)), 'Does date month not equal provide date'); - ok(!date.equal(new Date(2012, 9, 15)), 'Does date day not equal provide date'); + ok(date.equal(new Date(2012, 9, 16)), "Does date equal provide date"); + ok(!date.equal(new Date(2011, 9, 16)), "Does date year not equal provide date"); + ok(!date.equal(new Date(2012, 8, 16)), "Does date month not equal provide date"); + ok(!date.equal(new Date(2012, 9, 15)), "Does date day not equal provide date"); }); -test('Date', 1, function(){ +test("Date", 1, function(){ var date = $.date(); - ok(date.date() instanceof Date, 'Date returned'); + ok(date.date() instanceof Date, "Date returned"); }); -test('Format', 4, function(){ +test("Format", 4, function(){ var date = $.date(); date.setFullDate(2012, 9, 16); - equal(date.format(), '10/16/2012', 'Checking default US format'); - equal(date.format('yyyy/MM/dd'), '2012/10/16', 'Checking yyyy/MM/dd format'); - equal(date.format('yy/dd/MM'), '12/16/10', 'Checking yy/dd/MM format'); - equal(date.format('MMMM dd, yyyy'), 'October 16, 2012', 'Checking MMMM dd, yyyy format'); + equal(date.format(), "10/16/2012", "Checking default US format"); + equal(date.format("yyyy/MM/dd"), "2012/10/16", "Checking yyyy/MM/dd format"); + equal(date.format("yy/dd/MM"), "12/16/10", "Checking yy/dd/MM format"); + equal(date.format("MMMM dd, yyyy"), "October 16, 2012", "Checking MMMM dd, yyyy format"); }); -test('Calendar', 3, function(){ - var date = $.date(); - ok(date.calendar(), 'Calendar type returned') - var de_cal = {calendars: { - standard: { - "/": ".", - firstDay: 1, - days: { - names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], - namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], - namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] - }, - months: { - names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], - namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] - }, - AM: null, - PM: null, - eras: [{"name":"n. Chr.","start":null,"offset":0}], - patterns: { - d: "dd.MM.yyyy", - D: "dddd, d. MMMM yyyy", - t: "HH:mm", - T: "HH:mm:ss", - f: "dddd, d. MMMM yyyy HH:mm", - F: "dddd, d. MMMM yyyy HH:mm:ss", - M: "dd MMMM", - Y: "MMMM yyyy" +test("Calendar", 3, function(){ + var date = $.date(), + de_cal = { + calendars: { + standard: { + "/": ".", + firstDay: 1, + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: null, + PM: null, + eras: [{"name":"n. Chr.","start":null,"offset":0}], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + t: "HH:mm", + T: "HH:mm:ss", + f: "dddd, d. MMMM yyyy HH:mm", + F: "dddd, d. MMMM yyyy HH:mm:ss", + M: "dd MMMM", + Y: "MMMM yyyy" + } + } } - } - }}; - ok(date.calendar(de_cal), 'Calendar type changed'); - deepEqual(date.calendar(), de_cal, 'Calendar change verified'); -}); \ No newline at end of file + }; + ok(date.calendar(), "Calendar type returned"); + ok(date.calendar(de_cal), "Calendar type changed"); + deepEqual(date.calendar(), de_cal, "Calendar change verified"); +}); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 6c3e013dc05..ccc2edd7cc5 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -41,7 +41,6 @@ $.widget( "ui.datepicker", { select: null }, _create: function() { - var that = this; this.date = $.date(); this.date.eachDay = this.options.eachDay; this.id = "ui-datepicker-" + idIncrement; @@ -97,7 +96,8 @@ $.widget( "ui.datepicker", { } event.preventDefault(); - var activeCell = $( "#" + this.grid.attr( "aria-activedescendant" ) ), + var newId, newCell, + activeCell = $( "#" + this.grid.attr( "aria-activedescendant" ) ), oldMonth = this.date.month(), oldYear = this.date.year(); @@ -134,13 +134,13 @@ $.widget( "ui.datepicker", { return; } - if ( this.date.month() != oldMonth || this.date.year() != oldYear ) { + if ( this.date.month() !== oldMonth || this.date.year() !== oldYear ) { this.refresh(); this.grid.focus( 1 ); } else { - var newId = this.id + "-" + this.date.day(), - newCell = $("#" + newId); + newId = this.id + "-" + this.date.day(); + newCell = $("#" + newId); // TODO unnecessary optimization? is it really needed? if ( !newCell.length ) { @@ -160,7 +160,7 @@ $.widget( "ui.datepicker", { .uniqueId() .hide(); this._setHiddenPicker(); - this.picker.appendTo( this._appendTo() ) + this.picker.appendTo( this._appendTo() ); this.element .attr( "aria-haspopup", "true" ) @@ -210,7 +210,7 @@ $.widget( "ui.datepicker", { suppressExpandOnFocus = false; }, 100); }, - blur: function( event ) { + blur: function() { suppressExpandOnFocus = false; } }); @@ -224,10 +224,10 @@ $.widget( "ui.datepicker", { this.close( event ); }, 150); }, - focusin: function( event ) { + focusin: function() { clearTimeout( this.closeTimer ); }, - mouseup: function( event ) { + mouseup: function() { clearTimeout( this.closeTimer ); }, // TODO on TAB (or shift TAB), make sure it ends up on something useful in DOM order @@ -426,7 +426,7 @@ $.widget( "ui.datepicker", { return "" + cells + ""; }, _buildDayCell: function( day ) { - var contents = ""; + var contents = "", idAttribute = day.render ? ( "id=" + this.id + "-" + day.date ) : "", ariaSelectedAttribute = "aria-selected=" + ( day.current ? "true" : "false" ), ariaDisabledAttribute = day.selectable ? "" : "aria-disabled=true"; @@ -448,8 +448,8 @@ $.widget( "ui.datepicker", { classes = [ "ui-state-default" ], labels = Globalize.localize( "datepicker" ); - if ( day.date == this.date.day() ) { - classes.push( "ui-state-focus" ) + if ( day.date === this.date.day() ) { + classes.push( "ui-state-focus" ); } if ( day.current ) { classes.push( "ui-state-active" ); @@ -490,13 +490,13 @@ $.widget( "ui.datepicker", { "" + "
      "; }, - _focusTrigger: function( event ) { + _focusTrigger: function() { suppressExpandOnFocus = true; this.element.focus(); }, // Refreshing the entire datepicker during interaction confuses screen readers, specifically - // because the grid heading is marked up as a live region and will often not update if it's - // destroyed and recreated instead of just having its text change. Additionally, interacting + // because the grid heading is marked up as a live region and will often not update if it's + // destroyed and recreated instead of just having its text change. Additionally, interacting // with the prev and next links would cause loss of focus issues because the links being // interacted with will disappear while focused. refresh: function() { @@ -513,8 +513,7 @@ $.widget( "ui.datepicker", { } }, _refreshMultiplePicker: function() { - var currentDate = this.date, - i = 0; + var i = 0; for ( ; i < this.options.numberOfMonths; i++ ) { $( ".ui-datepicker-title", this.picker ).eq( i ).html( this._buildTitle() ); From 7a8f351a6c853cf0cd134f05dfc46836ee5cbaa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rn=20Zaefferer?= Date: Wed, 11 Sep 2013 17:00:15 +0200 Subject: [PATCH 005/172] Datepicker: Fix dateFormat demo by adding a dateFormat option and passing that through to $.date --- demos/datepicker/date-formats.html | 14 ++++++++------ ui/jquery.ui.datepicker.js | 5 +++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index 3a46308318c..dc7c58180ba 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -5,9 +5,14 @@ jQuery UI Datepicker - Format date + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demos/datepicker/min-max.html b/demos/datepicker/min-max.html index 52bf8cbf4e8..dacecb0d079 100644 --- a/demos/datepicker/min-max.html +++ b/demos/datepicker/min-max.html @@ -5,9 +5,14 @@ jQuery UI Datepicker - Restrict date range + + + + + + + + + + + + + + + + + + + + @@ -38,9 +40,8 @@

      Animations:
       

      From abaeedc21d533bbc798d825f01a4c5504e191d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rn=20Zaefferer?= Date: Wed, 11 Sep 2013 18:11:24 +0200 Subject: [PATCH 009/172] Datepicker: Update alt-field demo - remove the options and use Globalize to parse and format instead --- demos/datepicker/alt-field.html | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/demos/datepicker/alt-field.html b/demos/datepicker/alt-field.html index 8742da2cef0..bda5516de4c 100644 --- a/demos/datepicker/alt-field.html +++ b/demos/datepicker/alt-field.html @@ -5,15 +5,29 @@ jQuery UI Datepicker - Populate alternate field + + + + + + + + + + + + From cb3f5658dcc304f1bdd64a219f0684afc92c1009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rn=20Zaefferer?= Date: Wed, 11 Sep 2013 18:18:57 +0200 Subject: [PATCH 010/172] Datepicker: Fix dependencies on buttonbar demo --- demos/datepicker/buttonbar.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/demos/datepicker/buttonbar.html b/demos/datepicker/buttonbar.html index d8157409728..f3fa1e42af8 100644 --- a/demos/datepicker/buttonbar.html +++ b/demos/datepicker/buttonbar.html @@ -5,9 +5,14 @@ jQuery UI Datepicker - Display button bar + + + + + diff --git a/external/date.js b/external/date.js index 23efeef708d..fef4dcaeffe 100644 --- a/external/date.js +++ b/external/date.js @@ -130,8 +130,9 @@ $.date = function( datestring, formatstring ) { today: today.equal( printDate ) }; day.render = day.selectable = !day.lead; - // TODO undefined in picker demos, fix it - // this.eachDay( day ); + if ( this.eachDay ) { + this.eachDay( day ); + } // TODO use adjust("D", 1)? printDate.setDate( printDate.getDate() + 1 ); } diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 97be1fe4065..6b7595b6cf3 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -459,7 +459,7 @@ $.widget( "ui.datepicker", { classes.push( "ui-state-highlight" ); } if ( day.extraClasses ) { - classes.push( day.extraClasses.split( "" ) ); + classes.push( day.extraClasses.split( " " ) ); } link = "" + @@ -478,7 +478,7 @@ $.widget( "ui.datepicker", { classes.push( "ui-state-highlight" ); } if ( day.extraClasses ) { - classes.push( day.extraClasses.split( "" ) ); + classes.push( day.extraClasses.split( " " ) ); } return "" + From 88d3c69845630bf1c12039723b7490f5f5936ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rn=20Zaefferer?= Date: Wed, 11 Sep 2013 18:34:27 +0200 Subject: [PATCH 012/172] Datepicker: Update icon-trigger demo, build a custom trigger. Prevent the datepicker from opening with a new cancellable beforeOpen event. Cancel = don't open --- demos/datepicker/icon-trigger.html | 18 ++++++++++++++---- ui/jquery.ui.datepicker.js | 4 ++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index cdcf578c097..d84deae026a 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -16,11 +16,21 @@ diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 6b7595b6cf3..cf8d592029d 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -37,6 +37,7 @@ $.widget( "ui.datepicker", { hide: true, // callbacks + beforeOpen: null, close: null, open: null, select: null @@ -527,6 +528,9 @@ $.widget( "ui.datepicker", { if ( this.inline || this.isOpen ) { return; } + if ( this._trigger( "beforeOpen", event ) === false ) { + return; + } // TODO explain this this.date = $.date( this.element.val(), this.options.dateFormat ); From b59d4de8973dcaa6d0da1ca222fd613b73a93de9 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 30 Oct 2013 09:11:06 -0400 Subject: [PATCH 013/172] Datepicker: Only apply the ui-state-focus class name to one cell. This is specifically for multi month pickers. This makes the assumption that the keyboard is always interacting with the first month in a multi month calendar. The next step is to store which grid currently has focus and to base these focus logic off of that. --- ui/jquery.ui.datepicker.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index cf8d592029d..8adc3ed81de 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -150,8 +150,8 @@ $.widget( "ui.datepicker", { } this.grid.attr("aria-activedescendant", newId); - activeCell.children("a").removeClass("ui-state-focus"); - newCell.children("a").addClass("ui-state-focus"); + this.grid.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); + newCell.children( "a" ).addClass( "ui-state-focus" ); } }, _createPicker: function() { @@ -523,6 +523,10 @@ $.widget( "ui.datepicker", { this.date.adjust( "M", 1 ); } this.date.adjust( "M", -this.options.numberOfMonths ); + + // TODO: This assumes focus is on the first grid. For multi pickers, the widget needs + // to maintain the currently focused grid and base queries like this off of it. + $( this.picker ).find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" ); }, open: function( event ) { if ( this.inline || this.isOpen ) { From 45d64ea0c7fcfbb00324c830b5b70f6d774baa62 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Sat, 2 Nov 2013 09:54:05 -0400 Subject: [PATCH 014/172] Datepicker: Fixing widget() method test and minor coding standard changes. --- tests/unit/datepicker/datepicker_core.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 2312e482e27..5fa1703bf9e 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -10,14 +10,17 @@ TestHelpers.testJshint( "datepicker" ); test( "widget method - empty collection", function() { expect( 1 ); - $( "#nonExist" ).datepicker(); // should create nothing + + // should create nothing + $( "#nonExist" ).datepicker(); ok( !$( "#ui-datepicker-div" ).length, "Non init on empty collection" ); }); -test("widget method", function() { +test( "widget method", function() { expect( 1 ); - var actual = $("#inp").datepicker().datepicker("widget")[0]; - deepEqual($("body > #ui-datepicker-div:last-child")[0], actual); + var actual = $( "#inp" ).datepicker().datepicker( "widget" ); + deepEqual( $("body > .ui-front" )[ 0 ], actual[ 0 ] ); + actual.remove(); }); asyncTest( "baseStructure", function() { From 41add14c3053876cf8ca96189b2b2c94343cdc77 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Sat, 2 Nov 2013 10:42:13 -0400 Subject: [PATCH 015/172] Datepicker: Updating first batch of structure tests to new APIs and standards. --- tests/unit/datepicker/datepicker_core.js | 37 +++++++++++-------- .../datepicker/datepicker_test_helpers.js | 9 +++-- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 5fa1703bf9e..0cbd96a5a87 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -27,22 +27,23 @@ asyncTest( "baseStructure", function() { expect( 58 ); var header, title, table, thead, week, panel, inl, child, inp = TestHelpers.datepicker.initNewInput(), - dp = $( "#ui-datepicker-div" ); + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); function step1() { - TestHelpers.datepicker.onFocus( inp, function() { + inp.focus(); + setTimeout(function() { ok( dp.is( ":visible" ), "Structure - datepicker visible" ); ok( !dp.is( ".ui-datepicker-rtl" ), "Structure - not right-to-left" ); ok( !dp.is( ".ui-datepicker-multi" ), "Structure - not multi-month" ); - equal( dp.children().length, 2, "Structure - child count" ); + equal( dp.children().length, 3, "Structure - child count (header, calendar, buttonpane)" ); header = dp.children( ":first" ); ok( header.is( "div.ui-datepicker-header" ), "Structure - header division" ); equal( header.children().length, 3, "Structure - header child count" ); - ok( header.children( ":first" ).is( "a.ui-datepicker-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); - ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); + ok( header.children( ":first" ).is( ".ui-datepicker-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); + ok( header.children( ":eq(1)" ).is( ".ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); - title = header.children( ":last" ); + title = header.children( ":last" ).children( ":first" ); ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "","Structure - title division" ); equal( title.children().length, 2, "Structure - title child count" ); ok( title.children( ":first" ).is( "span.ui-datepicker-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); @@ -64,10 +65,10 @@ asyncTest( "baseStructure", function() { ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" ); ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + inp.datepicker( "close" ).datepicker( "destroy" ); step2(); }); - } + }; function step2() { // Editable month/year and button panel @@ -76,7 +77,8 @@ asyncTest( "baseStructure", function() { changeYear: true, showButtonPanel: true }); - TestHelpers.datepicker.onFocus( inp, function() { + inp.focus(); + setTimeout(function() { title = dp.find( "div.ui-datepicker-title" ); ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" ); ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" ); @@ -87,7 +89,7 @@ asyncTest( "baseStructure", function() { ok( panel.children( ":first" ).is( "button.ui-datepicker-current" ), "Structure - today button" ); ok( panel.children( ":last" ).is( "button.ui-datepicker-close" ), "Structure - close button" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + inp.datepicker( "close" ).datepicker( "destroy" ); step3(); }); } @@ -95,7 +97,8 @@ asyncTest( "baseStructure", function() { function step3() { // Multi-month 2 inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 2 }); - TestHelpers.datepicker.onFocus( inp, function() { + inp.focus(); + setTimeout(function() { ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" ); equal( dp.children().length, 3, "Structure multi [2] - child count" ); @@ -109,7 +112,7 @@ asyncTest( "baseStructure", function() { ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" ); ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + inp.datepicker( "close" ).datepicker( "destroy" ); step4(); }); } @@ -117,11 +120,12 @@ asyncTest( "baseStructure", function() { function step4() { // Multi-month 3 inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 3 }); - TestHelpers.datepicker.onFocus( inp, function() { + inp.focus(); + setTimeout(function() { ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" ); ok( !dp.is( ".ui-datepicker-multi-2" ), "Structure multi [3] - Trac #6704" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + inp.datepicker( "close" ).datepicker( "destroy" ); step5(); }); } @@ -129,7 +133,8 @@ asyncTest( "baseStructure", function() { function step5() { // Multi-month [2, 2] inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: [ 2, 2 ] }); - TestHelpers.datepicker.onFocus( inp, function() { + inp.focus(); + setTimeout(function() { ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" ); equal( dp.children().length, 6, "Structure multi [2,2] - child count" ); @@ -151,7 +156,7 @@ asyncTest( "baseStructure", function() { child = dp.children( ":eq(5)" ); ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + inp.datepicker( "close" ).datepicker( "destroy" ); // Inline inl = TestHelpers.datepicker.init( "#inl" ); diff --git a/tests/unit/datepicker/datepicker_test_helpers.js b/tests/unit/datepicker/datepicker_test_helpers.js index 34b41bbc6a5..060c6bf9505 100644 --- a/tests/unit/datepicker/datepicker_test_helpers.js +++ b/tests/unit/datepicker/datepicker_test_helpers.js @@ -15,12 +15,13 @@ TestHelpers.datepicker = { equal(d1.toString(), d2.toString(), message); }, init: function( id, options ) { - $.datepicker.setDefaults( $.datepicker.regional[ "" ] ); - return $( id ).datepicker( $.extend( { showAnim: "" }, options || {} ) ); + options = $.extend( { show: false }, options || {} ); + return $( id ).datepicker( options ); }, initNewInput: function( options ) { - var id = $( "" ).appendTo( "#qunit-fixture" ); - return TestHelpers.datepicker.init( id, options ); + options = $.extend( { show: false }, options || {} ); + return $( "" ).datepicker( options ) + .appendTo( "#qunit-fixture" ); }, onFocus: TestHelpers.onFocus, PROP_NAME: "datepicker" From ebeb23ed150beb3abd73f8a5299ea97b4509ee07 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Sat, 2 Nov 2013 10:59:56 -0400 Subject: [PATCH 016/172] Datepicker: Fixing and/or commenting out remaning multi month datepicker structure tests. --- tests/unit/datepicker/datepicker_core.js | 25 +++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 0cbd96a5a87..41d1b065bd9 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -62,8 +62,9 @@ asyncTest( "baseStructure", function() { week = table.children( ":eq(1)" ).children( ":first" ); ok( week.is( "tr" ), "Structure - month table week row" ); equal( week.children().length, 7, "Structure - week child count" ); - ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" ); - ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" ); + // TODO: Preserve these class names or let the user use :first-child and :last-child? + // ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" ); + // ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" ); inp.datepicker( "close" ).datepicker( "destroy" ); step2(); @@ -77,11 +78,13 @@ asyncTest( "baseStructure", function() { changeYear: true, showButtonPanel: true }); + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); inp.focus(); setTimeout(function() { title = dp.find( "div.ui-datepicker-title" ); - ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" ); - ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" ); + // TODO: Re-add tests when changeMonth and changeYear are re-implemented + //ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" ); + //ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" ); panel = dp.children( ":last" ); ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" ); @@ -97,16 +100,19 @@ asyncTest( "baseStructure", function() { function step3() { // Multi-month 2 inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 2 }); + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); inp.focus(); setTimeout(function() { ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" ); - equal( dp.children().length, 3, "Structure multi [2] - child count" ); + equal( dp.children().length, 4, "Structure multi [2] - child count" ); child = dp.children( ":first" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" ); + // TODO: Implement ui-datepicker-group-first class name + // ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" ); child = dp.children( ":eq(1)" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" ); + // TODO: Implement ui-datepicker-group-last class name + // ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" ); child = dp.children( ":eq(2)" ); ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" ); @@ -120,6 +126,7 @@ asyncTest( "baseStructure", function() { function step4() { // Multi-month 3 inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 3 }); + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ) inp.focus(); setTimeout(function() { ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" ); @@ -133,8 +140,11 @@ asyncTest( "baseStructure", function() { function step5() { // Multi-month [2, 2] inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: [ 2, 2 ] }); + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ) inp.focus(); setTimeout(function() { + /* + TODO: Re-add after array form of the numberOfMonths option is implemented. ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" ); equal( dp.children().length, 6, "Structure multi [2,2] - child count" ); @@ -157,6 +167,7 @@ asyncTest( "baseStructure", function() { ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); inp.datepicker( "close" ).datepicker( "destroy" ); + */ // Inline inl = TestHelpers.datepicker.init( "#inl" ); From 5baa227e36b7eb82e70c2d5a67ea38dd6dc24a49 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Sun, 3 Nov 2013 08:18:17 -0500 Subject: [PATCH 017/172] Datepicker: Fixing or commenting out remaining structure tests. --- tests/unit/datepicker/datepicker_core.js | 77 ++++++++++++++---------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 41d1b065bd9..0193fa5dba5 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -24,7 +24,7 @@ test( "widget method", function() { }); asyncTest( "baseStructure", function() { - expect( 58 ); + expect( 42 ); var header, title, table, thead, week, panel, inl, child, inp = TestHelpers.datepicker.initNewInput(), dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); @@ -165,50 +165,61 @@ asyncTest( "baseStructure", function() { child = dp.children( ":eq(5)" ); ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); - - inp.datepicker( "close" ).datepicker( "destroy" ); */ + inp.datepicker( "close" ).datepicker( "destroy" ); + step6(); + }); + }; - // Inline - inl = TestHelpers.datepicker.init( "#inl" ); - dp = inl.children(); + function step6() { + // Inline + inl = TestHelpers.datepicker.init( "#inl" ); + dp = inl.children(); - ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" ); - ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" ); - ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" ); - equal( dp.children().length, 2, "Structure inline - child count" ); + ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" ); + ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" ); + ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" ); + equal( dp.children().length, 3, "Structure inline - child count (header, calendar, buttonpane)" ); - header = dp.children( ":first" ); - ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" ); - equal( header.children().length, 3, "Structure inline - header child count" ); + header = dp.children( ":first" ); + ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" ); + equal( header.children().length, 3, "Structure inline - header child count" ); - table = dp.children( ":eq(1)" ); - ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" ); - ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" ); - ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" ); + table = dp.children( ":eq(1)" ); + ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" ); + ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" ); + ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" ); - inl.datepicker( "destroy" ); + inl.datepicker( "destroy" ); - // Inline multi-month - inl = TestHelpers.datepicker.init( "#inl", { numberOfMonths: 2 } ); - dp = inl.children(); + // TODO: Calling destroy() on inline pickers currently does not work. + inl.empty(); - ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" ); - equal( dp.children().length, 3, "Structure inline multi - child count" ); + step7(); + }; - child = dp.children( ":first" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" ); + function step7() { + // Inline multi-month + inl = TestHelpers.datepicker.init( "#inl", { numberOfMonths: 2 } ); + dp = inl.datepicker( "widget" ).find( ".ui-datepicker" ); - child = dp.children( ":eq(1)" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" ); + ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" ); + equal( dp.children().length, 4, "Structure inline multi - child count" ); - child = dp.children( ":eq(2)" ); - ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" ); + child = dp.children( ":first" ); + // TODO: Implement ui-datepicker-group-first class name + // ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" ); - inl.datepicker( "destroy" ); - start(); - }); - } + child = dp.children( ":eq(1)" ); + // TODO: Implement ui-datepicker-group-last class name + // ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" ); + + inl.datepicker( "destroy" ); + start(); + }; step1(); }); From c8a0eed9049fc2b42a2556267dd5f0e4f4caae77 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Sun, 3 Nov 2013 08:46:11 -0500 Subject: [PATCH 018/172] Datepicker: Cleaning up and commenting out custom structure tests as none of these options are implemented yet. --- external/globalize.culture.he.js | 97 ++++++++++++++++++++++++ tests/unit/datepicker/datepicker.html | 7 +- tests/unit/datepicker/datepicker_core.js | 80 +++++++++---------- 3 files changed, 141 insertions(+), 43 deletions(-) create mode 100644 external/globalize.culture.he.js diff --git a/external/globalize.culture.he.js b/external/globalize.culture.he.js new file mode 100644 index 00000000000..2d2e59abd6b --- /dev/null +++ b/external/globalize.culture.he.js @@ -0,0 +1,97 @@ +/* + * Globalize Culture he + * + * http://github.com/jquery/globalize + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * This file was generated by the Globalize Culture Generator + * Translation: bugs found in this file need to be fixed in the generator + */ + +(function( window, undefined ) { + +var Globalize; + +if ( typeof require !== "undefined" && + typeof exports !== "undefined" && + typeof module !== "undefined" ) { + // Assume CommonJS + Globalize = require( "globalize" ); +} else { + // Global variable + Globalize = window.Globalize; +} + +Globalize.addCultureInfo( "he", "default", { + name: "he", + englishName: "Hebrew", + nativeName: "עברית", + language: "he", + isRTL: true, + numberFormat: { + "NaN": "לא מספר", + negativeInfinity: "אינסוף שלילי", + positiveInfinity: "אינסוף חיובי", + percent: { + pattern: ["-n%","n%"] + }, + currency: { + pattern: ["$-n","$ n"], + symbol: "₪" + } + }, + calendars: { + standard: { + days: { + names: ["יום ראשון","יום שני","יום שלישי","יום רביעי","יום חמישי","יום שישי","שבת"], + namesAbbr: ["יום א","יום ב","יום ג","יום ד","יום ה","יום ו","שבת"], + namesShort: ["א","ב","ג","ד","ה","ו","ש"] + }, + months: { + names: ["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר",""], + namesAbbr: ["ינו","פבר","מרץ","אפר","מאי","יונ","יול","אוג","ספט","אוק","נוב","דצמ",""] + }, + eras: [{"name":"לספירה","start":null,"offset":0}], + patterns: { + d: "dd/MM/yyyy", + D: "dddd dd MMMM yyyy", + t: "HH:mm", + T: "HH:mm:ss", + f: "dddd dd MMMM yyyy HH:mm", + F: "dddd dd MMMM yyyy HH:mm:ss", + M: "dd MMMM", + Y: "MMMM yyyy" + } + }, + Hebrew: { + name: "Hebrew", + "/": " ", + days: { + names: ["יום ראשון","יום שני","יום שלישי","יום רביעי","יום חמישי","יום שישי","שבת"], + namesAbbr: ["א","ב","ג","ד","ה","ו","ש"], + namesShort: ["א","ב","ג","ד","ה","ו","ש"] + }, + months: { + names: ["תשרי","חשון","כסלו","טבת","שבט","אדר","אדר ב","ניסן","אייר","סיון","תמוז","אב","אלול"], + namesAbbr: ["תשרי","חשון","כסלו","טבת","שבט","אדר","אדר ב","ניסן","אייר","סיון","תמוז","אב","אלול"] + }, + eras: [{"name":"C.E.","start":null,"offset":0}], + twoDigitYearMax: 5790, + patterns: { + d: "dd MMMM yyyy", + D: "dddd dd MMMM yyyy", + t: "HH:mm", + T: "HH:mm:ss", + f: "dddd dd MMMM yyyy HH:mm", + F: "dddd dd MMMM yyyy HH:mm:ss", + M: "dd MMMM", + Y: "MMMM yyyy" + } + } + } +}); + +}( this )); \ No newline at end of file diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 162748b7ef3..119926ce174 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -20,11 +20,8 @@ "ui/jquery.ui.widget.js", "ui/jquery.ui.button.js", "ui/jquery.ui.datepicker.js", - "ui/jquery.ui.position.js" - /* TODO: Replace with Globalize cultures - "ui/i18n/jquery.ui.datepicker-fr.js", - "ui/i18n/jquery.ui.datepicker-he.js", - "ui/i18n/jquery.ui.datepicker-zh-CN.js"*/ + "ui/jquery.ui.position.js", + "external/globalize.culture.he.js" ] }); diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 0193fa5dba5..2b7fe0c2e40 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -69,7 +69,7 @@ asyncTest( "baseStructure", function() { inp.datepicker( "close" ).datepicker( "destroy" ); step2(); }); - }; + } function step2() { // Editable month/year and button panel @@ -126,7 +126,7 @@ asyncTest( "baseStructure", function() { function step4() { // Multi-month 3 inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 3 }); - dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ) + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); inp.focus(); setTimeout(function() { ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" ); @@ -140,7 +140,7 @@ asyncTest( "baseStructure", function() { function step5() { // Multi-month [2, 2] inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: [ 2, 2 ] }); - dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ) + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); inp.focus(); setTimeout(function() { /* @@ -169,7 +169,7 @@ asyncTest( "baseStructure", function() { inp.datepicker( "close" ).datepicker( "destroy" ); step6(); }); - }; + } function step6() { // Inline @@ -196,7 +196,7 @@ asyncTest( "baseStructure", function() { inl.empty(); step7(); - }; + } function step7() { // Inline multi-month @@ -219,21 +219,28 @@ asyncTest( "baseStructure", function() { inl.datepicker( "destroy" ); start(); - }; + } step1(); }); asyncTest( "customStructure", function() { - expect( 20 ); + expect( 0 ); + var header, panel, title, thead, - inp = TestHelpers.datepicker.initNewInput( $.datepicker.regional.he ), - dp = $( "#ui-datepicker-div" ); + inp = TestHelpers.datepicker.initNewInput(), + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); + + // Skip these tests for now as none are implemented yet. + start(); + return; function step1() { - inp.datepicker( "option", "showButtonPanel", true ); + /* + Globalize.culture( "he" ); + inp.focus(); - TestHelpers.datepicker.onFocus( inp, function() { + setTimeout(function() { ok( dp.is( ".ui-datepicker-rtl" ), "Structure RTL - right-to-left" ); header = dp.children( ":first" ); @@ -248,13 +255,17 @@ asyncTest( "customStructure", function() { ok( panel.children( ":first" ).is( "button.ui-datepicker-close" ), "Structure RTL - close button" ); ok( panel.children( ":last" ).is( "button.ui-datepicker-current" ), "Structure RTL - today button" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + inp.datepicker( "close" ).datepicker( "destroy" ); + Globalize.culture( "en-US" ); step2(); }); + */ } // Hide prev/next - function step2() { + // TODO: If we decide the hideIfNoPrevNext option is being removed these tests can be as well. + /* + function stepX() { inp = TestHelpers.datepicker.initNewInput({ hideIfNoPrevNext: true, minDate: new Date( 2008, 2 - 1, 4 ), @@ -272,47 +283,40 @@ asyncTest( "customStructure", function() { step3(); }); } + */ // Changeable Month with read-only year - function step3() { + function step2() { inp = TestHelpers.datepicker.initNewInput({ changeMonth: true }); + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); - TestHelpers.datepicker.onFocus( inp, function() { + inp.focus(); + setTimeout(function() { title = dp.children( ":first" ).children( ":last" ); - equal( title.children().length, 2, "Structure changeable month - title child count" ); - ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure changeable month - month selector" ); - ok( title.children( ":last" ).is( "span.ui-datepicker-year" ), "Structure changeable month - read-only year" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - step4(); + // TODO: Implement changeMonth option + // equal( title.children().length, 2, "Structure changeable month - title child count" ); + // ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure changeable month - month selector" ); + // ok( title.children( ":last" ).is( "span.ui-datepicker-year" ), "Structure changeable month - read-only year" ); + + inp.datepicker( "close" ).datepicker( "destroy" ); + step3(); }); } // Changeable year with read-only month - function step4() { + function step3() { inp = TestHelpers.datepicker.initNewInput({ changeYear: true }); TestHelpers.datepicker.onFocus( inp, function() { title = dp.children( ":first" ).children( ":last" ); - equal( title.children().length, 2, "Structure changeable year - title child count" ); - ok( title.children( ":first" ).is( "span.ui-datepicker-month" ), "Structure changeable year - read-only month" ); - ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure changeable year - year selector" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - step5(); - }); - } - - // Read-only first day of week - function step5() { - inp = TestHelpers.datepicker.initNewInput({ changeFirstDay: false }); + // TODO: Implement changeYear option + // equal( title.children().length, 2, "Structure changeable year - title child count" ); + // ok( title.children( ":first" ).is( "span.ui-datepicker-month" ), "Structure changeable year - read-only month" ); + // ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure changeable year - year selector" ); - TestHelpers.datepicker.onFocus( inp, function() { - thead = dp.find( ".ui-datepicker-calendar thead tr" ); - equal( thead.children().length, 7, "Structure read-only first day - thead child count" ); - equal( thead.find( "a" ).length, 0, "Structure read-only first day - thead links count" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); + inp.datepicker( "close" ).datepicker( "destroy" ); start(); }); } From 00debdf2d230ef80436c4aaa9840bf6fdabef2ed Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Mon, 4 Nov 2013 08:45:56 -0500 Subject: [PATCH 019/172] Datepicker: Coding standards and new APIs for keyboard handling tests. These tests are commented out for now as they need a means of getting a Date object from the widget and currently there isn't one. --- tests/unit/datepicker/datepicker_core.js | 273 +++++++++++++---------- 1 file changed, 152 insertions(+), 121 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 2b7fe0c2e40..8b515161c32 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -327,139 +327,170 @@ asyncTest( "customStructure", function() { setTimeout( step1 ); }); -test("keystrokes", function() { - expect( 26 ); - var inp = TestHelpers.datepicker.init("#inp"), +test( "Keyboard handling", function() { + // TODO: These tests all rely on having a method to retrieve a Date object. There + // is not only implemented yet so bail. + expect( 0 ); + return; + + expect( 24 ); + var inp = TestHelpers.datepicker.init( "#inp" ), date = new Date(); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke enter"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Keystroke enter - preset"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+home"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); - ok(inp.datepicker("getDate") == null, "Keystroke ctrl+end"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); + + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.val(), date, "Keystroke enter" ); + + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate("keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + "Keystroke enter - preset" ); + + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Keystroke ctrl+home" ); + + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END }); + ok( inp.datepicker( "getDate" ) == null, "Keystroke ctrl+end" ); + + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); ok(inp.datepicker("getDate") == null, "Keystroke esc"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Keystroke esc - preset"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Keystroke esc - abandoned"); + + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + "Keystroke esc - preset" ); + + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date(2008, 2 - 1, 4), + "Keystroke esc - abandoned" ); + // Moving by day or week - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.LEFT}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+left"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.LEFT}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke left"); - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.LEFT }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date.setDate( date.getDate() - 1 ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+left" ); + + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", {keyCode: $.ui.keyCode.LEFT }). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER }); + date.setDate( date.getDate() + 1 ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke left") ; + + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+right"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.RIGHT}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+right" ); + + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", {keyCode: $.ui.keyCode.RIGHT}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() - 1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke right"); - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke right" ); + + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() - 7); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+up"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+up" ); + + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", {keyCode: $.ui.keyCode.UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 7); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke up"); - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke up" ); + + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 7); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+down"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 7); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Keystroke down"); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+down" ); + + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date.setDate( date.getDate() - 7 ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke down" ); + // Moving by month or year - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 1 - 1, 4), - "Keystroke pgup"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 3 - 1, 4), - "Keystroke pgdn"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2007, 2 - 1, 4), - "Keystroke ctrl+pgup"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2009, 2 - 1, 4), - "Keystroke ctrl+pgdn"); + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 4 ), + "Keystroke pgup" ); + + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 3 - 1, 4 ), + "Keystroke pgdn" ); + + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 4 ), + "Keystroke ctrl+pgup" ); + + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 4 ), + "Keystroke ctrl+pgdn" ); + // Check for moving to short months - inp.val("03/31/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 29), - "Keystroke pgup - Feb"); - inp.val("01/30/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 29), - "Keystroke pgdn - Feb"); - inp.val("02/29/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2007, 2 - 1, 28), - "Keystroke ctrl+pgup - Feb"); - inp.val("02/29/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2009, 2 - 1, 28), - "Keystroke ctrl+pgdn - Feb"); + inp.val( "03/31/2008" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ), + "Keystroke pgup - Feb" ); + + inp.val( "01/30/2008" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ), + "Keystroke pgdn - Feb" ); + + inp.val( "02/29/2008" ).datepicker( "open" ) + .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 28 ), + "Keystroke ctrl+pgup - Feb" ); + + inp.val( "02/29/2008" ).datepicker( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 28 ), + "Keystroke ctrl+pgdn - Feb" ); + // Goto current - inp.datepicker("option", {gotoCurrent: true}). - datepicker("hide").val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Keystroke ctrl+home"); + inp.datepicker( "option", { gotoCurrent: true }) + .datepicker( "close" ).val( "02/04/2008" ).datepicker( "open" ) + .late( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + "Keystroke ctrl+home" ); + // Change steps - inp.datepicker("option", {stepMonths: 2, gotoCurrent: false}). - datepicker("hide").val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2007, 12 - 1, 4), - "Keystroke pgup step 2"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 4 - 1, 4), - "Keystroke pgdn step 2"); + inp.datepicker( "option", { stepMonths: 2, gotoCurrent: false }) + .datepicker( "close" ).val( "02/04/2008" ).datepicker( "open" ) + .late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2007, 12 - 1, 4 ), + "Keystroke pgup step 2" ); + + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 4 - 1, 4 ), + "Keystroke pgdn step 2" ); }); test("mouse", function() { From fb798426827e80b395f1bdfcd9b3e67d062ab452 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Mon, 4 Nov 2013 08:59:29 -0500 Subject: [PATCH 020/172] Datepicker: Coding standards and new APIs for mouse core tests. Disabling these tests as well as they utilize the old getDate() and setDate() methods and there is no replacement for these yet. --- tests/unit/datepicker/datepicker_core.js | 171 +++++++++++++---------- 1 file changed, 97 insertions(+), 74 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 8b515161c32..a7a47f0d646 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -493,87 +493,110 @@ test( "Keyboard handling", function() { "Keystroke pgdn step 2" ); }); -test("mouse", function() { +test( "mouse", function() { + // TODO: These tests use the old getDate() and setDate() methods. Re-activate these + // tests when those methods are available. + expect( 0 ); + return; + expect( 15 ); var inl, - inp = TestHelpers.datepicker.init("#inp"), - dp = $("#ui-datepicker-div"), + inp = TestHelpers.datepicker.init( "#inp" ), + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ), date = new Date(); - inp.val("").datepicker("show"); - $(".ui-datepicker-calendar tbody a:contains(10)", dp).simulate("click", {}); - date.setDate(10); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Mouse click"); - inp.val("02/04/2008").datepicker("show"); - $(".ui-datepicker-calendar tbody a:contains(12)", dp).simulate("click", {}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 12), - "Mouse click - preset"); - inp.val("02/04/2008").datepicker("show"); - inp.val("").datepicker("show"); - $("button.ui-datepicker-close", dp).simulate("click", {}); - ok(inp.datepicker("getDate") == null, "Mouse click - close"); - inp.val("02/04/2008").datepicker("show"); - $("button.ui-datepicker-close", dp).simulate("click", {}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Mouse click - close + preset"); - inp.val("02/04/2008").datepicker("show"); - $("a.ui-datepicker-prev", dp).simulate("click", {}); - $("button.ui-datepicker-close", dp).simulate("click", {}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Mouse click - abandoned"); + + inp.val( "" ).datepicker( "open" ); + $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} ); + date.setDate( 10 ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Mouse click" ); + + inp.val( "02/04/2008" ).datepicker( "open" ); + $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} ); + TestHelpers.datepicker.equalsDate( inp.datepicker("getDate"), new Date( 2008, 2 - 1, 12 ), + "Mouse click - preset") ; + + inp.val( "02/04/2008" ).datepicker( "open" ); + inp.val( "").datepicker( "open" ); + $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); + ok( inp.datepicker( "getDate" ) == null, "Mouse click - close" ); + inp.val( "02/04/2008" ).datepicker( "open" ); + $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + "Mouse click - close + preset" ); + + inp.val( "02/04/2008" ).datepicker( "open" ); + $( "a.ui-datepicker-prev", dp ).simulate( "click", {} ); + $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + "Mouse click - abandoned" ); + // Current/previous/next - inp.val("02/04/2008").datepicker("option", {showButtonPanel: true}).datepicker("show"); - $(".ui-datepicker-current", dp).simulate("click", {}); - $(".ui-datepicker-calendar tbody a:contains(14)", dp).simulate("click", {}); - date.setDate(14); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Mouse click - current"); - inp.val("02/04/2008").datepicker("show"); - $(".ui-datepicker-prev", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click"); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 1 - 1, 16), - "Mouse click - previous"); - inp.val("02/04/2008").datepicker("show"); - $(".ui-datepicker-next", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click"); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 3 - 1, 18), - "Mouse click - next"); + inp.val( "02/04/2008" ).datepicker( "option", { showButtonPanel: true }).datepicker( "open" ); + $( ".ui-datepicker-current", dp ).simulate( "click", {} ); + $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} ); + date.setDate( 14 ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Mouse click - current" ); + + inp.val( "02/04/2008" ).datepicker( "open" ); + $( ".ui-datepicker-prev", dp ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ), + "Mouse click - previous" ); + + inp.val( "02/04/2008" ).datepicker( "open" ); + $(".ui-datepicker-next", dp ).simulate( "click" ); + $(".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); + TestHelpers.datepicker.equalsDate( inp.datepicker("getDate"), new Date( 2008, 3 - 1, 18 ), + "Mouse click - next" ); + // Previous/next with minimum/maximum - inp.datepicker("option", {minDate: new Date(2008, 2 - 1, 2), - maxDate: new Date(2008, 2 - 1, 26)}).val("02/04/2008").datepicker("show"); - $(".ui-datepicker-prev", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click"); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 16), - "Mouse click - previous + min/max"); - inp.val("02/04/2008").datepicker("show"); - $(".ui-datepicker-next", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click"); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 18), - "Mouse click - next + min/max"); + inp.datepicker("option", { + minDate: new Date( 2008, 2 - 1, 2 ), + maxDate: new Date( 2008, 2 - 1, 26 ) + }).val( "02/04/2008" ).datepicker( "open" ); + $( ".ui-datepicker-prev", dp ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 16 ), + "Mouse click - previous + min/max" ); + + inp.val( "02/04/2008" ).datepicker( "open" ); + $( ".ui-datepicker-next", dp ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 18 ), + "Mouse click - next + min/max" ); + // Inline - inl = TestHelpers.datepicker.init("#inl"); - dp = $(".ui-datepicker-inline", inl); + inl = TestHelpers.datepicker.init( "#inl" ); + dp = $( ".ui-datepicker-inline", inl ); date = new Date(); - inl.datepicker("setDate", date); - $(".ui-datepicker-calendar tbody a:contains(10)", dp).simulate("click", {}); - date.setDate(10); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), date, "Mouse click inline"); - inl.datepicker("option", {showButtonPanel: true}).datepicker("setDate", new Date(2008, 2 - 1, 4)); - $(".ui-datepicker-calendar tbody a:contains(12)", dp).simulate("click", {}); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), new Date(2008, 2 - 1, 12), "Mouse click inline - preset"); - inl.datepicker("option", {showButtonPanel: true}); - $(".ui-datepicker-current", dp).simulate("click", {}); - $(".ui-datepicker-calendar tbody a:contains(14)", dp).simulate("click", {}); - date.setDate(14); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), date, "Mouse click inline - current"); - inl.datepicker("setDate", new Date(2008, 2 - 1, 4)); - $(".ui-datepicker-prev", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click"); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), new Date(2008, 1 - 1, 16), - "Mouse click inline - previous"); - inl.datepicker("setDate", new Date(2008, 2 - 1, 4)); - $(".ui-datepicker-next", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click"); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), new Date(2008, 3 - 1, 18), - "Mouse click inline - next"); + inl.datepicker( "setDate", date ); + $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} ); + date.setDate( 10 ); + TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), date, "Mouse click inline" ); + + inl.datepicker( "option", { showButtonPanel: true }) + .datepicker( "setDate", new Date( 2008, 2 - 1, 4 )); + $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} ); + TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), new Date( 2008, 2 - 1, 12 ), + "Mouse click inline - preset" ); + + inl.datepicker("option", { showButtonPanel: true }); + $( ".ui-datepicker-current", dp ).simulate( "click", {} ); + $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} ); + date.setDate( 14 ); + TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), date, "Mouse click inline - current" ); + + inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4) ); + $( ".ui-datepicker-prev", dp ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); + TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ), + "Mouse click inline - previous" ); + + inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4) ); + $( ".ui-datepicker-next", dp ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); + TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), new Date( 2008, 3 - 1, 18 ), + "Mouse click inline - next" ); }); })(jQuery); From f79cc9e6701269da1ff7477df25de4798ed9d49d Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Tue, 5 Nov 2013 08:59:07 -0500 Subject: [PATCH 021/172] Datepicker: Commenting out event tests with TODOs for now. --- tests/unit/datepicker/datepicker_events.js | 40 ++++++---------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index dfc42ccf911..a9ef4253720 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -1,10 +1,13 @@ -/* - * datepicker_events.js - */ -(function($) { +(function( $ ) { -module("datepicker: events"); +module( "datepicker: events" ); +// The implement of events is completely changing therefore these tests are no longer directly +// relevant. Leaving them around commented out so we can ensure the functionality is replicated. +// For example: +// TODO: In the old implementation the Enter key select's today's date when the has +// focus and is empty. Do we want to replicate this behavior in the rewrite? +/* var selectedThis = null, selectedDate = null, selectedInst = null; @@ -125,29 +128,6 @@ test("events", function() { inp.datepicker("show"); equal(selectedThis, inp2[0], "Callback close this"); }); +*/ -test("beforeShowDay-getDate", function() { - expect( 3 ); - var inp = TestHelpers.datepicker.init("#inp", {beforeShowDay: function() { inp.datepicker("getDate"); return [true, ""]; }}), - dp = $("#ui-datepicker-div"); - inp.val("01/01/2010").datepicker("show"); - // contains non-breaking space - equal($("div.ui-datepicker-title").text(), - // support: IE <9, jQuery <1.8 - // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways - $( "January 2010" ).text(), "Initial month"); - $("a.ui-datepicker-next", dp).click(); - $("a.ui-datepicker-next", dp).click(); - // contains non-breaking space - equal($("div.ui-datepicker-title").text(), - $( "March 2010" ).text(), "After next clicks"); - inp.datepicker("hide").datepicker("show"); - $("a.ui-datepicker-prev", dp).click(); - $("a.ui-datepicker-prev", dp).click(); - // contains non-breaking space - equal($("div.ui-datepicker-title").text(), - $( "November 2009" ).text(), "After prev clicks"); - inp.datepicker("hide"); -}); - -})(jQuery); +})( jQuery ); From 97ad9ca22bc3210b2b35e731f50e13f538d0e98c Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 6 Nov 2013 08:39:32 -0500 Subject: [PATCH 022/172] Datepicker: Adding boilerplate for events in new API. --- tests/unit/datepicker/datepicker_events.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index a9ef4253720..63e2b0e9cc7 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -2,6 +2,22 @@ module( "datepicker: events" ); +test( "beforeOpen", function() { + expect( 0 ); +}); + +test( "close", function() { + expect( 0 ); +}); + +test( "open", function() { + expect( 0 ); +}); + +test( "select", function() { + expect( 0 ); +}); + // The implement of events is completely changing therefore these tests are no longer directly // relevant. Leaving them around commented out so we can ensure the functionality is replicated. // For example: From 45c126d3609180734351b5c42b8738258b59b69f Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 6 Nov 2013 08:39:51 -0500 Subject: [PATCH 023/172] Datepicker: Updating tests for the destroy() method. --- tests/unit/datepicker/datepicker_methods.js | 80 ++++++--------------- 1 file changed, 22 insertions(+), 58 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index e52e126d2e6..dd9ddd519c6 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -1,66 +1,30 @@ /* * datepicker_methods.js */ -(function($) { +(function( $ ) { -module("datepicker: methods"); +module( "datepicker: methods" ); -test("destroy", function() { - expect( 33 ); +test( "destroy", function() { + expect( 9 ); var inl, - inp = TestHelpers.datepicker.init("#inp"); - ok(inp.is(".hasDatepicker"), "Default - marker class set"); - ok($.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Default - instance present"); - ok(inp.next().is("#alt"), "Default - button absent"); - inp.datepicker("destroy"); - inp = $("#inp"); - ok(!inp.is(".hasDatepicker"), "Default - marker class cleared"); - ok(!$.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Default - instance absent"); - ok(inp.next().is("#alt"), "Default - button absent"); - // With button - inp= TestHelpers.datepicker.init("#inp", {showOn: "both"}); - ok(inp.is(".hasDatepicker"), "Button - marker class set"); - ok($.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Button - instance present"); - ok(inp.next().text() === "...", "Button - button added"); - inp.datepicker("destroy"); - inp = $("#inp"); - ok(!inp.is(".hasDatepicker"), "Button - marker class cleared"); - ok(!$.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Button - instance absent"); - ok(inp.next().is("#alt"), "Button - button removed"); - // With append text - inp = TestHelpers.datepicker.init("#inp", {appendText: "Testing"}); - ok(inp.is(".hasDatepicker"), "Append - marker class set"); - ok($.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Append - instance present"); - ok(inp.next().text() === "Testing", "Append - append text added"); - inp.datepicker("destroy"); - inp = $("#inp"); - ok(!inp.is(".hasDatepicker"), "Append - marker class cleared"); - ok(!$.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Append - instance absent"); - ok(inp.next().is("#alt"), "Append - append text removed"); - // With both - inp= TestHelpers.datepicker.init("#inp", {showOn: "both", buttonImageOnly: true, - buttonImage: "images/calendar.gif", appendText: "Testing"}); - ok(inp.is(".hasDatepicker"), "Both - marker class set"); - ok($.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Both - instance present"); - ok(inp.next()[0].nodeName.toLowerCase() === "img", "Both - button added"); - ok(inp.next().next().text() === "Testing", "Both - append text added"); - inp.datepicker("destroy"); - inp = $("#inp"); - ok(!inp.is(".hasDatepicker"), "Both - marker class cleared"); - ok(!$.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Both - instance absent"); - ok(inp.next().is("#alt"), "Both - button and append text absent"); - // Inline - inl = TestHelpers.datepicker.init("#inl"); - ok(inl.is(".hasDatepicker"), "Inline - marker class set"); - ok(inl.html() !== "", "Inline - datepicker present"); - ok($.data(inl[0], TestHelpers.datepicker.PROP_NAME), "Inline - instance present"); - ok(inl.next().length === 0 || inl.next().is("p"), "Inline - button absent"); - inl.datepicker("destroy"); - inl = $("#inl"); - ok(!inl.is(".hasDatepicker"), "Inline - marker class cleared"); - ok(inl.html() === "", "Inline - datepicker absent"); - ok(!$.data(inl[0], TestHelpers.datepicker.PROP_NAME), "Inline - instance absent"); - ok(inl.next().length === 0 || inl.next().is("p"), "Inline - button absent"); + inp = TestHelpers.datepicker.init( "#inp" ); + + ok( inp.datepicker( "instance" ), "instance created" ); + ok( inp.attr( "aria-owns" ), "aria-owns attribute added" ); + ok( inp.attr( "aria-haspopup" ), "aria-haspopup attribute added" ); + inp.datepicker( "destroy" ); + ok( !inp.datepicker( "instance" ), "instance removed" ); + ok( !inp.attr( "aria-owns" ), "aria-owns attribute removed" ); + ok( !inp.attr( "aria-haspopup" ), "aria-haspopup attribute removed" ); + + inl = TestHelpers.datepicker.init( "#inl" ); + ok( inl.datepicker( "instance" ), "instance created" ); + ok( inl.children().length > 0, "inline datepicker has children" ); + inl.datepicker( "destroy" ); + ok( !inl.datepicker( "instance" ), "instance removed" ); + // TODO: Destroying inline datepickers currently does not work. + // ok( inl.children().length === 0, "inline picker no longer has children" ); }); test("enableDisable", function() { @@ -122,4 +86,4 @@ test("enableDisable", function() { inl.datepicker("destroy"); }); -})(jQuery); +})( jQuery ); From c68d3e538f5770580de6b8298b2f6b36e30e239d Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 6 Nov 2013 08:54:19 -0500 Subject: [PATCH 024/172] Datepicker: Updating enable()/disable() tests. --- tests/unit/datepicker/datepicker_methods.js | 82 ++++++--------------- 1 file changed, 23 insertions(+), 59 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index dd9ddd519c6..bfe32b459b5 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -1,6 +1,3 @@ -/* - * datepicker_methods.js - */ (function( $ ) { module( "datepicker: methods" ); @@ -27,63 +24,30 @@ test( "destroy", function() { // ok( inl.children().length === 0, "inline picker no longer has children" ); }); -test("enableDisable", function() { - expect( 33 ); - var inl, dp, - inp = TestHelpers.datepicker.init("#inp"); - ok(!inp.datepicker("isDisabled"), "Enable/disable - initially marked as enabled"); - ok(!inp[0].disabled, "Enable/disable - field initially enabled"); - inp.datepicker("disable"); - ok(inp.datepicker("isDisabled"), "Enable/disable - now marked as disabled"); - ok(inp[0].disabled, "Enable/disable - field now disabled"); - inp.datepicker("enable"); - ok(!inp.datepicker("isDisabled"), "Enable/disable - now marked as enabled"); - ok(!inp[0].disabled, "Enable/disable - field now enabled"); - inp.datepicker("destroy"); - // With a button - inp = TestHelpers.datepicker.init("#inp", {showOn: "button"}); - ok(!inp.datepicker("isDisabled"), "Enable/disable button - initially marked as enabled"); - ok(!inp[0].disabled, "Enable/disable button - field initially enabled"); - ok(!inp.next("button")[0].disabled, "Enable/disable button - button initially enabled"); - inp.datepicker("disable"); - ok(inp.datepicker("isDisabled"), "Enable/disable button - now marked as disabled"); - ok(inp[0].disabled, "Enable/disable button - field now disabled"); - ok(inp.next("button")[0].disabled, "Enable/disable button - button now disabled"); - inp.datepicker("enable"); - ok(!inp.datepicker("isDisabled"), "Enable/disable button - now marked as enabled"); - ok(!inp[0].disabled, "Enable/disable button - field now enabled"); - ok(!inp.next("button")[0].disabled, "Enable/disable button - button now enabled"); - inp.datepicker("destroy"); - // With an image button - inp = TestHelpers.datepicker.init("#inp", {showOn: "button", buttonImageOnly: true, - buttonImage: "images/calendar.gif"}); - ok(!inp.datepicker("isDisabled"), "Enable/disable image - initially marked as enabled"); - ok(!inp[0].disabled, "Enable/disable image - field initially enabled"); - ok(parseFloat(inp.next("img").css("opacity")) === 1, "Enable/disable image - image initially enabled"); - inp.datepicker("disable"); - ok(inp.datepicker("isDisabled"), "Enable/disable image - now marked as disabled"); - ok(inp[0].disabled, "Enable/disable image - field now disabled"); - ok(parseFloat(inp.next("img").css("opacity")) !== 1, "Enable/disable image - image now disabled"); - inp.datepicker("enable"); - ok(!inp.datepicker("isDisabled"), "Enable/disable image - now marked as enabled"); - ok(!inp[0].disabled, "Enable/disable image - field now enabled"); - ok(parseFloat(inp.next("img").css("opacity")) === 1, "Enable/disable image - image now enabled"); - inp.datepicker("destroy"); +test( "enable / disable", function() { + expect( 6 ); + var inl, + inp = TestHelpers.datepicker.init( "#inp" ), + dp = inp.datepicker( "widget" ); + + ok( !inp.datepicker( "option", "disabled" ), "initially enabled" ); + ok( !dp.hasClass( "ui-datepicker-disabled" ), "does not have disabled class name" ); + + inp.datepicker( "disable" ); + ok( inp.datepicker( "option", "disabled" ), "disabled option is set" ); + ok( dp.hasClass( "ui-datepicker-disabled" ), "datepicker has disabled class name" ); + + inp.datepicker( "enable" ); + ok( !inp.datepicker( "option", "disabled" ), "enabled after enable() call" ); + ok( !dp.hasClass( "ui-datepicker-disabled" ), "no longer has disabled class name" ); + // Inline - inl = TestHelpers.datepicker.init("#inl", {changeYear: true}); - dp = $(".ui-datepicker-inline", inl); - ok(!inl.datepicker("isDisabled"), "Enable/disable inline - initially marked as enabled"); - ok(!dp.children().is(".ui-state-disabled"), "Enable/disable inline - not visually disabled initially"); - ok(!dp.find("select").prop("disabled"), "Enable/disable inline - form element enabled initially"); - inl.datepicker("disable"); - ok(inl.datepicker("isDisabled"), "Enable/disable inline - now marked as disabled"); - ok(dp.children().is(".ui-state-disabled"), "Enable/disable inline - visually disabled"); - ok(dp.find("select").prop("disabled"), "Enable/disable inline - form element disabled"); - inl.datepicker("enable"); - ok(!inl.datepicker("isDisabled"), "Enable/disable inline - now marked as enabled"); - ok(!dp.children().is(".ui-state-disabled"), "Enable/disable inline - not visiually disabled"); - ok(!dp.find("select").prop("disabled"), "Enable/disable inline - form element enabled"); - inl.datepicker("destroy"); + inl = TestHelpers.datepicker.init( "#inl" ); + dp = inl.datepicker( "instance" ); + + // TODO: Disabling inline pickers does not work. + // TODO: When changeMonth and changeYear options are implemented ensure their dropdowns + // are properly disabled when in an inline picker. }); })( jQuery ); From 678214073c19c0445b76091572e0e3d8cfbaf73a Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 6 Nov 2013 08:58:11 -0500 Subject: [PATCH 025/172] Datepicker: Boilerplate for other method tests. Moving widget() method test from core.js as it makes more sense in methods.js. --- tests/unit/datepicker/datepicker_core.js | 15 --------------- tests/unit/datepicker/datepicker_methods.js | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index a7a47f0d646..a10f5386202 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -8,21 +8,6 @@ module("datepicker: core"); TestHelpers.testJshint( "datepicker" ); -test( "widget method - empty collection", function() { - expect( 1 ); - - // should create nothing - $( "#nonExist" ).datepicker(); - ok( !$( "#ui-datepicker-div" ).length, "Non init on empty collection" ); -}); - -test( "widget method", function() { - expect( 1 ); - var actual = $( "#inp" ).datepicker().datepicker( "widget" ); - deepEqual( $("body > .ui-front" )[ 0 ], actual[ 0 ] ); - actual.remove(); -}); - asyncTest( "baseStructure", function() { expect( 42 ); var header, title, table, thead, week, panel, inl, child, diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index bfe32b459b5..7cbc8de1634 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -50,4 +50,23 @@ test( "enable / disable", function() { // are properly disabled when in an inline picker. }); +test( "widget", function() { + expect( 1 ); + var actual = $( "#inp" ).datepicker().datepicker( "widget" ); + deepEqual( $("body > .ui-front" )[ 0 ], actual[ 0 ] ); + actual.remove(); +}); + +test( "close", function() { + expect( 0 ); +}); + +test( "open", function() { + expect( 0 ); +}); + +test( "value", function() { + expect( 0 ); +}); + })( jQuery ); From 0f6d4e29a61faf31b88727caae827466706dbd1c Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 13 Nov 2013 12:45:25 -0500 Subject: [PATCH 026/172] Datepicker: Commenting out the options tests for now as they are almost all irrelevant now. --- tests/unit/datepicker/datepicker_options.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 25257e99faf..600a1b1fb0d 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -1,11 +1,8 @@ -/* - * datepicker_options.js - */ - -(function($) { +(function( $ ) { -module("datepicker: options"); +module( "datepicker: options" ); +/* test("setDefaults", function() { expect( 3 ); TestHelpers.datepicker.init("#inp"); @@ -1109,5 +1106,6 @@ test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler equal( dp.css( "display" ), "none","beforeShow returns false" ); inp.datepicker( "destroy" ); }); +*/ })(jQuery); From d32a4828dcf28933d1f663bb48c1749515b405bf Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 15 Nov 2013 08:18:56 -0500 Subject: [PATCH 027/172] Datepicker: Saner id attribute values for the test suite. --- tests/unit/datepicker/datepicker.html | 6 ++++-- tests/unit/datepicker/datepicker_core.js | 10 +++++----- tests/unit/datepicker/datepicker_methods.js | 10 +++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 119926ce174..7b4cea7d28b 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -44,8 +44,10 @@

        -
        -

        + + + +
        diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index a10f5386202..f7dcd49c79d 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -158,7 +158,7 @@ asyncTest( "baseStructure", function() { function step6() { // Inline - inl = TestHelpers.datepicker.init( "#inl" ); + inl = TestHelpers.datepicker.init( "#inline" ); dp = inl.children(); ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" ); @@ -185,7 +185,7 @@ asyncTest( "baseStructure", function() { function step7() { // Inline multi-month - inl = TestHelpers.datepicker.init( "#inl", { numberOfMonths: 2 } ); + inl = TestHelpers.datepicker.init( "#inline", { numberOfMonths: 2 } ); dp = inl.datepicker( "widget" ).find( ".ui-datepicker" ); ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" ); @@ -319,7 +319,7 @@ test( "Keyboard handling", function() { return; expect( 24 ); - var inp = TestHelpers.datepicker.init( "#inp" ), + var inp = TestHelpers.datepicker.init( "#datepicker" ), date = new Date(); inp.val( "" ).datepicker( "open" ) @@ -486,7 +486,7 @@ test( "mouse", function() { expect( 15 ); var inl, - inp = TestHelpers.datepicker.init( "#inp" ), + inp = TestHelpers.datepicker.init( "#datepicker" ), dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ), date = new Date(); @@ -551,7 +551,7 @@ test( "mouse", function() { "Mouse click - next + min/max" ); // Inline - inl = TestHelpers.datepicker.init( "#inl" ); + inl = TestHelpers.datepicker.init( "#inline" ); dp = $( ".ui-datepicker-inline", inl ); date = new Date(); inl.datepicker( "setDate", date ); diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 7cbc8de1634..e00f886444e 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -5,7 +5,7 @@ module( "datepicker: methods" ); test( "destroy", function() { expect( 9 ); var inl, - inp = TestHelpers.datepicker.init( "#inp" ); + inp = TestHelpers.datepicker.init( "#datepicker" ); ok( inp.datepicker( "instance" ), "instance created" ); ok( inp.attr( "aria-owns" ), "aria-owns attribute added" ); @@ -15,7 +15,7 @@ test( "destroy", function() { ok( !inp.attr( "aria-owns" ), "aria-owns attribute removed" ); ok( !inp.attr( "aria-haspopup" ), "aria-haspopup attribute removed" ); - inl = TestHelpers.datepicker.init( "#inl" ); + inl = TestHelpers.datepicker.init( "#inline" ); ok( inl.datepicker( "instance" ), "instance created" ); ok( inl.children().length > 0, "inline datepicker has children" ); inl.datepicker( "destroy" ); @@ -27,7 +27,7 @@ test( "destroy", function() { test( "enable / disable", function() { expect( 6 ); var inl, - inp = TestHelpers.datepicker.init( "#inp" ), + inp = TestHelpers.datepicker.init( "#datepicker" ), dp = inp.datepicker( "widget" ); ok( !inp.datepicker( "option", "disabled" ), "initially enabled" ); @@ -42,7 +42,7 @@ test( "enable / disable", function() { ok( !dp.hasClass( "ui-datepicker-disabled" ), "no longer has disabled class name" ); // Inline - inl = TestHelpers.datepicker.init( "#inl" ); + inl = TestHelpers.datepicker.init( "#inline" ); dp = inl.datepicker( "instance" ); // TODO: Disabling inline pickers does not work. @@ -52,7 +52,7 @@ test( "enable / disable", function() { test( "widget", function() { expect( 1 ); - var actual = $( "#inp" ).datepicker().datepicker( "widget" ); + var actual = $( "#datepicker" ).datepicker().datepicker( "widget" ); deepEqual( $("body > .ui-front" )[ 0 ], actual[ 0 ] ); actual.remove(); }); From 1074fdd942b193f06926d7d054f3a9e098012822 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 15 Nov 2013 08:42:20 -0500 Subject: [PATCH 028/172] Datepicker: Support changing the appendTo option after init. Adding tests for the appendTo option. --- tests/unit/datepicker/datepicker_options.js | 38 +++++++++++++++++++++ ui/jquery.ui.datepicker.js | 7 ++++ 2 files changed, 45 insertions(+) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 600a1b1fb0d..60c9042dd0d 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -2,6 +2,44 @@ module( "datepicker: options" ); +test( "appendTo", function() { + expect( 6 ); + var container, + detached = $( "
        " ), + input = $( "#datepicker" ); + + input.datepicker(); + container = input.datepicker( "widget" ).parent()[ 0 ]; + equal( container, document.body, "defaults to body" ); + input.datepicker( "destroy" ); + + input.datepicker({ appendTo: "#qunit-fixture" }); + container = input.datepicker( "widget" ).parent()[ 0 ]; + equal( container, $( "#qunit-fixture" )[ 0 ], "child of specified element" ); + input.datepicker( "destroy" ); + + input.datepicker({ appendTo: "#does-not-exist" }); + container = input.datepicker( "widget" ).parent()[ 0 ]; + equal( container, document.body, "set to body if element does not exist" ); + input.datepicker( "destroy" ); + + input.datepicker() + .datepicker( "option", "appendTo", "#qunit-fixture" ); + container = input.datepicker( "widget" ).parent()[ 0 ]; + equal( container, $( "#qunit-fixture" )[ 0 ], "modified after init" ); + input.datepicker( "destroy" ); + + input.datepicker({ appendTo: detached }); + container = input.datepicker( "widget" ).parent()[ 0 ]; + equal( container, detached[ 0 ], "detached jQuery object" ); + input.datepicker( "destroy" ); + + input.datepicker({ appendTo: detached[ 0 ] }); + container = input.datepicker( "widget" ).parent()[ 0 ]; + equal( container, detached[ 0 ], "detached DOM element" ); + input.datepicker( "destroy" ); +}); + /* test("setDefaults", function() { expect( 3 ); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 2b9a8b031f1..4c77cf1373b 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -603,6 +603,13 @@ $.widget( "ui.datepicker", { }, widget: function() { return this.picker; + }, + _setOption: function( key, value ) { + this._super( key, value ); + + if ( key === "appendTo" ) { + this.picker.appendTo( this._appendTo() ); + } } }); From 601bf92d677a56f635c1839c285d05637e088a9e Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 15 Nov 2013 08:47:04 -0500 Subject: [PATCH 029/172] Datepicker: Boilerplate for tests for additional implemented options. --- tests/unit/datepicker/datepicker_options.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 60c9042dd0d..c4aefbd2c58 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -40,6 +40,26 @@ test( "appendTo", function() { input.datepicker( "destroy" ); }); +test( "dateFormat", function() { + expect( 0 ); +}); + +test( "eachDay", function() { + expect( 0 ); +}); + +test( "numberOfMonths", function() { + expect( 0 ); +}); + +test( "position", function() { + expect( 0 ); +}); + +test( "showWeek", function() { + expect( 0 ); +}); + /* test("setDefaults", function() { expect( 3 ); From 488665afc4a825a89a3c1681b97cb89b0c3c5593 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 15 Nov 2013 09:17:13 -0500 Subject: [PATCH 030/172] Datepicker: Various changes for the showWeek option. * Re-add ui-datepicker-week-col class name currently used. * Add test suite. * Support changing option after initialization. --- tests/unit/datepicker/datepicker_options.js | 24 ++++++++++++++++++++- ui/jquery.ui.datepicker.js | 8 +++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index c4aefbd2c58..a698301b59b 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -57,7 +57,29 @@ test( "position", function() { }); test( "showWeek", function() { - expect( 0 ); + expect( 7 ); + var input = $( "#datepicker" ).datepicker(), + container = input.datepicker( "widget" ); + + equal( container.find( "thead th" ).length, 7, "just 7 days, no column cell" ); + equal( container.find( ".ui-datepicker-week-col" ).length, 0, + "no week column cells present" ); + input.datepicker( "destroy" ); + + input = $( "#datepicker" ).datepicker({ showWeek: true }); + container = input.datepicker( "widget" ); + equal( container.find( "thead th" ).length, 8, "7 days + a column cell" ); + ok( container.find( "thead th:first" ).is( ".ui-datepicker-week-col" ), + "first cell should have ui-datepicker-week-col class name" ); + equal( container.find( ".ui-datepicker-week-col" ).length, + container.find( "tr" ).length, "one week cell for each week" ); + input.datepicker( "destroy" ); + + input = $( "#datepicker" ).datepicker(); + container = input.datepicker( "widget" ); + equal( container.find( "thead th" ).length, 7, "no week column" ); + input.datepicker( "option", "showWeek", true ); + equal( container.find( "thead th" ).length, 8, "supports changing option after init" ); }); /* diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 4c77cf1373b..c8989e2959a 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -391,7 +391,7 @@ $.widget( "ui.datepicker", { labels = Globalize.localize( "datepicker" ); if ( this.options.showWeek ) { - cells += "" + labels.weekHeader + ""; + cells += "" + labels.weekHeader + ""; } for ( i; i < this.date.weekdays().length; i++ ) { cells += this._buildGridHeaderCell( this.date.weekdays()[i] ); @@ -420,7 +420,7 @@ $.widget( "ui.datepicker", { i = 0; if ( this.options.showWeek ) { - cells += "" + week.number + ""; + cells += "" + week.number + ""; } for ( i; i < week.days.length; i++ ) { cells += this._buildDayCell( week.days[i] ); @@ -610,6 +610,10 @@ $.widget( "ui.datepicker", { if ( key === "appendTo" ) { this.picker.appendTo( this._appendTo() ); } + + if ( key === "showWeek" ) { + this.refresh(); + } } }); From 25ac26083889a63f7a8d084c216ad628989d5785 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Mon, 18 Nov 2013 09:23:15 -0500 Subject: [PATCH 031/172] Datepicker: Support position option changes after init. Added position option tests. --- tests/unit/datepicker/datepicker_options.js | 28 +++++++++++++++++++-- ui/jquery.ui.datepicker.js | 15 +++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index a698301b59b..e6cce915245 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -52,8 +52,32 @@ test( "numberOfMonths", function() { expect( 0 ); }); -test( "position", function() { - expect( 0 ); +asyncTest( "position", function() { + expect( 3 ); + var input = $( "input" ).datepicker().appendTo( "body" ).css({ + position: "absolute", + top: 0, + left: 0 + }), + container = input.datepicker( "widget" ); + + input.datepicker( "open" ); + setTimeout(function() { + closeEnough( input.offset().left, container.offset().left, 1, "left sides line up by default" ); + closeEnough( container.offset().top, input.offset().top + input.outerHeight(), 1, + "datepicker directly under input by default" ); + + // Change the position option using option() + input.datepicker( "option", "position", { + my: "left top", + at: "right bottom" + }); + closeEnough( container.offset().left, input.offset().left + input.outerWidth(), 1, + "datepicker on right hand side of input after position change" ); + + input.remove(); + start(); + }); }); test( "showWeek", function() { diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index c8989e2959a..accf2f06607 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -542,15 +542,11 @@ $.widget( "ui.datepicker", { this.date.select(); this.refresh(); - var position = $.extend( {}, { - of: this.element - }, this.options.position ); - this.picker .attr( "aria-hidden", "false" ) .attr( "aria-expanded", "true" ) .show() - .position( position ) + .position( this._buildPosition() ) .hide(); this._show( this.picker, this.options.show ); @@ -580,6 +576,11 @@ $.widget( "ui.datepicker", { .attr( "aria-hidden", "true" ) .attr( "aria-expanded", "false" ); }, + _buildPosition: function() { + return $.extend( {}, { + of: this.element + }, this.options.position ); + }, select: function( event, time ) { this.date.setTime( time ).select(); this.refresh(); @@ -614,6 +615,10 @@ $.widget( "ui.datepicker", { if ( key === "showWeek" ) { this.refresh(); } + + if ( key === "position" ) { + this.picker.position( this._buildPosition() ); + } } }); From 6da407b7b7066e2c6b15c6e55039d39ae4d54529 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Tue, 19 Nov 2013 08:08:18 -0500 Subject: [PATCH 032/172] Datepicker: Position tests should create a new . --- tests/unit/datepicker/datepicker_options.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index e6cce915245..f638060f3cc 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -54,7 +54,7 @@ test( "numberOfMonths", function() { asyncTest( "position", function() { expect( 3 ); - var input = $( "input" ).datepicker().appendTo( "body" ).css({ + var input = $( "" ).datepicker().appendTo( "body" ).css({ position: "absolute", top: 0, left: 0 From 6e366706953e2d2fdc56f35cede6222221fe6b9b Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Tue, 19 Nov 2013 08:35:19 -0500 Subject: [PATCH 033/172] Datepicker: Support changing eachDay after initialization. Add tests for eachDay. --- tests/unit/datepicker/datepicker_options.js | 38 ++++++++++++++++++++- ui/jquery.ui.datepicker.js | 5 +++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index f638060f3cc..6c8c8227f4a 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -45,7 +45,43 @@ test( "dateFormat", function() { }); test( "eachDay", function() { - expect( 0 ); + expect( 5 ); + var timestamp, + input = $( "#datepicker" ).datepicker(), + picker = input.datepicker( "widget" ); + firstCell = picker.find( "td[id]:first" ); + + equal( firstCell.find( "a" ).length, 1, "days are selectable by default" ); + timestamp = parseInt( firstCell.find( "a" ).attr( "data-timestamp" ), 10 ); + equal( new Date( timestamp ).getDate(), 1, "first available day is the 1st by default" ); + + // Do not render the 1st of the month + input.datepicker( "option", "eachDay", function( day ) { + if ( day.date === 1 ) { + day.render = false; + } + }); + firstCell = picker.find( "td[id]:first" ); + timestamp = parseInt( firstCell.find( "a" ).attr( "data-timestamp" ), 10 ); + equal( new Date( timestamp ).getDate(), 2, "first available day is the 2nd" ); + + // Display the 1st of the month but make it not selectable. + input.datepicker( "option", "eachDay", function( day ) { + if ( day.date === 1 ) { + day.selectable = false; + } + }); + firstCell = picker.find( "td[id]:first" ); + equal( firstCell.find( "a" ).length, 0, "the 1st is not selectable" ); + + input.datepicker( "option", "eachDay", function( day ) { + if ( day.date === 1 ) { + day.extraClasses = "ui-custom"; + } + }); + ok( picker.find( "td[id]:first a" ).hasClass( "ui-custom" ), "extraClasses applied" ); + + input.datepicker( "destroy" ); }); test( "numberOfMonths", function() { diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index accf2f06607..9725047ca4a 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -612,6 +612,11 @@ $.widget( "ui.datepicker", { this.picker.appendTo( this._appendTo() ); } + if ( key === "eachDay" ) { + this.date.eachDay = this.options.eachDay; + this.refresh(); + } + if ( key === "showWeek" ) { this.refresh(); } From dfad85fd801ba02efd7e9c0025dbb7628898bd15 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 20 Nov 2013 08:37:24 -0500 Subject: [PATCH 034/172] Datepicker: Allow dateFormat to be changed after init. Add dateFormat tests. --- tests/unit/datepicker/datepicker_options.js | 14 +++++++++++++- ui/jquery.ui.datepicker.js | 7 +++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 6c8c8227f4a..f712a543486 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -41,7 +41,19 @@ test( "appendTo", function() { }); test( "dateFormat", function() { - expect( 0 ); + expect( 2 ); + var input = $( "#datepicker" ).val( "1/1/2014" ).datepicker(), + picker = input.datepicker( "widget" ), + firstDayLink = picker.find( "td[id]:first a" ); + + input.datepicker( "open" ); + firstDayLink.trigger( "mousedown" ); + equal( input.val(), "1/1/2014", "default formatting" ); + + input.datepicker( "option", "dateFormat", "D" ); + equal( input.val(), "Wednesday, January 01, 2014", "updated formatting" ); + + input.datepicker( "destroy" ); }); test( "eachDay", function() { diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 9725047ca4a..fef69f4f4de 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -617,6 +617,13 @@ $.widget( "ui.datepicker", { this.refresh(); } + if ( key === "dateFormat" ) { + this.date.setFormat( this.options.dateFormat ); + if ( !this.inline ) { + this.element.val( this.date.format() ); + } + } + if ( key === "showWeek" ) { this.refresh(); } From f83adf889bbb1751a48a75bfe354c2d57c03114a Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 20 Nov 2013 08:53:02 -0500 Subject: [PATCH 035/172] Datepicker: Adding test to ensure the 's value is preselected in the picker. --- tests/unit/datepicker/datepicker_core.js | 25 +++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index f7dcd49c79d..bb216b18c24 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -1,13 +1,24 @@ -/* - * datepicker_core.js - */ +(function( $ ) { -(function($) { - -module("datepicker: core"); +module( "datepicker: core" ); TestHelpers.testJshint( "datepicker" ); +test( "input's value determines starting date", function() { + expect( 3 ); + + var input = $( "#datepicker" ).val( "1/1/2014" ).datepicker(), + picker = input.datepicker( "widget" ); + + input.datepicker( "open" ); + + equal( picker.find( ".ui-datepicker-month" ).html(), "January", "correct month displayed" ); + equal( picker.find( ".ui-datepicker-year" ).html(), "2014", "correct year displayed" ); + equal( picker.find( ".ui-state-focus" ).html(), "1", "correct day highlighted" ); + + input.val( "" ).datepicker( "destroy" ); +}); + asyncTest( "baseStructure", function() { expect( 42 ); var header, title, table, thead, week, panel, inl, child, @@ -584,4 +595,4 @@ test( "mouse", function() { "Mouse click inline - next" ); }); -})(jQuery); +})( jQuery ); From 83646f9da163caaa9fb99a31f09672d13156e354 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 21 Nov 2013 09:03:08 -0500 Subject: [PATCH 036/172] Datepicker: Implementing a value() method. --- tests/unit/datepicker/datepicker_methods.js | 16 +++++++++++++++- ui/jquery.ui.datepicker.js | 11 +++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index e00f886444e..b8990014b7b 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -66,7 +66,21 @@ test( "open", function() { }); test( "value", function() { - expect( 0 ); + expect( 3 ); + var input = $( "#datepicker" ).datepicker(), + picker = input.datepicker( "widget" ); + + input.datepicker( "value", "1/1/2014" ); + equal( input.val(), "1/1/2014", "input's value set" ); + ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + "first day marked as selected" ); + + equal( input.datepicker( "value" ), "1/1/2014", "getter" ); + + // TODO: Handle for invalid values. + // TODO: Add tests for inline pickers. + + input.datepicker( "destroy" ); }); })( jQuery ); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index fef69f4f4de..6646288ef2d 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -594,6 +594,17 @@ $.widget( "ui.datepicker", { date: this.date.format() }); }, + value: function( value ) { + if ( arguments.length ) { + this.date.setTime( value ).select(); + if ( !this.inline ) { + this.element.val( this.date.format() ); + } + this.refresh(); + } else { + return this.date.format(); + } + }, _destroy: function() { if ( !this.inline ) { this.picker.remove(); From b668db262942919ac4a5ce487783f8afcd250d83 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 21 Nov 2013 09:15:05 -0500 Subject: [PATCH 037/172] Datepicker: Implement a valueAsDate() method. --- tests/unit/datepicker/datepicker_methods.js | 19 +++++++++++++++++++ ui/jquery.ui.datepicker.js | 20 +++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index b8990014b7b..b8cf1efefea 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -83,4 +83,23 @@ test( "value", function() { input.datepicker( "destroy" ); }); +test( "valueAsDate", function() { + expect( 3 ); + var input = $( "#datepicker" ).datepicker(), + picker = input.datepicker( "widget" ); + + input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); + equal( input.val(), "1/1/2014", "input's value set" ); + ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + "first day marked as selected" ); + + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), + new Date( 2014, 0, 1 ), "getter" ); + + // TODO: Handle for invalid values. + // TODO: Add tests for inline pickers. + + input.datepicker( "destroy" ); +}); + })( jQuery ); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 6646288ef2d..f66ff33a0af 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -594,17 +594,27 @@ $.widget( "ui.datepicker", { date: this.date.format() }); }, + _value: function( value ) { + this.date.setTime( value ).select(); + if ( !this.inline ) { + this.element.val( this.date.format() ); + } + this.refresh(); + }, value: function( value ) { if ( arguments.length ) { - this.date.setTime( value ).select(); - if ( !this.inline ) { - this.element.val( this.date.format() ); - } - this.refresh(); + this._value( value ); } else { return this.date.format(); } }, + valueAsDate: function( value ) { + if ( arguments.length ) { + this._value( value ); + } else { + return this.date.date(); + } + }, _destroy: function() { if ( !this.inline ) { this.picker.remove(); From 560e704ba3b14e6be182c70d41776aa92b3a169c Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 22 Nov 2013 08:55:04 -0500 Subject: [PATCH 038/172] Datepicker: Support destroying inline datepickers. --- tests/unit/datepicker/datepicker_methods.js | 34 ++++++++++----------- ui/jquery.ui.datepicker.js | 4 ++- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index b8cf1efefea..3e411f285ac 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -3,25 +3,23 @@ module( "datepicker: methods" ); test( "destroy", function() { - expect( 9 ); - var inl, - inp = TestHelpers.datepicker.init( "#datepicker" ); - - ok( inp.datepicker( "instance" ), "instance created" ); - ok( inp.attr( "aria-owns" ), "aria-owns attribute added" ); - ok( inp.attr( "aria-haspopup" ), "aria-haspopup attribute added" ); - inp.datepicker( "destroy" ); - ok( !inp.datepicker( "instance" ), "instance removed" ); - ok( !inp.attr( "aria-owns" ), "aria-owns attribute removed" ); - ok( !inp.attr( "aria-haspopup" ), "aria-haspopup attribute removed" ); + expect( 10 ); + var input = $( "#datepicker" ).datepicker(), + inline = $( "#inline" ).datepicker(); - inl = TestHelpers.datepicker.init( "#inline" ); - ok( inl.datepicker( "instance" ), "instance created" ); - ok( inl.children().length > 0, "inline datepicker has children" ); - inl.datepicker( "destroy" ); - ok( !inl.datepicker( "instance" ), "instance removed" ); - // TODO: Destroying inline datepickers currently does not work. - // ok( inl.children().length === 0, "inline picker no longer has children" ); + ok( input.datepicker( "instance" ), "instance created" ); + ok( input.attr( "aria-owns" ), "aria-owns attribute added" ); + ok( input.attr( "aria-haspopup" ), "aria-haspopup attribute added" ); + input.datepicker( "destroy" ); + ok( !input.datepicker( "instance" ), "instance removed" ); + ok( !input.attr( "aria-owns" ), "aria-owns attribute removed" ); + ok( !input.attr( "aria-haspopup" ), "aria-haspopup attribute removed" ); + + ok( inline.datepicker( "instance" ), "instance created" ); + ok( inline.children().length > 0, "inline datepicker has children" ); + inline.datepicker( "destroy" ); + ok( !inline.datepicker( "instance" ), "instance removed" ); + ok( inline.children().length === 0, "inline picker no longer has children" ); }); test( "enable / disable", function() { diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index f66ff33a0af..9cc4a25c689 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -616,7 +616,9 @@ $.widget( "ui.datepicker", { } }, _destroy: function() { - if ( !this.inline ) { + if ( this.inline ) { + this.picker.empty(); + } else { this.picker.remove(); this.element .removeAttr( "aria-haspopup" ) From 44eb843ad17339dbaf0204d40a64223fcb8567e1 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 22 Nov 2013 09:02:16 -0500 Subject: [PATCH 039/172] Datepicker: Add tests for the value() and valueAsDate() methods and inline pickers. --- tests/unit/datepicker/datepicker_methods.js | 27 +++++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 3e411f285ac..dcd6dc2c7aa 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -64,40 +64,51 @@ test( "open", function() { }); test( "value", function() { - expect( 3 ); + expect( 5 ); var input = $( "#datepicker" ).datepicker(), - picker = input.datepicker( "widget" ); + picker = input.datepicker( "widget" ), + inline = $( "#inline" ).datepicker(); input.datepicker( "value", "1/1/2014" ); equal( input.val(), "1/1/2014", "input's value set" ); ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), "first day marked as selected" ); - equal( input.datepicker( "value" ), "1/1/2014", "getter" ); + inline.datepicker( "value", "1/1/2014" ); + ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + "first day marked as selected" ); + equal( inline.datepicker( "value" ), "1/1/2014", "getter" ); + // TODO: Handle for invalid values. - // TODO: Add tests for inline pickers. input.datepicker( "destroy" ); + inline.datepicker( "destroy" ); }); test( "valueAsDate", function() { - expect( 3 ); + expect( 5 ); var input = $( "#datepicker" ).datepicker(), - picker = input.datepicker( "widget" ); + picker = input.datepicker( "widget" ), + inline = $( "#inline" ).datepicker(); input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); equal( input.val(), "1/1/2014", "input's value set" ); ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), "first day marked as selected" ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "getter" ); + inline.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); + ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + "first day marked as selected" ); + TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), + new Date( 2014, 0, 1 ), "getter" ); + // TODO: Handle for invalid values. - // TODO: Add tests for inline pickers. input.datepicker( "destroy" ); + inline.datepicker( "destroy" ); }); })( jQuery ); From 3333c709a55b73cb4ad37a9d9feba364a016927e Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 22 Nov 2013 09:03:48 -0500 Subject: [PATCH 040/172] Datepicker: Remove unnecessary code now that destroying inline pickers is supported. --- tests/unit/datepicker/datepicker_core.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index bb216b18c24..df59f33564d 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -188,9 +188,6 @@ asyncTest( "baseStructure", function() { inl.datepicker( "destroy" ); - // TODO: Calling destroy() on inline pickers currently does not work. - inl.empty(); - step7(); } From fd947402cc01d8cd597430aa142a2a99835be645 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 22 Nov 2013 09:30:11 -0500 Subject: [PATCH 041/172] Datepicker: Enter keypresses on the should select the current date --- tests/unit/datepicker/datepicker_core.js | 16 +++++++--------- ui/jquery.ui.datepicker.js | 3 +++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index df59f33564d..bbb79806975 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -321,18 +321,16 @@ asyncTest( "customStructure", function() { }); test( "Keyboard handling", function() { - // TODO: These tests all rely on having a method to retrieve a Date object. There - // is not only implemented yet so bail. - expect( 0 ); - return; - - expect( 24 ); - var inp = TestHelpers.datepicker.init( "#datepicker" ), + expect( 1 ); + var input = $( "#datepicker" ).datepicker(), date = new Date(); - inp.val( "" ).datepicker( "open" ) + input.datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.val(), date, "Keystroke enter" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke enter" ); + + input.datepicker( "destroy" ); + return; inp.val( "02/04/2008" ).datepicker( "open" ) .simulate("keydown", { keyCode: $.ui.keyCode.ENTER }); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 9cc4a25c689..c9b14b15a2e 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -181,6 +181,9 @@ $.widget( "ui.datepicker", { this.close( event ); } break; + case $.ui.keyCode.ENTER: + this._handleKeydown( event ); + break; case $.ui.keyCode.DOWN: case $.ui.keyCode.UP: clearTimeout( this.closeTimer ); From a089c493fe626503bd767fc99cb48f5e94d52cba Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 22 Nov 2013 09:48:50 -0500 Subject: [PATCH 042/172] Datepicker: Enable enter with existing value test. Coding standards cleanup of keyboard tests. --- tests/unit/datepicker/datepicker_core.js | 116 +++++++++++------------ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index bbb79806975..4943ad745ee 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -321,7 +321,7 @@ asyncTest( "customStructure", function() { }); test( "Keyboard handling", function() { - expect( 1 ); + expect( 2 ); var input = $( "#datepicker" ).datepicker(), date = new Date(); @@ -329,158 +329,158 @@ test( "Keyboard handling", function() { .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke enter" ); - input.datepicker( "destroy" ); - return; - - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "1/1/2014" ).datepicker( "open" ) .simulate("keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke enter - preset" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + input.datepicker( "destroy" ); + return; + + input.val( "1/1/2014" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Keystroke ctrl+home" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+home" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "02/04/2008" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END }); - ok( inp.datepicker( "getDate" ) == null, "Keystroke ctrl+end" ); + ok( input.datepicker( "valueAsDate" ) == null, "Keystroke ctrl+end" ); - inp.val( "" ).datepicker( "open" ) + input.val( "" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); - ok(inp.datepicker("getDate") == null, "Keystroke esc"); + ok( input.datepicker( "valueAsDate" ) == null, "Keystroke esc" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "02/04/2008" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), "Keystroke esc - preset" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "02/04/2008" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date(2008, 2 - 1, 4), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date(2008, 2 - 1, 4), "Keystroke esc - abandoned" ); // Moving by day or week - inp.val( "" ).datepicker( "open" ) + input.val( "" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.LEFT }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); date.setDate( date.getDate() - 1 ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+left" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+left" ); - inp.val( "" ).datepicker( "open" ) - .simulate( "keydown", {keyCode: $.ui.keyCode.LEFT }). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER }); + input.val( "" ).datepicker( "open" ) + .simulate( "keydown", {keyCode: $.ui.keyCode.LEFT }) + .simulate( "keydown", {keyCode: $.ui.keyCode.ENTER }); date.setDate( date.getDate() + 1 ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke left") ; + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke left") ; - inp.val( "" ).datepicker( "open" ) - .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + input.val( "" ).datepicker( "open" ) + .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT }) + .simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 1); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+right" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+right" ); - inp.val( "" ).datepicker( "open" ) + input.val( "" ).datepicker( "open" ) .simulate( "keydown", {keyCode: $.ui.keyCode.RIGHT}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() - 1); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke right" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke right" ); - inp.val( "" ).datepicker( "open" ) + input.val( "" ).datepicker( "open" ) .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.UP}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() - 7); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+up" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+up" ); - inp.val( "" ).datepicker( "open" ) + input.val( "" ).datepicker( "open" ) .simulate( "keydown", {keyCode: $.ui.keyCode.UP}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 7); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke up" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke up" ); - inp.val( "" ).datepicker( "open" ) + input.val( "" ).datepicker( "open" ) .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 7); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke ctrl+down" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+down" ); - inp.val( "" ).datepicker( "open" ) + input.val( "" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); date.setDate( date.getDate() - 7 ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Keystroke down" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke down" ); // Moving by month or year - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "02/04/2008" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 4 ), "Keystroke pgup" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "02/04/2008" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 3 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 3 - 1, 4 ), "Keystroke pgdn" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "02/04/2008" ).datepicker( "open" ) .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2007, 2 - 1, 4 ), "Keystroke ctrl+pgup" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "02/04/2008" ).datepicker( "open" ) .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2009, 2 - 1, 4 ), "Keystroke ctrl+pgdn" ); // Check for moving to short months - inp.val( "03/31/2008" ).datepicker( "open" ) + input.val( "03/31/2008" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 29 ), "Keystroke pgup - Feb" ); - inp.val( "01/30/2008" ).datepicker( "open" ) + input.val( "01/30/2008" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 29 ), "Keystroke pgdn - Feb" ); - inp.val( "02/29/2008" ).datepicker( "open" ) + input.val( "02/29/2008" ).datepicker( "open" ) .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 28 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2007, 2 - 1, 28 ), "Keystroke ctrl+pgup - Feb" ); - inp.val( "02/29/2008" ).datepicker( "open" ) + input.val( "02/29/2008" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 28 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2009, 2 - 1, 28 ), "Keystroke ctrl+pgdn - Feb" ); // Goto current - inp.datepicker( "option", { gotoCurrent: true }) + input.datepicker( "option", { gotoCurrent: true }) .datepicker( "close" ).val( "02/04/2008" ).datepicker( "open" ) .late( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), "Keystroke ctrl+home" ); // Change steps - inp.datepicker( "option", { stepMonths: 2, gotoCurrent: false }) + input.datepicker( "option", { stepMonths: 2, gotoCurrent: false }) .datepicker( "close" ).val( "02/04/2008" ).datepicker( "open" ) .late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2007, 12 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2007, 12 - 1, 4 ), "Keystroke pgup step 2" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "02/04/2008" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 4 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ), "Keystroke pgdn step 2" ); }); From 845814cd97ff363a4a7ff3b3a21e792e7944d4ff Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 22 Nov 2013 13:39:02 -0500 Subject: [PATCH 043/172] Datepicker: Restore handling of Control+Home and Control+End on the . --- tests/unit/datepicker/datepicker_core.js | 15 +++++++++------ ui/jquery.ui.datepicker.js | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 4943ad745ee..35c273aec24 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -321,7 +321,7 @@ asyncTest( "customStructure", function() { }); test( "Keyboard handling", function() { - expect( 2 ); + expect( 4 ); var input = $( "#datepicker" ).datepicker(), date = new Date(); @@ -329,22 +329,25 @@ test( "Keyboard handling", function() { .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke enter" ); + // Enter = Select today's date by default input.val( "1/1/2014" ).datepicker( "open" ) .simulate("keydown", { keyCode: $.ui.keyCode.ENTER }); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke enter - preset" ); - input.datepicker( "destroy" ); - return; - + // Control + Home = Change the calendar to the current month input.val( "1/1/2014" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+home" ); - input.val( "02/04/2008" ).datepicker( "open" ) + // Control + End = Close the calendar and clear the input + input.val( "1/1/2014" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END }); - ok( input.datepicker( "valueAsDate" ) == null, "Keystroke ctrl+end" ); + equal( input.val(), "", "Keystroke ctrl+end" ); + + input.datepicker( "destroy" ); + return; input.val( "" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index c9b14b15a2e..d8a43801a75 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -44,6 +44,7 @@ $.widget( "ui.datepicker", { }, _create: function() { this.date = $.date( null, this.options.dateFormat ); + this.date.eachDay = this.options.eachDay; this.id = "ui-datepicker-" + idIncrement; idIncrement++; @@ -192,6 +193,26 @@ $.widget( "ui.datepicker", { this.grid.focus( 1 ); }, 1); break; + case $.ui.keyCode.HOME: + if ( event.ctrlKey ) { + this.date.setTime( new Date() ); + event.preventDefault(); + if ( this.isOpen ) { + this.refresh(); + } else { + this.open( event ); + } + } + break; + case $.ui.keyCode.END: + if ( event.ctrlKey ) { + this.element.val( "" ); + event.preventDefault(); + if ( this.isOpen ) { + this.close( event ); + } + } + break; } }, mousedown: function( event ) { From e14f8e6206d9955092fce14613ee9e67300a4835 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Mon, 25 Nov 2013 15:36:01 -0500 Subject: [PATCH 044/172] Datepicker: Updating escape key tests to new APIs. --- tests/unit/datepicker/datepicker_core.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 35c273aec24..7ebfcc9358f 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -321,8 +321,9 @@ asyncTest( "customStructure", function() { }); test( "Keyboard handling", function() { - expect( 4 ); + expect( 8 ); var input = $( "#datepicker" ).datepicker(), + instance = input.datepicker( "instance" ), date = new Date(); input.datepicker( "open" ) @@ -346,24 +347,25 @@ test( "Keyboard handling", function() { .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END }); equal( input.val(), "", "Keystroke ctrl+end" ); - input.datepicker( "destroy" ); - return; - - input.val( "" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); - ok( input.datepicker( "valueAsDate" ) == null, "Keystroke esc" ); + input.val( "" ).datepicker( "open" ); + ok( instance.isOpen, "datepicker is open before escape" ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); + ok( !instance.isOpen, "escape closes the datepicker" ); - input.val( "02/04/2008" ).datepicker( "open" ) + input.val( "1/1/2014" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke esc - preset" ); - input.val( "02/04/2008" ).datepicker( "open" ) + input.val( "1/1/2014" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date(2008, 2 - 1, 4), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke esc - abandoned" ); + input.datepicker( "destroy" ); + return; + // Moving by day or week input.val( "" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.LEFT }) From fdaac175d7256bae5b541f00db6e86ca4a07944b Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Mon, 25 Nov 2013 16:37:33 -0500 Subject: [PATCH 045/172] Datepicker: First batch of tests for arrow key handling. --- tests/unit/datepicker/datepicker_core.js | 95 +++++++++++++++++++----- 1 file changed, 75 insertions(+), 20 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 7ebfcc9358f..7f77b099de6 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -364,33 +364,88 @@ test( "Keyboard handling", function() { "Keystroke esc - abandoned" ); input.datepicker( "destroy" ); - return; +}); - // Moving by day or week - input.val( "" ).datepicker( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.LEFT }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - date.setDate( date.getDate() - 1 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+left" ); +asyncTest( "keyboard handling - arrow keys", function() { + expect( 6 ); + var picker, + input = $( "#datepicker" ), + date = new Date(); - input.val( "" ).datepicker( "open" ) - .simulate( "keydown", {keyCode: $.ui.keyCode.LEFT }) - .simulate( "keydown", {keyCode: $.ui.keyCode.ENTER }); - date.setDate( date.getDate() + 1 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke left") ; - + function step1() { + input.datepicker(); + picker = input.datepicker( "widget" ); + ok( !picker.is( ":visible" ), "datepicker closed" ); + input.val( "" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + + setTimeout(function() { + ok( picker.is( ":visible" ), "Keystroke down opens datepicker" ); + input.datepicker( "destroy" ); + step2(); + }); + }; + + function step2() { + input.datepicker(); + picker = input.datepicker( "widget" ) + ok( !picker.is( ":visible" ), "datepicker closed" ); + input.val( "" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.UP }); + + setTimeout(function() { + ok( picker.is( ":visible" ), "Keystroke up opens datepicker" ); + input.datepicker( "destroy" ); + step3(); + }); + }; + + function step3() { + input.datepicker() + .val( "" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date.setDate( date.getDate() - 1 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke left to switch to previous day" ); + + input.datepicker( "destroy" ); + step4(); + }, 100); + }; + + function step4() { + input.datepicker() + .val( "" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date.setDate( new Date().getDate() + 1 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke right to switch to next day" ); + + input.datepicker( "destroy" ); + start(); + }, 100); + }; + + step1(); +}); + +/* input.val( "" ).datepicker( "open" ) .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT }) .simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 1); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+right" ); - input.val( "" ).datepicker( "open" ) - .simulate( "keydown", {keyCode: $.ui.keyCode.RIGHT}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 1); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke right" ); - input.val( "" ).datepicker( "open" ) .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.UP}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); @@ -487,7 +542,7 @@ test( "Keyboard handling", function() { .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ), "Keystroke pgdn step 2" ); -}); +*/ test( "mouse", function() { // TODO: These tests use the old getDate() and setDate() methods. Re-activate these From febd2b28decacf50336d5122b67831ce36741a1b Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Sat, 30 Nov 2013 10:22:17 -0200 Subject: [PATCH 046/172] Datepicker: Use Globalize 1.0.0 - Update globalize; (not using bower yet :cry:) - Update $.date; - Update translations; (this isn't external libray, it should NOT be in /external) - Add comments on datepicker; --- external/date.js | 59 +- external/globalize.culture.de-DE.js | 81 - external/globalize.culture.he.js | 97 - external/globalize.culture.ja-JP.js | 100 - external/globalize.js | 1586 +------------- external/localization.js | 3056 +++++++++++++++++++++++---- ui/jquery.ui.datepicker.js | 26 +- 7 files changed, 2673 insertions(+), 2332 deletions(-) delete mode 100644 external/globalize.culture.de-DE.js delete mode 100644 external/globalize.culture.he.js delete mode 100644 external/globalize.culture.ja-JP.js mode change 100644 => 120000 external/globalize.js diff --git a/external/date.js b/external/date.js index fef4dcaeffe..1a7893acc3d 100644 --- a/external/date.js +++ b/external/date.js @@ -6,25 +6,37 @@ */ (function( $, undefined ) { -$.date = function( datestring, formatstring ) { +var weekdays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ], + weekdaysRev = { + "sun": 0, + "mon": 1, + "tue": 2, + "wed": 3, + "thu": 4, + "fri": 5, + "sat": 6 + }; + +Globalize.locale( "en" ); + +$.date = function( date, format ) { //TODO: Need to refactor $.date to be a constructor, move the methods to a prototype. - var calendar = Globalize.culture().calendar, - format = formatstring ? formatstring : calendar.patterns.d, - date = datestring ? Globalize.parseDate( datestring, format ) : new Date(); + var origFormat = format; - if ( !date ) { - date = new Date(); + if ( typeof date === "string" && date.length ) { + date = Globalize.parseDate( date, format ); } + date = date || new Date(); + return { refresh: function() { - calendar = Globalize.culture().calendar; - format = formatstring || calendar.patterns.d; + format = origFormat; return this; }, - setFormat: function( formatstring ) { - if ( formatstring ) { - format = formatstring; + setFormat: function( format ) { + if ( format ) { + format = format; } return this; }, @@ -82,7 +94,7 @@ $.date = function( datestring, formatstring ) { return 32 - new Date( year, month, 32 ).getDate(); }, monthName: function() { - return calendar.months.names[ date.getMonth() ]; + return Globalize.format( date, { pattern: "MMMM" } ); }, day: function() { return date.getDate(); @@ -101,10 +113,10 @@ $.date = function( datestring, formatstring ) { weekdays: function() { var result = []; for ( var dow = 0; dow < 7; dow++ ) { - var day = ( dow + calendar.firstDay ) % 7; + var day = ( dow + weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] ) % 7; result.push({ - shortname: calendar.days.namesShort[ day ], - fullname: calendar.days.names[ day ] + shortname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/abbreviated", weekdays[ day ] ]), + fullname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/wide", weekdays[ day ] ]), }); } return result; @@ -113,7 +125,7 @@ $.date = function( datestring, formatstring ) { var result = [], today = $.date(), firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(), - leadDays = ( firstDayOfMonth - calendar.firstDay + 7 ) % 7, + leadDays = ( firstDayOfMonth - weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] + 7 ) % 7, rows = Math.ceil( ( leadDays + this.daysInMonth() ) / 7 ), printDate = new Date( this.year(), date.getMonth(), 1 - leadDays ); for ( var row = 0; row < rows; row++ ) { @@ -170,27 +182,20 @@ $.date = function( datestring, formatstring ) { clone: function() { return $.date( new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), - date.getMinutes(), date.getSeconds()), formatstring ); + date.getMinutes(), date.getSeconds()), format ); }, // TODO compare year, month, day each for better performance equal: function( other ) { function format( date ) { - return Globalize.format( date, "d" ); + return Globalize.format( date, { pattern: "yyyyMMdd" } ); } return format( date ) === format( other ); }, date: function() { return date; }, - format: function( formatstring ) { - return Globalize.format( date, formatstring ? formatstring : format ); - }, - calendar: function( newcalendar ) { - if ( newcalendar ) { - calendar = newcalendar; - return this; - } - return calendar; + format: function( format ) { + return Globalize.format( date, format || origFormat ); } }; }; diff --git a/external/globalize.culture.de-DE.js b/external/globalize.culture.de-DE.js deleted file mode 100644 index 5466bd75e3b..00000000000 --- a/external/globalize.culture.de-DE.js +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Globalize Culture de-DE - * - * http://github.com/jquery/globalize - * - * Copyright Software Freedom Conservancy, Inc. - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * This file was generated by the Globalize Culture Generator - * Translation: bugs found in this file need to be fixed in the generator - */ - -(function( window, undefined ) { - -var Globalize; - -if ( typeof require !== "undefined" - && typeof exports !== "undefined" - && typeof module !== "undefined" ) { - // Assume CommonJS - Globalize = require( "globalize" ); -} else { - // Global variable - Globalize = window.Globalize; -} - -Globalize.addCultureInfo( "de-DE", "default", { - name: "de-DE", - englishName: "German (Germany)", - nativeName: "Deutsch (Deutschland)", - language: "de", - numberFormat: { - ",": ".", - ".": ",", - NaN: "n. def.", - negativeInfinity: "-unendlich", - positiveInfinity: "+unendlich", - percent: { - pattern: ["-n%","n%"], - ",": ".", - ".": "," - }, - currency: { - pattern: ["-n $","n $"], - ",": ".", - ".": ",", - symbol: "€" - } - }, - calendars: { - standard: { - "/": ".", - firstDay: 1, - days: { - names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], - namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], - namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] - }, - months: { - names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], - namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] - }, - AM: null, - PM: null, - eras: [{"name":"n. Chr.","start":null,"offset":0}], - patterns: { - d: "dd.MM.yyyy", - D: "dddd, d. MMMM yyyy", - t: "HH:mm", - T: "HH:mm:ss", - f: "dddd, d. MMMM yyyy HH:mm", - F: "dddd, d. MMMM yyyy HH:mm:ss", - M: "dd MMMM", - Y: "MMMM yyyy" - } - } - } -}); - -}( this )); diff --git a/external/globalize.culture.he.js b/external/globalize.culture.he.js deleted file mode 100644 index 2d2e59abd6b..00000000000 --- a/external/globalize.culture.he.js +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Globalize Culture he - * - * http://github.com/jquery/globalize - * - * Copyright Software Freedom Conservancy, Inc. - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * This file was generated by the Globalize Culture Generator - * Translation: bugs found in this file need to be fixed in the generator - */ - -(function( window, undefined ) { - -var Globalize; - -if ( typeof require !== "undefined" && - typeof exports !== "undefined" && - typeof module !== "undefined" ) { - // Assume CommonJS - Globalize = require( "globalize" ); -} else { - // Global variable - Globalize = window.Globalize; -} - -Globalize.addCultureInfo( "he", "default", { - name: "he", - englishName: "Hebrew", - nativeName: "עברית", - language: "he", - isRTL: true, - numberFormat: { - "NaN": "לא מספר", - negativeInfinity: "אינסוף שלילי", - positiveInfinity: "אינסוף חיובי", - percent: { - pattern: ["-n%","n%"] - }, - currency: { - pattern: ["$-n","$ n"], - symbol: "₪" - } - }, - calendars: { - standard: { - days: { - names: ["יום ראשון","יום שני","יום שלישי","יום רביעי","יום חמישי","יום שישי","שבת"], - namesAbbr: ["יום א","יום ב","יום ג","יום ד","יום ה","יום ו","שבת"], - namesShort: ["א","ב","ג","ד","ה","ו","ש"] - }, - months: { - names: ["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר",""], - namesAbbr: ["ינו","פבר","מרץ","אפר","מאי","יונ","יול","אוג","ספט","אוק","נוב","דצמ",""] - }, - eras: [{"name":"לספירה","start":null,"offset":0}], - patterns: { - d: "dd/MM/yyyy", - D: "dddd dd MMMM yyyy", - t: "HH:mm", - T: "HH:mm:ss", - f: "dddd dd MMMM yyyy HH:mm", - F: "dddd dd MMMM yyyy HH:mm:ss", - M: "dd MMMM", - Y: "MMMM yyyy" - } - }, - Hebrew: { - name: "Hebrew", - "/": " ", - days: { - names: ["יום ראשון","יום שני","יום שלישי","יום רביעי","יום חמישי","יום שישי","שבת"], - namesAbbr: ["א","ב","ג","ד","ה","ו","ש"], - namesShort: ["א","ב","ג","ד","ה","ו","ש"] - }, - months: { - names: ["תשרי","חשון","כסלו","טבת","שבט","אדר","אדר ב","ניסן","אייר","סיון","תמוז","אב","אלול"], - namesAbbr: ["תשרי","חשון","כסלו","טבת","שבט","אדר","אדר ב","ניסן","אייר","סיון","תמוז","אב","אלול"] - }, - eras: [{"name":"C.E.","start":null,"offset":0}], - twoDigitYearMax: 5790, - patterns: { - d: "dd MMMM yyyy", - D: "dddd dd MMMM yyyy", - t: "HH:mm", - T: "HH:mm:ss", - f: "dddd dd MMMM yyyy HH:mm", - F: "dddd dd MMMM yyyy HH:mm:ss", - M: "dd MMMM", - Y: "MMMM yyyy" - } - } - } -}); - -}( this )); \ No newline at end of file diff --git a/external/globalize.culture.ja-JP.js b/external/globalize.culture.ja-JP.js deleted file mode 100644 index a9469d709f4..00000000000 --- a/external/globalize.culture.ja-JP.js +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Globalize Culture ja-JP - * - * http://github.com/jquery/globalize - * - * Copyright Software Freedom Conservancy, Inc. - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * This file was generated by the Globalize Culture Generator - * Translation: bugs found in this file need to be fixed in the generator - */ - -(function( window, undefined ) { - -var Globalize; - -if ( typeof require !== "undefined" - && typeof exports !== "undefined" - && typeof module !== "undefined" ) { - // Assume CommonJS - Globalize = require( "globalize" ); -} else { - // Global variable - Globalize = window.Globalize; -} - -Globalize.addCultureInfo( "ja-JP", "default", { - name: "ja-JP", - englishName: "Japanese (Japan)", - nativeName: "日本語 (日本)", - language: "ja", - numberFormat: { - NaN: "NaN (非数値)", - negativeInfinity: "-∞", - positiveInfinity: "+∞", - percent: { - pattern: ["-n%","n%"] - }, - currency: { - pattern: ["-$n","$n"], - decimals: 0, - symbol: "¥" - } - }, - calendars: { - standard: { - days: { - names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], - namesAbbr: ["日","月","火","水","木","金","土"], - namesShort: ["日","月","火","水","木","金","土"] - }, - months: { - names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], - namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] - }, - AM: ["午前","午前","午前"], - PM: ["午後","午後","午後"], - eras: [{"name":"西暦","start":null,"offset":0}], - patterns: { - d: "yyyy/MM/dd", - D: "yyyy'年'M'月'd'日'", - t: "H:mm", - T: "H:mm:ss", - f: "yyyy'年'M'月'd'日' H:mm", - F: "yyyy'年'M'月'd'日' H:mm:ss", - M: "M'月'd'日'", - Y: "yyyy'年'M'月'" - } - }, - Japanese: { - name: "Japanese", - days: { - names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], - namesAbbr: ["日","月","火","水","木","金","土"], - namesShort: ["日","月","火","水","木","金","土"] - }, - months: { - names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], - namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] - }, - AM: ["午前","午前","午前"], - PM: ["午後","午後","午後"], - eras: [{"name":"平成","start":null,"offset":1867},{"name":"昭和","start":-1812153600000,"offset":1911},{"name":"大正","start":-1357603200000,"offset":1925},{"name":"明治","start":60022080000,"offset":1988}], - twoDigitYearMax: 99, - patterns: { - d: "gg y/M/d", - D: "gg y'年'M'月'd'日'", - t: "H:mm", - T: "H:mm:ss", - f: "gg y'年'M'月'd'日' H:mm", - F: "gg y'年'M'月'd'日' H:mm:ss", - M: "M'月'd'日'", - Y: "gg y'年'M'月'" - } - } - } -}); - -}( this )); diff --git a/external/globalize.js b/external/globalize.js deleted file mode 100644 index a38a32625d3..00000000000 --- a/external/globalize.js +++ /dev/null @@ -1,1585 +0,0 @@ -/*! - * Globalize - * - * http://github.com/jquery/globalize - * - * Copyright Software Freedom Conservancy, Inc. - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - */ - -(function( window, undefined ) { - -var Globalize, - // private variables - regexHex, - regexInfinity, - regexParseFloat, - regexTrim, - // private JavaScript utility functions - arrayIndexOf, - endsWith, - extend, - isArray, - isFunction, - isObject, - startsWith, - trim, - truncate, - zeroPad, - // private Globalization utility functions - appendPreOrPostMatch, - expandFormat, - formatDate, - formatNumber, - getTokenRegExp, - getEra, - getEraYear, - parseExact, - parseNegativePattern; - -// Global variable (Globalize) or CommonJS module (globalize) -Globalize = function( cultureSelector ) { - return new Globalize.prototype.init( cultureSelector ); -}; - -if ( typeof require !== "undefined" && - typeof exports !== "undefined" && - typeof module !== "undefined" ) { - // Assume CommonJS - module.exports = Globalize; -} else { - // Export as global variable - window.Globalize = Globalize; -} - -Globalize.cultures = {}; - -Globalize.prototype = { - constructor: Globalize, - init: function( cultureSelector ) { - this.cultures = Globalize.cultures; - this.cultureSelector = cultureSelector; - - return this; - } -}; -Globalize.prototype.init.prototype = Globalize.prototype; - -// 1. When defining a culture, all fields are required except the ones stated as optional. -// 2. Each culture should have a ".calendars" object with at least one calendar named "standard" -// which serves as the default calendar in use by that culture. -// 3. Each culture should have a ".calendar" object which is the current calendar being used, -// it may be dynamically changed at any time to one of the calendars in ".calendars". -Globalize.cultures[ "default" ] = { - // A unique name for the culture in the form - - name: "en", - // the name of the culture in the english language - englishName: "English", - // the name of the culture in its own language - nativeName: "English", - // whether the culture uses right-to-left text - isRTL: false, - // "language" is used for so-called "specific" cultures. - // For example, the culture "es-CL" means "Spanish, in Chili". - // It represents the Spanish-speaking culture as it is in Chili, - // which might have different formatting rules or even translations - // than Spanish in Spain. A "neutral" culture is one that is not - // specific to a region. For example, the culture "es" is the generic - // Spanish culture, which may be a more generalized version of the language - // that may or may not be what a specific culture expects. - // For a specific culture like "es-CL", the "language" field refers to the - // neutral, generic culture information for the language it is using. - // This is not always a simple matter of the string before the dash. - // For example, the "zh-Hans" culture is netural (Simplified Chinese). - // And the "zh-SG" culture is Simplified Chinese in Singapore, whose lanugage - // field is "zh-CHS", not "zh". - // This field should be used to navigate from a specific culture to it's - // more general, neutral culture. If a culture is already as general as it - // can get, the language may refer to itself. - language: "en", - // numberFormat defines general number formatting rules, like the digits in - // each grouping, the group separator, and how negative numbers are displayed. - numberFormat: { - // [negativePattern] - // Note, numberFormat.pattern has no "positivePattern" unlike percent and currency, - // but is still defined as an array for consistency with them. - // negativePattern: one of "(n)|-n|- n|n-|n -" - pattern: [ "-n" ], - // number of decimal places normally shown - decimals: 2, - // string that separates number groups, as in 1,000,000 - ",": ",", - // string that separates a number from the fractional portion, as in 1.99 - ".": ".", - // array of numbers indicating the size of each number group. - // TODO: more detailed description and example - groupSizes: [ 3 ], - // symbol used for positive numbers - "+": "+", - // symbol used for negative numbers - "-": "-", - // symbol used for NaN (Not-A-Number) - "NaN": "NaN", - // symbol used for Negative Infinity - negativeInfinity: "-Infinity", - // symbol used for Positive Infinity - positiveInfinity: "Infinity", - percent: { - // [negativePattern, positivePattern] - // negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %" - // positivePattern: one of "n %|n%|%n|% n" - pattern: [ "-n %", "n %" ], - // number of decimal places normally shown - decimals: 2, - // array of numbers indicating the size of each number group. - // TODO: more detailed description and example - groupSizes: [ 3 ], - // string that separates number groups, as in 1,000,000 - ",": ",", - // string that separates a number from the fractional portion, as in 1.99 - ".": ".", - // symbol used to represent a percentage - symbol: "%" - }, - currency: { - // [negativePattern, positivePattern] - // negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)" - // positivePattern: one of "$n|n$|$ n|n $" - pattern: [ "($n)", "$n" ], - // number of decimal places normally shown - decimals: 2, - // array of numbers indicating the size of each number group. - // TODO: more detailed description and example - groupSizes: [ 3 ], - // string that separates number groups, as in 1,000,000 - ",": ",", - // string that separates a number from the fractional portion, as in 1.99 - ".": ".", - // symbol used to represent currency - symbol: "$" - } - }, - // calendars defines all the possible calendars used by this culture. - // There should be at least one defined with name "standard", and is the default - // calendar used by the culture. - // A calendar contains information about how dates are formatted, information about - // the calendar's eras, a standard set of the date formats, - // translations for day and month names, and if the calendar is not based on the Gregorian - // calendar, conversion functions to and from the Gregorian calendar. - calendars: { - standard: { - // name that identifies the type of calendar this is - name: "Gregorian_USEnglish", - // separator of parts of a date (e.g. "/" in 11/05/1955) - "/": "/", - // separator of parts of a time (e.g. ":" in 05:44 PM) - ":": ":", - // the first day of the week (0 = Sunday, 1 = Monday, etc) - firstDay: 0, - days: { - // full day names - names: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], - // abbreviated day names - namesAbbr: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], - // shortest day names - namesShort: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ] - }, - months: { - // full month names (13 months for lunar calendards -- 13th month should be "" if not lunar) - names: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" ], - // abbreviated month names - namesAbbr: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" ] - }, - // AM and PM designators in one of these forms: - // The usual view, and the upper and lower case versions - // [ standard, lowercase, uppercase ] - // The culture does not use AM or PM (likely all standard date formats use 24 hour time) - // null - AM: [ "AM", "am", "AM" ], - PM: [ "PM", "pm", "PM" ], - eras: [ - // eras in reverse chronological order. - // name: the name of the era in this culture (e.g. A.D., C.E.) - // start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era. - // offset: offset in years from gregorian calendar - { - "name": "A.D.", - "start": null, - "offset": 0 - } - ], - // when a two digit year is given, it will never be parsed as a four digit - // year greater than this year (in the appropriate era for the culture) - // Set it as a full year (e.g. 2029) or use an offset format starting from - // the current year: "+19" would correspond to 2029 if the current year 2010. - twoDigitYearMax: 2029, - // set of predefined date and time patterns used by the culture - // these represent the format someone in this culture would expect - // to see given the portions of the date that are shown. - patterns: { - // short date pattern - d: "M/d/yyyy", - // long date pattern - D: "dddd, MMMM dd, yyyy", - // short time pattern - t: "h:mm tt", - // long time pattern - T: "h:mm:ss tt", - // long date, short time pattern - f: "dddd, MMMM dd, yyyy h:mm tt", - // long date, long time pattern - F: "dddd, MMMM dd, yyyy h:mm:ss tt", - // month/day pattern - M: "MMMM dd", - // month/year pattern - Y: "yyyy MMMM", - // S is a sortable format that does not vary by culture - S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss" - } - // optional fields for each calendar: - /* - monthsGenitive: - Same as months but used when the day preceeds the month. - Omit if the culture has no genitive distinction in month names. - For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx - convert: - Allows for the support of non-gregorian based calendars. This convert object is used to - to convert a date to and from a gregorian calendar date to handle parsing and formatting. - The two functions: - fromGregorian( date ) - Given the date as a parameter, return an array with parts [ year, month, day ] - corresponding to the non-gregorian based year, month, and day for the calendar. - toGregorian( year, month, day ) - Given the non-gregorian year, month, and day, return a new Date() object - set to the corresponding date in the gregorian calendar. - */ - } - }, - // For localized strings - messages: {} -}; - -Globalize.cultures[ "default" ].calendar = Globalize.cultures[ "default" ].calendars.standard; - -Globalize.cultures.en = Globalize.cultures[ "default" ]; - -Globalize.cultureSelector = "en"; - -// -// private variables -// - -regexHex = /^0x[a-f0-9]+$/i; -regexInfinity = /^[+\-]?infinity$/i; -regexParseFloat = /^[+\-]?\d*\.?\d*(e[+\-]?\d+)?$/; -regexTrim = /^\s+|\s+$/g; - -// -// private JavaScript utility functions -// - -arrayIndexOf = function( array, item ) { - if ( array.indexOf ) { - return array.indexOf( item ); - } - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[i] === item ) { - return i; - } - } - return -1; -}; - -endsWith = function( value, pattern ) { - return value.substr( value.length - pattern.length ) === pattern; -}; - -extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !isFunction(target) ) { - target = {}; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( isObject(copy) || (copyIsArray = isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && isArray(src) ? src : []; - - } else { - clone = src && isObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -isArray = Array.isArray || function( obj ) { - return Object.prototype.toString.call( obj ) === "[object Array]"; -}; - -isFunction = function( obj ) { - return Object.prototype.toString.call( obj ) === "[object Function]"; -}; - -isObject = function( obj ) { - return Object.prototype.toString.call( obj ) === "[object Object]"; -}; - -startsWith = function( value, pattern ) { - return value.indexOf( pattern ) === 0; -}; - -trim = function( value ) { - return ( value + "" ).replace( regexTrim, "" ); -}; - -truncate = function( value ) { - if ( isNaN( value ) ) { - return NaN; - } - return Math[ value < 0 ? "ceil" : "floor" ]( value ); -}; - -zeroPad = function( str, count, left ) { - var l; - for ( l = str.length; l < count; l += 1 ) { - str = ( left ? ("0" + str) : (str + "0") ); - } - return str; -}; - -// -// private Globalization utility functions -// - -appendPreOrPostMatch = function( preMatch, strings ) { - // appends pre- and post- token match strings while removing escaped characters. - // Returns a single quote count which is used to determine if the token occurs - // in a string literal. - var quoteCount = 0, - escaped = false; - for ( var i = 0, il = preMatch.length; i < il; i++ ) { - var c = preMatch.charAt( i ); - switch ( c ) { - case "\'": - if ( escaped ) { - strings.push( "\'" ); - } - else { - quoteCount++; - } - escaped = false; - break; - case "\\": - if ( escaped ) { - strings.push( "\\" ); - } - escaped = !escaped; - break; - default: - strings.push( c ); - escaped = false; - break; - } - } - return quoteCount; -}; - -expandFormat = function( cal, format ) { - // expands unspecified or single character date formats into the full pattern. - format = format || "F"; - var pattern, - patterns = cal.patterns, - len = format.length; - if ( len === 1 ) { - pattern = patterns[ format ]; - if ( !pattern ) { - throw "Invalid date format string \'" + format + "\'."; - } - format = pattern; - } - else if ( len === 2 && format.charAt(0) === "%" ) { - // %X escape format -- intended as a custom format string that is only one character, not a built-in format. - format = format.charAt( 1 ); - } - return format; -}; - -formatDate = function( value, format, culture ) { - var cal = culture.calendar, - convert = cal.convert, - ret; - - if ( !format || !format.length || format === "i" ) { - if ( culture && culture.name.length ) { - if ( convert ) { - // non-gregorian calendar, so we cannot use built-in toLocaleString() - ret = formatDate( value, cal.patterns.F, culture ); - } - else { - var eraDate = new Date( value.getTime() ), - era = getEra( value, cal.eras ); - eraDate.setFullYear( getEraYear(value, cal, era) ); - ret = eraDate.toLocaleString(); - } - } - else { - ret = value.toString(); - } - return ret; - } - - var eras = cal.eras, - sortable = format === "s"; - format = expandFormat( cal, format ); - - // Start with an empty string - ret = []; - var hour, - zeros = [ "0", "00", "000" ], - foundDay, - checkedDay, - dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g, - quoteCount = 0, - tokenRegExp = getTokenRegExp(), - converted; - - function padZeros( num, c ) { - var r, s = num + ""; - if ( c > 1 && s.length < c ) { - r = ( zeros[c - 2] + s); - return r.substr( r.length - c, c ); - } - else { - r = s; - } - return r; - } - - function hasDay() { - if ( foundDay || checkedDay ) { - return foundDay; - } - foundDay = dayPartRegExp.test( format ); - checkedDay = true; - return foundDay; - } - - function getPart( date, part ) { - if ( converted ) { - return converted[ part ]; - } - switch ( part ) { - case 0: - return date.getFullYear(); - case 1: - return date.getMonth(); - case 2: - return date.getDate(); - default: - throw "Invalid part value " + part; - } - } - - if ( !sortable && convert ) { - converted = convert.fromGregorian( value ); - } - - for ( ; ; ) { - // Save the current index - var index = tokenRegExp.lastIndex, - // Look for the next pattern - ar = tokenRegExp.exec( format ); - - // Append the text before the pattern (or the end of the string if not found) - var preMatch = format.slice( index, ar ? ar.index : format.length ); - quoteCount += appendPreOrPostMatch( preMatch, ret ); - - if ( !ar ) { - break; - } - - // do not replace any matches that occur inside a string literal. - if ( quoteCount % 2 ) { - ret.push( ar[0] ); - continue; - } - - var current = ar[ 0 ], - clength = current.length; - - switch ( current ) { - case "ddd": - //Day of the week, as a three-letter abbreviation - case "dddd": - // Day of the week, using the full name - var names = ( clength === 3 ) ? cal.days.namesAbbr : cal.days.names; - ret.push( names[value.getDay()] ); - break; - case "d": - // Day of month, without leading zero for single-digit days - case "dd": - // Day of month, with leading zero for single-digit days - foundDay = true; - ret.push( - padZeros( getPart(value, 2), clength ) - ); - break; - case "MMM": - // Month, as a three-letter abbreviation - case "MMMM": - // Month, using the full name - var part = getPart( value, 1 ); - ret.push( - ( cal.monthsGenitive && hasDay() ) ? - ( cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ] ) : - ( cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ] ) - ); - break; - case "M": - // Month, as digits, with no leading zero for single-digit months - case "MM": - // Month, as digits, with leading zero for single-digit months - ret.push( - padZeros( getPart(value, 1) + 1, clength ) - ); - break; - case "y": - // Year, as two digits, but with no leading zero for years less than 10 - case "yy": - // Year, as two digits, with leading zero for years less than 10 - case "yyyy": - // Year represented by four full digits - part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra(value, eras), sortable ); - if ( clength < 4 ) { - part = part % 100; - } - ret.push( - padZeros( part, clength ) - ); - break; - case "h": - // Hours with no leading zero for single-digit hours, using 12-hour clock - case "hh": - // Hours with leading zero for single-digit hours, using 12-hour clock - hour = value.getHours() % 12; - if ( hour === 0 ) hour = 12; - ret.push( - padZeros( hour, clength ) - ); - break; - case "H": - // Hours with no leading zero for single-digit hours, using 24-hour clock - case "HH": - // Hours with leading zero for single-digit hours, using 24-hour clock - ret.push( - padZeros( value.getHours(), clength ) - ); - break; - case "m": - // Minutes with no leading zero for single-digit minutes - case "mm": - // Minutes with leading zero for single-digit minutes - ret.push( - padZeros( value.getMinutes(), clength ) - ); - break; - case "s": - // Seconds with no leading zero for single-digit seconds - case "ss": - // Seconds with leading zero for single-digit seconds - ret.push( - padZeros( value.getSeconds(), clength ) - ); - break; - case "t": - // One character am/pm indicator ("a" or "p") - case "tt": - // Multicharacter am/pm indicator - part = value.getHours() < 12 ? ( cal.AM ? cal.AM[0] : " " ) : ( cal.PM ? cal.PM[0] : " " ); - ret.push( clength === 1 ? part.charAt(0) : part ); - break; - case "f": - // Deciseconds - case "ff": - // Centiseconds - case "fff": - // Milliseconds - ret.push( - padZeros( value.getMilliseconds(), 3 ).substr( 0, clength ) - ); - break; - case "z": - // Time zone offset, no leading zero - case "zz": - // Time zone offset with leading zero - hour = value.getTimezoneOffset() / 60; - ret.push( - ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), clength ) - ); - break; - case "zzz": - // Time zone offset with leading zero - hour = value.getTimezoneOffset() / 60; - ret.push( - ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), 2 ) + - // Hard coded ":" separator, rather than using cal.TimeSeparator - // Repeated here for consistency, plus ":" was already assumed in date parsing. - ":" + padZeros( Math.abs(value.getTimezoneOffset() % 60), 2 ) - ); - break; - case "g": - case "gg": - if ( cal.eras ) { - ret.push( - cal.eras[ getEra(value, eras) ].name - ); - } - break; - case "/": - ret.push( cal["/"] ); - break; - default: - throw "Invalid date format pattern \'" + current + "\'."; - } - } - return ret.join( "" ); -}; - -// formatNumber -(function() { - var expandNumber; - - expandNumber = function( number, precision, formatInfo ) { - var groupSizes = formatInfo.groupSizes, - curSize = groupSizes[ 0 ], - curGroupIndex = 1, - factor = Math.pow( 10, precision ), - rounded = Math.round( number * factor ) / factor; - - if ( !isFinite(rounded) ) { - rounded = number; - } - number = rounded; - - var numberString = number+"", - right = "", - split = numberString.split( /e/i ), - exponent = split.length > 1 ? parseInt( split[1], 10 ) : 0; - numberString = split[ 0 ]; - split = numberString.split( "." ); - numberString = split[ 0 ]; - right = split.length > 1 ? split[ 1 ] : ""; - - if ( exponent > 0 ) { - right = zeroPad( right, exponent, false ); - numberString += right.slice( 0, exponent ); - right = right.substr( exponent ); - } - else if ( exponent < 0 ) { - exponent = -exponent; - numberString = zeroPad( numberString, exponent + 1, true ); - right = numberString.slice( -exponent, numberString.length ) + right; - numberString = numberString.slice( 0, -exponent ); - } - - if ( precision > 0 ) { - right = formatInfo[ "." ] + - ( (right.length > precision) ? right.slice(0, precision) : zeroPad(right, precision) ); - } - else { - right = ""; - } - - var stringIndex = numberString.length - 1, - sep = formatInfo[ "," ], - ret = ""; - - while ( stringIndex >= 0 ) { - if ( curSize === 0 || curSize > stringIndex ) { - return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? (sep + ret + right) : right ); - } - ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? (sep + ret) : "" ); - - stringIndex -= curSize; - - if ( curGroupIndex < groupSizes.length ) { - curSize = groupSizes[ curGroupIndex ]; - curGroupIndex++; - } - } - - return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right; - }; - - formatNumber = function( value, format, culture ) { - if ( !isFinite(value) ) { - if ( value === Infinity ) { - return culture.numberFormat.positiveInfinity; - } - if ( value === -Infinity ) { - return culture.numberFormat.negativeInfinity; - } - return culture.numberFormat.NaN; - } - if ( !format || format === "i" ) { - return culture.name.length ? value.toLocaleString() : value.toString(); - } - format = format || "D"; - - var nf = culture.numberFormat, - number = Math.abs( value ), - precision = -1, - pattern; - if ( format.length > 1 ) precision = parseInt( format.slice(1), 10 ); - - var current = format.charAt( 0 ).toUpperCase(), - formatInfo; - - switch ( current ) { - case "D": - pattern = "n"; - number = truncate( number ); - if ( precision !== -1 ) { - number = zeroPad( "" + number, precision, true ); - } - if ( value < 0 ) number = "-" + number; - break; - case "N": - formatInfo = nf; - /* falls through */ - case "C": - formatInfo = formatInfo || nf.currency; - /* falls through */ - case "P": - formatInfo = formatInfo || nf.percent; - pattern = value < 0 ? formatInfo.pattern[ 0 ] : ( formatInfo.pattern[1] || "n" ); - if ( precision === -1 ) precision = formatInfo.decimals; - number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo ); - break; - default: - throw "Bad number format specifier: " + current; - } - - var patternParts = /n|\$|-|%/g, - ret = ""; - for ( ; ; ) { - var index = patternParts.lastIndex, - ar = patternParts.exec( pattern ); - - ret += pattern.slice( index, ar ? ar.index : pattern.length ); - - if ( !ar ) { - break; - } - - switch ( ar[0] ) { - case "n": - ret += number; - break; - case "$": - ret += nf.currency.symbol; - break; - case "-": - // don't make 0 negative - if ( /[1-9]/.test(number) ) { - ret += nf[ "-" ]; - } - break; - case "%": - ret += nf.percent.symbol; - break; - } - } - - return ret; - }; - -}()); - -getTokenRegExp = function() { - // regular expression for matching date and time tokens in format strings. - return (/\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g); -}; - -getEra = function( date, eras ) { - if ( !eras ) return 0; - var start, ticks = date.getTime(); - for ( var i = 0, l = eras.length; i < l; i++ ) { - start = eras[ i ].start; - if ( start === null || ticks >= start ) { - return i; - } - } - return 0; -}; - -getEraYear = function( date, cal, era, sortable ) { - var year = date.getFullYear(); - if ( !sortable && cal.eras ) { - // convert normal gregorian year to era-shifted gregorian - // year by subtracting the era offset - year -= cal.eras[ era ].offset; - } - return year; -}; - -// parseExact -(function() { - var expandYear, - getDayIndex, - getMonthIndex, - getParseRegExp, - outOfRange, - toUpper, - toUpperArray; - - expandYear = function( cal, year ) { - // expands 2-digit year into 4 digits. - if ( year < 100 ) { - var now = new Date(), - era = getEra( now ), - curr = getEraYear( now, cal, era ), - twoDigitYearMax = cal.twoDigitYearMax; - twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax; - year += curr - ( curr % 100 ); - if ( year > twoDigitYearMax ) { - year -= 100; - } - } - return year; - }; - - getDayIndex = function ( cal, value, abbr ) { - var ret, - days = cal.days, - upperDays = cal._upperDays; - if ( !upperDays ) { - cal._upperDays = upperDays = [ - toUpperArray( days.names ), - toUpperArray( days.namesAbbr ), - toUpperArray( days.namesShort ) - ]; - } - value = toUpper( value ); - if ( abbr ) { - ret = arrayIndexOf( upperDays[1], value ); - if ( ret === -1 ) { - ret = arrayIndexOf( upperDays[2], value ); - } - } - else { - ret = arrayIndexOf( upperDays[0], value ); - } - return ret; - }; - - getMonthIndex = function( cal, value, abbr ) { - var months = cal.months, - monthsGen = cal.monthsGenitive || cal.months, - upperMonths = cal._upperMonths, - upperMonthsGen = cal._upperMonthsGen; - if ( !upperMonths ) { - cal._upperMonths = upperMonths = [ - toUpperArray( months.names ), - toUpperArray( months.namesAbbr ) - ]; - cal._upperMonthsGen = upperMonthsGen = [ - toUpperArray( monthsGen.names ), - toUpperArray( monthsGen.namesAbbr ) - ]; - } - value = toUpper( value ); - var i = arrayIndexOf( abbr ? upperMonths[1] : upperMonths[0], value ); - if ( i < 0 ) { - i = arrayIndexOf( abbr ? upperMonthsGen[1] : upperMonthsGen[0], value ); - } - return i; - }; - - getParseRegExp = function( cal, format ) { - // converts a format string into a regular expression with groups that - // can be used to extract date fields from a date string. - // check for a cached parse regex. - var re = cal._parseRegExp; - if ( !re ) { - cal._parseRegExp = re = {}; - } - else { - var reFormat = re[ format ]; - if ( reFormat ) { - return reFormat; - } - } - - // expand single digit formats, then escape regular expression characters. - var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ), - regexp = [ "^" ], - groups = [], - index = 0, - quoteCount = 0, - tokenRegExp = getTokenRegExp(), - match; - - // iterate through each date token found. - while ( (match = tokenRegExp.exec(expFormat)) !== null ) { - var preMatch = expFormat.slice( index, match.index ); - index = tokenRegExp.lastIndex; - - // don't replace any matches that occur inside a string literal. - quoteCount += appendPreOrPostMatch( preMatch, regexp ); - if ( quoteCount % 2 ) { - regexp.push( match[0] ); - continue; - } - - // add a regex group for the token. - var m = match[ 0 ], - len = m.length, - add; - switch ( m ) { - case "dddd": case "ddd": - case "MMMM": case "MMM": - case "gg": case "g": - add = "(\\D+)"; - break; - case "tt": case "t": - add = "(\\D*)"; - break; - case "yyyy": - case "fff": - case "ff": - case "f": - add = "(\\d{" + len + "})"; - break; - case "dd": case "d": - case "MM": case "M": - case "yy": case "y": - case "HH": case "H": - case "hh": case "h": - case "mm": case "m": - case "ss": case "s": - add = "(\\d\\d?)"; - break; - case "zzz": - add = "([+-]?\\d\\d?:\\d{2})"; - break; - case "zz": case "z": - add = "([+-]?\\d\\d?)"; - break; - case "/": - add = "(\\/)"; - break; - default: - throw "Invalid date format pattern \'" + m + "\'."; - } - if ( add ) { - regexp.push( add ); - } - groups.push( match[0] ); - } - appendPreOrPostMatch( expFormat.slice(index), regexp ); - regexp.push( "$" ); - - // allow whitespace to differ when matching formats. - var regexpStr = regexp.join( "" ).replace( /\s+/g, "\\s+" ), - parseRegExp = { "regExp": regexpStr, "groups": groups }; - - // cache the regex for this format. - return re[ format ] = parseRegExp; - }; - - outOfRange = function( value, low, high ) { - return value < low || value > high; - }; - - toUpper = function( value ) { - // "he-IL" has non-breaking space in weekday names. - return value.split( "\u00A0" ).join( " " ).toUpperCase(); - }; - - toUpperArray = function( arr ) { - var results = []; - for ( var i = 0, l = arr.length; i < l; i++ ) { - results[ i ] = toUpper( arr[i] ); - } - return results; - }; - - parseExact = function( value, format, culture ) { - // try to parse the date string by matching against the format string - // while using the specified culture for date field names. - value = trim( value ); - var cal = culture.calendar, - // convert date formats into regular expressions with groupings. - // use the regexp to determine the input format and extract the date fields. - parseInfo = getParseRegExp( cal, format ), - match = new RegExp( parseInfo.regExp ).exec( value ); - if ( match === null ) { - return null; - } - // found a date format that matches the input. - var groups = parseInfo.groups, - era = null, year = null, month = null, date = null, weekDay = null, - hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null, - pmHour = false; - // iterate the format groups to extract and set the date fields. - for ( var j = 0, jl = groups.length; j < jl; j++ ) { - var matchGroup = match[ j + 1 ]; - if ( matchGroup ) { - var current = groups[ j ], - clength = current.length, - matchInt = parseInt( matchGroup, 10 ); - switch ( current ) { - case "dd": case "d": - // Day of month. - date = matchInt; - // check that date is generally in valid range, also checking overflow below. - if ( outOfRange(date, 1, 31) ) return null; - break; - case "MMM": case "MMMM": - month = getMonthIndex( cal, matchGroup, clength === 3 ); - if ( outOfRange(month, 0, 11) ) return null; - break; - case "M": case "MM": - // Month. - month = matchInt - 1; - if ( outOfRange(month, 0, 11) ) return null; - break; - case "y": case "yy": - case "yyyy": - year = clength < 4 ? expandYear( cal, matchInt ) : matchInt; - if ( outOfRange(year, 0, 9999) ) return null; - break; - case "h": case "hh": - // Hours (12-hour clock). - hour = matchInt; - if ( hour === 12 ) hour = 0; - if ( outOfRange(hour, 0, 11) ) return null; - break; - case "H": case "HH": - // Hours (24-hour clock). - hour = matchInt; - if ( outOfRange(hour, 0, 23) ) return null; - break; - case "m": case "mm": - // Minutes. - min = matchInt; - if ( outOfRange(min, 0, 59) ) return null; - break; - case "s": case "ss": - // Seconds. - sec = matchInt; - if ( outOfRange(sec, 0, 59) ) return null; - break; - case "tt": case "t": - // AM/PM designator. - // see if it is standard, upper, or lower case PM. If not, ensure it is at least one of - // the AM tokens. If not, fail the parse for this format. - pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] ); - if ( - !pmHour && ( - !cal.AM || ( matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2] ) - ) - ) return null; - break; - case "f": - // Deciseconds. - case "ff": - // Centiseconds. - case "fff": - // Milliseconds. - msec = matchInt * Math.pow( 10, 3 - clength ); - if ( outOfRange(msec, 0, 999) ) return null; - break; - case "ddd": - // Day of week. - case "dddd": - // Day of week. - weekDay = getDayIndex( cal, matchGroup, clength === 3 ); - if ( outOfRange(weekDay, 0, 6) ) return null; - break; - case "zzz": - // Time zone offset in +/- hours:min. - var offsets = matchGroup.split( /:/ ); - if ( offsets.length !== 2 ) return null; - hourOffset = parseInt( offsets[0], 10 ); - if ( outOfRange(hourOffset, -12, 13) ) return null; - var minOffset = parseInt( offsets[1], 10 ); - if ( outOfRange(minOffset, 0, 59) ) return null; - tzMinOffset = ( hourOffset * 60 ) + ( startsWith(matchGroup, "-") ? -minOffset : minOffset ); - break; - case "z": case "zz": - // Time zone offset in +/- hours. - hourOffset = matchInt; - if ( outOfRange(hourOffset, -12, 13) ) return null; - tzMinOffset = hourOffset * 60; - break; - case "g": case "gg": - var eraName = matchGroup; - if ( !eraName || !cal.eras ) return null; - eraName = trim( eraName.toLowerCase() ); - for ( var i = 0, l = cal.eras.length; i < l; i++ ) { - if ( eraName === cal.eras[i].name.toLowerCase() ) { - era = i; - break; - } - } - // could not find an era with that name - if ( era === null ) return null; - break; - } - } - } - var result = new Date(), defaultYear, convert = cal.convert; - defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear(); - if ( year === null ) { - year = defaultYear; - } - else if ( cal.eras ) { - // year must be shifted to normal gregorian year - // but not if year was not specified, its already normal gregorian - // per the main if clause above. - year += cal.eras[( era || 0 )].offset; - } - // set default day and month to 1 and January, so if unspecified, these are the defaults - // instead of the current day/month. - if ( month === null ) { - month = 0; - } - if ( date === null ) { - date = 1; - } - // now have year, month, and date, but in the culture's calendar. - // convert to gregorian if necessary - if ( convert ) { - result = convert.toGregorian( year, month, date ); - // conversion failed, must be an invalid match - if ( result === null ) return null; - } - else { - // have to set year, month and date together to avoid overflow based on current date. - result.setFullYear( year, month, date ); - // check to see if date overflowed for specified month (only checked 1-31 above). - if ( result.getDate() !== date ) return null; - // invalid day of week. - if ( weekDay !== null && result.getDay() !== weekDay ) { - return null; - } - } - // if pm designator token was found make sure the hours fit the 24-hour clock. - if ( pmHour && hour < 12 ) { - hour += 12; - } - result.setHours( hour, min, sec, msec ); - if ( tzMinOffset !== null ) { - // adjust timezone to utc before applying local offset. - var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() ); - // Safari limits hours and minutes to the range of -127 to 127. We need to use setHours - // to ensure both these fields will not exceed this range. adjustedMin will range - // somewhere between -1440 and 1500, so we only need to split this into hours. - result.setHours( result.getHours() + parseInt(adjustedMin / 60, 10), adjustedMin % 60 ); - } - return result; - }; -}()); - -parseNegativePattern = function( value, nf, negativePattern ) { - var neg = nf[ "-" ], - pos = nf[ "+" ], - ret; - switch ( negativePattern ) { - case "n -": - neg = " " + neg; - pos = " " + pos; - /* falls through */ - case "n-": - if ( endsWith(value, neg) ) { - ret = [ "-", value.substr(0, value.length - neg.length) ]; - } - else if ( endsWith(value, pos) ) { - ret = [ "+", value.substr(0, value.length - pos.length) ]; - } - break; - case "- n": - neg += " "; - pos += " "; - /* falls through */ - case "-n": - if ( startsWith(value, neg) ) { - ret = [ "-", value.substr(neg.length) ]; - } - else if ( startsWith(value, pos) ) { - ret = [ "+", value.substr(pos.length) ]; - } - break; - case "(n)": - if ( startsWith(value, "(") && endsWith(value, ")") ) { - ret = [ "-", value.substr(1, value.length - 2) ]; - } - break; - } - return ret || [ "", value ]; -}; - -// -// public instance functions -// - -Globalize.prototype.findClosestCulture = function( cultureSelector ) { - return Globalize.findClosestCulture.call( this, cultureSelector ); -}; - -Globalize.prototype.format = function( value, format, cultureSelector ) { - return Globalize.format.call( this, value, format, cultureSelector ); -}; - -Globalize.prototype.localize = function( key, cultureSelector ) { - return Globalize.localize.call( this, key, cultureSelector ); -}; - -Globalize.prototype.parseInt = function( value, radix, cultureSelector ) { - return Globalize.parseInt.call( this, value, radix, cultureSelector ); -}; - -Globalize.prototype.parseFloat = function( value, radix, cultureSelector ) { - return Globalize.parseFloat.call( this, value, radix, cultureSelector ); -}; - -Globalize.prototype.culture = function( cultureSelector ) { - return Globalize.culture.call( this, cultureSelector ); -}; - -// -// public singleton functions -// - -Globalize.addCultureInfo = function( cultureName, baseCultureName, info ) { - - var base = {}, - isNew = false; - - if ( typeof cultureName !== "string" ) { - // cultureName argument is optional string. If not specified, assume info is first - // and only argument. Specified info deep-extends current culture. - info = cultureName; - cultureName = this.culture().name; - base = this.cultures[ cultureName ]; - } else if ( typeof baseCultureName !== "string" ) { - // baseCultureName argument is optional string. If not specified, assume info is second - // argument. Specified info deep-extends specified culture. - // If specified culture does not exist, create by deep-extending default - info = baseCultureName; - isNew = ( this.cultures[ cultureName ] == null ); - base = this.cultures[ cultureName ] || this.cultures[ "default" ]; - } else { - // cultureName and baseCultureName specified. Assume a new culture is being created - // by deep-extending an specified base culture - isNew = true; - base = this.cultures[ baseCultureName ]; - } - - this.cultures[ cultureName ] = extend(true, {}, - base, - info - ); - // Make the standard calendar the current culture if it's a new culture - if ( isNew ) { - this.cultures[ cultureName ].calendar = this.cultures[ cultureName ].calendars.standard; - } -}; - -Globalize.findClosestCulture = function( name ) { - var match; - if ( !name ) { - return this.findClosestCulture( this.cultureSelector ) || this.cultures[ "default" ]; - } - if ( typeof name === "string" ) { - name = name.split( "," ); - } - if ( isArray(name) ) { - var lang, - cultures = this.cultures, - list = name, - i, l = list.length, - prioritized = []; - for ( i = 0; i < l; i++ ) { - name = trim( list[i] ); - var pri, parts = name.split( ";" ); - lang = trim( parts[0] ); - if ( parts.length === 1 ) { - pri = 1; - } - else { - name = trim( parts[1] ); - if ( name.indexOf("q=") === 0 ) { - name = name.substr( 2 ); - pri = parseFloat( name ); - pri = isNaN( pri ) ? 0 : pri; - } - else { - pri = 1; - } - } - prioritized.push({ lang: lang, pri: pri }); - } - prioritized.sort(function( a, b ) { - if ( a.pri < b.pri ) { - return 1; - } else if ( a.pri > b.pri ) { - return -1; - } - return 0; - }); - // exact match - for ( i = 0; i < l; i++ ) { - lang = prioritized[ i ].lang; - match = cultures[ lang ]; - if ( match ) { - return match; - } - } - - // neutral language match - for ( i = 0; i < l; i++ ) { - lang = prioritized[ i ].lang; - do { - var index = lang.lastIndexOf( "-" ); - if ( index === -1 ) { - break; - } - // strip off the last part. e.g. en-US => en - lang = lang.substr( 0, index ); - match = cultures[ lang ]; - if ( match ) { - return match; - } - } - while ( 1 ); - } - - // last resort: match first culture using that language - for ( i = 0; i < l; i++ ) { - lang = prioritized[ i ].lang; - for ( var cultureKey in cultures ) { - var culture = cultures[ cultureKey ]; - if ( culture.language === lang ) { - return culture; - } - } - } - } - else if ( typeof name === "object" ) { - return name; - } - return match || null; -}; - -Globalize.format = function( value, format, cultureSelector ) { - var culture = this.findClosestCulture( cultureSelector ); - if ( value instanceof Date ) { - value = formatDate( value, format, culture ); - } - else if ( typeof value === "number" ) { - value = formatNumber( value, format, culture ); - } - return value; -}; - -Globalize.localize = function( key, cultureSelector ) { - return this.findClosestCulture( cultureSelector ).messages[ key ] || - this.cultures[ "default" ].messages[ key ]; -}; - -Globalize.parseDate = function( value, formats, culture ) { - culture = this.findClosestCulture( culture ); - - var date, prop, patterns; - if ( formats ) { - if ( typeof formats === "string" ) { - formats = [ formats ]; - } - if ( formats.length ) { - for ( var i = 0, l = formats.length; i < l; i++ ) { - var format = formats[ i ]; - if ( format ) { - date = parseExact( value, format, culture ); - if ( date ) { - break; - } - } - } - } - } else { - patterns = culture.calendar.patterns; - for ( prop in patterns ) { - date = parseExact( value, patterns[prop], culture ); - if ( date ) { - break; - } - } - } - - return date || null; -}; - -Globalize.parseInt = function( value, radix, cultureSelector ) { - return truncate( Globalize.parseFloat(value, radix, cultureSelector) ); -}; - -Globalize.parseFloat = function( value, radix, cultureSelector ) { - // radix argument is optional - if ( typeof radix !== "number" ) { - cultureSelector = radix; - radix = 10; - } - - var culture = this.findClosestCulture( cultureSelector ); - var ret = NaN, - nf = culture.numberFormat; - - if ( value.indexOf(culture.numberFormat.currency.symbol) > -1 ) { - // remove currency symbol - value = value.replace( culture.numberFormat.currency.symbol, "" ); - // replace decimal seperator - value = value.replace( culture.numberFormat.currency["."], culture.numberFormat["."] ); - } - - //Remove percentage character from number string before parsing - if ( value.indexOf(culture.numberFormat.percent.symbol) > -1){ - value = value.replace( culture.numberFormat.percent.symbol, "" ); - } - - // remove spaces: leading, trailing and between - and number. Used for negative currency pt-BR - value = value.replace( / /g, "" ); - - // allow infinity or hexidecimal - if ( regexInfinity.test(value) ) { - ret = parseFloat( value ); - } - else if ( !radix && regexHex.test(value) ) { - ret = parseInt( value, 16 ); - } - else { - - // determine sign and number - var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ), - sign = signInfo[ 0 ], - num = signInfo[ 1 ]; - - // #44 - try parsing as "(n)" - if ( sign === "" && nf.pattern[0] !== "(n)" ) { - signInfo = parseNegativePattern( value, nf, "(n)" ); - sign = signInfo[ 0 ]; - num = signInfo[ 1 ]; - } - - // try parsing as "-n" - if ( sign === "" && nf.pattern[0] !== "-n" ) { - signInfo = parseNegativePattern( value, nf, "-n" ); - sign = signInfo[ 0 ]; - num = signInfo[ 1 ]; - } - - sign = sign || "+"; - - // determine exponent and number - var exponent, - intAndFraction, - exponentPos = num.indexOf( "e" ); - if ( exponentPos < 0 ) exponentPos = num.indexOf( "E" ); - if ( exponentPos < 0 ) { - intAndFraction = num; - exponent = null; - } - else { - intAndFraction = num.substr( 0, exponentPos ); - exponent = num.substr( exponentPos + 1 ); - } - // determine decimal position - var integer, - fraction, - decSep = nf[ "." ], - decimalPos = intAndFraction.indexOf( decSep ); - if ( decimalPos < 0 ) { - integer = intAndFraction; - fraction = null; - } - else { - integer = intAndFraction.substr( 0, decimalPos ); - fraction = intAndFraction.substr( decimalPos + decSep.length ); - } - // handle groups (e.g. 1,000,000) - var groupSep = nf[ "," ]; - integer = integer.split( groupSep ).join( "" ); - var altGroupSep = groupSep.replace( /\u00A0/g, " " ); - if ( groupSep !== altGroupSep ) { - integer = integer.split( altGroupSep ).join( "" ); - } - // build a natively parsable number string - var p = sign + integer; - if ( fraction !== null ) { - p += "." + fraction; - } - if ( exponent !== null ) { - // exponent itself may have a number patternd - var expSignInfo = parseNegativePattern( exponent, nf, "-n" ); - p += "e" + ( expSignInfo[0] || "+" ) + expSignInfo[ 1 ]; - } - if ( regexParseFloat.test(p) ) { - ret = parseFloat( p ); - } - } - return ret; -}; - -Globalize.culture = function( cultureSelector ) { - // setter - if ( typeof cultureSelector !== "undefined" ) { - this.cultureSelector = cultureSelector; - } - // getter - return this.findClosestCulture( cultureSelector ) || this.cultures[ "default" ]; -}; - -}( this )); \ No newline at end of file diff --git a/external/globalize.js b/external/globalize.js new file mode 120000 index 00000000000..6e8e2e25767 --- /dev/null +++ b/external/globalize.js @@ -0,0 +1 @@ +/home/xavier/jquery/globalize/dist/globalize.js \ No newline at end of file diff --git a/external/localization.js b/external/localization.js index d81e997b5e7..4c866f23b71 100644 --- a/external/localization.js +++ b/external/localization.js @@ -1,436 +1,2630 @@ -// regional data +/** + * CLDR locale data + */ +Globalize.load({ + "main": { + "en": { + "identity": { + "version": { + "_cldrVersion": "24", + "_number": "$Revision: 9287 $" + }, + "generation": { + "_date": "$Date: 2013-08-28 21:32:04 -0500 (Wed, 28 Aug 2013) $" + }, + "language": "en" + }, + "dates": { + "calendars": { + "gregorian": { + "months": { + "format": { + "abbreviated": { + "1": "Jan", + "2": "Feb", + "3": "Mar", + "4": "Apr", + "5": "May", + "6": "Jun", + "7": "Jul", + "8": "Aug", + "9": "Sep", + "10": "Oct", + "11": "Nov", + "12": "Dec" + }, + "narrow": { + "1": "J", + "2": "F", + "3": "M", + "4": "A", + "5": "M", + "6": "J", + "7": "J", + "8": "A", + "9": "S", + "10": "O", + "11": "N", + "12": "D" + }, + "wide": { + "1": "January", + "2": "February", + "3": "March", + "4": "April", + "5": "May", + "6": "June", + "7": "July", + "8": "August", + "9": "September", + "10": "October", + "11": "November", + "12": "December" + } + }, + "stand-alone": { + "abbreviated": { + "1": "Jan", + "2": "Feb", + "3": "Mar", + "4": "Apr", + "5": "May", + "6": "Jun", + "7": "Jul", + "8": "Aug", + "9": "Sep", + "10": "Oct", + "11": "Nov", + "12": "Dec" + }, + "narrow": { + "1": "J", + "2": "F", + "3": "M", + "4": "A", + "5": "M", + "6": "J", + "7": "J", + "8": "A", + "9": "S", + "10": "O", + "11": "N", + "12": "D" + }, + "wide": { + "1": "January", + "2": "February", + "3": "March", + "4": "April", + "5": "May", + "6": "June", + "7": "July", + "8": "August", + "9": "September", + "10": "October", + "11": "November", + "12": "December" + } + } + }, + "days": { + "format": { + "abbreviated": { + "sun": "Sun", + "mon": "Mon", + "tue": "Tue", + "wed": "Wed", + "thu": "Thu", + "fri": "Fri", + "sat": "Sat" + }, + "narrow": { + "sun": "S", + "mon": "M", + "tue": "T", + "wed": "W", + "thu": "T", + "fri": "F", + "sat": "S" + }, + "short": { + "sun": "Su", + "mon": "Mo", + "tue": "Tu", + "wed": "We", + "thu": "Th", + "fri": "Fr", + "sat": "Sa" + }, + "wide": { + "sun": "Sunday", + "mon": "Monday", + "tue": "Tuesday", + "wed": "Wednesday", + "thu": "Thursday", + "fri": "Friday", + "sat": "Saturday" + } + }, + "stand-alone": { + "abbreviated": { + "sun": "Sun", + "mon": "Mon", + "tue": "Tue", + "wed": "Wed", + "thu": "Thu", + "fri": "Fri", + "sat": "Sat" + }, + "narrow": { + "sun": "S", + "mon": "M", + "tue": "T", + "wed": "W", + "thu": "T", + "fri": "F", + "sat": "S" + }, + "short": { + "sun": "Su", + "mon": "Mo", + "tue": "Tu", + "wed": "We", + "thu": "Th", + "fri": "Fr", + "sat": "Sa" + }, + "wide": { + "sun": "Sunday", + "mon": "Monday", + "tue": "Tuesday", + "wed": "Wednesday", + "thu": "Thursday", + "fri": "Friday", + "sat": "Saturday" + } + } + }, + "quarters": { + "format": { + "abbreviated": { + "1": "Q1", + "2": "Q2", + "3": "Q3", + "4": "Q4" + }, + "narrow": { + "1": "1", + "2": "2", + "3": "3", + "4": "4" + }, + "wide": { + "1": "1st quarter", + "2": "2nd quarter", + "3": "3rd quarter", + "4": "4th quarter" + } + }, + "stand-alone": { + "abbreviated": { + "1": "Q1", + "2": "Q2", + "3": "Q3", + "4": "Q4" + }, + "narrow": { + "1": "1", + "2": "2", + "3": "3", + "4": "4" + }, + "wide": { + "1": "1st quarter", + "2": "2nd quarter", + "3": "3rd quarter", + "4": "4th quarter" + } + } + }, + "dayPeriods": { + "format": { + "abbreviated": { + "am": "AM", + "am-alt-variant": "a.m.", + "noon": "noon", + "pm": "PM", + "pm-alt-variant": "p.m." + }, + "narrow": { + "am": "a", + "am-alt-variant": "a.m.", + "noon": "n", + "pm": "p", + "pm-alt-variant": "p.m." + }, + "wide": { + "am": "AM", + "am-alt-variant": "a.m.", + "noon": "noon", + "pm": "PM", + "pm-alt-variant": "p.m." + } + }, + "stand-alone": { + "abbreviated": { + "am": "AM", + "am-alt-variant": "a.m.", + "noon": "noon", + "pm": "PM", + "pm-alt-variant": "p.m." + }, + "narrow": { + "am": "a", + "am-alt-variant": "a.m.", + "noon": "n", + "pm": "p", + "pm-alt-variant": "p.m." + }, + "wide": { + "am": "AM", + "am-alt-variant": "a.m.", + "noon": "noon", + "pm": "PM", + "pm-alt-variant": "p.m." + } + } + }, + "eras": { + "eraNames": { + "0": "Before Christ", + "0-alt-variant": "Before Common Era", + "1": "Anno Domini", + "1-alt-variant": "Common Era" + }, + "eraAbbr": { + "0": "BC", + "0-alt-variant": "BCE", + "1": "AD", + "1-alt-variant": "CE" + }, + "eraNarrow": { + "0": "B", + "0-alt-variant": "BCE", + "1": "A", + "1-alt-variant": "CE" + } + }, + "dateFormats": { + "full": "EEEE, MMMM d, y", + "long": "MMMM d, y", + "medium": "MMM d, y", + "short": "M/d/yy" + }, + "timeFormats": { + "full": "h:mm:ss a zzzz", + "long": "h:mm:ss a z", + "medium": "h:mm:ss a", + "short": "h:mm a" + }, + "dateTimeFormats": { + "full": "{1} 'at' {0}", + "long": "{1} 'at' {0}", + "medium": "{1}, {0}", + "short": "{1}, {0}", + "availableFormats": { + "d": "d", + "Ed": "d E", + "Ehm": "E h:mm a", + "EHm": "E HH:mm", + "Ehms": "E h:mm:ss a", + "EHms": "E HH:mm:ss", + "Gy": "y G", + "GyMMM": "MMM y G", + "GyMMMd": "MMM d, y G", + "GyMMMEd": "E, MMM d, y G", + "h": "h a", + "H": "HH", + "hm": "h:mm a", + "Hm": "HH:mm", + "hms": "h:mm:ss a", + "Hms": "HH:mm:ss", + "M": "L", + "Md": "M/d", + "MEd": "E, M/d", + "MMM": "LLL", + "MMMd": "MMM d", + "MMMEd": "E, MMM d", + "ms": "mm:ss", + "y": "y", + "yM": "M/y", + "yMd": "M/d/y", + "yMEd": "E, M/d/y", + "yMMM": "MMM y", + "yMMMd": "MMM d, y", + "yMMMEd": "E, MMM d, y", + "yQQQ": "QQQ y", + "yQQQQ": "QQQQ y" + }, + "appendItems": { + "Day": "{0} ({2}: {1})", + "Day-Of-Week": "{0} {1}", + "Era": "{0} {1}", + "Hour": "{0} ({2}: {1})", + "Minute": "{0} ({2}: {1})", + "Month": "{0} ({2}: {1})", + "Quarter": "{0} ({2}: {1})", + "Second": "{0} ({2}: {1})", + "Timezone": "{0} {1}", + "Week": "{0} ({2}: {1})", + "Year": "{0} {1}" + }, + "intervalFormats": { + "intervalFormatFallback": "{0} – {1}", + "d": { + "d": "d – d" + }, + "h": { + "a": "h a – h a", + "h": "h – h a" + }, + "H": { + "H": "HH – HH" + }, + "hm": { + "a": "h:mm a – h:mm a", + "h": "h:mm – h:mm a", + "m": "h:mm – h:mm a" + }, + "Hm": { + "H": "HH:mm – HH:mm", + "m": "HH:mm – HH:mm" + }, + "hmv": { + "a": "h:mm a – h:mm a v", + "h": "h:mm – h:mm a v", + "m": "h:mm – h:mm a v" + }, + "Hmv": { + "H": "HH:mm – HH:mm v", + "m": "HH:mm – HH:mm v" + }, + "hv": { + "a": "h a – h a v", + "h": "h – h a v" + }, + "Hv": { + "H": "HH – HH v" + }, + "M": { + "M": "M – M" + }, + "Md": { + "d": "M/d – M/d", + "M": "M/d – M/d" + }, + "MEd": { + "d": "E, M/d – E, M/d", + "M": "E, M/d – E, M/d" + }, + "MMM": { + "M": "MMM – MMM" + }, + "MMMd": { + "d": "MMM d – d", + "M": "MMM d – MMM d" + }, + "MMMEd": { + "d": "E, MMM d – E, MMM d", + "M": "E, MMM d – E, MMM d" + }, + "y": { + "y": "y – y" + }, + "yM": { + "M": "M/y – M/y", + "y": "M/y – M/y" + }, + "yMd": { + "d": "M/d/y – M/d/y", + "M": "M/d/y – M/d/y", + "y": "M/d/y – M/d/y" + }, + "yMEd": { + "d": "E, M/d/y – E, M/d/y", + "M": "E, M/d/y – E, M/d/y", + "y": "E, M/d/y – E, M/d/y" + }, + "yMMM": { + "M": "MMM – MMM y", + "y": "MMM y – MMM y" + }, + "yMMMd": { + "d": "MMM d – d, y", + "M": "MMM d – MMM d, y", + "y": "MMM d, y – MMM d, y" + }, + "yMMMEd": { + "d": "E, MMM d – E, MMM d, y", + "M": "E, MMM d – E, MMM d, y", + "y": "E, MMM d, y – E, MMM d, y" + }, + "yMMMM": { + "M": "MMMM – MMMM y", + "y": "MMMM y – MMMM y" + } + } + } + } + } + } + } + } +}); + +/** + * CLDR supplemental data + */ + +// likelySubtags +Globalize.load({ + "supplemental": { + "version": { + "_cldrVersion": "24", + "_number": "$Revision: 9305 $" + }, + "generation": { + "_date": "$Date: 2013-09-04 09:50:17 -0500 (Wed, 04 Sep 2013) $" + }, + "likelySubtags": { + "aa": "aa_Latn_ET", + "ab": "ab_Cyrl_GE", + "ace": "ace_Latn_ID", + "ady": "ady_Cyrl_RU", + "af": "af_Latn_ZA", + "agq": "agq_Latn_CM", + "ak": "ak_Latn_GH", + "alt": "alt_Cyrl_RU", + "am": "am_Ethi_ET", + "amo": "amo_Latn_NG", + "ar": "ar_Arab_EG", + "as": "as_Beng_IN", + "asa": "asa_Latn_TZ", + "ast": "ast_Latn_ES", + "av": "av_Cyrl_RU", + "awa": "awa_Deva_IN", + "ay": "ay_Latn_BO", + "az": "az_Latn_AZ", + "az_Arab": "az_Arab_IR", + "az_IR": "az_Arab_IR", + "az_RU": "az_Cyrl_RU", + "ba": "ba_Cyrl_RU", + "bal": "bal_Arab_PK", + "ban": "ban_Latn_ID", + "bas": "bas_Latn_CM", + "bax": "bax_Bamu_CM", + "bbc": "bbc_Latn_ID", + "be": "be_Cyrl_BY", + "bem": "bem_Latn_ZM", + "bez": "bez_Latn_TZ", + "bfq": "bfq_Taml_IN", + "bft": "bft_Arab_PK", + "bfy": "bfy_Deva_IN", + "bg": "bg_Cyrl_BG", + "bhb": "bhb_Deva_IN", + "bho": "bho_Deva_IN", + "bi": "bi_Latn_VU", + "bik": "bik_Latn_PH", + "bin": "bin_Latn_NG", + "bjj": "bjj_Deva_IN", + "bku": "bku_Latn_PH", + "bm": "bm_Latn_ML", + "bn": "bn_Beng_BD", + "bo": "bo_Tibt_CN", + "bqv": "bqv_Latn_CI", + "br": "br_Latn_FR", + "bra": "bra_Deva_IN", + "brx": "brx_Deva_IN", + "bs": "bs_Latn_BA", + "bss": "bss_Latn_CM", + "btv": "btv_Deva_PK", + "bua": "bua_Cyrl_RU", + "buc": "buc_Latn_YT", + "bug": "bug_Latn_ID", + "bya": "bya_Latn_ID", + "byn": "byn_Ethi_ER", + "ca": "ca_Latn_ES", + "cch": "cch_Latn_NG", + "ccp": "ccp_Beng_IN", + "ce": "ce_Cyrl_RU", + "ceb": "ceb_Latn_PH", + "cgg": "cgg_Latn_UG", + "ch": "ch_Latn_GU", + "chk": "chk_Latn_FM", + "chm": "chm_Cyrl_RU", + "chp": "chp_Latn_CA", + "chr": "chr_Cher_US", + "cja": "cja_Arab_KH", + "cjm": "cjm_Cham_VN", + "ckb": "ckb_Arab_IQ", + "co": "co_Latn_FR", + "cr": "cr_Cans_CA", + "crk": "crk_Cans_CA", + "cs": "cs_Latn_CZ", + "csb": "csb_Latn_PL", + "cv": "cv_Cyrl_RU", + "cy": "cy_Latn_GB", + "da": "da_Latn_DK", + "dar": "dar_Cyrl_RU", + "dav": "dav_Latn_KE", + "de": "de_Latn_DE", + "den": "den_Latn_CA", + "dgr": "dgr_Latn_CA", + "dje": "dje_Latn_NE", + "doi": "doi_Arab_IN", + "dsb": "dsb_Latn_DE", + "dua": "dua_Latn_CM", + "dv": "dv_Thaa_MV", + "dyo": "dyo_Latn_SN", + "dyu": "dyu_Latn_BF", + "dz": "dz_Tibt_BT", + "ebu": "ebu_Latn_KE", + "ee": "ee_Latn_GH", + "efi": "efi_Latn_NG", + "el": "el_Grek_GR", + "en": "en_Latn_US", + "eo": "eo_Latn_001", + "es": "es_Latn_ES", + "et": "et_Latn_EE", + "eu": "eu_Latn_ES", + "ewo": "ewo_Latn_CM", + "fa": "fa_Arab_IR", + "fan": "fan_Latn_GQ", + "ff": "ff_Latn_SN", + "fi": "fi_Latn_FI", + "fil": "fil_Latn_PH", + "fj": "fj_Latn_FJ", + "fo": "fo_Latn_FO", + "fon": "fon_Latn_BJ", + "fr": "fr_Latn_FR", + "fur": "fur_Latn_IT", + "fy": "fy_Latn_NL", + "ga": "ga_Latn_IE", + "gaa": "gaa_Latn_GH", + "gag": "gag_Latn_MD", + "gbm": "gbm_Deva_IN", + "gcr": "gcr_Latn_GF", + "gd": "gd_Latn_GB", + "gez": "gez_Ethi_ET", + "gil": "gil_Latn_KI", + "gl": "gl_Latn_ES", + "gn": "gn_Latn_PY", + "gon": "gon_Telu_IN", + "gor": "gor_Latn_ID", + "grt": "grt_Beng_IN", + "gsw": "gsw_Latn_CH", + "gu": "gu_Gujr_IN", + "guz": "guz_Latn_KE", + "gv": "gv_Latn_IM", + "gwi": "gwi_Latn_CA", + "ha": "ha_Latn_NG", + "ha_CM": "ha_Arab_CM", + "ha_SD": "ha_Arab_SD", + "haw": "haw_Latn_US", + "he": "he_Hebr_IL", + "hi": "hi_Deva_IN", + "hil": "hil_Latn_PH", + "hne": "hne_Deva_IN", + "hnn": "hnn_Latn_PH", + "ho": "ho_Latn_PG", + "hoc": "hoc_Deva_IN", + "hoj": "hoj_Deva_IN", + "hr": "hr_Latn_HR", + "ht": "ht_Latn_HT", + "hu": "hu_Latn_HU", + "hy": "hy_Armn_AM", + "ia": "ia_Latn_FR", + "ibb": "ibb_Latn_NG", + "id": "id_Latn_ID", + "ig": "ig_Latn_NG", + "ii": "ii_Yiii_CN", + "ik": "ik_Latn_US", + "ilo": "ilo_Latn_PH", + "in": "in_Latn_ID", + "inh": "inh_Cyrl_RU", + "is": "is_Latn_IS", + "it": "it_Latn_IT", + "iu": "iu_Cans_CA", + "iw": "iw_Hebr_IL", + "ja": "ja_Jpan_JP", + "jgo": "jgo_Latn_CM", + "ji": "ji_Hebr_UA", + "jmc": "jmc_Latn_TZ", + "jv": "jv_Latn_ID", + "jw": "jw_Latn_ID", + "ka": "ka_Geor_GE", + "kaa": "kaa_Cyrl_UZ", + "kab": "kab_Latn_DZ", + "kaj": "kaj_Latn_NG", + "kam": "kam_Latn_KE", + "kbd": "kbd_Cyrl_RU", + "kcg": "kcg_Latn_NG", + "kde": "kde_Latn_TZ", + "kdt": "kdt_Thai_TH", + "kea": "kea_Latn_CV", + "ken": "ken_Latn_CM", + "kfo": "kfo_Latn_CI", + "kfr": "kfr_Deva_IN", + "kg": "kg_Latn_CD", + "kha": "kha_Latn_IN", + "khb": "khb_Talu_CN", + "khq": "khq_Latn_ML", + "kht": "kht_Mymr_IN", + "ki": "ki_Latn_KE", + "kj": "kj_Latn_NA", + "kk": "kk_Cyrl_KZ", + "kk_AF": "kk_Arab_AF", + "kk_Arab": "kk_Arab_CN", + "kk_CN": "kk_Arab_CN", + "kk_IR": "kk_Arab_IR", + "kk_MN": "kk_Arab_MN", + "kkj": "kkj_Latn_CM", + "kl": "kl_Latn_GL", + "kln": "kln_Latn_KE", + "km": "km_Khmr_KH", + "kmb": "kmb_Latn_AO", + "kn": "kn_Knda_IN", + "ko": "ko_Kore_KR", + "koi": "koi_Cyrl_RU", + "kok": "kok_Deva_IN", + "kos": "kos_Latn_FM", + "kpe": "kpe_Latn_LR", + "krc": "krc_Cyrl_RU", + "kri": "kri_Latn_SL", + "krl": "krl_Latn_RU", + "kru": "kru_Deva_IN", + "ks": "ks_Arab_IN", + "ksb": "ksb_Latn_TZ", + "ksf": "ksf_Latn_CM", + "ksh": "ksh_Latn_DE", + "ku": "ku_Latn_TR", + "ku_Arab": "ku_Arab_IQ", + "ku_LB": "ku_Arab_LB", + "kum": "kum_Cyrl_RU", + "kv": "kv_Cyrl_RU", + "kw": "kw_Latn_GB", + "ky": "ky_Cyrl_KG", + "ky_Arab": "ky_Arab_CN", + "ky_CN": "ky_Arab_CN", + "ky_Latn": "ky_Latn_TR", + "ky_TR": "ky_Latn_TR", + "la": "la_Latn_VA", + "lag": "lag_Latn_TZ", + "lah": "lah_Arab_PK", + "lb": "lb_Latn_LU", + "lbe": "lbe_Cyrl_RU", + "lcp": "lcp_Thai_CN", + "lep": "lep_Lepc_IN", + "lez": "lez_Cyrl_RU", + "lg": "lg_Latn_UG", + "li": "li_Latn_NL", + "lif": "lif_Deva_NP", + "lis": "lis_Lisu_CN", + "lki": "lki_Arab_IR", + "lkt": "lkt_Latn_US", + "lmn": "lmn_Telu_IN", + "ln": "ln_Latn_CD", + "lo": "lo_Laoo_LA", + "lol": "lol_Latn_CD", + "lt": "lt_Latn_LT", + "lu": "lu_Latn_CD", + "lua": "lua_Latn_CD", + "luo": "luo_Latn_KE", + "luy": "luy_Latn_KE", + "lv": "lv_Latn_LV", + "lwl": "lwl_Thai_TH", + "mad": "mad_Latn_ID", + "mag": "mag_Deva_IN", + "mai": "mai_Deva_IN", + "mak": "mak_Latn_ID", + "man": "man_Latn_GM", + "man_GN": "man_Nkoo_GN", + "man_Nkoo": "man_Nkoo_GN", + "mas": "mas_Latn_KE", + "mdf": "mdf_Cyrl_RU", + "mdh": "mdh_Latn_PH", + "mdr": "mdr_Latn_ID", + "men": "men_Latn_SL", + "mer": "mer_Latn_KE", + "mfe": "mfe_Latn_MU", + "mg": "mg_Latn_MG", + "mgh": "mgh_Latn_MZ", + "mgo": "mgo_Latn_CM", + "mh": "mh_Latn_MH", + "mi": "mi_Latn_NZ", + "min": "min_Latn_ID", + "mk": "mk_Cyrl_MK", + "ml": "ml_Mlym_IN", + "mn": "mn_Cyrl_MN", + "mn_CN": "mn_Mong_CN", + "mn_Mong": "mn_Mong_CN", + "mni": "mni_Beng_IN", + "mnw": "mnw_Mymr_MM", + "mo": "mo_Latn_RO", + "mos": "mos_Latn_BF", + "mr": "mr_Deva_IN", + "ms": "ms_Latn_MY", + "ms_CC": "ms_Arab_CC", + "ms_ID": "ms_Arab_ID", + "mt": "mt_Latn_MT", + "mua": "mua_Latn_CM", + "mwr": "mwr_Deva_IN", + "my": "my_Mymr_MM", + "myv": "myv_Cyrl_RU", + "na": "na_Latn_NR", + "nap": "nap_Latn_IT", + "naq": "naq_Latn_NA", + "nb": "nb_Latn_NO", + "nd": "nd_Latn_ZW", + "nds": "nds_Latn_DE", + "ne": "ne_Deva_NP", + "new": "new_Deva_NP", + "ng": "ng_Latn_NA", + "niu": "niu_Latn_NU", + "nl": "nl_Latn_NL", + "nmg": "nmg_Latn_CM", + "nn": "nn_Latn_NO", + "nnh": "nnh_Latn_CM", + "no": "no_Latn_NO", + "nod": "nod_Lana_TH", + "nr": "nr_Latn_ZA", + "nso": "nso_Latn_ZA", + "nus": "nus_Latn_SD", + "nv": "nv_Latn_US", + "ny": "ny_Latn_MW", + "nym": "nym_Latn_TZ", + "nyn": "nyn_Latn_UG", + "oc": "oc_Latn_FR", + "om": "om_Latn_ET", + "or": "or_Orya_IN", + "os": "os_Cyrl_GE", + "pa": "pa_Guru_IN", + "pa_Arab": "pa_Arab_PK", + "pa_PK": "pa_Arab_PK", + "pag": "pag_Latn_PH", + "pam": "pam_Latn_PH", + "pap": "pap_Latn_AW", + "pau": "pau_Latn_PW", + "pl": "pl_Latn_PL", + "pon": "pon_Latn_FM", + "prd": "prd_Arab_IR", + "ps": "ps_Arab_AF", + "pt": "pt_Latn_BR", + "qu": "qu_Latn_PE", + "raj": "raj_Latn_IN", + "rcf": "rcf_Latn_RE", + "rej": "rej_Latn_ID", + "rjs": "rjs_Deva_NP", + "rkt": "rkt_Beng_BD", + "rm": "rm_Latn_CH", + "rn": "rn_Latn_BI", + "ro": "ro_Latn_RO", + "rof": "rof_Latn_TZ", + "ru": "ru_Cyrl_RU", + "rw": "rw_Latn_RW", + "rwk": "rwk_Latn_TZ", + "sa": "sa_Deva_IN", + "saf": "saf_Latn_GH", + "sah": "sah_Cyrl_RU", + "saq": "saq_Latn_KE", + "sas": "sas_Latn_ID", + "sat": "sat_Latn_IN", + "saz": "saz_Saur_IN", + "sbp": "sbp_Latn_TZ", + "scn": "scn_Latn_IT", + "sco": "sco_Latn_GB", + "sd": "sd_Arab_PK", + "sd_Deva": "sd_Deva_IN", + "sdh": "sdh_Arab_IR", + "se": "se_Latn_NO", + "seh": "seh_Latn_MZ", + "ses": "ses_Latn_ML", + "sg": "sg_Latn_CF", + "shi": "shi_Tfng_MA", + "shn": "shn_Mymr_MM", + "si": "si_Sinh_LK", + "sid": "sid_Latn_ET", + "sk": "sk_Latn_SK", + "sl": "sl_Latn_SI", + "sm": "sm_Latn_WS", + "sma": "sma_Latn_SE", + "smj": "smj_Latn_SE", + "smn": "smn_Latn_FI", + "sms": "sms_Latn_FI", + "sn": "sn_Latn_ZW", + "snk": "snk_Latn_ML", + "so": "so_Latn_SO", + "sq": "sq_Latn_AL", + "sr": "sr_Cyrl_RS", + "sr_ME": "sr_Latn_ME", + "sr_RO": "sr_Latn_RO", + "sr_RU": "sr_Latn_RU", + "sr_TR": "sr_Latn_TR", + "srn": "srn_Latn_SR", + "srr": "srr_Latn_SN", + "ss": "ss_Latn_ZA", + "ssy": "ssy_Latn_ER", + "st": "st_Latn_ZA", + "su": "su_Latn_ID", + "suk": "suk_Latn_TZ", + "sus": "sus_Latn_GN", + "sv": "sv_Latn_SE", + "sw": "sw_Latn_TZ", + "swb": "swb_Arab_YT", + "swc": "swc_Latn_CD", + "syl": "syl_Beng_BD", + "syr": "syr_Syrc_IQ", + "ta": "ta_Taml_IN", + "tbw": "tbw_Latn_PH", + "tcy": "tcy_Knda_IN", + "tdd": "tdd_Tale_CN", + "te": "te_Telu_IN", + "tem": "tem_Latn_SL", + "teo": "teo_Latn_UG", + "tet": "tet_Latn_TL", + "tg": "tg_Cyrl_TJ", + "tg_Arab": "tg_Arab_PK", + "tg_PK": "tg_Arab_PK", + "th": "th_Thai_TH", + "ti": "ti_Ethi_ET", + "tig": "tig_Ethi_ER", + "tiv": "tiv_Latn_NG", + "tk": "tk_Latn_TM", + "tkl": "tkl_Latn_TK", + "tl": "tl_Latn_PH", + "tmh": "tmh_Latn_NE", + "tn": "tn_Latn_ZA", + "to": "to_Latn_TO", + "tpi": "tpi_Latn_PG", + "tr": "tr_Latn_TR", + "trv": "trv_Latn_TW", + "ts": "ts_Latn_ZA", + "tsg": "tsg_Latn_PH", + "tt": "tt_Cyrl_RU", + "tts": "tts_Thai_TH", + "tum": "tum_Latn_MW", + "tvl": "tvl_Latn_TV", + "twq": "twq_Latn_NE", + "ty": "ty_Latn_PF", + "tyv": "tyv_Cyrl_RU", + "tzm": "tzm_Latn_MA", + "udm": "udm_Cyrl_RU", + "ug": "ug_Arab_CN", + "ug_Cyrl": "ug_Cyrl_KZ", + "ug_KZ": "ug_Cyrl_KZ", + "ug_MN": "ug_Cyrl_MN", + "uk": "uk_Cyrl_UA", + "uli": "uli_Latn_FM", + "umb": "umb_Latn_AO", + "und": "en_Latn_US", + "und_AD": "ca_Latn_AD", + "und_AE": "ar_Arab_AE", + "und_AF": "fa_Arab_AF", + "und_AL": "sq_Latn_AL", + "und_AM": "hy_Armn_AM", + "und_AO": "pt_Latn_AO", + "und_AQ": "und_Latn_AQ", + "und_AR": "es_Latn_AR", + "und_Arab": "ar_Arab_EG", + "und_Arab_CC": "ms_Arab_CC", + "und_Arab_CN": "ug_Arab_CN", + "und_Arab_GB": "ks_Arab_GB", + "und_Arab_ID": "ms_Arab_ID", + "und_Arab_IN": "ur_Arab_IN", + "und_Arab_KH": "cja_Arab_KH", + "und_Arab_MN": "kk_Arab_MN", + "und_Arab_MU": "ur_Arab_MU", + "und_Arab_NG": "ha_Arab_NG", + "und_Arab_PK": "ur_Arab_PK", + "und_Arab_TJ": "fa_Arab_TJ", + "und_Arab_TR": "zza_Arab_TR", + "und_Arab_YT": "swb_Arab_YT", + "und_Armi": "arc_Armi_IR", + "und_Armn": "hy_Armn_AM", + "und_AS": "sm_Latn_AS", + "und_AT": "de_Latn_AT", + "und_Avst": "ae_Avst_IR", + "und_AW": "nl_Latn_AW", + "und_AX": "sv_Latn_AX", + "und_AZ": "az_Latn_AZ", + "und_BA": "bs_Latn_BA", + "und_Bali": "ban_Bali_ID", + "und_Bamu": "bax_Bamu_CM", + "und_Batk": "bbc_Batk_ID", + "und_BD": "bn_Beng_BD", + "und_BE": "nl_Latn_BE", + "und_Beng": "bn_Beng_BD", + "und_BF": "fr_Latn_BF", + "und_BG": "bg_Cyrl_BG", + "und_BH": "ar_Arab_BH", + "und_BI": "rn_Latn_BI", + "und_BJ": "fr_Latn_BJ", + "und_BL": "fr_Latn_BL", + "und_BN": "ms_Latn_BN", + "und_BO": "es_Latn_BO", + "und_Bopo": "zh_Bopo_TW", + "und_BQ": "pap_Latn_BQ", + "und_BR": "pt_Latn_BR", + "und_Brah": "pra_Brah_IN", + "und_Brai": "und_Brai_FR", + "und_BT": "dz_Tibt_BT", + "und_Bugi": "bug_Bugi_ID", + "und_Buhd": "bku_Buhd_PH", + "und_BV": "und_Latn_BV", + "und_BY": "be_Cyrl_BY", + "und_Cakm": "ccp_Cakm_BD", + "und_Cans": "cr_Cans_CA", + "und_Cari": "xcr_Cari_TR", + "und_CD": "sw_Latn_CD", + "und_CF": "fr_Latn_CF", + "und_CG": "fr_Latn_CG", + "und_CH": "de_Latn_CH", + "und_Cham": "cjm_Cham_VN", + "und_Cher": "chr_Cher_US", + "und_CI": "fr_Latn_CI", + "und_CL": "es_Latn_CL", + "und_CM": "fr_Latn_CM", + "und_CN": "zh_Hans_CN", + "und_CO": "es_Latn_CO", + "und_Copt": "cop_Copt_EG", + "und_CP": "und_Latn_CP", + "und_Cprt": "grc_Cprt_CY", + "und_CR": "es_Latn_CR", + "und_CU": "es_Latn_CU", + "und_CV": "pt_Latn_CV", + "und_CW": "pap_Latn_CW", + "und_CY": "el_Grek_CY", + "und_Cyrl": "ru_Cyrl_RU", + "und_Cyrl_AL": "mk_Cyrl_AL", + "und_Cyrl_BA": "sr_Cyrl_BA", + "und_Cyrl_GE": "ab_Cyrl_GE", + "und_Cyrl_GR": "mk_Cyrl_GR", + "und_Cyrl_MD": "uk_Cyrl_MD", + "und_Cyrl_PL": "be_Cyrl_PL", + "und_Cyrl_RO": "bg_Cyrl_RO", + "und_Cyrl_SK": "uk_Cyrl_SK", + "und_Cyrl_TR": "kbd_Cyrl_TR", + "und_Cyrl_XK": "sr_Cyrl_XK", + "und_CZ": "cs_Latn_CZ", + "und_DE": "de_Latn_DE", + "und_Deva": "hi_Deva_IN", + "und_Deva_BT": "ne_Deva_BT", + "und_Deva_MU": "bho_Deva_MU", + "und_Deva_PK": "btv_Deva_PK", + "und_DJ": "aa_Latn_DJ", + "und_DK": "da_Latn_DK", + "und_DO": "es_Latn_DO", + "und_DZ": "ar_Arab_DZ", + "und_EA": "es_Latn_EA", + "und_EC": "es_Latn_EC", + "und_EE": "et_Latn_EE", + "und_EG": "ar_Arab_EG", + "und_Egyp": "egy_Egyp_EG", + "und_EH": "ar_Arab_EH", + "und_ER": "ti_Ethi_ER", + "und_ES": "es_Latn_ES", + "und_ET": "am_Ethi_ET", + "und_Ethi": "am_Ethi_ET", + "und_FI": "fi_Latn_FI", + "und_FM": "chk_Latn_FM", + "und_FO": "fo_Latn_FO", + "und_FR": "fr_Latn_FR", + "und_GA": "fr_Latn_GA", + "und_GE": "ka_Geor_GE", + "und_Geor": "ka_Geor_GE", + "und_GF": "fr_Latn_GF", + "und_GH": "ak_Latn_GH", + "und_GL": "kl_Latn_GL", + "und_Glag": "cu_Glag_BG", + "und_GN": "fr_Latn_GN", + "und_Goth": "got_Goth_UA", + "und_GP": "fr_Latn_GP", + "und_GQ": "es_Latn_GQ", + "und_GR": "el_Grek_GR", + "und_Grek": "el_Grek_GR", + "und_GS": "und_Latn_GS", + "und_GT": "es_Latn_GT", + "und_Gujr": "gu_Gujr_IN", + "und_Guru": "pa_Guru_IN", + "und_GW": "pt_Latn_GW", + "und_Hang": "ko_Hang_KR", + "und_Hani": "zh_Hani_CN", + "und_Hano": "hnn_Hano_PH", + "und_Hans": "zh_Hans_CN", + "und_Hant": "zh_Hant_TW", + "und_Hebr": "he_Hebr_IL", + "und_Hebr_CA": "yi_Hebr_CA", + "und_Hebr_GB": "yi_Hebr_GB", + "und_Hebr_SE": "yi_Hebr_SE", + "und_Hebr_UA": "yi_Hebr_UA", + "und_Hebr_US": "yi_Hebr_US", + "und_Hira": "ja_Hira_JP", + "und_HK": "zh_Hant_HK", + "und_HM": "und_Latn_HM", + "und_HN": "es_Latn_HN", + "und_HR": "hr_Latn_HR", + "und_HT": "ht_Latn_HT", + "und_HU": "hu_Latn_HU", + "und_IC": "es_Latn_IC", + "und_ID": "id_Latn_ID", + "und_IL": "he_Hebr_IL", + "und_IN": "hi_Deva_IN", + "und_IQ": "ar_Arab_IQ", + "und_IR": "fa_Arab_IR", + "und_IS": "is_Latn_IS", + "und_IT": "it_Latn_IT", + "und_Ital": "ett_Ital_IT", + "und_Java": "jv_Java_ID", + "und_JO": "ar_Arab_JO", + "und_JP": "ja_Jpan_JP", + "und_Jpan": "ja_Jpan_JP", + "und_Kali": "eky_Kali_MM", + "und_Kana": "ja_Kana_JP", + "und_KG": "ky_Cyrl_KG", + "und_KH": "km_Khmr_KH", + "und_Khar": "pra_Khar_PK", + "und_Khmr": "km_Khmr_KH", + "und_KM": "ar_Arab_KM", + "und_Knda": "kn_Knda_IN", + "und_Kore": "ko_Kore_KR", + "und_KP": "ko_Kore_KP", + "und_KR": "ko_Kore_KR", + "und_Kthi": "bh_Kthi_IN", + "und_KW": "ar_Arab_KW", + "und_KZ": "ru_Cyrl_KZ", + "und_LA": "lo_Laoo_LA", + "und_Lana": "nod_Lana_TH", + "und_Laoo": "lo_Laoo_LA", + "und_Latn_AF": "tk_Latn_AF", + "und_Latn_AM": "az_Latn_AM", + "und_Latn_BG": "tr_Latn_BG", + "und_Latn_CN": "za_Latn_CN", + "und_Latn_CY": "tr_Latn_CY", + "und_Latn_DZ": "fr_Latn_DZ", + "und_Latn_ET": "en_Latn_ET", + "und_Latn_GE": "ku_Latn_GE", + "und_Latn_GR": "tr_Latn_GR", + "und_Latn_IL": "ro_Latn_IL", + "und_Latn_IR": "tk_Latn_IR", + "und_Latn_KM": "fr_Latn_KM", + "und_Latn_KZ": "de_Latn_KZ", + "und_Latn_LB": "fr_Latn_LB", + "und_Latn_MA": "fr_Latn_MA", + "und_Latn_MK": "sq_Latn_MK", + "und_Latn_MO": "pt_Latn_MO", + "und_Latn_MR": "fr_Latn_MR", + "und_Latn_RU": "krl_Latn_RU", + "und_Latn_SY": "fr_Latn_SY", + "und_Latn_TN": "fr_Latn_TN", + "und_Latn_TW": "trv_Latn_TW", + "und_Latn_UA": "pl_Latn_UA", + "und_LB": "ar_Arab_LB", + "und_Lepc": "lep_Lepc_IN", + "und_LI": "de_Latn_LI", + "und_Limb": "lif_Limb_IN", + "und_Linb": "grc_Linb_GR", + "und_Lisu": "lis_Lisu_CN", + "und_LK": "si_Sinh_LK", + "und_LS": "st_Latn_LS", + "und_LT": "lt_Latn_LT", + "und_LU": "fr_Latn_LU", + "und_LV": "lv_Latn_LV", + "und_LY": "ar_Arab_LY", + "und_Lyci": "xlc_Lyci_TR", + "und_Lydi": "xld_Lydi_TR", + "und_MA": "ar_Arab_MA", + "und_Mand": "myz_Mand_IR", + "und_MC": "fr_Latn_MC", + "und_MD": "ro_Latn_MD", + "und_ME": "sr_Latn_ME", + "und_Merc": "xmr_Merc_SD", + "und_Mero": "xmr_Mero_SD", + "und_MF": "fr_Latn_MF", + "und_MG": "mg_Latn_MG", + "und_MK": "mk_Cyrl_MK", + "und_ML": "bm_Latn_ML", + "und_Mlym": "ml_Mlym_IN", + "und_MM": "my_Mymr_MM", + "und_MN": "mn_Cyrl_MN", + "und_MO": "zh_Hant_MO", + "und_Mong": "mn_Mong_CN", + "und_MQ": "fr_Latn_MQ", + "und_MR": "ar_Arab_MR", + "und_MT": "mt_Latn_MT", + "und_Mtei": "mni_Mtei_IN", + "und_MU": "mfe_Latn_MU", + "und_MV": "dv_Thaa_MV", + "und_MX": "es_Latn_MX", + "und_MY": "ms_Latn_MY", + "und_Mymr": "my_Mymr_MM", + "und_Mymr_IN": "kht_Mymr_IN", + "und_Mymr_TH": "mnw_Mymr_TH", + "und_MZ": "pt_Latn_MZ", + "und_NA": "af_Latn_NA", + "und_NC": "fr_Latn_NC", + "und_NE": "ha_Latn_NE", + "und_NI": "es_Latn_NI", + "und_Nkoo": "man_Nkoo_GN", + "und_NL": "nl_Latn_NL", + "und_NO": "nb_Latn_NO", + "und_NP": "ne_Deva_NP", + "und_Ogam": "sga_Ogam_IE", + "und_Olck": "sat_Olck_IN", + "und_OM": "ar_Arab_OM", + "und_Orkh": "otk_Orkh_MN", + "und_Orya": "or_Orya_IN", + "und_Osma": "so_Osma_SO", + "und_PA": "es_Latn_PA", + "und_PE": "es_Latn_PE", + "und_PF": "fr_Latn_PF", + "und_PG": "tpi_Latn_PG", + "und_PH": "fil_Latn_PH", + "und_Phag": "lzh_Phag_CN", + "und_Phli": "pal_Phli_IR", + "und_Phnx": "phn_Phnx_LB", + "und_PK": "ur_Arab_PK", + "und_PL": "pl_Latn_PL", + "und_Plrd": "hmd_Plrd_CN", + "und_PM": "fr_Latn_PM", + "und_PR": "es_Latn_PR", + "und_Prti": "xpr_Prti_IR", + "und_PS": "ar_Arab_PS", + "und_PT": "pt_Latn_PT", + "und_PW": "pau_Latn_PW", + "und_PY": "gn_Latn_PY", + "und_QA": "ar_Arab_QA", + "und_RE": "fr_Latn_RE", + "und_Rjng": "rej_Rjng_ID", + "und_RO": "ro_Latn_RO", + "und_RS": "sr_Cyrl_RS", + "und_RU": "ru_Cyrl_RU", + "und_Runr": "non_Runr_SE", + "und_RW": "rw_Latn_RW", + "und_SA": "ar_Arab_SA", + "und_Samr": "smp_Samr_IL", + "und_Sarb": "xsa_Sarb_YE", + "und_Saur": "saz_Saur_IN", + "und_SC": "fr_Latn_SC", + "und_SD": "ar_Arab_SD", + "und_SE": "sv_Latn_SE", + "und_Shaw": "en_Shaw_GB", + "und_Shrd": "sa_Shrd_IN", + "und_SI": "sl_Latn_SI", + "und_Sinh": "si_Sinh_LK", + "und_SJ": "nb_Latn_SJ", + "und_SK": "sk_Latn_SK", + "und_SM": "it_Latn_SM", + "und_SN": "fr_Latn_SN", + "und_SO": "so_Latn_SO", + "und_Sora": "srb_Sora_IN", + "und_SR": "nl_Latn_SR", + "und_ST": "pt_Latn_ST", + "und_Sund": "su_Sund_ID", + "und_SV": "es_Latn_SV", + "und_SY": "ar_Arab_SY", + "und_Sylo": "syl_Sylo_BD", + "und_Syrc": "syr_Syrc_IQ", + "und_Tagb": "tbw_Tagb_PH", + "und_Takr": "doi_Takr_IN", + "und_Tale": "tdd_Tale_CN", + "und_Talu": "khb_Talu_CN", + "und_Taml": "ta_Taml_IN", + "und_Tavt": "blt_Tavt_VN", + "und_TD": "fr_Latn_TD", + "und_Telu": "te_Telu_IN", + "und_TF": "fr_Latn_TF", + "und_Tfng": "zgh_Tfng_MA", + "und_TG": "fr_Latn_TG", + "und_Tglg": "fil_Tglg_PH", + "und_TH": "th_Thai_TH", + "und_Thaa": "dv_Thaa_MV", + "und_Thai": "th_Thai_TH", + "und_Thai_CN": "lcp_Thai_CN", + "und_Thai_KH": "kdt_Thai_KH", + "und_Thai_LA": "kdt_Thai_LA", + "und_Tibt": "bo_Tibt_CN", + "und_TJ": "tg_Cyrl_TJ", + "und_TK": "tkl_Latn_TK", + "und_TL": "pt_Latn_TL", + "und_TM": "tk_Latn_TM", + "und_TN": "ar_Arab_TN", + "und_TO": "to_Latn_TO", + "und_TR": "tr_Latn_TR", + "und_TV": "tvl_Latn_TV", + "und_TW": "zh_Hant_TW", + "und_TZ": "sw_Latn_TZ", + "und_UA": "uk_Cyrl_UA", + "und_UG": "sw_Latn_UG", + "und_Ugar": "uga_Ugar_SY", + "und_UY": "es_Latn_UY", + "und_UZ": "uz_Latn_UZ", + "und_VA": "la_Latn_VA", + "und_Vaii": "vai_Vaii_LR", + "und_VE": "es_Latn_VE", + "und_VN": "vi_Latn_VN", + "und_VU": "bi_Latn_VU", + "und_WF": "fr_Latn_WF", + "und_WS": "sm_Latn_WS", + "und_XK": "sq_Latn_XK", + "und_Xpeo": "peo_Xpeo_IR", + "und_Xsux": "akk_Xsux_IQ", + "und_YE": "ar_Arab_YE", + "und_Yiii": "ii_Yiii_CN", + "und_YT": "fr_Latn_YT", + "unr": "unr_Beng_IN", + "unr_Deva": "unr_Deva_NP", + "unr_NP": "unr_Deva_NP", + "unx": "unx_Beng_IN", + "ur": "ur_Arab_PK", + "uz": "uz_Latn_UZ", + "uz_AF": "uz_Arab_AF", + "uz_Arab": "uz_Arab_AF", + "uz_CN": "uz_Cyrl_CN", + "vai": "vai_Vaii_LR", + "ve": "ve_Latn_ZA", + "vi": "vi_Latn_VN", + "vo": "vo_Latn_001", + "vun": "vun_Latn_TZ", + "wa": "wa_Latn_BE", + "wae": "wae_Latn_CH", + "wal": "wal_Ethi_ET", + "war": "war_Latn_PH", + "wo": "wo_Latn_SN", + "xh": "xh_Latn_ZA", + "xog": "xog_Latn_UG", + "xsr": "xsr_Deva_NP", + "yao": "yao_Latn_MZ", + "yap": "yap_Latn_FM", + "yav": "yav_Latn_CM", + "yi": "yi_Hebr_UA", + "yo": "yo_Latn_NG", + "za": "za_Latn_CN", + "zgh": "zgh_Tfng_MA", + "zh": "zh_Hans_CN", + "zh_AU": "zh_Hant_AU", + "zh_BN": "zh_Hant_BN", + "zh_GB": "zh_Hant_GB", + "zh_GF": "zh_Hant_GF", + "zh_Hant": "zh_Hant_TW", + "zh_HK": "zh_Hant_HK", + "zh_ID": "zh_Hant_ID", + "zh_MO": "zh_Hant_MO", + "zh_MY": "zh_Hant_MY", + "zh_PA": "zh_Hant_PA", + "zh_PF": "zh_Hant_PF", + "zh_PH": "zh_Hant_PH", + "zh_SR": "zh_Hant_SR", + "zh_TH": "zh_Hant_TH", + "zh_TW": "zh_Hant_TW", + "zh_US": "zh_Hant_US", + "zh_VN": "zh_Hant_VN", + "zu": "zu_Latn_ZA", + "zza": "zza_Arab_TR" + } + } +}); + +// weekData +Globalize.load({ + "supplemental": { + "version": { + "_cldrVersion": "24", + "_number": "$Revision: 9270 $" + }, + "generation": { + "_date": "$Date: 2013-08-25 16:44:03 -0500 (Sun, 25 Aug 2013) $" + }, + "weekData": { + "minDays": { + "001": "1", + "AD": "4", + "AN": "4", + "AT": "4", + "AX": "4", + "BE": "4", + "BG": "4", + "CH": "4", + "CZ": "4", + "DE": "4", + "DK": "4", + "EE": "4", + "ES": "4", + "FI": "4", + "FJ": "4", + "FO": "4", + "FR": "4", + "GB": "4", + "GF": "4", + "GG": "4", + "GI": "4", + "GP": "4", + "GR": "4", + "GU": "1", + "HU": "4", + "IE": "4", + "IM": "4", + "IS": "4", + "IT": "4", + "JE": "4", + "LI": "4", + "LT": "4", + "LU": "4", + "MC": "4", + "MQ": "4", + "NL": "4", + "NO": "4", + "PL": "4", + "PT": "4", + "RE": "4", + "SE": "4", + "SJ": "4", + "SK": "4", + "SM": "4", + "UM": "1", + "US": "1", + "VA": "4", + "VI": "1" + }, + "firstDay": { + "001": "mon", + "AD": "mon", + "AE": "sat", + "AF": "sat", + "AG": "sun", + "AI": "mon", + "AL": "mon", + "AM": "mon", + "AN": "mon", + "AR": "sun", + "AS": "sun", + "AT": "mon", + "AU": "sun", + "AX": "mon", + "AZ": "mon", + "BA": "mon", + "BD": "fri", + "BE": "mon", + "BG": "mon", + "BH": "sat", + "BM": "mon", + "BN": "mon", + "BR": "sun", + "BS": "sun", + "BT": "sun", + "BW": "sun", + "BY": "sun", + "BZ": "sun", + "CA": "sun", + "CH": "mon", + "CL": "mon", + "CM": "mon", + "CN": "sun", + "CO": "sun", + "CR": "mon", + "CY": "mon", + "CZ": "mon", + "DE": "mon", + "DJ": "sat", + "DK": "mon", + "DM": "sun", + "DO": "sun", + "DZ": "sat", + "EC": "mon", + "EE": "mon", + "EG": "sat", + "ES": "mon", + "ET": "sun", + "FI": "mon", + "FJ": "mon", + "FO": "mon", + "FR": "mon", + "GB": "mon", + "GE": "mon", + "GF": "mon", + "GP": "mon", + "GR": "mon", + "GT": "sun", + "GU": "sun", + "HK": "sun", + "HN": "sun", + "HR": "mon", + "HU": "mon", + "ID": "sun", + "IE": "sun", + "IL": "sun", + "IN": "sun", + "IQ": "sat", + "IR": "sat", + "IS": "mon", + "IT": "mon", + "JM": "sun", + "JO": "sat", + "JP": "sun", + "KE": "sun", + "KG": "mon", + "KH": "sun", + "KR": "sun", + "KW": "sat", + "KZ": "mon", + "LA": "sun", + "LB": "mon", + "LI": "mon", + "LK": "mon", + "LT": "mon", + "LU": "mon", + "LV": "mon", + "LY": "sat", + "MA": "sat", + "MC": "mon", + "MD": "mon", + "ME": "mon", + "MH": "sun", + "MK": "mon", + "MM": "sun", + "MN": "mon", + "MO": "sun", + "MQ": "mon", + "MT": "sun", + "MV": "fri", + "MX": "sun", + "MY": "mon", + "MZ": "sun", + "NI": "sun", + "NL": "mon", + "NO": "mon", + "NP": "sun", + "NZ": "sun", + "OM": "sat", + "PA": "sun", + "PE": "sun", + "PH": "sun", + "PK": "sun", + "PL": "mon", + "PR": "sun", + "PT": "mon", + "PY": "sun", + "QA": "sat", + "RE": "mon", + "RO": "mon", + "RS": "mon", + "RU": "mon", + "SA": "sun", + "SD": "sat", + "SE": "mon", + "SG": "sun", + "SI": "mon", + "SK": "mon", + "SM": "mon", + "SV": "sun", + "SY": "sat", + "TH": "sun", + "TJ": "mon", + "TM": "mon", + "TN": "sun", + "TR": "mon", + "TT": "sun", + "TW": "sun", + "UA": "mon", + "UM": "sun", + "US": "sun", + "UY": "mon", + "UZ": "mon", + "VA": "mon", + "VE": "sun", + "VI": "sun", + "VN": "mon", + "WS": "sun", + "XK": "mon", + "YE": "sun", + "ZA": "sun", + "ZW": "sun" + }, + "firstDay-alt-variant": { + "GB": "sun" + }, + "weekendStart": { + "001": "sat", + "AE": "fri", + "AF": "thu", + "BH": "fri", + "DZ": "thu", + "EG": "fri", + "IL": "fri", + "IN": "sun", + "IQ": "fri", + "IR": "thu", + "JO": "fri", + "KW": "fri", + "LY": "fri", + "MA": "fri", + "OM": "thu", + "QA": "fri", + "SA": "fri", + "SD": "fri", + "SY": "fri", + "TN": "fri", + "YE": "fri" + }, + "weekendEnd": { + "001": "sun", + "AE": "sat", + "AF": "fri", + "BH": "sat", + "DZ": "fri", + "EG": "sat", + "IL": "sat", + "IQ": "sat", + "IR": "fri", + "JO": "sat", + "KW": "sat", + "LY": "sat", + "MA": "sat", + "OM": "fri", + "QA": "sat", + "SA": "sat", + "SD": "sat", + "SY": "sat", + "TN": "sat", + "YE": "sat" + } + } + } +}); + +// timeData +Globalize.load({ + "supplemental": { + "version": { + "_cldrVersion": "24", + "_number": "$Revision: 9270 $" + }, + "generation": { + "_date": "$Date: 2013-08-25 16:44:03 -0500 (Sun, 25 Aug 2013) $" + }, + "timeData": { + "001": { + "_allowed": "H h", + "_preferred": "H" + }, + "AD": { + "_allowed": "H", + "_preferred": "H" + }, + "AE": { + "_allowed": "H h", + "_preferred": "h" + }, + "AG": { + "_allowed": "H h", + "_preferred": "h" + }, + "AL": { + "_allowed": "H h", + "_preferred": "h" + }, + "AM": { + "_allowed": "H", + "_preferred": "H" + }, + "AO": { + "_allowed": "H", + "_preferred": "H" + }, + "AS": { + "_allowed": "H h", + "_preferred": "h" + }, + "AT": { + "_allowed": "H", + "_preferred": "H" + }, + "AU": { + "_allowed": "H h", + "_preferred": "h" + }, + "AW": { + "_allowed": "H", + "_preferred": "H" + }, + "AX": { + "_allowed": "H", + "_preferred": "H" + }, + "BB": { + "_allowed": "H h", + "_preferred": "h" + }, + "BD": { + "_allowed": "H h", + "_preferred": "h" + }, + "BE": { + "_allowed": "H", + "_preferred": "H" + }, + "BF": { + "_allowed": "H", + "_preferred": "H" + }, + "BH": { + "_allowed": "H h", + "_preferred": "h" + }, + "BJ": { + "_allowed": "H", + "_preferred": "H" + }, + "BL": { + "_allowed": "H", + "_preferred": "H" + }, + "BM": { + "_allowed": "H h", + "_preferred": "h" + }, + "BN": { + "_allowed": "H h", + "_preferred": "h" + }, + "BR": { + "_allowed": "H", + "_preferred": "H" + }, + "BS": { + "_allowed": "H h", + "_preferred": "h" + }, + "BT": { + "_allowed": "H h", + "_preferred": "h" + }, + "BW": { + "_allowed": "H h", + "_preferred": "h" + }, + "CA": { + "_allowed": "H h", + "_preferred": "h" + }, + "CD": { + "_allowed": "H", + "_preferred": "H" + }, + "CI": { + "_allowed": "H", + "_preferred": "H" + }, + "CN": { + "_allowed": "H h", + "_preferred": "h" + }, + "CO": { + "_allowed": "H h", + "_preferred": "h" + }, + "CP": { + "_allowed": "H", + "_preferred": "H" + }, + "CV": { + "_allowed": "H", + "_preferred": "H" + }, + "CY": { + "_allowed": "H h", + "_preferred": "h" + }, + "CZ": { + "_allowed": "H", + "_preferred": "H" + }, + "DE": { + "_allowed": "H", + "_preferred": "H" + }, + "DJ": { + "_allowed": "H h", + "_preferred": "h" + }, + "DK": { + "_allowed": "H", + "_preferred": "H" + }, + "DM": { + "_allowed": "H h", + "_preferred": "h" + }, + "DZ": { + "_allowed": "H h", + "_preferred": "h" + }, + "EE": { + "_allowed": "H", + "_preferred": "H" + }, + "EG": { + "_allowed": "H h", + "_preferred": "h" + }, + "EH": { + "_allowed": "H h", + "_preferred": "h" + }, + "ER": { + "_allowed": "H h", + "_preferred": "h" + }, + "ET": { + "_allowed": "H h", + "_preferred": "h" + }, + "FI": { + "_allowed": "H", + "_preferred": "H" + }, + "FJ": { + "_allowed": "H h", + "_preferred": "h" + }, + "FM": { + "_allowed": "H h", + "_preferred": "h" + }, + "FR": { + "_allowed": "H", + "_preferred": "H" + }, + "GA": { + "_allowed": "H", + "_preferred": "H" + }, + "GD": { + "_allowed": "H h", + "_preferred": "h" + }, + "GF": { + "_allowed": "H", + "_preferred": "H" + }, + "GH": { + "_allowed": "H h", + "_preferred": "h" + }, + "GL": { + "_allowed": "H h", + "_preferred": "h" + }, + "GM": { + "_allowed": "H h", + "_preferred": "h" + }, + "GN": { + "_allowed": "H", + "_preferred": "H" + }, + "GP": { + "_allowed": "H", + "_preferred": "H" + }, + "GR": { + "_allowed": "H h", + "_preferred": "h" + }, + "GU": { + "_allowed": "H h", + "_preferred": "h" + }, + "GW": { + "_allowed": "H", + "_preferred": "H" + }, + "GY": { + "_allowed": "H h", + "_preferred": "h" + }, + "HK": { + "_allowed": "H h", + "_preferred": "h" + }, + "HR": { + "_allowed": "H", + "_preferred": "H" + }, + "IL": { + "_allowed": "H", + "_preferred": "H" + }, + "IN": { + "_allowed": "H h", + "_preferred": "h" + }, + "IQ": { + "_allowed": "H h", + "_preferred": "h" + }, + "IS": { + "_allowed": "H", + "_preferred": "H" + }, + "IT": { + "_allowed": "H", + "_preferred": "H" + }, + "JM": { + "_allowed": "H h", + "_preferred": "h" + }, + "JO": { + "_allowed": "H h", + "_preferred": "h" + }, + "JP": { + "_allowed": "H K h", + "_preferred": "H" + }, + "KH": { + "_allowed": "H h", + "_preferred": "h" + }, + "KI": { + "_allowed": "H h", + "_preferred": "h" + }, + "KN": { + "_allowed": "H h", + "_preferred": "h" + }, + "KP": { + "_allowed": "H h", + "_preferred": "h" + }, + "KR": { + "_allowed": "H h", + "_preferred": "h" + }, + "KW": { + "_allowed": "H h", + "_preferred": "h" + }, + "KY": { + "_allowed": "H h", + "_preferred": "h" + }, + "LB": { + "_allowed": "H h", + "_preferred": "h" + }, + "LC": { + "_allowed": "H h", + "_preferred": "h" + }, + "LR": { + "_allowed": "H h", + "_preferred": "h" + }, + "LS": { + "_allowed": "H h", + "_preferred": "h" + }, + "LY": { + "_allowed": "H h", + "_preferred": "h" + }, + "MA": { + "_allowed": "H h", + "_preferred": "h" + }, + "MC": { + "_allowed": "H", + "_preferred": "H" + }, + "MD": { + "_allowed": "H", + "_preferred": "H" + }, + "MF": { + "_allowed": "H", + "_preferred": "H" + }, + "MH": { + "_allowed": "H h", + "_preferred": "h" + }, + "ML": { + "_allowed": "H", + "_preferred": "H" + }, + "MO": { + "_allowed": "H h", + "_preferred": "h" + }, + "MP": { + "_allowed": "H h", + "_preferred": "h" + }, + "MQ": { + "_allowed": "H", + "_preferred": "H" + }, + "MR": { + "_allowed": "H h", + "_preferred": "h" + }, + "MW": { + "_allowed": "H h", + "_preferred": "h" + }, + "MY": { + "_allowed": "H h", + "_preferred": "h" + }, + "MZ": { + "_allowed": "H", + "_preferred": "H" + }, + "NA": { + "_allowed": "H h", + "_preferred": "h" + }, + "NC": { + "_allowed": "H", + "_preferred": "H" + }, + "NE": { + "_allowed": "H", + "_preferred": "H" + }, + "NG": { + "_allowed": "H h", + "_preferred": "h" + }, + "NL": { + "_allowed": "H", + "_preferred": "H" + }, + "NZ": { + "_allowed": "H h", + "_preferred": "h" + }, + "OM": { + "_allowed": "H h", + "_preferred": "h" + }, + "PG": { + "_allowed": "H h", + "_preferred": "h" + }, + "PK": { + "_allowed": "H h", + "_preferred": "h" + }, + "PM": { + "_allowed": "H", + "_preferred": "H" + }, + "PR": { + "_allowed": "H h", + "_preferred": "h" + }, + "PS": { + "_allowed": "H h", + "_preferred": "h" + }, + "PT": { + "_allowed": "H", + "_preferred": "H" + }, + "PW": { + "_allowed": "H h", + "_preferred": "h" + }, + "QA": { + "_allowed": "H h", + "_preferred": "h" + }, + "RE": { + "_allowed": "H", + "_preferred": "H" + }, + "RO": { + "_allowed": "H", + "_preferred": "H" + }, + "RU": { + "_allowed": "H", + "_preferred": "H" + }, + "SA": { + "_allowed": "H h", + "_preferred": "h" + }, + "SB": { + "_allowed": "H h", + "_preferred": "h" + }, + "SD": { + "_allowed": "H h", + "_preferred": "h" + }, + "SE": { + "_allowed": "H", + "_preferred": "H" + }, + "SG": { + "_allowed": "H h", + "_preferred": "h" + }, + "SI": { + "_allowed": "H", + "_preferred": "H" + }, + "SJ": { + "_allowed": "H", + "_preferred": "H" + }, + "SK": { + "_allowed": "H", + "_preferred": "H" + }, + "SL": { + "_allowed": "H h", + "_preferred": "h" + }, + "SM": { + "_allowed": "H", + "_preferred": "H" + }, + "SO": { + "_allowed": "H h", + "_preferred": "h" + }, + "SR": { + "_allowed": "H", + "_preferred": "H" + }, + "SS": { + "_allowed": "H h", + "_preferred": "h" + }, + "ST": { + "_allowed": "H", + "_preferred": "H" + }, + "SY": { + "_allowed": "H h", + "_preferred": "h" + }, + "SZ": { + "_allowed": "H h", + "_preferred": "h" + }, + "TC": { + "_allowed": "H h", + "_preferred": "h" + }, + "TD": { + "_allowed": "H h", + "_preferred": "h" + }, + "TG": { + "_allowed": "H", + "_preferred": "H" + }, + "TN": { + "_allowed": "H h", + "_preferred": "h" + }, + "TR": { + "_allowed": "H", + "_preferred": "H" + }, + "TT": { + "_allowed": "H h", + "_preferred": "h" + }, + "TW": { + "_allowed": "H h", + "_preferred": "h" + }, + "UM": { + "_allowed": "H h", + "_preferred": "h" + }, + "US": { + "_allowed": "H h", + "_preferred": "h" + }, + "VC": { + "_allowed": "H h", + "_preferred": "h" + }, + "VG": { + "_allowed": "H h", + "_preferred": "h" + }, + "VI": { + "_allowed": "H h", + "_preferred": "h" + }, + "VU": { + "_allowed": "H h", + "_preferred": "h" + }, + "WF": { + "_allowed": "H", + "_preferred": "H" + }, + "WS": { + "_allowed": "H h", + "_preferred": "h" + }, + "YE": { + "_allowed": "H h", + "_preferred": "h" + }, + "YT": { + "_allowed": "H", + "_preferred": "H" + }, + "ZA": { + "_allowed": "H h", + "_preferred": "h" + }, + "ZM": { + "_allowed": "H h", + "_preferred": "h" + }, + "ZW": { + "_allowed": "H h", + "_preferred": "h" + } + } + } +}); + +/** + * jQuery UI translation data + */ var regions = { - "en": { - "closeText": "Done", - "prevText": "Prev", - "nextText": "Next", - "currentText": "Today", - "weekHeader": "Wk", - "dateFormat": "d", - "datePickerRole": "date picker" - }, - "af": { - "closeText": "Selekteer", - "prevText": "Vorige", - "nextText": "Volgende", - "currentText": "Vandag", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "zh-TW": { - "closeText": "\u95dc\u9589", - "prevText": "<\u4e0a\u6708", - "nextText": "\u4e0b\u6708>", - "currentText": "\u4eca\u5929", - "weekHeader": "\u5468", - "dateFormat": "d" - }, - "ar": { - "closeText": "\u0625\u063a\u0644\u0627\u0642", - "prevText": "<\u0627\u0644\u0633\u0627\u0628\u0642", - "nextText": "\u0627\u0644\u062a\u0627\u0644\u064a>", - "currentText": "\u0627\u0644\u064a\u0648\u0645", - "weekHeader": "\u0623\u0633\u0628\u0648\u0639", - "dateFormat": "d" - }, - "az": { - "closeText": "Ba\u011fla", - "prevText": "<Geri", - "nextText": "\u0130r\u0259li>", - "currentText": "Bug\u00fcn", - "weekHeader": "Hf", - "dateFormat": "d" - }, - "bg": { - "closeText": "\u0437\u0430\u0442\u0432\u043e\u0440\u0438", - "prevText": "<\u043d\u0430\u0437\u0430\u0434", - "nextText": "\u043d\u0430\u043f\u0440\u0435\u0434>", - "currentText": "\u0434\u043d\u0435\u0441", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "bs": { - "closeText": "Zatvori", - "prevText": "<", - "nextText": ">", - "currentText": "Danas", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "ca": { - "closeText": "Tancar", - "prevText": "<Ant", - "nextText": "Seg>", - "currentText": "Avui", - "weekHeader": "Sm", - "dateFormat": "d" - }, - "cs": { - "closeText": "Zav\u0159\u00edt", - "prevText": "<D\u0159\u00edve", - "nextText": "Pozd\u011bji>", - "currentText": "Nyn\u00ed", - "weekHeader": "T\u00fdd", - "dateFormat": "d" - }, - "da": { - "closeText": "Luk", - "prevText": "<Forrige", - "nextText": "N\u00e6ste>", - "currentText": "Idag", - "weekHeader": "Uge", - "dateFormat": "d" - }, - "de": { - "closeText": "schlie\u00dfen", - "prevText": "<zur\u00fcck", - "nextText": "Vor>", - "currentText": "heute", - "weekHeader": "Wo", - "dateFormat": "d" - }, - "el": { - "closeText": "\u039a\u03bb\u03b5\u03af\u03c3\u03b9\u03bc\u03bf", - "prevText": "\u03a0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2", - "nextText": "\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf\u03c2", - "currentText": "\u03a4\u03c1\u03ad\u03c7\u03c9\u03bd \u039c\u03ae\u03bd\u03b1\u03c2", - "weekHeader": "\u0395\u03b2\u03b4", - "dateFormat": "d" - }, - "en-GB": { - "closeText": "Done", - "prevText": "Prev", - "nextText": "Next", - "currentText": "Today", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "eo": { - "closeText": "Fermi", - "prevText": "<Anta", - "nextText": "Sekv>", - "currentText": "Nuna", - "weekHeader": "Sb", - "dateFormat": "dd/MM/yyyy" - }, - "es": { - "closeText": "Cerrar", - "prevText": "<Ant", - "nextText": "Sig>", - "currentText": "Hoy", - "weekHeader": "Sm", - "dateFormat": "d" - }, - "et": { - "closeText": "Sulge", - "prevText": "Eelnev", - "nextText": "J\u00e4rgnev", - "currentText": "T\u00e4na", - "weekHeader": "Sm", - "dateFormat": "d" - }, - "eu": { - "closeText": "Egina", - "prevText": "<Aur", - "nextText": "Hur>", - "currentText": "Gaur", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "fa": { - "closeText": "\u0628\u0633\u062a\u0646", - "prevText": "<\u0642\u0628\u0644\u064a", - "nextText": "\u0628\u0639\u062f\u064a>", - "currentText": "\u0627\u0645\u0631\u0648\u0632", - "weekHeader": "\u0647\u0641", - "dateFormat": "d" - }, - "fi": { - "closeText": "Sulje", - "prevText": "«Edellinen", - "nextText": "Seuraava»", - "currentText": "Tänään", - "weekHeader": "Vk", - "dateFormat": "d" - }, - "fo": { - "closeText": "Lat aftur", - "prevText": "<Fyrra", - "nextText": "N\u00e6sta>", - "currentText": "\u00cd dag", - "weekHeader": "Vk", - "dateFormat": "d" - }, - "fr-CH": { - "closeText": "Fermer", - "prevText": "<Pr\u00e9c", - "nextText": "Suiv>", - "currentText": "Courant", - "weekHeader": "Sm", - "dateFormat": "d" - }, - "fr": { - "closeText": "Fermer", - "prevText": "<Pr\u00e9c", - "nextText": "Suiv>", - "currentText": "Courant", - "weekHeader": "Sm", - "dateFormat": "d" - }, - "he": { - "closeText": "\u05e1\u05d2\u05d5\u05e8", - "prevText": "<\u05d4\u05e7\u05d5\u05d3\u05dd", - "nextText": "\u05d4\u05d1\u05d0>", - "currentText": "\u05d4\u05d9\u05d5\u05dd", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "hr": { - "closeText": "Zatvori", - "prevText": "<", - "nextText": ">", - "currentText": "Danas", - "weekHeader": "Tje", - "dateFormat": "d" - }, - "hu": { - "closeText": "bez\u00c3\u00a1r\u00c3\u00a1s", - "prevText": "« vissza", - "nextText": "el\u00c5\u2018re »", - "currentText": "ma", - "weekHeader": "H\u00c3\u00a9", - "dateFormat": "d" - }, - "hy": { - "closeText": "\u00d5\u201c\u00d5\u00a1\u00d5\u00af\u00d5\u00a5\u00d5\u00ac", - "prevText": "<\u00d5\u2020\u00d5\u00a1\u00d5\u00ad.", - "nextText": "\u00d5\u20ac\u00d5\u00a1\u00d5\u00bb.>", - "currentText": "\u00d4\u00b1\u00d5\u00b5\u00d5\u00bd\u00d6\u2026\u00d6\u20ac", - "weekHeader": "\u00d5\u2021\u00d4\u00b2\u00d5\u008f", - "dateFormat": "d" - }, - "id": { - "closeText": "Tutup", - "prevText": "<mundur", - "nextText": "maju>", - "currentText": "hari ini", - "weekHeader": "Mg", - "dateFormat": "d" - }, - "is": { - "closeText": "Loka", - "prevText": "< Fyrri", - "nextText": "Næsti >", - "currentText": "Í dag", - "weekHeader": "Vika", - "dateFormat": "d" - }, - "it": { - "closeText": "Chiudi", - "prevText": "<Prec", - "nextText": "Succ>", - "currentText": "Oggi", - "weekHeader": "Sm", - "dateFormat": "d" - }, - "ja": { - "closeText": "\u9589\u3058\u308b", - "prevText": "<\u524d", - "nextText": "\u6b21>", - "currentText": "\u4eca\u65e5", - "weekHeader": "\u9031", - "dateFormat": "d" - }, - "ko": { - "closeText": "\u00eb\u2039\u00ab\u00ea\u00b8\u00b0", - "prevText": "\u00ec\u009d\u00b4\u00ec\u00a0\u201e\u00eb\u2039\u00ac", - "nextText": "\u00eb\u2039\u00a4\u00ec\u009d\u0152\u00eb\u2039\u00ac", - "currentText": "\u00ec\u02dc\u00a4\u00eb\u0160\u02dc", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "lt": { - "closeText": "U\u00c5\u00bedaryti", - "prevText": "<Atgal", - "nextText": "Pirmyn>", - "currentText": "\u00c5\u00a0iandien", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "lv": { - "closeText": "Aizv\u00c4\u201crt", - "prevText": "Iepr", - "nextText": "N\u00c4\u0081ka", - "currentText": "\u00c5\u00a0odien", - "weekHeader": "Nav", - "dateFormat": "d" - }, - "ms": { - "closeText": "Tutup", - "prevText": "<Sebelum", - "nextText": "Selepas>", - "currentText": "hari ini", - "weekHeader": "Mg", - "dateFormat": "d" - }, - "nl": { - "closeText": "Sluiten", - "prevText": "\u2190", - "nextText": "\u2192", - "currentText": "Vandaag", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "no": { - "closeText": "Lukk", - "prevText": "«Forrige", - "nextText": "Neste»", - "currentText": "I dag", - "weekHeader": "Uke", - "dateFormat": "d" - }, - "pl": { - "closeText": "Zamknij", - "prevText": "<Poprzedni", - "nextText": "Nast\u00c4\u2122pny>", - "currentText": "Dzi\u00c5\u203a", - "weekHeader": "Tydz", - "dateFormat": "d" - }, - "pt-BR": { - "closeText": "Fechar", - "prevText": "<Anterior", - "nextText": "Próximo>", - "currentText": "Hoje", - "weekHeader": "Sm", - "dateFormat": "d" - }, - "ro": { - "closeText": "\u00cenchide", - "prevText": "« Luna precedent\u0103", - "nextText": "Luna urm\u0103toare »", - "currentText": "Azi", - "weekHeader": "S\u0103pt", - "dateFormat": "d" - }, - "ru": { - "closeText": "\u00d0\u2014\u00d0\u00b0\u00d0\u00ba\u00d1\u20ac\u00d1\u2039\u00d1\u201a\u00d1\u0152", - "prevText": "<\u00d0\u0178\u00d1\u20ac\u00d0\u00b5\u00d0\u00b4", - "nextText": "\u00d0\u00a1\u00d0\u00bb\u00d0\u00b5\u00d0\u00b4>", - "currentText": "\u00d0\u00a1\u00d0\u00b5\u00d0\u00b3\u00d0\u00be\u00d0\u00b4\u00d0\u00bd\u00d1\u008f", - "weekHeader": "\u00d0\u009d\u00d0\u00b5", - "dateFormat": "d" - }, - "sk": { - "closeText": "Zavrie\u00c5\u00a5", - "prevText": "<Predch\u00c3\u00a1dzaj\u00c3\u00baci", - "nextText": "Nasleduj\u00c3\u00baci>", - "currentText": "Dnes", - "weekHeader": "Ty", - "dateFormat": "d" - }, - "sl": { - "closeText": "Zapri", - "prevText": "<Prejšnji", - "nextText": "Naslednji>", - "currentText": "Trenutni", - "weekHeader": "Teden", - "dateFormat": "d" - }, - "sq": { - "closeText": "mbylle", - "prevText": "<mbrapa", - "nextText": "P\u00ebrpara>", - "currentText": "sot", - "weekHeader": "Ja", - "dateFormat": "d" - }, - "sr-SR": { - "closeText": "Zatvori", - "prevText": "<", - "nextText": ">", - "currentText": "Danas", - "weekHeader": "Sed", - "dateFormat": "dd/MM/yyyy" - }, - "sr": { - "closeText": "\u0417\u0430\u0442\u0432\u043e\u0440\u0438", - "prevText": "<", - "nextText": ">", - "currentText": "\u0414\u0430\u043d\u0430\u0441", - "weekHeader": "\u0421\u0435\u0434", - "dateFormat": "d" - }, - "sv": { - "closeText": "St\u00e4ng", - "prevText": "«F\u00f6rra", - "nextText": "N\u00e4sta»", - "currentText": "Idag", - "weekHeader": "Ve", - "dateFormat": "d" - }, - "ta": { - "closeText": "\u0bae\u0bc2\u0b9f\u0bc1", - "prevText": "\u0bae\u0bc1\u0ba9\u0bcd\u0ba9\u0bc8\u0baf\u0ba4\u0bc1", - "nextText": "\u0b85\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4\u0ba4\u0bc1", - "currentText": "\u0b87\u0ba9\u0bcd\u0bb1\u0bc1", - "weekHeader": "\u041d\u0435", - "dateFormat": "d" - }, - "th": { - "closeText": "\u0e1b\u0e34\u0e14", - "prevText": "« \u0e22\u0e49\u0e2d\u0e19", - "nextText": "\u0e16\u0e31\u0e14\u0e44\u0e1b »", - "currentText": "\u0e27\u0e31\u0e19\u0e19\u0e35\u0e49", - "weekHeader": "Wk", - "dateFormat": "d" - }, - "tr": { - "closeText": "kapat", - "prevText": "<geri", - "nextText": "ileri>", - "currentText": "bug\u00c3\u00bcn", - "weekHeader": "Hf", - "dateFormat": "d" - }, - "uk": { - "closeText": "\u00d0\u2014\u00d0\u00b0\u00d0\u00ba\u00d1\u20ac\u00d0\u00b8\u00d1\u201a\u00d0\u00b8", - "prevText": "<", - "nextText": ">", - "currentText": "\u00d0\u00a1\u00d1\u0152\u00d0\u00be\u00d0\u00b3\u00d0\u00be\u00d0\u00b4\u00d0\u00bd\u00d1\u2013", - "weekHeader": "\u00d0\u009d\u00d0\u00b5", - "dateFormat": "d" - }, - "vi": { - "closeText": "\u0110\u00f3ng", - "prevText": "<Tr\u01b0\u1edbc", - "nextText": "Ti\u1ebfp>", - "currentText": "H\u00f4m nay", - "weekHeader": "Tu", - "dateFormat": "d" - }, - "zh-CN": { - "closeText": "\u00e5\u2026\u00b3\u00e9\u2014\u00ad", - "prevText": "<\u00e4\u00b8\u0160\u00e6\u0153\u02c6", - "nextText": "\u00e4\u00b8\u2039\u00e6\u0153\u02c6>", - "currentText": "\u00e4\u00bb\u0160\u00e5\u00a4\u00a9", - "weekHeader": "\u00e5\u2018\u00a8", - "dateFormat": "d" - }, - "zh-HK": { - "closeText": "\u00e9\u2014\u0153\u00e9\u2013\u2030", - "prevText": "<\u00e4\u00b8\u0160\u00e6\u0153\u02c6", - "nextText": "\u00e4\u00b8\u2039\u00e6\u0153\u02c6>", - "currentText": "\u00e4\u00bb\u0160\u00e5\u00a4\u00a9", - "weekHeader": "\u00e5\u2018\u00a8", - "dateFormat": "d" - } + "en": { + "closeText": "Done", + "prevText": "Prev", + "nextText": "Next", + "currentText": "Today", + "weekHeader": "Wk", + "dateFormat": "d", + "datePickerRole": "date picker" + }, + "af": { + "closeText": "Selekteer", + "prevText": "Vorige", + "nextText": "Volgende", + "currentText": "Vandag", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "zh-TW": { + "closeText": "\u95dc\u9589", + "prevText": "<\u4e0a\u6708", + "nextText": "\u4e0b\u6708>", + "currentText": "\u4eca\u5929", + "weekHeader": "\u5468", + "dateFormat": "d" + }, + "ar": { + "closeText": "\u0625\u063a\u0644\u0627\u0642", + "prevText": "<\u0627\u0644\u0633\u0627\u0628\u0642", + "nextText": "\u0627\u0644\u062a\u0627\u0644\u064a>", + "currentText": "\u0627\u0644\u064a\u0648\u0645", + "weekHeader": "\u0623\u0633\u0628\u0648\u0639", + "dateFormat": "d" + }, + "az": { + "closeText": "Ba\u011fla", + "prevText": "<Geri", + "nextText": "\u0130r\u0259li>", + "currentText": "Bug\u00fcn", + "weekHeader": "Hf", + "dateFormat": "d" + }, + "bg": { + "closeText": "\u0437\u0430\u0442\u0432\u043e\u0440\u0438", + "prevText": "<\u043d\u0430\u0437\u0430\u0434", + "nextText": "\u043d\u0430\u043f\u0440\u0435\u0434>", + "currentText": "\u0434\u043d\u0435\u0441", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "bs": { + "closeText": "Zatvori", + "prevText": "<", + "nextText": ">", + "currentText": "Danas", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "ca": { + "closeText": "Tancar", + "prevText": "<Ant", + "nextText": "Seg>", + "currentText": "Avui", + "weekHeader": "Sm", + "dateFormat": "d" + }, + "cs": { + "closeText": "Zav\u0159\u00edt", + "prevText": "<D\u0159\u00edve", + "nextText": "Pozd\u011bji>", + "currentText": "Nyn\u00ed", + "weekHeader": "T\u00fdd", + "dateFormat": "d" + }, + "da": { + "closeText": "Luk", + "prevText": "<Forrige", + "nextText": "N\u00e6ste>", + "currentText": "Idag", + "weekHeader": "Uge", + "dateFormat": "d" + }, + "de": { + "closeText": "schlie\u00dfen", + "prevText": "<zur\u00fcck", + "nextText": "Vor>", + "currentText": "heute", + "weekHeader": "Wo", + "dateFormat": "d" + }, + "el": { + "closeText": "\u039a\u03bb\u03b5\u03af\u03c3\u03b9\u03bc\u03bf", + "prevText": "\u03a0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2", + "nextText": "\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf\u03c2", + "currentText": "\u03a4\u03c1\u03ad\u03c7\u03c9\u03bd \u039c\u03ae\u03bd\u03b1\u03c2", + "weekHeader": "\u0395\u03b2\u03b4", + "dateFormat": "d" + }, + "en-GB": { + "closeText": "Done", + "prevText": "Prev", + "nextText": "Next", + "currentText": "Today", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "eo": { + "closeText": "Fermi", + "prevText": "<Anta", + "nextText": "Sekv>", + "currentText": "Nuna", + "weekHeader": "Sb", + "dateFormat": "dd/MM/yyyy" + }, + "es": { + "closeText": "Cerrar", + "prevText": "<Ant", + "nextText": "Sig>", + "currentText": "Hoy", + "weekHeader": "Sm", + "dateFormat": "d" + }, + "et": { + "closeText": "Sulge", + "prevText": "Eelnev", + "nextText": "J\u00e4rgnev", + "currentText": "T\u00e4na", + "weekHeader": "Sm", + "dateFormat": "d" + }, + "eu": { + "closeText": "Egina", + "prevText": "<Aur", + "nextText": "Hur>", + "currentText": "Gaur", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "fa": { + "closeText": "\u0628\u0633\u062a\u0646", + "prevText": "<\u0642\u0628\u0644\u064a", + "nextText": "\u0628\u0639\u062f\u064a>", + "currentText": "\u0627\u0645\u0631\u0648\u0632", + "weekHeader": "\u0647\u0641", + "dateFormat": "d" + }, + "fi": { + "closeText": "Sulje", + "prevText": "«Edellinen", + "nextText": "Seuraava»", + "currentText": "Tänään", + "weekHeader": "Vk", + "dateFormat": "d" + }, + "fo": { + "closeText": "Lat aftur", + "prevText": "<Fyrra", + "nextText": "N\u00e6sta>", + "currentText": "\u00cd dag", + "weekHeader": "Vk", + "dateFormat": "d" + }, + "fr-CH": { + "closeText": "Fermer", + "prevText": "<Pr\u00e9c", + "nextText": "Suiv>", + "currentText": "Courant", + "weekHeader": "Sm", + "dateFormat": "d" + }, + "fr": { + "closeText": "Fermer", + "prevText": "<Pr\u00e9c", + "nextText": "Suiv>", + "currentText": "Courant", + "weekHeader": "Sm", + "dateFormat": "d" + }, + "he": { + "closeText": "\u05e1\u05d2\u05d5\u05e8", + "prevText": "<\u05d4\u05e7\u05d5\u05d3\u05dd", + "nextText": "\u05d4\u05d1\u05d0>", + "currentText": "\u05d4\u05d9\u05d5\u05dd", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "hr": { + "closeText": "Zatvori", + "prevText": "<", + "nextText": ">", + "currentText": "Danas", + "weekHeader": "Tje", + "dateFormat": "d" + }, + "hu": { + "closeText": "bez\u00c3\u00a1r\u00c3\u00a1s", + "prevText": "« vissza", + "nextText": "el\u00c5\u2018re »", + "currentText": "ma", + "weekHeader": "H\u00c3\u00a9", + "dateFormat": "d" + }, + "hy": { + "closeText": "\u00d5\u201c\u00d5\u00a1\u00d5\u00af\u00d5\u00a5\u00d5\u00ac", + "prevText": "<\u00d5\u2020\u00d5\u00a1\u00d5\u00ad.", + "nextText": "\u00d5\u20ac\u00d5\u00a1\u00d5\u00bb.>", + "currentText": "\u00d4\u00b1\u00d5\u00b5\u00d5\u00bd\u00d6\u2026\u00d6\u20ac", + "weekHeader": "\u00d5\u2021\u00d4\u00b2\u00d5\u008f", + "dateFormat": "d" + }, + "id": { + "closeText": "Tutup", + "prevText": "<mundur", + "nextText": "maju>", + "currentText": "hari ini", + "weekHeader": "Mg", + "dateFormat": "d" + }, + "is": { + "closeText": "Loka", + "prevText": "< Fyrri", + "nextText": "Næsti >", + "currentText": "Í dag", + "weekHeader": "Vika", + "dateFormat": "d" + }, + "it": { + "closeText": "Chiudi", + "prevText": "<Prec", + "nextText": "Succ>", + "currentText": "Oggi", + "weekHeader": "Sm", + "dateFormat": "d" + }, + "ja": { + "closeText": "\u9589\u3058\u308b", + "prevText": "<\u524d", + "nextText": "\u6b21>", + "currentText": "\u4eca\u65e5", + "weekHeader": "\u9031", + "dateFormat": "d" + }, + "ko": { + "closeText": "\u00eb\u2039\u00ab\u00ea\u00b8\u00b0", + "prevText": "\u00ec\u009d\u00b4\u00ec\u00a0\u201e\u00eb\u2039\u00ac", + "nextText": "\u00eb\u2039\u00a4\u00ec\u009d\u0152\u00eb\u2039\u00ac", + "currentText": "\u00ec\u02dc\u00a4\u00eb\u0160\u02dc", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "lt": { + "closeText": "U\u00c5\u00bedaryti", + "prevText": "<Atgal", + "nextText": "Pirmyn>", + "currentText": "\u00c5\u00a0iandien", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "lv": { + "closeText": "Aizv\u00c4\u201crt", + "prevText": "Iepr", + "nextText": "N\u00c4\u0081ka", + "currentText": "\u00c5\u00a0odien", + "weekHeader": "Nav", + "dateFormat": "d" + }, + "ms": { + "closeText": "Tutup", + "prevText": "<Sebelum", + "nextText": "Selepas>", + "currentText": "hari ini", + "weekHeader": "Mg", + "dateFormat": "d" + }, + "nl": { + "closeText": "Sluiten", + "prevText": "\u2190", + "nextText": "\u2192", + "currentText": "Vandaag", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "no": { + "closeText": "Lukk", + "prevText": "«Forrige", + "nextText": "Neste»", + "currentText": "I dag", + "weekHeader": "Uke", + "dateFormat": "d" + }, + "pl": { + "closeText": "Zamknij", + "prevText": "<Poprzedni", + "nextText": "Nast\u00c4\u2122pny>", + "currentText": "Dzi\u00c5\u203a", + "weekHeader": "Tydz", + "dateFormat": "d" + }, + "pt-BR": { + "closeText": "Fechar", + "prevText": "<Anterior", + "nextText": "Próximo>", + "currentText": "Hoje", + "weekHeader": "Sm", + "dateFormat": "d" + }, + "ro": { + "closeText": "\u00cenchide", + "prevText": "« Luna precedent\u0103", + "nextText": "Luna urm\u0103toare »", + "currentText": "Azi", + "weekHeader": "S\u0103pt", + "dateFormat": "d" + }, + "ru": { + "closeText": "\u00d0\u2014\u00d0\u00b0\u00d0\u00ba\u00d1\u20ac\u00d1\u2039\u00d1\u201a\u00d1\u0152", + "prevText": "<\u00d0\u0178\u00d1\u20ac\u00d0\u00b5\u00d0\u00b4", + "nextText": "\u00d0\u00a1\u00d0\u00bb\u00d0\u00b5\u00d0\u00b4>", + "currentText": "\u00d0\u00a1\u00d0\u00b5\u00d0\u00b3\u00d0\u00be\u00d0\u00b4\u00d0\u00bd\u00d1\u008f", + "weekHeader": "\u00d0\u009d\u00d0\u00b5", + "dateFormat": "d" + }, + "sk": { + "closeText": "Zavrie\u00c5\u00a5", + "prevText": "<Predch\u00c3\u00a1dzaj\u00c3\u00baci", + "nextText": "Nasleduj\u00c3\u00baci>", + "currentText": "Dnes", + "weekHeader": "Ty", + "dateFormat": "d" + }, + "sl": { + "closeText": "Zapri", + "prevText": "<Prejšnji", + "nextText": "Naslednji>", + "currentText": "Trenutni", + "weekHeader": "Teden", + "dateFormat": "d" + }, + "sq": { + "closeText": "mbylle", + "prevText": "<mbrapa", + "nextText": "P\u00ebrpara>", + "currentText": "sot", + "weekHeader": "Ja", + "dateFormat": "d" + }, + "sr-SR": { + "closeText": "Zatvori", + "prevText": "<", + "nextText": ">", + "currentText": "Danas", + "weekHeader": "Sed", + "dateFormat": "dd/MM/yyyy" + }, + "sr": { + "closeText": "\u0417\u0430\u0442\u0432\u043e\u0440\u0438", + "prevText": "<", + "nextText": ">", + "currentText": "\u0414\u0430\u043d\u0430\u0441", + "weekHeader": "\u0421\u0435\u0434", + "dateFormat": "d" + }, + "sv": { + "closeText": "St\u00e4ng", + "prevText": "«F\u00f6rra", + "nextText": "N\u00e4sta»", + "currentText": "Idag", + "weekHeader": "Ve", + "dateFormat": "d" + }, + "ta": { + "closeText": "\u0bae\u0bc2\u0b9f\u0bc1", + "prevText": "\u0bae\u0bc1\u0ba9\u0bcd\u0ba9\u0bc8\u0baf\u0ba4\u0bc1", + "nextText": "\u0b85\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4\u0ba4\u0bc1", + "currentText": "\u0b87\u0ba9\u0bcd\u0bb1\u0bc1", + "weekHeader": "\u041d\u0435", + "dateFormat": "d" + }, + "th": { + "closeText": "\u0e1b\u0e34\u0e14", + "prevText": "« \u0e22\u0e49\u0e2d\u0e19", + "nextText": "\u0e16\u0e31\u0e14\u0e44\u0e1b »", + "currentText": "\u0e27\u0e31\u0e19\u0e19\u0e35\u0e49", + "weekHeader": "Wk", + "dateFormat": "d" + }, + "tr": { + "closeText": "kapat", + "prevText": "<geri", + "nextText": "ileri>", + "currentText": "bug\u00c3\u00bcn", + "weekHeader": "Hf", + "dateFormat": "d" + }, + "uk": { + "closeText": "\u00d0\u2014\u00d0\u00b0\u00d0\u00ba\u00d1\u20ac\u00d0\u00b8\u00d1\u201a\u00d0\u00b8", + "prevText": "<", + "nextText": ">", + "currentText": "\u00d0\u00a1\u00d1\u0152\u00d0\u00be\u00d0\u00b3\u00d0\u00be\u00d0\u00b4\u00d0\u00bd\u00d1\u2013", + "weekHeader": "\u00d0\u009d\u00d0\u00b5", + "dateFormat": "d" + }, + "vi": { + "closeText": "\u0110\u00f3ng", + "prevText": "<Tr\u01b0\u1edbc", + "nextText": "Ti\u1ebfp>", + "currentText": "H\u00f4m nay", + "weekHeader": "Tu", + "dateFormat": "d" + }, + "zh-CN": { + "closeText": "\u00e5\u2026\u00b3\u00e9\u2014\u00ad", + "prevText": "<\u00e4\u00b8\u0160\u00e6\u0153\u02c6", + "nextText": "\u00e4\u00b8\u2039\u00e6\u0153\u02c6>", + "currentText": "\u00e4\u00bb\u0160\u00e5\u00a4\u00a9", + "weekHeader": "\u00e5\u2018\u00a8", + "dateFormat": "d" + }, + "zh-HK": { + "closeText": "\u00e9\u2014\u0153\u00e9\u2013\u2030", + "prevText": "<\u00e4\u00b8\u0160\u00e6\u0153\u02c6", + "nextText": "\u00e4\u00b8\u2039\u00e6\u0153\u02c6>", + "currentText": "\u00e4\u00bb\u0160\u00e5\u00a4\u00a9", + "weekHeader": "\u00e5\u2018\u00a8", + "dateFormat": "d" + } }; + $.each( regions, function( name, value ) { - var culture = Globalize.findClosestCulture( name ); - Globalize.addCultureInfo( culture && culture.name || name, { - messages : { - datepicker : value - } + Globalize.loadTranslations( name, { + datepicker : value }); }); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index d8a43801a75..f517bb884ad 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -43,6 +43,7 @@ $.widget( "ui.datepicker", { select: null }, _create: function() { + this.options.dateFormat = this.options.dateFormat || { date: "short" }; this.date = $.date( null, this.options.dateFormat ); this.date.eachDay = this.options.eachDay; @@ -335,6 +336,7 @@ $.widget( "ui.datepicker", { i = 0; for ( i; i < months.length; i++ ) { + // TODO Shouldn't we pass date as a parameter to build* fns instead of setting this.date? this.date = months[ i ]; headerClass = months[ i ].first ? "ui-corner-left" : months[ i ].last ? "ui-corner-right" : ""; @@ -368,7 +370,7 @@ $.widget( "ui.datepicker", { "
        "; }, _buildPreviousLink: function() { - var labels = Globalize.localize( "datepicker" ); + var labels = Globalize.translate( "datepicker" ); return ""; }, _buildNextLink: function() { - var labels = Globalize.localize( "datepicker" ); + var labels = Globalize.translate( "datepicker" ); return ""; }, _buildTitlebar: function() { - var labels = Globalize.localize( "datepicker" ); + var labels = Globalize.translate( "datepicker" ); return "
        " + "
        " + this._buildTitle() + @@ -412,7 +414,7 @@ $.widget( "ui.datepicker", { _buildGridHeading: function() { var cells = "", i = 0, - labels = Globalize.localize( "datepicker" ); + labels = Globalize.translate( "datepicker" ); if ( this.options.showWeek ) { cells += "" + labels.weekHeader + ""; @@ -432,10 +434,12 @@ $.widget( "ui.datepicker", { ""; }, _buildGridBody: function() { - var rows = "", - i = 0; - for ( i; i < this.date.days().length; i++ ) { - rows += this._buildWeekRow( this.date.days()[i] ); + // this.date.days() is not cached, and it has O(n^2) complexity. It is run O(n) times. So, it equals O(n^3). Not good at all. Caching. + var days = this.date.days(), + i = 0, + rows = ""; + for ( i; i < days.length; i++ ) { + rows += this._buildWeekRow( days[i] ); } return "" + rows + ""; }, @@ -472,7 +476,7 @@ $.widget( "ui.datepicker", { _buildDayLink: function( day ) { var link, classes = [ "ui-state-default" ], - labels = Globalize.localize( "datepicker" ); + labels = Globalize.translate( "datepicker" ); if ( day.date === this.date.day() ) { classes.push( "ui-state-focus" ); @@ -510,7 +514,7 @@ $.widget( "ui.datepicker", { day.date + ""; }, _buildButtons: function() { - var labels = Globalize.localize( "datepicker" ); + var labels = Globalize.translate( "datepicker" ); return "
        " + "" + "" + @@ -681,4 +685,4 @@ $.widget( "ui.datepicker", { } }); -}( jQuery )); \ No newline at end of file +}( jQuery )); From db78dd5fcebbb482ec7ee5f3105d4a7cac4d40ad Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Mon, 2 Dec 2013 10:09:51 -0200 Subject: [PATCH 047/172] Datepicker: Use Globalize 1.0.0 - Update $.date, and datepicker tests; - Update globalize; (previously, the link has been committed) - Update demos; - Change Week of Year of $.date days(). Drop iso8601Week and instead use CLDR's Week of Year ("w" pattern) generated using Globalize.format; --- demos/datepicker/date-formats.html | 25 +- demos/datepicker/jquery.ui.datepicker-ar.js | 23 - demos/datepicker/jquery.ui.datepicker-fr.js | 25 - demos/datepicker/jquery.ui.datepicker-he.js | 23 - .../datepicker/jquery.ui.datepicker-zh-TW.js | 23 - demos/datepicker/localization.html | 9 +- demos/datepicker/show-week.html | 10 +- external/date.js | 28 +- external/globalize.js | 1789 ++++++++++++++++- external/localization.js | 489 +++++ tests/unit/date/date.html | 6 +- tests/unit/date/date_core.js | 90 +- tests/unit/datepicker/datepicker.html | 5 +- tests/unit/datepicker/datepicker_core.js | 12 +- tests/unit/datepicker/datepicker_methods.js | 12 +- tests/unit/datepicker/datepicker_options.js | 8 +- ui/jquery.ui.datepicker.js | 4 - 17 files changed, 2354 insertions(+), 227 deletions(-) delete mode 100644 demos/datepicker/jquery.ui.datepicker-ar.js delete mode 100644 demos/datepicker/jquery.ui.datepicker-fr.js delete mode 100644 demos/datepicker/jquery.ui.datepicker-he.js delete mode 100644 demos/datepicker/jquery.ui.datepicker-zh-TW.js mode change 120000 => 100644 external/globalize.js diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index dc7c58180ba..6d091db85ca 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -18,7 +18,24 @@ $(function() { $( "#datepicker" ).datepicker(); $( "#format" ).change(function() { - $( "#datepicker" ).datepicker( "option", "dateFormat", $( this ).val() ); + var format; + switch( $( this ).val() ) { + case "short": + $( "#datepicker" ).datepicker( "option", "dateFormat", { + date: "short" + }); + break; + case "long": + $( "#datepicker" ).datepicker( "option", "dateFormat", { + date: "long" + }); + break; + case "iso": + $( "#datepicker" ).datepicker( "option", "dateFormat", { + pattern: "yyyy-MM-dd" + }); + break; + } }); }); @@ -29,9 +46,9 @@

        Format options:

        diff --git a/demos/datepicker/jquery.ui.datepicker-ar.js b/demos/datepicker/jquery.ui.datepicker-ar.js deleted file mode 100644 index cef0f08fd2d..00000000000 --- a/demos/datepicker/jquery.ui.datepicker-ar.js +++ /dev/null @@ -1,23 +0,0 @@ -/* Arabic Translation for jQuery UI date picker plugin. */ -/* Khaled Alhourani -- me@khaledalhourani.com */ -/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */ -jQuery(function($){ - $.datepicker.regional['ar'] = { - closeText: 'إغلاق', - prevText: '<السابق', - nextText: 'التالي>', - currentText: 'اليوم', - monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران', - 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], - monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], - dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'], - weekHeader: 'أسبوع', - dateFormat: 'dd/mm/yy', - firstDay: 6, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['ar']); -}); diff --git a/demos/datepicker/jquery.ui.datepicker-fr.js b/demos/datepicker/jquery.ui.datepicker-fr.js deleted file mode 100644 index 2d06743a661..00000000000 --- a/demos/datepicker/jquery.ui.datepicker-fr.js +++ /dev/null @@ -1,25 +0,0 @@ -/* French initialisation for the jQuery UI date picker plugin. */ -/* Written by Keith Wood (kbwood{at}iinet.com.au), - Stéphane Nahmani (sholby@sholby.net), - Stéphane Raimbault */ -jQuery(function($){ - $.datepicker.regional['fr'] = { - closeText: 'Fermer', - prevText: 'Précédent', - nextText: 'Suivant', - currentText: 'Aujourd\'hui', - monthNames: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', - 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], - monthNamesShort: ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin', - 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'], - dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'], - dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'], - dayNamesMin: ['D','L','M','M','J','V','S'], - weekHeader: 'Sem.', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['fr']); -}); diff --git a/demos/datepicker/jquery.ui.datepicker-he.js b/demos/datepicker/jquery.ui.datepicker-he.js deleted file mode 100644 index b9e8deec5fd..00000000000 --- a/demos/datepicker/jquery.ui.datepicker-he.js +++ /dev/null @@ -1,23 +0,0 @@ -/* Hebrew initialisation for the UI Datepicker extension. */ -/* Written by Amir Hardon (ahardon at gmail dot com). */ -jQuery(function($){ - $.datepicker.regional['he'] = { - closeText: 'סגור', - prevText: '<הקודם', - nextText: 'הבא>', - currentText: 'היום', - monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני', - 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'], - monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני', - 'יולי','אוג','ספט','אוק','נוב','דצמ'], - dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'], - dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], - dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; - $.datepicker.setDefaults($.datepicker.regional['he']); -}); diff --git a/demos/datepicker/jquery.ui.datepicker-zh-TW.js b/demos/datepicker/jquery.ui.datepicker-zh-TW.js deleted file mode 100644 index b9105ea507b..00000000000 --- a/demos/datepicker/jquery.ui.datepicker-zh-TW.js +++ /dev/null @@ -1,23 +0,0 @@ -/* Chinese initialisation for the jQuery UI date picker plugin. */ -/* Written by Ressol (ressol@gmail.com). */ -jQuery(function($){ - $.datepicker.regional['zh-TW'] = { - closeText: '關閉', - prevText: '<上月', - nextText: '下月>', - currentText: '今天', - monthNames: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - monthNamesShort: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], - dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], - dayNamesMin: ['日','一','二','三','四','五','六'], - weekHeader: '周', - dateFormat: 'yy/mm/dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '年'}; - $.datepicker.setDefaults($.datepicker.regional['zh-TW']); -}); diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index 21ddb236a32..dd0a47c3cb0 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -6,8 +6,6 @@ - - @@ -18,11 +16,11 @@ @@ -32,7 +30,6 @@

        Date:  

        diff --git a/demos/datepicker/show-week.html b/demos/datepicker/show-week.html index cc5732d6fc3..a4745952955 100644 --- a/demos/datepicker/show-week.html +++ b/demos/datepicker/show-week.html @@ -17,8 +17,7 @@ @@ -28,10 +27,9 @@

        Date:

        diff --git a/external/date.js b/external/date.js index 1a7893acc3d..b8d1ef30d33 100644 --- a/external/date.js +++ b/external/date.js @@ -19,24 +19,18 @@ var weekdays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ], Globalize.locale( "en" ); -$.date = function( date, format ) { +$.date = function( date, globalFormat ) { //TODO: Need to refactor $.date to be a constructor, move the methods to a prototype. - var origFormat = format; - if ( typeof date === "string" && date.length ) { - date = Globalize.parseDate( date, format ); + date = Globalize.parseDate( date, globalFormat ); } date = date || new Date(); return { - refresh: function() { - format = origFormat; - return this; - }, setFormat: function( format ) { if ( format ) { - format = format; + globalFormat = format; } return this; }, @@ -130,7 +124,7 @@ $.date = function( date, format ) { printDate = new Date( this.year(), date.getMonth(), 1 - leadDays ); for ( var row = 0; row < rows; row++ ) { var week = result[ result.length ] = { - number: this.iso8601Week( printDate ), + number: Globalize.format( printDate, { pattern: "w" } ), days: [] }; for ( var dayx = 0; dayx < 7; dayx++ ) { @@ -165,16 +159,6 @@ $.date = function( date, format ) { result[ result.length - 1 ].last = true; return result; }, - iso8601Week: function(date) { - var checkDate = new Date( date.getTime() ); - // Find Thursday of this week starting on Monday - checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); - var time = checkDate.getTime(); - // Compare with Jan 1 - checkDate.setMonth( 0 ); - checkDate.setDate( 1 ); - return Math.floor( Math.round( ( time - checkDate ) / 86400000) / 7 ) + 1; - }, select: function() { this.selected = this.clone(); return this; @@ -182,7 +166,7 @@ $.date = function( date, format ) { clone: function() { return $.date( new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), - date.getMinutes(), date.getSeconds()), format ); + date.getMinutes(), date.getSeconds()), globalFormat ); }, // TODO compare year, month, day each for better performance equal: function( other ) { @@ -195,7 +179,7 @@ $.date = function( date, format ) { return date; }, format: function( format ) { - return Globalize.format( date, format || origFormat ); + return Globalize.format( date, format || globalFormat ); } }; }; diff --git a/external/globalize.js b/external/globalize.js deleted file mode 120000 index 6e8e2e25767..00000000000 --- a/external/globalize.js +++ /dev/null @@ -1 +0,0 @@ -/home/xavier/jquery/globalize/dist/globalize.js \ No newline at end of file diff --git a/external/globalize.js b/external/globalize.js new file mode 100644 index 00000000000..1086d339db9 --- /dev/null +++ b/external/globalize.js @@ -0,0 +1,1788 @@ +/*! + * Globalize v1.0.0pre + * + * http://github.com/jquery/globalize + * + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-12-01T12:08Z + */ +(function( root, factory ) { + + if ( typeof define === "function" && define.amd ) { + // AMD. + define( factory ); + } else if ( typeof module === "object" && typeof module.exports === "object" ) { + // Node. CommonJS. + module.exports = factory(); + } else { + // Global + root.Globalize = factory(); + } + +}( this, function() { + +/** + * CLDR JavaScript Library v0.2.4-pre + * http://jquery.com/ + * + * Copyright 2013 Rafael Xavier de Souza + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-11-30T11:30Z + */ +/*! + * CLDR JavaScript Library v0.2.4-pre 2013-11-30T11:30Z MIT license © Rafael Xavier + * http://git.io/h4lmVg + */ + var Cldr = (function() { + + + + var alwaysArray = function( stringOrArray ) { + return typeof stringOrArray === "string" ? [ stringOrArray ] : stringOrArray; + }; + + + + + var common = function( Cldr ) { + + Cldr.prototype.main = function( path ) { + path = alwaysArray( path ); + return this.get( [ "main/{languageId}" ].concat( path ) ); + }; + + }; + + + + + var arrayIsArray = Array.isArray || function( obj ) { + return Object.prototype.toString.call( obj ) === "[object Array]"; + }; + + + + + var pathNormalize = function( path, attributes ) { + if ( arrayIsArray( path ) ) { + path = path.join( "/" ); + } + if ( typeof path !== "string" ) { + throw new Error( "invalid path \"" + path + "\"" ); + } + // 1: Ignore leading slash `/` + // 2: Ignore leading `cldr/` + path = path + .replace( /^\// , "" ) /* 1 */ + .replace( /^cldr\// , "" ); /* 2 */ + + // Replace {attribute}'s + path = path.replace( /{[a-zA-Z]+}/g, function( name ) { + name = name.replace( /^{([^}]*)}$/, "$1" ); + return attributes[ name ]; + }); + + return path.split( "/" ); + }; + + + + + var arraySome = function( array, callback ) { + var i, length; + if ( array.some ) { + return array.some( callback ); + } + for ( i = 0, length = array.length; i < length; i++ ) { + if ( callback( array[ i ], i, array ) ) { + return true; + } + } + return false; + }; + + + + + // Return the maximized language id as defined in + // http://www.unicode.org/reports/tr35/#Likely_Subtags + // 1. Canonicalize. + // 1.1 Make sure the input locale is in canonical form: uses the right separator, and has the right casing. + // TODO Right casing? What df? It seems languages are lowercase, scripts are Capitalized, territory is uppercase. I am leaving this as an exercise to the user. + + // 1.2 Replace any deprecated subtags with their canonical values using the data in supplemental metadata. Use the first value in the replacement list, if it exists. Language tag replacements may have multiple parts, such as "sh" ➞ "sr_Latn" or mo" ➞ "ro_MD". In such a case, the original script and/or region are retained if there is one. Thus "sh_Arab_AQ" ➞ "sr_Arab_AQ", not "sr_Latn_AQ". + // TODO What data? + + // 1.3 If the tag is grandfathered (see in the supplemental data), then return it. + // TODO grandfathered? + + // 1.4 Remove the script code 'Zzzz' and the region code 'ZZ' if they occur. + // 1.5 Get the components of the cleaned-up source tag (languages, scripts, and regions), plus any variants and extensions. + // 2. Lookup. Lookup each of the following in order, and stop on the first match: + // 2.1 languages_scripts_regions + // 2.2 languages_regions + // 2.3 languages_scripts + // 2.4 languages + // 2.5 und_scripts + // 3. Return + // 3.1 If there is no match, either return an error value, or the match for "und" (in APIs where a valid language tag is required). + // 3.2 Otherwise there is a match = languagem_scriptm_regionm + // 3.3 Let xr = xs if xs is not empty, and xm otherwise. + // 3.4 Return the language tag composed of languager _ scriptr _ regionr + variants + extensions . + + // + // @subtags [Array] normalized language id subtags tuple (see init.js). + var likelySubtags = function( cldr, subtags, options ) { + var match, matchFound, + language = subtags[ 0 ], + script = subtags[ 1 ], + territory = subtags[ 2 ]; + options = options || {}; + + // Skip if (language, script, territory) is not empty [3.3] + if ( language !== "und" && script !== "Zzzz" && territory !== "ZZ" ) { + return [ language, script, territory ]; + } + + // Skip if no supplemental likelySubtags data is present + if ( typeof cldr.get( "supplemental/likelySubtags" ) === "undefined" ) { + return; + } + + // [2] + matchFound = arraySome([ + [ language, script, territory ], + [ language, territory ], + [ language, script ], + [ language ], + [ "und", script ] + ], function( test ) { + return match = !(/\b(Zzzz|ZZ)\b/).test( test.join( "_" ) ) /* [1.4] */ && cldr.get( [ "supplemental/likelySubtags", test.join( "_" ) ] ); + }); + + // [3] + if ( matchFound ) { + // [3.2 .. 3.4] + match = match.split( "_" ); + return [ + language !== "und" ? language : match[ 0 ], + script !== "Zzzz" ? script : match[ 1 ], + territory !== "ZZ" ? territory : match[ 2 ] + ]; + } else if ( options.force ) { + // [3.1.2] + return cldr.get( "supplemental/likelySubtags/und" ).split( "_" ); + } else { + // [3.1.1] + return; + } + }; + + + + // Given a locale, remove any fields that Add Likely Subtags would add. + // http://www.unicode.org/reports/tr35/#Likely_Subtags + // 1. First get max = AddLikelySubtags(inputLocale). If an error is signaled, return it. + // 2. Remove the variants from max. + // 3. Then for trial in {language, language _ region, language _ script}. If AddLikelySubtags(trial) = max, then return trial + variants. + // 4. If you do not get a match, return max + variants. + // + // @maxLanguageId [Array] maxLanguageId tuple (see init.js). + var removeLikelySubtags = function( cldr, maxLanguageId ) { + var match, matchFound, + language = maxLanguageId[ 0 ], + script = maxLanguageId[ 1 ], + territory = maxLanguageId[ 2 ]; + + // [3] + matchFound = arraySome([ + [ [ language, "Zzzz", "ZZ" ], [ language ] ], + [ [ language, "Zzzz", territory ], [ language, territory ] ], + [ [ language, script, "ZZ" ], [ language, script ] ] + ], function( test ) { + var result = likelySubtags( cldr, test[ 0 ] ); + match = test[ 1 ]; + return result && result[ 0 ] === maxLanguageId[ 0 ] && + result[ 1 ] === maxLanguageId[ 1 ] && + result[ 2 ] === maxLanguageId[ 2 ]; + }); + + // [4] + return matchFound ? match : maxLanguageId; + }; + + + + + var supplemental = function( cldr ) { + + var prepend, supplemental; + + prepend = function( prepend ) { + return function( path ) { + path = alwaysArray( path ); + return cldr.get( [ prepend ].concat( path ) ); + }; + }; + + supplemental = prepend( "supplemental" ); + + // Week Data + // http://www.unicode.org/reports/tr35/tr35-dates.html#Week_Data + supplemental.weekData = prepend( "supplemental/weekData" ); + + supplemental.weekData.firstDay = function() { + return cldr.get( "supplemental/weekData/firstDay/{territory}" ) || + cldr.get( "supplemental/weekData/firstDay/001" ); + }; + + supplemental.weekData.minDays = function() { + var minDays = cldr.get( "supplemental/weekData/minDays/{territory}" ) || + cldr.get( "supplemental/weekData/minDays/001" ); + return parseInt( minDays, 10 ); + }; + + // Time Data + // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data + supplemental.timeData = prepend( "supplemental/timeData" ); + + supplemental.timeData.allowed = function() { + return cldr.get( "supplemental/timeData/{territory}/_allowed" ) || + cldr.get( "supplemental/timeData/001/_allowed" ); + }; + + supplemental.timeData.preferred = function() { + return cldr.get( "supplemental/timeData/{territory}/_preferred" ) || + cldr.get( "supplemental/timeData/001/_preferred" ); + }; + + return supplemental; + + }; + + + + + var init = function( locale ) { + var language, languageId, maxLanguageId, script, territory, unicodeLanguageId, variant; + + if ( typeof locale !== "string" ) { + throw new Error( "invalid locale type: \"" + JSON.stringify( locale ) + "\"" ); + } + + // Normalize locale code. + // Get (or deduce) the "triple subtags": language, territory (also aliased as region), and script subtags. + // Get the variant subtags (calendar, collation, currency, etc). + // refs: + // - http://www.unicode.org/reports/tr35/#Field_Definitions + // - http://www.unicode.org/reports/tr35/#Language_and_Locale_IDs + // - http://www.unicode.org/reports/tr35/#Unicode_locale_identifier + + locale = locale.replace( /-/, "_" ); + + // TODO normalize unicode locale extensions. Currently, skipped. + // unicodeLocaleExtensions = locale.split( "_u_" )[ 1 ]; + locale = locale.split( "_u_" )[ 0 ]; + + // TODO normalize transformed extensions. Currently, skipped. + // transformedExtensions = locale.split( "_t_" )[ 1 ]; + locale = locale.split( "_t_" )[ 0 ]; + + unicodeLanguageId = locale; + + // unicodeLanguageId = ... + switch ( true ) { + + // language_script_territory.. + case /^[a-z]{2}_[A-Z][a-z]{3}_[A-Z0-9]{2}(\b|_)/.test( unicodeLanguageId ): + language = unicodeLanguageId.split( "_" )[ 0 ]; + script = unicodeLanguageId.split( "_" )[ 1 ]; + territory = unicodeLanguageId.split( "_" )[ 2 ]; + variant = unicodeLanguageId.split( "_" )[ 3 ]; + break; + + // language_script.. + case /^[a-z]{2}_[A-Z][a-z]{3}(\b|_)/.test( unicodeLanguageId ): + language = unicodeLanguageId.split( "_" )[ 0 ]; + script = unicodeLanguageId.split( "_" )[ 1 ]; + territory = "ZZ"; + variant = unicodeLanguageId.split( "_" )[ 2 ]; + break; + + // language_territory.. + case /^[a-z]{2}_[A-Z0-9]{2}(\b|_)/.test( unicodeLanguageId ): + language = unicodeLanguageId.split( "_" )[ 0 ]; + script = "Zzzz"; + territory = unicodeLanguageId.split( "_" )[ 1 ]; + variant = unicodeLanguageId.split( "_" )[ 2 ]; + break; + + // language.., or root + case /^([a-z]{2}|root)(\b|_)/.test( unicodeLanguageId ): + language = unicodeLanguageId.split( "_" )[ 0 ]; + script = "Zzzz"; + territory = "ZZ"; + variant = unicodeLanguageId.split( "_" )[ 1 ]; + break; + + default: + language = "und"; + break; + } + + // When a locale id does not specify a language, or territory (region), or script, they are obtained by Likely Subtags. + maxLanguageId = likelySubtags( this, [ language, script, territory ], { force: true } ) || unicodeLanguageId.split( "_" ); + language = maxLanguageId[ 0 ]; + script = maxLanguageId[ 1 ]; + territory = maxLanguageId[ 2 ]; + + // TODO json content distributed on zip file use languageId with `-` on main.. Why `-` vs. `_` ? + languageId = removeLikelySubtags( this, maxLanguageId ).join( "_" ); + + // Set attributes + this.attributes = { + + // Unicode Language Id + languageId: languageId, + maxLanguageId: maxLanguageId.join( "_" ), + + // Unicode Language Id Subtabs + language: language, + script: script, + territory: territory, + region: territory, /* alias */ + variant: variant + }; + + this.locale = variant ? [ languageId, variant ].join( "_" ) : languageId; + + // Inlcude supplemental helper + this.supplemental = supplemental( this ); + }; + + + + + // @path: normalized path + var resourceGet = function( data, path ) { + var i, + node = data, + length = path.length; + + for ( i = 0; i < length - 1; i++ ) { + node = node[ path[ i ] ]; + if ( !node ) { + return undefined; + } + } + return node[ path[ i ] ]; + }; + + + + + var bundleParentLookup = function( Cldr, locale ) { + var parent; + + if ( locale === "root" ) { + return; + } + + // First, try to find parent on supplemental data. + parent = resourceGet( Cldr._resolved, pathNormalize( [ "supplemental/parentLocales/parentLocale", locale ] ) ); + if ( parent ) { + return parent; + } + + // Or truncate locale. + parent = locale.substr( 0, locale.lastIndexOf( "_" ) ); + if ( !parent ) { + return "root"; + } + + return parent; + }; + + + + + // @path: normalized path + var resourceSet = function( data, path, value ) { + var i, + node = data, + length = path.length; + + for ( i = 0; i < length - 1; i++ ) { + if ( !node[ path[ i ] ] ) { + node[ path[ i ] ] = {}; + } + node = node[ path[ i ] ]; + } + node[ path[ i ] ] = value; + }; + + + + + var arrayForEach = function( array, callback ) { + var i, length; + if ( array.forEach ) { + return array.forEach( callback ); + } + for ( i = 0, length = array.length; i < length; i++ ) { + callback( array[ i ], i, array ); + } + }; + + + var jsonMerge = (function() { + + // Returns new deeply merged JSON. + // + // Eg. + // merge( { a: { b: 1, c: 2 } }, { a: { b: 3, d: 4 } } ) + // -> { a: { b: 3, c: 2, d: 4 } } + // + // @arguments JSON's + // + var merge = function() { + var destination = {}, + sources = [].slice.call( arguments, 0 ); + arrayForEach( sources, function( source ) { + var prop; + for ( prop in source ) { + if ( prop in destination && arrayIsArray( destination[ prop ] ) ) { + + // Concat Arrays + destination[ prop ] = destination[ prop ].concat( source[ prop ] ); + + } else if ( prop in destination && typeof destination[ prop ] === "object" ) { + + // Merge Objects + destination[ prop ] = merge( destination[ prop ], source[ prop ] ); + + } else { + + // Set new values + destination[ prop ] = source[ prop ]; + + } + } + }); + return destination; + }; + + return merge; + +}()); + var itemLookup = (function() { + + var lookup; + + lookup = function( Cldr, locale, path, attributes, childLocale ) { + var normalizedPath, parent, value; + + // 1: Finish recursion + // 2: Avoid infinite loop + if ( typeof locale === "undefined" /* 1 */ || locale === childLocale /* 2 */ ) { + return; + } + + // Resolve path + normalizedPath = pathNormalize( path, attributes ); + + // Check resolved (cached) data first + value = resourceGet( Cldr._resolved, normalizedPath ); + if ( value ) { + return value; + } + + // Check raw data + value = resourceGet( Cldr._raw, normalizedPath ); + + if ( !value ) { + // Or, lookup at parent locale + parent = bundleParentLookup( Cldr, locale ); + value = lookup( Cldr, parent, path, jsonMerge( attributes, { languageId: parent }), locale ); + } + + // Set resolved (cached) + resourceSet( Cldr._resolved, normalizedPath, value ); + + return value; + }; + + return lookup; + +}()); + + + var itemGetResolved = function( Cldr, path, attributes ) { + // Resolve path + var normalizedPath = pathNormalize( path, attributes ); + + return resourceGet( Cldr._resolved, normalizedPath ); + }; + + + + + var Cldr = function() { + init.apply( this, arguments ); + }; + + Cldr._resolved = {}; + Cldr._raw = {}; + + // Load resolved or unresolved cldr data + // @json [JSON] + Cldr.load = function( json ) { + if ( typeof json !== "object" ) { + throw new Error( "invalid json" ); + } + Cldr._raw = jsonMerge( Cldr._raw, json ); + }; + + Cldr.prototype.get = function( path ) { + // Simplify locale using languageId (there are no other resource bundles) + // 1: during init(), get is called, but languageId is not defined. Use "" as a workaround in this very specific scenario. + var locale = this.attributes && this.attributes.languageId || "" /* 1 */; + + return itemGetResolved( Cldr, path, this.attributes ) || + itemLookup( Cldr, locale, path, this.attributes ); + }; + + common( Cldr ); + + return Cldr; + + + +}()); + + + var arrayMap = function( array, callback ) { + var clone, i, length; + if ( array.map ) { + return array.map( callback ); + } + for ( clone = [], i = 0, length = array.length; i < length; i++ ) { + clone[ i ] = callback( array[ i ], i, array ); + } + return clone; + }; + + + + + var objectValues = function( object ) { + var i, + result = []; + + for ( i in object ) { + result.push( object[ i ] ); + } + + return result; + }; + + + + + /** + * allPreset() + * + * @cldr [Cldr instance]. + * + * Return an Array with all (skeleton, date, time, datetime) presets. + */ + var datetimeAllPresets = function( cldr ) { + var result = []; + + // Skeleton + result = objectValues( cldr.main( "dates/calendars/gregorian/dateTimeFormats/availableFormats" ) ); + + // Time + result = result.concat( objectValues( cldr.main( "dates/calendars/gregorian/timeFormats" ) ) ); + + // Date + result = result.concat( objectValues( cldr.main( "dates/calendars/gregorian/dateFormats" ) ) ); + + // Datetime + result = result.concat( arrayMap( objectValues( cldr.main( "dates/calendars/gregorian/dateTimeFormats" ) ), function( datetimeFormat, key ) { + if ( typeof datetimeFormat !== "string" ) { + return datetimeFormat; + } + return datetimeFormat + .replace( /\{0\}/, cldr.main([ + "dates/calendars/gregorian/timeFormats", + key + ])) + .replace( /\{1\}/, cldr.main([ + "dates/calendars/gregorian/dateFormats", + key + ])); + })); + + return arrayMap( result, function( pattern ) { + return { pattern: pattern }; + }); + }; + + + + + /** + * expandPattern( pattern, cldr ) + * + * @pattern [String or Object] if String, it's considered a skeleton. Object accepts: + * - skeleton: [String] lookup availableFormat; + * - date: [String] ( "full" | "long" | "medium" | "short" ); + * - time: [String] ( "full" | "long" | "medium" | "short" ); + * - datetime: [String] ( "full" | "long" | "medium" | "short" ); + * - pattern: [String] For more info see datetime/format.js. + * + * @cldr [Cldr instance]. + * + * Return the corresponding pattern. + * Eg for "en": + * - "GyMMMd" returns "MMM d, y G"; + * - { skeleton: "GyMMMd" } returns "MMM d, y G"; + * - { date: "full" } returns "EEEE, MMMM d, y"; + * - { time: "full" } returns "h:mm:ss a zzzz"; + * - { datetime: "full" } returns "EEEE, MMMM d, y 'at' h:mm:ss a zzzz"; + * - { pattern: "dd/mm" } returns "dd/mm"; + */ + var datetimeExpandPattern = function( pattern, cldr ) { + var result; + + if ( typeof pattern === "string" ) { + pattern = { skeleton: pattern }; + } + + if ( typeof pattern === "object" ) { + + switch ( true ) { + case "skeleton" in pattern: + result = cldr.main([ + "dates/calendars/gregorian/dateTimeFormats/availableFormats", + pattern.skeleton + ]); + break; + + case "date" in pattern: + case "time" in pattern: + result = cldr.main([ + "dates/calendars/gregorian", + "date" in pattern ? "dateFormats" : "timeFormats", + ( pattern.date || pattern.time ) + ]); + break; + + case "datetime" in pattern: + result = cldr.main([ + "dates/calendars/gregorian/dateTimeFormats", + pattern.datetime + ]); + if ( result ) { + result = result + .replace( /\{0\}/, cldr.main([ + "dates/calendars/gregorian/timeFormats", + pattern.datetime + ])) + .replace( /\{1\}/, cldr.main([ + "dates/calendars/gregorian/dateFormats", + pattern.datetime + ])); + } + break; + + case "pattern" in pattern: + result = pattern.pattern; + break; + + default: + throw new Error( "Invalid pattern" ); + } + + } else { + throw new Error( "Invalid pattern" ); + } + + if ( !result ) { + throw new Error( "Pattern not found" ); + } + + return result; + }; + + + + var datetimeWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ]; + + + + var arrayIndexOf = function( array, item ) { + if ( array.indexOf ) { + return array.indexOf( item ); + } + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[i] === item ) { + return i; + } + } + return -1; + }; + + + + + /** + * firstDayOfWeek + */ + var datetimeFirstDayOfWeek = function( cldr ) { + return arrayIndexOf( datetimeWeekDays, cldr.supplemental.weekData.firstDay() ); + }; + + + + + /** + * dayOfWeek + * + * Return the day of the week normalized by the territory's firstDay [0-6]. + * Eg for "mon": + * - return 0 if territory is GB, or BR, or DE, or FR (week starts on "mon"); + * - return 1 if territory is US (week starts on "sun"); + * - return 2 if territory is EG (week starts on "sat"); + */ + var datetimeDayOfWeek = function( date, cldr ) { + return ( date.getDay() - datetimeFirstDayOfWeek( cldr ) + 7 ) % 7; + }; + + + + + /** + * distanceInDays( from, to ) + * + * Return the distance in days between from and to Dates. + */ + var datetimeDistanceInDays = function( from, to ) { + var inDays = 864e5; + return ( to.getTime() - from.getTime() ) / inDays; + }; + + + + + /** + * startOf + * + * Return the + */ + var datetimeStartOf = function( date, unit ) { + date = new Date( date.getTime() ); + switch( unit ) { + case "year": + date.setMonth( 0 ); + /* falls through */ + case "month": + date.setDate( 1 ); + /* falls through */ + case "day": + date.setHours( 0 ); + /* falls through */ + case "hour": + date.setMinutes( 0 ); + /* falls through */ + case "minute": + date.setSeconds( 0 ); + /* falls through */ + case "second": + date.setMilliseconds( 0 ); + } + return date; + }; + + + + + /** + * dayOfYear + * + * Return the distance in days of the date to the begin of the year [0-d]. + */ + var datetimeDayOfYear = function( date ) { + return Math.floor( datetimeDistanceInDays( datetimeStartOf( date, "year" ), date ) ); + }; + + + + + /** + * millisecondsInDay + */ + var datetimeMillisecondsInDay = function( date ) { + // TODO Handle daylight savings discontinuities + return date - datetimeStartOf( date, "day" ); + }; + + + + var datetimePatternRe = (/([a-z])\1*|'[^']+'|''|./ig); + + + + var stringPad = function( str, count, right ) { + var length; + if ( typeof str !== "string" ) { + str = String( str ); + } + for ( length = str.length; length < count; length += 1 ) { + str = ( right ? ( str + "0" ) : ( "0" + str ) ); + } + return str; + }; + + + + + /** + * format( date, pattern, cldr ) + * + * @date [Date instance]. + * + * @pattern [String] raw pattern. + * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns + * + * @cldr [Cldr instance]. + * + * TODO Support other calendar types. + * + * Disclosure: this function borrows excerpts of dojo/date/locale. + */ + var datetimeFormat = function( date, pattern, cldr ) { + var widths = [ "abbreviated", "wide", "narrow" ]; + return pattern.replace( datetimePatternRe, function( current ) { + var pad, ret, + chr = current.charAt( 0 ), + length = current.length; + + if ( chr === "j" ) { + // Locale preferred hHKk. + // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data + chr = cldr.supplemental.timeData.preferred(); + } + + switch ( chr ) { + + // Era + case "G": + ret = cldr.main([ + "dates/calendars/gregorian/eras", + length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" ), + date.getFullYear() < 0 ? 0 : 1 + ]); + break; + + // Year + case "y": + // Plain year. + // The length specifies the padding, but for two letters it also specifies the maximum length. + ret = String( date.getFullYear() ); + pad = true; + if ( length === 2 ) { + ret = ret.substr( ret.length - 2 ); + } + break; + + case "Y": + // Year in "Week of Year" + // The length specifies the padding, but for two letters it also specifies the maximum length. + // yearInWeekofYear = date + DaysInAWeek - (dayOfWeek - firstDay) - minDays + ret = new Date( date.getTime() ); + ret.setDate( ret.getDate() + 7 - ( datetimeDayOfWeek( date, cldr ) - datetimeFirstDayOfWeek( cldr ) ) - cldr.supplemental.weekData.minDays() ); + ret = String( ret.getFullYear() ); + pad = true; + if ( length === 2 ) { + ret = ret.substr( ret.length - 2 ); + } + break; + + case "u": // Extended year. Need to be implemented. + case "U": // Cyclic year name. Need to be implemented. + throw new Error( "Not implemented" ); + + // Quarter + case "Q": + case "q": + ret = Math.ceil( ( date.getMonth() + 1 ) / 3 ); + if ( length <= 2 ) { + pad = true; + } else { + // http://unicode.org/cldr/trac/ticket/6788 + ret = cldr.main([ + "dates/calendars/gregorian/quarters", + chr === "Q" ? "format" : "stand-alone", + widths[ length - 3 ], + ret + ]); + } + break; + + // Month + case "M": + case "L": + ret = date.getMonth() + 1; + if ( length <= 2 ) { + pad = true; + } else { + ret = cldr.main([ + "dates/calendars/gregorian/months", + chr === "M" ? "format" : "stand-alone", + widths[ length - 3 ], + ret + ]); + } + break; + + // Week + case "w": + // Week of Year. + // woy = ceil( ( doy + dow of 1/1 ) / 7 ) - minDaysStuff ? 1 : 0. + // TODO should pad on ww? Not documented, but I guess so. + ret = datetimeDayOfWeek( datetimeStartOf( date, "year" ), cldr ); + ret = Math.ceil( ( datetimeDayOfYear( date ) + ret ) / 7 ) - ( 7 - ret >= cldr.supplemental.weekData.minDays() ? 0 : 1 ); + pad = true; + break; + + case "W": + // Week of Month. + // wom = ceil( ( dom + dow of `1/month` ) / 7 ) - minDaysStuff ? 1 : 0. + ret = datetimeDayOfWeek( datetimeStartOf( date, "month" ), cldr ); + ret = Math.ceil( ( date.getDate() + ret ) / 7 ) - ( 7 - ret >= cldr.supplemental.weekData.minDays() ? 0 : 1 ); + break; + + // Day + case "d": + ret = date.getDate(); + pad = true; + break; + + case "D": + ret = datetimeDayOfYear( date ) + 1; + pad = true; + break; + + case "F": + // Day of Week in month. eg. 2nd Wed in July. + ret = Math.floor( date.getDate() / 7 ) + 1; + break; + + case "g+": + // Modified Julian day. Need to be implemented. + throw new Error( "Not implemented" ); + + // Week day + case "e": + case "c": + if ( length <= 2 ) { + // Range is [1-7] (deduced by example provided on documentation) + // TODO Should pad with zeros (not specified in the docs)? + ret = datetimeDayOfWeek( date, cldr ) + 1; + pad = true; + break; + } + + /* falls through */ + case "E": + ret = datetimeWeekDays[ date.getDay() ]; + if ( length === 6 ) { + // If short day names are not explicitly specified, abbreviated day names are used instead. + // http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras + // http://unicode.org/cldr/trac/ticket/6790 + ret = cldr.main([ + "dates/calendars/gregorian/days", + [ chr === "c" ? "stand-alone" : "format" ], + "short", + ret + ]) || cldr.main([ + "dates/calendars/gregorian/days", + [ chr === "c" ? "stand-alone" : "format" ], + "abbreviated", + ret + ]); + } else { + ret = cldr.main([ + "dates/calendars/gregorian/days", + [ chr === "c" ? "stand-alone" : "format" ], + widths[ length < 3 ? 0 : length - 3 ], + ret + ]); + } + break; + + // Period (AM or PM) + case "a": + ret = cldr.main([ + "dates/calendars/gregorian/dayPeriods/format/wide", + date.getHours() < 12 ? "am" : "pm" + ]); + break; + + // Hour + case "h": // 1-12 + ret = ( date.getHours() % 12 ) || 12; + pad = true; + break; + + case "H": // 0-23 + ret = date.getHours(); + pad = true; + break; + + case "K": // 0-11 + ret = date.getHours() % 12; + pad = true; + break; + + case "k": // 1-24 + ret = date.getHours() || 24; + pad = true; + break; + + // Minute + case "m": + ret = date.getMinutes(); + pad = true; + break; + + // Second + case "s": + ret = date.getSeconds(); + pad = true; + break; + + case "S": + ret = Math.round( date.getMilliseconds() * Math.pow( 10, length - 3 ) ); + pad = true; + break; + + case "A": + ret = Math.round( datetimeMillisecondsInDay( date ) * Math.pow( 10, length - 3 ) ); + pad = true; + break; + + // Zone + // see http://www.unicode.org/reports/tr35/tr35-dates.html#Using_Time_Zone_Names ? + // Need to be implemented. + case "z": + case "Z": + case "O": + case "v": + case "V": + case "X": + case "x": + throw new Error( "Not implemented" ); + + // Anything else is considered a literal, including [ ,:/.'@#], chinese, japonese, and arabic characters. + default: + return current; + } + if ( pad ) { + ret = stringPad( ret, length ); + } + return ret; + }); + }; + + + + + var arrayEvery = function( array, callback ) { + var i, length; + if ( array.every ) { + return array.every( callback ); + } + for ( i = 0, length = array.length; i < length; i++ ) { + if ( !callback( array[ i ], i, array ) ) { + return false; + } + } + return true; + }; + + + + + /** + * tokenizer( value, pattern ) + * + * Returns an Array of tokens, eg. value "5 o'clock PM", pattern "h 'o''clock' a": + * [{ + * type: "h", + * lexeme: "5" + * }, { + * type: "literal", + * lexeme: " " + * }, { + * type: "literal", + * lexeme: "o'clock" + * }, { + * type: "literal", + * lexeme: " " + * }, { + * type: "a", + * lexeme: "PM", + * value: "pm" + * }] + * + * OBS: lexeme's are always String and may return invalid ranges depending of the token type. Eg. "99" for month number. + * + * Return an empty Array when not successfully parsed. + */ + var datetimeTokenizer = function( value, pattern, cldr ) { + var valid, + tokens = [], + widths = [ "abbreviated", "wide", "narrow" ]; + + valid = arrayEvery( pattern.match( datetimePatternRe ), function( current ) { + var chr, length, tokenRe, + token = {}; + + function oneDigitIfLengthOne() { + if ( length === 1 ) { + return tokenRe = /\d/; + } + } + + function oneOrTwoDigitsIfLengthOne() { + if ( length === 1 ) { + return tokenRe = /\d\d?/; + } + } + + function twoDigitsIfLengthTwo() { + if ( length === 2 ) { + return tokenRe = /\d\d/; + } + } + + // Brute-force test every locale entry in an attempt to match the given value. + // Return the first found one (and set token accordingly), or null. + function lookup( path ) { + var i, re, + data = cldr.main( path ); + for ( i in data ) { + re = new RegExp( "^" + data[ i ] ); + if ( re.test( value ) ) { + token.value = i; + return tokenRe = new RegExp( data[ i ] ); + } + } + return null; + } + + token.type = current; + chr = current.charAt( 0 ), + length = current.length; + + switch ( chr ) { + + // Era + case "G": + lookup([ + "dates/calendars/gregorian/eras", + length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" ) + ]); + break; + + // Year + case "y": + case "Y": + // number l=1:+, l=2:{2}, l=3:{3,}, l=4:{4,}, ... + if ( length === 1 ) { + tokenRe = /\d+/; + } else if ( length === 2 ) { + tokenRe = /\d\d/; + } else { + tokenRe = new RegExp( "\\d{" + length + ",}" ); + } + break; + + case "u": // Extended year. Need to be implemented. + case "U": // Cyclic year name. Need to be implemented. + throw new Error( "Not implemented" ); + + // Quarter + case "Q": + case "q": + // number l=1:{1}, l=2:{2}. + // lookup l=3... + oneDigitIfLengthOne() || twoDigitsIfLengthTwo() || lookup([ + "dates/calendars/gregorian/quarters", + chr === "Q" ? "format" : "stand-alone", + widths[ length - 3 ] + ]); + break; + + // Month + case "M": + case "L": + // number l=1:{1,2}, l=2:{2}. + // lookup l=3... + oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo() || lookup([ + "dates/calendars/gregorian/months", + chr === "M" ? "format" : "stand-alone", + widths[ length - 3 ] + ]); + break; + + // Day (see d below) + case "D": + // number {l,3}. + if ( length <= 3 ) { + tokenRe = new RegExp( "\\d{" + length + ",3}" ); + } + break; + + case "W": + case "F": + // number l=1:{1}. + oneDigitIfLengthOne(); + break; + + case "g+": + // Modified Julian day. Need to be implemented. + throw new Error( "Not implemented" ); + + // Week day + case "e": + case "c": + // number l=1:{1}, l=2:{2}. + // lookup for length >=3. + if( length <= 2 ) { + oneDigitIfLengthOne() || twoDigitsIfLengthTwo(); + break; + } + + /* falls through */ + case "E": + if ( length === 6 ) { + // Note: if short day names are not explicitly specified, abbreviated day names are used instead http://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras + lookup([ + "dates/calendars/gregorian/days", + [ chr === "c" ? "stand-alone" : "format" ], + "short" + ]) || lookup([ + "dates/calendars/gregorian/days", + [ chr === "c" ? "stand-alone" : "format" ], + "abbreviated" + ]); + } else { + lookup([ + "dates/calendars/gregorian/days", + [ chr === "c" ? "stand-alone" : "format" ], + widths[ length < 3 ? 0 : length - 3 ] + ]); + } + break; + + // Period (AM or PM) + case "a": + lookup([ + "dates/calendars/gregorian/dayPeriods/format/wide" + ]); + break; + + // Week, Day, Hour, Minute, or Second + case "w": + case "d": + case "h": + case "H": + case "K": + case "k": + case "j": + case "m": + case "s": + // number l1:{1,2}, l2:{2}. + oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo(); + break; + + case "S": + // number {l}. + tokenRe = new RegExp( "\\d{" + length + "}" ); + break; + + case "A": + // number {l+5}. + tokenRe = new RegExp( "\\d{" + ( length + 5 ) + "}" ); + break; + + // Zone + // see http://www.unicode.org/reports/tr35/tr35-dates.html#Using_Time_Zone_Names ? + // Need to be implemented. + case "z": + case "Z": + case "O": + case "v": + case "V": + case "X": + case "x": + throw new Error( "Not implemented" ); + + case "'": + token.type = "literal"; + if ( current.charAt( 1 ) === "'" ) { + tokenRe = /'/; + } else { + tokenRe = /'[^']+'/; + } + break; + + default: + token.type = "literal"; + tokenRe = /./; + } + + if ( !tokenRe ) { + return false; + } + + // Get lexeme and consume it. + value = value.replace( new RegExp( "^" + tokenRe.source ), function( lexeme ) { + token.lexeme = lexeme; + return ""; + }); + + if ( !token.lexeme ) { + return false; + } + + tokens.push( token ); + return true; + }); + + return valid ? tokens : []; + }; + + + var datetimeParse = (function() { + + function outOfRange( value, low, high ) { + return value < low || value > high; + } + + /** + * parse + * + * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns + */ + return function( value, pattern, cldr ) { + var amPm, era, hour24, valid, + YEAR = 0, + MONTH = 1, + DAY = 2, + HOUR = 3, + MINUTE = 4, + SECOND = 5, + MILLISECONDS = 6, + date = new Date(), + tokens = datetimeTokenizer( value, pattern, cldr ), + truncateAt = [], + units = [ "year", "month", "day", "hour", "minute", "second", "milliseconds" ]; + + if ( !tokens.length ) { + return null; + } + + valid = arrayEvery( tokens, function( token ) { + var century, chr, value, length; + + if ( token.type === "literal" ) { + // continue + return true; + } + + chr = token.type.charAt( 0 ); + length = token.type.length; + + if ( chr === "j" ) { + // Locale preferred hHKk. + // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data + chr = cldr.supplemental.timeData.preferred(); + } + + switch ( chr ) { + + // Era + case "G": + truncateAt.push( YEAR ); + era = +token.value; + break; + + // Year + case "y": + value = +token.lexeme; + if ( length === 2 ) { + if ( outOfRange( value, 0, 99 ) ) { + return false; + } + // mimic dojo/date/locale: choose century to apply, according to a sliding window of 80 years before and 20 years after present year. + century = Math.floor( date.getFullYear() / 100 ) * 100; + value += century; + if ( value > date.getFullYear() + 20 ) { + value -= 100; + } + } + date.setFullYear( value ); + truncateAt.push( YEAR ); + break; + + case "Y": // Year in "Week of Year" + case "u": // Extended year. Need to be implemented. + case "U": // Cyclic year name. Need to be implemented. + throw new Error( "Not implemented" ); + + // Quarter (skip) + case "Q": + case "q": + break; + + // Month + case "M": + case "L": + if ( length <= 2 ) { + value = +token.lexeme; + } else { + value = +token.value; + } + if( outOfRange( value, 1, 12 ) ) { + return false; + } + date.setMonth( value - 1 ); + truncateAt.push( MONTH ); + break; + + // Week (skip) + case "w": // Week of Year. + case "W": // Week of Month. + break; + + // Day + case "d": + value = +token.lexeme; + if( outOfRange( value, 1, 31 ) ) { + return false; + } + date.setDate( value ); + truncateAt.push( DAY ); + break; + + case "D": + value = +token.lexeme; + if( outOfRange( value, 1, 366 ) ) { + return false; + } + date.setMonth(0); + date.setDate( value ); + truncateAt.push( DAY ); + break; + + case "F": + // Day of Week in month. eg. 2nd Wed in July. + // Skip + break; + + case "g+": + // Modified Julian day. Need to be implemented. + throw new Error( "Not implemented" ); + + // Week day + case "e": + case "c": + case "E": + // Skip. + // value = arrayIndexOf( datetimeWeekDays, token.value ); + break; + + // Period (AM or PM) + case "a": + amPm = token.value; + break; + + // Hour + case "K": // 0-11 + value = +token.lexeme + 1; + + /* falls through */ + case "h": // 1-12 + value = value || +token.lexeme; + if( outOfRange( value, 1, 12 ) ) { + return false; + } + date.setHours( value ); + truncateAt.push( HOUR ); + break; + + case "H": // 0-23 + value = +token.lexeme + 1; + + /* falls through */ + case "k": // 1-24 + hour24 = true; + value = value || +token.lexeme; + if( outOfRange( value, 1, 24 ) ) { + return false; + } + date.setHours( value ); + truncateAt.push( HOUR ); + break; + + // Minute + case "m": + value = +token.lexeme; + if( outOfRange( value, 0, 59 ) ) { + return false; + } + date.setMinutes( value ); + truncateAt.push( MINUTE ); + break; + + // Second + case "s": + value = +token.lexeme; + if( outOfRange( value, 0, 59 ) ) { + return false; + } + date.setSeconds( value ); + truncateAt.push( SECOND ); + break; + + case "A": + date.setHours( 0 ); + date.setMinutes( 0 ); + date.setSeconds( 0 ); + + /* falls through */ + case "S": + value = Math.round( +token.lexeme * Math.pow( 10, 3 - length ) ); + date.setMilliseconds( value ); + truncateAt.push( MILLISECONDS ); + break; + + // Zone + // see http://www.unicode.org/reports/tr35/tr35-dates.html#Using_Time_Zone_Names ? + // Need to be implemented. + case "z": + case "Z": + case "O": + case "v": + case "V": + case "X": + case "x": + throw new Error( "Not implemented" ); + } + + return true; + }); + + if ( !valid || amPm && hour24 ) { + return null; + } + + if ( era === 0 ) { + // 1 BC = year 0 + date.setFullYear( date.getFullYear() * -1 + 1 ); + } + + if ( amPm === "pm" && date.getHours() !== 12 ) { + date.setHours( date.getHours() + 12 ); + } + + // Truncate date at the most precise unit defined. Eg. + // If value is "12/31", and pattern is "MM/dd": + // => new Date( , 12, 31, 0, 0, 0, 0 ); + truncateAt = Math.max.apply( null, truncateAt ); + date = datetimeStartOf( date, units[ truncateAt ] ); + + return date; + }; + +}()); + + + var arrayIsArray = Array.isArray || function( obj ) { + return Object.prototype.toString.call( obj ) === "[object Array]"; + }; + + + + + var alwaysArray = function( stringOrArray ) { + return arrayIsArray( stringOrArray ) ? stringOrArray : [ stringOrArray ]; + }; + + + + + var arraySome = function( array, callback ) { + var i, length; + if ( array.some ) { + return array.some( callback ); + } + for ( i = 0, length = array.length; i < length; i++ ) { + if ( callback( array[ i ], i, array ) ) { + return true; + } + } + return false; + }; + + + + + var defaultLocale; + + function getLocale( locale ) { + return locale ? new Cldr( locale ) : defaultLocale; + } + + var Globalize = {}; + + /** + * Globalize.load( json ) + * + * @json [JSON] + * + * Load resolved or unresolved cldr data. + * Somewhat equivalent to previous Globalize.addCultureInfo(...). + */ + Globalize.load = function( json ) { + Cldr.load( json ); + }; + + /** + * Globalize.loadTranslations( locale, json ) + * + * @locale [String] + * + * @json [JSON] + * + * Load translation data per locale. + */ + Globalize.loadTranslations = function( locale, json ) { + var customData = { + "globalize-translation": {} + }; + locale = new Cldr( locale ); + customData[ "globalize-translation" ][ locale.attributes.languageId ] = json; + Cldr.load( customData ); + }; + + /** + * Globalize.locale( locale ) + * + * @locale [String] + * + * Set default locale. + * Somewhat equivalent to previous culture( selector ). + */ + Globalize.locale = function( locale ) { + if ( arguments.length ) { + defaultLocale = new Cldr( locale ); + } + return defaultLocale; + }; + + /** + * Globalize.format( value, pattern, locale ) + * + * @value [Date or Number] + * + * @pattern [String or Object] see datetime/expand_pattern for more info. + * + * @locale [String] + * + * Formats a date or number according to the given pattern string and the given locale (or the default locale if not specified). + */ + Globalize.format = function( value, pattern, locale ) { + locale = getLocale( locale ); + + if ( value instanceof Date ) { + + if ( !pattern ) { + throw new Error( "Missing pattern" ); + } + pattern = datetimeExpandPattern( pattern, locale ); + + value = datetimeFormat( value, pattern, locale ); + + } else if ( typeof value === "number" ) { + // TODO value = numberFormat( value, pattern, locale ); + throw new Error( "Number Format not implemented yet" ); + } + + return value; + }; + + /** + * Globalize.parseDate( value, patterns, locale ) + * + * @value [Date] + * + * @patterns [Array] Optional. See datetime/expand_pattern for more info about each pattern. Defaults to the list of all presets defined in the locale (see datetime/all_presets for more info). + * + * @locale [String] + * + * Return a Date instance or null. + */ + Globalize.parseDate = function( value, patterns, locale ) { + var date; + locale = getLocale( locale ); + + if ( typeof value !== "string" ) { + throw new Error( "invalid value (" + value + "), string expected" ); + } + + if ( !patterns ) { + patterns = datetimeAllPresets( locale ); + } else { + patterns = alwaysArray( patterns ); + } + + arraySome( patterns, function( pattern ) { + pattern = datetimeExpandPattern( pattern, locale ); + date = datetimeParse( value, pattern, locale ); + return !!date; + }); + + return date || null; + }; + + /** + * Globalize.translate( path, locale ) + * + * @path [String or Array] + * + * @locale [String] + * + * Translate item given its path. + */ + Globalize.translate = function( path , locale ) { + locale = getLocale( locale ); + path = alwaysArray( path ); + return locale.get( [ "globalize-translation/{languageId}" ].concat( path ) ); + }; + + return Globalize; + + + +})); diff --git a/external/localization.js b/external/localization.js index 4c866f23b71..98d8f813052 100644 --- a/external/localization.js +++ b/external/localization.js @@ -462,6 +462,495 @@ Globalize.load({ } }); +Globalize.load({ + "main": { + "de": { + "identity": { + "version": { + "_cldrVersion": "24", + "_number": "$Revision: 9287 $" + }, + "generation": { + "_date": "$Date: 2013-08-28 21:32:04 -0500 (Wed, 28 Aug 2013) $" + }, + "language": "de" + }, + "dates": { + "calendars": { + "gregorian": { + "months": { + "format": { + "abbreviated": { + "1": "Jan.", + "2": "Feb.", + "3": "März", + "4": "Apr.", + "5": "Mai", + "6": "Juni", + "7": "Juli", + "8": "Aug.", + "9": "Sep.", + "10": "Okt.", + "11": "Nov.", + "12": "Dez." + }, + "narrow": { + "1": "J", + "2": "F", + "3": "M", + "4": "A", + "5": "M", + "6": "J", + "7": "J", + "8": "A", + "9": "S", + "10": "O", + "11": "N", + "12": "D" + }, + "wide": { + "1": "Januar", + "2": "Februar", + "3": "März", + "4": "April", + "5": "Mai", + "6": "Juni", + "7": "Juli", + "8": "August", + "9": "September", + "10": "Oktober", + "11": "November", + "12": "Dezember" + } + }, + "stand-alone": { + "abbreviated": { + "1": "Jan", + "2": "Feb", + "3": "Mär", + "4": "Apr", + "5": "Mai", + "6": "Jun", + "7": "Jul", + "8": "Aug", + "9": "Sep", + "10": "Okt", + "11": "Nov", + "12": "Dez" + }, + "narrow": { + "1": "J", + "2": "F", + "3": "M", + "4": "A", + "5": "M", + "6": "J", + "7": "J", + "8": "A", + "9": "S", + "10": "O", + "11": "N", + "12": "D" + }, + "wide": { + "1": "Januar", + "2": "Februar", + "3": "März", + "4": "April", + "5": "Mai", + "6": "Juni", + "7": "Juli", + "8": "August", + "9": "September", + "10": "Oktober", + "11": "November", + "12": "Dezember" + } + } + }, + "days": { + "format": { + "abbreviated": { + "sun": "So.", + "mon": "Mo.", + "tue": "Di.", + "wed": "Mi.", + "thu": "Do.", + "fri": "Fr.", + "sat": "Sa." + }, + "narrow": { + "sun": "S", + "mon": "M", + "tue": "D", + "wed": "M", + "thu": "D", + "fri": "F", + "sat": "S" + }, + "short": { + "sun": "So.", + "mon": "Mo.", + "tue": "Di.", + "wed": "Mi.", + "thu": "Do.", + "fri": "Fr.", + "sat": "Sa." + }, + "wide": { + "sun": "Sonntag", + "mon": "Montag", + "tue": "Dienstag", + "wed": "Mittwoch", + "thu": "Donnerstag", + "fri": "Freitag", + "sat": "Samstag" + } + }, + "stand-alone": { + "abbreviated": { + "sun": "So", + "mon": "Mo", + "tue": "Di", + "wed": "Mi", + "thu": "Do", + "fri": "Fr", + "sat": "Sa" + }, + "narrow": { + "sun": "S", + "mon": "M", + "tue": "D", + "wed": "M", + "thu": "D", + "fri": "F", + "sat": "S" + }, + "short": { + "sun": "So.", + "mon": "Mo.", + "tue": "Di.", + "wed": "Mi.", + "thu": "Do.", + "fri": "Fr.", + "sat": "Sa." + }, + "wide": { + "sun": "Sonntag", + "mon": "Montag", + "tue": "Dienstag", + "wed": "Mittwoch", + "thu": "Donnerstag", + "fri": "Freitag", + "sat": "Samstag" + } + } + }, + "quarters": { + "format": { + "abbreviated": { + "1": "Q1", + "2": "Q2", + "3": "Q3", + "4": "Q4" + }, + "narrow": { + "1": "1", + "2": "2", + "3": "3", + "4": "4" + }, + "wide": { + "1": "1. Quartal", + "2": "2. Quartal", + "3": "3. Quartal", + "4": "4. Quartal" + } + }, + "stand-alone": { + "abbreviated": { + "1": "Q1", + "2": "Q2", + "3": "Q3", + "4": "Q4" + }, + "narrow": { + "1": "1", + "2": "2", + "3": "3", + "4": "4" + }, + "wide": { + "1": "1. Quartal", + "2": "2. Quartal", + "3": "3. Quartal", + "4": "4. Quartal" + } + } + }, + "dayPeriods": { + "format": { + "abbreviated": { + "afternoon": "nachmittags", + "am": "vorm.", + "earlyMorning": "morgens", + "evening": "abends", + "morning": "vormittags", + "night": "nachts", + "noon": "Mittag", + "pm": "nachm." + }, + "narrow": { + "afternoon": "nachmittags", + "am": "vorm.", + "earlyMorning": "morgens", + "evening": "abends", + "morning": "vormittags", + "night": "nachts", + "noon": "Mittag", + "pm": "nachm." + }, + "wide": { + "afternoon": "nachmittags", + "am": "vorm.", + "earlyMorning": "morgens", + "evening": "abends", + "morning": "vormittags", + "night": "nachts", + "noon": "Mittag", + "pm": "nachm." + } + }, + "stand-alone": { + "abbreviated": { + "afternoon": "nachmittags", + "am": "vorm.", + "earlyMorning": "morgens", + "evening": "abends", + "morning": "vormittags", + "night": "nachts", + "noon": "Mittag", + "pm": "nachm." + }, + "narrow": { + "afternoon": "nachmittags", + "am": "vorm.", + "earlyMorning": "morgens", + "evening": "abends", + "morning": "vormittags", + "night": "nachts", + "noon": "Mittag", + "pm": "nachm." + }, + "wide": { + "afternoon": "Nachmittag", + "am": "vorm.", + "earlyMorning": "Morgen", + "evening": "Abend", + "morning": "Vormittag", + "night": "Nacht", + "noon": "Mittag", + "pm": "nachm." + } + } + }, + "eras": { + "eraNames": { + "0": "v. Chr.", + "0-alt-variant": "vor der gewöhnlichen Zeitrechnung", + "1": "n. Chr.", + "1-alt-variant": "der gewöhnlichen Zeitrechnung" + }, + "eraAbbr": { + "0": "v. Chr.", + "0-alt-variant": "v. u. Z.", + "1": "n. Chr.", + "1-alt-variant": "u. Z." + }, + "eraNarrow": { + "0": "v. Chr.", + "0-alt-variant": "vdZ", + "1": "n. Chr.", + "1-alt-variant": "dZ" + } + }, + "dateFormats": { + "full": "EEEE, d. MMMM y", + "long": "d. MMMM y", + "medium": "dd.MM.y", + "short": "dd.MM.yy" + }, + "timeFormats": { + "full": "HH:mm:ss zzzz", + "long": "HH:mm:ss z", + "medium": "HH:mm:ss", + "short": "HH:mm" + }, + "dateTimeFormats": { + "full": "{1} {0}", + "long": "{1} {0}", + "medium": "{1} {0}", + "short": "{1} {0}", + "availableFormats": { + "d": "d", + "Ed": "E, d.", + "Ehm": "E h:mm a", + "EHm": "E, HH:mm", + "Ehms": "E, h:mm:ss a", + "EHms": "E, HH:mm:ss", + "Gy": "y G", + "GyMMM": "MMM y G", + "GyMMMd": "d. MMM y G", + "GyMMMEd": "E, d. MMM y G", + "h": "h a", + "H": "HH 'Uhr'", + "hm": "h:mm a", + "Hm": "HH:mm", + "hms": "h:mm:ss a", + "Hms": "HH:mm:ss", + "M": "L", + "Md": "d.M.", + "MEd": "E, d.M.", + "MMd": "d.MM.", + "MMdd": "dd.MM.", + "MMM": "LLL", + "MMMd": "d. MMM", + "MMMEd": "E, d. MMM", + "MMMMdd": "dd. MMMM", + "MMMMEd": "E, d. MMMM", + "ms": "mm:ss", + "y": "y", + "yM": "M.y", + "yMd": "d.M.y", + "yMEd": "E, d.M.y", + "yMM": "MM.y", + "yMMdd": "dd.MM.y", + "yMMM": "MMM y", + "yMMMd": "d. MMM y", + "yMMMEd": "E, d. MMM y", + "yMMMM": "MMMM y", + "yQQQ": "QQQ y", + "yQQQQ": "QQQQ y" + }, + "appendItems": { + "Day": "{0} ({2}: {1})", + "Day-Of-Week": "{0} {1}", + "Era": "{1} {0}", + "Hour": "{0} ({2}: {1})", + "Minute": "{0} ({2}: {1})", + "Month": "{0} ({2}: {1})", + "Quarter": "{0} ({2}: {1})", + "Second": "{0} ({2}: {1})", + "Timezone": "{0} {1}", + "Week": "{0} ({2}: {1})", + "Year": "{1} {0}" + }, + "intervalFormats": { + "intervalFormatFallback": "{0} - {1}", + "d": { + "d": "d.-d." + }, + "h": { + "a": "h a - h a", + "h": "h-h a" + }, + "H": { + "H": "HH-HH 'Uhr'" + }, + "hm": { + "a": "h:mm a - h:mm a", + "h": "h:mm-h:mm a", + "m": "h:mm-h:mm a" + }, + "Hm": { + "H": "HH:mm-HH:mm", + "m": "HH:mm-HH:mm" + }, + "hmv": { + "a": "h:mm a - h:mm a v", + "h": "h:mm-h:mm a v", + "m": "h:mm-h:mm a v" + }, + "Hmv": { + "H": "HH:mm-HH:mm v", + "m": "HH:mm-HH:mm v" + }, + "hv": { + "a": "h a - h a v", + "h": "h-h a v" + }, + "Hv": { + "H": "HH-HH 'Uhr' v" + }, + "M": { + "M": "M.-M." + }, + "Md": { + "d": "dd.MM. - dd.MM.", + "M": "dd.MM. - dd.MM." + }, + "MEd": { + "d": "E, dd.MM. - E, dd.MM.", + "M": "E, dd.MM. - E, dd.MM." + }, + "MMM": { + "M": "MMM-MMM" + }, + "MMMd": { + "d": "d.-d. MMM", + "M": "d. MMM - d. MMM" + }, + "MMMEd": { + "d": "E, d. - E, d. MMM", + "M": "E, d. MMM - E, d. MMM" + }, + "MMMM": { + "M": "LLLL-LLLL" + }, + "y": { + "y": "y-y" + }, + "yM": { + "M": "MM.y - MM.y", + "y": "MM.y - MM.y" + }, + "yMd": { + "d": "dd.MM.y - dd.MM.y", + "M": "dd.MM.y - dd.MM.y", + "y": "dd.MM.y - dd.MM.y" + }, + "yMEd": { + "d": "E, dd.MM.y - E, dd.MM.y", + "M": "E, dd.MM.y - E, dd.MM.y", + "y": "E, dd.MM.y - E, dd.MM.y" + }, + "yMMM": { + "M": "MMM-MMM y", + "y": "MMM y - MMM y" + }, + "yMMMd": { + "d": "d.-d. MMM y", + "M": "d. MMM - d. MMM y", + "y": "d. MMM y - d. MMM y" + }, + "yMMMEd": { + "d": "E, d. - E, d. MMM y", + "M": "E, d. MMM - E, d. MMM y", + "y": "E, d. MMM y - E, d. MMM y" + }, + "yMMMM": { + "M": "MMMM-MMMM y", + "y": "MMMM y - MMMM y" + } + } + } + } + } + } + } + } +}); + /** * CLDR supplemental data */ diff --git a/tests/unit/date/date.html b/tests/unit/date/date.html index e3454a55b83..d759fdeaee7 100644 --- a/tests/unit/date/date.html +++ b/tests/unit/date/date.html @@ -12,9 +12,9 @@ @@ -37,4 +37,4 @@

        - \ No newline at end of file + diff --git a/tests/unit/date/date_core.js b/tests/unit/date/date_core.js index b75ef8087eb..3452580c840 100644 --- a/tests/unit/date/date_core.js +++ b/tests/unit/date/date_core.js @@ -53,29 +53,28 @@ test("Date Adjustments - Leap Year Edge Cases", 1, function(){ test("List days of Week", 2, function(){ var date = $.date(), offset0 = [ - { "fullname": "Sunday", "shortname": "Su" }, - { "fullname": "Monday", "shortname": "Mo" }, - { "fullname": "Tuesday", "shortname": "Tu" }, - { "fullname": "Wednesday", "shortname": "We" }, - { "fullname": "Thursday", "shortname": "Th" }, - { "fullname": "Friday", "shortname": "Fr" }, - { "fullname": "Saturday", "shortname": "Sa" } + { "fullname": "Sunday", "shortname": "Sun" }, + { "fullname": "Monday", "shortname": "Mon" }, + { "fullname": "Tuesday", "shortname": "Tue" }, + { "fullname": "Wednesday", "shortname": "Wed" }, + { "fullname": "Thursday", "shortname": "Thu" }, + { "fullname": "Friday", "shortname": "Fri" }, + { "fullname": "Saturday", "shortname": "Sat" } ], offset1 = [ - { "fullname": "Montag", "shortname": "Mo" }, - { "fullname": "Dienstag", "shortname": "Di" }, - { "fullname": "Mittwoch", "shortname": "Mi" }, - { "fullname": "Donnerstag", "shortname": "Do" }, - { "fullname": "Freitag", "shortname": "Fr" }, - { "fullname": "Samstag", "shortname": "Sa" }, - { "fullname": "Sonntag", "shortname": "So" } + { "fullname": "Montag", "shortname": "Mo." }, + { "fullname": "Dienstag", "shortname": "Di." }, + { "fullname": "Mittwoch", "shortname": "Mi." }, + { "fullname": "Donnerstag", "shortname": "Do." }, + { "fullname": "Freitag", "shortname": "Fr." }, + { "fullname": "Samstag", "shortname": "Sa." }, + { "fullname": "Sonntag", "shortname": "So." } ]; deepEqual(date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)"); - Globalize.culture( "de-DE" ); - date.refresh(); + Globalize.locale( "de-DE" ); deepEqual(date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)"); //Revert Globalize changes back to English - Globalize.culture("en-EN"); + Globalize.locale( "en" ); }); test("Leap Year Check", 8, function(){ @@ -101,10 +100,9 @@ test("Days in Month", 3, function(){ test("Month Name", 2, function(){ var date = $.date(); equal(date.setMonth(3).monthName(), "April", "Month name return April (English)"); - Globalize.culture( "de-DE" ); - date.refresh(); + Globalize.locale( "de-DE" ); equal(date.setMonth(2).monthName(), "März", "Month name return March (German)"); - Globalize.culture("en-EN"); + Globalize.locale( "en" ); }); @@ -154,13 +152,6 @@ test( "Months", 5, function(){ ok( firstMonth.month() === lastMonth.month() - 1 ); }); -test("iso8601Week", 2, function(){ - var date = $.date(); - //date.setFullDate(2012, 0, 8); - equal(date.iso8601Week(new Date(2012, 0, 8)), 1, "Test first week is 1"); - equal(date.iso8601Week(new Date(2012, 11, 31)), 1, "Test last week is 1 in next year"); -}); - test("Equal", 4, function(){ var date = $.date(); date.setFullDate(2012, 9, 16); @@ -178,45 +169,8 @@ test("Date", 1, function(){ test("Format", 4, function(){ var date = $.date(); date.setFullDate(2012, 9, 16); - equal(date.format(), "10/16/2012", "Checking default US format"); - equal(date.format("yyyy/MM/dd"), "2012/10/16", "Checking yyyy/MM/dd format"); - equal(date.format("yy/dd/MM"), "12/16/10", "Checking yy/dd/MM format"); - equal(date.format("MMMM dd, yyyy"), "October 16, 2012", "Checking MMMM dd, yyyy format"); -}); - -test("Calendar", 3, function(){ - var date = $.date(), - de_cal = { - calendars: { - standard: { - "/": ".", - firstDay: 1, - days: { - names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], - namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], - namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] - }, - months: { - names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], - namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] - }, - AM: null, - PM: null, - eras: [{"name":"n. Chr.","start":null,"offset":0}], - patterns: { - d: "dd.MM.yyyy", - D: "dddd, d. MMMM yyyy", - t: "HH:mm", - T: "HH:mm:ss", - f: "dddd, d. MMMM yyyy HH:mm", - F: "dddd, d. MMMM yyyy HH:mm:ss", - M: "dd MMMM", - Y: "MMMM yyyy" - } - } - } - }; - ok(date.calendar(), "Calendar type returned"); - ok(date.calendar(de_cal), "Calendar type changed"); - deepEqual(date.calendar(), de_cal, "Calendar change verified"); + equal(date.format({ date: "short" }), "10/16/12", "Checking default US format"); + equal(date.format({ pattern: "yyyy/MM/dd" }), "2012/10/16", "Checking yyyy/MM/dd format"); + equal(date.format({ pattern: "yy/dd/MM" }), "12/16/10", "Checking yy/dd/MM format"); + equal(date.format({ pattern: "MMMM dd, yyyy" }), "October 16, 2012", "Checking MMMM dd, yyyy format"); }); diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 7b4cea7d28b..940b4b42222 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -5,9 +5,9 @@ jQuery UI Datepicker Test Suite - + @@ -20,8 +20,7 @@ "ui/jquery.ui.widget.js", "ui/jquery.ui.button.js", "ui/jquery.ui.datepicker.js", - "ui/jquery.ui.position.js", - "external/globalize.culture.he.js" + "ui/jquery.ui.position.js" ] }); diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 7f77b099de6..6b4b368e0e1 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -7,7 +7,7 @@ TestHelpers.testJshint( "datepicker" ); test( "input's value determines starting date", function() { expect( 3 ); - var input = $( "#datepicker" ).val( "1/1/2014" ).datepicker(), + var input = $( "#datepicker" ).val( "1/1/14" ).datepicker(), picker = input.datepicker( "widget" ); input.datepicker( "open" ); @@ -331,19 +331,19 @@ test( "Keyboard handling", function() { TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke enter" ); // Enter = Select today's date by default - input.val( "1/1/2014" ).datepicker( "open" ) + input.val( "1/1/14" ).datepicker( "open" ) .simulate("keydown", { keyCode: $.ui.keyCode.ENTER }); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke enter - preset" ); // Control + Home = Change the calendar to the current month - input.val( "1/1/2014" ).datepicker( "open" ) + input.val( "1/1/14" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+home" ); // Control + End = Close the calendar and clear the input - input.val( "1/1/2014" ).datepicker( "open" ) + input.val( "1/1/14" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END }); equal( input.val(), "", "Keystroke ctrl+end" ); @@ -352,12 +352,12 @@ test( "Keyboard handling", function() { input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); ok( !instance.isOpen, "escape closes the datepicker" ); - input.val( "1/1/2014" ).datepicker( "open" ) + input.val( "1/1/14" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke esc - preset" ); - input.val( "1/1/2014" ).datepicker( "open" ) + input.val( "1/1/14" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index dcd6dc2c7aa..81d1b096ba8 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -69,16 +69,16 @@ test( "value", function() { picker = input.datepicker( "widget" ), inline = $( "#inline" ).datepicker(); - input.datepicker( "value", "1/1/2014" ); - equal( input.val(), "1/1/2014", "input's value set" ); + input.datepicker( "value", "1/1/14" ); + equal( input.val(), "1/1/14", "input's value set" ); ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), "first day marked as selected" ); - equal( input.datepicker( "value" ), "1/1/2014", "getter" ); + equal( input.datepicker( "value" ), "1/1/14", "getter" ); - inline.datepicker( "value", "1/1/2014" ); + inline.datepicker( "value", "1/1/14" ); ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), "first day marked as selected" ); - equal( inline.datepicker( "value" ), "1/1/2014", "getter" ); + equal( inline.datepicker( "value" ), "1/1/14", "getter" ); // TODO: Handle for invalid values. @@ -93,7 +93,7 @@ test( "valueAsDate", function() { inline = $( "#inline" ).datepicker(); input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); - equal( input.val(), "1/1/2014", "input's value set" ); + equal( input.val(), "1/1/14", "input's value set" ); ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), "first day marked as selected" ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index f712a543486..84bfa3bb01b 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -42,16 +42,16 @@ test( "appendTo", function() { test( "dateFormat", function() { expect( 2 ); - var input = $( "#datepicker" ).val( "1/1/2014" ).datepicker(), + var input = $( "#datepicker" ).val( "1/1/14" ).datepicker(), picker = input.datepicker( "widget" ), firstDayLink = picker.find( "td[id]:first a" ); input.datepicker( "open" ); firstDayLink.trigger( "mousedown" ); - equal( input.val(), "1/1/2014", "default formatting" ); + equal( input.val(), "1/1/14", "default formatting" ); - input.datepicker( "option", "dateFormat", "D" ); - equal( input.val(), "Wednesday, January 01, 2014", "updated formatting" ); + input.datepicker( "option", "dateFormat", { date: "full" } ); + equal( input.val(), "Wednesday, January 1, 2014", "updated formatting" ); input.datepicker( "destroy" ); }); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index f517bb884ad..ed8c378a85f 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -294,8 +294,6 @@ $.widget( "ui.datepicker", { return element; }, _createTmpl: function() { - this.date.refresh(); - this._createDatepicker(); this.picker.find( "button" ).button(); @@ -532,8 +530,6 @@ $.widget( "ui.datepicker", { refresh: function() { //determine which day gridcell to focus after refresh //TODO: Prevent disabled cells from being focused - this.date.refresh(); - if ( this.options.numberOfMonths === 1 ) { this.grid = $( this._buildGrid() ); $( ".ui-datepicker-title", this.picker ).html( this._buildTitle() ); From e4a3e82a1790d55e01b8ab4b9ab0da2b916d07b9 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 27 Dec 2013 08:28:00 -0500 Subject: [PATCH 048/172] Datepicker: Test for up and down arrow keys --- tests/unit/datepicker/datepicker_core.js | 72 +++++++++++++----------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 6b4b368e0e1..1de1c48f86f 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -367,7 +367,7 @@ test( "Keyboard handling", function() { }); asyncTest( "keyboard handling - arrow keys", function() { - expect( 6 ); + expect( 8 ); var picker, input = $( "#datepicker" ), date = new Date(); @@ -415,7 +415,7 @@ asyncTest( "keyboard handling - arrow keys", function() { input.datepicker( "destroy" ); step4(); - }, 100); + }, 100 ); }; function step4() { @@ -431,45 +431,51 @@ asyncTest( "keyboard handling - arrow keys", function() { TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke right to switch to next day" ); + input.datepicker( "destroy" ); + step5(); + }, 100 ); + }; + + function step5() { + input.datepicker() + .val( "" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.UP }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date.setDate( new Date().getDate() - 7 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke up to move to the previous week" ); + + input.datepicker( "destroy" ); + step6(); + }, 100 ); + }; + + function step6() { + input.datepicker() + .val( "" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date.setDate( new Date().getDate() + 7 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke down to move to the next week" ); + input.datepicker( "destroy" ); start(); - }, 100); + }, 100 ); }; step1(); }); /* - input.val( "" ).datepicker( "open" ) - .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT }) - .simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 1); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+right" ); - - input.val( "" ).datepicker( "open" ) - .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.UP}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 7); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+up" ); - - input.val( "" ).datepicker( "open" ) - .simulate( "keydown", {keyCode: $.ui.keyCode.UP}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 7); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke up" ); - - input.val( "" ).datepicker( "open" ) - .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 7); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+down" ); - - input.val( "" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - date.setDate( date.getDate() - 7 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke down" ); - // Moving by month or year input.val( "02/04/2008" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) From 677601ce0d38ae02a227b77dff9f44a6d90cec8a Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 27 Dec 2013 08:49:59 -0500 Subject: [PATCH 049/172] Datepicker: Tests for Page Up and Page Down keys --- tests/unit/datepicker/datepicker_core.js | 40 ++++++++++++++++++++++-- ui/jquery.ui.datepicker.js | 4 +-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 1de1c48f86f..e6a4e89c3f1 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -366,8 +366,8 @@ test( "Keyboard handling", function() { input.datepicker( "destroy" ); }); -asyncTest( "keyboard handling - arrow keys", function() { - expect( 8 ); +asyncTest( "keyboard handling", function() { + expect( 10 ); var picker, input = $( "#datepicker" ), date = new Date(); @@ -467,6 +467,42 @@ asyncTest( "keyboard handling - arrow keys", function() { TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke down to move to the next week" ); + input.datepicker( "destroy" ); + step7(); + }, 100 ); + }; + + function step7() { + input.datepicker() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date = new Date( 2013, 12 - 1, 1 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke Page Up moves date to next month" ); + + input.datepicker( "destroy" ); + step8(); + }, 100 ); + }; + + function step8() { + input.datepicker() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date = new Date( 2014, 2 - 1, 1 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke Page Down moves date to previous month" ); + input.datepicker( "destroy" ); start(); }, 100 ); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index ed8c378a85f..84b2c9670e5 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -111,10 +111,10 @@ $.widget( "ui.datepicker", { activeCell.children( "a:first" ).mousedown(); return; case $.ui.keyCode.PAGE_UP: - this.date.adjust( event.altKey ? "Y" : "M", 1 ); + this.date.adjust( event.altKey ? "Y" : "M", -1 ); break; case $.ui.keyCode.PAGE_DOWN: - this.date.adjust( event.altKey ? "Y" : "M", -1 ); + this.date.adjust( event.altKey ? "Y" : "M", 1 ); break; case $.ui.keyCode.END: this.date.setDay( this.date.daysInMonth() ); From 7e79a71314aad01b175a27ae503c37bc779d7ade Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 27 Dec 2013 08:59:51 -0500 Subject: [PATCH 050/172] Datepicker: Tests for moving years with Page Up and Page Down --- tests/unit/datepicker/datepicker_core.js | 67 ++++++++++++++---------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index e6a4e89c3f1..e0472715745 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -367,7 +367,7 @@ test( "Keyboard handling", function() { }); asyncTest( "keyboard handling", function() { - expect( 10 ); + expect( 12 ); var picker, input = $( "#datepicker" ), date = new Date(); @@ -483,7 +483,7 @@ asyncTest( "keyboard handling", function() { .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); date = new Date( 2013, 12 - 1, 1 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Up moves date to next month" ); + "Keystroke Page Up moves date to previous month" ); input.datepicker( "destroy" ); step8(); @@ -495,13 +495,49 @@ asyncTest( "keyboard handling", function() { .val( "1/1/14" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date = new Date( 2013, 1 - 1, 1 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke Page Up + Ctrl moves date to previous year" ); + + input.datepicker( "destroy" ); + step9(); + }, 100 ); + }; + + function step9() { + input.datepicker() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + setTimeout(function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); date = new Date( 2014, 2 - 1, 1 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Down moves date to previous month" ); + "Keystroke Page Down moves date to next month" ); + + input.datepicker( "destroy" ); + step10(); + }, 100 ); + }; + + function step10() { + input.datepicker() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date = new Date( 2015, 1 - 1, 1 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke Page Down + Ctrl moves date to next year" ); input.datepicker( "destroy" ); start(); @@ -512,31 +548,6 @@ asyncTest( "keyboard handling", function() { }); /* - // Moving by month or year - input.val( "02/04/2008" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 4 ), - "Keystroke pgup" ); - - input.val( "02/04/2008" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 3 - 1, 4 ), - "Keystroke pgdn" ); - - input.val( "02/04/2008" ).datepicker( "open" ) - .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2007, 2 - 1, 4 ), - "Keystroke ctrl+pgup" ); - - input.val( "02/04/2008" ).datepicker( "open" ) - .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2009, 2 - 1, 4 ), - "Keystroke ctrl+pgdn" ); - // Check for moving to short months input.val( "03/31/2008" ).datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) From 6c2a80697e69d51ef893d0eebcca5ed8a2dd6eed Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 2 Jan 2014 15:45:02 -0500 Subject: [PATCH 051/172] Datepicker: Use explicit dates in tests. This prevents tests from running differently dependent on the current date. Some of these tests when the clocked moved forward to 2014. --- tests/unit/datepicker/datepicker_core.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index e0472715745..d2dab294abf 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -402,14 +402,14 @@ asyncTest( "keyboard handling", function() { function step3() { input.datepicker() - .val( "" ) + .val( "1/1/14" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); setTimeout(function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - date.setDate( date.getDate() - 1 ); + date = new Date( 2013, 12 - 1, 31 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke left to switch to previous day" ); @@ -420,14 +420,14 @@ asyncTest( "keyboard handling", function() { function step4() { input.datepicker() - .val( "" ) + .val( "1/1/14" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); setTimeout(function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - date.setDate( new Date().getDate() + 1 ); + date = new Date( 2014, 1 - 1, 2 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke right to switch to next day" ); @@ -438,14 +438,14 @@ asyncTest( "keyboard handling", function() { function step5() { input.datepicker() - .val( "" ) + .val( "1/1/14" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); setTimeout(function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.UP }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - date.setDate( new Date().getDate() - 7 ); + date = new Date( 2013, 12 - 1, 25 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke up to move to the previous week" ); @@ -456,14 +456,14 @@ asyncTest( "keyboard handling", function() { function step6() { input.datepicker() - .val( "" ) + .val( "1/1/14" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); setTimeout(function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - date.setDate( new Date().getDate() + 7 ); + date = new Date( 2014, 1 - 1, 8 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke down to move to the next week" ); From 0c40d2a93ccf83105aa8e6bcdf9566888a41b5d7 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 2 Jan 2014 15:57:24 -0500 Subject: [PATCH 052/172] Datepicker: Port tests for keyboard handling with short months & leap years. --- tests/unit/datepicker/datepicker_core.js | 73 ++++++++++++------------ 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index d2dab294abf..30794af2935 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -367,7 +367,7 @@ test( "Keyboard handling", function() { }); asyncTest( "keyboard handling", function() { - expect( 12 ); + expect( 14 ); var picker, input = $( "#datepicker" ), date = new Date(); @@ -540,49 +540,52 @@ asyncTest( "keyboard handling", function() { "Keystroke Page Down + Ctrl moves date to next year" ); input.datepicker( "destroy" ); - start(); + step11(); }, 100 ); }; - step1(); -}); - -/* // Check for moving to short months - input.val( "03/31/2008" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 29 ), - "Keystroke pgup - Feb" ); + function step11() { + input.datepicker() + .val( "3/31/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); - input.val( "01/30/2008" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 29 ), - "Keystroke pgdn - Feb" ); + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date = new Date( 2014, 2 - 1, 28 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke Page Up and short months" ); - input.val( "02/29/2008" ).datepicker( "open" ) - .simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2007, 2 - 1, 28 ), - "Keystroke ctrl+pgup - Feb" ); + input.datepicker( "destroy" ); + step12(); + }, 100 ); + }; - input.val( "02/29/2008" ).datepicker( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2009, 2 - 1, 28 ), - "Keystroke ctrl+pgdn - Feb" ); + function step12() { + input.datepicker() + .val( "1/30/16" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); - // Goto current - input.datepicker( "option", { gotoCurrent: true }) - .datepicker( "close" ).val( "02/04/2008" ).datepicker( "open" ) - .late( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), - "Keystroke ctrl+home" ); + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + date = new Date( 2016, 2 - 1, 29 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, + "Keystroke Page Down and leap years" ); - // Change steps + input.datepicker( "destroy" ); + start(); + }, 100 ); + }; + + step1(); +}); + +/* + // TODO: Re-add tests if we implement a stepMonths option input.datepicker( "option", { stepMonths: 2, gotoCurrent: false }) .datepicker( "close" ).val( "02/04/2008" ).datepicker( "open" ) .late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) From 010a13134c41182b5678862da0c75ecaf9d48c7c Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 2 Jan 2014 16:25:38 -0500 Subject: [PATCH 053/172] Datepicker: Re-adding mouse tests. --- tests/unit/datepicker/datepicker_core.js | 140 +++++++++++------------ 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 30794af2935..73bcd185367 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -601,109 +601,109 @@ asyncTest( "keyboard handling", function() { */ test( "mouse", function() { - // TODO: These tests use the old getDate() and setDate() methods. Re-activate these - // tests when those methods are available. - expect( 0 ); - return; - - expect( 15 ); - var inl, - inp = TestHelpers.datepicker.init( "#datepicker" ), - dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ), + expect( 13 ); + var input = $( "#datepicker" ).datepicker(), + picker = input.datepicker( "widget" ), + inline = $( "#inline" ).datepicker, date = new Date(); - inp.val( "" ).datepicker( "open" ); - $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} ); + input.val( "" ).datepicker( "open" ); + $( ".ui-datepicker-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} ); date.setDate( 10 ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Mouse click" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Mouse click" ); - inp.val( "02/04/2008" ).datepicker( "open" ); - $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} ); - TestHelpers.datepicker.equalsDate( inp.datepicker("getDate"), new Date( 2008, 2 - 1, 12 ), + input.val( "2/4/08" ).datepicker( "open" ); + $( ".ui-datepicker-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); + TestHelpers.datepicker.equalsDate( input.datepicker("valueAsDate"), new Date( 2008, 2 - 1, 12 ), "Mouse click - preset") ; - inp.val( "02/04/2008" ).datepicker( "open" ); - inp.val( "").datepicker( "open" ); - $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); - ok( inp.datepicker( "getDate" ) == null, "Mouse click - close" ); - inp.val( "02/04/2008" ).datepicker( "open" ); - $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + input.val( "" ).datepicker( "open" ); + $( "button.ui-datepicker-close", picker ).simulate( "click", {} ); + ok( input.datepicker( "valueAsDate" ) == null, "Mouse click - close" ); + + input.val( "2/4/08" ).datepicker( "open" ); + $( "button.ui-datepicker-close", picker ).simulate( "click", {} ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), "Mouse click - close + preset" ); - inp.val( "02/04/2008" ).datepicker( "open" ); - $( "a.ui-datepicker-prev", dp ).simulate( "click", {} ); - $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), + input.val( "2/4/08" ).datepicker( "open" ); + $( "a.ui-datepicker-prev", picker ).simulate( "click", {} ); + $( "button.ui-datepicker-close", picker ).simulate( "click", {} ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), "Mouse click - abandoned" ); // Current/previous/next - inp.val( "02/04/2008" ).datepicker( "option", { showButtonPanel: true }).datepicker( "open" ); - $( ".ui-datepicker-current", dp ).simulate( "click", {} ); - $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} ); - date.setDate( 14 ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), date, "Mouse click - current" ); - - inp.val( "02/04/2008" ).datepicker( "open" ); - $( ".ui-datepicker-prev", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ), + input.val( "" ).datepicker( "open" ); + $( ".ui-datepicker-current", picker ).simulate( "click", {} ); + date.setDate( new Date().getDate() ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Mouse click - current" ); + + input.val( "2/4/08" ).datepicker( "open" ); + $( ".ui-datepicker-prev", picker ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), "Mouse click - previous" ); - inp.val( "02/04/2008" ).datepicker( "open" ); - $(".ui-datepicker-next", dp ).simulate( "click" ); - $(".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); - TestHelpers.datepicker.equalsDate( inp.datepicker("getDate"), new Date( 2008, 3 - 1, 18 ), + input.val( "2/4/08" ).datepicker( "open" ); + $(".ui-datepicker-next", picker ).simulate( "click" ); + $(".ui-datepicker-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( input.datepicker("valueAsDate"), new Date( 2008, 3 - 1, 18 ), "Mouse click - next" ); + /* + // TODO: Re-add when min and max options are introduced. // Previous/next with minimum/maximum - inp.datepicker("option", { + input.datepicker("option", { minDate: new Date( 2008, 2 - 1, 2 ), maxDate: new Date( 2008, 2 - 1, 26 ) - }).val( "02/04/2008" ).datepicker( "open" ); - $( ".ui-datepicker-prev", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 16 ), + }).val( "2/4/08" ).datepicker( "open" ); + $( ".ui-datepicker-prev", picker ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 16 ), "Mouse click - previous + min/max" ); - inp.val( "02/04/2008" ).datepicker( "open" ); - $( ".ui-datepicker-next", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 18 ), + input.val( "2/4/08" ).datepicker( "open" ); + $( ".ui-datepicker-next", picker ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate(input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 18 ), "Mouse click - next + min/max" ); + */ // Inline - inl = TestHelpers.datepicker.init( "#inline" ); - dp = $( ".ui-datepicker-inline", inl ); + inline = TestHelpers.datepicker.init( "#inline" ); + picker = $( ".ui-datepicker-inline", inline ); date = new Date(); - inl.datepicker( "setDate", date ); - $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} ); + inline.datepicker( "valueAsDate", date ); + $( ".ui-datepicker-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} ); date.setDate( 10 ); - TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), date, "Mouse click inline" ); + TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), date, "Mouse click inline" ); - inl.datepicker( "option", { showButtonPanel: true }) - .datepicker( "setDate", new Date( 2008, 2 - 1, 4 )); - $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} ); - TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), new Date( 2008, 2 - 1, 12 ), + inline.datepicker( "option", { showButtonPanel: true }) + .datepicker( "valueAsDate", new Date( 2008, 2 - 1, 4 )); + $( ".ui-datepicker-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); + TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), "Mouse click inline - preset" ); - inl.datepicker("option", { showButtonPanel: true }); - $( ".ui-datepicker-current", dp ).simulate( "click", {} ); - $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} ); + inline.datepicker("option", { showButtonPanel: true }); + $( ".ui-datepicker-current", picker ).simulate( "click", {} ); + $( ".ui-datepicker-calendar tbody a:contains(14)", picker ).simulate( "mousedown", {} ); date.setDate( 14 ); - TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), date, "Mouse click inline - current" ); + TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), date, "Mouse click inline - current" ); - inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4) ); - $( ".ui-datepicker-prev", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); - TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ), + inline.datepicker( "valueAsDate", new Date( 2008, 2 - 1, 4) ); + $( ".ui-datepicker-prev", picker ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), "Mouse click inline - previous" ); - inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4) ); - $( ".ui-datepicker-next", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); - TestHelpers.datepicker.equalsDate( inl.datepicker( "getDate" ), new Date( 2008, 3 - 1, 18 ), + inline.datepicker( "valueAsDate", new Date( 2008, 2 - 1, 4) ); + $( ".ui-datepicker-next", picker ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), "Mouse click inline - next" ); + + input.datepicker( "destroy" ); + inline.datepicker( "destroy" ); }); })( jQuery ); From 5da48808e09bfc7341346f7aa587c3574c0d3cc0 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 3 Jan 2014 09:07:38 -0500 Subject: [PATCH 054/172] Datepicker: Adding an isValid() method. --- tests/unit/datepicker/datepicker_methods.js | 13 +++++++++++++ ui/jquery.ui.datepicker.js | 3 +++ 2 files changed, 16 insertions(+) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 81d1b096ba8..98034dacdf1 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -111,4 +111,17 @@ test( "valueAsDate", function() { inline.datepicker( "destroy" ); }); +test( "isValid", function() { + expect( 2 ); + var input = $( "#datepicker" ).datepicker(); + + input.val( "1/1/14" ); + ok( input.datepicker( "isValid" ) ); + + input.val( "1/1/abc" ); + ok( !input.datepicker( "isValid" ) ); + + input.datepicker( "destroy" ); +}); + })( jQuery ); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 84b2c9670e5..311d8a8a4f9 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -639,6 +639,9 @@ $.widget( "ui.datepicker", { return this.date.date(); } }, + isValid: function() { + return Globalize.parseDate( this.element.val(), this.options.dateFormat ) !== null; + }, _destroy: function() { if ( this.inline ) { this.picker.empty(); From b2018c47f46716cad415a3a138187f95559e9ac9 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 3 Jan 2014 09:16:03 -0500 Subject: [PATCH 055/172] Datepicker: Handle for invalid values in value() and valueAsDate() --- tests/unit/datepicker/datepicker_methods.js | 15 +++++++++------ ui/jquery.ui.datepicker.js | 7 +++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 98034dacdf1..281a81c8d9b 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -64,7 +64,7 @@ test( "open", function() { }); test( "value", function() { - expect( 5 ); + expect( 6 ); var input = $( "#datepicker" ).datepicker(), picker = input.datepicker( "widget" ), inline = $( "#inline" ).datepicker(); @@ -75,19 +75,21 @@ test( "value", function() { "first day marked as selected" ); equal( input.datepicker( "value" ), "1/1/14", "getter" ); + input.val( "abc" ); + equal( input.datepicker( "value" ), "abc", + "Invalid values should be returned without formatting." ); + inline.datepicker( "value", "1/1/14" ); ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), "first day marked as selected" ); equal( inline.datepicker( "value" ), "1/1/14", "getter" ); - // TODO: Handle for invalid values. - input.datepicker( "destroy" ); inline.datepicker( "destroy" ); }); test( "valueAsDate", function() { - expect( 5 ); + expect( 6 ); var input = $( "#datepicker" ).datepicker(), picker = input.datepicker( "widget" ), inline = $( "#inline" ).datepicker(); @@ -99,14 +101,15 @@ test( "valueAsDate", function() { TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "getter" ); + input.val( "a/b/c" ); + equal( input.datepicker( "valueAsDate" ), null, "Invalid dates return null" ); + inline.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), "first day marked as selected" ); TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "getter" ); - // TODO: Handle for invalid values. - input.datepicker( "destroy" ); inline.datepicker( "destroy" ); }); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 311d8a8a4f9..c79a1fa64c4 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -629,17 +629,20 @@ $.widget( "ui.datepicker", { if ( arguments.length ) { this._value( value ); } else { - return this.date.format(); + return this.isValid() ? this.date.format() : this.element.val(); } }, valueAsDate: function( value ) { if ( arguments.length ) { this._value( value ); } else { - return this.date.date(); + return this.isValid() ? this.date.date() : null; } }, isValid: function() { + if ( this.inline ) { + return true; + } return Globalize.parseDate( this.element.val(), this.options.dateFormat ) !== null; }, _destroy: function() { From 98c855603ab2c81882677161c44a2cc20da1a641 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 3 Jan 2014 09:55:06 -0500 Subject: [PATCH 056/172] Datepicker: Update the picker as the user types valid dates --- tests/unit/datepicker/datepicker_core.js | 7 ++++++- ui/jquery.ui.datepicker.js | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 73bcd185367..1f7333675ca 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -321,7 +321,7 @@ asyncTest( "customStructure", function() { }); test( "Keyboard handling", function() { - expect( 8 ); + expect( 9 ); var input = $( "#datepicker" ).datepicker(), instance = input.datepicker( "instance" ), date = new Date(); @@ -363,6 +363,11 @@ test( "Keyboard handling", function() { TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke esc - abandoned" ); + input.val( "1/2/14" ) + .simulate( "keyup" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ), + "Picker updated as user types into input" ); + input.datepicker( "destroy" ); }); diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index c79a1fa64c4..fc32fccf948 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -216,6 +216,12 @@ $.widget( "ui.datepicker", { break; } }, + keyup: function() { + if ( this.isValid() && !this.inline ) { + this.date.setTime( this.element.val() ).select(); + this.refresh(); + } + }, mousedown: function( event ) { if (this.isOpen) { suppressExpandOnFocus = true; From 0cd4989d0b0e190086219dd022e574edf3469c3e Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 9 Jan 2014 09:15:42 -0500 Subject: [PATCH 057/172] Date: Updating test suite to coding standards. --- tests/unit/date/date_core.js | 169 +++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 78 deletions(-) diff --git a/tests/unit/date/date_core.js b/tests/unit/date/date_core.js index 3452580c840..09ffd206abe 100644 --- a/tests/unit/date/date_core.js +++ b/tests/unit/date/date_core.js @@ -1,56 +1,67 @@ -module("date: core"); +module( "date: core" ); -test("Check Date Setup", 2, function(){ - ok(true,"First Test Always Passes"); - ok($.date(), "Load JQuery Date"); +test( "Check Date Setup", 2, function() { + ok( true, "First Test Always Passes" ); + ok( $.date(), "Load JQuery Date" ); }); -test("Check Sets and Gets", 6, function(){ + +test( "Check Sets and Gets", 6, function() { var date = $.date(); - equal(date.setYear(2012).year(), 2012, "Set year and retrieve"); - equal(date.setMonth(9).month(), 9, "Set month and retrieve"); - equal(date.setDay(15).day(), 15, "Set day and retrieve"); - equal(date.setFullDate(2012,9,15).year(), 2012, "Set full date and retrieve year"); - equal(date.month(), 9, "Set full date and retrieve month"); - equal(date.day(), 15, "Set full date and retrieve day"); + equal( date.setYear( 2012 ).year(), 2012, "Set year and retrieve" ); + equal( date.setMonth( 9 ).month(), 9, "Set month and retrieve" ); + equal( date.setDay( 15 ).day(), 15, "Set day and retrieve" ); + equal( date.setFullDate( 2012, 9, 15 ).year(), 2012, "Set full date and retrieve year" ); + equal( date.month(), 9, "Set full date and retrieve month" ); + equal( date.day(), 15, "Set full date and retrieve day" ); }); -test("Date Adjustments - Normal Use Cases", 10, function(){ + +test( "Date Adjustments - Normal Use Cases", 10, function() { var date = $.date(); - //Use October 15, 2012 - date.setFullDate(2012,9,15); - equal(date.adjust("D",1).day(),16,"Add 1 day"); - equal(date.adjust("D",-1).day(),15,"Subtract 1 day"); - equal(date.adjust("M",1).month(),10,"Add 1 month"); - equal(date.adjust("M",-1).month(),9,"Subtract 1 month"); - equal(date.adjust("Y",1).year(),2013,"Add 1 year"); - equal(date.adjust("Y",-1).year(),2012,"Subtract 1 year"); - //Check changing one value impact another. Ex: Day impacts month - //Use April 30th 2012 - date.setFullDate(2012,3,30); - equal(date.adjust("D",1).month(),4,"Add 1 day to change month from April to May"); - equal(date.adjust("D",-1).month(),3,"Subtract 1 day to change month from May to April"); - //Use December 31st 2012 - date.setFullDate(2012,11,31); - equal(date.adjust("D",1).year(),2013,"Add 1 day to change year from 2012 to 2013"); - equal(date.adjust("D",-1).year(),2012,"Subtract 1 day to change month from 2013 to 2012"); + + // Use October 15, 2012 + date.setFullDate( 2012, 9, 15 ); + equal( date.adjust( "D", 1 ).day(), 16, "Add 1 day" ); + equal( date.adjust( "D", -1 ).day(), 15, "Subtract 1 day" ); + equal( date.adjust( "M", 1 ).month(), 10, "Add 1 month" ); + equal( date.adjust( "M", -1 ).month(), 9, "Subtract 1 month" ); + equal( date.adjust( "Y", 1 ).year(), 2013, "Add 1 year" ); + equal( date.adjust( "Y", -1 ).year(), 2012, "Subtract 1 year" ); + + // Check changing one value impact another. Ex: Day impacts month + // Use April 30th 2012 + date.setFullDate( 2012, 3, 30 ); + equal( date.adjust( "D", 1 ).month(), 4, "Add 1 day to change month from April to May" ); + equal( date.adjust( "D", -1 ).month(), 3, "Subtract 1 day to change month from May to April" ); + + // Use December 31st 2012 + date.setFullDate( 2012, 11, 31 ); + equal( date.adjust( "D", 1 ).year(), 2013, "Add 1 day to change year from 2012 to 2013" ); + equal( date.adjust( "D", -1 ).year(), 2012, + "Subtract 1 day to change month from 2013 to 2012" ); }); -test("Date Adjustments - Month Overflow Edge Cases", 2, function(){ +test( "Date Adjustments - Month Overflow Edge Cases", 2, function() { var date = $.date(); - //Use May 31 2012 - date.setFullDate(2012,4,31); - equal(date.adjust("M",1).day(),30,"Add 1 month from May to June sets days to 30, last day in June (prevent Overflow)"); - equal(date.adjust("M",-1).day(),30,"Subtract 1 month from June to May sets days to 30 in May"); + + // Use May 31 2012 + date.setFullDate( 2012, 4, 31 ); + equal( date.adjust( "M", 1 ).day(), 30, + "Add 1 month from May to June sets days to 30, last day in June (prevent Overflow)" ); + equal( date.adjust( "M", -1 ).day(), 30, + "Subtract 1 month from June to May sets days to 30 in May" ); }); -test("Date Adjustments - Leap Year Edge Cases", 1, function(){ +test( "Date Adjustments - Leap Year Edge Cases", 1, function() { var date = $.date(); - //Use February 29 2012 a Leap year - date.setFullDate(2012,1,29); - equal(date.adjust("Y",1).day(),28,"Feb 29 2012, add a year to convert to Feb 28, 2013"); + + // Use February 29 2012 a Leap year + date.setFullDate( 2012, 1, 29 ); + equal( date.adjust( "Y", 1 ).day(), 28, + "Feb 29 2012, add a year to convert to Feb 28, 2013" ); }); -test("List days of Week", 2, function(){ +test( "List days of Week", 2, function() { var date = $.date(), offset0 = [ { "fullname": "Sunday", "shortname": "Sun" }, @@ -70,50 +81,51 @@ test("List days of Week", 2, function(){ { "fullname": "Samstag", "shortname": "Sa." }, { "fullname": "Sonntag", "shortname": "So." } ]; - deepEqual(date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)"); + + deepEqual( date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)" ); Globalize.locale( "de-DE" ); - deepEqual(date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)"); - //Revert Globalize changes back to English + deepEqual( date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)" ); + + // Revert Globalize changes back to English Globalize.locale( "en" ); }); -test("Leap Year Check", 8, function(){ +test( "Leap Year Check", 8, function() { var date = $.date(); - ok(date.setYear( 2008 ).isLeapYear(), "2008 is a Leap Year"); - ok(!date.setYear( 2009 ).isLeapYear(), "2009 is not a Leap Year"); - ok(!date.setYear( 2010 ).isLeapYear(), "2010 is not a Leap Year"); - ok(!date.setYear( 2011 ).isLeapYear(), "2011 is not a Leap Year"); - ok(date.isLeapYear( 2012 ), "2012 is a Leap Year"); - ok(!date.isLeapYear( 2013 ), "2013 is not a Leap Year"); - ok(!date.isLeapYear( 2014 ), "2014 is not a Leap year"); - ok(!date.isLeapYear( 2015 ), "2015 is not a Leap year"); + ok( date.setYear( 2008 ).isLeapYear(), "2008 is a Leap Year" ); + ok( !date.setYear( 2009 ).isLeapYear(), "2009 is not a Leap Year" ); + ok( !date.setYear( 2010 ).isLeapYear(), "2010 is not a Leap Year" ); + ok( !date.setYear( 2011 ).isLeapYear(), "2011 is not a Leap Year" ); + ok( date.isLeapYear( 2012 ), "2012 is a Leap Year" ); + ok( !date.isLeapYear( 2013 ), "2013 is not a Leap Year" ); + ok( !date.isLeapYear( 2014 ), "2014 is not a Leap year" ); + ok( !date.isLeapYear( 2015 ), "2015 is not a Leap year" ); }); -test("Days in Month", 3, function(){ +test( "Days in Month", 3, function() { var date = $.date(); date.setFullDate( 2012, 1, 1 ); - equal(date.daysInMonth(), 29, "Leap Year implicit check for 29 days"); - equal(date.daysInMonth( 2012, 1 ), 29, "Leap Year explicit check for 29 days"); - equal(date.daysInMonth( 2011, 3 ), 30, "April has 30 days"); + equal( date.daysInMonth(), 29, "Leap Year implicit check for 29 days" ); + equal( date.daysInMonth( 2012, 1 ), 29, "Leap Year explicit check for 29 days" ); + equal( date.daysInMonth( 2011, 3 ), 30, "April has 30 days" ); }); -test("Month Name", 2, function(){ +test( "Month Name", 2, function() { var date = $.date(); - equal(date.setMonth(3).monthName(), "April", "Month name return April (English)"); + equal( date.setMonth( 3 ).monthName(), "April", "Month name return April (English)" ); Globalize.locale( "de-DE" ); - equal(date.setMonth(2).monthName(), "März", "Month name return March (German)"); + equal( date.setMonth( 2 ).monthName(), "März", "Month name return March (German)" ); Globalize.locale( "en" ); - }); -test("Clone", 2, function(){ +test( "Clone", 2, function() { var date = $.date(), date2 = date.clone(); - ok(date2, "Created cloned object"); - notEqual(date.adjust("Y",1).year(), date2.year(), "Object manipulated independently"); + ok( date2, "Created cloned object" ); + notEqual( date.adjust( "Y", 1 ).year(), date2.year(), "Object manipulated independently" ); }); -test("Days", 1, function(){ +test( "Days", 1, function() { //TODO needs work var date = $.date(); date.eachDay = function( day ) { @@ -136,7 +148,7 @@ test("Days", 1, function(){ day.title = "A good day!"; } }; - ok(date.days(), "Date days() returns"); + ok( date.days(), "Date days() returns"); }); test( "Months", 5, function(){ @@ -152,25 +164,26 @@ test( "Months", 5, function(){ ok( firstMonth.month() === lastMonth.month() - 1 ); }); -test("Equal", 4, function(){ +test( "Equal", 4, function() { var date = $.date(); - date.setFullDate(2012, 9, 16); - ok(date.equal(new Date(2012, 9, 16)), "Does date equal provide date"); - ok(!date.equal(new Date(2011, 9, 16)), "Does date year not equal provide date"); - ok(!date.equal(new Date(2012, 8, 16)), "Does date month not equal provide date"); - ok(!date.equal(new Date(2012, 9, 15)), "Does date day not equal provide date"); + date.setFullDate( 2012, 9, 16 ); + ok( date.equal( new Date( 2012, 9, 16 ) ), "Does date equal provide date" ); + ok( !date.equal( new Date( 2011, 9, 16 ) ), "Does date year not equal provide date" ); + ok( !date.equal( new Date( 2012, 8, 16 ) ), "Does date month not equal provide date" ); + ok( !date.equal( new Date( 2012, 9, 15 ) ), "Does date day not equal provide date" ); }); -test("Date", 1, function(){ +test( "Date", 1, function() { var date = $.date(); - ok(date.date() instanceof Date, "Date returned"); + ok( date.date() instanceof Date, "Date returned" ); }); -test("Format", 4, function(){ +test( "Format", 4, function() { var date = $.date(); - date.setFullDate(2012, 9, 16); - equal(date.format({ date: "short" }), "10/16/12", "Checking default US format"); - equal(date.format({ pattern: "yyyy/MM/dd" }), "2012/10/16", "Checking yyyy/MM/dd format"); - equal(date.format({ pattern: "yy/dd/MM" }), "12/16/10", "Checking yy/dd/MM format"); - equal(date.format({ pattern: "MMMM dd, yyyy" }), "October 16, 2012", "Checking MMMM dd, yyyy format"); + date.setFullDate( 2012, 9, 16 ); + equal( date.format({ date: "short" }), "10/16/12", "Checking default US format" ); + equal( date.format({ pattern: "yyyy/MM/dd" }), "2012/10/16", "Checking yyyy/MM/dd format" ); + equal( date.format({ pattern: "yy/dd/MM" }), "12/16/10", "Checking yy/dd/MM format" ); + equal( date.format({ pattern: "MMMM dd, yyyy" }), "October 16, 2012", + "Checking MMMM dd, yyyy format" ); }); From dee3879e765fc6671f8537a47242a9a1a96249f9 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 9 Jan 2014 09:48:43 -0500 Subject: [PATCH 058/172] Date: Make $.date() a constructor function. Move methods to prototype. --- external/date.js | 321 ++++++++++++++++++----------------- tests/unit/date/date_core.js | 8 +- 2 files changed, 173 insertions(+), 156 deletions(-) diff --git a/external/date.js b/external/date.js index b8d1ef30d33..101afb17581 100644 --- a/external/date.js +++ b/external/date.js @@ -20,168 +20,185 @@ var weekdays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ], Globalize.locale( "en" ); $.date = function( date, globalFormat ) { - //TODO: Need to refactor $.date to be a constructor, move the methods to a prototype. + if ( !( this instanceof $.date ) ) { + return new $.date( date, globalFormat ); + } if ( typeof date === "string" && date.length ) { - date = Globalize.parseDate( date, globalFormat ); + this.dateObject = Globalize.parseDate( date, globalFormat ); } - date = date || new Date(); + this.dateObject = this.dateObject || new Date(); + this.globalFormat = globalFormat; +}; - return { - setFormat: function( format ) { - if ( format ) { - globalFormat = format; - } - return this; - }, - //TODO: same as the underlying Date object's terminology, but still misleading. - //TODO: We can use .setTime() instead of new Date and rename to setTimestamp. - setTime: function( time ) { - date = new Date( time ); - return this; - }, - setDay: function( day ) { - date = new Date( date.getFullYear(), date.getMonth(), day, date.getHours(), date.getMinutes(), date.getSeconds() ); - return this; - }, - setMonth: function( month ) { - // Overflow example: Month is October 31 (yeah Halloween) and month is changed to April with 30 days, - // the new date will me May 1. We will honor the month the user wants to set and if and overflow - // occurs, set to last day of month. - var days = date.getDay(), year = date.getFullYear(); - if ( days > this.daysInMonth( year, month ) ) { - // Overflow - days = this.daysInMonth( year, month ); - } - date = new Date( year, month, days, date.getHours(), date.getMinutes(), date.getSeconds() ); - return this; - }, - setYear: function( year ) { - var day = date.getDate(), - month = date.getMonth(); - // Check if Leap, and February and day is 29th - if ( this.isLeapYear( year ) && month == 1 && day == 29 ) { - // set day to last day of February - day = this.daysInMonth( year, month ); - } - date = new Date( year, month, day, date.getHours(), date.getMinutes(), date.getSeconds() ); - return this; - }, - setFullDate: function( year, month, day ) { - date = new Date( year, month, day ); - return this; - }, - adjust: function( period, offset ) { - var day = period == "D" ? date.getDate() + offset : date.getDate(), - month = period == "M" ? date.getMonth() + offset : date.getMonth(), - year = period == "Y" ? date.getFullYear() + offset : date.getFullYear(); - // If not day, update the day to the new month and year - if ( period != "D" ) { - day = Math.max( 1, Math.min( day, this.daysInMonth( year, month ) ) ); - } - date = new Date( year, month, day, date.getHours(), date.getMinutes(), date.getSeconds() ); - return this; - }, - daysInMonth: function( year, month ) { - year = year || date.getFullYear(); - month = month || date.getMonth(); - return 32 - new Date( year, month, 32 ).getDate(); - }, - monthName: function() { - return Globalize.format( date, { pattern: "MMMM" } ); - }, - day: function() { - return date.getDate(); - }, - month: function() { - return date.getMonth(); - }, - year: function() { - return date.getFullYear(); - }, - isLeapYear: function( year ) { - year = year || date.getFullYear(); - return new Date( year, 1, 29 ).getMonth() == 1; +$.date.prototype = { + setFormat: function( format ) { + if ( format ) { + this.globalFormat = format; + } + return this; + }, + //TODO: same as the underlying Date object's terminology, but still misleading. + //TODO: We can use .setTime() instead of new Date and rename to setTimestamp. + setTime: function( time ) { + this.dateObject = new Date( time ); + return this; + }, + setDay: function( day ) { + var date = this.dateObject; + this.dateObject = new Date( date.getFullYear(), date.getMonth(), day, date.getHours(), + date.getMinutes(), date.getSeconds() ); + return this; + }, + setMonth: function( month ) { + // Overflow example: Month is October 31 (yeah Halloween) and month is changed to April with 30 days, + // the new date will me May 1. We will honor the month the user wants to set and if and overflow + // occurs, set to last day of month. + var date = this.dateObject, + days = date.getDay(), year = date.getFullYear(); + if ( days > this.daysInMonth( year, month ) ) { - }, - weekdays: function() { - var result = []; - for ( var dow = 0; dow < 7; dow++ ) { - var day = ( dow + weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] ) % 7; - result.push({ - shortname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/abbreviated", weekdays[ day ] ]), - fullname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/wide", weekdays[ day ] ]), - }); - } - return result; - }, - days: function() { - var result = [], - today = $.date(), - firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(), - leadDays = ( firstDayOfMonth - weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] + 7 ) % 7, - rows = Math.ceil( ( leadDays + this.daysInMonth() ) / 7 ), - printDate = new Date( this.year(), date.getMonth(), 1 - leadDays ); - for ( var row = 0; row < rows; row++ ) { - var week = result[ result.length ] = { - number: Globalize.format( printDate, { pattern: "w" } ), - days: [] + // Overflow + days = this.daysInMonth( year, month ); + } + this.dateObject = new Date( year, month, days, date.getHours(), + date.getMinutes(), date.getSeconds() ); + return this; + }, + setYear: function( year ) { + var date = this.dateObject, + day = date.getDate(), + month = date.getMonth(); + + // Check if Leap, and February and day is 29th + if ( this.isLeapYear( year ) && month == 1 && day == 29 ) { + + // set day to last day of February + day = this.daysInMonth( year, month ); + } + this.dateObject = new Date( year, month, day, date.getHours(), + date.getMinutes(), date.getSeconds() ); + return this; + }, + setFullDate: function( year, month, day ) { + this.dateObject = new Date( year, month, day ); + return this; + }, + adjust: function( period, offset ) { + var date = this.dateObject, + day = period == "D" ? date.getDate() + offset : date.getDate(), + month = period == "M" ? date.getMonth() + offset : date.getMonth(), + year = period == "Y" ? date.getFullYear() + offset : date.getFullYear(); + + // If not day, update the day to the new month and year + if ( period != "D" ) { + day = Math.max( 1, Math.min( day, this.daysInMonth( year, month ) ) ); + } + this.dateObject = new Date( year, month, day, date.getHours(), + date.getMinutes(), date.getSeconds() ); + return this; + }, + daysInMonth: function( year, month ) { + var date = this.dateObject; + year = year || date.getFullYear(); + month = month || date.getMonth(); + return 32 - new Date( year, month, 32 ).getDate(); + }, + monthName: function() { + return Globalize.format( this.dateObject, { pattern: "MMMM" } ); + }, + day: function() { + return this.dateObject.getDate(); + }, + month: function() { + return this.dateObject.getMonth(); + }, + year: function() { + return this.dateObject.getFullYear(); + }, + isLeapYear: function( year ) { + year = year || this.dateObject.getFullYear(); + return new Date( year, 1, 29 ).getMonth() == 1; + }, + weekdays: function() { + var result = []; + for ( var dow = 0; dow < 7; dow++ ) { + var day = ( dow + weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] ) % 7; + result.push({ + shortname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/abbreviated", weekdays[ day ] ]), + fullname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/wide", weekdays[ day ] ]), + }); + } + return result; + }, + days: function() { + var result = [], + today = $.date(), + date = this.dateObject, + firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(), + leadDays = ( firstDayOfMonth - weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] + 7 ) % 7, + rows = Math.ceil( ( leadDays + this.daysInMonth() ) / 7 ), + printDate = new Date( this.year(), date.getMonth(), 1 - leadDays ); + for ( var row = 0; row < rows; row++ ) { + var week = result[ result.length ] = { + number: Globalize.format( printDate, { pattern: "w" } ), + days: [] + }; + for ( var dayx = 0; dayx < 7; dayx++ ) { + var day = week.days[ week.days.length ] = { + lead: printDate.getMonth() != date.getMonth(), + date: printDate.getDate(), + timestamp: printDate.getTime(), + current: this.selected && this.selected.equal( printDate ), + today: today.equal( printDate ) }; - for ( var dayx = 0; dayx < 7; dayx++ ) { - var day = week.days[ week.days.length ] = { - lead: printDate.getMonth() != date.getMonth(), - date: printDate.getDate(), - timestamp: printDate.getTime(), - current: this.selected && this.selected.equal( printDate ), - today: today.equal( printDate ) - }; - day.render = day.selectable = !day.lead; - if ( this.eachDay ) { - this.eachDay( day ); - } - // TODO use adjust("D", 1)? - printDate.setDate( printDate.getDate() + 1 ); + day.render = day.selectable = !day.lead; + if ( this.eachDay ) { + this.eachDay( day ); } + // TODO use adjust("D", 1)? + printDate.setDate( printDate.getDate() + 1 ); } - return result; - }, - // specialized for multi-month template, could be used in general - months: function( add ) { - var clone, - result = [ this ]; + } + return result; + }, + // specialized for multi-month template, could be used in general + months: function( add ) { + var clone, + result = [ this ]; - for ( var i = 0; i < add; i++ ) { - clone = this.clone(); - clone.adjust( "M", i + 1 ); - result.push( clone ); - } - result[ 0 ].first = true; - result[ result.length - 1 ].last = true; - return result; - }, - select: function() { - this.selected = this.clone(); - return this; - }, - clone: function() { - return $.date( new Date(date.getFullYear(), date.getMonth(), - date.getDate(), date.getHours(), - date.getMinutes(), date.getSeconds()), globalFormat ); - }, - // TODO compare year, month, day each for better performance - equal: function( other ) { - function format( date ) { - return Globalize.format( date, { pattern: "yyyyMMdd" } ); - } - return format( date ) === format( other ); - }, - date: function() { - return date; - }, - format: function( format ) { - return Globalize.format( date, format || globalFormat ); + for ( var i = 0; i < add; i++ ) { + clone = this.clone(); + clone.adjust( "M", i + 1 ); + result.push( clone ); } - }; + result[ 0 ].first = true; + result[ result.length - 1 ].last = true; + return result; + }, + select: function() { + this.selected = this.clone(); + return this; + }, + clone: function() { + var date = this.dateObject; + return new $.date( new Date( date.getFullYear(), date.getMonth(), + date.getDate(), date.getHours(), + date.getMinutes(), date.getSeconds()), this.globalFormat ); + }, + // TODO compare year, month, day each for better performance + equal: function( other ) { + function format( date ) { + return Globalize.format( date, { pattern: "yyyyMMdd" } ); + } + return format( this.dateObject ) === format( other ); + }, + date: function() { + return this.dateObject; + }, + format: function( format ) { + return Globalize.format( this.dateObject, format || this.globalFormat ); + } }; }( jQuery )); diff --git a/tests/unit/date/date_core.js b/tests/unit/date/date_core.js index 09ffd206abe..db94cb67d56 100644 --- a/tests/unit/date/date_core.js +++ b/tests/unit/date/date_core.js @@ -1,8 +1,9 @@ module( "date: core" ); -test( "Check Date Setup", 2, function() { - ok( true, "First Test Always Passes" ); - ok( $.date(), "Load JQuery Date" ); +test( "Instantiation", function() { + expect( 2 ); + ok( new $.date() instanceof $.date, "constructor function" ); + ok( $.date() instanceof $.date, "instantiation without new" ); }); test( "Check Sets and Gets", 6, function() { @@ -38,7 +39,6 @@ test( "Date Adjustments - Normal Use Cases", 10, function() { equal( date.adjust( "D", 1 ).year(), 2013, "Add 1 day to change year from 2012 to 2013" ); equal( date.adjust( "D", -1 ).year(), 2012, "Subtract 1 day to change month from 2013 to 2012" ); - }); test( "Date Adjustments - Month Overflow Edge Cases", 2, function() { From 4d65daeb28a7138b7a5d57da83da5457f2e3d045 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 23 Apr 2014 17:49:03 +0200 Subject: [PATCH 059/172] Datepicker: fix jshint and htmllint issues, code style --- demos/datepicker/show-week.html | 2 +- tests/unit/datepicker/datepicker_core.js | 157 +- tests/unit/datepicker/datepicker_events.js | 151 +- tests/unit/datepicker/datepicker_methods.js | 2 +- tests/unit/datepicker/datepicker_options.js | 1284 ++++++++--------- .../datepicker/datepicker_test_helpers.js | 20 +- ui/datepicker.js | 65 +- 7 files changed, 861 insertions(+), 820 deletions(-) diff --git a/demos/datepicker/show-week.html b/demos/datepicker/show-week.html index 747398d4988..091fed4cdf6 100644 --- a/demos/datepicker/show-week.html +++ b/demos/datepicker/show-week.html @@ -28,7 +28,7 @@

        The datepicker can show the week of the year. The calculation follows - Unicode CLDR specification. + Unicode CLDR specification. This means that some days from one year may be placed into weeks 'belonging' to another year.

        diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 1f7333675ca..88bf8ab6acb 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -40,7 +40,7 @@ asyncTest( "baseStructure", function() { ok( header.children( ":eq(1)" ).is( ".ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); title = header.children( ":last" ).children( ":first" ); - ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "","Structure - title division" ); + ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "", "Structure - title division" ); equal( title.children().length, 2, "Structure - title child count" ); ok( title.children( ":first" ).is( "span.ui-datepicker-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); ok( title.children( ":last" ).is( "span.ui-datepicker-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); @@ -95,7 +95,7 @@ asyncTest( "baseStructure", function() { function step3() { // Multi-month 2 - inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 2 }); + inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 2 } ); dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); inp.focus(); setTimeout(function() { @@ -121,7 +121,7 @@ asyncTest( "baseStructure", function() { function step4() { // Multi-month 3 - inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 3 }); + inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 3 } ); dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); inp.focus(); setTimeout(function() { @@ -135,7 +135,7 @@ asyncTest( "baseStructure", function() { function step5() { // Multi-month [2, 2] - inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: [ 2, 2 ] }); + inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: [ 2, 2 ] } ); dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); inp.focus(); setTimeout(function() { @@ -217,19 +217,18 @@ asyncTest( "baseStructure", function() { step1(); }); +// Skip these tests for now as none are implemented yet. +/* asyncTest( "customStructure", function() { expect( 0 ); - var header, panel, title, thead, + var header, panel, title, inp = TestHelpers.datepicker.initNewInput(), dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); - // Skip these tests for now as none are implemented yet. start(); - return; function step1() { - /* Globalize.culture( "he" ); inp.focus(); @@ -252,12 +251,10 @@ asyncTest( "customStructure", function() { Globalize.culture( "en-US" ); step2(); }); - */ } // Hide prev/next // TODO: If we decide the hideIfNoPrevNext option is being removed these tests can be as well. - /* function stepX() { inp = TestHelpers.datepicker.initNewInput({ hideIfNoPrevNext: true, @@ -276,11 +273,10 @@ asyncTest( "customStructure", function() { step3(); }); } - */ // Changeable Month with read-only year function step2() { - inp = TestHelpers.datepicker.initNewInput({ changeMonth: true }); + inp = TestHelpers.datepicker.initNewInput({ changeMonth: true } ); dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); inp.focus(); @@ -299,7 +295,7 @@ asyncTest( "customStructure", function() { // Changeable year with read-only month function step3() { - inp = TestHelpers.datepicker.initNewInput({ changeYear: true }); + inp = TestHelpers.datepicker.initNewInput({ changeYear: true } ); TestHelpers.datepicker.onFocus( inp, function() { title = dp.children( ":first" ).children( ":last" ); @@ -319,6 +315,7 @@ asyncTest( "customStructure", function() { // Support: IE setTimeout( step1 ); }); +*/ test( "Keyboard handling", function() { expect( 9 ); @@ -327,39 +324,39 @@ test( "Keyboard handling", function() { date = new Date(); input.datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke enter" ); // Enter = Select today's date by default input.val( "1/1/14" ).datepicker( "open" ) - .simulate("keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke enter - preset" ); // Control + Home = Change the calendar to the current month input.val( "1/1/14" ).datepicker( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+home" ); // Control + End = Close the calendar and clear the input input.val( "1/1/14" ).datepicker( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END }); + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); equal( input.val(), "", "Keystroke ctrl+end" ); input.val( "" ).datepicker( "open" ); ok( instance.isOpen, "datepicker is open before escape" ); - input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); + input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); ok( !instance.isOpen, "escape closes the datepicker" ); input.val( "1/1/14" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke esc - preset" ); input.val( "1/1/14" ).datepicker( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke esc - abandoned" ); @@ -382,38 +379,38 @@ asyncTest( "keyboard handling", function() { picker = input.datepicker( "widget" ); ok( !picker.is( ":visible" ), "datepicker closed" ); input.val( "" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { ok( picker.is( ":visible" ), "Keystroke down opens datepicker" ); input.datepicker( "destroy" ); step2(); }); - }; + } function step2() { input.datepicker(); - picker = input.datepicker( "widget" ) + picker = input.datepicker( "widget" ); ok( !picker.is( ":visible" ), "datepicker closed" ); input.val( "" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.UP }); + .simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); setTimeout(function() { ok( picker.is( ":visible" ), "Keystroke up opens datepicker" ); input.datepicker( "destroy" ); step3(); }); - }; + } function step3() { input.datepicker() .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2013, 12 - 1, 31 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke left to switch to previous day" ); @@ -421,17 +418,17 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); step4(); }, 100 ); - }; + } function step4() { input.datepicker() .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2014, 1 - 1, 2 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke right to switch to next day" ); @@ -439,17 +436,17 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); step5(); }, 100 ); - }; + } function step5() { input.datepicker() .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.UP }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2013, 12 - 1, 25 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke up to move to the previous week" ); @@ -457,17 +454,17 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); step6(); }, 100 ); - }; + } function step6() { input.datepicker() .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2014, 1 - 1, 8 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke down to move to the next week" ); @@ -475,17 +472,17 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); step7(); }, 100 ); - }; + } function step7() { input.datepicker() .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2013, 12 - 1, 1 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke Page Up moves date to previous month" ); @@ -493,17 +490,17 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); step8(); }, 100 ); - }; + } function step8() { input.datepicker() .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2013, 1 - 1, 1 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke Page Up + Ctrl moves date to previous year" ); @@ -511,17 +508,17 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); step9(); }, 100 ); - }; + } function step9() { input.datepicker() .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2014, 2 - 1, 1 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke Page Down moves date to next month" ); @@ -529,17 +526,17 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); step10(); }, 100 ); - }; + } function step10() { input.datepicker() .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2015, 1 - 1, 1 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke Page Down + Ctrl moves date to next year" ); @@ -547,18 +544,18 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); step11(); }, 100 ); - }; + } // Check for moving to short months function step11() { input.datepicker() .val( "3/31/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2014, 2 - 1, 28 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke Page Up and short months" ); @@ -566,17 +563,17 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); step12(); }, 100 ); - }; + } function step12() { input.datepicker() .val( "1/30/16" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2016, 2 - 1, 29 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke Page Down and leap years" ); @@ -584,23 +581,23 @@ asyncTest( "keyboard handling", function() { input.datepicker( "destroy" ); start(); }, 100 ); - }; + } step1(); }); /* // TODO: Re-add tests if we implement a stepMonths option - input.datepicker( "option", { stepMonths: 2, gotoCurrent: false }) + input.datepicker( "option", { stepMonths: 2, gotoCurrent: false } ) .datepicker( "close" ).val( "02/04/2008" ).datepicker( "open" ) - .late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2007, 12 - 1, 4 ), "Keystroke pgup step 2" ); input.val( "02/04/2008" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN }) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ), "Keystroke pgdn step 2" ); */ @@ -619,8 +616,8 @@ test( "mouse", function() { input.val( "2/4/08" ).datepicker( "open" ); $( ".ui-datepicker-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); - TestHelpers.datepicker.equalsDate( input.datepicker("valueAsDate"), new Date( 2008, 2 - 1, 12 ), - "Mouse click - preset") ; + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), + "Mouse click - preset" ) ; input.val( "" ).datepicker( "open" ); $( "button.ui-datepicker-close", picker ).simulate( "click", {} ); @@ -650,15 +647,15 @@ test( "mouse", function() { "Mouse click - previous" ); input.val( "2/4/08" ).datepicker( "open" ); - $(".ui-datepicker-next", picker ).simulate( "click" ); - $(".ui-datepicker-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); - TestHelpers.datepicker.equalsDate( input.datepicker("valueAsDate"), new Date( 2008, 3 - 1, 18 ), + $( ".ui-datepicker-next", picker ).simulate( "click" ); + $( ".ui-datepicker-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), "Mouse click - next" ); /* // TODO: Re-add when min and max options are introduced. // Previous/next with minimum/maximum - input.datepicker("option", { + input.datepicker( "option", { minDate: new Date( 2008, 2 - 1, 2 ), maxDate: new Date( 2008, 2 - 1, 26 ) }).val( "2/4/08" ).datepicker( "open" ); @@ -683,13 +680,13 @@ test( "mouse", function() { date.setDate( 10 ); TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), date, "Mouse click inline" ); - inline.datepicker( "option", { showButtonPanel: true }) + inline.datepicker( "option", { showButtonPanel: true } ) .datepicker( "valueAsDate", new Date( 2008, 2 - 1, 4 )); $( ".ui-datepicker-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), "Mouse click inline - preset" ); - inline.datepicker("option", { showButtonPanel: true }); + inline.datepicker( "option", { showButtonPanel: true } ); $( ".ui-datepicker-current", picker ).simulate( "click", {} ); $( ".ui-datepicker-calendar tbody a:contains(14)", picker ).simulate( "mousedown", {} ); date.setDate( 14 ); diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index 63e2b0e9cc7..9ee254e5351 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -1,3 +1,10 @@ +// The implement of events is completely changing therefore these tests are no longer directly +// relevant. Leaving them around commented out so we can ensure the functionality is replicated. +// For example: +// TODO: In the old implementation the Enter key select's today's date when the has +// focus and is empty. Do we want to replicate this behavior in the rewrite? +/* + (function( $ ) { module( "datepicker: events" ); @@ -18,12 +25,6 @@ test( "select", function() { expect( 0 ); }); -// The implement of events is completely changing therefore these tests are no longer directly -// relevant. Leaving them around commented out so we can ensure the functionality is replicated. -// For example: -// TODO: In the old implementation the Enter key select's today's date when the has -// focus and is empty. Do we want to replicate this behavior in the rewrite? -/* var selectedThis = null, selectedDate = null, selectedInst = null; @@ -40,110 +41,110 @@ function callback2(year, month, inst) { selectedInst = inst; } -test("events", function() { +test( "events", function() { expect( 26 ); var dateStr, newMonthYear, inp2, - inp = TestHelpers.datepicker.init("#inp", {onSelect: callback}), + inp = TestHelpers.datepicker.init( "#inp", {onSelect: callback}), date = new Date(); // onSelect - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(selectedThis, inp[0], "Callback selected this"); - equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Callback selected inst"); - equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date), - "Callback selected date"); - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + inp.val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(selectedThis, inp[0], "Callback selected this" ); + equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Callback selected inst" ); + equal(selectedDate, $.datepicker.formatDate( "mm/dd/yy", date), + "Callback selected date" ); + inp.val( "" ).datepicker( "show" ). + simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 7); - equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date), - "Callback selected date - ctrl+down"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date), - "Callback selected date - esc"); + equal(selectedDate, $.datepicker.formatDate( "mm/dd/yy", date), + "Callback selected date - ctrl+down" ); + inp.val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(selectedDate, $.datepicker.formatDate( "mm/dd/yy", date), + "Callback selected date - esc" ); dateStr = "02/04/2008"; - inp.val(dateStr).datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + inp.val(dateStr).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); equal(dateStr, selectedDate, - "onSelect is called after enter keydown"); + "onSelect is called after enter keydown" ); // onChangeMonthYear - inp.datepicker("option", {onChangeMonthYear: callback2, onSelect: null}). - val("").datepicker("show"); + inp.datepicker( "option", {onChangeMonthYear: callback2, onSelect: null}). + val( "" ).datepicker( "show" ); newMonthYear = function(date) { return date.getFullYear() + "/" + (date.getMonth() + 1); }; date = new Date(); date.setDate(1); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_UP}); date.setMonth(date.getMonth() - 1); - equal(selectedThis, inp[0], "Callback change month/year this"); - equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Callback change month/year inst"); + equal(selectedThis, inp[0], "Callback change month/year this" ); + equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Callback change month/year inst" ); equal(selectedDate, newMonthYear(date), - "Callback change month/year date - pgup"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); + "Callback change month/year date - pgup" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); date.setMonth(date.getMonth() + 1); equal(selectedDate, newMonthYear(date), - "Callback change month/year date - pgdn"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); + "Callback change month/year date - pgdn" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); date.setFullYear(date.getFullYear() - 1); equal(selectedDate, newMonthYear(date), - "Callback change month/year date - ctrl+pgup"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}); + "Callback change month/year date - ctrl+pgup" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}); date.setFullYear(date.getFullYear() + 1); equal(selectedDate, newMonthYear(date), - "Callback change month/year date - ctrl+home"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); + "Callback change month/year date - ctrl+home" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); date.setFullYear(date.getFullYear() + 1); equal(selectedDate, newMonthYear(date), - "Callback change month/year date - ctrl+pgdn"); - inp.datepicker("setDate", new Date(2007, 1 - 1, 26)); - equal(selectedDate, "2007/1", "Callback change month/year date - setDate"); + "Callback change month/year date - ctrl+pgdn" ); + inp.datepicker( "setDate", new Date(2007, 1 - 1, 26)); + equal(selectedDate, "2007/1", "Callback change month/year date - setDate" ); selectedDate = null; - inp.datepicker("setDate", new Date(2007, 1 - 1, 12)); - ok(selectedDate == null, "Callback change month/year date - setDate no change"); + inp.datepicker( "setDate", new Date(2007, 1 - 1, 12)); + ok(selectedDate == null, "Callback change month/year date - setDate no change" ); // onChangeMonthYear step by 2 - inp.datepicker("option", {stepMonths: 2}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}); + inp.datepicker( "option", {stepMonths: 2}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_UP}); date.setMonth(date.getMonth() - 14); equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - pgup"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); + "Callback change month/year by 2 date - pgup" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); date.setMonth(date.getMonth() - 12); equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - ctrl+pgup"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); + "Callback change month/year by 2 date - ctrl+pgup" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); date.setMonth(date.getMonth() + 2); equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - pgdn"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); + "Callback change month/year by 2 date - pgdn" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); date.setMonth(date.getMonth() + 12); equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - ctrl+pgdn"); + "Callback change month/year by 2 date - ctrl+pgdn" ); // onClose - inp.datepicker("option", {onClose: callback, onChangeMonthYear: null, stepMonths: 1}). - val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(selectedThis, inp[0], "Callback close this"); - equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Callback close inst"); - equal(selectedDate, "", "Callback close date - esc"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", new Date()), - "Callback close date - enter"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(selectedDate, "02/04/2008", "Callback close date - preset"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); - equal(selectedDate, "", "Callback close date - ctrl+end"); + inp.datepicker( "option", {onClose: callback, onChangeMonthYear: null, stepMonths: 1}). + val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(selectedThis, inp[0], "Callback close this" ); + equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Callback close inst" ); + equal(selectedDate, "", "Callback close date - esc" ); + inp.val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(selectedDate, $.datepicker.formatDate( "mm/dd/yy", new Date()), + "Callback close date - enter" ); + inp.val( "02/04/2008" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(selectedDate, "02/04/2008", "Callback close date - preset" ); + inp.val( "02/04/2008" ).datepicker( "show" ). + simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); + equal(selectedDate, "", "Callback close date - ctrl+end" ); - inp2 = TestHelpers.datepicker.init("#inp2"); - inp2.datepicker().datepicker("option", {onClose: callback}).datepicker("show"); - inp.datepicker("show"); - equal(selectedThis, inp2[0], "Callback close this"); + inp2 = TestHelpers.datepicker.init( "#inp2" ); + inp2.datepicker().datepicker( "option", {onClose: callback}).datepicker( "show" ); + inp.datepicker( "show" ); + equal(selectedThis, inp2[0], "Callback close this" ); }); -*/ })( jQuery ); + */ diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 281a81c8d9b..7efea106918 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -51,7 +51,7 @@ test( "enable / disable", function() { test( "widget", function() { expect( 1 ); var actual = $( "#datepicker" ).datepicker().datepicker( "widget" ); - deepEqual( $("body > .ui-front" )[ 0 ], actual[ 0 ] ); + deepEqual( $( "body > .ui-front" )[ 0 ], actual[ 0 ] ); actual.remove(); }); diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index c08c370e26f..173e19e5203 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -44,7 +44,7 @@ test( "dateFormat", function() { expect( 2 ); var input = $( "#datepicker" ).val( "1/1/14" ).datepicker(), picker = input.datepicker( "widget" ), - firstDayLink = picker.find( "td[id]:first a" ); + firstDayLink = picker.find( "td[id]:first a" ); input.datepicker( "open" ); firstDayLink.trigger( "mousedown" ); @@ -60,7 +60,7 @@ test( "eachDay", function() { expect( 5 ); var timestamp, input = $( "#datepicker" ).datepicker(), - picker = input.datepicker( "widget" ); + picker = input.datepicker( "widget" ), firstCell = picker.find( "td[id]:first" ); equal( firstCell.find( "a" ).length, 1, "days are selectable by default" ); @@ -155,85 +155,85 @@ test( "showWeek", function() { }); /* -test("setDefaults", function() { +test( "setDefaults", function() { expect( 3 ); - TestHelpers.datepicker.init("#inp"); - equal($.datepicker._defaults.showOn, "focus", "Initial showOn"); + TestHelpers.datepicker.init( "#inp" ); + equal($.datepicker._defaults.showOn, "focus", "Initial showOn" ); $.datepicker.setDefaults({showOn: "button"}); - equal($.datepicker._defaults.showOn, "button", "Change default showOn"); + equal($.datepicker._defaults.showOn, "button", "Change default showOn" ); $.datepicker.setDefaults({showOn: "focus"}); - equal($.datepicker._defaults.showOn, "focus", "Restore showOn"); + equal($.datepicker._defaults.showOn, "focus", "Restore showOn" ); }); -test("option", function() { +test( "option", function() { expect( 17 ); - var inp = TestHelpers.datepicker.init("#inp"), + var inp = TestHelpers.datepicker.init( "#inp" ), inst = $.data(inp[0], TestHelpers.datepicker.PROP_NAME); // Set option - equal(inst.settings.showOn, null, "Initial setting showOn"); - equal($.datepicker._get(inst, "showOn"), "focus", "Initial instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Initial default showOn"); - inp.datepicker("option", "showOn", "button"); - equal(inst.settings.showOn, "button", "Change setting showOn"); - equal($.datepicker._get(inst, "showOn"), "button", "Change instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); - inp.datepicker("option", {showOn: "both"}); - equal(inst.settings.showOn, "both", "Change setting showOn"); - equal($.datepicker._get(inst, "showOn"), "both", "Change instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); - inp.datepicker("option", "showOn", undefined); - equal(inst.settings.showOn, null, "Clear setting showOn"); - equal($.datepicker._get(inst, "showOn"), "focus", "Restore instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); + equal(inst.settings.showOn, null, "Initial setting showOn" ); + equal($.datepicker._get(inst, "showOn" ), "focus", "Initial instance showOn" ); + equal($.datepicker._defaults.showOn, "focus", "Initial default showOn" ); + inp.datepicker( "option", "showOn", "button" ); + equal(inst.settings.showOn, "button", "Change setting showOn" ); + equal($.datepicker._get(inst, "showOn" ), "button", "Change instance showOn" ); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); + inp.datepicker( "option", {showOn: "both"}); + equal(inst.settings.showOn, "both", "Change setting showOn" ); + equal($.datepicker._get(inst, "showOn" ), "both", "Change instance showOn" ); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); + inp.datepicker( "option", "showOn", undefined); + equal(inst.settings.showOn, null, "Clear setting showOn" ); + equal($.datepicker._get(inst, "showOn" ), "focus", "Restore instance showOn" ); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); // Get option - inp = TestHelpers.datepicker.init("#inp"); - equal(inp.datepicker("option", "showOn"), "focus", "Initial setting showOn"); - inp.datepicker("option", "showOn", "button"); - equal(inp.datepicker("option", "showOn"), "button", "Change instance showOn"); - inp.datepicker("option", "showOn", undefined); - equal(inp.datepicker("option", "showOn"), "focus", "Reset instance showOn"); - deepEqual(inp.datepicker("option", "all"), {showAnim: ""}, "Get instance settings"); - deepEqual(inp.datepicker("option", "defaults"), $.datepicker._defaults, - "Get default settings"); + inp = TestHelpers.datepicker.init( "#inp" ); + equal(inp.datepicker( "option", "showOn" ), "focus", "Initial setting showOn" ); + inp.datepicker( "option", "showOn", "button" ); + equal(inp.datepicker( "option", "showOn" ), "button", "Change instance showOn" ); + inp.datepicker( "option", "showOn", undefined); + equal(inp.datepicker( "option", "showOn" ), "focus", "Reset instance showOn" ); + deepEqual(inp.datepicker( "option", "all" ), {showAnim: ""}, "Get instance settings" ); + deepEqual(inp.datepicker( "option", "defaults" ), $.datepicker._defaults, + "Get default settings" ); }); test( "disabled", function() { expect(8); - var inp = TestHelpers.datepicker.init("#inp"); - ok(!inp.datepicker("isDisabled"), "Initially marked as enabled"); - ok(!inp[0].disabled, "Field initially enabled"); - inp.datepicker("option", "disabled", true); - ok(inp.datepicker("isDisabled"), "Marked as disabled"); - ok(inp[0].disabled, "Field now disabled"); - inp.datepicker("option", "disabled", false); - ok(!inp.datepicker("isDisabled"), "Marked as enabled"); - ok(!inp[0].disabled, "Field now enabled"); - inp.datepicker("destroy"); - - inp = TestHelpers.datepicker.init("#inp", { disabled: true }); - ok(inp.datepicker("isDisabled"), "Initially marked as disabled"); - ok(inp[0].disabled, "Field initially disabled"); + var inp = TestHelpers.datepicker.init( "#inp" ); + ok(!inp.datepicker( "isDisabled" ), "Initially marked as enabled" ); + ok(!inp[0].disabled, "Field initially enabled" ); + inp.datepicker( "option", "disabled", true); + ok(inp.datepicker( "isDisabled" ), "Marked as disabled" ); + ok(inp[0].disabled, "Field now disabled" ); + inp.datepicker( "option", "disabled", false); + ok(!inp.datepicker( "isDisabled" ), "Marked as enabled" ); + ok(!inp[0].disabled, "Field now enabled" ); + inp.datepicker( "destroy" ); + + inp = TestHelpers.datepicker.init( "#inp", { disabled: true }); + ok(inp.datepicker( "isDisabled" ), "Initially marked as disabled" ); + ok(inp[0].disabled, "Field initially disabled" ); }); -test("change", function() { +test( "change", function() { expect( 12 ); - var inp = TestHelpers.datepicker.init("#inp"), + var inp = TestHelpers.datepicker.init( "#inp" ), inst = $.data(inp[0], TestHelpers.datepicker.PROP_NAME); - equal(inst.settings.showOn, null, "Initial setting showOn"); - equal($.datepicker._get(inst, "showOn"), "focus", "Initial instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Initial default showOn"); - inp.datepicker("change", "showOn", "button"); - equal(inst.settings.showOn, "button", "Change setting showOn"); - equal($.datepicker._get(inst, "showOn"), "button", "Change instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); - inp.datepicker("change", {showOn: "both"}); - equal(inst.settings.showOn, "both", "Change setting showOn"); - equal($.datepicker._get(inst, "showOn"), "both", "Change instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); - inp.datepicker("change", "showOn", undefined); - equal(inst.settings.showOn, null, "Clear setting showOn"); - equal($.datepicker._get(inst, "showOn"), "focus", "Restore instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); + equal(inst.settings.showOn, null, "Initial setting showOn" ); + equal($.datepicker._get(inst, "showOn" ), "focus", "Initial instance showOn" ); + equal($.datepicker._defaults.showOn, "focus", "Initial default showOn" ); + inp.datepicker( "change", "showOn", "button" ); + equal(inst.settings.showOn, "button", "Change setting showOn" ); + equal($.datepicker._get(inst, "showOn" ), "button", "Change instance showOn" ); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); + inp.datepicker( "change", {showOn: "both"}); + equal(inst.settings.showOn, "both", "Change setting showOn" ); + equal($.datepicker._get(inst, "showOn" ), "both", "Change instance showOn" ); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); + inp.datepicker( "change", "showOn", undefined); + equal(inst.settings.showOn, null, "Clear setting showOn" ); + equal($.datepicker._get(inst, "showOn" ), "focus", "Restore instance showOn" ); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); }); (function() { @@ -377,135 +377,135 @@ test("change", function() { }); })(); -test("otherMonths", function() { +test( "otherMonths", function() { expect( 8 ); - var inp = TestHelpers.datepicker.init("#inp"), - pop = $("#ui-datepicker-div"); - inp.val("06/01/2009").datepicker("show"); - equal(pop.find("tbody").text(), + var inp = TestHelpers.datepicker.init( "#inp" ), + pop = $( "#ui-datepicker-div" ); + inp.val( "06/01/2009" ).datepicker( "show" ); + equal(pop.find( "tbody" ).text(), // support: IE <9, jQuery <1.8 // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), - "Other months - none"); - ok(pop.find("td:last *").length === 0, "Other months - no content"); - inp.datepicker("hide").datepicker("option", "showOtherMonths", true).datepicker("show"); - equal(pop.find("tbody").text(), "311234567891011121314151617181920212223242526272829301234", - "Other months - show"); - ok(pop.find("td:last span").length === 1, "Other months - span content"); - inp.datepicker("hide").datepicker("option", "selectOtherMonths", true).datepicker("show"); - equal(pop.find("tbody").text(), "311234567891011121314151617181920212223242526272829301234", - "Other months - select"); - ok(pop.find("td:last a").length === 1, "Other months - link content"); - inp.datepicker("hide").datepicker("option", "showOtherMonths", false).datepicker("show"); - equal(pop.find("tbody").text(), + "Other months - none" ); + ok(pop.find( "td:last *" ).length === 0, "Other months - no content" ); + inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", true).datepicker( "show" ); + equal(pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", + "Other months - show" ); + ok(pop.find( "td:last span" ).length === 1, "Other months - span content" ); + inp.datepicker( "hide" ).datepicker( "option", "selectOtherMonths", true).datepicker( "show" ); + equal(pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", + "Other months - select" ); + ok(pop.find( "td:last a" ).length === 1, "Other months - link content" ); + inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", false).datepicker( "show" ); + equal(pop.find( "tbody" ).text(), // support: IE <9, jQuery <1.8 // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), - "Other months - none"); - ok(pop.find("td:last *").length === 0, "Other months - no content"); + "Other months - none" ); + ok(pop.find( "td:last *" ).length === 0, "Other months - no content" ); }); -test("defaultDate", function() { +test( "defaultDate", function() { expect( 16 ); - var inp = TestHelpers.datepicker.init("#inp"), + var inp = TestHelpers.datepicker.init( "#inp" ), date = new Date(); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date null"); + inp.val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date null" ); // Numeric values - inp.datepicker("option", {defaultDate: -2}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + inp.datepicker( "option", {defaultDate: -2}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() - 2); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date -2"); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date -2" ); date = new Date(); - inp.datepicker("option", {defaultDate: 3}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + inp.datepicker( "option", {defaultDate: 3}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 3); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date 3"); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date 3" ); date = new Date(); - inp.datepicker("option", {defaultDate: 1 / "a"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date NaN"); + inp.datepicker( "option", {defaultDate: 1 / "a"}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date NaN" ); // String offset values - inp.datepicker("option", {defaultDate: "-1d"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + inp.datepicker( "option", {defaultDate: "-1d"}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() - 1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date -1d"); - inp.datepicker("option", {defaultDate: "+3D"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date -1d" ); + inp.datepicker( "option", {defaultDate: "+3D"}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 4); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date +3D"); - inp.datepicker("option", {defaultDate: " -2 w "}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date +3D" ); + inp.datepicker( "option", {defaultDate: " -2 w "}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date = new Date(); date.setDate(date.getDate() - 14); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date -2 w"); - inp.datepicker("option", {defaultDate: "+1 W"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date -2 w" ); + inp.datepicker( "option", {defaultDate: "+1 W"}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setDate(date.getDate() + 21); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date +1 W"); - inp.datepicker("option", {defaultDate: " -1 m "}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date +1 W" ); + inp.datepicker( "option", {defaultDate: " -1 m "}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date = TestHelpers.datepicker.addMonths(new Date(), -1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date -1 m"); - inp.datepicker("option", {defaultDate: "+2M"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date -1 m" ); + inp.datepicker( "option", {defaultDate: "+2M"}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date = TestHelpers.datepicker.addMonths(new Date(), 2); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date +2M"); - inp.datepicker("option", {defaultDate: "-2y"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date +2M" ); + inp.datepicker( "option", {defaultDate: "-2y"}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date = new Date(); date.setFullYear(date.getFullYear() - 2); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date -2y"); - inp.datepicker("option", {defaultDate: "+1 Y "}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date -2y" ); + inp.datepicker( "option", {defaultDate: "+1 Y "}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date.setFullYear(date.getFullYear() + 3); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date +1 Y"); - inp.datepicker("option", {defaultDate: "+1M +10d"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date +1 Y" ); + inp.datepicker( "option", {defaultDate: "+1M +10d"}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date = TestHelpers.datepicker.addMonths(new Date(), 1); date.setDate(date.getDate() + 10); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date +1M +10d"); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date +1M +10d" ); // String date values - inp.datepicker("option", {defaultDate: "07/04/2007"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + inp.datepicker( "option", {defaultDate: "07/04/2007"}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date = new Date(2007, 7 - 1, 4); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date 07/04/2007"); - inp.datepicker("option", {dateFormat: "yy-mm-dd", defaultDate: "2007-04-02"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date 07/04/2007" ); + inp.datepicker( "option", {dateFormat: "yy-mm-dd", defaultDate: "2007-04-02"}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date = new Date(2007, 4 - 1, 2); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date 2007-04-02"); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date 2007-04-02" ); // Date value date = new Date(2007, 1 - 1, 26); - inp.datepicker("option", {dateFormat: "mm/dd/yy", defaultDate: date}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, "Default date 01/26/2007"); + inp.datepicker( "option", {dateFormat: "mm/dd/yy", defaultDate: date}). + datepicker( "hide" ).val( "" ).datepicker( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date 01/26/2007" ); }); -test("miscellaneous", function() { +test( "miscellaneous", function() { expect( 19 ); var curYear, longNames, shortNames, date, - dp = $("#ui-datepicker-div"), - inp = TestHelpers.datepicker.init("#inp"); + dp = $( "#ui-datepicker-div" ), + inp = TestHelpers.datepicker.init( "#inp" ); // Year range function genRange(start, offset) { var i = start, @@ -516,398 +516,398 @@ test("miscellaneous", function() { return range; } curYear = new Date().getFullYear(); - inp.val("02/04/2008").datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), "2008", "Year range - read-only default"); - inp.datepicker("hide").datepicker("option", {changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(2008 - 10, 21), "Year range - changeable default"); - inp.datepicker("hide").datepicker("option", {yearRange: "c-6:c+2", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(2008 - 6, 9), "Year range - c-6:c+2"); - inp.datepicker("hide").datepicker("option", {yearRange: "2000:2010", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(2000, 11), "Year range - 2000:2010"); - inp.datepicker("hide").datepicker("option", {yearRange: "-5:+3", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(curYear - 5, 9), "Year range - -5:+3"); - inp.datepicker("hide").datepicker("option", {yearRange: "2000:-5", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(2000, curYear - 2004), "Year range - 2000:-5"); - inp.datepicker("hide").datepicker("option", {yearRange: "", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(curYear, 1), "Year range - -6:+2"); + inp.val( "02/04/2008" ).datepicker( "show" ); + equal(dp.find( ".ui-datepicker-year" ).text(), "2008", "Year range - read-only default" ); + inp.datepicker( "hide" ).datepicker( "option", {changeYear: true}).datepicker( "show" ); + equal(dp.find( ".ui-datepicker-year" ).text(), genRange(2008 - 10, 21), "Year range - changeable default" ); + inp.datepicker( "hide" ).datepicker( "option", {yearRange: "c-6:c+2", changeYear: true}).datepicker( "show" ); + equal(dp.find( ".ui-datepicker-year" ).text(), genRange(2008 - 6, 9), "Year range - c-6:c+2" ); + inp.datepicker( "hide" ).datepicker( "option", {yearRange: "2000:2010", changeYear: true}).datepicker( "show" ); + equal(dp.find( ".ui-datepicker-year" ).text(), genRange(2000, 11), "Year range - 2000:2010" ); + inp.datepicker( "hide" ).datepicker( "option", {yearRange: "-5:+3", changeYear: true}).datepicker( "show" ); + equal(dp.find( ".ui-datepicker-year" ).text(), genRange(curYear - 5, 9), "Year range - -5:+3" ); + inp.datepicker( "hide" ).datepicker( "option", {yearRange: "2000:-5", changeYear: true}).datepicker( "show" ); + equal(dp.find( ".ui-datepicker-year" ).text(), genRange(2000, curYear - 2004), "Year range - 2000:-5" ); + inp.datepicker( "hide" ).datepicker( "option", {yearRange: "", changeYear: true}).datepicker( "show" ); + equal(dp.find( ".ui-datepicker-year" ).text(), genRange(curYear, 1), "Year range - -6:+2" ); // Navigation as date format - inp.datepicker("option", {showButtonPanel: true}); - equal(dp.find(".ui-datepicker-prev").text(), "Prev", "Navigation prev - default"); - equal(dp.find(".ui-datepicker-current").text(), "Today", "Navigation current - default"); - equal(dp.find(".ui-datepicker-next").text(), "Next", "Navigation next - default"); - inp.datepicker("hide").datepicker("option", {navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >"}). - val("02/04/2008").datepicker("show"); + inp.datepicker( "option", {showButtonPanel: true}); + equal(dp.find( ".ui-datepicker-prev" ).text(), "Prev", "Navigation prev - default" ); + equal(dp.find( ".ui-datepicker-current" ).text(), "Today", "Navigation current - default" ); + equal(dp.find( ".ui-datepicker-next" ).text(), "Next", "Navigation next - default" ); + inp.datepicker( "hide" ).datepicker( "option", {navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >"}). + val( "02/04/2008" ).datepicker( "show" ); longNames = $.datepicker.regional[""].monthNames; shortNames = $.datepicker.regional[""].monthNamesShort; date = new Date(); - equal(dp.find(".ui-datepicker-prev").text(), "< " + shortNames[0], "Navigation prev - as date format"); - equal(dp.find(".ui-datepicker-current").text(), - longNames[date.getMonth()], "Navigation current - as date format"); - equal(dp.find(".ui-datepicker-next").text(), - shortNames[2] + " >", "Navigation next - as date format"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); - equal(dp.find(".ui-datepicker-prev").text(), - "< " + shortNames[1], "Navigation prev - as date format + pgdn"); - equal(dp.find(".ui-datepicker-current").text(), - longNames[date.getMonth()], "Navigation current - as date format + pgdn"); - equal(dp.find(".ui-datepicker-next").text(), - shortNames[3] + " >", "Navigation next - as date format + pgdn"); - inp.datepicker("hide").datepicker("option", {gotoCurrent: true}). - val("02/04/2008").datepicker("show"); - equal(dp.find(".ui-datepicker-prev").text(), - "< " + shortNames[0], "Navigation prev - as date format + goto current"); - equal(dp.find(".ui-datepicker-current").text(), - longNames[1], "Navigation current - as date format + goto current"); - equal(dp.find(".ui-datepicker-next").text(), - shortNames[2] + " >", "Navigation next - as date format + goto current"); + equal(dp.find( ".ui-datepicker-prev" ).text(), "< " + shortNames[0], "Navigation prev - as date format" ); + equal(dp.find( ".ui-datepicker-current" ).text(), + longNames[date.getMonth()], "Navigation current - as date format" ); + equal(dp.find( ".ui-datepicker-next" ).text(), + shortNames[2] + " >", "Navigation next - as date format" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); + equal(dp.find( ".ui-datepicker-prev" ).text(), + "< " + shortNames[1], "Navigation prev - as date format + pgdn" ); + equal(dp.find( ".ui-datepicker-current" ).text(), + longNames[date.getMonth()], "Navigation current - as date format + pgdn" ); + equal(dp.find( ".ui-datepicker-next" ).text(), + shortNames[3] + " >", "Navigation next - as date format + pgdn" ); + inp.datepicker( "hide" ).datepicker( "option", {gotoCurrent: true}). + val( "02/04/2008" ).datepicker( "show" ); + equal(dp.find( ".ui-datepicker-prev" ).text(), + "< " + shortNames[0], "Navigation prev - as date format + goto current" ); + equal(dp.find( ".ui-datepicker-current" ).text(), + longNames[1], "Navigation current - as date format + goto current" ); + equal(dp.find( ".ui-datepicker-next" ).text(), + shortNames[2] + " >", "Navigation next - as date format + goto current" ); }); -test("minMax", function() { +test( "minMax", function() { expect( 23 ); var date, - inp = TestHelpers.datepicker.init("#inp"), - dp = $("#ui-datepicker-div"), + inp = TestHelpers.datepicker.init( "#inp" ), + dp = $( "#ui-datepicker-div" ), lastYear = new Date(2007, 6 - 1, 4), nextYear = new Date(2009, 6 - 1, 4), minDate = new Date(2008, 2 - 1, 29), maxDate = new Date(2008, 12 - 1, 7); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), lastYear, - "Min/max - null, null - ctrl+pgup"); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), nextYear, - "Min/max - null, null - ctrl+pgdn"); - inp.datepicker("option", {minDate: minDate}). - datepicker("hide").val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), minDate, - "Min/max - 02/29/2008, null - ctrl+pgup"); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), nextYear, - "Min/max - 02/29/2008, null - ctrl+pgdn"); - inp.datepicker("option", {maxDate: maxDate}). - datepicker("hide").val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), minDate, - "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup"); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), maxDate, - "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn"); - inp.datepicker("option", {minDate: null}). - datepicker("hide").val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), lastYear, - "Min/max - null, 12/07/2008 - ctrl+pgup"); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), maxDate, - "Min/max - null, 12/07/2008 - ctrl+pgdn"); + inp.val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), lastYear, + "Min/max - null, null - ctrl+pgup" ); + inp.val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), nextYear, + "Min/max - null, null - ctrl+pgdn" ); + inp.datepicker( "option", {minDate: minDate}). + datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, + "Min/max - 02/29/2008, null - ctrl+pgup" ); + inp.val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), nextYear, + "Min/max - 02/29/2008, null - ctrl+pgdn" ); + inp.datepicker( "option", {maxDate: maxDate}). + datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, + "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup" ); + inp.val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, + "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn" ); + inp.datepicker( "option", {minDate: null}). + datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), lastYear, + "Min/max - null, 12/07/2008 - ctrl+pgup" ); + inp.val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, + "Min/max - null, 12/07/2008 - ctrl+pgdn" ); // Relative dates date = new Date(); date.setDate(date.getDate() - 7); - inp.datepicker("option", {minDate: "-1w", maxDate: "+1 M +10 D "}). - datepicker("hide").val("").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, - "Min/max - -1w, +1 M +10 D - ctrl+pgup"); + inp.datepicker( "option", {minDate: "-1w", maxDate: "+1 M +10 D "}). + datepicker( "hide" ).val( "" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, + "Min/max - -1w, +1 M +10 D - ctrl+pgup" ); date = TestHelpers.datepicker.addMonths(new Date(), 1); date.setDate(date.getDate() + 10); - inp.val("").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date, - "Min/max - -1w, +1 M +10 D - ctrl+pgdn"); + inp.val( "" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, + "Min/max - -1w, +1 M +10 D - ctrl+pgdn" ); // With existing date - inp = TestHelpers.datepicker.init("#inp"); - inp.val("06/04/2008").datepicker("option", {minDate: minDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate > min"); - inp.datepicker("option", {minDate: null}).val("01/04/2008").datepicker("option", {minDate: minDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), minDate, "Min/max - setDate < min"); - inp.datepicker("option", {minDate: null}).val("06/04/2008").datepicker("option", {maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate < max"); - inp.datepicker("option", {maxDate: null}).val("01/04/2009").datepicker("option", {maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), maxDate, "Min/max - setDate > max"); - inp.datepicker("option", {maxDate: null}).val("01/04/2008").datepicker("option", {minDate: minDate, maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), minDate, "Min/max - setDate < min"); - inp.datepicker("option", {maxDate: null}).val("06/04/2008").datepicker("option", {minDate: minDate, maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate > min, < max"); - inp.datepicker("option", {maxDate: null}).val("01/04/2009").datepicker("option", {minDate: minDate, maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), maxDate, "Min/max - setDate > max"); - - inp.datepicker("option", {yearRange: "-0:+1"}).val("01/01/" + new Date().getFullYear()); - ok(dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - previous button disabled at 1/1/minYear"); - inp.datepicker("setDate", "12/30/" + new Date().getFullYear()); - ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - next button disabled at 12/30/maxYear"); - - inp.datepicker("option", { + inp = TestHelpers.datepicker.init( "#inp" ); + inp.val( "06/04/2008" ).datepicker( "option", {minDate: minDate}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), new Date(2008, 6 - 1, 4), "Min/max - setDate > min" ); + inp.datepicker( "option", {minDate: null}).val( "01/04/2008" ).datepicker( "option", {minDate: minDate}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" ); + inp.datepicker( "option", {minDate: null}).val( "06/04/2008" ).datepicker( "option", {maxDate: maxDate}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), new Date(2008, 6 - 1, 4), "Min/max - setDate < max" ); + inp.datepicker( "option", {maxDate: null}).val( "01/04/2009" ).datepicker( "option", {maxDate: maxDate}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" ); + inp.datepicker( "option", {maxDate: null}).val( "01/04/2008" ).datepicker( "option", {minDate: minDate, maxDate: maxDate}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" ); + inp.datepicker( "option", {maxDate: null}).val( "06/04/2008" ).datepicker( "option", {minDate: minDate, maxDate: maxDate}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), new Date(2008, 6 - 1, 4), "Min/max - setDate > min, < max" ); + inp.datepicker( "option", {maxDate: null}).val( "01/04/2009" ).datepicker( "option", {minDate: minDate, maxDate: maxDate}); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" ); + + inp.datepicker( "option", {yearRange: "-0:+1"}).val( "01/01/" + new Date().getFullYear()); + ok(dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - previous button disabled at 1/1/minYear" ); + inp.datepicker( "setDate", "12/30/" + new Date().getFullYear()); + ok(dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled at 12/30/maxYear" ); + + inp.datepicker( "option", { minDate: new Date(1900, 0, 1), maxDate: "-6Y", yearRange: "1900:-6" }).val( "" ); - ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - next button disabled"); - ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - prev button enabled"); + ok(dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled" ); + ok(!dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - prev button enabled" ); - inp.datepicker("option", { + inp.datepicker( "option", { minDate: new Date(1900, 0, 1), maxDate: "1/25/2007", yearRange: "1900:2007" }).val( "" ); - ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - next button disabled"); - ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - prev button enabled"); + ok(dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled" ); + ok(!dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - prev button enabled" ); }); -test("setDate", function() { +test( "setDate", function() { expect( 24 ); var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, - inp = TestHelpers.datepicker.init("#inp"), + inp = TestHelpers.datepicker.init( "#inp" ), date1 = new Date(2008, 6 - 1, 4), date2 = new Date(); - ok(inp.datepicker("getDate") == null, "Set date - default"); - inp.datepicker("setDate", date1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date1, "Set date - 2008-06-04"); + ok(inp.datepicker( "getDate" ) == null, "Set date - default" ); + inp.datepicker( "setDate", date1); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - 2008-06-04" ); date1 = new Date(); date1.setDate(date1.getDate() + 7); - inp.datepicker("setDate", +7); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date1, "Set date - +7"); + inp.datepicker( "setDate", +7); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - +7" ); date2.setFullYear(date2.getFullYear() + 2); - inp.datepicker("setDate", "+2y"); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date2, "Set date - +2y"); - inp.datepicker("setDate", date1, date2); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date1, "Set date - two dates"); - inp.datepicker("setDate"); - ok(inp.datepicker("getDate") == null, "Set date - null"); + inp.datepicker( "setDate", "+2y" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date2, "Set date - +2y" ); + inp.datepicker( "setDate", date1, date2); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - two dates" ); + inp.datepicker( "setDate" ); + ok(inp.datepicker( "getDate" ) == null, "Set date - null" ); // Relative to current date date1 = new Date(); date1.setDate(date1.getDate() + 7); - inp.datepicker("setDate", "c +7"); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date1, "Set date - c +7"); + inp.datepicker( "setDate", "c +7" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - c +7" ); date1.setDate(date1.getDate() + 7); - inp.datepicker("setDate", "c+7"); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date1, "Set date - c+7"); + inp.datepicker( "setDate", "c+7" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - c+7" ); date1.setDate(date1.getDate() - 21); - inp.datepicker("setDate", "c -3 w"); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date1, "Set date - c -3 w"); + inp.datepicker( "setDate", "c -3 w" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - c -3 w" ); // Inline - inl = TestHelpers.datepicker.init("#inl"); + inl = TestHelpers.datepicker.init( "#inl" ); date1 = new Date(2008, 6 - 1, 4); date2 = new Date(); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), date2, "Set date inline - default"); - inl.datepicker("setDate", date1); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - 2008-06-04"); + TestHelpers.datepicker.equalsDate(inl.datepicker( "getDate" ), date2, "Set date inline - default" ); + inl.datepicker( "setDate", date1); + TestHelpers.datepicker.equalsDate(inl.datepicker( "getDate" ), date1, "Set date inline - 2008-06-04" ); date1 = new Date(); date1.setDate(date1.getDate() + 7); - inl.datepicker("setDate", +7); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - +7"); + inl.datepicker( "setDate", +7); + TestHelpers.datepicker.equalsDate(inl.datepicker( "getDate" ), date1, "Set date inline - +7" ); date2.setFullYear(date2.getFullYear() + 2); - inl.datepicker("setDate", "+2y"); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), date2, "Set date inline - +2y"); - inl.datepicker("setDate", date1, date2); - TestHelpers.datepicker.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - two dates"); - inl.datepicker("setDate"); - ok(inl.datepicker("getDate") == null, "Set date inline - null"); + inl.datepicker( "setDate", "+2y" ); + TestHelpers.datepicker.equalsDate(inl.datepicker( "getDate" ), date2, "Set date inline - +2y" ); + inl.datepicker( "setDate", date1, date2); + TestHelpers.datepicker.equalsDate(inl.datepicker( "getDate" ), date1, "Set date inline - two dates" ); + inl.datepicker( "setDate" ); + ok(inl.datepicker( "getDate" ) == null, "Set date inline - null" ); // Alternate field - alt = $("#alt"); - inp.datepicker("option", {altField: "#alt", altFormat: "yy-mm-dd"}); + alt = $( "#alt" ); + inp.datepicker( "option", {altField: "#alt", altFormat: "yy-mm-dd"}); date1 = new Date(2008, 6 - 1, 4); - inp.datepicker("setDate", date1); - equal(inp.val(), "06/04/2008", "Set date alternate - 06/04/2008"); - equal(alt.val(), "2008-06-04", "Set date alternate - 2008-06-04"); + inp.datepicker( "setDate", date1); + equal(inp.val(), "06/04/2008", "Set date alternate - 06/04/2008" ); + equal(alt.val(), "2008-06-04", "Set date alternate - 2008-06-04" ); // With minimum/maximum - inp = TestHelpers.datepicker.init("#inp"); + inp = TestHelpers.datepicker.init( "#inp" ); date1 = new Date(2008, 1 - 1, 4); date2 = new Date(2008, 6 - 1, 4); minDate = new Date(2008, 2 - 1, 29); maxDate = new Date(2008, 3 - 1, 28); - inp.val("").datepicker("option", {minDate: minDate}).datepicker("setDate", date2); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date2, "Set date min/max - setDate > min"); - inp.datepicker("setDate", date1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), minDate, "Set date min/max - setDate < min"); - inp.val("").datepicker("option", {maxDate: maxDate, minDate: null}).datepicker("setDate", date1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), date1, "Set date min/max - setDate < max"); - inp.datepicker("setDate", date2); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), maxDate, "Set date min/max - setDate > max"); - inp.val("").datepicker("option", {minDate: minDate}).datepicker("setDate", date1); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), minDate, "Set date min/max - setDate < min"); - inp.datepicker("setDate", date2); - TestHelpers.datepicker.equalsDate(inp.datepicker("getDate"), maxDate, "Set date min/max - setDate > max"); + inp.val( "" ).datepicker( "option", {minDate: minDate}).datepicker( "setDate", date2); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date2, "Set date min/max - setDate > min" ); + inp.datepicker( "setDate", date1); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" ); + inp.val( "" ).datepicker( "option", {maxDate: maxDate, minDate: null}).datepicker( "setDate", date1); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date min/max - setDate < max" ); + inp.datepicker( "setDate", date2); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" ); + inp.val( "" ).datepicker( "option", {minDate: minDate}).datepicker( "setDate", date1); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" ); + inp.datepicker( "setDate", date2); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" ); dateAndTimeToSet = new Date(2008, 3 - 1, 28, 1, 11, 0); dateAndTimeClone = new Date(2008, 3 - 1, 28, 1, 11, 0); - inp.datepicker("setDate", dateAndTimeToSet); - equal(dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate"); + inp.datepicker( "setDate", dateAndTimeToSet); + equal(dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate" ); }); -test("altField", function() { +test( "altField", function() { expect( 10 ); - var inp = TestHelpers.datepicker.init("#inp"), - alt = $("#alt"); + var inp = TestHelpers.datepicker.init( "#inp" ), + alt = $( "#alt" ); // No alternate field set - alt.val(""); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(inp.val(), "06/04/2008", "Alt field - dp - enter"); - equal(alt.val(), "", "Alt field - alt not set"); + alt.val( "" ); + inp.val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(inp.val(), "06/04/2008", "Alt field - dp - enter" ); + equal(alt.val(), "", "Alt field - alt not set" ); // Alternate field set - alt.val(""); - inp.datepicker("option", {altField: "#alt", altFormat: "yy-mm-dd"}). - val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(inp.val(), "06/04/2008", "Alt field - dp - enter"); - equal(alt.val(), "2008-06-04", "Alt field - alt - enter"); + alt.val( "" ); + inp.datepicker( "option", {altField: "#alt", altFormat: "yy-mm-dd"}). + val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(inp.val(), "06/04/2008", "Alt field - dp - enter" ); + equal(alt.val(), "2008-06-04", "Alt field - alt - enter" ); // Move from initial date - alt.val(""); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(inp.val(), "07/04/2008", "Alt field - dp - pgdn"); - equal(alt.val(), "2008-07-04", "Alt field - alt - pgdn"); + alt.val( "" ); + inp.val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(inp.val(), "07/04/2008", "Alt field - dp - pgdn" ); + equal(alt.val(), "2008-07-04", "Alt field - alt - pgdn" ); // Alternate field set - closed - alt.val(""); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc"); - equal(alt.val(), "", "Alt field - alt - pgdn/esc"); + alt.val( "" ); + inp.val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc" ); + equal(alt.val(), "", "Alt field - alt - pgdn/esc" ); // Clear date and alternate - alt.val(""); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); - equal(inp.val(), "", "Alt field - dp - ctrl+end"); - equal(alt.val(), "", "Alt field - alt - ctrl+end"); + alt.val( "" ); + inp.val( "06/04/2008" ).datepicker( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); + equal(inp.val(), "", "Alt field - dp - ctrl+end" ); + equal(alt.val(), "", "Alt field - alt - ctrl+end" ); }); -test("autoSize", function() { +test( "autoSize", function() { expect( 15 ); - var inp = TestHelpers.datepicker.init("#inp"); - equal(inp.prop("size"), 20, "Auto size - default"); - inp.datepicker("option", "autoSize", true); - equal(inp.prop("size"), 10, "Auto size - mm/dd/yy"); - inp.datepicker("option", "dateFormat", "m/d/yy"); - equal(inp.prop("size"), 10, "Auto size - m/d/yy"); - inp.datepicker("option", "dateFormat", "D M d yy"); - equal(inp.prop("size"), 15, "Auto size - D M d yy"); - inp.datepicker("option", "dateFormat", "DD, MM dd, yy"); - equal(inp.prop("size"), 29, "Auto size - DD, MM dd, yy"); + var inp = TestHelpers.datepicker.init( "#inp" ); + equal(inp.prop( "size" ), 20, "Auto size - default" ); + inp.datepicker( "option", "autoSize", true); + equal(inp.prop( "size" ), 10, "Auto size - mm/dd/yy" ); + inp.datepicker( "option", "dateFormat", "m/d/yy" ); + equal(inp.prop( "size" ), 10, "Auto size - m/d/yy" ); + inp.datepicker( "option", "dateFormat", "D M d yy" ); + equal(inp.prop( "size" ), 15, "Auto size - D M d yy" ); + inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); + equal(inp.prop( "size" ), 29, "Auto size - DD, MM dd, yy" ); // French - inp.datepicker("option", $.extend({autoSize: false}, $.datepicker.regional.fr)); - equal(inp.prop("size"), 29, "Auto size - fr - default"); - inp.datepicker("option", "autoSize", true); - equal(inp.prop("size"), 10, "Auto size - fr - dd/mm/yy"); - inp.datepicker("option", "dateFormat", "m/d/yy"); - equal(inp.prop("size"), 10, "Auto size - fr - m/d/yy"); - inp.datepicker("option", "dateFormat", "D M d yy"); - equal(inp.prop("size"), 18, "Auto size - fr - D M d yy"); - inp.datepicker("option", "dateFormat", "DD, MM dd, yy"); - equal(inp.prop("size"), 28, "Auto size - fr - DD, MM dd, yy"); + inp.datepicker( "option", $.extend({autoSize: false}, $.datepicker.regional.fr)); + equal(inp.prop( "size" ), 29, "Auto size - fr - default" ); + inp.datepicker( "option", "autoSize", true); + equal(inp.prop( "size" ), 10, "Auto size - fr - dd/mm/yy" ); + inp.datepicker( "option", "dateFormat", "m/d/yy" ); + equal(inp.prop( "size" ), 10, "Auto size - fr - m/d/yy" ); + inp.datepicker( "option", "dateFormat", "D M d yy" ); + equal(inp.prop( "size" ), 18, "Auto size - fr - D M d yy" ); + inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); + equal(inp.prop( "size" ), 28, "Auto size - fr - DD, MM dd, yy" ); // Hebrew - inp.datepicker("option", $.extend({autoSize: false}, $.datepicker.regional.he)); - equal(inp.prop("size"), 28, "Auto size - he - default"); - inp.datepicker("option", "autoSize", true); - equal(inp.prop("size"), 10, "Auto size - he - dd/mm/yy"); - inp.datepicker("option", "dateFormat", "m/d/yy"); - equal(inp.prop("size"), 10, "Auto size - he - m/d/yy"); - inp.datepicker("option", "dateFormat", "D M d yy"); - equal(inp.prop("size"), 16, "Auto size - he - D M d yy"); - inp.datepicker("option", "dateFormat", "DD, MM dd, yy"); - equal(inp.prop("size"), 23, "Auto size - he - DD, MM dd, yy"); + inp.datepicker( "option", $.extend({autoSize: false}, $.datepicker.regional.he)); + equal(inp.prop( "size" ), 28, "Auto size - he - default" ); + inp.datepicker( "option", "autoSize", true); + equal(inp.prop( "size" ), 10, "Auto size - he - dd/mm/yy" ); + inp.datepicker( "option", "dateFormat", "m/d/yy" ); + equal(inp.prop( "size" ), 10, "Auto size - he - m/d/yy" ); + inp.datepicker( "option", "dateFormat", "D M d yy" ); + equal(inp.prop( "size" ), 16, "Auto size - he - D M d yy" ); + inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); + equal(inp.prop( "size" ), 23, "Auto size - he - DD, MM dd, yy" ); }); -test("daylightSaving", function() { +test( "daylightSaving", function() { expect( 25 ); - var inp = TestHelpers.datepicker.init("#inp"), - dp = $("#ui-datepicker-div"); + var inp = TestHelpers.datepicker.init( "#inp" ), + dp = $( "#ui-datepicker-div" ); ok(true, "Daylight saving - " + new Date()); // Australia, Sydney - AM change, southern hemisphere - inp.val("04/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click"); - equal(inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008"); - inp.val("04/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click"); - equal(inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008"); - inp.val("04/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click"); - equal(inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click"); - equal(inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click"); - equal(inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click"); - equal(inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008"); + inp.val( "04/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(6) a", dp).simulate( "click" ); + equal(inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008" ); + inp.val( "04/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(7) a", dp).simulate( "click" ); + equal(inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008" ); + inp.val( "04/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(8) a", dp).simulate( "click" ); + equal(inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008" ); + inp.val( "10/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(6) a", dp).simulate( "click" ); + equal(inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008" ); + inp.val( "10/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(7) a", dp).simulate( "click" ); + equal(inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008" ); + inp.val( "10/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(8) a", dp).simulate( "click" ); + equal(inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008" ); // Brasil, Brasilia - midnight change, southern hemisphere - inp.val("02/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(20) a", dp).simulate("click"); - equal(inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008"); - inp.val("02/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(21) a", dp).simulate("click"); - equal(inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008"); - inp.val("02/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(22) a", dp).simulate("click"); - equal(inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(13) a", dp).simulate("click"); - equal(inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(14) a", dp).simulate("click"); - equal(inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(15) a", dp).simulate("click"); - equal(inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008"); + inp.val( "02/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(20) a", dp).simulate( "click" ); + equal(inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008" ); + inp.val( "02/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(21) a", dp).simulate( "click" ); + equal(inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008" ); + inp.val( "02/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(22) a", dp).simulate( "click" ); + equal(inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008" ); + inp.val( "10/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(13) a", dp).simulate( "click" ); + equal(inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008" ); + inp.val( "10/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(14) a", dp).simulate( "click" ); + equal(inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008" ); + inp.val( "10/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(15) a", dp).simulate( "click" ); + equal(inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008" ); // Lebanon, Beirut - midnight change, northern hemisphere - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(34) a", dp).simulate("click"); - equal(inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008"); - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(35) a", dp).simulate("click"); - equal(inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008"); - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(36) a", dp).simulate("click"); - equal(inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(27) a", dp).simulate("click"); - equal(inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(28) a", dp).simulate("click"); - equal(inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(29) a", dp).simulate("click"); - equal(inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008"); + inp.val( "03/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(34) a", dp).simulate( "click" ); + equal(inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008" ); + inp.val( "03/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(35) a", dp).simulate( "click" ); + equal(inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008" ); + inp.val( "03/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(36) a", dp).simulate( "click" ); + equal(inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008" ); + inp.val( "10/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(27) a", dp).simulate( "click" ); + equal(inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008" ); + inp.val( "10/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(28) a", dp).simulate( "click" ); + equal(inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008" ); + inp.val( "10/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(29) a", dp).simulate( "click" ); + equal(inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008" ); // US, Eastern - AM change, northern hemisphere - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(13) a", dp).simulate("click"); - equal(inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008"); - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(14) a", dp).simulate("click"); - equal(inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008"); - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(15) a", dp).simulate("click"); - equal(inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008"); - inp.val("11/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click"); - equal(inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008"); - inp.val("11/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click"); - equal(inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008"); - inp.val("11/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click"); - equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008"); + inp.val( "03/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(13) a", dp).simulate( "click" ); + equal(inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008" ); + inp.val( "03/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(14) a", dp).simulate( "click" ); + equal(inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008" ); + inp.val( "03/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(15) a", dp).simulate( "click" ); + equal(inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008" ); + inp.val( "11/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(6) a", dp).simulate( "click" ); + equal(inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008" ); + inp.val( "11/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(7) a", dp).simulate( "click" ); + equal(inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008" ); + inp.val( "11/01/2008" ).datepicker( "show" ); + $( ".ui-datepicker-calendar td:eq(8) a", dp).simulate( "click" ); + equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" ); }); var beforeShowThis = null, @@ -928,86 +928,86 @@ function beforeDay(date) { beforeShowDayThis = this; beforeShowDayOK &= (date > new Date(2008, 1 - 1, 26) && date < new Date(2008, 3 - 1, 6)); - return [(date.getDate() % 2 === 0), (date.getDate() % 10 === 0 ? "day10" : ""), - (date.getDate() % 3 === 0 ? "Divisble by 3" : "")]; + return [(date.getDate() % 2 === 0), (date.getDate() % 10 === 0 ? "day10" : "" ), + (date.getDate() % 3 === 0 ? "Divisble by 3" : "" )]; } -test("callbacks", function() { +test( "callbacks", function() { expect( 13 ); // Before show var dp, day20, day21, - inp = TestHelpers.datepicker.init("#inp", {beforeShow: beforeAll}), - inst = $.data(inp[0], "datepicker"); - equal($.datepicker._get(inst, "currentText"), "Today", "Before show - initial"); - inp.val("02/04/2008").datepicker("show"); - equal($.datepicker._get(inst, "currentText"), "Current", "Before show - changed"); - ok(beforeShowThis.id === inp[0].id, "Before show - this OK"); - ok(beforeShowInput.id === inp[0].id, "Before show - input OK"); - deepEqual(beforeShowInst, inst, "Before show - inst OK"); - inp.datepicker("hide").datepicker("destroy"); + inp = TestHelpers.datepicker.init( "#inp", {beforeShow: beforeAll}), + inst = $.data(inp[0], "datepicker" ); + equal($.datepicker._get(inst, "currentText" ), "Today", "Before show - initial" ); + inp.val( "02/04/2008" ).datepicker( "show" ); + equal($.datepicker._get(inst, "currentText" ), "Current", "Before show - changed" ); + ok(beforeShowThis.id === inp[0].id, "Before show - this OK" ); + ok(beforeShowInput.id === inp[0].id, "Before show - input OK" ); + deepEqual(beforeShowInst, inst, "Before show - inst OK" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); // Before show day - inp = TestHelpers.datepicker.init("#inp", {beforeShowDay: beforeDay}); - dp = $("#ui-datepicker-div"); - inp.val("02/04/2008").datepicker("show"); - ok(beforeShowDayThis.id === inp[0].id, "Before show day - this OK"); - ok(beforeShowDayOK, "Before show day - dates OK"); - day20 = dp.find(".ui-datepicker-calendar td:contains('20')"); - day21 = dp.find(".ui-datepicker-calendar td:contains('21')"); - ok(!day20.is(".ui-datepicker-unselectable"), "Before show day - unselectable 20"); - ok(day21.is(".ui-datepicker-unselectable"), "Before show day - unselectable 21"); - ok(day20.is(".day10"), "Before show day - CSS 20"); - ok(!day21.is(".day10"), "Before show day - CSS 21"); - ok(!day20.attr("title"), "Before show day - title 20"); - ok(day21.attr("title") === "Divisble by 3", "Before show day - title 21"); - inp.datepicker("hide").datepicker("destroy"); + inp = TestHelpers.datepicker.init( "#inp", {beforeShowDay: beforeDay}); + dp = $( "#ui-datepicker-div" ); + inp.val( "02/04/2008" ).datepicker( "show" ); + ok(beforeShowDayThis.id === inp[0].id, "Before show day - this OK" ); + ok(beforeShowDayOK, "Before show day - dates OK" ); + day20 = dp.find( ".ui-datepicker-calendar td:contains('20')" ); + day21 = dp.find( ".ui-datepicker-calendar td:contains('21')" ); + ok(!day20.is( ".ui-datepicker-unselectable" ), "Before show day - unselectable 20" ); + ok(day21.is( ".ui-datepicker-unselectable" ), "Before show day - unselectable 21" ); + ok(day20.is( ".day10" ), "Before show day - CSS 20" ); + ok(!day21.is( ".day10" ), "Before show day - CSS 21" ); + ok(!day20.attr( "title" ), "Before show day - title 20" ); + ok(day21.attr( "title" ) === "Divisble by 3", "Before show day - title 21" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); }); -test("beforeShowDay - tooltips with quotes", function() { +test( "beforeShowDay - tooltips with quotes", function() { expect( 1 ); var inp, dp; - inp = TestHelpers.datepicker.init("#inp", { + inp = TestHelpers.datepicker.init( "#inp", { beforeShowDay: function() { return [ true, "", "'" ]; } }); - dp = $("#ui-datepicker-div"); + dp = $( "#ui-datepicker-div" ); - inp.datepicker("show"); - equal( dp.find( ".ui-datepicker-calendar td:contains('9')").attr( "title" ), "'" ); - inp.datepicker("hide").datepicker("destroy"); + inp.datepicker( "show" ); + equal( dp.find( ".ui-datepicker-calendar td:contains('9')" ).attr( "title" ), "'" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); }); -test("localisation", function() { +test( "localisation", function() { expect( 24 ); var dp, month, day, date, - inp = TestHelpers.datepicker.init("#inp", $.datepicker.regional.fr); - inp.datepicker("option", {dateFormat: "DD, d MM yy", showButtonPanel:true, changeMonth:true, changeYear:true}).val("").datepicker("show"); - dp = $("#ui-datepicker-div"); - equal($(".ui-datepicker-close", dp).text(), "Fermer", "Localisation - close"); - $(".ui-datepicker-close", dp).simulate("mouseover"); - equal($(".ui-datepicker-prev", dp).text(), "Précédent", "Localisation - previous"); - equal($(".ui-datepicker-current", dp).text(), "Aujourd'hui", "Localisation - current"); - equal($(".ui-datepicker-next", dp).text(), "Suivant", "Localisation - next"); + inp = TestHelpers.datepicker.init( "#inp", $.datepicker.regional.fr); + inp.datepicker( "option", {dateFormat: "DD, d MM yy", showButtonPanel:true, changeMonth:true, changeYear:true}).val( "" ).datepicker( "show" ); + dp = $( "#ui-datepicker-div" ); + equal($( ".ui-datepicker-close", dp).text(), "Fermer", "Localisation - close" ); + $( ".ui-datepicker-close", dp).simulate( "mouseover" ); + equal($( ".ui-datepicker-prev", dp).text(), "Précédent", "Localisation - previous" ); + equal($( ".ui-datepicker-current", dp).text(), "Aujourd'hui", "Localisation - current" ); + equal($( ".ui-datepicker-next", dp).text(), "Suivant", "Localisation - next" ); month = 0; - $(".ui-datepicker-month option", dp).each(function() { + $( ".ui-datepicker-month option", dp).each(function() { equal($(this).text(), $.datepicker.regional.fr.monthNamesShort[month], "Localisation - month " + month); month++; }); day = 1; - $(".ui-datepicker-calendar th", dp).each(function() { + $( ".ui-datepicker-calendar th", dp).each(function() { equal($(this).text(), $.datepicker.regional.fr.dayNamesMin[day], "Localisation - day " + day); day = (day + 1) % 7; }); - inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); date = new Date(); equal(inp.val(), $.datepicker.regional.fr.dayNames[date.getDay()] + ", " + date.getDate() + " " + $.datepicker.regional.fr.monthNames[date.getMonth()] + - " " + date.getFullYear(), "Localisation - formatting"); + " " + date.getFullYear(), "Localisation - formatting" ); }); -test("noWeekends", function() { +test( "noWeekends", function() { expect( 31 ); var i, date; for (i = 1; i <= 31; i++) { @@ -1017,7 +1017,7 @@ test("noWeekends", function() { } }); -test("iso8601Week", function() { +test( "iso8601Week", function() { expect( 12 ); var date = new Date(2000, 12 - 1, 31); equal($.datepicker.iso8601Week(date), 52, "ISO 8601 week " + date); @@ -1045,74 +1045,74 @@ test("iso8601Week", function() { equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); }); -test("parseDate", function() { +test( "parseDate", function() { expect( 26 ); - TestHelpers.datepicker.init("#inp"); + TestHelpers.datepicker.init( "#inp" ); var currentYear, gmtDate, fr, settings, zh; - ok($.datepicker.parseDate("d m y", "") == null, "Parse date empty"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("d m y", "3 2 01"), - new Date(2001, 2 - 1, 3), "Parse date d m y"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("dd mm yy", "03 02 2001"), - new Date(2001, 2 - 1, 3), "Parse date dd mm yy"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("d m y", "13 12 01"), - new Date(2001, 12 - 1, 13), "Parse date d m y"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("dd mm yy", "13 12 2001"), - new Date(2001, 12 - 1, 13), "Parse date dd mm yy"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("y-o", "01-34"), - new Date(2001, 2 - 1, 3), "Parse date y-o"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("yy-oo", "2001-347"), - new Date(2001, 12 - 1, 13), "Parse date yy-oo"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("oo yy", "348 2004"), - new Date(2004, 12 - 1, 13), "Parse date oo yy"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("D d M y", "Sat 3 Feb 01"), - new Date(2001, 2 - 1, 3), "Parse date D d M y"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("d MM DD yy", "3 February Saturday 2001"), - new Date(2001, 2 - 1, 3), "Parse date dd MM DD yy"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("DD, MM d, yy", "Saturday, February 3, 2001"), - new Date(2001, 2 - 1, 3), "Parse date DD, MM d, yy"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("'day' d 'of' MM (''DD''), yy", - "day 3 of February ('Saturday'), 2001"), new Date(2001, 2 - 1, 3), - "Parse date 'day' d 'of' MM (''DD''), yy"); + ok($.datepicker.parseDate( "d m y", "" ) == null, "Parse date empty" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "d m y", "3 2 01" ), + new Date(2001, 2 - 1, 3), "Parse date d m y" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "dd mm yy", "03 02 2001" ), + new Date(2001, 2 - 1, 3), "Parse date dd mm yy" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "d m y", "13 12 01" ), + new Date(2001, 12 - 1, 13), "Parse date d m y" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "dd mm yy", "13 12 2001" ), + new Date(2001, 12 - 1, 13), "Parse date dd mm yy" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-o", "01-34" ), + new Date(2001, 2 - 1, 3), "Parse date y-o" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "yy-oo", "2001-347" ), + new Date(2001, 12 - 1, 13), "Parse date yy-oo" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "oo yy", "348 2004" ), + new Date(2004, 12 - 1, 13), "Parse date oo yy" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "D d M y", "Sat 3 Feb 01" ), + new Date(2001, 2 - 1, 3), "Parse date D d M y" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "d MM DD yy", "3 February Saturday 2001" ), + new Date(2001, 2 - 1, 3), "Parse date dd MM DD yy" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "DD, MM d, yy", "Saturday, February 3, 2001" ), + new Date(2001, 2 - 1, 3), "Parse date DD, MM d, yy" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy", + "day 3 of February ('Saturday'), 2001" ), new Date(2001, 2 - 1, 3), + "Parse date 'day' d 'of' MM (''DD''), yy" ); currentYear = new Date().getFullYear(); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000) + "-02-03"), - new Date(currentYear, 2 - 1, 3), "Parse date y-m-d - default cutuff"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 10) + "-02-03"), - new Date(currentYear+10, 2 - 1, 3), "Parse date y-m-d - default cutuff"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 11) + "-02-03"), - new Date(currentYear-89, 2 - 1, 3), "Parse date y-m-d - default cutuff"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("y-m-d", "80-02-03", {shortYearCutoff: 80}), - new Date(2080, 2 - 1, 3), "Parse date y-m-d - cutoff 80"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("y-m-d", "81-02-03", {shortYearCutoff: 80}), - new Date(1981, 2 - 1, 3), "Parse date y-m-d - cutoff 80"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 60) + "-02-03", {shortYearCutoff: "+60"}), - new Date(currentYear + 60, 2 - 1, 3), "Parse date y-m-d - cutoff +60"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 61) + "-02-03", {shortYearCutoff: "+60"}), - new Date(currentYear - 39, 2 - 1, 3), "Parse date y-m-d - cutoff +60"); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000) + "-02-03" ), + new Date(currentYear, 2 - 1, 3), "Parse date y-m-d - default cutuff" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000 + 10) + "-02-03" ), + new Date(currentYear+10, 2 - 1, 3), "Parse date y-m-d - default cutuff" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000 + 11) + "-02-03" ), + new Date(currentYear-89, 2 - 1, 3), "Parse date y-m-d - default cutuff" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", "80-02-03", {shortYearCutoff: 80}), + new Date(2080, 2 - 1, 3), "Parse date y-m-d - cutoff 80" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", "81-02-03", {shortYearCutoff: 80}), + new Date(1981, 2 - 1, 3), "Parse date y-m-d - cutoff 80" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000 + 60) + "-02-03", {shortYearCutoff: "+60"}), + new Date(currentYear + 60, 2 - 1, 3), "Parse date y-m-d - cutoff +60" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000 + 61) + "-02-03", {shortYearCutoff: "+60"}), + new Date(currentYear - 39, 2 - 1, 3), "Parse date y-m-d - cutoff +60" ); gmtDate = new Date(2001, 2 - 1, 3); gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("@", "981158400000"), gmtDate, "Parse date @"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("!", "631167552000000000"), gmtDate, "Parse date !"); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "@", "981158400000" ), gmtDate, "Parse date @" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "!", "631167552000000000" ), gmtDate, "Parse date !" ); fr = $.datepicker.regional.fr; settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("D d M y", "Lun. 9 Avril 01", settings), - new Date(2001, 4 - 1, 9), "Parse date D M y with settings"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("d MM DD yy", "9 Avril Lundi 2001", settings), - new Date(2001, 4 - 1, 9), "Parse date d MM DD yy with settings"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("DD, MM d, yy", "Lundi, Avril 9, 2001", settings), - new Date(2001, 4 - 1, 9), "Parse date DD, MM d, yy with settings"); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings), - new Date(2001, 4 - 1, 9), "Parse date 'jour' d 'de' MM (''DD''), yy with settings"); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "D d M y", "Lun. 9 Avril 01", settings), + new Date(2001, 4 - 1, 9), "Parse date D M y with settings" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "d MM DD yy", "9 Avril Lundi 2001", settings), + new Date(2001, 4 - 1, 9), "Parse date d MM DD yy with settings" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "DD, MM d, yy", "Lundi, Avril 9, 2001", settings), + new Date(2001, 4 - 1, 9), "Parse date DD, MM d, yy with settings" ); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings), + new Date(2001, 4 - 1, 9), "Parse date 'jour' d 'de' MM (''DD''), yy with settings" ); zh = $.datepicker.regional["zh-CN"]; - TestHelpers.datepicker.equalsDate($.datepicker.parseDate("yy M d", "2011 十一月 22", zh), - new Date(2011, 11 - 1, 22), "Parse date yy M d with zh-CN"); + TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "yy M d", "2011 十一月 22", zh), + new Date(2011, 11 - 1, 22), "Parse date yy M d with zh-CN" ); }); -test("parseDateErrors", function() { +test( "parseDateErrors", function() { expect( 17 ); - TestHelpers.datepicker.init("#inp"); + TestHelpers.datepicker.init( "#inp" ); var fr, settings; function expectError(expr, value, error) { try { @@ -1123,114 +1123,114 @@ test("parseDateErrors", function() { equal(e, error, "Parsed error " + value); } } - expectError(function() { $.datepicker.parseDate(null, "Sat 2 01"); }, - "Sat 2 01", "Invalid arguments"); - expectError(function() { $.datepicker.parseDate("d m y", null); }, - "null", "Invalid arguments"); - expectError(function() { $.datepicker.parseDate("d m y", "Sat 2 01"); }, - "Sat 2 01 - d m y", "Missing number at position 0"); - expectError(function() { $.datepicker.parseDate("dd mm yy", "Sat 2 01"); }, - "Sat 2 01 - dd mm yy", "Missing number at position 0"); - expectError(function() { $.datepicker.parseDate("d m y", "3 Feb 01"); }, - "3 Feb 01 - d m y", "Missing number at position 2"); - expectError(function() { $.datepicker.parseDate("dd mm yy", "3 Feb 01"); }, - "3 Feb 01 - dd mm yy", "Missing number at position 2"); - expectError(function() { $.datepicker.parseDate("d m y", "3 2 AD01"); }, - "3 2 AD01 - d m y", "Missing number at position 4"); - expectError(function() { $.datepicker.parseDate("d m yy", "3 2 AD01"); }, - "3 2 AD01 - dd mm yy", "Missing number at position 4"); - expectError(function() { $.datepicker.parseDate("y-o", "01-D01"); }, - "2001-D01 - y-o", "Missing number at position 3"); - expectError(function() { $.datepicker.parseDate("yy-oo", "2001-D01"); }, - "2001-D01 - yy-oo", "Missing number at position 5"); - expectError(function() { $.datepicker.parseDate("D d M y", "D7 3 Feb 01"); }, - "D7 3 Feb 01 - D d M y", "Unknown name at position 0"); - expectError(function() { $.datepicker.parseDate("D d M y", "Sat 3 M2 01"); }, - "Sat 3 M2 01 - D d M y", "Unknown name at position 6"); - expectError(function() { $.datepicker.parseDate("DD, MM d, yy", "Saturday- Feb 3, 2001"); }, - "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8"); - expectError(function() { $.datepicker.parseDate("'day' d 'of' MM (''DD''), yy", - "day 3 of February (\"Saturday\"), 2001"); }, - "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19"); - expectError(function() { $.datepicker.parseDate("d m y", "29 2 01"); }, - "29 2 01 - d m y", "Invalid date"); + expectError(function() { $.datepicker.parseDate(null, "Sat 2 01" ); }, + "Sat 2 01", "Invalid arguments" ); + expectError(function() { $.datepicker.parseDate( "d m y", null); }, + "null", "Invalid arguments" ); + expectError(function() { $.datepicker.parseDate( "d m y", "Sat 2 01" ); }, + "Sat 2 01 - d m y", "Missing number at position 0" ); + expectError(function() { $.datepicker.parseDate( "dd mm yy", "Sat 2 01" ); }, + "Sat 2 01 - dd mm yy", "Missing number at position 0" ); + expectError(function() { $.datepicker.parseDate( "d m y", "3 Feb 01" ); }, + "3 Feb 01 - d m y", "Missing number at position 2" ); + expectError(function() { $.datepicker.parseDate( "dd mm yy", "3 Feb 01" ); }, + "3 Feb 01 - dd mm yy", "Missing number at position 2" ); + expectError(function() { $.datepicker.parseDate( "d m y", "3 2 AD01" ); }, + "3 2 AD01 - d m y", "Missing number at position 4" ); + expectError(function() { $.datepicker.parseDate( "d m yy", "3 2 AD01" ); }, + "3 2 AD01 - dd mm yy", "Missing number at position 4" ); + expectError(function() { $.datepicker.parseDate( "y-o", "01-D01" ); }, + "2001-D01 - y-o", "Missing number at position 3" ); + expectError(function() { $.datepicker.parseDate( "yy-oo", "2001-D01" ); }, + "2001-D01 - yy-oo", "Missing number at position 5" ); + expectError(function() { $.datepicker.parseDate( "D d M y", "D7 3 Feb 01" ); }, + "D7 3 Feb 01 - D d M y", "Unknown name at position 0" ); + expectError(function() { $.datepicker.parseDate( "D d M y", "Sat 3 M2 01" ); }, + "Sat 3 M2 01 - D d M y", "Unknown name at position 6" ); + expectError(function() { $.datepicker.parseDate( "DD, MM d, yy", "Saturday- Feb 3, 2001" ); }, + "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8" ); + expectError(function() { $.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy", + "day 3 of February (\"Saturday\" ), 2001" ); }, + "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19" ); + expectError(function() { $.datepicker.parseDate( "d m y", "29 2 01" ); }, + "29 2 01 - d m y", "Invalid date" ); fr = $.datepicker.regional.fr; settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; - expectError(function() { $.datepicker.parseDate("D d M y", "Mon 9 Avr 01", settings); }, - "Mon 9 Avr 01 - D d M y", "Unknown name at position 0"); - expectError(function() { $.datepicker.parseDate("D d M y", "Lun. 9 Apr 01", settings); }, - "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7"); + expectError(function() { $.datepicker.parseDate( "D d M y", "Mon 9 Avr 01", settings); }, + "Mon 9 Avr 01 - D d M y", "Unknown name at position 0" ); + expectError(function() { $.datepicker.parseDate( "D d M y", "Lun. 9 Apr 01", settings); }, + "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7" ); }); -test("Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function() { +test( "Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function() { expect( 4 ); var date; try{ - date = $.datepicker.parseDate("dd/mm/yy", "18/04/19881"); - ok(false, "Did not properly detect an invalid date"); + date = $.datepicker.parseDate( "dd/mm/yy", "18/04/19881" ); + ok(false, "Did not properly detect an invalid date" ); }catch(e){ - ok("invalid date detected"); + ok( "invalid date detected" ); } try { - date = $.datepicker.parseDate("dd/mm/yy", "18/04/1988 @ 2:43 pm"); + date = $.datepicker.parseDate( "dd/mm/yy", "18/04/1988 @ 2:43 pm" ); equal(date.getDate(), 18); equal(date.getMonth(), 3); equal(date.getFullYear(), 1988); } catch(e) { - ok(false, "Did not properly parse date with extra text separated by whitespace"); + ok(false, "Did not properly parse date with extra text separated by whitespace" ); } }); -test("formatDate", function() { +test( "formatDate", function() { expect( 16 ); - TestHelpers.datepicker.init("#inp"); + TestHelpers.datepicker.init( "#inp" ); var gmtDate, fr, settings; - equal($.datepicker.formatDate("d m y", new Date(2001, 2 - 1, 3)), - "3 2 01", "Format date d m y"); - equal($.datepicker.formatDate("dd mm yy", new Date(2001, 2 - 1, 3)), - "03 02 2001", "Format date dd mm yy"); - equal($.datepicker.formatDate("d m y", new Date(2001, 12 - 1, 13)), - "13 12 01", "Format date d m y"); - equal($.datepicker.formatDate("dd mm yy", new Date(2001, 12 - 1, 13)), - "13 12 2001", "Format date dd mm yy"); - equal($.datepicker.formatDate("yy-o", new Date(2001, 2 - 1, 3)), - "2001-34", "Format date yy-o"); - equal($.datepicker.formatDate("yy-oo", new Date(2001, 2 - 1, 3)), - "2001-034", "Format date yy-oo"); - equal($.datepicker.formatDate("D M y", new Date(2001, 2 - 1, 3)), - "Sat Feb 01", "Format date D M y"); - equal($.datepicker.formatDate("DD MM yy", new Date(2001, 2 - 1, 3)), - "Saturday February 2001", "Format date DD MM yy"); - equal($.datepicker.formatDate("DD, MM d, yy", new Date(2001, 2 - 1, 3)), - "Saturday, February 3, 2001", "Format date DD, MM d, yy"); - equal($.datepicker.formatDate("'day' d 'of' MM (''DD''), yy", + equal($.datepicker.formatDate( "d m y", new Date(2001, 2 - 1, 3)), + "3 2 01", "Format date d m y" ); + equal($.datepicker.formatDate( "dd mm yy", new Date(2001, 2 - 1, 3)), + "03 02 2001", "Format date dd mm yy" ); + equal($.datepicker.formatDate( "d m y", new Date(2001, 12 - 1, 13)), + "13 12 01", "Format date d m y" ); + equal($.datepicker.formatDate( "dd mm yy", new Date(2001, 12 - 1, 13)), + "13 12 2001", "Format date dd mm yy" ); + equal($.datepicker.formatDate( "yy-o", new Date(2001, 2 - 1, 3)), + "2001-34", "Format date yy-o" ); + equal($.datepicker.formatDate( "yy-oo", new Date(2001, 2 - 1, 3)), + "2001-034", "Format date yy-oo" ); + equal($.datepicker.formatDate( "D M y", new Date(2001, 2 - 1, 3)), + "Sat Feb 01", "Format date D M y" ); + equal($.datepicker.formatDate( "DD MM yy", new Date(2001, 2 - 1, 3)), + "Saturday February 2001", "Format date DD MM yy" ); + equal($.datepicker.formatDate( "DD, MM d, yy", new Date(2001, 2 - 1, 3)), + "Saturday, February 3, 2001", "Format date DD, MM d, yy" ); + equal($.datepicker.formatDate( "'day' d 'of' MM (''DD''), yy", new Date(2001, 2 - 1, 3)), "day 3 of February ('Saturday'), 2001", - "Format date 'day' d 'of' MM ('DD'), yy"); + "Format date 'day' d 'of' MM ('DD'), yy" ); gmtDate = new Date(2001, 2 - 1, 3); - gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); - equal($.datepicker.formatDate("@", gmtDate), "981158400000", "Format date @"); - equal($.datepicker.formatDate("!", gmtDate), "631167552000000000", "Format date !"); + gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() ); + equal($.datepicker.formatDate( "@", gmtDate), "981158400000", "Format date @" ); + equal($.datepicker.formatDate( "!", gmtDate), "631167552000000000", "Format date !" ); fr = $.datepicker.regional.fr; settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; - equal($.datepicker.formatDate("D M y", new Date(2001, 4 - 1, 9), settings), - "lun. avril 01", "Format date D M y with settings"); - equal($.datepicker.formatDate("DD MM yy", new Date(2001, 4 - 1, 9), settings), - "lundi avril 2001", "Format date DD MM yy with settings"); - equal($.datepicker.formatDate("DD, MM d, yy", new Date(2001, 4 - 1, 9), settings), - "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings"); - equal($.datepicker.formatDate("'jour' d 'de' MM (''DD''), yy", + equal($.datepicker.formatDate( "D M y", new Date(2001, 4 - 1, 9), settings), + "lun. avril 01", "Format date D M y with settings" ); + equal($.datepicker.formatDate( "DD MM yy", new Date(2001, 4 - 1, 9), settings), + "lundi avril 2001", "Format date DD MM yy with settings" ); + equal($.datepicker.formatDate( "DD, MM d, yy", new Date(2001, 4 - 1, 9), settings), + "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings" ); + equal($.datepicker.formatDate( "'jour' d 'de' MM (''DD''), yy", new Date(2001, 4 - 1, 9), settings), "jour 9 de avril ('lundi'), 2001", - "Format date 'jour' d 'de' MM (''DD''), yy with settings"); + "Format date 'jour' d 'de' MM (''DD''), yy with settings" ); }); // TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos -// test("Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ +// test( "Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ // expect( 1 ); -// var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT")); -// equal(time, "089"); +// var time = $.datepicker.formatDate( "oo", new Date( "2010/03/30 12:00:00 CDT" )); +// equal(time, "089" ); // }); test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function() { @@ -1265,7 +1265,7 @@ test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler }); dp = $( "#ui-datepicker-div" ); inp.datepicker( "show" ); - equal( dp.css( "display" ), "none","beforeShow returns false" ); + equal( dp.css( "display" ), "none", "beforeShow returns false" ); inp.datepicker( "destroy" ); }); */ diff --git a/tests/unit/datepicker/datepicker_test_helpers.js b/tests/unit/datepicker/datepicker_test_helpers.js index 060c6bf9505..1d922c72220 100644 --- a/tests/unit/datepicker/datepicker_test_helpers.js +++ b/tests/unit/datepicker/datepicker_test_helpers.js @@ -1,18 +1,18 @@ TestHelpers.datepicker = { - addMonths: function(date, offset) { - var maxDay = 32 - new Date(date.getFullYear(), date.getMonth() + offset, 32).getDate(); - date.setDate(Math.min(date.getDate(), maxDay)); - date.setMonth(date.getMonth() + offset); + addMonths: function( date, offset ) { + var maxDay = 32 - new Date( date.getFullYear(), date.getMonth() + offset, 32 ).getDate(); + date.setDate( Math.min( date.getDate(), maxDay ) ); + date.setMonth( date.getMonth() + offset ); return date; }, - equalsDate: function(d1, d2, message) { - if (!d1 || !d2) { - ok(false, message + " - missing date"); + equalsDate: function( d1, d2, message ) { + if ( !d1 || !d2 ) { + ok( false, message + " - missing date" ); return; } - d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()); - d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate()); - equal(d1.toString(), d2.toString(), message); + d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() ); + d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() ); + equal( d1.toString(), d2.toString(), message ); }, init: function( id, options ) { options = $.extend( { show: false }, options || {} ); diff --git a/ui/datepicker.js b/ui/datepicker.js index bd50d075c6c..4860dbace32 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -52,6 +52,7 @@ return $.widget( "ui.datepicker", { open: null, select: null }, + _create: function() { this.options.dateFormat = this.options.dateFormat || { date: "short" }; this.date = $.date( null, this.options.dateFormat ); @@ -103,6 +104,7 @@ return $.widget( "ui.datepicker", { this._createTmpl(); }, + _handleKeydown: function( event ) { if ( jQuery.inArray( event.keyCode, [ 13, 33, 34, 35, 36, 37, 38, 39, 40 ] ) === -1 ) { //only interested navigation keys @@ -154,7 +156,7 @@ return $.widget( "ui.datepicker", { } else { newId = this.id + "-" + this.date.day(); - newCell = $("#" + newId); + newCell = $( "#" + newId ); // TODO unnecessary optimization? is it really needed? if ( !newCell.length ) { @@ -166,6 +168,7 @@ return $.widget( "ui.datepicker", { newCell.children( "a" ).addClass( "ui-state-focus" ); } }, + _createPicker: function() { this.picker = $( "
        " ) .addClass( "ui-front" ) @@ -199,10 +202,10 @@ return $.widget( "ui.datepicker", { case $.ui.keyCode.DOWN: case $.ui.keyCode.UP: clearTimeout( this.closeTimer ); - this._delay(function() { + this._delay( function() { this.open( event ); this.grid.focus( 1 ); - }, 1); + }, 1 ); break; case $.ui.keyCode.HOME: if ( event.ctrlKey ) { @@ -251,7 +254,7 @@ return $.widget( "ui.datepicker", { } this._delay( function() { suppressExpandOnFocus = false; - }, 100); + }, 100 ); }, blur: function() { suppressExpandOnFocus = false; @@ -265,7 +268,7 @@ return $.widget( "ui.datepicker", { // also allows tabbing inside the calendar without it closing this.closeTimer = this._delay( function() { this.close( event ); - }, 150); + }, 150 ); }, focusin: function() { clearTimeout( this.closeTimer ); @@ -290,6 +293,7 @@ return $.widget( "ui.datepicker", { } }); }, + _appendTo: function() { var element = this.options.appendTo; @@ -304,7 +308,7 @@ return $.widget( "ui.datepicker", { } if ( !element.length ) { - element = this.document[0].body; + element = this.document[ 0 ].body; } return element; @@ -357,10 +361,10 @@ return $.widget( "ui.datepicker", { html += "
        " + "
        "; - if ( months[i].first ) { + if ( months[ i ].first ) { html += this._buildPreviousLink(); } - if ( months[i].last ) { + if ( months[ i ].last ) { html += this._buildNextLink(); } @@ -374,8 +378,10 @@ return $.widget( "ui.datepicker", { html += this._buildButtons(); this.date = currentDate; + return html; }, + _buildHeader: function() { return "
        " + this._buildPreviousLink() + @@ -383,8 +389,10 @@ return $.widget( "ui.datepicker", { this._buildTitlebar() + "
        "; }, + _buildPreviousLink: function() { var labels = Globalize.translate( "datepicker" ); + return ""; }, + _buildNextLink: function() { var labels = Globalize.translate( "datepicker" ); + return ""; }, + _buildTitlebar: function() { var labels = Globalize.translate( "datepicker" ); + return "
        " + "
        " + this._buildTitle() + @@ -410,6 +422,7 @@ return $.widget( "ui.datepicker", { ", " + labels.datePickerRole + "" + "
        "; }, + _buildTitle: function() { return "" + this.date.monthName() + @@ -418,6 +431,7 @@ return $.widget( "ui.datepicker", { this.date.year() + ""; }, + _buildGrid: function() { return "" + @@ -425,6 +439,7 @@ return $.widget( "ui.datepicker", { this._buildGridBody() + "
        "; }, + _buildGridHeading: function() { var cells = "", i = 0, @@ -436,10 +451,12 @@ return $.widget( "ui.datepicker", { for ( i; i < this.date.weekdays().length; i++ ) { cells += this._buildGridHeaderCell( this.date.weekdays()[i] ); } + return "" + "" + cells + "" + ""; }, + _buildGridHeaderCell: function( day ) { return "" + "" + @@ -447,16 +464,20 @@ return $.widget( "ui.datepicker", { "" + ""; }, + _buildGridBody: function() { // this.date.days() is not cached, and it has O(n^2) complexity. It is run O(n) times. So, it equals O(n^3). Not good at all. Caching. var days = this.date.days(), i = 0, rows = ""; + for ( i; i < days.length; i++ ) { - rows += this._buildWeekRow( days[i] ); + rows += this._buildWeekRow( days[ i ] ); } + return "" + rows + ""; }, + _buildWeekRow: function( week ) { var cells = "", i = 0; @@ -469,6 +490,7 @@ return $.widget( "ui.datepicker", { } return "" + cells + ""; }, + _buildDayCell: function( day ) { var contents = "", idAttribute = day.render ? ( "id=" + this.id + "-" + day.date ) : "", @@ -487,6 +509,7 @@ return $.widget( "ui.datepicker", { contents + ""; }, + _buildDayLink: function( day ) { var link, classes = [ "ui-state-default" ], @@ -510,10 +533,13 @@ return $.widget( "ui.datepicker", { if ( day.today ) { link += ", " + labels.currentText + ""; } + return link; }, + _buildDayDisplay: function( day ) { var classes = []; + if ( day.current ) { classes.push( "ui-state-active" ); } @@ -524,20 +550,23 @@ return $.widget( "ui.datepicker", { classes.push( day.extraClasses.split( " " ) ); } - return "" + - day.date + ""; + return "" + day.date + ""; }, + _buildButtons: function() { var labels = Globalize.translate( "datepicker" ); + return "
        " + "" + "" + "
        "; }, + _focusTrigger: function() { suppressExpandOnFocus = true; this.element.focus(); }, + // Refreshing the entire datepicker during interaction confuses screen readers, specifically // because the grid heading is marked up as a live region and will often not update if it's // destroyed and recreated instead of just having its text change. Additionally, interacting @@ -554,6 +583,7 @@ return $.widget( "ui.datepicker", { this._refreshMultiplePicker(); } }, + _refreshMultiplePicker: function() { var i = 0; @@ -568,6 +598,7 @@ return $.widget( "ui.datepicker", { // to maintain the currently focused grid and base queries like this off of it. $( this.picker ).find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" ); }, + open: function( event ) { if ( this.inline || this.isOpen ) { return; @@ -598,6 +629,7 @@ return $.widget( "ui.datepicker", { this._trigger( "open", event ); }, + close: function( event ) { if ( this.inline ) { return; @@ -611,16 +643,19 @@ return $.widget( "ui.datepicker", { this.isOpen = false; this._trigger( "close", event ); }, + _setHiddenPicker: function() { this.picker .attr( "aria-hidden", "true" ) .attr( "aria-expanded", "false" ); }, + _buildPosition: function() { return $.extend( {}, { of: this.element }, this.options.position ); }, + select: function( event, time ) { this.date.setTime( time ).select(); this.refresh(); @@ -634,6 +669,7 @@ return $.widget( "ui.datepicker", { date: this.date.format() }); }, + _value: function( value ) { this.date.setTime( value ).select(); if ( !this.inline ) { @@ -641,6 +677,7 @@ return $.widget( "ui.datepicker", { } this.refresh(); }, + value: function( value ) { if ( arguments.length ) { this._value( value ); @@ -648,6 +685,7 @@ return $.widget( "ui.datepicker", { return this.isValid() ? this.date.format() : this.element.val(); } }, + valueAsDate: function( value ) { if ( arguments.length ) { this._value( value ); @@ -655,12 +693,15 @@ return $.widget( "ui.datepicker", { return this.isValid() ? this.date.date() : null; } }, + isValid: function() { if ( this.inline ) { return true; } + return Globalize.parseDate( this.element.val(), this.options.dateFormat ) !== null; }, + _destroy: function() { if ( this.inline ) { this.picker.empty(); @@ -671,9 +712,11 @@ return $.widget( "ui.datepicker", { .removeAttr( "aria-owns" ); } }, + widget: function() { return this.picker; }, + _setOption: function( key, value ) { this._super( key, value ); From 036190e40eda4a48beda247da16bd329870ddd70 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 13:30:09 +0200 Subject: [PATCH 060/172] Datepicker: rename select method to _select Make select() a private method as it's not part of the specification. --- ui/datepicker.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 4860dbace32..0d46991e088 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -79,7 +79,7 @@ return $.widget( "ui.datepicker", { }, "click .ui-datepicker-current": function( event ) { event.preventDefault(); - this.select( event, new Date().getTime() ); + this._select( event, new Date().getTime() ); }, "click .ui-datepicker-close": function( event ) { event.preventDefault(); @@ -89,7 +89,7 @@ return $.widget( "ui.datepicker", { event.preventDefault(); // TODO exclude clicks on lead days or handle them correctly // TODO store/read more then just date, also required for multi month picker - this.select( event, $( event.currentTarget ).data( "timestamp" ) ); + this._select( event, $( event.currentTarget ).data( "timestamp" ) ); if ( this.inline ) { this.grid.focus( 1 ); } @@ -656,7 +656,7 @@ return $.widget( "ui.datepicker", { }, this.options.position ); }, - select: function( event, time ) { + _select: function( event, time ) { this.date.setTime( time ).select(); this.refresh(); if ( !this.inline ) { From 6ee2cd5f8e7526cd991655887c2c50489cdc01d0 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 14:05:56 +0200 Subject: [PATCH 061/172] Datepicker: fix and simplify icon trigger demo --- demos/datepicker/icon-trigger.html | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index 36b35a4cb32..05263228cc0 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -16,21 +16,13 @@ From 7175e0df6afdde2c2568f24b1aec9caa2fe31ed8 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 14:31:28 +0200 Subject: [PATCH 062/172] Datepicker: use short instead of abbreviated format for table header Revert to old behavior with two instead of three chars. Fixes layout issue with wrong day table cell width. --- external/date.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/date.js b/external/date.js index 101afb17581..4565c04223e 100644 --- a/external/date.js +++ b/external/date.js @@ -125,7 +125,7 @@ $.date.prototype = { for ( var dow = 0; dow < 7; dow++ ) { var day = ( dow + weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] ) % 7; result.push({ - shortname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/abbreviated", weekdays[ day ] ]), + shortname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/short", weekdays[ day ] ]), fullname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/wide", weekdays[ day ] ]), }); } From 291476606a99574e82c6ff5c69dea2d1cdfe51a8 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 14:34:02 +0200 Subject: [PATCH 063/172] Datepicker: remove unneeded comma --- external/date.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/date.js b/external/date.js index 4565c04223e..06a67553205 100644 --- a/external/date.js +++ b/external/date.js @@ -126,7 +126,7 @@ $.date.prototype = { var day = ( dow + weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] ) % 7; result.push({ shortname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/short", weekdays[ day ] ]), - fullname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/wide", weekdays[ day ] ]), + fullname: Globalize.locale().main([ "dates/calendars/gregorian/days/format/wide", weekdays[ day ] ]) }); } return result; From c3a2b1ba25fa550c5518d1499d8fc83fac15b5b0 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 14:44:31 +0200 Subject: [PATCH 064/172] Datepicker: remove unneeded default setting of option dateFormat --- ui/datepicker.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 0d46991e088..80b407b1ba2 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -34,7 +34,7 @@ var idIncrement = 0, return $.widget( "ui.datepicker", { options: { appendTo: null, - dateFormat: null, + dateFormat: { date: "short" }, // TODO review eachDay: $.noop, numberOfMonths: 1, @@ -54,7 +54,6 @@ return $.widget( "ui.datepicker", { }, _create: function() { - this.options.dateFormat = this.options.dateFormat || { date: "short" }; this.date = $.date( null, this.options.dateFormat ); this.date.eachDay = this.options.eachDay; From 37368080b49b8756d5a53e5fca47b3bf71e27e7c Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 15:07:32 +0200 Subject: [PATCH 065/172] Datepicker: fix populate alternate field demo --- demos/datepicker/alt-field.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demos/datepicker/alt-field.html b/demos/datepicker/alt-field.html index 645d4b6b9e4..47d3d9f8984 100644 --- a/demos/datepicker/alt-field.html +++ b/demos/datepicker/alt-field.html @@ -18,8 +18,8 @@ $(function() { $( "#datepicker" ).datepicker({ select: function( event, ui ) { - var date = Globalize.parseDate( ui.date ); - $( "#alternate" ).val( Globalize.format( date, "dddd, d MMMM, yyyy" ) ); + var date = Globalize.parseDate( ui.date, { date: "short" } ); + $( "#alternate" ).val( Globalize.format( date, { date: "long" } ) ); } }); }); From 8d9f5db21098ca4d6b399d8caf3bbbda8590ce31 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 15:36:46 +0200 Subject: [PATCH 066/172] Datepicker: adjust date.js day name unit test to short name change --- tests/unit/date/date_core.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/unit/date/date_core.js b/tests/unit/date/date_core.js index db94cb67d56..65665431c32 100644 --- a/tests/unit/date/date_core.js +++ b/tests/unit/date/date_core.js @@ -64,13 +64,13 @@ test( "Date Adjustments - Leap Year Edge Cases", 1, function() { test( "List days of Week", 2, function() { var date = $.date(), offset0 = [ - { "fullname": "Sunday", "shortname": "Sun" }, - { "fullname": "Monday", "shortname": "Mon" }, - { "fullname": "Tuesday", "shortname": "Tue" }, - { "fullname": "Wednesday", "shortname": "Wed" }, - { "fullname": "Thursday", "shortname": "Thu" }, - { "fullname": "Friday", "shortname": "Fri" }, - { "fullname": "Saturday", "shortname": "Sat" } + { "fullname": "Sunday", "shortname": "Su" }, + { "fullname": "Monday", "shortname": "Mo" }, + { "fullname": "Tuesday", "shortname": "Tu" }, + { "fullname": "Wednesday", "shortname": "We" }, + { "fullname": "Thursday", "shortname": "Th" }, + { "fullname": "Friday", "shortname": "Fr" }, + { "fullname": "Saturday", "shortname": "Sa" } ], offset1 = [ { "fullname": "Montag", "shortname": "Mo." }, From cd96b4c6db0b0e5cbef1df7aa7873394a5324224 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 28 Apr 2014 17:07:03 +0200 Subject: [PATCH 067/172] Datepicker: restore old icon trigger demo behavior --- demos/datepicker/icon-trigger.html | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index 05263228cc0..4631e900cc0 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -16,12 +16,21 @@ From 49728a9a9c7164781c35eee606ec77c0b8e1ab06 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 16 May 2014 00:19:32 +0200 Subject: [PATCH 068/172] Datepicker: Introduce value option Change status caching, fix existing value related methods, introduce $.date construction with date object, add selected getter --- external/date.js | 6 ++++ ui/datepicker.js | 85 +++++++++++++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/external/date.js b/external/date.js index 06a67553205..bad6679ec40 100644 --- a/external/date.js +++ b/external/date.js @@ -26,6 +26,9 @@ $.date = function( date, globalFormat ) { if ( typeof date === "string" && date.length ) { this.dateObject = Globalize.parseDate( date, globalFormat ); } + if ( date instanceof Date ) { + this.dateObject = date; + } this.dateObject = this.dateObject || new Date(); this.globalFormat = globalFormat; @@ -180,6 +183,9 @@ $.date.prototype = { this.selected = this.clone(); return this; }, + selected: function() { + return this.selected; + }, clone: function() { var date = this.dateObject; return new $.date( new Date( date.getFullYear(), date.getMonth(), diff --git a/ui/datepicker.js b/ui/datepicker.js index 80b407b1ba2..0dea81f4ea8 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -45,6 +45,7 @@ return $.widget( "ui.datepicker", { showWeek: false, show: true, hide: true, + value: null, // callbacks beforeOpen: null, @@ -54,17 +55,22 @@ return $.widget( "ui.datepicker", { }, _create: function() { - this.date = $.date( null, this.options.dateFormat ); - - this.date.eachDay = this.options.eachDay; this.id = "ui-datepicker-" + idIncrement; idIncrement++; + if ( this.element.is( "input" ) ) { + if ( !this.options.value && this.isValid() ) { + this.options.value = this._getParsedValue(); + } this._createPicker(); } else { this.inline = true; this.picker = this.element; } + + this.date = $.date( this.options.value, this.options.dateFormat ).select(); + this.date.eachDay = this.options.eachDay; + this._on( this.picker, { "click .ui-datepicker-prev": function( event ) { event.preventDefault(); @@ -106,7 +112,7 @@ return $.widget( "ui.datepicker", { _handleKeydown: function( event ) { if ( jQuery.inArray( event.keyCode, [ 13, 33, 34, 35, 36, 37, 38, 39, 40 ] ) === -1 ) { - //only interested navigation keys + // only interested navigation keys return; } event.preventDefault(); @@ -171,7 +177,7 @@ return $.widget( "ui.datepicker", { _createPicker: function() { this.picker = $( "
        " ) .addClass( "ui-front" ) - // TODO add a ui-datepicker-popup class, move position:absolte to that + // TODO add a ui-datepicker-popup class, move position:absolute to that .css( "position", "absolute" ) .uniqueId() .hide(); @@ -217,6 +223,7 @@ return $.widget( "ui.datepicker", { } } break; + // TODO this is not in specs, keep? case $.ui.keyCode.END: if ( event.ctrlKey ) { this.element.val( "" ); @@ -230,12 +237,12 @@ return $.widget( "ui.datepicker", { }, keyup: function() { if ( this.isValid() && !this.inline ) { - this.date.setTime( this.element.val() ).select(); + this.date.setTime( this._getParsedValue() ).select(); this.refresh(); } }, mousedown: function( event ) { - if (this.isOpen) { + if ( this.isOpen ) { suppressExpandOnFocus = true; this.close(); return; @@ -312,6 +319,7 @@ return $.widget( "ui.datepicker", { return element; }, + _createTmpl: function() { this._createDatepicker(); this.picker.find( "button" ).button(); @@ -323,6 +331,7 @@ return $.widget( "ui.datepicker", { this.picker.find( ".ui-datepicker" ).css( "display", "block" ); this.grid = this.picker.find( ".ui-datepicker-calendar" ); }, + _createDatepicker: function() { var multiClasses = [], pickerHtml = ""; @@ -345,6 +354,7 @@ return $.widget( "ui.datepicker", { .html( pickerHtml ) .appendTo( this.picker ); }, + _buildMultiplePicker: function() { var headerClass, html = "", @@ -572,8 +582,8 @@ return $.widget( "ui.datepicker", { // with the prev and next links would cause loss of focus issues because the links being // interacted with will disappear while focused. refresh: function() { - //determine which day gridcell to focus after refresh - //TODO: Prevent disabled cells from being focused + // determine which day gridcell to focus after refresh + // TODO: Prevent disabled cells from being focused if ( this.options.numberOfMonths === 1 ) { this.grid = $( this._buildGrid() ); $( ".ui-datepicker-title", this.picker ).html( this._buildTitle() ); @@ -606,10 +616,6 @@ return $.widget( "ui.datepicker", { return; } - // TODO explain this - this.date = $.date( this.element.val(), this.options.dateFormat ); - this.date.eachDay = this.options.eachDay; - this.date.select(); this.refresh(); this.picker @@ -650,46 +656,38 @@ return $.widget( "ui.datepicker", { }, _buildPosition: function() { - return $.extend( {}, { - of: this.element - }, this.options.position ); + return $.extend( {}, { of: this.element }, this.options.position ); }, _select: function( event, time ) { - this.date.setTime( time ).select(); - this.refresh(); + this._setOption( "value", new Date( time ) ); if ( !this.inline ) { - this.element.val( this.date.format() ); this.close(); this._focusTrigger(); } this._trigger( "select", event, { // TODO replace with value option to initialise and read - date: this.date.format() + date: this.value() }); }, - _value: function( value ) { - this.date.setTime( value ).select(); - if ( !this.inline ) { - this.element.val( this.date.format() ); - } - this.refresh(); - }, - value: function( value ) { if ( arguments.length ) { - this._value( value ); + this._setOption( "value", Globalize.parseDate( value, this.options.dateFormat ) ); } else { - return this.isValid() ? this.date.format() : this.element.val(); + if ( this.inline ) { + return Globalize.format( this.date.selected(), this.options.dateFormat ); + } else { + return this.element.val(); + } } }, valueAsDate: function( value ) { if ( arguments.length ) { - this._value( value ); + this._setOption( "value", value ); } else { - return this.isValid() ? this.date.date() : null; + return this.option( "value" ); } }, @@ -698,7 +696,7 @@ return $.widget( "ui.datepicker", { return true; } - return Globalize.parseDate( this.element.val(), this.options.dateFormat ) !== null; + return this._getParsedValue() !== null; }, _destroy: function() { @@ -716,7 +714,28 @@ return $.widget( "ui.datepicker", { return this.picker; }, + _getParsedValue: function() { + return Globalize.parseDate( this.element.val(), this.options.dateFormat ); + }, + + option: function( key ) { + if ( arguments.length === 0 || ( arguments.length === 1 && key === "value" ) ) { + this.options.value = this.inline ? this.date.selected() : this._getParsedValue(); + } + return this._superApply( arguments ); + }, + _setOption: function( key, value ) { + if ( key === "value" ) { + if ( value instanceof Date ) { + this.date.setTime( value.getTime() ).select(); + this.refresh(); + if ( !this.inline ) { + this.element.val( this.date.format() ); + } + } + } + this._super( key, value ); if ( key === "appendTo" ) { From d6c8e5db89f58891100214f85202801145a342b0 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 3 Jun 2014 23:18:51 +0200 Subject: [PATCH 069/172] Calendar: Add calendar widget Add calendar widget by copying and renaming datepicker widget files --- Gruntfile.js | 1 + build/tasks/testswarm.js | 1 + demos/calendar/alt-field.html | 36 + demos/calendar/animation.html | 59 + demos/calendar/buttonbar.html | 33 + demos/calendar/calendar-ar.js | 36 + demos/calendar/calendar-fr.js | 38 + demos/calendar/calendar-he.js | 36 + demos/calendar/calendar-zh-TW.js | 36 + demos/calendar/date-formats.html | 59 + demos/calendar/date-range.html | 49 + demos/calendar/default.html | 31 + demos/calendar/dropdown-month-year.html | 34 + demos/calendar/icon-trigger.html | 46 + demos/calendar/images/calendar.gif | Bin 0 -> 258 bytes demos/calendar/index.html | 28 + demos/calendar/inline.html | 31 + demos/calendar/localization.html | 40 + demos/calendar/min-max.html | 31 + demos/calendar/multiple-calendars.html | 34 + demos/calendar/other-months.html | 40 + demos/calendar/show-week.html | 35 + demos/index.html | 1 + tests/unit/all.html | 1 + tests/unit/calendar/all.html | 26 + tests/unit/calendar/calendar.html | 49 + tests/unit/calendar/calendar_common.js | 7 + tests/unit/calendar/calendar_core.js | 711 ++++++++++ tests/unit/calendar/calendar_events.js | 150 +++ tests/unit/calendar/calendar_methods.js | 130 ++ tests/unit/calendar/calendar_options.js | 1273 ++++++++++++++++++ tests/unit/calendar/calendar_test_helpers.js | 28 + tests/unit/calendar/images/calendar.gif | Bin 0 -> 258 bytes tests/unit/index.html | 1 + themes/base/base.css | 1 + themes/base/calendar.css | 180 +++ ui/calendar.js | 767 +++++++++++ 37 files changed, 4059 insertions(+) create mode 100644 demos/calendar/alt-field.html create mode 100644 demos/calendar/animation.html create mode 100644 demos/calendar/buttonbar.html create mode 100644 demos/calendar/calendar-ar.js create mode 100644 demos/calendar/calendar-fr.js create mode 100644 demos/calendar/calendar-he.js create mode 100644 demos/calendar/calendar-zh-TW.js create mode 100644 demos/calendar/date-formats.html create mode 100644 demos/calendar/date-range.html create mode 100644 demos/calendar/default.html create mode 100644 demos/calendar/dropdown-month-year.html create mode 100644 demos/calendar/icon-trigger.html create mode 100644 demos/calendar/images/calendar.gif create mode 100644 demos/calendar/index.html create mode 100644 demos/calendar/inline.html create mode 100644 demos/calendar/localization.html create mode 100644 demos/calendar/min-max.html create mode 100644 demos/calendar/multiple-calendars.html create mode 100644 demos/calendar/other-months.html create mode 100644 demos/calendar/show-week.html create mode 100644 tests/unit/calendar/all.html create mode 100644 tests/unit/calendar/calendar.html create mode 100644 tests/unit/calendar/calendar_common.js create mode 100644 tests/unit/calendar/calendar_core.js create mode 100644 tests/unit/calendar/calendar_events.js create mode 100644 tests/unit/calendar/calendar_methods.js create mode 100644 tests/unit/calendar/calendar_options.js create mode 100644 tests/unit/calendar/calendar_test_helpers.js create mode 100644 tests/unit/calendar/images/calendar.gif create mode 100644 themes/base/calendar.css create mode 100644 ui/calendar.js diff --git a/Gruntfile.js b/Gruntfile.js index 384b52ff376..d7f276f7b88 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -28,6 +28,7 @@ var "core", "accordion", "autocomplete", + "calendar", "button", "datepicker", "dialog", diff --git a/build/tasks/testswarm.js b/build/tasks/testswarm.js index a147b8f573c..0d500ef09dd 100644 --- a/build/tasks/testswarm.js +++ b/build/tasks/testswarm.js @@ -14,6 +14,7 @@ var versions = { "Accordion": "accordion/accordion.html", "Autocomplete": "autocomplete/autocomplete.html", "Button": "button/button.html", + "Calendar": "calendar/calendar.html", "Core": "core/core.html", "Core_deprecated": "core/core_deprecated.html", "Datepicker": "datepicker/datepicker.html", diff --git a/demos/calendar/alt-field.html b/demos/calendar/alt-field.html new file mode 100644 index 00000000000..bc8289eab38 --- /dev/null +++ b/demos/calendar/alt-field.html @@ -0,0 +1,36 @@ + + + + + jQuery UI Calendar - Populate alternate field + + + + + + + + + + + + + + + +

        Date:  

        + +
        +

        Populate an alternate field with its own date format whenever a date is selected using the altField and altFormat options. This feature could be used to present a human-friendly date for user selection, while passing a more computer-friendly date through for further processing.

        +
        + + diff --git a/demos/calendar/animation.html b/demos/calendar/animation.html new file mode 100644 index 00000000000..989006722a0 --- /dev/null +++ b/demos/calendar/animation.html @@ -0,0 +1,59 @@ + + + + + jQuery UI Calendar - Animations + + + + + + + + + + + + + + + + + + + + + + +

        Date:

        + +

        Animations:
        + +

        + +
        +

        Use different animations when opening or closing the calendar. Choose an animation from the dropdown, then click on the input to see its effect. You can use one of the three standard animations or any of the UI Effects.

        +
        + + diff --git a/demos/calendar/buttonbar.html b/demos/calendar/buttonbar.html new file mode 100644 index 00000000000..77da1ab5749 --- /dev/null +++ b/demos/calendar/buttonbar.html @@ -0,0 +1,33 @@ + + + + + jQuery UI Calendar - Display button bar + + + + + + + + + + + + + + + +

        Date:

        + +
        +

        Display a button for selecting Today's date and a Done button for closing the calendar with the boolean showButtonPanel option. Each button is enabled by default when the bar is displayed, but can be turned off with additional options. Button text is customizable.

        +
        + + diff --git a/demos/calendar/calendar-ar.js b/demos/calendar/calendar-ar.js new file mode 100644 index 00000000000..3f6eef2329e --- /dev/null +++ b/demos/calendar/calendar-ar.js @@ -0,0 +1,36 @@ +/* Arabic Translation for jQuery UI date picker plugin. */ +/* Khaled Alhourani -- me@khaledalhourani.com */ +/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ "../jquery.ui.calendar" ], factory ); + } else { + + // Browser globals + factory( jQuery.calendar ); + } +}(function( calendar ) { + calendar.regional['ar'] = { + closeText: 'إغلاق', + prevText: '<السابق', + nextText: 'التالي>', + currentText: 'اليوم', + monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران', + 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'], + weekHeader: 'أسبوع', + dateFormat: 'dd/mm/yy', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + calendar.setDefaults(calendar.regional['ar']); + + return calendar.regional['ar']; + +})); diff --git a/demos/calendar/calendar-fr.js b/demos/calendar/calendar-fr.js new file mode 100644 index 00000000000..ba25b8da688 --- /dev/null +++ b/demos/calendar/calendar-fr.js @@ -0,0 +1,38 @@ +/* French initialisation for the jQuery UI date picker plugin. */ +/* Written by Keith Wood (kbwood{at}iinet.com.au), + Stéphane Nahmani (sholby@sholby.net), + Stéphane Raimbault */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ "../jquery.ui.calendar" ], factory ); + } else { + + // Browser globals + factory( jQuery.calendar ); + } +}(function( calendar ) { + calendar.regional['fr'] = { + closeText: 'Fermer', + prevText: 'Précédent', + nextText: 'Suivant', + currentText: 'Aujourd\'hui', + monthNames: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', + 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], + monthNamesShort: ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin', + 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'], + dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'], + dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'], + dayNamesMin: ['D','L','M','M','J','V','S'], + weekHeader: 'Sem.', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + calendar.setDefaults(calendar.regional['fr']); + + return calendar.regional['fr']; + +})); diff --git a/demos/calendar/calendar-he.js b/demos/calendar/calendar-he.js new file mode 100644 index 00000000000..40f83c1cd50 --- /dev/null +++ b/demos/calendar/calendar-he.js @@ -0,0 +1,36 @@ +/* Hebrew initialisation for the UI Calendar extension. */ +/* Written by Amir Hardon (ahardon at gmail dot com). */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ "../jquery.ui.calendar" ], factory ); + } else { + + // Browser globals + factory( jQuery.calendar ); + } +}(function( calendar ) { + calendar.regional['he'] = { + closeText: 'סגור', + prevText: '<הקודם', + nextText: 'הבא>', + currentText: 'היום', + monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני', + 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'], + monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני', + 'יולי','אוג','ספט','אוק','נוב','דצמ'], + dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'], + dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + calendar.setDefaults(calendar.regional['he']); + + return calendar.regional['he']; + +})); diff --git a/demos/calendar/calendar-zh-TW.js b/demos/calendar/calendar-zh-TW.js new file mode 100644 index 00000000000..99c1719438c --- /dev/null +++ b/demos/calendar/calendar-zh-TW.js @@ -0,0 +1,36 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Ressol (ressol@gmail.com). */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ "../jquery.ui.calendar" ], factory ); + } else { + + // Browser globals + factory( jQuery.calendar ); + } +}(function( calendar ) { + calendar.regional['zh-TW'] = { + closeText: '關閉', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'yy/mm/dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + calendar.setDefaults(calendar.regional['zh-TW']); + + return calendar.regional['zh-TW']; + +})); diff --git a/demos/calendar/date-formats.html b/demos/calendar/date-formats.html new file mode 100644 index 00000000000..95adf01fd64 --- /dev/null +++ b/demos/calendar/date-formats.html @@ -0,0 +1,59 @@ + + + + + jQuery UI Calendar - Format date + + + + + + + + + + + + + + + +

        Date:

        + +

        Format options:
        + +

        + +
        +

        Display date feedback in a variety of ways. Choose a date format from the dropdown, then click on the input and select a date to see it in that format.

        +
        + + diff --git a/demos/calendar/date-range.html b/demos/calendar/date-range.html new file mode 100644 index 00000000000..7962dacce38 --- /dev/null +++ b/demos/calendar/date-range.html @@ -0,0 +1,49 @@ + + + + + jQuery UI Calendar - Select a Date Range + + + + + + + + + + + + + + + + + + + + +
        +

        Select the date range to search for.

        +
        + + diff --git a/demos/calendar/default.html b/demos/calendar/default.html new file mode 100644 index 00000000000..26c4c2eb3d5 --- /dev/null +++ b/demos/calendar/default.html @@ -0,0 +1,31 @@ + + + + + jQuery UI Calendar - Default functionality + + + + + + + + + + + + + + + +

        Date:

        + +
        +

        The calendar is tied to a standard form input field. Focus on the input (click, or use the tab key) to open an interactive calendar in a small overlay. Choose a date, click elsewhere on the page (blur the input), or hit the Esc key to close. If a date is chosen, feedback is shown as the input's value.

        +
        + + diff --git a/demos/calendar/dropdown-month-year.html b/demos/calendar/dropdown-month-year.html new file mode 100644 index 00000000000..30d4fa80b87 --- /dev/null +++ b/demos/calendar/dropdown-month-year.html @@ -0,0 +1,34 @@ + + + + + jQuery UI Calendar - Display month & year menus + + + + + + + + + + + + + + + +

        Date:

        + +
        +

        Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes. Add the boolean changeMonth and changeYear options.

        +
        + + diff --git a/demos/calendar/icon-trigger.html b/demos/calendar/icon-trigger.html new file mode 100644 index 00000000000..168708520e7 --- /dev/null +++ b/demos/calendar/icon-trigger.html @@ -0,0 +1,46 @@ + + + + + jQuery UI Calendar - Icon trigger + + + + + + + + + + + + + + + +

        Date:

        + +
        +

        Click the icon next to the input field to show the calendar. Set the calendar to open on focus (default behavior), on icon click, or both.

        +
        + + diff --git a/demos/calendar/images/calendar.gif b/demos/calendar/images/calendar.gif new file mode 100644 index 0000000000000000000000000000000000000000..52f2863c90764cabb11ac926b3f7e02b9b9e5e49 GIT binary patch literal 258 zcmZ?wbh9u|6ky<+Y9vrwbI($!DTUl#W73z|)4nX4`*rp5ZyQ#B-@379)%)KM@Be-M>hGtI|Gs_w|L4#D z|Nj|~fDVWavWtPW{Q*md3PbOU5QXTA``&Hf+-&MQNyN4Pv4TT$qr;4tz7x@TlA2nj z{VVh>rsSCQXN#@AXk#?9q4e^OX(ylcxawre$mLbEZVWhZ^wyuYi=i=Ui~?zCvD{J; zob`>l`Gve(T%4S?jg@f;{OB2!bOQWALGdFOQVvkR?QwQ_|pZzJQT&0DrAGFSru Doau8X literal 0 HcmV?d00001 diff --git a/demos/calendar/index.html b/demos/calendar/index.html new file mode 100644 index 00000000000..48097f5983e --- /dev/null +++ b/demos/calendar/index.html @@ -0,0 +1,28 @@ + + + + + + jQuery UI Calendar Demos + + + + + + + diff --git a/demos/calendar/inline.html b/demos/calendar/inline.html new file mode 100644 index 00000000000..b6f2575993b --- /dev/null +++ b/demos/calendar/inline.html @@ -0,0 +1,31 @@ + + + + + jQuery UI Calendar - Display inline + + + + + + + + + + + + + + + +Date:
        + +
        +

        Display the calendar embedded in the page instead of in an overlay. Simply call .calendar() on a div instead of an input.

        +
        + + diff --git a/demos/calendar/localization.html b/demos/calendar/localization.html new file mode 100644 index 00000000000..8f97bbcc8ef --- /dev/null +++ b/demos/calendar/localization.html @@ -0,0 +1,40 @@ + + + + + jQuery UI Calendar - Localize calendar + + + + + + + + + + + + + + + +

        Date:   +

        + +
        +

        Localize the calendar calendar language and format (English / Western formatting is the default). The calendar includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.

        +
        + + diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html new file mode 100644 index 00000000000..94826c71a71 --- /dev/null +++ b/demos/calendar/min-max.html @@ -0,0 +1,31 @@ + + + + + jQuery UI Calendar - Restrict date range + + + + + + + + + + + + + + + +

        Date:

        + +
        +

        Restrict the range of selectable dates with the minDate and maxDate options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D'). For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.

        +
        + + diff --git a/demos/calendar/multiple-calendars.html b/demos/calendar/multiple-calendars.html new file mode 100644 index 00000000000..9fe2b7ab526 --- /dev/null +++ b/demos/calendar/multiple-calendars.html @@ -0,0 +1,34 @@ + + + + + jQuery UI Calendar - Display multiple months + + + + + + + + + + + + + + + +

        Date:

        + +
        +

        Set the numberOfMonths option to an integer of 2 or more to show multiple months in a single calendar.

        +
        + + diff --git a/demos/calendar/other-months.html b/demos/calendar/other-months.html new file mode 100644 index 00000000000..3ad1aba37d9 --- /dev/null +++ b/demos/calendar/other-months.html @@ -0,0 +1,40 @@ + + + + + jQuery UI Calendar - Dates in other months + + + + + + + + + + + + + + + +

        Date:

        + +
        +

        The calendar can show dates that come from other than the main month + being displayed. These other dates can also be made selectable.

        +
        + + diff --git a/demos/calendar/show-week.html b/demos/calendar/show-week.html new file mode 100644 index 00000000000..e7fcb84957b --- /dev/null +++ b/demos/calendar/show-week.html @@ -0,0 +1,35 @@ + + + + + jQuery UI Calendar - Show week of the year + + + + + + + + + + + + + + + +

        Date:

        + +
        +

        The calendar can show the week of the year. The calculation follows + Unicode CLDR specification. + This means that some days from one year may be placed into weeks 'belonging' to another year.

        +
        + + diff --git a/demos/index.html b/demos/index.html index f37874a4481..c4a0fdf9501 100644 --- a/demos/index.html +++ b/demos/index.html @@ -11,6 +11,7 @@
      1. accordion
      2. autocomplete
      3. button
      4. +
      5. calendar
      6. datepicker
      7. dialog
      8. draggable
      9. diff --git a/tests/unit/all.html b/tests/unit/all.html index 0d59d0ec6eb..643c591a1fc 100644 --- a/tests/unit/all.html +++ b/tests/unit/all.html @@ -21,6 +21,7 @@ "button/button.html", "core/core.html", "core/core_deprecated.html", + "calendar/calendar.html", "datepicker/datepicker.html", "dialog/dialog.html", "draggable/draggable.html", diff --git a/tests/unit/calendar/all.html b/tests/unit/calendar/all.html new file mode 100644 index 00000000000..26c46415a6e --- /dev/null +++ b/tests/unit/calendar/all.html @@ -0,0 +1,26 @@ + + + + + jQuery UI calendar Test Suite + + + + + + + + + + + + + +
        +
        + +
        + + diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html new file mode 100644 index 00000000000..5a5256a6bab --- /dev/null +++ b/tests/unit/calendar/calendar.html @@ -0,0 +1,49 @@ + + + + + jQuery UI calendar Test Suite + + + + + + + + + + + + + + + + + + + + + + +
        +
        + + + + +
        + +
        + + diff --git a/tests/unit/calendar/calendar_common.js b/tests/unit/calendar/calendar_common.js new file mode 100644 index 00000000000..b0df728acb6 --- /dev/null +++ b/tests/unit/calendar/calendar_common.js @@ -0,0 +1,7 @@ +/* +TestHelpers.commonWidgetTests( "calendar", { + defaults: { + disabled: false + } +}); +*/ diff --git a/tests/unit/calendar/calendar_core.js b/tests/unit/calendar/calendar_core.js new file mode 100644 index 00000000000..18f00274ec3 --- /dev/null +++ b/tests/unit/calendar/calendar_core.js @@ -0,0 +1,711 @@ +(function( $ ) { + +module( "calendar: core" ); + +TestHelpers.testJshint( "calendar" ); + +test( "input's value determines starting date", function() { + expect( 3 ); + + var input = $( "#calendar" ).val( "1/1/14" ).calendar(), + picker = input.calendar( "widget" ); + + input.calendar( "open" ); + + equal( picker.find( ".ui-calendar-month" ).html(), "January", "correct month displayed" ); + equal( picker.find( ".ui-calendar-year" ).html(), "2014", "correct year displayed" ); + equal( picker.find( ".ui-state-focus" ).html(), "1", "correct day highlighted" ); + + input.val( "" ).calendar( "destroy" ); +}); + +asyncTest( "baseStructure", function() { + expect( 42 ); + var header, title, table, thead, week, panel, inl, child, + inp = TestHelpers.calendar.initNewInput(), + dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + + function step1() { + inp.focus(); + setTimeout(function() { + ok( dp.is( ":visible" ), "Structure - calendar visible" ); + ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" ); + ok( !dp.is( ".ui-calendar-multi" ), "Structure - not multi-month" ); + equal( dp.children().length, 3, "Structure - child count (header, calendar, buttonpane)" ); + + header = dp.children( ":first" ); + ok( header.is( "div.ui-calendar-header" ), "Structure - header division" ); + equal( header.children().length, 3, "Structure - header child count" ); + ok( header.children( ":first" ).is( ".ui-calendar-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); + ok( header.children( ":eq(1)" ).is( ".ui-calendar-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); + + title = header.children( ":last" ).children( ":first" ); + ok( title.is( "div.ui-calendar-title" ) && title.html() !== "", "Structure - title division" ); + equal( title.children().length, 2, "Structure - title child count" ); + ok( title.children( ":first" ).is( "span.ui-calendar-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); + ok( title.children( ":last" ).is( "span.ui-calendar-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); + + table = dp.children( ":eq(1)" ); + ok( table.is( "table.ui-calendar-calendar" ), "Structure - month table" ); + ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); + + thead = table.children( ":first" ).children( ":first" ); + ok( thead.is( "tr" ), "Structure - month table title row" ); + equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); + ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" ); + ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" ); + + week = table.children( ":eq(1)" ).children( ":first" ); + ok( week.is( "tr" ), "Structure - month table week row" ); + equal( week.children().length, 7, "Structure - week child count" ); + // TODO: Preserve these class names or let the user use :first-child and :last-child? + // ok( week.children( ":first" ).is( "td.ui-calendar-week-end" ), "Structure - month table first day cell" ); + // ok( week.children( ":last" ).is( "td.ui-calendar-week-end" ), "Structure - month table second day cell" ); + + inp.calendar( "close" ).calendar( "destroy" ); + step2(); + }); + } + + function step2() { + // Editable month/year and button panel + inp = TestHelpers.calendar.initNewInput({ + changeMonth: true, + changeYear: true, + showButtonPanel: true + }); + dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + inp.focus(); + setTimeout(function() { + title = dp.find( "div.ui-calendar-title" ); + // TODO: Re-add tests when changeMonth and changeYear are re-implemented + //ok( title.children( ":first" ).is( "select.ui-calendar-month" ), "Structure - month selector" ); + //ok( title.children( ":last" ).is( "select.ui-calendar-year" ), "Structure - year selector" ); + + panel = dp.children( ":last" ); + ok( panel.is( "div.ui-calendar-buttonpane" ), "Structure - button panel division" ); + equal( panel.children().length, 2, "Structure - button panel child count" ); + ok( panel.children( ":first" ).is( "button.ui-calendar-current" ), "Structure - today button" ); + ok( panel.children( ":last" ).is( "button.ui-calendar-close" ), "Structure - close button" ); + + inp.calendar( "close" ).calendar( "destroy" ); + step3(); + }); + } + + function step3() { + // Multi-month 2 + inp = TestHelpers.calendar.initNewInput({ numberOfMonths: 2 } ); + dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + inp.focus(); + setTimeout(function() { + ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" ); + equal( dp.children().length, 4, "Structure multi [2] - child count" ); + + child = dp.children( ":first" ); + // TODO: Implement ui-calendar-group-first class name + // ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-first" ), "Structure multi [2] - first month division" ); + + child = dp.children( ":eq(1)" ); + // TODO: Implement ui-calendar-group-last class name + // ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-last" ), "Structure multi [2] - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" ); + ok( dp.is( ".ui-calendar-multi-2" ), "Structure multi [2] - multi-2" ); + + inp.calendar( "close" ).calendar( "destroy" ); + step4(); + }); + } + + function step4() { + // Multi-month 3 + inp = TestHelpers.calendar.initNewInput({ numberOfMonths: 3 } ); + dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + inp.focus(); + setTimeout(function() { + ok( dp.is( ".ui-calendar-multi-3" ), "Structure multi [3] - multi-3" ); + ok( !dp.is( ".ui-calendar-multi-2" ), "Structure multi [3] - Trac #6704" ); + + inp.calendar( "close" ).calendar( "destroy" ); + step5(); + }); + } + + function step5() { + // Multi-month [2, 2] + inp = TestHelpers.calendar.initNewInput({ numberOfMonths: [ 2, 2 ] } ); + dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + inp.focus(); + setTimeout(function() { + /* + TODO: Re-add after array form of the numberOfMonths option is implemented. + ok( dp.is( ".ui-calendar-multi" ), "Structure multi - multi-month" ); + equal( dp.children().length, 6, "Structure multi [2,2] - child count" ); + + child = dp.children( ":first" ); + ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-first" ), "Structure multi [2,2] - first month division" ); + + child = dp.children( ":eq(1)" ); + ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-last" ), "Structure multi [2,2] - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2,2] - row break" ); + + child = dp.children( ":eq(3)" ); + ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-first" ), "Structure multi [2,2] - third month division" ); + + child = dp.children( ":eq(4)" ); + ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-last" ), "Structure multi [2,2] - fourth month division" ); + + child = dp.children( ":eq(5)" ); + ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2,2] - row break" ); + */ + inp.calendar( "close" ).calendar( "destroy" ); + step6(); + }); + } + + function step6() { + // Inline + inl = TestHelpers.calendar.init( "#inline" ); + dp = inl.children(); + + ok( dp.is( ".ui-calendar-inline" ), "Structure inline - main div" ); + ok( !dp.is( ".ui-calendar-rtl" ), "Structure inline - not right-to-left" ); + ok( !dp.is( ".ui-calendar-multi" ), "Structure inline - not multi-month" ); + equal( dp.children().length, 3, "Structure inline - child count (header, calendar, buttonpane)" ); + + header = dp.children( ":first" ); + ok( header.is( "div.ui-calendar-header" ), "Structure inline - header division" ); + equal( header.children().length, 3, "Structure inline - header child count" ); + + table = dp.children( ":eq(1)" ); + ok( table.is( "table.ui-calendar-calendar" ), "Structure inline - month table" ); + ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" ); + ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" ); + + inl.calendar( "destroy" ); + + step7(); + } + + function step7() { + // Inline multi-month + inl = TestHelpers.calendar.init( "#inline", { numberOfMonths: 2 } ); + dp = inl.calendar( "widget" ).find( ".ui-calendar" ); + + ok( dp.is( ".ui-calendar-inline" ) && dp.is( ".ui-calendar-multi" ), "Structure inline multi - main div" ); + equal( dp.children().length, 4, "Structure inline multi - child count" ); + + child = dp.children( ":first" ); + // TODO: Implement ui-calendar-group-first class name + // ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-first" ), "Structure inline multi - first month division" ); + + child = dp.children( ":eq(1)" ); + // TODO: Implement ui-calendar-group-last class name + // ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-last" ), "Structure inline multi - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-calendar-row-break" ), "Structure inline multi - row break" ); + + inl.calendar( "destroy" ); + start(); + } + + step1(); +}); + +// Skip these tests for now as none are implemented yet. +/* +asyncTest( "customStructure", function() { + expect( 0 ); + + var header, panel, title, + inp = TestHelpers.calendar.initNewInput(), + dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + + start(); + + function step1() { + Globalize.culture( "he" ); + inp.focus(); + + setTimeout(function() { + ok( dp.is( ".ui-calendar-rtl" ), "Structure RTL - right-to-left" ); + + header = dp.children( ":first" ); + ok( header.is( "div.ui-calendar-header" ), "Structure RTL - header division" ); + equal( header.children().length, 3, "Structure RTL - header child count" ); + ok( header.children( ":first" ).is( "a.ui-calendar-next" ), "Structure RTL - prev link" ); + ok( header.children( ":eq(1)" ).is( "a.ui-calendar-prev" ), "Structure RTL - next link" ); + + panel = dp.children( ":last" ); + ok( panel.is( "div.ui-calendar-buttonpane" ), "Structure RTL - button division" ); + equal( panel.children().length, 2, "Structure RTL - button panel child count" ); + ok( panel.children( ":first" ).is( "button.ui-calendar-close" ), "Structure RTL - close button" ); + ok( panel.children( ":last" ).is( "button.ui-calendar-current" ), "Structure RTL - today button" ); + + inp.calendar( "close" ).calendar( "destroy" ); + Globalize.culture( "en-US" ); + step2(); + }); + } + + // Hide prev/next + // TODO: If we decide the hideIfNoPrevNext option is being removed these tests can be as well. + function stepX() { + inp = TestHelpers.calendar.initNewInput({ + hideIfNoPrevNext: true, + minDate: new Date( 2008, 2 - 1, 4 ), + maxDate: new Date( 2008, 2 - 1, 14 ) + }); + inp.val( "02/10/2008" ); + + TestHelpers.calendar.onFocus( inp, function() { + header = dp.children( ":first" ); + ok( header.is( "div.ui-calendar-header" ), "Structure hide prev/next - header division" ); + equal( header.children().length, 1, "Structure hide prev/next - links child count" ); + ok( header.children( ":first" ).is( "div.ui-calendar-title" ), "Structure hide prev/next - title division" ); + + inp.calendar( "hide" ).calendar( "destroy" ); + step3(); + }); + } + + // Changeable Month with read-only year + function step2() { + inp = TestHelpers.calendar.initNewInput({ changeMonth: true } ); + dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + + inp.focus(); + setTimeout(function() { + title = dp.children( ":first" ).children( ":last" ); + + // TODO: Implement changeMonth option + // equal( title.children().length, 2, "Structure changeable month - title child count" ); + // ok( title.children( ":first" ).is( "select.ui-calendar-month" ), "Structure changeable month - month selector" ); + // ok( title.children( ":last" ).is( "span.ui-calendar-year" ), "Structure changeable month - read-only year" ); + + inp.calendar( "close" ).calendar( "destroy" ); + step3(); + }); + } + + // Changeable year with read-only month + function step3() { + inp = TestHelpers.calendar.initNewInput({ changeYear: true } ); + + TestHelpers.calendar.onFocus( inp, function() { + title = dp.children( ":first" ).children( ":last" ); + + // TODO: Implement changeYear option + // equal( title.children().length, 2, "Structure changeable year - title child count" ); + // ok( title.children( ":first" ).is( "span.ui-calendar-month" ), "Structure changeable year - read-only month" ); + // ok( title.children( ":last" ).is( "select.ui-calendar-year" ), "Structure changeable year - year selector" ); + + inp.calendar( "close" ).calendar( "destroy" ); + start(); + }); + } + + // TODO: figure out why this setTimeout is needed in IE, + // it only is necessary when the previous baseStructure tests runs first + // Support: IE + setTimeout( step1 ); +}); +*/ + +test( "Keyboard handling", function() { + expect( 9 ); + var input = $( "#calendar" ).calendar(), + instance = input.calendar( "instance" ), + date = new Date(); + + input.calendar( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, "Keystroke enter" ); + + // Enter = Select today's date by default + input.val( "1/1/14" ).calendar( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke enter - preset" ); + + // Control + Home = Change the calendar to the current month + input.val( "1/1/14" ).calendar( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, "Keystroke ctrl+home" ); + + // Control + End = Close the calendar and clear the input + input.val( "1/1/14" ).calendar( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); + equal( input.val(), "", "Keystroke ctrl+end" ); + + input.val( "" ).calendar( "open" ); + ok( instance.isOpen, "calendar is open before escape" ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + ok( !instance.isOpen, "escape closes the calendar" ); + + input.val( "1/1/14" ).calendar( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke esc - preset" ); + + input.val( "1/1/14" ).calendar( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke esc - abandoned" ); + + input.val( "1/2/14" ) + .simulate( "keyup" ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2014, 0, 2 ), + "Picker updated as user types into input" ); + + input.calendar( "destroy" ); +}); + +asyncTest( "keyboard handling", function() { + expect( 14 ); + var picker, + input = $( "#calendar" ), + date = new Date(); + + function step1() { + input.calendar(); + picker = input.calendar( "widget" ); + ok( !picker.is( ":visible" ), "calendar closed" ); + input.val( "" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + ok( picker.is( ":visible" ), "Keystroke down opens calendar" ); + input.calendar( "destroy" ); + step2(); + }); + } + + function step2() { + input.calendar(); + picker = input.calendar( "widget" ); + ok( !picker.is( ":visible" ), "calendar closed" ); + input.val( "" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + + setTimeout(function() { + ok( picker.is( ":visible" ), "Keystroke up opens calendar" ); + input.calendar( "destroy" ); + step3(); + }); + } + + function step3() { + input.calendar() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2013, 12 - 1, 31 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke left to switch to previous day" ); + + input.calendar( "destroy" ); + step4(); + }, 100 ); + } + + function step4() { + input.calendar() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2014, 1 - 1, 2 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke right to switch to next day" ); + + input.calendar( "destroy" ); + step5(); + }, 100 ); + } + + function step5() { + input.calendar() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2013, 12 - 1, 25 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke up to move to the previous week" ); + + input.calendar( "destroy" ); + step6(); + }, 100 ); + } + + function step6() { + input.calendar() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2014, 1 - 1, 8 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke down to move to the next week" ); + + input.calendar( "destroy" ); + step7(); + }, 100 ); + } + + function step7() { + input.calendar() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2013, 12 - 1, 1 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke Page Up moves date to previous month" ); + + input.calendar( "destroy" ); + step8(); + }, 100 ); + } + + function step8() { + input.calendar() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2013, 1 - 1, 1 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke Page Up + Ctrl moves date to previous year" ); + + input.calendar( "destroy" ); + step9(); + }, 100 ); + } + + function step9() { + input.calendar() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2014, 2 - 1, 1 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke Page Down moves date to next month" ); + + input.calendar( "destroy" ); + step10(); + }, 100 ); + } + + function step10() { + input.calendar() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2015, 1 - 1, 1 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke Page Down + Ctrl moves date to next year" ); + + input.calendar( "destroy" ); + step11(); + }, 100 ); + } + + // Check for moving to short months + function step11() { + input.calendar() + .val( "3/31/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2014, 2 - 1, 28 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke Page Up and short months" ); + + input.calendar( "destroy" ); + step12(); + }, 100 ); + } + + function step12() { + input.calendar() + .val( "1/30/16" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + date = new Date( 2016, 2 - 1, 29 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, + "Keystroke Page Down and leap years" ); + + input.calendar( "destroy" ); + start(); + }, 100 ); + } + + step1(); +}); + +/* + // TODO: Re-add tests if we implement a stepMonths option + input.calendar( "option", { stepMonths: 2, gotoCurrent: false } ) + .calendar( "close" ).val( "02/04/2008" ).calendar( "open" ) + .late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2007, 12 - 1, 4 ), + "Keystroke pgup step 2" ); + + input.val( "02/04/2008" ).calendar( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ), + "Keystroke pgdn step 2" ); +*/ + +test( "mouse", function() { + expect( 13 ); + var input = $( "#calendar" ).calendar(), + picker = input.calendar( "widget" ), + inline = $( "#inline" ).calendar, + date = new Date(); + + input.val( "" ).calendar( "open" ); + $( ".ui-calendar-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} ); + date.setDate( 10 ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, "Mouse click" ); + + input.val( "2/4/08" ).calendar( "open" ); + $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), + "Mouse click - preset" ) ; + + input.val( "" ).calendar( "open" ); + $( "button.ui-calendar-close", picker ).simulate( "click", {} ); + ok( input.calendar( "valueAsDate" ) == null, "Mouse click - close" ); + + input.val( "2/4/08" ).calendar( "open" ); + $( "button.ui-calendar-close", picker ).simulate( "click", {} ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), + "Mouse click - close + preset" ); + + input.val( "2/4/08" ).calendar( "open" ); + $( "a.ui-calendar-prev", picker ).simulate( "click", {} ); + $( "button.ui-calendar-close", picker ).simulate( "click", {} ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), + "Mouse click - abandoned" ); + + // Current/previous/next + input.val( "" ).calendar( "open" ); + $( ".ui-calendar-current", picker ).simulate( "click", {} ); + date.setDate( new Date().getDate() ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, "Mouse click - current" ); + + input.val( "2/4/08" ).calendar( "open" ); + $( ".ui-calendar-prev", picker ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), + "Mouse click - previous" ); + + input.val( "2/4/08" ).calendar( "open" ); + $( ".ui-calendar-next", picker ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), + "Mouse click - next" ); + + /* + // TODO: Re-add when min and max options are introduced. + // Previous/next with minimum/maximum + input.calendar( "option", { + minDate: new Date( 2008, 2 - 1, 2 ), + maxDate: new Date( 2008, 2 - 1, 26 ) + }).val( "2/4/08" ).calendar( "open" ); + $( ".ui-calendar-prev", picker ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 16 ), + "Mouse click - previous + min/max" ); + + input.val( "2/4/08" ).calendar( "open" ); + $( ".ui-calendar-next", picker ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate(input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 18 ), + "Mouse click - next + min/max" ); + */ + + // Inline + inline = TestHelpers.calendar.init( "#inline" ); + picker = $( ".ui-calendar-inline", inline ); + date = new Date(); + inline.calendar( "valueAsDate", date ); + $( ".ui-calendar-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} ); + date.setDate( 10 ); + TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), date, "Mouse click inline" ); + + inline.calendar( "option", { showButtonPanel: true } ) + .calendar( "valueAsDate", new Date( 2008, 2 - 1, 4 )); + $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); + TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), + "Mouse click inline - preset" ); + + inline.calendar( "option", { showButtonPanel: true } ); + $( ".ui-calendar-current", picker ).simulate( "click", {} ); + $( ".ui-calendar-calendar tbody a:contains(14)", picker ).simulate( "mousedown", {} ); + date.setDate( 14 ); + TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), date, "Mouse click inline - current" ); + + inline.calendar( "valueAsDate", new Date( 2008, 2 - 1, 4) ); + $( ".ui-calendar-prev", picker ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), + "Mouse click inline - previous" ); + + inline.calendar( "valueAsDate", new Date( 2008, 2 - 1, 4) ); + $( ".ui-calendar-next", picker ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), + "Mouse click inline - next" ); + + input.calendar( "destroy" ); + inline.calendar( "destroy" ); +}); + +})( jQuery ); diff --git a/tests/unit/calendar/calendar_events.js b/tests/unit/calendar/calendar_events.js new file mode 100644 index 00000000000..2d03801fadb --- /dev/null +++ b/tests/unit/calendar/calendar_events.js @@ -0,0 +1,150 @@ +// The implement of events is completely changing therefore these tests are no longer directly +// relevant. Leaving them around commented out so we can ensure the functionality is replicated. +// For example: +// TODO: In the old implementation the Enter key select's today's date when the has +// focus and is empty. Do we want to replicate this behavior in the rewrite? +/* + +(function( $ ) { + +module( "calendar: events" ); + +test( "beforeOpen", function() { + expect( 0 ); +}); + +test( "close", function() { + expect( 0 ); +}); + +test( "open", function() { + expect( 0 ); +}); + +test( "select", function() { + expect( 0 ); +}); + +var selectedThis = null, +selectedDate = null, +selectedInst = null; + +function callback(date, inst) { + selectedThis = this; + selectedDate = date; + selectedInst = inst; +} + +function callback2(year, month, inst) { + selectedThis = this; + selectedDate = year + "/" + month; + selectedInst = inst; +} + +test( "events", function() { + expect( 26 ); + var dateStr, newMonthYear, inp2, + inp = TestHelpers.calendar.init( "#inp", {onSelect: callback}), + date = new Date(); + // onSelect + inp.val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(selectedThis, inp[0], "Callback selected this" ); + equal(selectedInst, $.data(inp[0], TestHelpers.calendar.PROP_NAME), "Callback selected inst" ); + equal(selectedDate, $.calendar.formatDate( "mm/dd/yy", date), + "Callback selected date" ); + inp.val( "" ).calendar( "show" ). + simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 7); + equal(selectedDate, $.calendar.formatDate( "mm/dd/yy", date), + "Callback selected date - ctrl+down" ); + inp.val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(selectedDate, $.calendar.formatDate( "mm/dd/yy", date), + "Callback selected date - esc" ); + dateStr = "02/04/2008"; + inp.val(dateStr).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(dateStr, selectedDate, + "onSelect is called after enter keydown" ); + // onChangeMonthYear + inp.calendar( "option", {onChangeMonthYear: callback2, onSelect: null}). + val( "" ).calendar( "show" ); + newMonthYear = function(date) { + return date.getFullYear() + "/" + (date.getMonth() + 1); + }; + date = new Date(); + date.setDate(1); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_UP}); + date.setMonth(date.getMonth() - 1); + equal(selectedThis, inp[0], "Callback change month/year this" ); + equal(selectedInst, $.data(inp[0], TestHelpers.calendar.PROP_NAME), "Callback change month/year inst" ); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - pgup" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); + date.setMonth(date.getMonth() + 1); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - pgdn" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); + date.setFullYear(date.getFullYear() - 1); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - ctrl+pgup" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}); + date.setFullYear(date.getFullYear() + 1); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - ctrl+home" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); + date.setFullYear(date.getFullYear() + 1); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - ctrl+pgdn" ); + inp.calendar( "setDate", new Date(2007, 1 - 1, 26)); + equal(selectedDate, "2007/1", "Callback change month/year date - setDate" ); + selectedDate = null; + inp.calendar( "setDate", new Date(2007, 1 - 1, 12)); + ok(selectedDate == null, "Callback change month/year date - setDate no change" ); + // onChangeMonthYear step by 2 + inp.calendar( "option", {stepMonths: 2}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_UP}); + date.setMonth(date.getMonth() - 14); + equal(selectedDate, newMonthYear(date), + "Callback change month/year by 2 date - pgup" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); + date.setMonth(date.getMonth() - 12); + equal(selectedDate, newMonthYear(date), + "Callback change month/year by 2 date - ctrl+pgup" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); + date.setMonth(date.getMonth() + 2); + equal(selectedDate, newMonthYear(date), + "Callback change month/year by 2 date - pgdn" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); + date.setMonth(date.getMonth() + 12); + equal(selectedDate, newMonthYear(date), + "Callback change month/year by 2 date - ctrl+pgdn" ); + // onClose + inp.calendar( "option", {onClose: callback, onChangeMonthYear: null, stepMonths: 1}). + val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(selectedThis, inp[0], "Callback close this" ); + equal(selectedInst, $.data(inp[0], TestHelpers.calendar.PROP_NAME), "Callback close inst" ); + equal(selectedDate, "", "Callback close date - esc" ); + inp.val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(selectedDate, $.calendar.formatDate( "mm/dd/yy", new Date()), + "Callback close date - enter" ); + inp.val( "02/04/2008" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(selectedDate, "02/04/2008", "Callback close date - preset" ); + inp.val( "02/04/2008" ).calendar( "show" ). + simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); + equal(selectedDate, "", "Callback close date - ctrl+end" ); + + inp2 = TestHelpers.calendar.init( "#inp2" ); + inp2.calendar().calendar( "option", {onClose: callback}).calendar( "show" ); + inp.calendar( "show" ); + equal(selectedThis, inp2[0], "Callback close this" ); +}); + +})( jQuery ); + */ diff --git a/tests/unit/calendar/calendar_methods.js b/tests/unit/calendar/calendar_methods.js new file mode 100644 index 00000000000..89547463cf8 --- /dev/null +++ b/tests/unit/calendar/calendar_methods.js @@ -0,0 +1,130 @@ +(function( $ ) { + +module( "calendar: methods" ); + +test( "destroy", function() { + expect( 10 ); + var input = $( "#calendar" ).calendar(), + inline = $( "#inline" ).calendar(); + + ok( input.calendar( "instance" ), "instance created" ); + ok( input.attr( "aria-owns" ), "aria-owns attribute added" ); + ok( input.attr( "aria-haspopup" ), "aria-haspopup attribute added" ); + input.calendar( "destroy" ); + ok( !input.calendar( "instance" ), "instance removed" ); + ok( !input.attr( "aria-owns" ), "aria-owns attribute removed" ); + ok( !input.attr( "aria-haspopup" ), "aria-haspopup attribute removed" ); + + ok( inline.calendar( "instance" ), "instance created" ); + ok( inline.children().length > 0, "inline calendar has children" ); + inline.calendar( "destroy" ); + ok( !inline.calendar( "instance" ), "instance removed" ); + ok( inline.children().length === 0, "inline picker no longer has children" ); +}); + +test( "enable / disable", function() { + expect( 6 ); + var inl, + inp = TestHelpers.calendar.init( "#calendar" ), + dp = inp.calendar( "widget" ); + + ok( !inp.calendar( "option", "disabled" ), "initially enabled" ); + ok( !dp.hasClass( "ui-calendar-disabled" ), "does not have disabled class name" ); + + inp.calendar( "disable" ); + ok( inp.calendar( "option", "disabled" ), "disabled option is set" ); + ok( dp.hasClass( "ui-calendar-disabled" ), "calendar has disabled class name" ); + + inp.calendar( "enable" ); + ok( !inp.calendar( "option", "disabled" ), "enabled after enable() call" ); + ok( !dp.hasClass( "ui-calendar-disabled" ), "no longer has disabled class name" ); + + // Inline + inl = TestHelpers.calendar.init( "#inline" ); + dp = inl.calendar( "instance" ); + + // TODO: Disabling inline pickers does not work. + // TODO: When changeMonth and changeYear options are implemented ensure their dropdowns + // are properly disabled when in an inline picker. +}); + +test( "widget", function() { + expect( 1 ); + var actual = $( "#calendar" ).calendar().calendar( "widget" ); + deepEqual( $( "body > .ui-front" )[ 0 ], actual[ 0 ] ); + actual.remove(); +}); + +test( "close", function() { + expect( 0 ); +}); + +test( "open", function() { + expect( 0 ); +}); + +test( "value", function() { + expect( 6 ); + var input = $( "#calendar" ).calendar(), + picker = input.calendar( "widget" ), + inline = $( "#inline" ).calendar(); + + input.calendar( "value", "1/1/14" ); + equal( input.val(), "1/1/14", "input's value set" ); + ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + "first day marked as selected" ); + equal( input.calendar( "value" ), "1/1/14", "getter" ); + + input.val( "abc" ); + equal( input.calendar( "value" ), "abc", + "Invalid values should be returned without formatting." ); + + inline.calendar( "value", "1/1/14" ); + ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + "first day marked as selected" ); + equal( inline.calendar( "value" ), "1/1/14", "getter" ); + + input.calendar( "destroy" ); + inline.calendar( "destroy" ); +}); + +test( "valueAsDate", function() { + expect( 6 ); + var input = $( "#calendar" ).calendar(), + picker = input.calendar( "widget" ), + inline = $( "#inline" ).calendar(); + + input.calendar( "valueAsDate", new Date( 2014, 0, 1 ) ); + equal( input.val(), "1/1/14", "input's value set" ); + ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + "first day marked as selected" ); + TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), + new Date( 2014, 0, 1 ), "getter" ); + + input.val( "a/b/c" ); + equal( input.calendar( "valueAsDate" ), null, "Invalid dates return null" ); + + inline.calendar( "valueAsDate", new Date( 2014, 0, 1 ) ); + ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + "first day marked as selected" ); + TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), + new Date( 2014, 0, 1 ), "getter" ); + + input.calendar( "destroy" ); + inline.calendar( "destroy" ); +}); + +test( "isValid", function() { + expect( 2 ); + var input = $( "#calendar" ).calendar(); + + input.val( "1/1/14" ); + ok( input.calendar( "isValid" ) ); + + input.val( "1/1/abc" ); + ok( !input.calendar( "isValid" ) ); + + input.calendar( "destroy" ); +}); + +})( jQuery ); diff --git a/tests/unit/calendar/calendar_options.js b/tests/unit/calendar/calendar_options.js new file mode 100644 index 00000000000..d45181e91cd --- /dev/null +++ b/tests/unit/calendar/calendar_options.js @@ -0,0 +1,1273 @@ +(function( $ ) { + +module( "calendar: options" ); + +test( "appendTo", function() { + expect( 6 ); + var container, + detached = $( "
        " ), + input = $( "#calendar" ); + + input.calendar(); + container = input.calendar( "widget" ).parent()[ 0 ]; + equal( container, document.body, "defaults to body" ); + input.calendar( "destroy" ); + + input.calendar({ appendTo: "#qunit-fixture" }); + container = input.calendar( "widget" ).parent()[ 0 ]; + equal( container, $( "#qunit-fixture" )[ 0 ], "child of specified element" ); + input.calendar( "destroy" ); + + input.calendar({ appendTo: "#does-not-exist" }); + container = input.calendar( "widget" ).parent()[ 0 ]; + equal( container, document.body, "set to body if element does not exist" ); + input.calendar( "destroy" ); + + input.calendar() + .calendar( "option", "appendTo", "#qunit-fixture" ); + container = input.calendar( "widget" ).parent()[ 0 ]; + equal( container, $( "#qunit-fixture" )[ 0 ], "modified after init" ); + input.calendar( "destroy" ); + + input.calendar({ appendTo: detached }); + container = input.calendar( "widget" ).parent()[ 0 ]; + equal( container, detached[ 0 ], "detached jQuery object" ); + input.calendar( "destroy" ); + + input.calendar({ appendTo: detached[ 0 ] }); + container = input.calendar( "widget" ).parent()[ 0 ]; + equal( container, detached[ 0 ], "detached DOM element" ); + input.calendar( "destroy" ); +}); + +test( "dateFormat", function() { + expect( 2 ); + var input = $( "#calendar" ).val( "1/1/14" ).calendar(), + picker = input.calendar( "widget" ), + firstDayLink = picker.find( "td[id]:first a" ); + + input.calendar( "open" ); + firstDayLink.trigger( "mousedown" ); + equal( input.val(), "1/1/14", "default formatting" ); + + input.calendar( "option", "dateFormat", { date: "full" } ); + equal( input.val(), "Wednesday, January 1, 2014", "updated formatting" ); + + input.calendar( "destroy" ); +}); + +test( "eachDay", function() { + expect( 5 ); + var timestamp, + input = $( "#calendar" ).calendar(), + picker = input.calendar( "widget" ), + firstCell = picker.find( "td[id]:first" ); + + equal( firstCell.find( "a" ).length, 1, "days are selectable by default" ); + timestamp = parseInt( firstCell.find( "a" ).attr( "data-timestamp" ), 10 ); + equal( new Date( timestamp ).getDate(), 1, "first available day is the 1st by default" ); + + // Do not render the 1st of the month + input.calendar( "option", "eachDay", function( day ) { + if ( day.date === 1 ) { + day.render = false; + } + }); + firstCell = picker.find( "td[id]:first" ); + timestamp = parseInt( firstCell.find( "a" ).attr( "data-timestamp" ), 10 ); + equal( new Date( timestamp ).getDate(), 2, "first available day is the 2nd" ); + + // Display the 1st of the month but make it not selectable. + input.calendar( "option", "eachDay", function( day ) { + if ( day.date === 1 ) { + day.selectable = false; + } + }); + firstCell = picker.find( "td[id]:first" ); + equal( firstCell.find( "a" ).length, 0, "the 1st is not selectable" ); + + input.calendar( "option", "eachDay", function( day ) { + if ( day.date === 1 ) { + day.extraClasses = "ui-custom"; + } + }); + ok( picker.find( "td[id]:first a" ).hasClass( "ui-custom" ), "extraClasses applied" ); + + input.calendar( "destroy" ); +}); + +test( "numberOfMonths", function() { + expect( 0 ); +}); + +asyncTest( "position", function() { + expect( 3 ); + var input = $( "" ).calendar().appendTo( "body" ).css({ + position: "absolute", + top: 0, + left: 0 + }), + container = input.calendar( "widget" ); + + input.calendar( "open" ); + setTimeout(function() { + closeEnough( input.offset().left, container.offset().left, 1, "left sides line up by default" ); + closeEnough( container.offset().top, input.offset().top + input.outerHeight(), 1, + "calendar directly under input by default" ); + + // Change the position option using option() + input.calendar( "option", "position", { + my: "left top", + at: "right bottom" + }); + closeEnough( container.offset().left, input.offset().left + input.outerWidth(), 1, + "calendar on right hand side of input after position change" ); + + input.remove(); + start(); + }); +}); + +test( "showWeek", function() { + expect( 7 ); + var input = $( "#calendar" ).calendar(), + container = input.calendar( "widget" ); + + equal( container.find( "thead th" ).length, 7, "just 7 days, no column cell" ); + equal( container.find( ".ui-calendar-week-col" ).length, 0, + "no week column cells present" ); + input.calendar( "destroy" ); + + input = $( "#calendar" ).calendar({ showWeek: true }); + container = input.calendar( "widget" ); + equal( container.find( "thead th" ).length, 8, "7 days + a column cell" ); + ok( container.find( "thead th:first" ).is( ".ui-calendar-week-col" ), + "first cell should have ui-calendar-week-col class name" ); + equal( container.find( ".ui-calendar-week-col" ).length, + container.find( "tr" ).length, "one week cell for each week" ); + input.calendar( "destroy" ); + + input = $( "#calendar" ).calendar(); + container = input.calendar( "widget" ); + equal( container.find( "thead th" ).length, 7, "no week column" ); + input.calendar( "option", "showWeek", true ); + equal( container.find( "thead th" ).length, 8, "supports changing option after init" ); +}); + +/* +test( "setDefaults", function() { + expect( 3 ); + TestHelpers.calendar.init( "#inp" ); + equal($.calendar._defaults.showOn, "focus", "Initial showOn" ); + $.calendar.setDefaults({showOn: "button"}); + equal($.calendar._defaults.showOn, "button", "Change default showOn" ); + $.calendar.setDefaults({showOn: "focus"}); + equal($.calendar._defaults.showOn, "focus", "Restore showOn" ); +}); + +test( "option", function() { + expect( 17 ); + var inp = TestHelpers.calendar.init( "#inp" ), + inst = $.data(inp[0], TestHelpers.calendar.PROP_NAME); + // Set option + equal(inst.settings.showOn, null, "Initial setting showOn" ); + equal($.calendar._get(inst, "showOn" ), "focus", "Initial instance showOn" ); + equal($.calendar._defaults.showOn, "focus", "Initial default showOn" ); + inp.calendar( "option", "showOn", "button" ); + equal(inst.settings.showOn, "button", "Change setting showOn" ); + equal($.calendar._get(inst, "showOn" ), "button", "Change instance showOn" ); + equal($.calendar._defaults.showOn, "focus", "Retain default showOn" ); + inp.calendar( "option", {showOn: "both"}); + equal(inst.settings.showOn, "both", "Change setting showOn" ); + equal($.calendar._get(inst, "showOn" ), "both", "Change instance showOn" ); + equal($.calendar._defaults.showOn, "focus", "Retain default showOn" ); + inp.calendar( "option", "showOn", undefined); + equal(inst.settings.showOn, null, "Clear setting showOn" ); + equal($.calendar._get(inst, "showOn" ), "focus", "Restore instance showOn" ); + equal($.calendar._defaults.showOn, "focus", "Retain default showOn" ); + // Get option + inp = TestHelpers.calendar.init( "#inp" ); + equal(inp.calendar( "option", "showOn" ), "focus", "Initial setting showOn" ); + inp.calendar( "option", "showOn", "button" ); + equal(inp.calendar( "option", "showOn" ), "button", "Change instance showOn" ); + inp.calendar( "option", "showOn", undefined); + equal(inp.calendar( "option", "showOn" ), "focus", "Reset instance showOn" ); + deepEqual(inp.calendar( "option", "all" ), {showAnim: ""}, "Get instance settings" ); + deepEqual(inp.calendar( "option", "defaults" ), $.calendar._defaults, + "Get default settings" ); +}); + +test( "disabled", function() { + expect(8); + var inp = TestHelpers.calendar.init( "#inp" ); + ok(!inp.calendar( "isDisabled" ), "Initially marked as enabled" ); + ok(!inp[0].disabled, "Field initially enabled" ); + inp.calendar( "option", "disabled", true); + ok(inp.calendar( "isDisabled" ), "Marked as disabled" ); + ok(inp[0].disabled, "Field now disabled" ); + inp.calendar( "option", "disabled", false); + ok(!inp.calendar( "isDisabled" ), "Marked as enabled" ); + ok(!inp[0].disabled, "Field now enabled" ); + inp.calendar( "destroy" ); + + inp = TestHelpers.calendar.init( "#inp", { disabled: true }); + ok(inp.calendar( "isDisabled" ), "Initially marked as disabled" ); + ok(inp[0].disabled, "Field initially disabled" ); +}); + +test( "change", function() { + expect( 12 ); + var inp = TestHelpers.calendar.init( "#inp" ), + inst = $.data(inp[0], TestHelpers.calendar.PROP_NAME); + equal(inst.settings.showOn, null, "Initial setting showOn" ); + equal($.calendar._get(inst, "showOn" ), "focus", "Initial instance showOn" ); + equal($.calendar._defaults.showOn, "focus", "Initial default showOn" ); + inp.calendar( "change", "showOn", "button" ); + equal(inst.settings.showOn, "button", "Change setting showOn" ); + equal($.calendar._get(inst, "showOn" ), "button", "Change instance showOn" ); + equal($.calendar._defaults.showOn, "focus", "Retain default showOn" ); + inp.calendar( "change", {showOn: "both"}); + equal(inst.settings.showOn, "both", "Change setting showOn" ); + equal($.calendar._get(inst, "showOn" ), "both", "Change instance showOn" ); + equal($.calendar._defaults.showOn, "focus", "Retain default showOn" ); + inp.calendar( "change", "showOn", undefined); + equal(inst.settings.showOn, null, "Clear setting showOn" ); + equal($.calendar._get(inst, "showOn" ), "focus", "Restore instance showOn" ); + equal($.calendar._defaults.showOn, "focus", "Retain default showOn" ); +}); + +(function() { + var url = window.location.search; + url = decodeURIComponent( url.slice( url.indexOf( "swarmURL=" ) + 9 ) ); + + // TODO: This test occassionally fails in IE in TestSwarm + if ( $.ui.ie && url && url.indexOf( "http" ) === 0 ) { + return; + } + + asyncTest( "invocation", function() { + var button, image, + isOldIE = $.ui.ie && ( !document.documentMode || document.documentMode < 9 ), + body = $( "body" ); + + expect( isOldIE ? 25 : 29 ); + + function step0() { + var inp = TestHelpers.calendar.initNewInput(), + dp = $( "#ui-calendar-div" ); + + button = inp.siblings( "button" ); + ok( button.length === 0, "Focus - button absent" ); + image = inp.siblings( "img" ); + ok( image.length === 0, "Focus - image absent" ); + + TestHelpers.calendar.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Focus - rendered on focus" ); + inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + ok( !dp.is( ":visible" ), "Focus - hidden on exit" ); + step1(); + }); + } + + function step1() { + + var inp = TestHelpers.calendar.initNewInput(), + dp = $( "#ui-calendar-div" ); + + TestHelpers.calendar.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Focus - rendered on focus" ); + body.simulate( "mousedown", {} ); + ok( !dp.is( ":visible" ), "Focus - hidden on external click" ); + inp.calendar( "hide" ).calendar( "destroy" ); + + step2(); + }); + } + + function step2() { + var inp = TestHelpers.calendar.initNewInput({ + showOn: "button", + buttonText: "Popup" + }), + dp = $( "#ui-calendar-div" ); + + ok( !dp.is( ":visible" ), "Button - initially hidden" ); + button = inp.siblings( "button" ); + image = inp.siblings( "img" ); + ok( button.length === 1, "Button - button present" ); + ok( image.length === 0, "Button - image absent" ); + equal( button.text(), "Popup", "Button - button text" ); + + TestHelpers.calendar.onFocus( inp, function() { + ok( !dp.is( ":visible" ), "Button - not rendered on focus" ); + button.click(); + ok( dp.is( ":visible" ), "Button - rendered on button click" ); + button.click(); + ok( !dp.is( ":visible" ), "Button - hidden on second button click" ); + inp.calendar( "hide" ).calendar( "destroy" ); + + step3(); + }); + } + + function step3() { + var inp = TestHelpers.calendar.initNewInput({ + showOn: "button", + buttonImageOnly: true, + buttonImage: "images/calendar.gif", + buttonText: "Cal" + }), + dp = $( "#ui-calendar-div" ); + + ok( !dp.is( ":visible" ), "Image button - initially hidden" ); + button = inp.siblings( "button" ); + ok( button.length === 0, "Image button - button absent" ); + image = inp.siblings( "img" ); + ok( image.length === 1, "Image button - image present" ); + ok( /images\/calendar\.gif$/.test( image.attr( "src" ) ), "Image button - image source" ); + equal( image.attr( "title" ), "Cal", "Image button - image text" ); + + TestHelpers.calendar.onFocus( inp, function() { + ok( !dp.is( ":visible" ), "Image button - not rendered on focus" ); + image.click(); + ok( dp.is( ":visible" ), "Image button - rendered on image click" ); + image.click(); + ok( !dp.is( ":visible" ), "Image button - hidden on second image click" ); + inp.calendar( "hide" ).calendar( "destroy" ); + + step4(); + }); + } + + function step4() { + var inp = TestHelpers.calendar.initNewInput({ + showOn: "both", + buttonImage: "images/calendar.gif" + }), + dp = $( "#ui-calendar-div" ); + + ok( !dp.is( ":visible" ), "Both - initially hidden" ); + button = inp.siblings( "button" ); + ok( button.length === 1, "Both - button present" ); + image = inp.siblings( "img" ); + ok( image.length === 0, "Both - image absent" ); + image = button.children( "img" ); + ok( image.length === 1, "Both - button image present" ); + + // TODO: This test occasionally fails to focus in IE8 in BrowserStack + if ( !isOldIE ) { + TestHelpers.calendar.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Both - rendered on focus" ); + body.simulate( "mousedown", {} ); + ok( !dp.is( ":visible" ), "Both - hidden on external click" ); + button.click(); + ok( dp.is( ":visible" ), "Both - rendered on button click" ); + button.click(); + ok( !dp.is( ":visible" ), "Both - hidden on second button click" ); + inp.calendar( "hide" ).calendar( "destroy" ); + + start(); + }); + } else { + start(); + } + } + + step0(); + }); +})(); + +test( "otherMonths", function() { + expect( 8 ); + var inp = TestHelpers.calendar.init( "#inp" ), + pop = $( "#ui-calendar-div" ); + inp.val( "06/01/2009" ).calendar( "show" ); + equal(pop.find( "tbody" ).text(), + // support: IE <9, jQuery <1.8 + // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways + $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), + "Other months - none" ); + ok(pop.find( "td:last *" ).length === 0, "Other months - no content" ); + inp.calendar( "hide" ).calendar( "option", "showOtherMonths", true).calendar( "show" ); + equal(pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", + "Other months - show" ); + ok(pop.find( "td:last span" ).length === 1, "Other months - span content" ); + inp.calendar( "hide" ).calendar( "option", "selectOtherMonths", true).calendar( "show" ); + equal(pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", + "Other months - select" ); + ok(pop.find( "td:last a" ).length === 1, "Other months - link content" ); + inp.calendar( "hide" ).calendar( "option", "showOtherMonths", false).calendar( "show" ); + equal(pop.find( "tbody" ).text(), + // support: IE <9, jQuery <1.8 + // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways + $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), + "Other months - none" ); + ok(pop.find( "td:last *" ).length === 0, "Other months - no content" ); +}); + +test( "defaultDate", function() { + expect( 16 ); + var inp = TestHelpers.calendar.init( "#inp" ), + date = new Date(); + inp.val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date null" ); + + // Numeric values + inp.calendar( "option", {defaultDate: -2}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() - 2); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date -2" ); + + date = new Date(); + inp.calendar( "option", {defaultDate: 3}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 3); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date 3" ); + + date = new Date(); + inp.calendar( "option", {defaultDate: 1 / "a"}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date NaN" ); + + // String offset values + inp.calendar( "option", {defaultDate: "-1d"}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() - 1); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date -1d" ); + inp.calendar( "option", {defaultDate: "+3D"}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 4); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date +3D" ); + inp.calendar( "option", {defaultDate: " -2 w "}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(); + date.setDate(date.getDate() - 14); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date -2 w" ); + inp.calendar( "option", {defaultDate: "+1 W"}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 21); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date +1 W" ); + inp.calendar( "option", {defaultDate: " -1 m "}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date = TestHelpers.calendar.addMonths(new Date(), -1); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date -1 m" ); + inp.calendar( "option", {defaultDate: "+2M"}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date = TestHelpers.calendar.addMonths(new Date(), 2); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date +2M" ); + inp.calendar( "option", {defaultDate: "-2y"}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(); + date.setFullYear(date.getFullYear() - 2); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date -2y" ); + inp.calendar( "option", {defaultDate: "+1 Y "}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setFullYear(date.getFullYear() + 3); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date +1 Y" ); + inp.calendar( "option", {defaultDate: "+1M +10d"}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date = TestHelpers.calendar.addMonths(new Date(), 1); + date.setDate(date.getDate() + 10); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date +1M +10d" ); + // String date values + inp.calendar( "option", {defaultDate: "07/04/2007"}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(2007, 7 - 1, 4); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date 07/04/2007" ); + inp.calendar( "option", {dateFormat: "yy-mm-dd", defaultDate: "2007-04-02"}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(2007, 4 - 1, 2); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date 2007-04-02" ); + // Date value + date = new Date(2007, 1 - 1, 26); + inp.calendar( "option", {dateFormat: "mm/dd/yy", defaultDate: date}). + calendar( "hide" ).val( "" ).calendar( "show" ). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, "Default date 01/26/2007" ); +}); + +test( "miscellaneous", function() { + expect( 19 ); + var curYear, longNames, shortNames, date, + dp = $( "#ui-calendar-div" ), + inp = TestHelpers.calendar.init( "#inp" ); + // Year range + function genRange(start, offset) { + var i = start, + range = ""; + for (; i < start + offset; i++) { + range += i; + } + return range; + } + curYear = new Date().getFullYear(); + inp.val( "02/04/2008" ).calendar( "show" ); + equal(dp.find( ".ui-calendar-year" ).text(), "2008", "Year range - read-only default" ); + inp.calendar( "hide" ).calendar( "option", {changeYear: true}).calendar( "show" ); + equal(dp.find( ".ui-calendar-year" ).text(), genRange(2008 - 10, 21), "Year range - changeable default" ); + inp.calendar( "hide" ).calendar( "option", {yearRange: "c-6:c+2", changeYear: true}).calendar( "show" ); + equal(dp.find( ".ui-calendar-year" ).text(), genRange(2008 - 6, 9), "Year range - c-6:c+2" ); + inp.calendar( "hide" ).calendar( "option", {yearRange: "2000:2010", changeYear: true}).calendar( "show" ); + equal(dp.find( ".ui-calendar-year" ).text(), genRange(2000, 11), "Year range - 2000:2010" ); + inp.calendar( "hide" ).calendar( "option", {yearRange: "-5:+3", changeYear: true}).calendar( "show" ); + equal(dp.find( ".ui-calendar-year" ).text(), genRange(curYear - 5, 9), "Year range - -5:+3" ); + inp.calendar( "hide" ).calendar( "option", {yearRange: "2000:-5", changeYear: true}).calendar( "show" ); + equal(dp.find( ".ui-calendar-year" ).text(), genRange(2000, curYear - 2004), "Year range - 2000:-5" ); + inp.calendar( "hide" ).calendar( "option", {yearRange: "", changeYear: true}).calendar( "show" ); + equal(dp.find( ".ui-calendar-year" ).text(), genRange(curYear, 1), "Year range - -6:+2" ); + + // Navigation as date format + inp.calendar( "option", {showButtonPanel: true}); + equal(dp.find( ".ui-calendar-prev" ).text(), "Prev", "Navigation prev - default" ); + equal(dp.find( ".ui-calendar-current" ).text(), "Today", "Navigation current - default" ); + equal(dp.find( ".ui-calendar-next" ).text(), "Next", "Navigation next - default" ); + inp.calendar( "hide" ).calendar( "option", {navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >"}). + val( "02/04/2008" ).calendar( "show" ); + longNames = $.calendar.regional[""].monthNames; + shortNames = $.calendar.regional[""].monthNamesShort; + date = new Date(); + equal(dp.find( ".ui-calendar-prev" ).text(), "< " + shortNames[0], "Navigation prev - as date format" ); + equal(dp.find( ".ui-calendar-current" ).text(), + longNames[date.getMonth()], "Navigation current - as date format" ); + equal(dp.find( ".ui-calendar-next" ).text(), + shortNames[2] + " >", "Navigation next - as date format" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); + equal(dp.find( ".ui-calendar-prev" ).text(), + "< " + shortNames[1], "Navigation prev - as date format + pgdn" ); + equal(dp.find( ".ui-calendar-current" ).text(), + longNames[date.getMonth()], "Navigation current - as date format + pgdn" ); + equal(dp.find( ".ui-calendar-next" ).text(), + shortNames[3] + " >", "Navigation next - as date format + pgdn" ); + inp.calendar( "hide" ).calendar( "option", {gotoCurrent: true}). + val( "02/04/2008" ).calendar( "show" ); + equal(dp.find( ".ui-calendar-prev" ).text(), + "< " + shortNames[0], "Navigation prev - as date format + goto current" ); + equal(dp.find( ".ui-calendar-current" ).text(), + longNames[1], "Navigation current - as date format + goto current" ); + equal(dp.find( ".ui-calendar-next" ).text(), + shortNames[2] + " >", "Navigation next - as date format + goto current" ); +}); + +test( "minMax", function() { + expect( 23 ); + var date, + inp = TestHelpers.calendar.init( "#inp" ), + dp = $( "#ui-calendar-div" ), + lastYear = new Date(2007, 6 - 1, 4), + nextYear = new Date(2009, 6 - 1, 4), + minDate = new Date(2008, 2 - 1, 29), + maxDate = new Date(2008, 12 - 1, 7); + inp.val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), lastYear, + "Min/max - null, null - ctrl+pgup" ); + inp.val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), nextYear, + "Min/max - null, null - ctrl+pgdn" ); + inp.calendar( "option", {minDate: minDate}). + calendar( "hide" ).val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), minDate, + "Min/max - 02/29/2008, null - ctrl+pgup" ); + inp.val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), nextYear, + "Min/max - 02/29/2008, null - ctrl+pgdn" ); + inp.calendar( "option", {maxDate: maxDate}). + calendar( "hide" ).val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), minDate, + "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup" ); + inp.val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), maxDate, + "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn" ); + inp.calendar( "option", {minDate: null}). + calendar( "hide" ).val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), lastYear, + "Min/max - null, 12/07/2008 - ctrl+pgup" ); + inp.val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), maxDate, + "Min/max - null, 12/07/2008 - ctrl+pgdn" ); + // Relative dates + date = new Date(); + date.setDate(date.getDate() - 7); + inp.calendar( "option", {minDate: "-1w", maxDate: "+1 M +10 D "}). + calendar( "hide" ).val( "" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, + "Min/max - -1w, +1 M +10 D - ctrl+pgup" ); + date = TestHelpers.calendar.addMonths(new Date(), 1); + date.setDate(date.getDate() + 10); + inp.val( "" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date, + "Min/max - -1w, +1 M +10 D - ctrl+pgdn" ); + // With existing date + inp = TestHelpers.calendar.init( "#inp" ); + inp.val( "06/04/2008" ).calendar( "option", {minDate: minDate}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), new Date(2008, 6 - 1, 4), "Min/max - setDate > min" ); + inp.calendar( "option", {minDate: null}).val( "01/04/2008" ).calendar( "option", {minDate: minDate}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), minDate, "Min/max - setDate < min" ); + inp.calendar( "option", {minDate: null}).val( "06/04/2008" ).calendar( "option", {maxDate: maxDate}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), new Date(2008, 6 - 1, 4), "Min/max - setDate < max" ); + inp.calendar( "option", {maxDate: null}).val( "01/04/2009" ).calendar( "option", {maxDate: maxDate}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), maxDate, "Min/max - setDate > max" ); + inp.calendar( "option", {maxDate: null}).val( "01/04/2008" ).calendar( "option", {minDate: minDate, maxDate: maxDate}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), minDate, "Min/max - setDate < min" ); + inp.calendar( "option", {maxDate: null}).val( "06/04/2008" ).calendar( "option", {minDate: minDate, maxDate: maxDate}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), new Date(2008, 6 - 1, 4), "Min/max - setDate > min, < max" ); + inp.calendar( "option", {maxDate: null}).val( "01/04/2009" ).calendar( "option", {minDate: minDate, maxDate: maxDate}); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), maxDate, "Min/max - setDate > max" ); + + inp.calendar( "option", {yearRange: "-0:+1"}).val( "01/01/" + new Date().getFullYear()); + ok(dp.find( ".ui-calendar-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - previous button disabled at 1/1/minYear" ); + inp.calendar( "setDate", "12/30/" + new Date().getFullYear()); + ok(dp.find( ".ui-calendar-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled at 12/30/maxYear" ); + + inp.calendar( "option", { + minDate: new Date(1900, 0, 1), + maxDate: "-6Y", + yearRange: "1900:-6" + }).val( "" ); + ok(dp.find( ".ui-calendar-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled" ); + ok(!dp.find( ".ui-calendar-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - prev button enabled" ); + + inp.calendar( "option", { + minDate: new Date(1900, 0, 1), + maxDate: "1/25/2007", + yearRange: "1900:2007" + }).val( "" ); + ok(dp.find( ".ui-calendar-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled" ); + ok(!dp.find( ".ui-calendar-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - prev button enabled" ); +}); + +test( "setDate", function() { + expect( 24 ); + var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, + inp = TestHelpers.calendar.init( "#inp" ), + date1 = new Date(2008, 6 - 1, 4), + date2 = new Date(); + ok(inp.calendar( "getDate" ) == null, "Set date - default" ); + inp.calendar( "setDate", date1); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date1, "Set date - 2008-06-04" ); + date1 = new Date(); + date1.setDate(date1.getDate() + 7); + inp.calendar( "setDate", +7); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date1, "Set date - +7" ); + date2.setFullYear(date2.getFullYear() + 2); + inp.calendar( "setDate", "+2y" ); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date2, "Set date - +2y" ); + inp.calendar( "setDate", date1, date2); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date1, "Set date - two dates" ); + inp.calendar( "setDate" ); + ok(inp.calendar( "getDate" ) == null, "Set date - null" ); + // Relative to current date + date1 = new Date(); + date1.setDate(date1.getDate() + 7); + inp.calendar( "setDate", "c +7" ); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date1, "Set date - c +7" ); + date1.setDate(date1.getDate() + 7); + inp.calendar( "setDate", "c+7" ); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date1, "Set date - c+7" ); + date1.setDate(date1.getDate() - 21); + inp.calendar( "setDate", "c -3 w" ); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date1, "Set date - c -3 w" ); + // Inline + inl = TestHelpers.calendar.init( "#inl" ); + date1 = new Date(2008, 6 - 1, 4); + date2 = new Date(); + TestHelpers.calendar.equalsDate(inl.calendar( "getDate" ), date2, "Set date inline - default" ); + inl.calendar( "setDate", date1); + TestHelpers.calendar.equalsDate(inl.calendar( "getDate" ), date1, "Set date inline - 2008-06-04" ); + date1 = new Date(); + date1.setDate(date1.getDate() + 7); + inl.calendar( "setDate", +7); + TestHelpers.calendar.equalsDate(inl.calendar( "getDate" ), date1, "Set date inline - +7" ); + date2.setFullYear(date2.getFullYear() + 2); + inl.calendar( "setDate", "+2y" ); + TestHelpers.calendar.equalsDate(inl.calendar( "getDate" ), date2, "Set date inline - +2y" ); + inl.calendar( "setDate", date1, date2); + TestHelpers.calendar.equalsDate(inl.calendar( "getDate" ), date1, "Set date inline - two dates" ); + inl.calendar( "setDate" ); + ok(inl.calendar( "getDate" ) == null, "Set date inline - null" ); + // Alternate field + alt = $( "#alt" ); + inp.calendar( "option", {altField: "#alt", altFormat: "yy-mm-dd"}); + date1 = new Date(2008, 6 - 1, 4); + inp.calendar( "setDate", date1); + equal(inp.val(), "06/04/2008", "Set date alternate - 06/04/2008" ); + equal(alt.val(), "2008-06-04", "Set date alternate - 2008-06-04" ); + // With minimum/maximum + inp = TestHelpers.calendar.init( "#inp" ); + date1 = new Date(2008, 1 - 1, 4); + date2 = new Date(2008, 6 - 1, 4); + minDate = new Date(2008, 2 - 1, 29); + maxDate = new Date(2008, 3 - 1, 28); + inp.val( "" ).calendar( "option", {minDate: minDate}).calendar( "setDate", date2); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date2, "Set date min/max - setDate > min" ); + inp.calendar( "setDate", date1); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), minDate, "Set date min/max - setDate < min" ); + inp.val( "" ).calendar( "option", {maxDate: maxDate, minDate: null}).calendar( "setDate", date1); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), date1, "Set date min/max - setDate < max" ); + inp.calendar( "setDate", date2); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), maxDate, "Set date min/max - setDate > max" ); + inp.val( "" ).calendar( "option", {minDate: minDate}).calendar( "setDate", date1); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), minDate, "Set date min/max - setDate < min" ); + inp.calendar( "setDate", date2); + TestHelpers.calendar.equalsDate(inp.calendar( "getDate" ), maxDate, "Set date min/max - setDate > max" ); + dateAndTimeToSet = new Date(2008, 3 - 1, 28, 1, 11, 0); + dateAndTimeClone = new Date(2008, 3 - 1, 28, 1, 11, 0); + inp.calendar( "setDate", dateAndTimeToSet); + equal(dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate" ); +}); + +test( "altField", function() { + expect( 10 ); + var inp = TestHelpers.calendar.init( "#inp" ), + alt = $( "#alt" ); + // No alternate field set + alt.val( "" ); + inp.val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(inp.val(), "06/04/2008", "Alt field - dp - enter" ); + equal(alt.val(), "", "Alt field - alt not set" ); + // Alternate field set + alt.val( "" ); + inp.calendar( "option", {altField: "#alt", altFormat: "yy-mm-dd"}). + val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(inp.val(), "06/04/2008", "Alt field - dp - enter" ); + equal(alt.val(), "2008-06-04", "Alt field - alt - enter" ); + // Move from initial date + alt.val( "" ); + inp.val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(inp.val(), "07/04/2008", "Alt field - dp - pgdn" ); + equal(alt.val(), "2008-07-04", "Alt field - alt - pgdn" ); + // Alternate field set - closed + alt.val( "" ); + inp.val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc" ); + equal(alt.val(), "", "Alt field - alt - pgdn/esc" ); + // Clear date and alternate + alt.val( "" ); + inp.val( "06/04/2008" ).calendar( "show" ); + inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); + equal(inp.val(), "", "Alt field - dp - ctrl+end" ); + equal(alt.val(), "", "Alt field - alt - ctrl+end" ); +}); + +test( "autoSize", function() { + expect( 15 ); + var inp = TestHelpers.calendar.init( "#inp" ); + equal(inp.prop( "size" ), 20, "Auto size - default" ); + inp.calendar( "option", "autoSize", true); + equal(inp.prop( "size" ), 10, "Auto size - mm/dd/yy" ); + inp.calendar( "option", "dateFormat", "m/d/yy" ); + equal(inp.prop( "size" ), 10, "Auto size - m/d/yy" ); + inp.calendar( "option", "dateFormat", "D M d yy" ); + equal(inp.prop( "size" ), 15, "Auto size - D M d yy" ); + inp.calendar( "option", "dateFormat", "DD, MM dd, yy" ); + equal(inp.prop( "size" ), 29, "Auto size - DD, MM dd, yy" ); + + // French + inp.calendar( "option", $.extend({autoSize: false}, $.calendar.regional.fr)); + equal(inp.prop( "size" ), 29, "Auto size - fr - default" ); + inp.calendar( "option", "autoSize", true); + equal(inp.prop( "size" ), 10, "Auto size - fr - dd/mm/yy" ); + inp.calendar( "option", "dateFormat", "m/d/yy" ); + equal(inp.prop( "size" ), 10, "Auto size - fr - m/d/yy" ); + inp.calendar( "option", "dateFormat", "D M d yy" ); + equal(inp.prop( "size" ), 18, "Auto size - fr - D M d yy" ); + inp.calendar( "option", "dateFormat", "DD, MM dd, yy" ); + equal(inp.prop( "size" ), 28, "Auto size - fr - DD, MM dd, yy" ); + + // Hebrew + inp.calendar( "option", $.extend({autoSize: false}, $.calendar.regional.he)); + equal(inp.prop( "size" ), 28, "Auto size - he - default" ); + inp.calendar( "option", "autoSize", true); + equal(inp.prop( "size" ), 10, "Auto size - he - dd/mm/yy" ); + inp.calendar( "option", "dateFormat", "m/d/yy" ); + equal(inp.prop( "size" ), 10, "Auto size - he - m/d/yy" ); + inp.calendar( "option", "dateFormat", "D M d yy" ); + equal(inp.prop( "size" ), 16, "Auto size - he - D M d yy" ); + inp.calendar( "option", "dateFormat", "DD, MM dd, yy" ); + equal(inp.prop( "size" ), 23, "Auto size - he - DD, MM dd, yy" ); +}); + +test( "daylightSaving", function() { + expect( 25 ); + var inp = TestHelpers.calendar.init( "#inp" ), + dp = $( "#ui-calendar-div" ); + ok(true, "Daylight saving - " + new Date()); + // Australia, Sydney - AM change, southern hemisphere + inp.val( "04/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" ); + equal(inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008" ); + inp.val( "04/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" ); + equal(inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008" ); + inp.val( "04/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" ); + equal(inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008" ); + inp.val( "10/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" ); + equal(inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008" ); + inp.val( "10/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" ); + equal(inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008" ); + inp.val( "10/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" ); + equal(inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008" ); + // Brasil, Brasilia - midnight change, southern hemisphere + inp.val( "02/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(20) a", dp).simulate( "click" ); + equal(inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008" ); + inp.val( "02/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(21) a", dp).simulate( "click" ); + equal(inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008" ); + inp.val( "02/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(22) a", dp).simulate( "click" ); + equal(inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008" ); + inp.val( "10/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(13) a", dp).simulate( "click" ); + equal(inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008" ); + inp.val( "10/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(14) a", dp).simulate( "click" ); + equal(inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008" ); + inp.val( "10/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(15) a", dp).simulate( "click" ); + equal(inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008" ); + // Lebanon, Beirut - midnight change, northern hemisphere + inp.val( "03/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(34) a", dp).simulate( "click" ); + equal(inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008" ); + inp.val( "03/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(35) a", dp).simulate( "click" ); + equal(inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008" ); + inp.val( "03/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(36) a", dp).simulate( "click" ); + equal(inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008" ); + inp.val( "10/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(27) a", dp).simulate( "click" ); + equal(inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008" ); + inp.val( "10/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(28) a", dp).simulate( "click" ); + equal(inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008" ); + inp.val( "10/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(29) a", dp).simulate( "click" ); + equal(inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008" ); + // US, Eastern - AM change, northern hemisphere + inp.val( "03/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(13) a", dp).simulate( "click" ); + equal(inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008" ); + inp.val( "03/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(14) a", dp).simulate( "click" ); + equal(inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008" ); + inp.val( "03/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(15) a", dp).simulate( "click" ); + equal(inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008" ); + inp.val( "11/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" ); + equal(inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008" ); + inp.val( "11/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" ); + equal(inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008" ); + inp.val( "11/01/2008" ).calendar( "show" ); + $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" ); + equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" ); +}); + +var beforeShowThis = null, + beforeShowInput = null, + beforeShowInst = null, + beforeShowDayThis = null, + beforeShowDayOK = true; + + +function beforeAll(input, inst) { + beforeShowThis = this; + beforeShowInput = input; + beforeShowInst = inst; + return {currentText: "Current"}; +} + +function beforeDay(date) { + beforeShowDayThis = this; + beforeShowDayOK &= (date > new Date(2008, 1 - 1, 26) && + date < new Date(2008, 3 - 1, 6)); + return [(date.getDate() % 2 === 0), (date.getDate() % 10 === 0 ? "day10" : "" ), + (date.getDate() % 3 === 0 ? "Divisble by 3" : "" )]; +} + +test( "callbacks", function() { + expect( 13 ); + // Before show + var dp, day20, day21, + inp = TestHelpers.calendar.init( "#inp", {beforeShow: beforeAll}), + inst = $.data(inp[0], "calendar" ); + equal($.calendar._get(inst, "currentText" ), "Today", "Before show - initial" ); + inp.val( "02/04/2008" ).calendar( "show" ); + equal($.calendar._get(inst, "currentText" ), "Current", "Before show - changed" ); + ok(beforeShowThis.id === inp[0].id, "Before show - this OK" ); + ok(beforeShowInput.id === inp[0].id, "Before show - input OK" ); + deepEqual(beforeShowInst, inst, "Before show - inst OK" ); + inp.calendar( "hide" ).calendar( "destroy" ); + // Before show day + inp = TestHelpers.calendar.init( "#inp", {beforeShowDay: beforeDay}); + dp = $( "#ui-calendar-div" ); + inp.val( "02/04/2008" ).calendar( "show" ); + ok(beforeShowDayThis.id === inp[0].id, "Before show day - this OK" ); + ok(beforeShowDayOK, "Before show day - dates OK" ); + day20 = dp.find( ".ui-calendar-calendar td:contains('20')" ); + day21 = dp.find( ".ui-calendar-calendar td:contains('21')" ); + ok(!day20.is( ".ui-calendar-unselectable" ), "Before show day - unselectable 20" ); + ok(day21.is( ".ui-calendar-unselectable" ), "Before show day - unselectable 21" ); + ok(day20.is( ".day10" ), "Before show day - CSS 20" ); + ok(!day21.is( ".day10" ), "Before show day - CSS 21" ); + ok(!day20.attr( "title" ), "Before show day - title 20" ); + ok(day21.attr( "title" ) === "Divisble by 3", "Before show day - title 21" ); + inp.calendar( "hide" ).calendar( "destroy" ); +}); + +test( "beforeShowDay - tooltips with quotes", function() { + expect( 1 ); + var inp, dp; + inp = TestHelpers.calendar.init( "#inp", { + beforeShowDay: function() { + return [ true, "", "'" ]; + } + }); + dp = $( "#ui-calendar-div" ); + + inp.calendar( "show" ); + equal( dp.find( ".ui-calendar-calendar td:contains('9')" ).attr( "title" ), "'" ); + inp.calendar( "hide" ).calendar( "destroy" ); +}); + +test( "localisation", function() { + expect( 24 ); + var dp, month, day, date, + inp = TestHelpers.calendar.init( "#inp", $.calendar.regional.fr); + inp.calendar( "option", {dateFormat: "DD, d MM yy", showButtonPanel:true, changeMonth:true, changeYear:true}).val( "" ).calendar( "show" ); + dp = $( "#ui-calendar-div" ); + equal($( ".ui-calendar-close", dp).text(), "Fermer", "Localisation - close" ); + $( ".ui-calendar-close", dp).simulate( "mouseover" ); + equal($( ".ui-calendar-prev", dp).text(), "Précédent", "Localisation - previous" ); + equal($( ".ui-calendar-current", dp).text(), "Aujourd'hui", "Localisation - current" ); + equal($( ".ui-calendar-next", dp).text(), "Suivant", "Localisation - next" ); + month = 0; + $( ".ui-calendar-month option", dp).each(function() { + equal($(this).text(), $.calendar.regional.fr.monthNamesShort[month], + "Localisation - month " + month); + month++; + }); + day = 1; + $( ".ui-calendar-calendar th", dp).each(function() { + equal($(this).text(), $.calendar.regional.fr.dayNamesMin[day], + "Localisation - day " + day); + day = (day + 1) % 7; + }); + inp.simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(); + equal(inp.val(), $.calendar.regional.fr.dayNames[date.getDay()] + ", " + + date.getDate() + " " + $.calendar.regional.fr.monthNames[date.getMonth()] + + " " + date.getFullYear(), "Localisation - formatting" ); +}); + +test( "noWeekends", function() { + expect( 31 ); + var i, date; + for (i = 1; i <= 31; i++) { + date = new Date(2001, 1 - 1, i); + deepEqual($.calendar.noWeekends(date), [(i + 1) % 7 >= 2, ""], + "No weekends " + date); + } +}); + +test( "iso8601Week", function() { + expect( 12 ); + var date = new Date(2000, 12 - 1, 31); + equal($.calendar.iso8601Week(date), 52, "ISO 8601 week " + date); + date = new Date(2001, 1 - 1, 1); + equal($.calendar.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2001, 1 - 1, 7); + equal($.calendar.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2001, 1 - 1, 8); + equal($.calendar.iso8601Week(date), 2, "ISO 8601 week " + date); + date = new Date(2003, 12 - 1, 28); + equal($.calendar.iso8601Week(date), 52, "ISO 8601 week " + date); + date = new Date(2003, 12 - 1, 29); + equal($.calendar.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2004, 1 - 1, 4); + equal($.calendar.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2004, 1 - 1, 5); + equal($.calendar.iso8601Week(date), 2, "ISO 8601 week " + date); + date = new Date(2009, 12 - 1, 28); + equal($.calendar.iso8601Week(date), 53, "ISO 8601 week " + date); + date = new Date(2010, 1 - 1, 3); + equal($.calendar.iso8601Week(date), 53, "ISO 8601 week " + date); + date = new Date(2010, 1 - 1, 4); + equal($.calendar.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2010, 1 - 1, 10); + equal($.calendar.iso8601Week(date), 1, "ISO 8601 week " + date); +}); + +test( "parseDate", function() { + expect( 26 ); + TestHelpers.calendar.init( "#inp" ); + var currentYear, gmtDate, fr, settings, zh; + ok($.calendar.parseDate( "d m y", "" ) == null, "Parse date empty" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "d m y", "3 2 01" ), + new Date(2001, 2 - 1, 3), "Parse date d m y" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "dd mm yy", "03 02 2001" ), + new Date(2001, 2 - 1, 3), "Parse date dd mm yy" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "d m y", "13 12 01" ), + new Date(2001, 12 - 1, 13), "Parse date d m y" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "dd mm yy", "13 12 2001" ), + new Date(2001, 12 - 1, 13), "Parse date dd mm yy" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "y-o", "01-34" ), + new Date(2001, 2 - 1, 3), "Parse date y-o" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "yy-oo", "2001-347" ), + new Date(2001, 12 - 1, 13), "Parse date yy-oo" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "oo yy", "348 2004" ), + new Date(2004, 12 - 1, 13), "Parse date oo yy" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "D d M y", "Sat 3 Feb 01" ), + new Date(2001, 2 - 1, 3), "Parse date D d M y" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "d MM DD yy", "3 February Saturday 2001" ), + new Date(2001, 2 - 1, 3), "Parse date dd MM DD yy" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "DD, MM d, yy", "Saturday, February 3, 2001" ), + new Date(2001, 2 - 1, 3), "Parse date DD, MM d, yy" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "'day' d 'of' MM (''DD''), yy", + "day 3 of February ('Saturday'), 2001" ), new Date(2001, 2 - 1, 3), + "Parse date 'day' d 'of' MM (''DD''), yy" ); + currentYear = new Date().getFullYear(); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "y-m-d", (currentYear - 2000) + "-02-03" ), + new Date(currentYear, 2 - 1, 3), "Parse date y-m-d - default cutuff" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "y-m-d", (currentYear - 2000 + 10) + "-02-03" ), + new Date(currentYear+10, 2 - 1, 3), "Parse date y-m-d - default cutuff" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "y-m-d", (currentYear - 2000 + 11) + "-02-03" ), + new Date(currentYear-89, 2 - 1, 3), "Parse date y-m-d - default cutuff" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "y-m-d", "80-02-03", {shortYearCutoff: 80}), + new Date(2080, 2 - 1, 3), "Parse date y-m-d - cutoff 80" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "y-m-d", "81-02-03", {shortYearCutoff: 80}), + new Date(1981, 2 - 1, 3), "Parse date y-m-d - cutoff 80" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "y-m-d", (currentYear - 2000 + 60) + "-02-03", {shortYearCutoff: "+60"}), + new Date(currentYear + 60, 2 - 1, 3), "Parse date y-m-d - cutoff +60" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "y-m-d", (currentYear - 2000 + 61) + "-02-03", {shortYearCutoff: "+60"}), + new Date(currentYear - 39, 2 - 1, 3), "Parse date y-m-d - cutoff +60" ); + gmtDate = new Date(2001, 2 - 1, 3); + gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "@", "981158400000" ), gmtDate, "Parse date @" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "!", "631167552000000000" ), gmtDate, "Parse date !" ); + + fr = $.calendar.regional.fr; + settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, + monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; + TestHelpers.calendar.equalsDate($.calendar.parseDate( "D d M y", "Lun. 9 Avril 01", settings), + new Date(2001, 4 - 1, 9), "Parse date D M y with settings" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "d MM DD yy", "9 Avril Lundi 2001", settings), + new Date(2001, 4 - 1, 9), "Parse date d MM DD yy with settings" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "DD, MM d, yy", "Lundi, Avril 9, 2001", settings), + new Date(2001, 4 - 1, 9), "Parse date DD, MM d, yy with settings" ); + TestHelpers.calendar.equalsDate($.calendar.parseDate( "'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings), + new Date(2001, 4 - 1, 9), "Parse date 'jour' d 'de' MM (''DD''), yy with settings" ); + + zh = $.calendar.regional["zh-CN"]; + TestHelpers.calendar.equalsDate($.calendar.parseDate( "yy M d", "2011 十一月 22", zh), + new Date(2011, 11 - 1, 22), "Parse date yy M d with zh-CN" ); +}); + +test( "parseDateErrors", function() { + expect( 17 ); + TestHelpers.calendar.init( "#inp" ); + var fr, settings; + function expectError(expr, value, error) { + try { + expr(); + ok(false, "Parsed error " + value); + } + catch (e) { + equal(e, error, "Parsed error " + value); + } + } + expectError(function() { $.calendar.parseDate(null, "Sat 2 01" ); }, + "Sat 2 01", "Invalid arguments" ); + expectError(function() { $.calendar.parseDate( "d m y", null); }, + "null", "Invalid arguments" ); + expectError(function() { $.calendar.parseDate( "d m y", "Sat 2 01" ); }, + "Sat 2 01 - d m y", "Missing number at position 0" ); + expectError(function() { $.calendar.parseDate( "dd mm yy", "Sat 2 01" ); }, + "Sat 2 01 - dd mm yy", "Missing number at position 0" ); + expectError(function() { $.calendar.parseDate( "d m y", "3 Feb 01" ); }, + "3 Feb 01 - d m y", "Missing number at position 2" ); + expectError(function() { $.calendar.parseDate( "dd mm yy", "3 Feb 01" ); }, + "3 Feb 01 - dd mm yy", "Missing number at position 2" ); + expectError(function() { $.calendar.parseDate( "d m y", "3 2 AD01" ); }, + "3 2 AD01 - d m y", "Missing number at position 4" ); + expectError(function() { $.calendar.parseDate( "d m yy", "3 2 AD01" ); }, + "3 2 AD01 - dd mm yy", "Missing number at position 4" ); + expectError(function() { $.calendar.parseDate( "y-o", "01-D01" ); }, + "2001-D01 - y-o", "Missing number at position 3" ); + expectError(function() { $.calendar.parseDate( "yy-oo", "2001-D01" ); }, + "2001-D01 - yy-oo", "Missing number at position 5" ); + expectError(function() { $.calendar.parseDate( "D d M y", "D7 3 Feb 01" ); }, + "D7 3 Feb 01 - D d M y", "Unknown name at position 0" ); + expectError(function() { $.calendar.parseDate( "D d M y", "Sat 3 M2 01" ); }, + "Sat 3 M2 01 - D d M y", "Unknown name at position 6" ); + expectError(function() { $.calendar.parseDate( "DD, MM d, yy", "Saturday- Feb 3, 2001" ); }, + "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8" ); + expectError(function() { $.calendar.parseDate( "'day' d 'of' MM (''DD''), yy", + "day 3 of February (\"Saturday\" ), 2001" ); }, + "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19" ); + expectError(function() { $.calendar.parseDate( "d m y", "29 2 01" ); }, + "29 2 01 - d m y", "Invalid date" ); + fr = $.calendar.regional.fr; + settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, + monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; + expectError(function() { $.calendar.parseDate( "D d M y", "Mon 9 Avr 01", settings); }, + "Mon 9 Avr 01 - D d M y", "Unknown name at position 0" ); + expectError(function() { $.calendar.parseDate( "D d M y", "Lun. 9 Apr 01", settings); }, + "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7" ); +}); + +test( "Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function() { + expect( 4 ); + var date; + try{ + date = $.calendar.parseDate( "dd/mm/yy", "18/04/19881" ); + ok(false, "Did not properly detect an invalid date" ); + }catch(e){ + ok( "invalid date detected" ); + } + + try { + date = $.calendar.parseDate( "dd/mm/yy", "18/04/1988 @ 2:43 pm" ); + equal(date.getDate(), 18); + equal(date.getMonth(), 3); + equal(date.getFullYear(), 1988); + } catch(e) { + ok(false, "Did not properly parse date with extra text separated by whitespace" ); + } +}); + +test( "formatDate", function() { + expect( 16 ); + TestHelpers.calendar.init( "#inp" ); + var gmtDate, fr, settings; + equal($.calendar.formatDate( "d m y", new Date(2001, 2 - 1, 3)), + "3 2 01", "Format date d m y" ); + equal($.calendar.formatDate( "dd mm yy", new Date(2001, 2 - 1, 3)), + "03 02 2001", "Format date dd mm yy" ); + equal($.calendar.formatDate( "d m y", new Date(2001, 12 - 1, 13)), + "13 12 01", "Format date d m y" ); + equal($.calendar.formatDate( "dd mm yy", new Date(2001, 12 - 1, 13)), + "13 12 2001", "Format date dd mm yy" ); + equal($.calendar.formatDate( "yy-o", new Date(2001, 2 - 1, 3)), + "2001-34", "Format date yy-o" ); + equal($.calendar.formatDate( "yy-oo", new Date(2001, 2 - 1, 3)), + "2001-034", "Format date yy-oo" ); + equal($.calendar.formatDate( "D M y", new Date(2001, 2 - 1, 3)), + "Sat Feb 01", "Format date D M y" ); + equal($.calendar.formatDate( "DD MM yy", new Date(2001, 2 - 1, 3)), + "Saturday February 2001", "Format date DD MM yy" ); + equal($.calendar.formatDate( "DD, MM d, yy", new Date(2001, 2 - 1, 3)), + "Saturday, February 3, 2001", "Format date DD, MM d, yy" ); + equal($.calendar.formatDate( "'day' d 'of' MM (''DD''), yy", + new Date(2001, 2 - 1, 3)), "day 3 of February ('Saturday'), 2001", + "Format date 'day' d 'of' MM ('DD'), yy" ); + gmtDate = new Date(2001, 2 - 1, 3); + gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() ); + equal($.calendar.formatDate( "@", gmtDate), "981158400000", "Format date @" ); + equal($.calendar.formatDate( "!", gmtDate), "631167552000000000", "Format date !" ); + fr = $.calendar.regional.fr; + settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, + monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; + equal($.calendar.formatDate( "D M y", new Date(2001, 4 - 1, 9), settings), + "lun. avril 01", "Format date D M y with settings" ); + equal($.calendar.formatDate( "DD MM yy", new Date(2001, 4 - 1, 9), settings), + "lundi avril 2001", "Format date DD MM yy with settings" ); + equal($.calendar.formatDate( "DD, MM d, yy", new Date(2001, 4 - 1, 9), settings), + "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings" ); + equal($.calendar.formatDate( "'jour' d 'de' MM (''DD''), yy", + new Date(2001, 4 - 1, 9), settings), "jour 9 de avril ('lundi'), 2001", + "Format date 'jour' d 'de' MM (''DD''), yy with settings" ); +}); + +// TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos +// test( "Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ +// expect( 1 ); +// var time = $.calendar.formatDate( "oo", new Date( "2010/03/30 12:00:00 CDT" )); +// equal(time, "089" ); +// }); + +test( "Ticket 7602: Stop calendar from appearing with beforeShow event handler", function() { + expect( 3 ); + + var inp, dp; + + inp = TestHelpers.calendar.init( "#inp", { + beforeShow: function() { + } + }); + dp = $( "#ui-calendar-div" ); + inp.calendar( "show" ); + equal( dp.css( "display" ), "block", "beforeShow returns nothing" ); + inp.calendar( "hide" ).calendar( "destroy" ); + + inp = TestHelpers.calendar.init( "#inp", { + beforeShow: function() { + return true; + } + }); + dp = $( "#ui-calendar-div" ); + inp.calendar( "show" ); + equal( dp.css( "display" ), "block", "beforeShow returns true" ); + inp.calendar( "hide" ); + inp.calendar( "destroy" ); + + inp = TestHelpers.calendar.init( "#inp", { + beforeShow: function() { + return false; + } + }); + dp = $( "#ui-calendar-div" ); + inp.calendar( "show" ); + equal( dp.css( "display" ), "none", "beforeShow returns false" ); + inp.calendar( "destroy" ); +}); +*/ + +})(jQuery); diff --git a/tests/unit/calendar/calendar_test_helpers.js b/tests/unit/calendar/calendar_test_helpers.js new file mode 100644 index 00000000000..fa53c408fb6 --- /dev/null +++ b/tests/unit/calendar/calendar_test_helpers.js @@ -0,0 +1,28 @@ +TestHelpers.calendar = { + addMonths: function( date, offset ) { + var maxDay = 32 - new Date( date.getFullYear(), date.getMonth() + offset, 32 ).getDate(); + date.setDate( Math.min( date.getDate(), maxDay ) ); + date.setMonth( date.getMonth() + offset ); + return date; + }, + equalsDate: function( d1, d2, message ) { + if ( !d1 || !d2 ) { + ok( false, message + " - missing date" ); + return; + } + d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() ); + d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() ); + equal( d1.toString(), d2.toString(), message ); + }, + init: function( id, options ) { + options = $.extend( { show: false }, options || {} ); + return $( id ).calendar( options ); + }, + initNewInput: function( options ) { + options = $.extend( { show: false }, options || {} ); + return $( "" ).calendar( options ) + .appendTo( "#qunit-fixture" ); + }, + onFocus: TestHelpers.onFocus, + PROP_NAME: "calendar" +}; \ No newline at end of file diff --git a/tests/unit/calendar/images/calendar.gif b/tests/unit/calendar/images/calendar.gif new file mode 100644 index 0000000000000000000000000000000000000000..52f2863c90764cabb11ac926b3f7e02b9b9e5e49 GIT binary patch literal 258 zcmZ?wbh9u|6ky<+Y9vrwbI($!DTUl#W73z|)4nX4`*rp5ZyQ#B-@379)%)KM@Be-M>hGtI|Gs_w|L4#D z|Nj|~fDVWavWtPW{Q*md3PbOU5QXTA``&Hf+-&MQNyN4Pv4TT$qr;4tz7x@TlA2nj z{VVh>rsSCQXN#@AXk#?9q4e^OX(ylcxawre$mLbEZVWhZ^wyuYi=i=Ui~?zCvD{J; zob`>l`Gve(T%4S?jg@f;{OB2!bOQWALGdFOQVvkR?QwQ_|pZzJQT&0DrAGFSru Doau8X literal 0 HcmV?d00001 diff --git a/tests/unit/index.html b/tests/unit/index.html index bd48590ec37..842ba7e6a8d 100644 --- a/tests/unit/index.html +++ b/tests/unit/index.html @@ -39,6 +39,7 @@

        Widgets

        • Accordion
        • Autocomplete
        • +
        • Calendar
        • Button
        • Datepicker
        • Dialog
        • diff --git a/themes/base/base.css b/themes/base/base.css index 479c3279d9b..b9adae8899c 100644 --- a/themes/base/base.css +++ b/themes/base/base.css @@ -13,6 +13,7 @@ @import url("accordion.css"); @import url("autocomplete.css"); @import url("button.css"); +@import url("calendar.css"); @import url("datepicker.css"); @import url("dialog.css"); @import url("draggable.css"); diff --git a/themes/base/calendar.css b/themes/base/calendar.css new file mode 100644 index 00000000000..d30eb6fcfa5 --- /dev/null +++ b/themes/base/calendar.css @@ -0,0 +1,180 @@ +/*! + * jQuery UI Calendar @VERSION + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/calendar/#theming + */ +.ui-calendar { + width: 17em; + padding: .2em .2em 0; + display: none; +} +.ui-calendar .ui-calendar-header { + position: relative; + padding: .2em 0; +} +.ui-calendar .ui-calendar-prev, +.ui-calendar .ui-calendar-next { + position: absolute; + top: 2px; + width: 19px; + height: 18px; +} +.ui-calendar .ui-calendar-prev:not(.ui-state-hover):not(.ui-state-focus), +.ui-calendar .ui-calendar-next:not(.ui-state-hover):not(.ui-state-focus) { + background: none; + border: none; +} +.ui-calendar .ui-calendar-prev-hover, +.ui-calendar .ui-calendar-next-hover { + top: 1px; +} +.ui-calendar .ui-calendar-prev { + left: 2px; +} +.ui-calendar .ui-calendar-next { + right: 2px; +} +.ui-calendar .ui-calendar-prev-hover { + left: 1px; +} +.ui-calendar .ui-calendar-next-hover { + right: 1px; +} +.ui-calendar .ui-calendar-prev .ui-icon, +.ui-calendar .ui-calendar-next .ui-icon { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-calendar .ui-calendar-title { + margin: 0 2.3em; + line-height: 1.8em; + text-align: center; +} +.ui-calendar .ui-calendar-title select { + font-size: 1em; + margin: 1px 0; +} +.ui-calendar select.ui-calendar-month, +.ui-calendar select.ui-calendar-year { + width: 49%; +} +.ui-calendar table { + width: 100%; + font-size: .9em; + border-collapse: collapse; + margin: 0 0 .4em; +} +.ui-calendar th { + padding: .7em .3em; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-calendar td { + border: 0; + padding: 1px; +} +.ui-calendar td span, +.ui-calendar td a { + display: block; + padding: .2em; + text-align: right; + text-decoration: none; +} +.ui-calendar .ui-calendar-buttonpane { + background-image: none; + margin: .7em 0 0 0; + padding: 0 .2em; + border-left: 0; + border-right: 0; + border-bottom: 0; +} +.ui-calendar .ui-calendar-buttonpane button { + float: right; + margin: .5em .2em .4em; + cursor: pointer; + padding: .2em .6em .3em .6em; + width: auto; + overflow: visible; +} +.ui-calendar .ui-calendar-buttonpane button.ui-calendar-current { + float: left; +} + +/* with multiple calendars */ +.ui-calendar.ui-calendar-multi { + width: auto; +} +.ui-calendar-multi .ui-calendar-group { + float: left; +} +.ui-calendar-multi .ui-calendar-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-calendar-multi-2 .ui-calendar-group { + width: 50%; +} +.ui-calendar-multi-3 .ui-calendar-group { + width: 33.3%; +} +.ui-calendar-multi-4 .ui-calendar-group { + width: 25%; +} +.ui-calendar-multi .ui-calendar-group-last .ui-calendar-header, +.ui-calendar-multi .ui-calendar-group-middle .ui-calendar-header { + border-left-width: 0; +} +.ui-calendar-multi .ui-calendar-buttonpane { + clear: left; +} +.ui-calendar-row-break { + clear: both; + width: 100%; + font-size: 0; +} + +/* RTL support */ +.ui-calendar-rtl { + direction: rtl; +} +.ui-calendar-rtl .ui-calendar-prev { + right: 2px; + left: auto; +} +.ui-calendar-rtl .ui-calendar-next { + left: 2px; + right: auto; +} +.ui-calendar-rtl .ui-calendar-prev:hover { + right: 1px; + left: auto; +} +.ui-calendar-rtl .ui-calendar-next:hover { + left: 1px; + right: auto; +} +.ui-calendar-rtl .ui-calendar-buttonpane { + clear: right; +} +.ui-calendar-rtl .ui-calendar-buttonpane button { + float: left; +} +.ui-calendar-rtl .ui-calendar-buttonpane button.ui-calendar-current, +.ui-calendar-rtl .ui-calendar-group { + float: right; +} +.ui-calendar-rtl .ui-calendar-group-last .ui-calendar-header, +.ui-calendar-rtl .ui-calendar-group-middle .ui-calendar-header { + border-right-width: 0; + border-left-width: 1px; +} diff --git a/ui/calendar.js b/ui/calendar.js new file mode 100644 index 00000000000..327e8936e59 --- /dev/null +++ b/ui/calendar.js @@ -0,0 +1,767 @@ +/*! + * jQuery UI Calendar @VERSION + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/calendar/ + */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery", + "./core", + "./widget", + "./button", + "./position" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +// TODO use uniqueId, if possible +var idIncrement = 0, + // TODO move this to the instance + suppressExpandOnFocus = false; + +return $.widget( "ui.calendar", { + options: { + appendTo: null, + dateFormat: { date: "short" }, + // TODO review + eachDay: $.noop, + numberOfMonths: 1, + position: { + my: "left top", + at: "left bottom" + }, + showWeek: false, + show: true, + hide: true, + value: null, + + // callbacks + beforeOpen: null, + close: null, + open: null, + select: null + }, + + _create: function() { + this.id = "ui-calendar-" + idIncrement; + idIncrement++; + + if ( this.element.is( "input" ) ) { + if ( !this.options.value && this.isValid() ) { + this.options.value = this._getParsedValue(); + } + this._createPicker(); + } else { + this.inline = true; + this.picker = this.element; + } + + this.date = $.date( this.options.value, this.options.dateFormat ).select(); + this.date.eachDay = this.options.eachDay; + + this._on( this.picker, { + "click .ui-calendar-prev": function( event ) { + event.preventDefault(); + this.date.adjust( "M", -this.options.numberOfMonths ); + this.refresh(); + }, + "click .ui-calendar-next": function( event ) { + event.preventDefault(); + this.date.adjust( "M", this.options.numberOfMonths ); + this.refresh(); + }, + "click .ui-calendar-current": function( event ) { + event.preventDefault(); + this._select( event, new Date().getTime() ); + }, + "click .ui-calendar-close": function( event ) { + event.preventDefault(); + this.close( event ); + }, + "mousedown .ui-calendar-calendar a": function( event ) { + event.preventDefault(); + // TODO exclude clicks on lead days or handle them correctly + // TODO store/read more then just date, also required for multi month picker + this._select( event, $( event.currentTarget ).data( "timestamp" ) ); + if ( this.inline ) { + this.grid.focus( 1 ); + } + }, + "keydown .ui-calendar-calendar": "_handleKeydown" + }); + + // TODO use hoverable (no delegation support)? convert to _on? + this.picker.delegate( ".ui-calendar-header a, .ui-calendar-calendar a", "mouseenter.calendar mouseleave.calendar", function() { + $( this ).toggleClass( "ui-state-hover" ); + }); + + this._createTmpl(); + }, + + _handleKeydown: function( event ) { + if ( jQuery.inArray( event.keyCode, [ 13, 33, 34, 35, 36, 37, 38, 39, 40 ] ) === -1 ) { + // only interested navigation keys + return; + } + event.preventDefault(); + + var newId, newCell, + activeCell = $( "#" + this.grid.attr( "aria-activedescendant" ) ), + oldMonth = this.date.month(), + oldYear = this.date.year(); + + // TODO: Handle for pickers with multiple months + switch ( event.keyCode ) { + case $.ui.keyCode.ENTER: + activeCell.children( "a:first" ).mousedown(); + return; + case $.ui.keyCode.PAGE_UP: + this.date.adjust( event.altKey ? "Y" : "M", -1 ); + break; + case $.ui.keyCode.PAGE_DOWN: + this.date.adjust( event.altKey ? "Y" : "M", 1 ); + break; + case $.ui.keyCode.END: + this.date.setDay( this.date.daysInMonth() ); + break; + case $.ui.keyCode.HOME: + this.date.setDay( 1 ); + break; + case $.ui.keyCode.LEFT: + this.date.adjust( "D", -1 ); + break; + case $.ui.keyCode.UP: + this.date.adjust( "D", -7 ); + break; + case $.ui.keyCode.RIGHT: + this.date.adjust( "D", 1 ); + break; + case $.ui.keyCode.DOWN: + this.date.adjust( "D", 7 ); + break; + default: + return; + } + + if ( this.date.month() !== oldMonth || this.date.year() !== oldYear ) { + this.refresh(); + this.grid.focus( 1 ); + } + else { + newId = this.id + "-" + this.date.day(); + newCell = $( "#" + newId ); + + // TODO unnecessary optimization? is it really needed? + if ( !newCell.length ) { + return; + } + this.grid.attr("aria-activedescendant", newId); + + this.grid.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); + newCell.children( "a" ).addClass( "ui-state-focus" ); + } + }, + + _createPicker: function() { + this.picker = $( "
          " ) + .addClass( "ui-front" ) + // TODO add a ui-calendar-popup class, move position:absolute to that + .css( "position", "absolute" ) + .uniqueId() + .hide(); + this._setHiddenPicker(); + this.picker.appendTo( this._appendTo() ); + + this.element + .attr( "aria-haspopup", "true" ) + .attr( "aria-owns", this.picker.attr( "id" ) ); + + this._on({ + keydown: function( event ) { + switch ( event.keyCode ) { + case $.ui.keyCode.TAB: + // Waiting for close() will make popup hide too late, which breaks tab key behavior + this.picker.hide(); + this.close( event ); + break; + case $.ui.keyCode.ESCAPE: + if ( this.isOpen ) { + this.close( event ); + } + break; + case $.ui.keyCode.ENTER: + this._handleKeydown( event ); + break; + case $.ui.keyCode.DOWN: + case $.ui.keyCode.UP: + clearTimeout( this.closeTimer ); + this._delay( function() { + this.open( event ); + this.grid.focus( 1 ); + }, 1 ); + break; + case $.ui.keyCode.HOME: + if ( event.ctrlKey ) { + this.date.setTime( new Date() ); + event.preventDefault(); + if ( this.isOpen ) { + this.refresh(); + } else { + this.open( event ); + } + } + break; + // TODO this is not in specs, keep? + case $.ui.keyCode.END: + if ( event.ctrlKey ) { + this.element.val( "" ); + event.preventDefault(); + if ( this.isOpen ) { + this.close( event ); + } + } + break; + } + }, + keyup: function() { + if ( this.isValid() && !this.inline ) { + this.date.setTime( this._getParsedValue() ).select(); + this.refresh(); + } + }, + mousedown: function( event ) { + if ( this.isOpen ) { + suppressExpandOnFocus = true; + this.close(); + return; + } + this.open( event ); + clearTimeout( this.closeTimer ); + }, + focus: function( event ) { + if ( !suppressExpandOnFocus ) { + this._delay( function() { + if ( !this.isOpen ) { + this.open( event ); + } + }, 1); + } + this._delay( function() { + suppressExpandOnFocus = false; + }, 100 ); + }, + blur: function() { + suppressExpandOnFocus = false; + } + }); + + this._on( this.picker, { + focusout: function( event ) { + // use a timer to allow click to clear it and letting that + // handle the closing instead of opening again + // also allows tabbing inside the calendar without it closing + this.closeTimer = this._delay( function() { + this.close( event ); + }, 150 ); + }, + focusin: function() { + clearTimeout( this.closeTimer ); + }, + mouseup: function() { + clearTimeout( this.closeTimer ); + }, + // TODO on TAB (or shift TAB), make sure it ends up on something useful in DOM order + keyup: function( event ) { + if ( event.keyCode === $.ui.keyCode.ESCAPE && this.picker.is( ":visible" ) ) { + this.close( event ); + this._focusTrigger(); + } + } + }); + + this._on( this.document, { + click: function( event ) { + if ( this.isOpen && !$( event.target ).closest( this.element.add( this.picker ) ).length ) { + this.close( event ); + } + } + }); + }, + + _appendTo: function() { + var element = this.options.appendTo; + + if ( element ) { + element = element.jquery || element.nodeType ? + $( element ) : + this.document.find( element ).eq( 0 ); + } + + if ( !element ) { + element = this.element.closest( ".ui-front" ); + } + + if ( !element.length ) { + element = this.document[ 0 ].body; + } + + return element; + }, + + _createTmpl: function() { + this._createDatepicker(); + this.picker.find( "button" ).button(); + + if ( this.inline ) { + this.picker.children().addClass( "ui-calendar-inline" ); + } + // against display:none in calendar.css + this.picker.find( ".ui-calendar" ).css( "display", "block" ); + this.grid = this.picker.find( ".ui-calendar-calendar" ); + }, + + _createDatepicker: function() { + var multiClasses = [], + pickerHtml = ""; + + if (this.options.numberOfMonths === 1 ) { + pickerHtml = this._buildHeader() + this._buildGrid() + this._buildButtons(); + } else { + pickerHtml = this._buildMultiplePicker(); + multiClasses.push( "ui-calendar-multi" ); + multiClasses.push( "ui-calendar-multi-" + this.options.numberOfMonths ); + } + + $( "
          " ) + .addClass( "ui-calendar ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" ) + .addClass( multiClasses.join( " " ) ) + .attr({ + role: "region", + "aria-labelledby": this.id + "-title" + }) + .html( pickerHtml ) + .appendTo( this.picker ); + }, + + _buildMultiplePicker: function() { + var headerClass, + html = "", + currentDate = this.date, + months = this.date.months( this.options.numberOfMonths - 1 ), + i = 0; + + for ( i; i < months.length; i++ ) { + // TODO Shouldn't we pass date as a parameter to build* fns instead of setting this.date? + this.date = months[ i ]; + headerClass = months[ i ].first ? "ui-corner-left" : + months[ i ].last ? "ui-corner-right" : ""; + + html += "
          " + + "
          "; + if ( months[ i ].first ) { + html += this._buildPreviousLink(); + } + if ( months[ i ].last ) { + html += this._buildNextLink(); + } + + html += this._buildTitlebar(); + html += "
          "; + html += this._buildGrid(); + html += "
          "; + } + + html += "
          "; + html += this._buildButtons(); + + this.date = currentDate; + + return html; + }, + + _buildHeader: function() { + return "
          " + + this._buildPreviousLink() + + this._buildNextLink() + + this._buildTitlebar() + + "
          "; + }, + + _buildPreviousLink: function() { + var labels = Globalize.translate( "calendar" ); + + return ""; + }, + + _buildNextLink: function() { + var labels = Globalize.translate( "calendar" ); + + return ""; + }, + + _buildTitlebar: function() { + var labels = Globalize.translate( "calendar" ); + + return "
          " + + "
          " + + this._buildTitle() + + "
          " + + ", " + labels.datePickerRole + "" + + "
          "; + }, + + _buildTitle: function() { + return "" + + this.date.monthName() + + " " + + "" + + this.date.year() + + ""; + }, + + _buildGrid: function() { + return "" + + this._buildGridHeading() + + this._buildGridBody() + + "
          "; + }, + + _buildGridHeading: function() { + var cells = "", + i = 0, + labels = Globalize.translate( "calendar" ); + + if ( this.options.showWeek ) { + cells += "" + labels.weekHeader + ""; + } + for ( i; i < this.date.weekdays().length; i++ ) { + cells += this._buildGridHeaderCell( this.date.weekdays()[i] ); + } + + return "" + + "" + cells + "" + + ""; + }, + + _buildGridHeaderCell: function( day ) { + return "" + + "" + + day.shortname + + "" + + ""; + }, + + _buildGridBody: function() { + // this.date.days() is not cached, and it has O(n^2) complexity. It is run O(n) times. So, it equals O(n^3). Not good at all. Caching. + var days = this.date.days(), + i = 0, + rows = ""; + + for ( i; i < days.length; i++ ) { + rows += this._buildWeekRow( days[ i ] ); + } + + return "" + rows + ""; + }, + + _buildWeekRow: function( week ) { + var cells = "", + i = 0; + + if ( this.options.showWeek ) { + cells += "" + week.number + ""; + } + for ( i; i < week.days.length; i++ ) { + cells += this._buildDayCell( week.days[i] ); + } + return "" + cells + ""; + }, + + _buildDayCell: function( day ) { + var contents = "", + idAttribute = day.render ? ( "id=" + this.id + "-" + day.date ) : "", + ariaSelectedAttribute = "aria-selected=" + ( day.current ? "true" : "false" ), + ariaDisabledAttribute = day.selectable ? "" : "aria-disabled=true"; + + if ( day.render ) { + if ( day.selectable ) { + contents = this._buildDayLink( day ); + } else { + contents = this._buildDayDisplay( day ); + } + } + + return "" + + contents + + ""; + }, + + _buildDayLink: function( day ) { + var link, + classes = [ "ui-state-default" ], + labels = Globalize.translate( "calendar" ); + + if ( day.date === this.date.day() ) { + classes.push( "ui-state-focus" ); + } + if ( day.current ) { + classes.push( "ui-state-active" ); + } + if ( day.today ) { + classes.push( "ui-state-highlight" ); + } + if ( day.extraClasses ) { + classes.push( day.extraClasses.split( " " ) ); + } + + link = "" + + day.date + ""; + if ( day.today ) { + link += ", " + labels.currentText + ""; + } + + return link; + }, + + _buildDayDisplay: function( day ) { + var classes = []; + + if ( day.current ) { + classes.push( "ui-state-active" ); + } + if ( day.today ) { + classes.push( "ui-state-highlight" ); + } + if ( day.extraClasses ) { + classes.push( day.extraClasses.split( " " ) ); + } + + return "" + day.date + ""; + }, + + _buildButtons: function() { + var labels = Globalize.translate( "calendar" ); + + return "
          " + + "" + + "" + + "
          "; + }, + + _focusTrigger: function() { + suppressExpandOnFocus = true; + this.element.focus(); + }, + + // Refreshing the entire calendar during interaction confuses screen readers, specifically + // because the grid heading is marked up as a live region and will often not update if it's + // destroyed and recreated instead of just having its text change. Additionally, interacting + // with the prev and next links would cause loss of focus issues because the links being + // interacted with will disappear while focused. + refresh: function() { + // determine which day gridcell to focus after refresh + // TODO: Prevent disabled cells from being focused + if ( this.options.numberOfMonths === 1 ) { + this.grid = $( this._buildGrid() ); + $( ".ui-calendar-title", this.picker ).html( this._buildTitle() ); + $( ".ui-calendar-calendar", this.picker ).replaceWith( this.grid ); + } else { + this._refreshMultiplePicker(); + } + }, + + _refreshMultiplePicker: function() { + var i = 0; + + for ( ; i < this.options.numberOfMonths; i++ ) { + $( ".ui-calendar-title", this.picker ).eq( i ).html( this._buildTitle() ); + $( ".ui-calendar-calendar", this.picker ).eq( i ).html( this._buildGrid() ); + this.date.adjust( "M", 1 ); + } + this.date.adjust( "M", -this.options.numberOfMonths ); + + // TODO: This assumes focus is on the first grid. For multi pickers, the widget needs + // to maintain the currently focused grid and base queries like this off of it. + $( this.picker ).find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" ); + }, + + open: function( event ) { + if ( this.inline || this.isOpen ) { + return; + } + if ( this._trigger( "beforeOpen", event ) === false ) { + return; + } + + this.refresh(); + + this.picker + .attr( "aria-hidden", "false" ) + .attr( "aria-expanded", "true" ) + .show() + .position( this._buildPosition() ) + .hide(); + + this._show( this.picker, this.options.show ); + + // take trigger out of tab order to allow shift-tab to skip trigger + // TODO does this really make sense? related bug: tab-shift moves focus to last element on page + this.element.attr( "tabindex", -1 ); + this.isOpen = true; + + this._trigger( "open", event ); + }, + + close: function( event ) { + if ( this.inline ) { + return; + } + + this._setHiddenPicker(); + this._hide( this.picker, this.options.hide ); + + this.element.attr( "tabindex" , 0 ); + + this.isOpen = false; + this._trigger( "close", event ); + }, + + _setHiddenPicker: function() { + this.picker + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); + }, + + _buildPosition: function() { + return $.extend( {}, { of: this.element }, this.options.position ); + }, + + _select: function( event, time ) { + this._setOption( "value", new Date( time ) ); + if ( !this.inline ) { + this.close(); + this._focusTrigger(); + } + this._trigger( "select", event, { + // TODO replace with value option to initialise and read + date: this.value() + }); + }, + + value: function( value ) { + if ( arguments.length ) { + this._setOption( "value", Globalize.parseDate( value, this.options.dateFormat ) ); + } else { + if ( this.inline ) { + return Globalize.format( this.date.selected(), this.options.dateFormat ); + } else { + return this.element.val(); + } + } + }, + + valueAsDate: function( value ) { + if ( arguments.length ) { + this._setOption( "value", value ); + } else { + return this.option( "value" ); + } + }, + + isValid: function() { + if ( this.inline ) { + return true; + } + + return this._getParsedValue() !== null; + }, + + _destroy: function() { + if ( this.inline ) { + this.picker.empty(); + } else { + this.picker.remove(); + this.element + .removeAttr( "aria-haspopup" ) + .removeAttr( "aria-owns" ); + } + }, + + widget: function() { + return this.picker; + }, + + _getParsedValue: function() { + return Globalize.parseDate( this.element.val(), this.options.dateFormat ); + }, + + option: function( key ) { + if ( arguments.length === 0 || ( arguments.length === 1 && key === "value" ) ) { + this.options.value = this.inline ? this.date.selected() : this._getParsedValue(); + } + return this._superApply( arguments ); + }, + + _setOption: function( key, value ) { + if ( key === "value" ) { + if ( value instanceof Date ) { + this.date.setTime( value.getTime() ).select(); + this.refresh(); + if ( !this.inline ) { + this.element.val( this.date.format() ); + } + } + } + + this._super( key, value ); + + if ( key === "appendTo" ) { + this.picker.appendTo( this._appendTo() ); + } + + if ( key === "eachDay" ) { + this.date.eachDay = this.options.eachDay; + this.refresh(); + } + + if ( key === "dateFormat" ) { + this.date.setFormat( this.options.dateFormat ); + if ( !this.inline ) { + this.element.val( this.date.format() ); + } + } + + if ( key === "showWeek" ) { + this.refresh(); + } + + if ( key === "position" ) { + this.picker.position( this._buildPosition() ); + } + } +}); + +})); \ No newline at end of file From bb275b7c65219bfb7093473576b3ddf9b02e7f76 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 3 Jun 2014 23:43:36 +0200 Subject: [PATCH 070/172] Calendar: remove unneeded translation files --- demos/calendar/calendar-ar.js | 36 ------------------------------ demos/calendar/calendar-fr.js | 38 -------------------------------- demos/calendar/calendar-he.js | 36 ------------------------------ demos/calendar/calendar-zh-TW.js | 36 ------------------------------ 4 files changed, 146 deletions(-) delete mode 100644 demos/calendar/calendar-ar.js delete mode 100644 demos/calendar/calendar-fr.js delete mode 100644 demos/calendar/calendar-he.js delete mode 100644 demos/calendar/calendar-zh-TW.js diff --git a/demos/calendar/calendar-ar.js b/demos/calendar/calendar-ar.js deleted file mode 100644 index 3f6eef2329e..00000000000 --- a/demos/calendar/calendar-ar.js +++ /dev/null @@ -1,36 +0,0 @@ -/* Arabic Translation for jQuery UI date picker plugin. */ -/* Khaled Alhourani -- me@khaledalhourani.com */ -/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../jquery.ui.calendar" ], factory ); - } else { - - // Browser globals - factory( jQuery.calendar ); - } -}(function( calendar ) { - calendar.regional['ar'] = { - closeText: 'إغلاق', - prevText: '<السابق', - nextText: 'التالي>', - currentText: 'اليوم', - monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران', - 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], - monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], - dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], - dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'], - weekHeader: 'أسبوع', - dateFormat: 'dd/mm/yy', - firstDay: 6, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; - calendar.setDefaults(calendar.regional['ar']); - - return calendar.regional['ar']; - -})); diff --git a/demos/calendar/calendar-fr.js b/demos/calendar/calendar-fr.js deleted file mode 100644 index ba25b8da688..00000000000 --- a/demos/calendar/calendar-fr.js +++ /dev/null @@ -1,38 +0,0 @@ -/* French initialisation for the jQuery UI date picker plugin. */ -/* Written by Keith Wood (kbwood{at}iinet.com.au), - Stéphane Nahmani (sholby@sholby.net), - Stéphane Raimbault */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../jquery.ui.calendar" ], factory ); - } else { - - // Browser globals - factory( jQuery.calendar ); - } -}(function( calendar ) { - calendar.regional['fr'] = { - closeText: 'Fermer', - prevText: 'Précédent', - nextText: 'Suivant', - currentText: 'Aujourd\'hui', - monthNames: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', - 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], - monthNamesShort: ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin', - 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'], - dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'], - dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'], - dayNamesMin: ['D','L','M','M','J','V','S'], - weekHeader: 'Sem.', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; - calendar.setDefaults(calendar.regional['fr']); - - return calendar.regional['fr']; - -})); diff --git a/demos/calendar/calendar-he.js b/demos/calendar/calendar-he.js deleted file mode 100644 index 40f83c1cd50..00000000000 --- a/demos/calendar/calendar-he.js +++ /dev/null @@ -1,36 +0,0 @@ -/* Hebrew initialisation for the UI Calendar extension. */ -/* Written by Amir Hardon (ahardon at gmail dot com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../jquery.ui.calendar" ], factory ); - } else { - - // Browser globals - factory( jQuery.calendar ); - } -}(function( calendar ) { - calendar.regional['he'] = { - closeText: 'סגור', - prevText: '<הקודם', - nextText: 'הבא>', - currentText: 'היום', - monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני', - 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'], - monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני', - 'יולי','אוג','ספט','אוק','נוב','דצמ'], - dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'], - dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], - dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; - calendar.setDefaults(calendar.regional['he']); - - return calendar.regional['he']; - -})); diff --git a/demos/calendar/calendar-zh-TW.js b/demos/calendar/calendar-zh-TW.js deleted file mode 100644 index 99c1719438c..00000000000 --- a/demos/calendar/calendar-zh-TW.js +++ /dev/null @@ -1,36 +0,0 @@ -/* Chinese initialisation for the jQuery UI date picker plugin. */ -/* Written by Ressol (ressol@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../jquery.ui.calendar" ], factory ); - } else { - - // Browser globals - factory( jQuery.calendar ); - } -}(function( calendar ) { - calendar.regional['zh-TW'] = { - closeText: '關閉', - prevText: '<上月', - nextText: '下月>', - currentText: '今天', - monthNames: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - monthNamesShort: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], - dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], - dayNamesMin: ['日','一','二','三','四','五','六'], - weekHeader: '周', - dateFormat: 'yy/mm/dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '年'}; - calendar.setDefaults(calendar.regional['zh-TW']); - - return calendar.regional['zh-TW']; - -})); From 44baada68fdac1a20468e605499b3f2e79347c06 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 00:06:38 +0200 Subject: [PATCH 071/172] Calendar: Rename $.date selected method Rename $.date selected method in order to prevent internal variable conflict. --- external/date.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/date.js b/external/date.js index bad6679ec40..71963981129 100644 --- a/external/date.js +++ b/external/date.js @@ -183,7 +183,7 @@ $.date.prototype = { this.selected = this.clone(); return this; }, - selected: function() { + selectedDate: function() { return this.selected; }, clone: function() { From d11e35bc11aef6a28cabc0ebe7dbae98e43a4069 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 00:08:03 +0200 Subject: [PATCH 072/172] Calendar: remove datepicker functionality, options and methods --- demos/calendar/default.html | 2 +- ui/calendar.js | 328 +++--------------------------------- 2 files changed, 29 insertions(+), 301 deletions(-) diff --git a/demos/calendar/default.html b/demos/calendar/default.html index 26c4c2eb3d5..b35e9e769bd 100644 --- a/demos/calendar/default.html +++ b/demos/calendar/default.html @@ -22,7 +22,7 @@ -

          Date:

          +

          The calendar is tied to a standard form input field. Focus on the input (click, or use the tab key) to open an interactive calendar in a small overlay. Choose a date, click elsewhere on the page (blur the input), or hit the Esc key to close. If a date is chosen, feedback is shown as the input's value.

          diff --git a/ui/calendar.js b/ui/calendar.js index 327e8936e59..8474f0f8f91 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -27,30 +27,18 @@ }(function( $ ) { // TODO use uniqueId, if possible -var idIncrement = 0, - // TODO move this to the instance - suppressExpandOnFocus = false; +var idIncrement = 0; return $.widget( "ui.calendar", { options: { - appendTo: null, dateFormat: { date: "short" }, // TODO review eachDay: $.noop, numberOfMonths: 1, - position: { - my: "left top", - at: "left bottom" - }, showWeek: false, - show: true, - hide: true, value: null, // callbacks - beforeOpen: null, - close: null, - open: null, select: null }, @@ -58,20 +46,10 @@ return $.widget( "ui.calendar", { this.id = "ui-calendar-" + idIncrement; idIncrement++; - if ( this.element.is( "input" ) ) { - if ( !this.options.value && this.isValid() ) { - this.options.value = this._getParsedValue(); - } - this._createPicker(); - } else { - this.inline = true; - this.picker = this.element; - } - this.date = $.date( this.options.value, this.options.dateFormat ).select(); this.date.eachDay = this.options.eachDay; - this._on( this.picker, { + this._on( this.element, { "click .ui-calendar-prev": function( event ) { event.preventDefault(); this.date.adjust( "M", -this.options.numberOfMonths ); @@ -86,24 +64,18 @@ return $.widget( "ui.calendar", { event.preventDefault(); this._select( event, new Date().getTime() ); }, - "click .ui-calendar-close": function( event ) { - event.preventDefault(); - this.close( event ); - }, "mousedown .ui-calendar-calendar a": function( event ) { event.preventDefault(); // TODO exclude clicks on lead days or handle them correctly // TODO store/read more then just date, also required for multi month picker this._select( event, $( event.currentTarget ).data( "timestamp" ) ); - if ( this.inline ) { - this.grid.focus( 1 ); - } + this.grid.focus( 1 ); }, "keydown .ui-calendar-calendar": "_handleKeydown" }); // TODO use hoverable (no delegation support)? convert to _on? - this.picker.delegate( ".ui-calendar-header a, .ui-calendar-calendar a", "mouseenter.calendar mouseleave.calendar", function() { + this.element.delegate( ".ui-calendar-header a, .ui-calendar-calendar a", "mouseenter.calendar mouseleave.calendar", function() { $( this ).toggleClass( "ui-state-hover" ); }); @@ -174,162 +146,13 @@ return $.widget( "ui.calendar", { } }, - _createPicker: function() { - this.picker = $( "
          " ) - .addClass( "ui-front" ) - // TODO add a ui-calendar-popup class, move position:absolute to that - .css( "position", "absolute" ) - .uniqueId() - .hide(); - this._setHiddenPicker(); - this.picker.appendTo( this._appendTo() ); - - this.element - .attr( "aria-haspopup", "true" ) - .attr( "aria-owns", this.picker.attr( "id" ) ); - - this._on({ - keydown: function( event ) { - switch ( event.keyCode ) { - case $.ui.keyCode.TAB: - // Waiting for close() will make popup hide too late, which breaks tab key behavior - this.picker.hide(); - this.close( event ); - break; - case $.ui.keyCode.ESCAPE: - if ( this.isOpen ) { - this.close( event ); - } - break; - case $.ui.keyCode.ENTER: - this._handleKeydown( event ); - break; - case $.ui.keyCode.DOWN: - case $.ui.keyCode.UP: - clearTimeout( this.closeTimer ); - this._delay( function() { - this.open( event ); - this.grid.focus( 1 ); - }, 1 ); - break; - case $.ui.keyCode.HOME: - if ( event.ctrlKey ) { - this.date.setTime( new Date() ); - event.preventDefault(); - if ( this.isOpen ) { - this.refresh(); - } else { - this.open( event ); - } - } - break; - // TODO this is not in specs, keep? - case $.ui.keyCode.END: - if ( event.ctrlKey ) { - this.element.val( "" ); - event.preventDefault(); - if ( this.isOpen ) { - this.close( event ); - } - } - break; - } - }, - keyup: function() { - if ( this.isValid() && !this.inline ) { - this.date.setTime( this._getParsedValue() ).select(); - this.refresh(); - } - }, - mousedown: function( event ) { - if ( this.isOpen ) { - suppressExpandOnFocus = true; - this.close(); - return; - } - this.open( event ); - clearTimeout( this.closeTimer ); - }, - focus: function( event ) { - if ( !suppressExpandOnFocus ) { - this._delay( function() { - if ( !this.isOpen ) { - this.open( event ); - } - }, 1); - } - this._delay( function() { - suppressExpandOnFocus = false; - }, 100 ); - }, - blur: function() { - suppressExpandOnFocus = false; - } - }); - - this._on( this.picker, { - focusout: function( event ) { - // use a timer to allow click to clear it and letting that - // handle the closing instead of opening again - // also allows tabbing inside the calendar without it closing - this.closeTimer = this._delay( function() { - this.close( event ); - }, 150 ); - }, - focusin: function() { - clearTimeout( this.closeTimer ); - }, - mouseup: function() { - clearTimeout( this.closeTimer ); - }, - // TODO on TAB (or shift TAB), make sure it ends up on something useful in DOM order - keyup: function( event ) { - if ( event.keyCode === $.ui.keyCode.ESCAPE && this.picker.is( ":visible" ) ) { - this.close( event ); - this._focusTrigger(); - } - } - }); - - this._on( this.document, { - click: function( event ) { - if ( this.isOpen && !$( event.target ).closest( this.element.add( this.picker ) ).length ) { - this.close( event ); - } - } - }); - }, - - _appendTo: function() { - var element = this.options.appendTo; - - if ( element ) { - element = element.jquery || element.nodeType ? - $( element ) : - this.document.find( element ).eq( 0 ); - } - - if ( !element ) { - element = this.element.closest( ".ui-front" ); - } - - if ( !element.length ) { - element = this.document[ 0 ].body; - } - - return element; - }, - _createTmpl: function() { this._createDatepicker(); - this.picker.find( "button" ).button(); + this.element.find( "button" ).button(); - if ( this.inline ) { - this.picker.children().addClass( "ui-calendar-inline" ); - } // against display:none in calendar.css - this.picker.find( ".ui-calendar" ).css( "display", "block" ); - this.grid = this.picker.find( ".ui-calendar-calendar" ); + this.element.find( ".ui-calendar" ).css( "display", "block" ); + this.grid = this.element.find( ".ui-calendar-calendar" ); }, _createDatepicker: function() { @@ -352,7 +175,7 @@ return $.widget( "ui.calendar", { "aria-labelledby": this.id + "-title" }) .html( pickerHtml ) - .appendTo( this.picker ); + .appendTo( this.element ); }, _buildMultiplePicker: function() { @@ -400,10 +223,9 @@ return $.widget( "ui.calendar", { }, _buildPreviousLink: function() { - var labels = Globalize.translate( "calendar" ); + var labels = Globalize.translate( "datepicker" ); - return "" + - "" + "
          "; }, - _focusTrigger: function() { - suppressExpandOnFocus = true; - this.element.focus(); - }, - // Refreshing the entire calendar during interaction confuses screen readers, specifically // because the grid heading is marked up as a live region and will often not update if it's // destroyed and recreated instead of just having its text change. Additionally, interacting @@ -586,8 +401,8 @@ return $.widget( "ui.calendar", { // TODO: Prevent disabled cells from being focused if ( this.options.numberOfMonths === 1 ) { this.grid = $( this._buildGrid() ); - $( ".ui-calendar-title", this.picker ).html( this._buildTitle() ); - $( ".ui-calendar-calendar", this.picker ).replaceWith( this.grid ); + $( ".ui-calendar-title", this.element ).html( this._buildTitle() ); + $( ".ui-calendar-calendar", this.element ).replaceWith( this.grid ); } else { this._refreshMultiplePicker(); } @@ -597,74 +412,25 @@ return $.widget( "ui.calendar", { var i = 0; for ( ; i < this.options.numberOfMonths; i++ ) { - $( ".ui-calendar-title", this.picker ).eq( i ).html( this._buildTitle() ); - $( ".ui-calendar-calendar", this.picker ).eq( i ).html( this._buildGrid() ); + $( ".ui-calendar-title", this.element ).eq( i ).html( this._buildTitle() ); + $( ".ui-calendar-calendar", this.element ).eq( i ).html( this._buildGrid() ); this.date.adjust( "M", 1 ); } this.date.adjust( "M", -this.options.numberOfMonths ); // TODO: This assumes focus is on the first grid. For multi pickers, the widget needs // to maintain the currently focused grid and base queries like this off of it. - $( this.picker ).find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" ); - }, - - open: function( event ) { - if ( this.inline || this.isOpen ) { - return; - } - if ( this._trigger( "beforeOpen", event ) === false ) { - return; - } - - this.refresh(); - - this.picker - .attr( "aria-hidden", "false" ) - .attr( "aria-expanded", "true" ) - .show() - .position( this._buildPosition() ) - .hide(); - - this._show( this.picker, this.options.show ); - - // take trigger out of tab order to allow shift-tab to skip trigger - // TODO does this really make sense? related bug: tab-shift moves focus to last element on page - this.element.attr( "tabindex", -1 ); - this.isOpen = true; - - this._trigger( "open", event ); - }, - - close: function( event ) { - if ( this.inline ) { - return; - } - - this._setHiddenPicker(); - this._hide( this.picker, this.options.hide ); - - this.element.attr( "tabindex" , 0 ); - - this.isOpen = false; - this._trigger( "close", event ); + $( this.element ).find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" ); }, _setHiddenPicker: function() { - this.picker + this.element .attr( "aria-hidden", "true" ) .attr( "aria-expanded", "false" ); }, - _buildPosition: function() { - return $.extend( {}, { of: this.element }, this.options.position ); - }, - _select: function( event, time ) { this._setOption( "value", new Date( time ) ); - if ( !this.inline ) { - this.close(); - this._focusTrigger(); - } this._trigger( "select", event, { // TODO replace with value option to initialise and read date: this.value() @@ -675,11 +441,7 @@ return $.widget( "ui.calendar", { if ( arguments.length ) { this._setOption( "value", Globalize.parseDate( value, this.options.dateFormat ) ); } else { - if ( this.inline ) { - return Globalize.format( this.date.selected(), this.options.dateFormat ); - } else { - return this.element.val(); - } + return Globalize.format( this.option( "value" ), this.options.dateFormat ); } }, @@ -691,36 +453,16 @@ return $.widget( "ui.calendar", { } }, - isValid: function() { - if ( this.inline ) { - return true; - } - - return this._getParsedValue() !== null; - }, - _destroy: function() { - if ( this.inline ) { - this.picker.empty(); - } else { - this.picker.remove(); - this.element - .removeAttr( "aria-haspopup" ) - .removeAttr( "aria-owns" ); - } - }, - - widget: function() { - return this.picker; - }, - - _getParsedValue: function() { - return Globalize.parseDate( this.element.val(), this.options.dateFormat ); + this.element + .empty() + .removeAttr( "aria-haspopup" ) + .removeAttr( "aria-owns" ); }, option: function( key ) { if ( arguments.length === 0 || ( arguments.length === 1 && key === "value" ) ) { - this.options.value = this.inline ? this.date.selected() : this._getParsedValue(); + this.options.value = this.date.selectedDate(); } return this._superApply( arguments ); }, @@ -730,18 +472,11 @@ return $.widget( "ui.calendar", { if ( value instanceof Date ) { this.date.setTime( value.getTime() ).select(); this.refresh(); - if ( !this.inline ) { - this.element.val( this.date.format() ); - } } } this._super( key, value ); - if ( key === "appendTo" ) { - this.picker.appendTo( this._appendTo() ); - } - if ( key === "eachDay" ) { this.date.eachDay = this.options.eachDay; this.refresh(); @@ -749,18 +484,11 @@ return $.widget( "ui.calendar", { if ( key === "dateFormat" ) { this.date.setFormat( this.options.dateFormat ); - if ( !this.inline ) { - this.element.val( this.date.format() ); - } } if ( key === "showWeek" ) { this.refresh(); } - - if ( key === "position" ) { - this.picker.position( this._buildPosition() ); - } } }); From 7aac60a9bd8ad02e8fb338b3cd6fca1ac2d7159d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 00:30:40 +0200 Subject: [PATCH 073/172] Calendar: Fix focus highlighting when month is changed --- ui/calendar.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 8474f0f8f91..6f46bab5c00 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -89,8 +89,7 @@ return $.widget( "ui.calendar", { } event.preventDefault(); - var newId, newCell, - activeCell = $( "#" + this.grid.attr( "aria-activedescendant" ) ), + var activeCell = $( "#" + this.grid.attr( "aria-activedescendant" ) ), oldMonth = this.date.month(), oldYear = this.date.year(); @@ -131,19 +130,17 @@ return $.widget( "ui.calendar", { this.refresh(); this.grid.focus( 1 ); } - else { - newId = this.id + "-" + this.date.day(); - newCell = $( "#" + newId ); - // TODO unnecessary optimization? is it really needed? - if ( !newCell.length ) { - return; - } - this.grid.attr("aria-activedescendant", newId); + this._setActiveDescendant(); + }, - this.grid.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); - newCell.children( "a" ).addClass( "ui-state-focus" ); - } + _setActiveDescendant: function() { + var newId = this.id + "-" + this.date.day(), + newCell = $( "#" + newId ); + + this.grid.attr( "aria-activedescendant", newId ); + this.grid.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); + newCell.children( "a" ).addClass( "ui-state-focus" ); }, _createTmpl: function() { @@ -345,7 +342,7 @@ return $.widget( "ui.calendar", { classes = [ "ui-state-default" ], labels = Globalize.translate( "datepicker" ); - if ( day.date === this.date.day() ) { + if ( day === this.date ) { classes.push( "ui-state-focus" ); } if ( day.current ) { From 485825d5317e7bdbf45a6e8783821002c51aa70d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 00:59:16 +0200 Subject: [PATCH 074/172] Calendar: Make use of uniqueId method --- ui/calendar.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 6f46bab5c00..669383a82a3 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -26,9 +26,6 @@ } }(function( $ ) { -// TODO use uniqueId, if possible -var idIncrement = 0; - return $.widget( "ui.calendar", { options: { dateFormat: { date: "short" }, @@ -43,8 +40,7 @@ return $.widget( "ui.calendar", { }, _create: function() { - this.id = "ui-calendar-" + idIncrement; - idIncrement++; + this.id = this.element.uniqueId().attr( "id" ); this.date = $.date( this.options.value, this.options.dateFormat ).select(); this.date.eachDay = this.options.eachDay; @@ -453,8 +449,7 @@ return $.widget( "ui.calendar", { _destroy: function() { this.element .empty() - .removeAttr( "aria-haspopup" ) - .removeAttr( "aria-owns" ); + .removeUniqueId(); }, option: function( key ) { From dad7a631c692abdcd9f49911d4538946c483f881 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 19:07:23 +0200 Subject: [PATCH 075/172] Calendar: Add _isValid method Add a basic _isValid method for both widgets to check for valid dates. --- ui/calendar.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 669383a82a3..01f80964320 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -425,7 +425,6 @@ return $.widget( "ui.calendar", { _select: function( event, time ) { this._setOption( "value", new Date( time ) ); this._trigger( "select", event, { - // TODO replace with value option to initialise and read date: this.value() }); }, @@ -446,6 +445,11 @@ return $.widget( "ui.calendar", { } }, + _isValid: function( value ) { + // ToDo implement min / max option + return ( value instanceof Date ); + }, + _destroy: function() { this.element .empty() @@ -461,7 +465,7 @@ return $.widget( "ui.calendar", { _setOption: function( key, value ) { if ( key === "value" ) { - if ( value instanceof Date ) { + if ( this._isValid( value ) ) { this.date.setTime( value.getTime() ).select(); this.refresh(); } From 91917854d143baa8100f3e886e4edc4b463ea77a Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 19:09:16 +0200 Subject: [PATCH 076/172] Datepicker: $.date.selected() should return the actual date object The method should return the actual date object instead of the copied $.date object --- external/date.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/date.js b/external/date.js index 71963981129..1bc5b836038 100644 --- a/external/date.js +++ b/external/date.js @@ -184,7 +184,7 @@ $.date.prototype = { return this; }, selectedDate: function() { - return this.selected; + return this.selected.date(); }, clone: function() { var date = this.dateObject; From 8acfca5205385363ab94fb9b7c46ce60d15d984b Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 19:13:32 +0200 Subject: [PATCH 077/172] Datepicker: Remove calendar functionality, options and methods --- demos/datepicker/default.html | 1 + themes/base/datepicker.css | 172 +---------- ui/datepicker.js | 553 ++++------------------------------ 3 files changed, 68 insertions(+), 658 deletions(-) diff --git a/demos/datepicker/default.html b/demos/datepicker/default.html index 0a8fe43da25..6fb48dda2b6 100644 --- a/demos/datepicker/default.html +++ b/demos/datepicker/default.html @@ -11,6 +11,7 @@ + diff --git a/themes/base/datepicker.css b/themes/base/datepicker.css index aa47853507f..d5f7f7c8c7f 100644 --- a/themes/base/datepicker.css +++ b/themes/base/datepicker.css @@ -7,174 +7,4 @@ * http://jquery.org/license * * http://api.jqueryui.com/datepicker/#theming - */ -.ui-datepicker { - width: 17em; - padding: .2em .2em 0; - display: none; -} -.ui-datepicker .ui-datepicker-header { - position: relative; - padding: .2em 0; -} -.ui-datepicker .ui-datepicker-prev, -.ui-datepicker .ui-datepicker-next { - position: absolute; - top: 2px; - width: 19px; - height: 18px; -} -.ui-datepicker .ui-datepicker-prev:not(.ui-state-hover):not(.ui-state-focus), -.ui-datepicker .ui-datepicker-next:not(.ui-state-hover):not(.ui-state-focus) { - background: none; - border: none; -} -.ui-datepicker .ui-datepicker-prev-hover, -.ui-datepicker .ui-datepicker-next-hover { - top: 1px; -} -.ui-datepicker .ui-datepicker-prev { - left: 2px; -} -.ui-datepicker .ui-datepicker-next { - right: 2px; -} -.ui-datepicker .ui-datepicker-prev-hover { - left: 1px; -} -.ui-datepicker .ui-datepicker-next-hover { - right: 1px; -} -.ui-datepicker .ui-datepicker-prev .ui-icon, -.ui-datepicker .ui-datepicker-next .ui-icon { - display: block; - position: absolute; - left: 50%; - margin-left: -8px; - top: 50%; - margin-top: -8px; -} -.ui-datepicker .ui-datepicker-title { - margin: 0 2.3em; - line-height: 1.8em; - text-align: center; -} -.ui-datepicker .ui-datepicker-title select { - font-size: 1em; - margin: 1px 0; -} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { - width: 49%; -} -.ui-datepicker table { - width: 100%; - font-size: .9em; - border-collapse: collapse; - margin: 0 0 .4em; -} -.ui-datepicker th { - padding: .7em .3em; - text-align: center; - font-weight: bold; - border: 0; -} -.ui-datepicker td { - border: 0; - padding: 1px; -} -.ui-datepicker td span, -.ui-datepicker td a { - display: block; - padding: .2em; - text-align: right; - text-decoration: none; -} -.ui-datepicker .ui-datepicker-buttonpane { - background-image: none; - margin: .7em 0 0 0; - padding: 0 .2em; - border-left: 0; - border-right: 0; - border-bottom: 0; -} -.ui-datepicker .ui-datepicker-buttonpane button { - float: right; - margin: .5em .2em .4em; - cursor: pointer; - padding: .2em .6em .3em .6em; - width: auto; - overflow: visible; -} -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { - float: left; -} - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { - width: auto; -} -.ui-datepicker-multi .ui-datepicker-group { - float: left; -} -.ui-datepicker-multi .ui-datepicker-group table { - width: 95%; - margin: 0 auto .4em; -} -.ui-datepicker-multi-2 .ui-datepicker-group { - width: 50%; -} -.ui-datepicker-multi-3 .ui-datepicker-group { - width: 33.3%; -} -.ui-datepicker-multi-4 .ui-datepicker-group { - width: 25%; -} -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { - border-left-width: 0; -} -.ui-datepicker-multi .ui-datepicker-buttonpane { - clear: left; -} -.ui-datepicker-row-break { - clear: both; - width: 100%; - font-size: 0; -} - -/* RTL support */ -.ui-datepicker-rtl { - direction: rtl; -} -.ui-datepicker-rtl .ui-datepicker-prev { - right: 2px; - left: auto; -} -.ui-datepicker-rtl .ui-datepicker-next { - left: 2px; - right: auto; -} -.ui-datepicker-rtl .ui-datepicker-prev:hover { - right: 1px; - left: auto; -} -.ui-datepicker-rtl .ui-datepicker-next:hover { - left: 1px; - right: auto; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane { - clear: right; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane button { - float: left; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, -.ui-datepicker-rtl .ui-datepicker-group { - float: right; -} -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { - border-right-width: 0; - border-left-width: 1px; -} + */ \ No newline at end of file diff --git a/ui/datepicker.js b/ui/datepicker.js index 0dea81f4ea8..fa81f3e0674 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -16,7 +16,7 @@ "jquery", "./core", "./widget", - "./button", + "./calendar", "./position" ], factory ); } else { @@ -26,16 +26,13 @@ } }(function( $ ) { -// TODO use uniqueId, if possible -var idIncrement = 0, - // TODO move this to the instance - suppressExpandOnFocus = false; +// TODO move this to the instance +var suppressExpandOnFocus = false; return $.widget( "ui.datepicker", { options: { appendTo: null, dateFormat: { date: "short" }, - // TODO review eachDay: $.noop, numberOfMonths: 1, position: { @@ -45,7 +42,6 @@ return $.widget( "ui.datepicker", { showWeek: false, show: true, hide: true, - value: null, // callbacks beforeOpen: null, @@ -55,145 +51,54 @@ return $.widget( "ui.datepicker", { }, _create: function() { - this.id = "ui-datepicker-" + idIncrement; - idIncrement++; - - if ( this.element.is( "input" ) ) { - if ( !this.options.value && this.isValid() ) { - this.options.value = this._getParsedValue(); - } - this._createPicker(); - } else { - this.inline = true; - this.picker = this.element; + if ( !this.element.is( "input" ) ) { + return; } - this.date = $.date( this.options.value, this.options.dateFormat ).select(); - this.date.eachDay = this.options.eachDay; - - this._on( this.picker, { - "click .ui-datepicker-prev": function( event ) { - event.preventDefault(); - this.date.adjust( "M", -this.options.numberOfMonths ); - this.refresh(); - }, - "click .ui-datepicker-next": function( event ) { - event.preventDefault(); - this.date.adjust( "M", this.options.numberOfMonths ); - this.refresh(); - }, - "click .ui-datepicker-current": function( event ) { - event.preventDefault(); - this._select( event, new Date().getTime() ); - }, - "click .ui-datepicker-close": function( event ) { - event.preventDefault(); - this.close( event ); - }, - "mousedown .ui-datepicker-calendar a": function( event ) { - event.preventDefault(); - // TODO exclude clicks on lead days or handle them correctly - // TODO store/read more then just date, also required for multi month picker - this._select( event, $( event.currentTarget ).data( "timestamp" ) ); - if ( this.inline ) { - this.grid.focus( 1 ); - } - }, - "keydown .ui-datepicker-calendar": "_handleKeydown" - }); - - // TODO use hoverable (no delegation support)? convert to _on? - this.picker.delegate( ".ui-datepicker-header a, .ui-datepicker-calendar a", "mouseenter.datepicker mouseleave.datepicker", function() { - $( this ).toggleClass( "ui-state-hover" ); - }); - - this._createTmpl(); + this._createCalendar(); }, - _handleKeydown: function( event ) { - if ( jQuery.inArray( event.keyCode, [ 13, 33, 34, 35, 36, 37, 38, 39, 40 ] ) === -1 ) { - // only interested navigation keys - return; - } - event.preventDefault(); - - var newId, newCell, - activeCell = $( "#" + this.grid.attr( "aria-activedescendant" ) ), - oldMonth = this.date.month(), - oldYear = this.date.year(); - - // TODO: Handle for pickers with multiple months - switch ( event.keyCode ) { - case $.ui.keyCode.ENTER: - activeCell.children( "a:first" ).mousedown(); - return; - case $.ui.keyCode.PAGE_UP: - this.date.adjust( event.altKey ? "Y" : "M", -1 ); - break; - case $.ui.keyCode.PAGE_DOWN: - this.date.adjust( event.altKey ? "Y" : "M", 1 ); - break; - case $.ui.keyCode.END: - this.date.setDay( this.date.daysInMonth() ); - break; - case $.ui.keyCode.HOME: - this.date.setDay( 1 ); - break; - case $.ui.keyCode.LEFT: - this.date.adjust( "D", -1 ); - break; - case $.ui.keyCode.UP: - this.date.adjust( "D", -7 ); - break; - case $.ui.keyCode.RIGHT: - this.date.adjust( "D", 1 ); - break; - case $.ui.keyCode.DOWN: - this.date.adjust( "D", 7 ); - break; - default: - return; - } + _createCalendar: function() { + var that = this; - if ( this.date.month() !== oldMonth || this.date.year() !== oldYear ) { - this.refresh(); - this.grid.focus( 1 ); - } - else { - newId = this.id + "-" + this.date.day(); - newCell = $( "#" + newId ); - - // TODO unnecessary optimization? is it really needed? - if ( !newCell.length ) { - return; - } - this.grid.attr("aria-activedescendant", newId); + this.calendar = $( "
          " ); - this.grid.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); - newCell.children( "a" ).addClass( "ui-state-focus" ); - } - }, + // Initialize calendar widget + this.calendarInstance = this.calendar + .calendar({ + dateFormat: this.options.dateFormat, + eachDay: this.options.eachDay, + numberOfMonths: this.options.numberOfMonths, + showWeek: this.options.showWeek, + value: this._getParsedValue(), + select: function( event, data ) { + that.element.val( data.date ); + that.close(); + that._focusTrigger(); + that._trigger( "select", event, data); + } + }) + .calendar( "instance" ); - _createPicker: function() { - this.picker = $( "
          " ) + this.calendar .addClass( "ui-front" ) // TODO add a ui-datepicker-popup class, move position:absolute to that .css( "position", "absolute" ) - .uniqueId() .hide(); + this._setHiddenPicker(); - this.picker.appendTo( this._appendTo() ); + this.calendar.appendTo( this._appendTo() ); this.element .attr( "aria-haspopup", "true" ) - .attr( "aria-owns", this.picker.attr( "id" ) ); + .attr( "aria-owns", this.calendar.attr( "id" ) ); this._on({ keydown: function( event ) { switch ( event.keyCode ) { case $.ui.keyCode.TAB: // Waiting for close() will make popup hide too late, which breaks tab key behavior - this.picker.hide(); + this.calendar.hide(); this.close( event ); break; case $.ui.keyCode.ESCAPE: @@ -209,7 +114,7 @@ return $.widget( "ui.datepicker", { clearTimeout( this.closeTimer ); this._delay( function() { this.open( event ); - this.grid.focus( 1 ); + this.calendarInstance.grid.focus( 1 ); }, 1 ); break; case $.ui.keyCode.HOME: @@ -236,9 +141,8 @@ return $.widget( "ui.datepicker", { } }, keyup: function() { - if ( this.isValid() && !this.inline ) { - this.date.setTime( this._getParsedValue() ).select(); - this.refresh(); + if ( this.isValid() ) { + this.valueAsDate( this._getParsedValue() ); } }, mousedown: function( event ) { @@ -267,7 +171,7 @@ return $.widget( "ui.datepicker", { } }); - this._on( this.picker, { + this._on( this.calendar, { focusout: function( event ) { // use a timer to allow click to clear it and letting that // handle the closing instead of opening again @@ -284,7 +188,7 @@ return $.widget( "ui.datepicker", { }, // TODO on TAB (or shift TAB), make sure it ends up on something useful in DOM order keyup: function( event ) { - if ( event.keyCode === $.ui.keyCode.ESCAPE && this.picker.is( ":visible" ) ) { + if ( event.keyCode === $.ui.keyCode.ESCAPE && this.calendar.is( ":visible" ) ) { this.close( event ); this._focusTrigger(); } @@ -293,7 +197,7 @@ return $.widget( "ui.datepicker", { this._on( this.document, { click: function( event ) { - if ( this.isOpen && !$( event.target ).closest( this.element.add( this.picker ) ).length ) { + if ( this.isOpen && !$( event.target ).closest( this.element.add( this.calendar ) ).length ) { this.close( event ); } } @@ -309,7 +213,7 @@ return $.widget( "ui.datepicker", { this.document.find( element ).eq( 0 ); } - if ( !element ) { + if ( !element || !element[ 0 ] ) { element = this.element.closest( ".ui-front" ); } @@ -320,296 +224,17 @@ return $.widget( "ui.datepicker", { return element; }, - _createTmpl: function() { - this._createDatepicker(); - this.picker.find( "button" ).button(); - - if ( this.inline ) { - this.picker.children().addClass( "ui-datepicker-inline" ); - } - // against display:none in datepicker.css - this.picker.find( ".ui-datepicker" ).css( "display", "block" ); - this.grid = this.picker.find( ".ui-datepicker-calendar" ); - }, - - _createDatepicker: function() { - var multiClasses = [], - pickerHtml = ""; - - if (this.options.numberOfMonths === 1 ) { - pickerHtml = this._buildHeader() + this._buildGrid() + this._buildButtons(); - } else { - pickerHtml = this._buildMultiplePicker(); - multiClasses.push( "ui-datepicker-multi" ); - multiClasses.push( "ui-datepicker-multi-" + this.options.numberOfMonths ); - } - - $( "
          " ) - .addClass( "ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" ) - .addClass( multiClasses.join( " " ) ) - .attr({ - role: "region", - "aria-labelledby": this.id + "-title" - }) - .html( pickerHtml ) - .appendTo( this.picker ); - }, - - _buildMultiplePicker: function() { - var headerClass, - html = "", - currentDate = this.date, - months = this.date.months( this.options.numberOfMonths - 1 ), - i = 0; - - for ( i; i < months.length; i++ ) { - // TODO Shouldn't we pass date as a parameter to build* fns instead of setting this.date? - this.date = months[ i ]; - headerClass = months[ i ].first ? "ui-corner-left" : - months[ i ].last ? "ui-corner-right" : ""; - - html += "
          " + - "
          "; - if ( months[ i ].first ) { - html += this._buildPreviousLink(); - } - if ( months[ i ].last ) { - html += this._buildNextLink(); - } - - html += this._buildTitlebar(); - html += "
          "; - html += this._buildGrid(); - html += "
          "; - } - - html += "
          "; - html += this._buildButtons(); - - this.date = currentDate; - - return html; - }, - - _buildHeader: function() { - return "
          " + - this._buildPreviousLink() + - this._buildNextLink() + - this._buildTitlebar() + - "
          "; - }, - - _buildPreviousLink: function() { - var labels = Globalize.translate( "datepicker" ); - - return ""; - }, - - _buildNextLink: function() { - var labels = Globalize.translate( "datepicker" ); - - return ""; - }, - - _buildTitlebar: function() { - var labels = Globalize.translate( "datepicker" ); - - return "
          " + - "
          " + - this._buildTitle() + - "
          " + - ", " + labels.datePickerRole + "" + - "
          "; - }, - - _buildTitle: function() { - return "" + - this.date.monthName() + - " " + - "" + - this.date.year() + - ""; - }, - - _buildGrid: function() { - return "" + - this._buildGridHeading() + - this._buildGridBody() + - "
          "; - }, - - _buildGridHeading: function() { - var cells = "", - i = 0, - labels = Globalize.translate( "datepicker" ); - - if ( this.options.showWeek ) { - cells += "" + labels.weekHeader + ""; - } - for ( i; i < this.date.weekdays().length; i++ ) { - cells += this._buildGridHeaderCell( this.date.weekdays()[i] ); - } - - return "" + - "" + cells + "" + - ""; - }, - - _buildGridHeaderCell: function( day ) { - return "" + - "" + - day.shortname + - "" + - ""; - }, - - _buildGridBody: function() { - // this.date.days() is not cached, and it has O(n^2) complexity. It is run O(n) times. So, it equals O(n^3). Not good at all. Caching. - var days = this.date.days(), - i = 0, - rows = ""; - - for ( i; i < days.length; i++ ) { - rows += this._buildWeekRow( days[ i ] ); - } - - return "" + rows + ""; - }, - - _buildWeekRow: function( week ) { - var cells = "", - i = 0; - - if ( this.options.showWeek ) { - cells += "" + week.number + ""; - } - for ( i; i < week.days.length; i++ ) { - cells += this._buildDayCell( week.days[i] ); - } - return "" + cells + ""; - }, - - _buildDayCell: function( day ) { - var contents = "", - idAttribute = day.render ? ( "id=" + this.id + "-" + day.date ) : "", - ariaSelectedAttribute = "aria-selected=" + ( day.current ? "true" : "false" ), - ariaDisabledAttribute = day.selectable ? "" : "aria-disabled=true"; - - if ( day.render ) { - if ( day.selectable ) { - contents = this._buildDayLink( day ); - } else { - contents = this._buildDayDisplay( day ); - } - } - - return "" + - contents + - ""; - }, - - _buildDayLink: function( day ) { - var link, - classes = [ "ui-state-default" ], - labels = Globalize.translate( "datepicker" ); - - if ( day.date === this.date.day() ) { - classes.push( "ui-state-focus" ); - } - if ( day.current ) { - classes.push( "ui-state-active" ); - } - if ( day.today ) { - classes.push( "ui-state-highlight" ); - } - if ( day.extraClasses ) { - classes.push( day.extraClasses.split( " " ) ); - } - - link = "" + - day.date + ""; - if ( day.today ) { - link += ", " + labels.currentText + ""; - } - - return link; - }, - - _buildDayDisplay: function( day ) { - var classes = []; - - if ( day.current ) { - classes.push( "ui-state-active" ); - } - if ( day.today ) { - classes.push( "ui-state-highlight" ); - } - if ( day.extraClasses ) { - classes.push( day.extraClasses.split( " " ) ); - } - - return "" + day.date + ""; - }, - - _buildButtons: function() { - var labels = Globalize.translate( "datepicker" ); - - return "
          " + - "" + - "" + - "
          "; - }, - _focusTrigger: function() { suppressExpandOnFocus = true; this.element.focus(); }, - // Refreshing the entire datepicker during interaction confuses screen readers, specifically - // because the grid heading is marked up as a live region and will often not update if it's - // destroyed and recreated instead of just having its text change. Additionally, interacting - // with the prev and next links would cause loss of focus issues because the links being - // interacted with will disappear while focused. refresh: function() { - // determine which day gridcell to focus after refresh - // TODO: Prevent disabled cells from being focused - if ( this.options.numberOfMonths === 1 ) { - this.grid = $( this._buildGrid() ); - $( ".ui-datepicker-title", this.picker ).html( this._buildTitle() ); - $( ".ui-datepicker-calendar", this.picker ).replaceWith( this.grid ); - } else { - this._refreshMultiplePicker(); - } - }, - - _refreshMultiplePicker: function() { - var i = 0; - - for ( ; i < this.options.numberOfMonths; i++ ) { - $( ".ui-datepicker-title", this.picker ).eq( i ).html( this._buildTitle() ); - $( ".ui-datepicker-calendar", this.picker ).eq( i ).html( this._buildGrid() ); - this.date.adjust( "M", 1 ); - } - this.date.adjust( "M", -this.options.numberOfMonths ); - - // TODO: This assumes focus is on the first grid. For multi pickers, the widget needs - // to maintain the currently focused grid and base queries like this off of it. - $( this.picker ).find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" ); + this.calendarInstance.refresh(); }, open: function( event ) { - if ( this.inline || this.isOpen ) { + if ( this.isOpen ) { return; } if ( this._trigger( "beforeOpen", event ) === false ) { @@ -618,14 +243,14 @@ return $.widget( "ui.datepicker", { this.refresh(); - this.picker + this.calendar .attr( "aria-hidden", "false" ) .attr( "aria-expanded", "true" ) .show() .position( this._buildPosition() ) .hide(); - this._show( this.picker, this.options.show ); + this._show( this.calendar, this.options.show ); // take trigger out of tab order to allow shift-tab to skip trigger // TODO does this really make sense? related bug: tab-shift moves focus to last element on page @@ -636,12 +261,8 @@ return $.widget( "ui.datepicker", { }, close: function( event ) { - if ( this.inline ) { - return; - } - this._setHiddenPicker(); - this._hide( this.picker, this.options.hide ); + this._hide( this.calendar, this.options.hide ); this.element.attr( "tabindex" , 0 ); @@ -650,7 +271,7 @@ return $.widget( "ui.datepicker", { }, _setHiddenPicker: function() { - this.picker + this.calendar .attr( "aria-hidden", "true" ) .attr( "aria-expanded", "false" ); }, @@ -659,107 +280,65 @@ return $.widget( "ui.datepicker", { return $.extend( {}, { of: this.element }, this.options.position ); }, - _select: function( event, time ) { - this._setOption( "value", new Date( time ) ); - if ( !this.inline ) { - this.close(); - this._focusTrigger(); - } - this._trigger( "select", event, { - // TODO replace with value option to initialise and read - date: this.value() - }); - }, - value: function( value ) { if ( arguments.length ) { - this._setOption( "value", Globalize.parseDate( value, this.options.dateFormat ) ); - } else { - if ( this.inline ) { - return Globalize.format( this.date.selected(), this.options.dateFormat ); - } else { - return this.element.val(); + var date = Globalize.parseDate( value, this.options.dateFormat ); + if ( this.calendarInstance._isValid( date ) ) { + this.valueAsDate( date ); + this.element.val( value ); } + } else { + return ( this._getParsedValue() !== null ) ? this.element.val() : null; } }, valueAsDate: function( value ) { if ( arguments.length ) { - this._setOption( "value", value ); + if ( this.calendarInstance._isValid( value ) ) { + this.calendarInstance.valueAsDate( value ); + this.element.val( Globalize.format( value, this.options.dateFormat ) ); + } } else { - return this.option( "value" ); + return this._getParsedValue(); } }, isValid: function() { - if ( this.inline ) { - return true; - } - - return this._getParsedValue() !== null; + return this.calendarInstance._isValid( this._getParsedValue() ); }, _destroy: function() { - if ( this.inline ) { - this.picker.empty(); - } else { - this.picker.remove(); - this.element - .removeAttr( "aria-haspopup" ) - .removeAttr( "aria-owns" ); - } + this.calendarInstance.destroy(); + this.element + .removeAttr( "aria-haspopup" ) + .removeAttr( "aria-owns" ); }, widget: function() { - return this.picker; + return this.calendar; }, _getParsedValue: function() { return Globalize.parseDate( this.element.val(), this.options.dateFormat ); }, - option: function( key ) { - if ( arguments.length === 0 || ( arguments.length === 1 && key === "value" ) ) { - this.options.value = this.inline ? this.date.selected() : this._getParsedValue(); - } - return this._superApply( arguments ); - }, - _setOption: function( key, value ) { - if ( key === "value" ) { - if ( value instanceof Date ) { - this.date.setTime( value.getTime() ).select(); - this.refresh(); - if ( !this.inline ) { - this.element.val( this.date.format() ); - } - } - } - this._super( key, value ); if ( key === "appendTo" ) { - this.picker.appendTo( this._appendTo() ); - } - - if ( key === "eachDay" ) { - this.date.eachDay = this.options.eachDay; - this.refresh(); + this.calendar.appendTo( this._appendTo() ); } if ( key === "dateFormat" ) { - this.date.setFormat( this.options.dateFormat ); - if ( !this.inline ) { - this.element.val( this.date.format() ); - } + this.element.val( this.date.format() ); } - if ( key === "showWeek" ) { - this.refresh(); + if ( key === "position" ) { + this.calendar.position( this._buildPosition() ); } - if ( key === "position" ) { - this.picker.position( this._buildPosition() ); + if ( $.inArray( key, [ "showWeek", "numberOfMonths", "dateFormat", "eachDay" ] ) ) { + this.calendarInstance._setOption( key, value ); } } }); From aa1aea15f8e461d68ac3b3ad750b1f86665ec5dc Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 19:13:53 +0200 Subject: [PATCH 078/172] Calendar: Fix AMD dependencies --- ui/calendar.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 01f80964320..c0ac8d5d925 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -16,8 +16,7 @@ "jquery", "./core", "./widget", - "./button", - "./position" + "./button" ], factory ); } else { From 504ab73c32279cd0655e36db84ad1cbaf0978ed0 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 23:15:50 +0200 Subject: [PATCH 079/172] Calendar: Add min and max option Add min and max option by extending _isValid method and improving render day cell mechanism --- demos/calendar/min-max.html | 14 ++++-- ui/calendar.js | 88 ++++++++++++++++++++++--------------- 2 files changed, 63 insertions(+), 39 deletions(-) diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html index 94826c71a71..2fddbcbc3bd 100644 --- a/demos/calendar/min-max.html +++ b/demos/calendar/min-max.html @@ -16,16 +16,24 @@ -

          Date:

          +
          -

          Restrict the range of selectable dates with the minDate and maxDate options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D'). For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.

          +

          Restrict the range of selectable dates with the min and max options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)).

          diff --git a/ui/calendar.js b/ui/calendar.js index c0ac8d5d925..4dbdd4522d6 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -30,6 +30,8 @@ return $.widget( "ui.calendar", { dateFormat: { date: "short" }, // TODO review eachDay: $.noop, + max: null, + min: null, numberOfMonths: 1, showWeek: false, value: null, @@ -314,30 +316,33 @@ return $.widget( "ui.calendar", { }, _buildDayCell: function( day ) { - var contents = "", - idAttribute = day.render ? ( "id=" + this.id + "-" + day.date ) : "", - ariaSelectedAttribute = "aria-selected=" + ( day.current ? "true" : "false" ), - ariaDisabledAttribute = day.selectable ? "" : "aria-disabled=true"; + var content = "", + attributes = [ + "role='gridcell'", + "aria-selected='" + day.current ? true : false + "'" + ], + selectable = ( day.selectable && this._isValid( new Date( day.timestamp ) ) ); if ( day.render ) { - if ( day.selectable ) { - contents = this._buildDayLink( day ); - } else { - contents = this._buildDayDisplay( day ); + attributes.push( "id='" + this.id + "-" + day.date + "'" ); + + if ( !selectable ) { + attributes.push( "aria-disabled='true'" ); + attributes.push( "class='ui-state-disabled'" ); } + + content = this._buildDayElement( day, selectable ); } - return "" + - contents + - ""; + return "" + content + ""; }, - _buildDayLink: function( day ) { - var link, - classes = [ "ui-state-default" ], - labels = Globalize.translate( "datepicker" ); + _buildDayElement: function( day, selectable ) { + var classes = [ "ui-state-default" ], + labels = Globalize.translate( "datepicker" ), + content = ""; - if ( day === this.date ) { + if ( day === this.date && selectable ) { classes.push( "ui-state-focus" ); } if ( day.current ) { @@ -346,33 +351,23 @@ return $.widget( "ui.calendar", { if ( day.today ) { classes.push( "ui-state-highlight" ); } + // ToDo Explain and document this if ( day.extraClasses ) { classes.push( day.extraClasses.split( " " ) ); } - link = "" + - day.date + ""; - if ( day.today ) { - link += ", " + labels.currentText + ""; + classes = " class='" + classes.join( " " ) + "'"; + if ( selectable ) { + content = "" + day.date + ""; + } else { + content = "" + day.date + ""; } - return link; - }, - - _buildDayDisplay: function( day ) { - var classes = []; - - if ( day.current ) { - classes.push( "ui-state-active" ); - } if ( day.today ) { - classes.push( "ui-state-highlight" ); - } - if ( day.extraClasses ) { - classes.push( day.extraClasses.split( " " ) ); + content += ", " + labels.currentText + ""; } - return "" + day.date + ""; + return content; }, _buildButtons: function() { @@ -445,8 +440,23 @@ return $.widget( "ui.calendar", { }, _isValid: function( value ) { - // ToDo implement min / max option - return ( value instanceof Date ); + if ( !( value instanceof Date ) ) { + return false; + } + + if ( this.options.max instanceof Date ) { + if ( value > this.options.max ) { + return false; + } + } + + if ( this.options.min instanceof Date ) { + if ( value < $.date( this.options.min ).adjust( "D", -1 ).date() ) { + return false; + } + } + + return true; }, _destroy: function() { @@ -470,6 +480,12 @@ return $.widget( "ui.calendar", { } } + if ( key === "max" || key === "min" ) { + if ( !( value instanceof Date ) ) { + return; + } + } + this._super( key, value ); if ( key === "eachDay" ) { From ada1afb3853f0ba7606177e96de075cb1c324ac4 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 23:17:45 +0200 Subject: [PATCH 080/172] Calendar: Remove unneeded demo files --- demos/calendar/alt-field.html | 36 ------------------- demos/calendar/animation.html | 59 -------------------------------- demos/calendar/date-range.html | 49 -------------------------- demos/calendar/icon-trigger.html | 46 ------------------------- demos/calendar/inline.html | 31 ----------------- 5 files changed, 221 deletions(-) delete mode 100644 demos/calendar/alt-field.html delete mode 100644 demos/calendar/animation.html delete mode 100644 demos/calendar/date-range.html delete mode 100644 demos/calendar/icon-trigger.html delete mode 100644 demos/calendar/inline.html diff --git a/demos/calendar/alt-field.html b/demos/calendar/alt-field.html deleted file mode 100644 index bc8289eab38..00000000000 --- a/demos/calendar/alt-field.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - jQuery UI Calendar - Populate alternate field - - - - - - - - - - - - - - - -

          Date:  

          - -
          -

          Populate an alternate field with its own date format whenever a date is selected using the altField and altFormat options. This feature could be used to present a human-friendly date for user selection, while passing a more computer-friendly date through for further processing.

          -
          - - diff --git a/demos/calendar/animation.html b/demos/calendar/animation.html deleted file mode 100644 index 989006722a0..00000000000 --- a/demos/calendar/animation.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - jQuery UI Calendar - Animations - - - - - - - - - - - - - - - - - - - - - - -

          Date:

          - -

          Animations:
          - -

          - -
          -

          Use different animations when opening or closing the calendar. Choose an animation from the dropdown, then click on the input to see its effect. You can use one of the three standard animations or any of the UI Effects.

          -
          - - diff --git a/demos/calendar/date-range.html b/demos/calendar/date-range.html deleted file mode 100644 index 7962dacce38..00000000000 --- a/demos/calendar/date-range.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - jQuery UI Calendar - Select a Date Range - - - - - - - - - - - - - - - - - - - - -
          -

          Select the date range to search for.

          -
          - - diff --git a/demos/calendar/icon-trigger.html b/demos/calendar/icon-trigger.html deleted file mode 100644 index 168708520e7..00000000000 --- a/demos/calendar/icon-trigger.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - jQuery UI Calendar - Icon trigger - - - - - - - - - - - - - - - -

          Date:

          - -
          -

          Click the icon next to the input field to show the calendar. Set the calendar to open on focus (default behavior), on icon click, or both.

          -
          - - diff --git a/demos/calendar/inline.html b/demos/calendar/inline.html deleted file mode 100644 index b6f2575993b..00000000000 --- a/demos/calendar/inline.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - jQuery UI Calendar - Display inline - - - - - - - - - - - - - - - -Date:
          - -
          -

          Display the calendar embedded in the page instead of in an overlay. Simply call .calendar() on a div instead of an input.

          -
          - - From 8f5e4c8819a9c3174b9f4676ed57e8888df792bb Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 23:24:54 +0200 Subject: [PATCH 081/172] Datepicker: Add min and max option --- demos/datepicker/min-max.html | 13 +++++++++++-- ui/datepicker.js | 6 +++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/demos/datepicker/min-max.html b/demos/datepicker/min-max.html index 59559678484..6253a4a2ddc 100644 --- a/demos/datepicker/min-max.html +++ b/demos/datepicker/min-max.html @@ -11,12 +11,21 @@ + @@ -25,7 +34,7 @@

          Date:

          -

          Restrict the range of selectable dates with the minDate and maxDate options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D'). For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.

          +

          Restrict the range of selectable dates with the min and max options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)).

          diff --git a/ui/datepicker.js b/ui/datepicker.js index fa81f3e0674..f237fef4f9a 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -34,6 +34,8 @@ return $.widget( "ui.datepicker", { appendTo: null, dateFormat: { date: "short" }, eachDay: $.noop, + max: null, + min: null, numberOfMonths: 1, position: { my: "left top", @@ -68,6 +70,8 @@ return $.widget( "ui.datepicker", { .calendar({ dateFormat: this.options.dateFormat, eachDay: this.options.eachDay, + max: this.options.max, + min: this.options.min, numberOfMonths: this.options.numberOfMonths, showWeek: this.options.showWeek, value: this._getParsedValue(), @@ -337,7 +341,7 @@ return $.widget( "ui.datepicker", { this.calendar.position( this._buildPosition() ); } - if ( $.inArray( key, [ "showWeek", "numberOfMonths", "dateFormat", "eachDay" ] ) ) { + if ( $.inArray( key, [ "showWeek", "numberOfMonths", "dateFormat", "eachDay", "min", "max" ] ) ) { this.calendarInstance._setOption( key, value ); } } From 83ff362af6fa8fbb228137ff73ff3c0e3e940e29 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 23:40:39 +0200 Subject: [PATCH 082/172] Datepicker: Remove select callback reference --- ui/datepicker.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index f237fef4f9a..5819611e419 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -75,11 +75,11 @@ return $.widget( "ui.datepicker", { numberOfMonths: this.options.numberOfMonths, showWeek: this.options.showWeek, value: this._getParsedValue(), - select: function( event, data ) { - that.element.val( data.date ); + select: function( event ) { + that.element.val( that.calendarInstance.value() ); that.close(); that._focusTrigger(); - that._trigger( "select", event, data); + that._trigger( "select", event ); } }) .calendar( "instance" ); From 088bcca84567802ed8b7876c95054f933ec0304c Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 23:41:13 +0200 Subject: [PATCH 083/172] Calendar: Remove select callback reference --- ui/calendar.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 4dbdd4522d6..269b77d7918 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -418,9 +418,7 @@ return $.widget( "ui.calendar", { _select: function( event, time ) { this._setOption( "value", new Date( time ) ); - this._trigger( "select", event, { - date: this.value() - }); + this._trigger( "select", event ); }, value: function( value ) { From c1e4bebed682d9ffd4a2de409e5ae30705d7c768 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 5 Jun 2014 00:38:13 +0200 Subject: [PATCH 084/172] Calendar: Fix min / max option incl. refresh after setting option --- demos/calendar/min-max.html | 9 ++++----- demos/datepicker/min-max.html | 7 +++---- ui/calendar.js | 12 +++++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html index 2fddbcbc3bd..067b6f02f66 100644 --- a/demos/calendar/min-max.html +++ b/demos/calendar/min-max.html @@ -16,12 +16,11 @@ + - - - - - - - - - - - - - -Date:
          - -
          -

          Display the datepicker embedded in the page instead of in an overlay. Simply call .datepicker() on a div instead of an input.

          -
          - - From 6083a0162bbaf6464cac11c2afb382502483a569 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 5 Jun 2014 01:17:58 +0200 Subject: [PATCH 088/172] Datepicker: Read and write min / max attributes --- ui/datepicker.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 5819611e419..c8ba41c48d1 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -57,6 +57,13 @@ return $.widget( "ui.datepicker", { return; } + if ( this.options.max === null ) { + this.options.max = this._parseDate( this.element.attr( "max" ) ); + } + if ( this.options.min === null ) { + this.options.min = this._parseDate( this.element.attr( "min" ) ); + } + this._createCalendar(); }, @@ -286,7 +293,7 @@ return $.widget( "ui.datepicker", { value: function( value ) { if ( arguments.length ) { - var date = Globalize.parseDate( value, this.options.dateFormat ); + var date = this._parseDate( value ); if ( this.calendarInstance._isValid( date ) ) { this.valueAsDate( date ); this.element.val( value ); @@ -323,7 +330,11 @@ return $.widget( "ui.datepicker", { }, _getParsedValue: function() { - return Globalize.parseDate( this.element.val(), this.options.dateFormat ); + return this._parseDate( this.element.val() ); + }, + + _parseDate: function( string ) { + return Globalize.parseDate( string , this.options.dateFormat ); }, _setOption: function( key, value ) { @@ -337,6 +348,10 @@ return $.widget( "ui.datepicker", { this.element.val( this.date.format() ); } + if ( key === "max" || key === "min" ) { + this.element.attr( key, Globalize.format( value, this.options.dateFormat ) ); + } + if ( key === "position" ) { this.calendar.position( this._buildPosition() ); } From 7cabbeffca1f18da992c6a34aa6fa49c5fc9d659 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 5 Jun 2014 01:19:34 +0200 Subject: [PATCH 089/172] Calendar: Add missing AMD dependency todo comment --- ui/calendar.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/calendar.js b/ui/calendar.js index 884641c850c..e54748a109f 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -12,6 +12,7 @@ if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. + // ToDo Add globalize and $.date? define([ "jquery", "./core", From 43b448e0888f1519844fa9821aa0670ab4d7f722 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 5 Jun 2014 01:37:42 +0200 Subject: [PATCH 090/172] Datepicker: Read and write min / max attributes (follow-up) --- ui/datepicker.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index c8ba41c48d1..f5f93ae9370 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -57,11 +57,14 @@ return $.widget( "ui.datepicker", { return; } - if ( this.options.max === null ) { - this.options.max = this._parseDate( this.element.attr( "max" ) ); + var max = this.element.attr( "max" ), + min = this.element.attr( "min" ); + + if ( this.options.max === null && max ) { + this.options.max = this._parseDate( max ); } - if ( this.options.min === null ) { - this.options.min = this._parseDate( this.element.attr( "min" ) ); + if ( this.options.min === null && min ) { + this.options.min = this._parseDate( min ); } this._createCalendar(); From fb774c8140837808601cf22c31a1ea80986e7f23 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 5 Jun 2014 01:41:00 +0200 Subject: [PATCH 091/172] Datepicker tests: Add Calendar widget dependency to unit tests --- tests/unit/datepicker/datepicker.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 95f26957812..42c2363f2bc 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -14,11 +14,12 @@ + diff --git a/ui/datepicker.js b/ui/datepicker.js index f330eeab57c..501f9254a56 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -316,7 +316,7 @@ widget = $.widget( "ui.datepicker", { _setOption: function( key, value ) { this._super( key, value ); - if ( $.inArray( key, calendarOptions ) ) { + if ( $.inArray( key, calendarOptions ) !== -1 ) { this.calendarInstance._setOption( key, value ); } @@ -325,7 +325,7 @@ widget = $.widget( "ui.datepicker", { } if ( key === "dateFormat" ) { - this.element.val( this.date.format() ); + this.element.val( this.calendarInstance.value() ); } if ( key === "max" || key === "min" ) { From 42e895056646c57c7514c657ba571670b8862b2f Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 13 Jun 2014 18:29:58 +0200 Subject: [PATCH 108/172] Datepicker tests: Adjust methods unit tests according to specs --- tests/unit/datepicker/datepicker_methods.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 75cfb7372e2..c2a766a3379 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -40,10 +40,12 @@ test( "widget", function() { }); test( "close", function() { + // ToDo implement this expect( 0 ); }); test( "open", function() { + // ToDo implement this expect( 0 ); }); @@ -54,12 +56,13 @@ test( "value", function() { input.datepicker( "value", "1/1/14" ); equal( input.val(), "1/1/14", "input's value set" ); - ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + input.datepicker( "open" ); + ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "first day marked as selected" ); equal( input.datepicker( "value" ), "1/1/14", "getter" ); input.val( "abc" ); - equal( input.datepicker( "value" ), "abc", + equal( input.datepicker( "value" ), null, "Invalid values should be returned without formatting." ); }); @@ -70,7 +73,7 @@ test( "valueAsDate", function() { input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); equal( input.val(), "1/1/14", "input's value set" ); - ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), + ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "first day marked as selected" ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "getter" ); From 26a4ed6a021268dc5561393db636ea52f9bc1cc4 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 13 Jun 2014 19:22:00 +0200 Subject: [PATCH 109/172] Datepicker: Fix some core unit tests, remove unneeded tests --- tests/unit/datepicker/datepicker_core.js | 198 +++++------------------ 1 file changed, 42 insertions(+), 156 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 25b9473a782..65a0c5c6fdc 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -20,13 +20,15 @@ test( "input's value determines starting date", function() { }); asyncTest( "baseStructure", function() { - expect( 25 ); + expect( 23 ); + var header, title, table, thead, week, child, inp = TestHelpers.datepicker.initNewInput(), dp = inp.datepicker( "widget" ); function step1() { inp.focus(); + setTimeout(function() { ok( dp.is( ":visible" ), "Structure - datepicker visible" ); ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" ); @@ -58,13 +60,10 @@ asyncTest( "baseStructure", function() { week = table.children( ":eq(1)" ).children( ":first" ); ok( week.is( "tr" ), "Structure - month table week row" ); equal( week.children().length, 7, "Structure - week child count" ); - // TODO: Preserve these class names or let the user use :first-child and :last-child? - ok( week.children( ":first" ).is( "td.ui-calendar-week-end" ), "Structure - month table first day cell" ); - ok( week.children( ":last" ).is( "td.ui-calendar-week-end" ), "Structure - month table second day cell" ); inp.datepicker( "close" ).datepicker( "destroy" ); step2(); - }); + }, 50 ); } function step2() { @@ -76,14 +75,6 @@ asyncTest( "baseStructure", function() { ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" ); equal( dp.children().length, 4, "Structure multi [2] - child count" ); - // TODO: Implement ui-datepicker-group-first class name -// child = dp.children( ":first" ); -// ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-first" ), "Structure multi [2] - first month division" ); - - // TODO: Implement ui-datepicker-group-last class name -// child = dp.children( ":eq(1)" ); -// ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-last" ), "Structure multi [2] - second month division" ); - child = dp.children( ":eq(2)" ); ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" ); @@ -95,118 +86,21 @@ asyncTest( "baseStructure", function() { step1(); }); -// Skip these tests for now as none are implemented yet. -/* -asyncTest( "customStructure", function() { - expect( 0 ); - - var header, panel, title, - inp = TestHelpers.datepicker.initNewInput(), - dp = inp.datepicker( "widget" ); - - start(); - - function step1() { - Globalize.culture( "he" ); - inp.focus(); - - setTimeout(function() { - ok( dp.is( ".ui-calendar-rtl" ), "Structure RTL - right-to-left" ); - - header = dp.children( ":first" ); - ok( header.is( "div.ui-calendar-header" ), "Structure RTL - header division" ); - equal( header.children().length, 3, "Structure RTL - header child count" ); - ok( header.children( ":first" ).is( "a.ui-calendar-next" ), "Structure RTL - prev link" ); - ok( header.children( ":eq(1)" ).is( "a.ui-calendar-prev" ), "Structure RTL - next link" ); - - panel = dp.children( ":last" ); - ok( panel.is( "div.ui-calendar-buttonpane" ), "Structure RTL - button division" ); - equal( panel.children().length, 2, "Structure RTL - button panel child count" ); - ok( panel.children( ":first" ).is( "button.ui-calendar-close" ), "Structure RTL - close button" ); - ok( panel.children( ":last" ).is( "button.ui-calendar-current" ), "Structure RTL - today button" ); - - inp.datepicker( "close" ).datepicker( "destroy" ); - Globalize.culture( "en-US" ); - step2(); - }); - } - - // Hide prev/next - // TODO: If we decide the hideIfNoPrevNext option is being removed these tests can be as well. - function stepX() { - inp = TestHelpers.datepicker.initNewInput({ - hideIfNoPrevNext: true, - minDate: new Date( 2008, 2 - 1, 4 ), - maxDate: new Date( 2008, 2 - 1, 14 ) - }); - inp.val( "02/10/2008" ); - - TestHelpers.datepicker.onFocus( inp, function() { - header = dp.children( ":first" ); - ok( header.is( "div.ui-calendar-header" ), "Structure hide prev/next - header division" ); - equal( header.children().length, 1, "Structure hide prev/next - links child count" ); - ok( header.children( ":first" ).is( "div.ui-calendar-title" ), "Structure hide prev/next - title division" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step3(); - }); - } - - // Changeable Month with read-only year - function step2() { - inp = TestHelpers.datepicker.initNewInput({ changeMonth: true } ); - dp = inp.datepicker( "widget" ); - - inp.focus(); - setTimeout(function() { - title = dp.children( ":first" ).children( ":last" ); - - // TODO: Implement changeMonth option - // equal( title.children().length, 2, "Structure changeable month - title child count" ); - // ok( title.children( ":first" ).is( "select.ui-calendar-month" ), "Structure changeable month - month selector" ); - // ok( title.children( ":last" ).is( "span.ui-calendar-year" ), "Structure changeable month - read-only year" ); - - inp.datepicker( "close" ).datepicker( "destroy" ); - step3(); - }); - } - - // Changeable year with read-only month - function step3() { - inp = TestHelpers.datepicker.initNewInput({ changeYear: true } ); - - TestHelpers.datepicker.onFocus( inp, function() { - title = dp.children( ":first" ).children( ":last" ); - - // TODO: Implement changeYear option - // equal( title.children().length, 2, "Structure changeable year - title child count" ); - // ok( title.children( ":first" ).is( "span.ui-calendar-month" ), "Structure changeable year - read-only month" ); - // ok( title.children( ":last" ).is( "select.ui-calendar-year" ), "Structure changeable year - year selector" ); - - inp.datepicker( "close" ).datepicker( "destroy" ); - start(); - }); - } - - // TODO: figure out why this setTimeout is needed in IE, - // it only is necessary when the previous baseStructure tests runs first - // Support: IE - setTimeout( step1 ); -}); -*/ - test( "Keyboard handling", function() { - expect( 9 ); + expect( 8 ); var input = $( "#datepicker" ).datepicker(), instance = input.datepicker( "instance" ), date = new Date(); + // Enter = Select today's date by default input.datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke enter" ); - // Enter = Select today's date by default - input.val( "1/1/14" ).datepicker( "open" ) + // Enter = Select preset date + input.val( "1/1/14" ) + .datepicker( "refresh" ) + .datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke enter - preset" ); @@ -217,11 +111,6 @@ test( "Keyboard handling", function() { .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+home" ); - // Control + End = Close the calendar and clear the input - input.val( "1/1/14" ).datepicker( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); - equal( input.val(), "", "Keystroke ctrl+end" ); - input.val( "" ).datepicker( "open" ); ok( instance.isOpen, "datepicker is open before escape" ); input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); @@ -263,7 +152,7 @@ asyncTest( "keyboard handling", function() { ok( picker.is( ":visible" ), "Keystroke down opens datepicker" ); input.datepicker( "destroy" ); step2(); - }); + }, 50 ); } function step2() { @@ -277,12 +166,12 @@ asyncTest( "keyboard handling", function() { ok( picker.is( ":visible" ), "Keystroke up opens datepicker" ); input.datepicker( "destroy" ); step3(); - }); + }, 50 ); } function step3() { - input.datepicker() - .val( "1/1/14" ) + input.val( "1/1/14" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -299,8 +188,8 @@ asyncTest( "keyboard handling", function() { } function step4() { - input.datepicker() - .val( "1/1/14" ) + input.val( "1/1/14" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -317,8 +206,8 @@ asyncTest( "keyboard handling", function() { } function step5() { - input.datepicker() - .val( "1/1/14" ) + input.val( "1/1/14" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -335,8 +224,8 @@ asyncTest( "keyboard handling", function() { } function step6() { - input.datepicker() - .val( "1/1/14" ) + input.val( "1/1/14" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -353,8 +242,8 @@ asyncTest( "keyboard handling", function() { } function step7() { - input.datepicker() - .val( "1/1/14" ) + input.val( "1/1/14" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -371,8 +260,8 @@ asyncTest( "keyboard handling", function() { } function step8() { - input.datepicker() - .val( "1/1/14" ) + input.val( "1/1/14" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -389,8 +278,8 @@ asyncTest( "keyboard handling", function() { } function step9() { - input.datepicker() - .val( "1/1/14" ) + input.val( "1/1/14" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -407,8 +296,8 @@ asyncTest( "keyboard handling", function() { } function step10() { - input.datepicker() - .val( "1/1/14" ) + input.val( "1/1/14" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -426,8 +315,8 @@ asyncTest( "keyboard handling", function() { // Check for moving to short months function step11() { - input.datepicker() - .val( "3/31/14" ) + input.val( "3/31/14" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -444,8 +333,8 @@ asyncTest( "keyboard handling", function() { } function step12() { - input.datepicker() - .val( "1/30/16" ) + input.val( "1/30/16" ) + .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { @@ -481,7 +370,7 @@ asyncTest( "keyboard handling", function() { */ test( "mouse", function() { - expect( 8 ); + expect( 10 ); var input = $( "#datepicker" ).datepicker(), picker = input.datepicker( "widget" ), date = new Date(); @@ -491,50 +380,48 @@ test( "mouse", function() { date.setDate( 10 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Mouse click" ); - input.val( "2/4/08" ).datepicker( "open" ); + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), "Mouse click - preset" ) ; - input.val( "" ).datepicker( "open" ); + input.val( "" ).datepicker( "refresh" ).datepicker( "open" ); $( "button.ui-calendar-close", picker ).simulate( "click", {} ); ok( input.datepicker( "valueAsDate" ) == null, "Mouse click - close" ); - input.val( "2/4/08" ).datepicker( "open" ); + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); $( "button.ui-calendar-close", picker ).simulate( "click", {} ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), "Mouse click - close + preset" ); - input.val( "2/4/08" ).datepicker( "open" ); + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); $( "a.ui-calendar-prev", picker ).simulate( "click", {} ); $( "button.ui-calendar-close", picker ).simulate( "click", {} ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), "Mouse click - abandoned" ); // Current/previous/next - input.val( "" ).datepicker( "open" ); + input.val( "" ).datepicker( "refresh" ).datepicker( "open" ); $( ".ui-calendar-current", picker ).simulate( "click", {} ); date.setDate( new Date().getDate() ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Mouse click - current" ); - input.val( "2/4/08" ).datepicker( "open" ); + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); $( ".ui-calendar-prev", picker ).simulate( "click" ); $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), "Mouse click - previous" ); - input.val( "2/4/08" ).datepicker( "open" ); + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); $( ".ui-calendar-next", picker ).simulate( "click" ); $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), "Mouse click - next" ); - /* - // TODO: Re-add when min and max options are introduced. // Previous/next with minimum/maximum input.datepicker( "option", { - minDate: new Date( 2008, 2 - 1, 2 ), - maxDate: new Date( 2008, 2 - 1, 26 ) + min: new Date( 2008, 2 - 1, 2 ), + max: new Date( 2008, 2 - 1, 26 ) }).val( "2/4/08" ).datepicker( "open" ); $( ".ui-calendar-prev", picker ).simulate( "click" ); $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); @@ -546,7 +433,6 @@ test( "mouse", function() { $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); TestHelpers.datepicker.equalsDate(input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 18 ), "Mouse click - next + min/max" ); - */ }); })( jQuery ); From f375c7dc4f29c74c8b29721642bf1e62a040bb05 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 16 Jun 2014 18:07:06 +0200 Subject: [PATCH 110/172] Datepicker tests: Remove unneeded options unit tests, add todo comments --- tests/unit/datepicker/datepicker_options.js | 671 +------------------- 1 file changed, 7 insertions(+), 664 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index e6807f4b72e..117a60f0de8 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -155,48 +155,7 @@ test( "showWeek", function() { }); /* -test( "setDefaults", function() { - expect( 3 ); - TestHelpers.datepicker.init( "#inp" ); - equal($.datepicker._defaults.showOn, "focus", "Initial showOn" ); - $.datepicker.setDefaults({showOn: "button"}); - equal($.datepicker._defaults.showOn, "button", "Change default showOn" ); - $.datepicker.setDefaults({showOn: "focus"}); - equal($.datepicker._defaults.showOn, "focus", "Restore showOn" ); -}); - -test( "option", function() { - expect( 17 ); - var inp = TestHelpers.datepicker.init( "#inp" ), - inst = $.data(inp[0], TestHelpers.datepicker.PROP_NAME); - // Set option - equal(inst.settings.showOn, null, "Initial setting showOn" ); - equal($.datepicker._get(inst, "showOn" ), "focus", "Initial instance showOn" ); - equal($.datepicker._defaults.showOn, "focus", "Initial default showOn" ); - inp.datepicker( "option", "showOn", "button" ); - equal(inst.settings.showOn, "button", "Change setting showOn" ); - equal($.datepicker._get(inst, "showOn" ), "button", "Change instance showOn" ); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - inp.datepicker( "option", {showOn: "both"}); - equal(inst.settings.showOn, "both", "Change setting showOn" ); - equal($.datepicker._get(inst, "showOn" ), "both", "Change instance showOn" ); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - inp.datepicker( "option", "showOn", undefined); - equal(inst.settings.showOn, null, "Clear setting showOn" ); - equal($.datepicker._get(inst, "showOn" ), "focus", "Restore instance showOn" ); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - // Get option - inp = TestHelpers.datepicker.init( "#inp" ); - equal(inp.datepicker( "option", "showOn" ), "focus", "Initial setting showOn" ); - inp.datepicker( "option", "showOn", "button" ); - equal(inp.datepicker( "option", "showOn" ), "button", "Change instance showOn" ); - inp.datepicker( "option", "showOn", undefined); - equal(inp.datepicker( "option", "showOn" ), "focus", "Reset instance showOn" ); - deepEqual(inp.datepicker( "option", "all" ), {showAnim: ""}, "Get instance settings" ); - deepEqual(inp.datepicker( "option", "defaults" ), $.datepicker._defaults, - "Get default settings" ); -}); - +// TODO: Rewrite test( "disabled", function() { expect(8); var inp = TestHelpers.datepicker.init( "#inp" ); @@ -215,196 +174,7 @@ test( "disabled", function() { ok(inp[0].disabled, "Field initially disabled" ); }); -test( "change", function() { - expect( 12 ); - var inp = TestHelpers.datepicker.init( "#inp" ), - inst = $.data(inp[0], TestHelpers.datepicker.PROP_NAME); - equal(inst.settings.showOn, null, "Initial setting showOn" ); - equal($.datepicker._get(inst, "showOn" ), "focus", "Initial instance showOn" ); - equal($.datepicker._defaults.showOn, "focus", "Initial default showOn" ); - inp.datepicker( "change", "showOn", "button" ); - equal(inst.settings.showOn, "button", "Change setting showOn" ); - equal($.datepicker._get(inst, "showOn" ), "button", "Change instance showOn" ); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - inp.datepicker( "change", {showOn: "both"}); - equal(inst.settings.showOn, "both", "Change setting showOn" ); - equal($.datepicker._get(inst, "showOn" ), "both", "Change instance showOn" ); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - inp.datepicker( "change", "showOn", undefined); - equal(inst.settings.showOn, null, "Clear setting showOn" ); - equal($.datepicker._get(inst, "showOn" ), "focus", "Restore instance showOn" ); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn" ); -}); - -(function() { - var url = window.location.search; - url = decodeURIComponent( url.slice( url.indexOf( "swarmURL=" ) + 9 ) ); - - // TODO: This test occassionally fails in IE in TestSwarm - if ( $.ui.ie && url && url.indexOf( "http" ) === 0 ) { - return; - } - - asyncTest( "invocation", function() { - var button, image, - isOldIE = $.ui.ie && ( !document.documentMode || document.documentMode < 9 ), - body = $( "body" ); - - expect( isOldIE ? 25 : 29 ); - - function step0() { - var inp = TestHelpers.datepicker.initNewInput(), - dp = $( "#ui-datepicker-div" ); - - button = inp.siblings( "button" ); - ok( button.length === 0, "Focus - button absent" ); - image = inp.siblings( "img" ); - ok( image.length === 0, "Focus - image absent" ); - - TestHelpers.datepicker.onFocus( inp, function() { - ok( dp.is( ":visible" ), "Focus - rendered on focus" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - ok( !dp.is( ":visible" ), "Focus - hidden on exit" ); - step1(); - }); - } - - function step1() { - - var inp = TestHelpers.datepicker.initNewInput(), - dp = $( "#ui-datepicker-div" ); - - TestHelpers.datepicker.onFocus( inp, function() { - ok( dp.is( ":visible" ), "Focus - rendered on focus" ); - body.simulate( "mousedown", {} ); - ok( !dp.is( ":visible" ), "Focus - hidden on external click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - step2(); - }); - } - - function step2() { - var inp = TestHelpers.datepicker.initNewInput({ - showOn: "button", - buttonText: "Popup" - }), - dp = $( "#ui-datepicker-div" ); - - ok( !dp.is( ":visible" ), "Button - initially hidden" ); - button = inp.siblings( "button" ); - image = inp.siblings( "img" ); - ok( button.length === 1, "Button - button present" ); - ok( image.length === 0, "Button - image absent" ); - equal( button.text(), "Popup", "Button - button text" ); - - TestHelpers.datepicker.onFocus( inp, function() { - ok( !dp.is( ":visible" ), "Button - not rendered on focus" ); - button.click(); - ok( dp.is( ":visible" ), "Button - rendered on button click" ); - button.click(); - ok( !dp.is( ":visible" ), "Button - hidden on second button click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - step3(); - }); - } - - function step3() { - var inp = TestHelpers.datepicker.initNewInput({ - showOn: "button", - buttonImageOnly: true, - buttonImage: "images/calendar.gif", - buttonText: "Cal" - }), - dp = $( "#ui-datepicker-div" ); - - ok( !dp.is( ":visible" ), "Image button - initially hidden" ); - button = inp.siblings( "button" ); - ok( button.length === 0, "Image button - button absent" ); - image = inp.siblings( "img" ); - ok( image.length === 1, "Image button - image present" ); - ok( /images\/calendar\.gif$/.test( image.attr( "src" ) ), "Image button - image source" ); - equal( image.attr( "title" ), "Cal", "Image button - image text" ); - - TestHelpers.datepicker.onFocus( inp, function() { - ok( !dp.is( ":visible" ), "Image button - not rendered on focus" ); - image.click(); - ok( dp.is( ":visible" ), "Image button - rendered on image click" ); - image.click(); - ok( !dp.is( ":visible" ), "Image button - hidden on second image click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - step4(); - }); - } - - function step4() { - var inp = TestHelpers.datepicker.initNewInput({ - showOn: "both", - buttonImage: "images/calendar.gif" - }), - dp = $( "#ui-datepicker-div" ); - - ok( !dp.is( ":visible" ), "Both - initially hidden" ); - button = inp.siblings( "button" ); - ok( button.length === 1, "Both - button present" ); - image = inp.siblings( "img" ); - ok( image.length === 0, "Both - image absent" ); - image = button.children( "img" ); - ok( image.length === 1, "Both - button image present" ); - - // TODO: This test occasionally fails to focus in IE8 in BrowserStack - if ( !isOldIE ) { - TestHelpers.datepicker.onFocus( inp, function() { - ok( dp.is( ":visible" ), "Both - rendered on focus" ); - body.simulate( "mousedown", {} ); - ok( !dp.is( ":visible" ), "Both - hidden on external click" ); - button.click(); - ok( dp.is( ":visible" ), "Both - rendered on button click" ); - button.click(); - ok( !dp.is( ":visible" ), "Both - hidden on second button click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - start(); - }); - } else { - start(); - } - } - - step0(); - }); -})(); - -test( "otherMonths", function() { - expect( 8 ); - var inp = TestHelpers.datepicker.init( "#inp" ), - pop = $( "#ui-datepicker-div" ); - inp.val( "06/01/2009" ).datepicker( "show" ); - equal(pop.find( "tbody" ).text(), - // support: IE <9, jQuery <1.8 - // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways - $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), - "Other months - none" ); - ok(pop.find( "td:last *" ).length === 0, "Other months - no content" ); - inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", true).datepicker( "show" ); - equal(pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", - "Other months - show" ); - ok(pop.find( "td:last span" ).length === 1, "Other months - span content" ); - inp.datepicker( "hide" ).datepicker( "option", "selectOtherMonths", true).datepicker( "show" ); - equal(pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", - "Other months - select" ); - ok(pop.find( "td:last a" ).length === 1, "Other months - link content" ); - inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", false).datepicker( "show" ); - equal(pop.find( "tbody" ).text(), - // support: IE <9, jQuery <1.8 - // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways - $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), - "Other months - none" ); - ok(pop.find( "td:last *" ).length === 0, "Other months - no content" ); -}); - +// TODO: Rewrite for value option test( "defaultDate", function() { expect( 16 ); var inp = TestHelpers.datepicker.init( "#inp" ), @@ -501,68 +271,7 @@ test( "defaultDate", function() { TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date 01/26/2007" ); }); -test( "miscellaneous", function() { - expect( 19 ); - var curYear, longNames, shortNames, date, - dp = $( "#ui-datepicker-div" ), - inp = TestHelpers.datepicker.init( "#inp" ); - // Year range - function genRange(start, offset) { - var i = start, - range = ""; - for (; i < start + offset; i++) { - range += i; - } - return range; - } - curYear = new Date().getFullYear(); - inp.val( "02/04/2008" ).datepicker( "show" ); - equal(dp.find( ".ui-calendar-year" ).text(), "2008", "Year range - read-only default" ); - inp.datepicker( "hide" ).datepicker( "option", {changeYear: true}).datepicker( "show" ); - equal(dp.find( ".ui-calendar-year" ).text(), genRange(2008 - 10, 21), "Year range - changeable default" ); - inp.datepicker( "hide" ).datepicker( "option", {yearRange: "c-6:c+2", changeYear: true}).datepicker( "show" ); - equal(dp.find( ".ui-calendar-year" ).text(), genRange(2008 - 6, 9), "Year range - c-6:c+2" ); - inp.datepicker( "hide" ).datepicker( "option", {yearRange: "2000:2010", changeYear: true}).datepicker( "show" ); - equal(dp.find( ".ui-calendar-year" ).text(), genRange(2000, 11), "Year range - 2000:2010" ); - inp.datepicker( "hide" ).datepicker( "option", {yearRange: "-5:+3", changeYear: true}).datepicker( "show" ); - equal(dp.find( ".ui-calendar-year" ).text(), genRange(curYear - 5, 9), "Year range - -5:+3" ); - inp.datepicker( "hide" ).datepicker( "option", {yearRange: "2000:-5", changeYear: true}).datepicker( "show" ); - equal(dp.find( ".ui-calendar-year" ).text(), genRange(2000, curYear - 2004), "Year range - 2000:-5" ); - inp.datepicker( "hide" ).datepicker( "option", {yearRange: "", changeYear: true}).datepicker( "show" ); - equal(dp.find( ".ui-calendar-year" ).text(), genRange(curYear, 1), "Year range - -6:+2" ); - - // Navigation as date format - inp.datepicker( "option", {showButtonPanel: true}); - equal(dp.find( ".ui-calendar-prev" ).text(), "Prev", "Navigation prev - default" ); - equal(dp.find( ".ui-calendar-current" ).text(), "Today", "Navigation current - default" ); - equal(dp.find( ".ui-calendar-next" ).text(), "Next", "Navigation next - default" ); - inp.datepicker( "hide" ).datepicker( "option", {navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >"}). - val( "02/04/2008" ).datepicker( "show" ); - longNames = $.datepicker.regional[""].monthNames; - shortNames = $.datepicker.regional[""].monthNamesShort; - date = new Date(); - equal(dp.find( ".ui-calendar-prev" ).text(), "< " + shortNames[0], "Navigation prev - as date format" ); - equal(dp.find( ".ui-calendar-current" ).text(), - longNames[date.getMonth()], "Navigation current - as date format" ); - equal(dp.find( ".ui-calendar-next" ).text(), - shortNames[2] + " >", "Navigation next - as date format" ); - inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); - equal(dp.find( ".ui-calendar-prev" ).text(), - "< " + shortNames[1], "Navigation prev - as date format + pgdn" ); - equal(dp.find( ".ui-calendar-current" ).text(), - longNames[date.getMonth()], "Navigation current - as date format + pgdn" ); - equal(dp.find( ".ui-calendar-next" ).text(), - shortNames[3] + " >", "Navigation next - as date format + pgdn" ); - inp.datepicker( "hide" ).datepicker( "option", {gotoCurrent: true}). - val( "02/04/2008" ).datepicker( "show" ); - equal(dp.find( ".ui-calendar-prev" ).text(), - "< " + shortNames[0], "Navigation prev - as date format + goto current" ); - equal(dp.find( ".ui-calendar-current" ).text(), - longNames[1], "Navigation current - as date format + goto current" ); - equal(dp.find( ".ui-calendar-next" ).text(), - shortNames[2] + " >", "Navigation next - as date format + goto current" ); -}); - +// TODO: Rewrite test( "minMax", function() { expect( 23 ); var date, @@ -670,6 +379,7 @@ test( "minMax", function() { ok(!dp.find( ".ui-calendar-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - prev button enabled" ); }); +// TODO: Rewrite for valueAsDate / value test( "setDate", function() { expect( 24 ); var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, @@ -732,83 +442,7 @@ test( "setDate", function() { equal(dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate" ); }); -test( "altField", function() { - expect( 10 ); - var inp = TestHelpers.datepicker.init( "#inp" ), - alt = $( "#alt" ); - // No alternate field set - alt.val( "" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(inp.val(), "06/04/2008", "Alt field - dp - enter" ); - equal(alt.val(), "", "Alt field - alt not set" ); - // Alternate field set - alt.val( "" ); - inp.datepicker( "option", {altField: "#alt", altFormat: "yy-mm-dd"}). - val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(inp.val(), "06/04/2008", "Alt field - dp - enter" ); - equal(alt.val(), "2008-06-04", "Alt field - alt - enter" ); - // Move from initial date - alt.val( "" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(inp.val(), "07/04/2008", "Alt field - dp - pgdn" ); - equal(alt.val(), "2008-07-04", "Alt field - alt - pgdn" ); - // Alternate field set - closed - alt.val( "" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc" ); - equal(alt.val(), "", "Alt field - alt - pgdn/esc" ); - // Clear date and alternate - alt.val( "" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); - equal(inp.val(), "", "Alt field - dp - ctrl+end" ); - equal(alt.val(), "", "Alt field - alt - ctrl+end" ); -}); - -test( "autoSize", function() { - expect( 15 ); - var inp = TestHelpers.datepicker.init( "#inp" ); - equal(inp.prop( "size" ), 20, "Auto size - default" ); - inp.datepicker( "option", "autoSize", true); - equal(inp.prop( "size" ), 10, "Auto size - mm/dd/yy" ); - inp.datepicker( "option", "dateFormat", "m/d/yy" ); - equal(inp.prop( "size" ), 10, "Auto size - m/d/yy" ); - inp.datepicker( "option", "dateFormat", "D M d yy" ); - equal(inp.prop( "size" ), 15, "Auto size - D M d yy" ); - inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); - equal(inp.prop( "size" ), 29, "Auto size - DD, MM dd, yy" ); - - // French - inp.datepicker( "option", $.extend({autoSize: false}, $.datepicker.regional.fr)); - equal(inp.prop( "size" ), 29, "Auto size - fr - default" ); - inp.datepicker( "option", "autoSize", true); - equal(inp.prop( "size" ), 10, "Auto size - fr - dd/mm/yy" ); - inp.datepicker( "option", "dateFormat", "m/d/yy" ); - equal(inp.prop( "size" ), 10, "Auto size - fr - m/d/yy" ); - inp.datepicker( "option", "dateFormat", "D M d yy" ); - equal(inp.prop( "size" ), 18, "Auto size - fr - D M d yy" ); - inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); - equal(inp.prop( "size" ), 28, "Auto size - fr - DD, MM dd, yy" ); - - // Hebrew - inp.datepicker( "option", $.extend({autoSize: false}, $.datepicker.regional.he)); - equal(inp.prop( "size" ), 28, "Auto size - he - default" ); - inp.datepicker( "option", "autoSize", true); - equal(inp.prop( "size" ), 10, "Auto size - he - dd/mm/yy" ); - inp.datepicker( "option", "dateFormat", "m/d/yy" ); - equal(inp.prop( "size" ), 10, "Auto size - he - m/d/yy" ); - inp.datepicker( "option", "dateFormat", "D M d yy" ); - equal(inp.prop( "size" ), 16, "Auto size - he - D M d yy" ); - inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); - equal(inp.prop( "size" ), 23, "Auto size - he - DD, MM dd, yy" ); -}); - +// TODO: Move this to $.date, Globalize or calendar widget test( "daylightSaving", function() { expect( 25 ); var inp = TestHelpers.datepicker.init( "#inp" ), @@ -892,73 +526,7 @@ test( "daylightSaving", function() { equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" ); }); -var beforeShowThis = null, - beforeShowInput = null, - beforeShowInst = null, - beforeShowDayThis = null, - beforeShowDayOK = true; - - -function beforeAll(input, inst) { - beforeShowThis = this; - beforeShowInput = input; - beforeShowInst = inst; - return {currentText: "Current"}; -} - -function beforeDay(date) { - beforeShowDayThis = this; - beforeShowDayOK &= (date > new Date(2008, 1 - 1, 26) && - date < new Date(2008, 3 - 1, 6)); - return [(date.getDate() % 2 === 0), (date.getDate() % 10 === 0 ? "day10" : "" ), - (date.getDate() % 3 === 0 ? "Divisble by 3" : "" )]; -} - -test( "callbacks", function() { - expect( 13 ); - // Before show - var dp, day20, day21, - inp = TestHelpers.datepicker.init( "#inp", {beforeShow: beforeAll}), - inst = $.data(inp[0], "datepicker" ); - equal($.datepicker._get(inst, "currentText" ), "Today", "Before show - initial" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - equal($.datepicker._get(inst, "currentText" ), "Current", "Before show - changed" ); - ok(beforeShowThis.id === inp[0].id, "Before show - this OK" ); - ok(beforeShowInput.id === inp[0].id, "Before show - input OK" ); - deepEqual(beforeShowInst, inst, "Before show - inst OK" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - // Before show day - inp = TestHelpers.datepicker.init( "#inp", {beforeShowDay: beforeDay}); - dp = $( "#ui-datepicker-div" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - ok(beforeShowDayThis.id === inp[0].id, "Before show day - this OK" ); - ok(beforeShowDayOK, "Before show day - dates OK" ); - day20 = dp.find( ".ui-calendar-calendar td:contains('20')" ); - day21 = dp.find( ".ui-calendar-calendar td:contains('21')" ); - ok(!day20.is( ".ui-calendar-unselectable" ), "Before show day - unselectable 20" ); - ok(day21.is( ".ui-calendar-unselectable" ), "Before show day - unselectable 21" ); - ok(day20.is( ".day10" ), "Before show day - CSS 20" ); - ok(!day21.is( ".day10" ), "Before show day - CSS 21" ); - ok(!day20.attr( "title" ), "Before show day - title 20" ); - ok(day21.attr( "title" ) === "Divisble by 3", "Before show day - title 21" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); -}); - -test( "beforeShowDay - tooltips with quotes", function() { - expect( 1 ); - var inp, dp; - inp = TestHelpers.datepicker.init( "#inp", { - beforeShowDay: function() { - return [ true, "", "'" ]; - } - }); - dp = $( "#ui-datepicker-div" ); - - inp.datepicker( "show" ); - equal( dp.find( ".ui-calendar-calendar td:contains('9')" ).attr( "title" ), "'" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); -}); - +// TODO: Move to calendar. Perhaps adda calendar_external test file? test( "localisation", function() { expect( 24 ); var dp, month, day, date, @@ -989,232 +557,7 @@ test( "localisation", function() { " " + date.getFullYear(), "Localisation - formatting" ); }); -test( "noWeekends", function() { - expect( 31 ); - var i, date; - for (i = 1; i <= 31; i++) { - date = new Date(2001, 1 - 1, i); - deepEqual($.datepicker.noWeekends(date), [(i + 1) % 7 >= 2, ""], - "No weekends " + date); - } -}); - -test( "iso8601Week", function() { - expect( 12 ); - var date = new Date(2000, 12 - 1, 31); - equal($.datepicker.iso8601Week(date), 52, "ISO 8601 week " + date); - date = new Date(2001, 1 - 1, 1); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2001, 1 - 1, 7); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2001, 1 - 1, 8); - equal($.datepicker.iso8601Week(date), 2, "ISO 8601 week " + date); - date = new Date(2003, 12 - 1, 28); - equal($.datepicker.iso8601Week(date), 52, "ISO 8601 week " + date); - date = new Date(2003, 12 - 1, 29); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2004, 1 - 1, 4); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2004, 1 - 1, 5); - equal($.datepicker.iso8601Week(date), 2, "ISO 8601 week " + date); - date = new Date(2009, 12 - 1, 28); - equal($.datepicker.iso8601Week(date), 53, "ISO 8601 week " + date); - date = new Date(2010, 1 - 1, 3); - equal($.datepicker.iso8601Week(date), 53, "ISO 8601 week " + date); - date = new Date(2010, 1 - 1, 4); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2010, 1 - 1, 10); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); -}); - -test( "parseDate", function() { - expect( 26 ); - TestHelpers.datepicker.init( "#inp" ); - var currentYear, gmtDate, fr, settings, zh; - ok($.datepicker.parseDate( "d m y", "" ) == null, "Parse date empty" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "d m y", "3 2 01" ), - new Date(2001, 2 - 1, 3), "Parse date d m y" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "dd mm yy", "03 02 2001" ), - new Date(2001, 2 - 1, 3), "Parse date dd mm yy" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "d m y", "13 12 01" ), - new Date(2001, 12 - 1, 13), "Parse date d m y" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "dd mm yy", "13 12 2001" ), - new Date(2001, 12 - 1, 13), "Parse date dd mm yy" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-o", "01-34" ), - new Date(2001, 2 - 1, 3), "Parse date y-o" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "yy-oo", "2001-347" ), - new Date(2001, 12 - 1, 13), "Parse date yy-oo" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "oo yy", "348 2004" ), - new Date(2004, 12 - 1, 13), "Parse date oo yy" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "D d M y", "Sat 3 Feb 01" ), - new Date(2001, 2 - 1, 3), "Parse date D d M y" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "d MM DD yy", "3 February Saturday 2001" ), - new Date(2001, 2 - 1, 3), "Parse date dd MM DD yy" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "DD, MM d, yy", "Saturday, February 3, 2001" ), - new Date(2001, 2 - 1, 3), "Parse date DD, MM d, yy" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy", - "day 3 of February ('Saturday'), 2001" ), new Date(2001, 2 - 1, 3), - "Parse date 'day' d 'of' MM (''DD''), yy" ); - currentYear = new Date().getFullYear(); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000) + "-02-03" ), - new Date(currentYear, 2 - 1, 3), "Parse date y-m-d - default cutuff" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000 + 10) + "-02-03" ), - new Date(currentYear+10, 2 - 1, 3), "Parse date y-m-d - default cutuff" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000 + 11) + "-02-03" ), - new Date(currentYear-89, 2 - 1, 3), "Parse date y-m-d - default cutuff" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", "80-02-03", {shortYearCutoff: 80}), - new Date(2080, 2 - 1, 3), "Parse date y-m-d - cutoff 80" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", "81-02-03", {shortYearCutoff: 80}), - new Date(1981, 2 - 1, 3), "Parse date y-m-d - cutoff 80" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000 + 60) + "-02-03", {shortYearCutoff: "+60"}), - new Date(currentYear + 60, 2 - 1, 3), "Parse date y-m-d - cutoff +60" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "y-m-d", (currentYear - 2000 + 61) + "-02-03", {shortYearCutoff: "+60"}), - new Date(currentYear - 39, 2 - 1, 3), "Parse date y-m-d - cutoff +60" ); - gmtDate = new Date(2001, 2 - 1, 3); - gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "@", "981158400000" ), gmtDate, "Parse date @" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "!", "631167552000000000" ), gmtDate, "Parse date !" ); - - fr = $.datepicker.regional.fr; - settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, - monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "D d M y", "Lun. 9 Avril 01", settings), - new Date(2001, 4 - 1, 9), "Parse date D M y with settings" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "d MM DD yy", "9 Avril Lundi 2001", settings), - new Date(2001, 4 - 1, 9), "Parse date d MM DD yy with settings" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "DD, MM d, yy", "Lundi, Avril 9, 2001", settings), - new Date(2001, 4 - 1, 9), "Parse date DD, MM d, yy with settings" ); - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings), - new Date(2001, 4 - 1, 9), "Parse date 'jour' d 'de' MM (''DD''), yy with settings" ); - - zh = $.datepicker.regional["zh-CN"]; - TestHelpers.datepicker.equalsDate($.datepicker.parseDate( "yy M d", "2011 十一月 22", zh), - new Date(2011, 11 - 1, 22), "Parse date yy M d with zh-CN" ); -}); - -test( "parseDateErrors", function() { - expect( 17 ); - TestHelpers.datepicker.init( "#inp" ); - var fr, settings; - function expectError(expr, value, error) { - try { - expr(); - ok(false, "Parsed error " + value); - } - catch (e) { - equal(e, error, "Parsed error " + value); - } - } - expectError(function() { $.datepicker.parseDate(null, "Sat 2 01" ); }, - "Sat 2 01", "Invalid arguments" ); - expectError(function() { $.datepicker.parseDate( "d m y", null); }, - "null", "Invalid arguments" ); - expectError(function() { $.datepicker.parseDate( "d m y", "Sat 2 01" ); }, - "Sat 2 01 - d m y", "Missing number at position 0" ); - expectError(function() { $.datepicker.parseDate( "dd mm yy", "Sat 2 01" ); }, - "Sat 2 01 - dd mm yy", "Missing number at position 0" ); - expectError(function() { $.datepicker.parseDate( "d m y", "3 Feb 01" ); }, - "3 Feb 01 - d m y", "Missing number at position 2" ); - expectError(function() { $.datepicker.parseDate( "dd mm yy", "3 Feb 01" ); }, - "3 Feb 01 - dd mm yy", "Missing number at position 2" ); - expectError(function() { $.datepicker.parseDate( "d m y", "3 2 AD01" ); }, - "3 2 AD01 - d m y", "Missing number at position 4" ); - expectError(function() { $.datepicker.parseDate( "d m yy", "3 2 AD01" ); }, - "3 2 AD01 - dd mm yy", "Missing number at position 4" ); - expectError(function() { $.datepicker.parseDate( "y-o", "01-D01" ); }, - "2001-D01 - y-o", "Missing number at position 3" ); - expectError(function() { $.datepicker.parseDate( "yy-oo", "2001-D01" ); }, - "2001-D01 - yy-oo", "Missing number at position 5" ); - expectError(function() { $.datepicker.parseDate( "D d M y", "D7 3 Feb 01" ); }, - "D7 3 Feb 01 - D d M y", "Unknown name at position 0" ); - expectError(function() { $.datepicker.parseDate( "D d M y", "Sat 3 M2 01" ); }, - "Sat 3 M2 01 - D d M y", "Unknown name at position 6" ); - expectError(function() { $.datepicker.parseDate( "DD, MM d, yy", "Saturday- Feb 3, 2001" ); }, - "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8" ); - expectError(function() { $.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy", - "day 3 of February (\"Saturday\" ), 2001" ); }, - "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19" ); - expectError(function() { $.datepicker.parseDate( "d m y", "29 2 01" ); }, - "29 2 01 - d m y", "Invalid date" ); - fr = $.datepicker.regional.fr; - settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, - monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; - expectError(function() { $.datepicker.parseDate( "D d M y", "Mon 9 Avr 01", settings); }, - "Mon 9 Avr 01 - D d M y", "Unknown name at position 0" ); - expectError(function() { $.datepicker.parseDate( "D d M y", "Lun. 9 Apr 01", settings); }, - "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7" ); -}); - -test( "Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function() { - expect( 4 ); - var date; - try{ - date = $.datepicker.parseDate( "dd/mm/yy", "18/04/19881" ); - ok(false, "Did not properly detect an invalid date" ); - }catch(e){ - ok( "invalid date detected" ); - } - - try { - date = $.datepicker.parseDate( "dd/mm/yy", "18/04/1988 @ 2:43 pm" ); - equal(date.getDate(), 18); - equal(date.getMonth(), 3); - equal(date.getFullYear(), 1988); - } catch(e) { - ok(false, "Did not properly parse date with extra text separated by whitespace" ); - } -}); - -test( "formatDate", function() { - expect( 16 ); - TestHelpers.datepicker.init( "#inp" ); - var gmtDate, fr, settings; - equal($.datepicker.formatDate( "d m y", new Date(2001, 2 - 1, 3)), - "3 2 01", "Format date d m y" ); - equal($.datepicker.formatDate( "dd mm yy", new Date(2001, 2 - 1, 3)), - "03 02 2001", "Format date dd mm yy" ); - equal($.datepicker.formatDate( "d m y", new Date(2001, 12 - 1, 13)), - "13 12 01", "Format date d m y" ); - equal($.datepicker.formatDate( "dd mm yy", new Date(2001, 12 - 1, 13)), - "13 12 2001", "Format date dd mm yy" ); - equal($.datepicker.formatDate( "yy-o", new Date(2001, 2 - 1, 3)), - "2001-34", "Format date yy-o" ); - equal($.datepicker.formatDate( "yy-oo", new Date(2001, 2 - 1, 3)), - "2001-034", "Format date yy-oo" ); - equal($.datepicker.formatDate( "D M y", new Date(2001, 2 - 1, 3)), - "Sat Feb 01", "Format date D M y" ); - equal($.datepicker.formatDate( "DD MM yy", new Date(2001, 2 - 1, 3)), - "Saturday February 2001", "Format date DD MM yy" ); - equal($.datepicker.formatDate( "DD, MM d, yy", new Date(2001, 2 - 1, 3)), - "Saturday, February 3, 2001", "Format date DD, MM d, yy" ); - equal($.datepicker.formatDate( "'day' d 'of' MM (''DD''), yy", - new Date(2001, 2 - 1, 3)), "day 3 of February ('Saturday'), 2001", - "Format date 'day' d 'of' MM ('DD'), yy" ); - gmtDate = new Date(2001, 2 - 1, 3); - gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() ); - equal($.datepicker.formatDate( "@", gmtDate), "981158400000", "Format date @" ); - equal($.datepicker.formatDate( "!", gmtDate), "631167552000000000", "Format date !" ); - fr = $.datepicker.regional.fr; - settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, - monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; - equal($.datepicker.formatDate( "D M y", new Date(2001, 4 - 1, 9), settings), - "lun. avril 01", "Format date D M y with settings" ); - equal($.datepicker.formatDate( "DD MM yy", new Date(2001, 4 - 1, 9), settings), - "lundi avril 2001", "Format date DD MM yy with settings" ); - equal($.datepicker.formatDate( "DD, MM d, yy", new Date(2001, 4 - 1, 9), settings), - "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings" ); - equal($.datepicker.formatDate( "'jour' d 'de' MM (''DD''), yy", - new Date(2001, 4 - 1, 9), settings), "jour 9 de avril ('lundi'), 2001", - "Format date 'jour' d 'de' MM (''DD''), yy with settings" ); -}); - -// TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos -// test( "Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ -// expect( 1 ); -// var time = $.datepicker.formatDate( "oo", new Date( "2010/03/30 12:00:00 CDT" )); -// equal(time, "089" ); -// }); - +// TODO: Rewrite this for beforeOpen test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function() { expect( 3 ); From 3c2917eab97a0417b101d54c2a5e5c382679fedc Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 16 Jun 2014 20:56:02 +0200 Subject: [PATCH 111/172] Datepicker tests: Rewrite unit test for beforeOpen event (#7602) --- tests/unit/datepicker/datepicker_options.js | 42 ++++++++++----------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 117a60f0de8..b26c39bebde 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -557,42 +557,38 @@ test( "localisation", function() { " " + date.getFullYear(), "Localisation - formatting" ); }); -// TODO: Rewrite this for beforeOpen -test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function() { + */ + +test( "Ticket 7602: Stop datepicker from appearing with beforeOpen event handler", function() { expect( 3 ); - var inp, dp; + var input; - inp = TestHelpers.datepicker.init( "#inp", { - beforeShow: function() { + input = TestHelpers.datepicker.init( "#datepicker", { + beforeOpen: function() { } }); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - equal( dp.css( "display" ), "block", "beforeShow returns nothing" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + input.datepicker( "open" ); + equal( input.datepicker( "widget" ).css( "display" ), "block", "beforeOpen returns nothing" ); + input.datepicker( "close" ).datepicker( "destroy" ); - inp = TestHelpers.datepicker.init( "#inp", { - beforeShow: function() { + input = TestHelpers.datepicker.init( "#datepicker", { + beforeOpen: function() { return true; } }); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - equal( dp.css( "display" ), "block", "beforeShow returns true" ); - inp.datepicker( "hide" ); - inp.datepicker( "destroy" ); + input.datepicker( "open" ); + equal( input.datepicker( "widget" ).css( "display" ), "block", "beforeOpen returns true" ); + input.datepicker( "close" ).datepicker( "destroy" ); - inp = TestHelpers.datepicker.init( "#inp", { - beforeShow: function() { + input = TestHelpers.datepicker.init( "#datepicker", { + beforeOpen: function() { return false; } }); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - equal( dp.css( "display" ), "none", "beforeShow returns false" ); - inp.datepicker( "destroy" ); + input.datepicker( "open" ); + equal( input.datepicker( "widget" ).css( "display" ), "none", "beforeOpen returns false" ); + input.datepicker( "destroy" ); }); -*/ })(jQuery); From c4ff049e6d3265c027d68b22911bb8d196cc68ce Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 16 Jun 2014 21:44:36 +0200 Subject: [PATCH 112/172] Datepicker tests: Re-enable some min / max option unit tests --- tests/unit/datepicker/datepicker_options.js | 154 +++++++++++--------- 1 file changed, 87 insertions(+), 67 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index b26c39bebde..b7f279839d6 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -97,6 +97,7 @@ test( "eachDay", function() { }); test( "numberOfMonths", function() { + // TODO implement this expect( 0 ); }); @@ -270,115 +271,134 @@ test( "defaultDate", function() { simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, "Default date 01/26/2007" ); }); +*/ -// TODO: Rewrite -test( "minMax", function() { - expect( 23 ); +test( "min / max", function() { + expect( 7 ); + + /* + // TODO CTRL + PgUp / PgDn is not implemented yet, see wiki var date, - inp = TestHelpers.datepicker.init( "#inp" ), - dp = $( "#ui-datepicker-div" ), - lastYear = new Date(2007, 6 - 1, 4), - nextYear = new Date(2009, 6 - 1, 4), - minDate = new Date(2008, 2 - 1, 29), - maxDate = new Date(2008, 12 - 1, 7); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), lastYear, - "Min/max - null, null - ctrl+pgup" ); - inp.val( "06/04/2008" ).datepicker( "show" ); + inp = TestHelpers.datepicker.init( "#datepicker" ), + dp = inp.datepicker( "widget" ), + lastYear = new Date( 2007, 6 - 1, 4 ), + nextYear = new Date( 2009, 6 - 1, 4 ), + minDate = new Date( 2008, 2 - 1, 29 ), + maxDate = new Date( 2008, 12 - 1, 7 ); + + inp.val( "06/04/2008" ).datepicker( "refresh" ).datepicker( "open" ); + inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). + simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), lastYear, "Min/max - null, null - ctrl+pgup" ); + + inp.val( "06/04/2008" ).datepicker( "refresh" ).datepicker( "open" ); + inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). + simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), nextYear, "Min/max - null, null - ctrl+pgdn" ); + + inp.datepicker( "option", { min: minDate } ). + datepicker( "close" ).val( "06/04/2008" ).datepicker( "refresh" ).datepicker( "open" ); + inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). + simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), minDate, "Min/max - 02/29/2008, null - ctrl+pgup" ); + + inp.val( "06/04/2008" ).datepicker( "refresh" ).datepicker( "open" ); inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), nextYear, - "Min/max - null, null - ctrl+pgdn" ); - inp.datepicker( "option", {minDate: minDate}). - datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, - "Min/max - 02/29/2008, null - ctrl+pgup" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), nextYear, - "Min/max - 02/29/2008, null - ctrl+pgdn" ); - inp.datepicker( "option", {maxDate: maxDate}). - datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, - "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup" ); - inp.val( "06/04/2008" ).datepicker( "show" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), nextYear, "Min/max - 02/29/2008, null - ctrl+pgdn" ); + + inp.datepicker( "option", { max: maxDate } ). + datepicker( "hide" ).val( "06/04/2008" ).datepicker( "open" ); + inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). + simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup" ); + + inp.val( "06/04/2008" ).datepicker( "open" ); inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, - "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "valueAsDate" ), maxDate, "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn" ); + inp.datepicker( "option", {minDate: null}). - datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); + datepicker( "hide" ).val( "06/04/2008" ).datepicker( "open" ); inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), lastYear, - "Min/max - null, 12/07/2008 - ctrl+pgup" ); - inp.val( "06/04/2008" ).datepicker( "show" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "valueAsDate" ), lastYear, "Min/max - null, 12/07/2008 - ctrl+pgup" ); + + inp.val( "06/04/2008" ).datepicker( "open" ); inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, - "Min/max - null, 12/07/2008 - ctrl+pgdn" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "valueAsDate" ), maxDate, "Min/max - null, 12/07/2008 - ctrl+pgdn" ); + // Relative dates date = new Date(); date.setDate(date.getDate() - 7); inp.datepicker( "option", {minDate: "-1w", maxDate: "+1 M +10 D "}). - datepicker( "hide" ).val( "" ).datepicker( "show" ); + datepicker( "hide" ).val( "" ).datepicker( "open" ); inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, - "Min/max - -1w, +1 M +10 D - ctrl+pgup" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "valueAsDate" ), date, "Min/max - -1w, +1 M +10 D - ctrl+pgup" ); + date = TestHelpers.datepicker.addMonths(new Date(), 1); date.setDate(date.getDate() + 10); inp.val( "" ).datepicker( "show" ); inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date, - "Min/max - -1w, +1 M +10 D - ctrl+pgdn" ); + TestHelpers.datepicker.equalsDate(inp.datepicker( "valueAsDate" ), date, "Min/max - -1w, +1 M +10 D - ctrl+pgdn" ); + */ + // With existing date - inp = TestHelpers.datepicker.init( "#inp" ); - inp.val( "06/04/2008" ).datepicker( "option", {minDate: minDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), new Date(2008, 6 - 1, 4), "Min/max - setDate > min" ); - inp.datepicker( "option", {minDate: null}).val( "01/04/2008" ).datepicker( "option", {minDate: minDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" ); - inp.datepicker( "option", {minDate: null}).val( "06/04/2008" ).datepicker( "option", {maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), new Date(2008, 6 - 1, 4), "Min/max - setDate < max" ); - inp.datepicker( "option", {maxDate: null}).val( "01/04/2009" ).datepicker( "option", {maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" ); - inp.datepicker( "option", {maxDate: null}).val( "01/04/2008" ).datepicker( "option", {minDate: minDate, maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" ); - inp.datepicker( "option", {maxDate: null}).val( "06/04/2008" ).datepicker( "option", {minDate: minDate, maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), new Date(2008, 6 - 1, 4), "Min/max - setDate > min, < max" ); - inp.datepicker( "option", {maxDate: null}).val( "01/04/2009" ).datepicker( "option", {minDate: minDate, maxDate: maxDate}); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" ); + var inp = TestHelpers.datepicker.init( "#datepicker" ), + minDate = new Date( 2008, 2 - 1, 29 ), + maxDate = new Date( 2008, 12 - 1, 7 ); + + inp.val( "6/4/08" ).datepicker( "option", { min: minDate } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min" ); + + inp.datepicker( "option", { min: null } ).val( "1/4/08" ).datepicker( "option", { min: minDate } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), minDate, "Min/max - value < min" ); + inp.datepicker( "option", { min: null } ).val( "6/4/08" ).datepicker( "option", { max: maxDate } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < max" ); + + inp.datepicker( "option", { max: null } ).val( "1/4/09" ).datepicker( "option", { max: maxDate } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), maxDate, "Min/max - setDate > max" ); + + inp.datepicker( "option", { max: null } ).val( "1/4/08" ).datepicker( "option", { min: minDate, max: maxDate } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), minDate, "Min/max - value < min" ); + + inp.datepicker( "option", { max: null } ).val( "6/4/08" ).datepicker( "option", { min: minDate, max: maxDate } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min, < max" ); + + inp.datepicker( "option", { max: null } ).val( "1/4/09" ).datepicker( "option", { min: minDate, max: maxDate } ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), maxDate, "Min/max - value > max" ); + + /* + // TODO: enable when yearRange option is implemented inp.datepicker( "option", {yearRange: "-0:+1"}).val( "01/01/" + new Date().getFullYear()); ok(dp.find( ".ui-calendar-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - previous button disabled at 1/1/minYear" ); inp.datepicker( "setDate", "12/30/" + new Date().getFullYear()); ok(dp.find( ".ui-calendar-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled at 12/30/maxYear" ); inp.datepicker( "option", { - minDate: new Date(1900, 0, 1), - maxDate: "-6Y", + min: new Date(1900, 0, 1), + max: "-6Y", yearRange: "1900:-6" }).val( "" ); ok(dp.find( ".ui-calendar-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled" ); ok(!dp.find( ".ui-calendar-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - prev button enabled" ); inp.datepicker( "option", { - minDate: new Date(1900, 0, 1), - maxDate: "1/25/2007", + min: new Date(1900, 0, 1), + max: "1/25/2007", yearRange: "1900:2007" }).val( "" ); ok(dp.find( ".ui-calendar-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled" ); ok(!dp.find( ".ui-calendar-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - prev button enabled" ); + */ }); +/* + // TODO: Rewrite for valueAsDate / value test( "setDate", function() { expect( 24 ); From 1131bce5e1240be797e427b4b0bc8a83c617531d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 16 Jun 2014 21:49:45 +0200 Subject: [PATCH 113/172] Datepicker tests: Adjust min / max option unit tests to specification Datepicker should return input value even if invalid regarding min and max option. Test for correct min / max setting by using isValid method. --- tests/unit/datepicker/datepicker_options.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index b7f279839d6..9817fe9b190 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -274,7 +274,7 @@ test( "defaultDate", function() { */ test( "min / max", function() { - expect( 7 ); + expect( 14 ); /* // TODO CTRL + PgUp / PgDn is not implemented yet, see wiki @@ -353,24 +353,31 @@ test( "min / max", function() { inp.val( "6/4/08" ).datepicker( "option", { min: minDate } ); TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min" ); + ok( inp.datepicker( "isValid" ) ); inp.datepicker( "option", { min: null } ).val( "1/4/08" ).datepicker( "option", { min: minDate } ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), minDate, "Min/max - value < min" ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 4 ), "Min/max - value < min" ); + ok( !inp.datepicker( "isValid" ) ); inp.datepicker( "option", { min: null } ).val( "6/4/08" ).datepicker( "option", { max: maxDate } ); TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < max" ); + ok( inp.datepicker( "isValid" ) ); inp.datepicker( "option", { max: null } ).val( "1/4/09" ).datepicker( "option", { max: maxDate } ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), maxDate, "Min/max - setDate > max" ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2009, 1 - 1, 4 ), "Min/max - setDate > max" ); + ok( !inp.datepicker( "isValid" ) ); inp.datepicker( "option", { max: null } ).val( "1/4/08" ).datepicker( "option", { min: minDate, max: maxDate } ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), minDate, "Min/max - value < min" ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 4 ), "Min/max - value < min" ); + ok( !inp.datepicker( "isValid" ) ); inp.datepicker( "option", { max: null } ).val( "6/4/08" ).datepicker( "option", { min: minDate, max: maxDate } ); TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min, < max" ); + ok( inp.datepicker( "isValid" ) ); inp.datepicker( "option", { max: null } ).val( "1/4/09" ).datepicker( "option", { min: minDate, max: maxDate } ); - TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), maxDate, "Min/max - value > max" ); + TestHelpers.datepicker.equalsDate( inp.datepicker( "valueAsDate" ), new Date( 2009, 1 - 1, 4 ), "Min/max - value > max" ); + ok( !inp.datepicker( "isValid" ) ); /* // TODO: enable when yearRange option is implemented From 66ba886c8796975ff6730429e947a8fdbbe42b57 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 16 Jun 2014 22:02:08 +0200 Subject: [PATCH 114/172] Datepicker tests: clean up method tests --- tests/unit/datepicker/datepicker_methods.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index c2a766a3379..d65b5cbf56a 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -40,12 +40,12 @@ test( "widget", function() { }); test( "close", function() { - // ToDo implement this + // TODO: implement this expect( 0 ); }); test( "open", function() { - // ToDo implement this + // TODO: implement this expect( 0 ); }); @@ -57,13 +57,11 @@ test( "value", function() { input.datepicker( "value", "1/1/14" ); equal( input.val(), "1/1/14", "input's value set" ); input.datepicker( "open" ); - ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), - "first day marked as selected" ); + ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "first day marked as selected" ); equal( input.datepicker( "value" ), "1/1/14", "getter" ); input.val( "abc" ); - equal( input.datepicker( "value" ), null, - "Invalid values should be returned without formatting." ); + equal( input.datepicker( "value" ), null, "Invalid values should return null." ); }); test( "valueAsDate", function() { @@ -73,10 +71,8 @@ test( "valueAsDate", function() { input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); equal( input.val(), "1/1/14", "input's value set" ); - ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), - "first day marked as selected" ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), - new Date( 2014, 0, 1 ), "getter" ); + ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "first day marked as selected" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "getter" ); input.val( "a/b/c" ); equal( input.datepicker( "valueAsDate" ), null, "Invalid dates return null" ); From 0d3cd04a22d184150b1dbe6757cfb2026c831b96 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 16 Jun 2014 22:11:50 +0200 Subject: [PATCH 115/172] Calendar: Add version property --- ui/calendar.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/calendar.js b/ui/calendar.js index fd7730d2e6b..7ff2b63acc5 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -27,6 +27,7 @@ }(function( $ ) { return $.widget( "ui.calendar", { + version: "@VERSION", options: { dateFormat: { date: "short" }, // TODO review From 8531690555045a81b01e25d8008ef6677294036b Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 16 Jun 2014 22:12:07 +0200 Subject: [PATCH 116/172] Datepicker: Add version property --- ui/datepicker.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/datepicker.js b/ui/datepicker.js index 501f9254a56..a3dfd7e55d3 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -32,6 +32,7 @@ var widget, suppressExpandOnFocus = false; widget = $.widget( "ui.datepicker", { + version: "@VERSION", options: { appendTo: null, position: { From f338f59272dc01fcf69e3096f59973398f7d91ee Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 16 Jun 2014 22:12:27 +0200 Subject: [PATCH 117/172] Datepicker tests: Add common unit tests --- tests/unit/datepicker/datepicker_common.js | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/unit/datepicker/datepicker_common.js b/tests/unit/datepicker/datepicker_common.js index 1eecc85cb50..4a2ece05da8 100644 --- a/tests/unit/datepicker/datepicker_common.js +++ b/tests/unit/datepicker/datepicker_common.js @@ -1,7 +1,25 @@ -/* TestHelpers.commonWidgetTests( "datepicker", { defaults: { - disabled: false + appendTo: null, + dateFormat: { date: "short" }, + disabled: false, + eachDay: $.noop, + max: null, + min: null, + numberOfMonths: 1, + position: { + my: "left top", + at: "left bottom" + }, + showWeek: false, + show: true, + hide: true, + + // callbacks + beforeOpen: null, + close: null, + create: null, + open: null, + select: null } }); -*/ From f00e7332e80149d0a3502bb666f2d59cda1ad371 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 00:20:31 +0200 Subject: [PATCH 118/172] Datepicker: code style --- ui/datepicker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index a3dfd7e55d3..1216ec0da2e 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -345,4 +345,4 @@ $.each( calendarOptions, function( index, option ) { return widget; -})); \ No newline at end of file +})); From fe57299708eeea7de885726f8a2641ebde871d44 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 00:20:42 +0200 Subject: [PATCH 119/172] Calendar: code style --- ui/calendar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/calendar.js b/ui/calendar.js index 7ff2b63acc5..6bd478a9533 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -499,4 +499,4 @@ return $.widget( "ui.calendar", { } }); -})); \ No newline at end of file +})); From dcbac008da8989b775ef0bff25dc066b4a8ef656 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 00:46:08 +0200 Subject: [PATCH 120/172] Datepicker tests: Add open and close unit tests --- tests/unit/datepicker/datepicker_methods.js | 23 ++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index d65b5cbf56a..f5236e30ce8 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -39,14 +39,23 @@ test( "widget", function() { actual.remove(); }); -test( "close", function() { - // TODO: implement this - expect( 0 ); -}); +test( "open / close", function() { + expect( 7 ); + + var input = TestHelpers.datepicker.initNewInput({ show: false, hide: false }), + calendar = input.datepicker( "widget" ); -test( "open", function() { - // TODO: implement this - expect( 0 ); + ok( calendar.is( ":hidden" ), "calendar hidden on init" ); + + input.datepicker( "open" ); + ok( calendar.is( ":visible" ), "open: calendar visible" ); + equal( calendar.attr( "aria-hidden" ), "false", "open: calendar aria-disabled" ); + equal( calendar.attr( "aria-expanded" ), "true", "close: calendar aria-expanded" ); + + input.datepicker( "close" ); + ok( !calendar.is( ":visible" ), "close: calendar hidden" ); + equal( calendar.attr( "aria-hidden" ), "true", "close: calendar aria-disabled" ); + equal( calendar.attr( "aria-expanded" ), "false", "close: calendar aria-expanded" ); }); test( "value", function() { From 95a33b58ac1b5b77022ef3e5221aa8f428ee9a3a Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 00:49:38 +0200 Subject: [PATCH 121/172] Datepicker tests: Remove unneeded disabled / enabled options Remove unneeded disabled / enabled options as tests exists for disable and enable methods. --- tests/unit/datepicker/datepicker_options.js | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 9817fe9b190..036a9c55a30 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -156,25 +156,6 @@ test( "showWeek", function() { }); /* -// TODO: Rewrite -test( "disabled", function() { - expect(8); - var inp = TestHelpers.datepicker.init( "#inp" ); - ok(!inp.datepicker( "isDisabled" ), "Initially marked as enabled" ); - ok(!inp[0].disabled, "Field initially enabled" ); - inp.datepicker( "option", "disabled", true); - ok(inp.datepicker( "isDisabled" ), "Marked as disabled" ); - ok(inp[0].disabled, "Field now disabled" ); - inp.datepicker( "option", "disabled", false); - ok(!inp.datepicker( "isDisabled" ), "Marked as enabled" ); - ok(!inp[0].disabled, "Field now enabled" ); - inp.datepicker( "destroy" ); - - inp = TestHelpers.datepicker.init( "#inp", { disabled: true }); - ok(inp.datepicker( "isDisabled" ), "Initially marked as disabled" ); - ok(inp[0].disabled, "Field initially disabled" ); -}); - // TODO: Rewrite for value option test( "defaultDate", function() { expect( 16 ); From 3daa9a72d97d03c2762dfba5f6e85e5fae2a116d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 11:27:46 +0200 Subject: [PATCH 122/172] Datepicker tests: Rewrite setDate tests as valueAsDate method tests --- tests/unit/datepicker/datepicker_methods.js | 56 +++++++++++++++-- tests/unit/datepicker/datepicker_options.js | 69 +-------------------- 2 files changed, 52 insertions(+), 73 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index f5236e30ce8..a4209740ea6 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -74,17 +74,61 @@ test( "value", function() { }); test( "valueAsDate", function() { - expect( 4 ); - var input = $( "#datepicker" ).datepicker(), - picker = input.datepicker( "widget" ); + expect( 14 ); + + var minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, + input = TestHelpers.datepicker.init( "#datepicker" ), + picker = input.datepicker( "widget" ), + date1 = new Date(2008, 6 - 1, 4), + date2 = new Date(); input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); - equal( input.val(), "1/1/14", "input's value set" ); - ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "first day marked as selected" ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "getter" ); + equal( input.val(), "1/1/14", "Input's value set" ); + ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "First day marked as selected" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" ); input.val( "a/b/c" ); equal( input.datepicker( "valueAsDate" ), null, "Invalid dates return null" ); + + input.val( "" ).datepicker( "destroy" ); + input = TestHelpers.datepicker.init( "#datepicker" ); + + ok(input.datepicker( "valueAsDate" ) == null, "Set date - default" ); + input.datepicker( "valueAsDate", date1); + TestHelpers.datepicker.equalsDate(input.datepicker( "valueAsDate" ), date1, "Set date - 2008-06-04" ); + + input.datepicker( "valueAsDate", date1, date2); + TestHelpers.datepicker.equalsDate(input.datepicker( "valueAsDate" ), date1, "Set date - two dates" ); + + // With minimum/maximum + input = TestHelpers.datepicker.init( "#datepicker" ); + date1 = new Date( 2008, 1 - 1, 4 ); + date2 = new Date( 2008, 6 - 1, 4 ); + minDate = new Date( 2008, 2 - 1, 29 ); + maxDate = new Date( 2008, 3 - 1, 28 ); + + input.val( "" ).datepicker( "option", { min: minDate } ).datepicker( "valueAsDate", date2 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date2, "Set date min/max - value > min" ); + + input.datepicker( "valueAsDate", date1 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date2, "Set date min/max - value < min" ); + + input.val( "" ).datepicker( "option", { max: maxDate, min: null } ).datepicker( "valueAsDate", date1 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date1, "Set date min/max - value < max" ); + + input.datepicker( "valueAsDate", date2 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date1, "Set date min/max - value > max" ); + + input.val( "" ).datepicker( "option", { min: minDate } ).datepicker( "valueAsDate", date1 ); + ok( input.datepicker( "valueAsDate" ) === null, "Set date min/max - value < min" ); + + input.datepicker( "valueAsDate", date2 ); + ok( input.datepicker( "valueAsDate" ) === null, "Set date min/max - value > max" ); + + dateAndTimeToSet = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); + dateAndTimeClone = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); + input.datepicker( "valueAsDate", dateAndTimeToSet ); + equal( dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by valueAsDate" ); }); test( "isValid", function() { diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 036a9c55a30..f73ee569d80 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -156,7 +156,7 @@ test( "showWeek", function() { }); /* -// TODO: Rewrite for value option +// TODO: Move to calendar and rewrite for value option test( "defaultDate", function() { expect( 16 ); var inp = TestHelpers.datepicker.init( "#inp" ), @@ -386,70 +386,6 @@ test( "min / max", function() { }); /* - -// TODO: Rewrite for valueAsDate / value -test( "setDate", function() { - expect( 24 ); - var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, - inp = TestHelpers.datepicker.init( "#inp" ), - date1 = new Date(2008, 6 - 1, 4), - date2 = new Date(); - ok(inp.datepicker( "getDate" ) == null, "Set date - default" ); - inp.datepicker( "setDate", date1); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - 2008-06-04" ); - date1 = new Date(); - date1.setDate(date1.getDate() + 7); - inp.datepicker( "setDate", +7); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - +7" ); - date2.setFullYear(date2.getFullYear() + 2); - inp.datepicker( "setDate", "+2y" ); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date2, "Set date - +2y" ); - inp.datepicker( "setDate", date1, date2); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - two dates" ); - inp.datepicker( "setDate" ); - ok(inp.datepicker( "getDate" ) == null, "Set date - null" ); - // Relative to current date - date1 = new Date(); - date1.setDate(date1.getDate() + 7); - inp.datepicker( "setDate", "c +7" ); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - c +7" ); - date1.setDate(date1.getDate() + 7); - inp.datepicker( "setDate", "c+7" ); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - c+7" ); - date1.setDate(date1.getDate() - 21); - inp.datepicker( "setDate", "c -3 w" ); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date - c -3 w" ); - // Alternate field - alt = $( "#alt" ); - inp.datepicker( "option", {altField: "#alt", altFormat: "yy-mm-dd"}); - date1 = new Date(2008, 6 - 1, 4); - inp.datepicker( "setDate", date1); - equal(inp.val(), "06/04/2008", "Set date alternate - 06/04/2008" ); - equal(alt.val(), "2008-06-04", "Set date alternate - 2008-06-04" ); - // With minimum/maximum - inp = TestHelpers.datepicker.init( "#inp" ); - date1 = new Date(2008, 1 - 1, 4); - date2 = new Date(2008, 6 - 1, 4); - minDate = new Date(2008, 2 - 1, 29); - maxDate = new Date(2008, 3 - 1, 28); - inp.val( "" ).datepicker( "option", {minDate: minDate}).datepicker( "setDate", date2); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date2, "Set date min/max - setDate > min" ); - inp.datepicker( "setDate", date1); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" ); - inp.val( "" ).datepicker( "option", {maxDate: maxDate, minDate: null}).datepicker( "setDate", date1); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), date1, "Set date min/max - setDate < max" ); - inp.datepicker( "setDate", date2); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" ); - inp.val( "" ).datepicker( "option", {minDate: minDate}).datepicker( "setDate", date1); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" ); - inp.datepicker( "setDate", date2); - TestHelpers.datepicker.equalsDate(inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" ); - dateAndTimeToSet = new Date(2008, 3 - 1, 28, 1, 11, 0); - dateAndTimeClone = new Date(2008, 3 - 1, 28, 1, 11, 0); - inp.datepicker( "setDate", dateAndTimeToSet); - equal(dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate" ); -}); - // TODO: Move this to $.date, Globalize or calendar widget test( "daylightSaving", function() { expect( 25 ); @@ -535,7 +471,7 @@ test( "daylightSaving", function() { }); // TODO: Move to calendar. Perhaps adda calendar_external test file? -test( "localisation", function() { +test( "localization", function() { expect( 24 ); var dp, month, day, date, inp = TestHelpers.datepicker.init( "#inp", $.datepicker.regional.fr); @@ -564,7 +500,6 @@ test( "localisation", function() { date.getDate() + " " + $.datepicker.regional.fr.monthNames[date.getMonth()] + " " + date.getFullYear(), "Localisation - formatting" ); }); - */ test( "Ticket 7602: Stop datepicker from appearing with beforeOpen event handler", function() { From 8cf0e8f2da9e65e4684d51e3fb67d7361cb7cca0 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 11:28:29 +0200 Subject: [PATCH 123/172] Calendar: Make it possible to set min / max option to null --- ui/calendar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/calendar.js b/ui/calendar.js index 6bd478a9533..f3cc63141ef 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -475,7 +475,7 @@ return $.widget( "ui.calendar", { } if ( key === "max" || key === "min" ) { - if ( value instanceof Date ) { + if ( value instanceof Date || value === null ) { this._super( key, value ); this.refresh(); } From a8189d90d8aa5cc775214ec8e906995266ed139d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 16:25:24 +0200 Subject: [PATCH 124/172] Datepicker: Improve document click event --- ui/datepicker.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 1216ec0da2e..519cc477d3f 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -191,8 +191,12 @@ widget = $.widget( "ui.datepicker", { }, _documentEvents: { - click: function( event ) { - if ( this.isOpen && !$( event.target ).closest( this.element.add( this.calendar ) ).length ) { + mousedown: function( event ) { + if ( !this.isOpen ) { + return; + } + + if ( !$( event.target ).closest( this.element.add( this.calendar ) ).length ) { this.close( event ); } } From 91dfe6eb8d7240f2efde77d2fc1bc354b8aadf6a Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 19:05:06 +0200 Subject: [PATCH 125/172] Calendar: Fix broken day table cell attributes --- ui/calendar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/calendar.js b/ui/calendar.js index f3cc63141ef..fc29da9027b 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -313,7 +313,7 @@ return $.widget( "ui.calendar", { var content = "", attributes = [ "role='gridcell'", - "aria-selected='" + day.current ? true : false + "'" + "aria-selected='" + ( day.current ? true : false ) + "'" ], selectable = ( day.selectable && this._isValid( new Date( day.timestamp ) ) ); From 2aacbb997981644616958197127d098534bfd155 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 19:53:08 +0200 Subject: [PATCH 126/172] Datepicker tests: Rewrite event unit tests --- tests/unit/datepicker/datepicker_events.js | 260 +++++++++--------- .../datepicker/datepicker_test_helpers.js | 6 +- 2 files changed, 129 insertions(+), 137 deletions(-) diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index 9ee254e5351..6739f843589 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -1,150 +1,144 @@ -// The implement of events is completely changing therefore these tests are no longer directly -// relevant. Leaving them around commented out so we can ensure the functionality is replicated. -// For example: -// TODO: In the old implementation the Enter key select's today's date when the has -// focus and is empty. Do we want to replicate this behavior in the rewrite? -/* - (function( $ ) { module( "datepicker: events" ); test( "beforeOpen", function() { - expect( 0 ); + expect( 3 ); + + var input = TestHelpers.datepicker.init( "#datepicker", { + beforeOpen: function() { + ok( true, "beforeOpen event fired before open" ); + ok( input.datepicker( "widget" ).is( ":hidden" ), "calendar hidden on beforeOpen" ); + }, + open: function() { + ok( input.datepicker( "widget" ).is( ":visible" ), "calendar open on open" ); + } + }); + + input + .datepicker( "open" ) + .datepicker( "close" ) + .datepicker( "option", { + beforeOpen: function() { + return false; + }, + open: function() { + ok( false, "calendar should not open when openBefore is canceled" ); + } + }) + .datepicker( "open" ); }); test( "close", function() { - expect( 0 ); + expect( 4 ); + + var shouldFire, + input = TestHelpers.datepicker.init( "#datepicker", { + close: function() { + ok( shouldFire, "close event fired" ); + } + }); + + shouldFire = false; + input.datepicker( "open" ); + shouldFire = true; + input.datepicker( "close" ); + + shouldFire = false; + input.datepicker( "open" ); + shouldFire = true; + $( "body" ).trigger( "mousedown" ); + + shouldFire = false; + input.datepicker( "open" ); + shouldFire = true; + input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + + shouldFire = false; + input.datepicker( "open" ); + shouldFire = true; + input.datepicker( "widget" ).find( "tbody tr:first td:first a" ).simulate( "mousedown" ); + }); test( "open", function() { - expect( 0 ); -}); + expect( 2 ); + + var input = TestHelpers.datepicker.init( "#datepicker", { + open: function() { + ok( true, "open event fired on open" ); + ok( widget.is( ":visible" ), "calendar open on open" ); + } + }), + widget = input.datepicker( "widget" ); -test( "select", function() { - expect( 0 ); + input.datepicker( "open" ); }); -var selectedThis = null, -selectedDate = null, -selectedInst = null; - -function callback(date, inst) { - selectedThis = this; - selectedDate = date; - selectedInst = inst; -} - -function callback2(year, month, inst) { - selectedThis = this; - selectedDate = year + "/" + month; - selectedInst = inst; -} - -test( "events", function() { - expect( 26 ); - var dateStr, newMonthYear, inp2, - inp = TestHelpers.datepicker.init( "#inp", {onSelect: callback}), - date = new Date(); - // onSelect - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(selectedThis, inp[0], "Callback selected this" ); - equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Callback selected inst" ); - equal(selectedDate, $.datepicker.formatDate( "mm/dd/yy", date), - "Callback selected date" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 7); - equal(selectedDate, $.datepicker.formatDate( "mm/dd/yy", date), - "Callback selected date - ctrl+down" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(selectedDate, $.datepicker.formatDate( "mm/dd/yy", date), - "Callback selected date - esc" ); - dateStr = "02/04/2008"; - inp.val(dateStr).datepicker( "show" ). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(dateStr, selectedDate, - "onSelect is called after enter keydown" ); - // onChangeMonthYear - inp.datepicker( "option", {onChangeMonthYear: callback2, onSelect: null}). - val( "" ).datepicker( "show" ); - newMonthYear = function(date) { - return date.getFullYear() + "/" + (date.getMonth() + 1); - }; - date = new Date(); - date.setDate(1); - inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_UP}); - date.setMonth(date.getMonth() - 1); - equal(selectedThis, inp[0], "Callback change month/year this" ); - equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Callback change month/year inst" ); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - pgup" ); - inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); - date.setMonth(date.getMonth() + 1); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - pgdn" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); - date.setFullYear(date.getFullYear() - 1); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - ctrl+pgup" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}); - date.setFullYear(date.getFullYear() + 1); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - ctrl+home" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); - date.setFullYear(date.getFullYear() + 1); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - ctrl+pgdn" ); - inp.datepicker( "setDate", new Date(2007, 1 - 1, 26)); - equal(selectedDate, "2007/1", "Callback change month/year date - setDate" ); - selectedDate = null; - inp.datepicker( "setDate", new Date(2007, 1 - 1, 12)); - ok(selectedDate == null, "Callback change month/year date - setDate no change" ); - // onChangeMonthYear step by 2 - inp.datepicker( "option", {stepMonths: 2}). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_UP}); - date.setMonth(date.getMonth() - 14); - equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - pgup" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); - date.setMonth(date.getMonth() - 12); - equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - ctrl+pgup" ); - inp.simulate( "keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); - date.setMonth(date.getMonth() + 2); - equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - pgdn" ); - inp.simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); - date.setMonth(date.getMonth() + 12); - equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - ctrl+pgdn" ); - // onClose - inp.datepicker( "option", {onClose: callback, onChangeMonthYear: null, stepMonths: 1}). - val( "" ).datepicker( "show" ). - simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(selectedThis, inp[0], "Callback close this" ); - equal(selectedInst, $.data(inp[0], TestHelpers.datepicker.PROP_NAME), "Callback close inst" ); - equal(selectedDate, "", "Callback close date - esc" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(selectedDate, $.datepicker.formatDate( "mm/dd/yy", new Date()), - "Callback close date - enter" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(selectedDate, "02/04/2008", "Callback close date - preset" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); - equal(selectedDate, "", "Callback close date - ctrl+end" ); - - inp2 = TestHelpers.datepicker.init( "#inp2" ); - inp2.datepicker().datepicker( "option", {onClose: callback}).datepicker( "show" ); - inp.datepicker( "show" ); - equal(selectedThis, inp2[0], "Callback close this" ); +asyncTest( "select", function() { + expect( 6 ); + + var input = TestHelpers.datepicker.init( "#datepicker", { + select: function( event ) { + ok( true, "select event fired " + message ); + equal( + event.originalEvent.type, + "calendarselect", + "select originalEvent " + message + ); + } + }), + widget = input.datepicker( "widget" ), + message = ""; + + function step1() { + message = "on input enter"; + input + .simulate( "focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + input.datepicker( "close" ); + step2(); + } + + function step2() { + message = "on calendar cell click"; + input + .simulate( "focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout(function() { + widget.find( "tbody tr:first td:first a" ).simulate( "mousedown" ); + input.datepicker( "close" ); + step3(); + }, 100 ); + } + + function step3() { + message = "on calendar cell enter"; + input + .simulate( "focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout(function() { + $( ":focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + input.datepicker( "close" ); + step4(); + }, 100 ); + } + + function step4() { + message = "on calendar escape (not expected)"; + input + .simulate( "focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + input.datepicker( "close" ); + start(); + }, 100 ); + } + + step1(); }); })( jQuery ); - */ diff --git a/tests/unit/datepicker/datepicker_test_helpers.js b/tests/unit/datepicker/datepicker_test_helpers.js index 1d922c72220..23f5025b48b 100644 --- a/tests/unit/datepicker/datepicker_test_helpers.js +++ b/tests/unit/datepicker/datepicker_test_helpers.js @@ -15,14 +15,12 @@ TestHelpers.datepicker = { equal( d1.toString(), d2.toString(), message ); }, init: function( id, options ) { - options = $.extend( { show: false }, options || {} ); + options = $.extend( { show: false, hide: false }, options || {} ); return $( id ).datepicker( options ); }, initNewInput: function( options ) { options = $.extend( { show: false }, options || {} ); return $( "" ).datepicker( options ) .appendTo( "#qunit-fixture" ); - }, - onFocus: TestHelpers.onFocus, - PROP_NAME: "datepicker" + } }; \ No newline at end of file From 8bf7263255d36c8bd97acc638b9f1ef57c8ef752 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 19:54:02 +0200 Subject: [PATCH 127/172] Datepicker tests: Code style improvements, add todo comment for ARIA --- tests/unit/datepicker/datepicker_core.js | 156 +++++++++++++++-------- 1 file changed, 101 insertions(+), 55 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 65a0c5c6fdc..79135278647 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -86,19 +86,21 @@ asyncTest( "baseStructure", function() { step1(); }); -test( "Keyboard handling", function() { +test( "Keyboard handling: input", function() { expect( 8 ); var input = $( "#datepicker" ).datepicker(), instance = input.datepicker( "instance" ), date = new Date(); // Enter = Select today's date by default - input.datepicker( "open" ) + input + .datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke enter" ); // Enter = Select preset date - input.val( "1/1/14" ) + input + .val( "1/1/14" ) .datepicker( "refresh" ) .datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); @@ -106,28 +108,37 @@ test( "Keyboard handling", function() { "Keystroke enter - preset" ); // Control + Home = Change the calendar to the current month - input.val( "1/1/14" ).datepicker( "open" ) + input + .val( "1/1/14" ).datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+home" ); - input.val( "" ).datepicker( "open" ); + input + .val( "" ) + .datepicker( "open" ); ok( instance.isOpen, "datepicker is open before escape" ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); ok( !instance.isOpen, "escape closes the datepicker" ); - input.val( "1/1/14" ).datepicker( "open" ) + input + .val( "1/1/14" ) + .datepicker( "open" ) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke esc - preset" ); - input.val( "1/1/14" ).datepicker( "open" ) + input + .val( "1/1/14" ) + .datepicker( "open" ) .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke esc - abandoned" ); - input.val( "1/2/14" ) + input + .val( "1/2/14" ) .simulate( "keyup" ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ), "Picker updated as user types into input" ); @@ -135,19 +146,19 @@ test( "Keyboard handling", function() { input.datepicker( "destroy" ); }); -asyncTest( "keyboard handling", function() { +asyncTest( "keyboard handling: calendar", function() { expect( 14 ); + var picker, - input = $( "#datepicker" ), - date = new Date(); + input = $( "#datepicker" ); function step1() { input.datepicker(); picker = input.datepicker( "widget" ); + ok( !picker.is( ":visible" ), "datepicker closed" ); - input.val( "" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { ok( picker.is( ":visible" ), "Keystroke down opens datepicker" ); input.datepicker( "destroy" ); @@ -158,10 +169,10 @@ asyncTest( "keyboard handling", function() { function step2() { input.datepicker(); picker = input.datepicker( "widget" ); + ok( !picker.is( ":visible" ), "datepicker closed" ); - input.val( "" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); setTimeout(function() { ok( picker.is( ":visible" ), "Keystroke up opens datepicker" ); input.datepicker( "destroy" ); @@ -170,7 +181,8 @@ asyncTest( "keyboard handling", function() { } function step3() { - input.val( "1/1/14" ) + input + .val( "1/1/14" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -178,17 +190,20 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2013, 12 - 1, 31 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke left to switch to previous day" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2013, 12 - 1, 31 ), + "Keystroke left to switch to previous day" + ); input.datepicker( "destroy" ); step4(); }, 100 ); } function step4() { - input.val( "1/1/14" ) + input + .val( "1/1/14" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -196,17 +211,20 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2014, 1 - 1, 2 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke right to switch to next day" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2014, 1 - 1, 2 ), + "Keystroke right to switch to next day" + ); input.datepicker( "destroy" ); step5(); }, 100 ); } function step5() { - input.val( "1/1/14" ) + input + .val( "1/1/14" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -214,17 +232,20 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.UP } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2013, 12 - 1, 25 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke up to move to the previous week" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2013, 12 - 1, 25 ), + "Keystroke up to move to the previous week" + ); input.datepicker( "destroy" ); step6(); }, 100 ); } function step6() { - input.val( "1/1/14" ) + input + .val( "1/1/14" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -232,17 +253,20 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2014, 1 - 1, 8 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke down to move to the next week" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2014, 1 - 1, 8 ), + "Keystroke down to move to the next week" + ); input.datepicker( "destroy" ); step7(); }, 100 ); } function step7() { - input.val( "1/1/14" ) + input + .val( "1/1/14" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -250,17 +274,20 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2013, 12 - 1, 1 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Up moves date to previous month" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2013, 12 - 1, 1 ), + "Keystroke Page Up moves date to previous month" + ); input.datepicker( "destroy" ); step8(); }, 100 ); } function step8() { - input.val( "1/1/14" ) + input + .val( "1/1/14" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -268,17 +295,20 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2013, 1 - 1, 1 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Up + Ctrl moves date to previous year" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2013, 1 - 1, 1 ), + "Keystroke Page Up + Ctrl moves date to previous year" + ); input.datepicker( "destroy" ); step9(); }, 100 ); } function step9() { - input.val( "1/1/14" ) + input + .val( "1/1/14" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -286,17 +316,20 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2014, 2 - 1, 1 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Down moves date to next month" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2014, 2 - 1, 1 ), + "Keystroke Page Down moves date to next month" + ); input.datepicker( "destroy" ); step10(); }, 100 ); } function step10() { - input.val( "1/1/14" ) + input + .val( "1/1/14" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -304,10 +337,12 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2015, 1 - 1, 1 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Down + Ctrl moves date to next year" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2015, 1 - 1, 1 ), + "Keystroke Page Down + Ctrl moves date to next year" + ); input.datepicker( "destroy" ); step11(); }, 100 ); @@ -315,7 +350,8 @@ asyncTest( "keyboard handling", function() { // Check for moving to short months function step11() { - input.val( "3/31/14" ) + input + .val( "3/31/14" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -323,17 +359,20 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2014, 2 - 1, 28 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Up and short months" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2014, 2 - 1, 28 ), + "Keystroke Page Up and short months" + ); input.datepicker( "destroy" ); step12(); }, 100 ); } function step12() { - input.val( "1/30/16" ) + input + .val( "1/30/16" ) .datepicker() .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -341,10 +380,12 @@ asyncTest( "keyboard handling", function() { $( ":focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2016, 2 - 1, 29 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Down and leap years" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2016, 2 - 1, 29 ), + "Keystroke Page Down and leap years" + ); input.datepicker( "destroy" ); start(); }, 100 ); @@ -369,6 +410,11 @@ asyncTest( "keyboard handling", function() { "Keystroke pgdn step 2" ); */ +// TODO: implement +test( "ARIA", function() { + expect( 0 ); +}); + test( "mouse", function() { expect( 10 ); var input = $( "#datepicker" ).datepicker(), From 32eb9ac5c3a6a3aa65f2589cb4c64ea58ea8f59a Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 20:48:20 +0200 Subject: [PATCH 128/172] Datepicker tests: Fix calendar keyboard control tests Fix calendar keyboard control tests by disabling animation and adding delay --- tests/unit/datepicker/datepicker_core.js | 277 +++++++++++------------ 1 file changed, 134 insertions(+), 143 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 79135278647..c041be19682 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -153,7 +153,7 @@ asyncTest( "keyboard handling: calendar", function() { input = $( "#datepicker" ); function step1() { - input.datepicker(); + TestHelpers.datepicker.init( input ); picker = input.datepicker( "widget" ); ok( !picker.is( ":visible" ), "datepicker closed" ); @@ -163,11 +163,11 @@ asyncTest( "keyboard handling: calendar", function() { ok( picker.is( ":visible" ), "Keystroke down opens datepicker" ); input.datepicker( "destroy" ); step2(); - }, 50 ); + }, 100 ); } function step2() { - input.datepicker(); + TestHelpers.datepicker.init( input ); picker = input.datepicker( "widget" ); ok( !picker.is( ":visible" ), "datepicker closed" ); @@ -177,35 +177,33 @@ asyncTest( "keyboard handling: calendar", function() { ok( picker.is( ":visible" ), "Keystroke up opens datepicker" ); input.datepicker( "destroy" ); step3(); - }, 50 ); + }, 100 ); } function step3() { - input - .val( "1/1/14" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "1/1/14" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2013, 12 - 1, 31 ), - "Keystroke left to switch to previous day" - ); - input.datepicker( "destroy" ); - step4(); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2013, 12 - 1, 31 ), + "Keystroke left to switch to previous day" + ); + input.datepicker( "destroy" ); + step4(); + }, 50 ); }, 100 ); } function step4() { - input - .val( "1/1/14" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "1/1/14" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { $( ":focus" ) @@ -223,171 +221,164 @@ asyncTest( "keyboard handling: calendar", function() { } function step5() { - input - .val( "1/1/14" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "1/1/14" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2013, 12 - 1, 25 ), - "Keystroke up to move to the previous week" - ); - input.datepicker( "destroy" ); - step6(); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2013, 12 - 1, 25 ), + "Keystroke up to move to the previous week" + ); + input.datepicker( "destroy" ); + step6(); + }, 50 ); }, 100 ); } function step6() { - input - .val( "1/1/14" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "1/1/14" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2014, 1 - 1, 8 ), - "Keystroke down to move to the next week" - ); - input.datepicker( "destroy" ); - step7(); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2014, 1 - 1, 8 ), + "Keystroke down to move to the next week" + ); + input.datepicker( "destroy" ); + step7(); + }, 50 ); }, 100 ); } function step7() { - input - .val( "1/1/14" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "1/1/14" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2013, 12 - 1, 1 ), - "Keystroke Page Up moves date to previous month" - ); - input.datepicker( "destroy" ); - step8(); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2013, 12 - 1, 1 ), + "Keystroke Page Up moves date to previous month" + ); + input.datepicker( "destroy" ); + step8(); + }, 50 ); }, 100 ); } function step8() { - input - .val( "1/1/14" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "1/1/14" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2013, 1 - 1, 1 ), - "Keystroke Page Up + Ctrl moves date to previous year" - ); - input.datepicker( "destroy" ); - step9(); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2013, 1 - 1, 1 ), + "Keystroke Page Up + Ctrl moves date to previous year" + ); + input.datepicker( "destroy" ); + step9(); + }, 50 ); }, 100 ); } function step9() { - input - .val( "1/1/14" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "1/1/14" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2014, 2 - 1, 1 ), - "Keystroke Page Down moves date to next month" - ); - input.datepicker( "destroy" ); - step10(); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2014, 2 - 1, 1 ), + "Keystroke Page Down moves date to next month" + ); + input.datepicker( "destroy" ); + step10(); + }, 50 ); }, 100 ); } function step10() { - input - .val( "1/1/14" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "1/1/14" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2015, 1 - 1, 1 ), - "Keystroke Page Down + Ctrl moves date to next year" - ); - input.datepicker( "destroy" ); - step11(); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2015, 1 - 1, 1 ), + "Keystroke Page Down + Ctrl moves date to next year" + ); + input.datepicker( "destroy" ); + step11(); + }, 50 ); }, 100 ); } // Check for moving to short months function step11() { - input - .val( "3/31/14" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "3/31/14" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2014, 2 - 1, 28 ), - "Keystroke Page Up and short months" - ); - input.datepicker( "destroy" ); - step12(); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2014, 2 - 1, 28 ), + "Keystroke Page Up and short months" + ); + input.datepicker( "destroy" ); + step12(); + }, 50 ); }, 100 ); } function step12() { - input - .val( "1/30/16" ) - .datepicker() - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + input.val( "1/30/16" ); + TestHelpers.datepicker.init( input ); + input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2016, 2 - 1, 29 ), - "Keystroke Page Down and leap years" - ); - input.datepicker( "destroy" ); - start(); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); + setTimeout(function() { + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2016, 2 - 1, 29 ), + "Keystroke Page Down and leap years" + ); + input.datepicker( "destroy" ); + start(); + }, 50 ); }, 100 ); } From 550a0a10e8c83ccb5c845e49ce642b29f3e9e618 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 00:50:08 +0200 Subject: [PATCH 129/172] Datepicker tests: Fix mouse core unit tests by adding delay --- tests/unit/datepicker/datepicker_core.js | 178 +++++++++++++++-------- 1 file changed, 120 insertions(+), 58 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index c041be19682..1c336157485 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -406,70 +406,132 @@ test( "ARIA", function() { expect( 0 ); }); -test( "mouse", function() { +asyncTest( "mouse", function() { expect( 10 ); - var input = $( "#datepicker" ).datepicker(), + + var input = TestHelpers.datepicker.init( $( "#datepicker" ).val( "" ) ), picker = input.datepicker( "widget" ), date = new Date(); - input.val( "" ).datepicker( "open" ); - $( ".ui-calendar-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} ); - date.setDate( 10 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Mouse click" ); - - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), - "Mouse click - preset" ) ; - - input.val( "" ).datepicker( "refresh" ).datepicker( "open" ); - $( "button.ui-calendar-close", picker ).simulate( "click", {} ); - ok( input.datepicker( "valueAsDate" ) == null, "Mouse click - close" ); - - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( "button.ui-calendar-close", picker ).simulate( "click", {} ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), - "Mouse click - close + preset" ); - - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( "a.ui-calendar-prev", picker ).simulate( "click", {} ); - $( "button.ui-calendar-close", picker ).simulate( "click", {} ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), - "Mouse click - abandoned" ); - - // Current/previous/next - input.val( "" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-current", picker ).simulate( "click", {} ); - date.setDate( new Date().getDate() ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Mouse click - current" ); - - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-prev", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), - "Mouse click - previous" ); - - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-next", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), - "Mouse click - next" ); + function step1() { + input.datepicker( "open" ); + + setTimeout(function() { + $( "tbody a:contains(10)", picker ).simulate( "mousedown", {} ); + date.setDate( 10 ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + date, + "Mouse click" + ); + + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 2 - 1, 12 ), + "Mouse click - preset" + ); + + input.val( "" ).datepicker( "refresh" ).datepicker( "open" ); + $( "button.ui-calendar-close", picker ).simulate( "click", {} ); + ok( input.datepicker( "valueAsDate" ) == null, "Mouse click - close" ); + + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + $( "button.ui-calendar-close", picker ).simulate( "click", {} ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 2 - 1, 4 ), + "Mouse click - close + preset" + ); + + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + $( "a.ui-calendar-prev", picker ).simulate( "click", {} ); + $( "button.ui-calendar-close", picker ).simulate( "click", {} ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 2 - 1, 4 ), + "Mouse click - abandoned" + ); + + // Current/previous/next + input.val( "" ).datepicker( "refresh" ).datepicker( "open" ); + $( ".ui-calendar-current", picker ).simulate( "click", {} ); + date.setDate( new Date().getDate() ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + date, + "Mouse click - current" + ); + + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + $( ".ui-calendar-prev", picker ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 1 - 1, 16 ), + "Mouse click - previous" + ); + + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + $( ".ui-calendar-next", picker ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 3 - 1, 18 ), + "Mouse click - next" + ); + + step2(); + }, 100 ); + } // Previous/next with minimum/maximum - input.datepicker( "option", { - min: new Date( 2008, 2 - 1, 2 ), - max: new Date( 2008, 2 - 1, 26 ) - }).val( "2/4/08" ).datepicker( "open" ); - $( ".ui-calendar-prev", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 16 ), - "Mouse click - previous + min/max" ); - - input.val( "2/4/08" ).datepicker( "open" ); - $( ".ui-calendar-next", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); - TestHelpers.datepicker.equalsDate(input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 18 ), - "Mouse click - next + min/max" ); + function step2() { + input + .datepicker( "destroy" ) + .val( "3/4/08" ); + input = TestHelpers.datepicker.init( "#datepicker", { + min: new Date( 2008, 2 - 1, 2 ), + max: new Date( 2008, 2 - 1, 26 ) + }); + picker = input.datepicker( "widget" ); + input.datepicker( "open" ); + setTimeout(function() { + $( ".ui-calendar-prev", picker ).simulate( "click" ); + $( "tbody a:contains(16)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 2 - 1, 16 ), + "Mouse click - previous + min/max" + ); + step3(); + }, 100 ); + } + + function step3() { + input + .datepicker( "destroy" ) + .val( "1/4/08" ); + input = TestHelpers.datepicker.init( "#datepicker", { + min: new Date( 2008, 2 - 1, 2 ), + max: new Date( 2008, 2 - 1, 26 ) + }); + picker = input.datepicker( "widget" ); + input.datepicker( "open" ); + setTimeout(function() { + $( ".ui-calendar-next", picker ).simulate( "click" ); + $( "tbody a:contains(18)", picker ).simulate( "mousedown" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 2 - 1, 18 ), + "Mouse click - next + min/max" + ); + start(); + }, 100 ); + } + + step1(); }); })( jQuery ); From b9278de7885d78409955859a99833cbc662ec7aa Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 00:56:21 +0200 Subject: [PATCH 130/172] Datepicker tests: Code style --- tests/unit/datepicker/datepicker_options.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index f73ee569d80..6432c8eddcc 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -505,12 +505,11 @@ test( "localization", function() { test( "Ticket 7602: Stop datepicker from appearing with beforeOpen event handler", function() { expect( 3 ); - var input; - - input = TestHelpers.datepicker.init( "#datepicker", { + var input = TestHelpers.datepicker.init( "#datepicker", { beforeOpen: function() { } }); + input.datepicker( "open" ); equal( input.datepicker( "widget" ).css( "display" ), "block", "beforeOpen returns nothing" ); input.datepicker( "close" ).datepicker( "destroy" ); From f187eb55464edaa7f95a5cd2cb958bc31b115875 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 00:57:59 +0200 Subject: [PATCH 131/172] Datepicker tests: Unify show / hide options in helper create method --- tests/unit/datepicker/datepicker_test_helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/datepicker/datepicker_test_helpers.js b/tests/unit/datepicker/datepicker_test_helpers.js index 23f5025b48b..f62e086b974 100644 --- a/tests/unit/datepicker/datepicker_test_helpers.js +++ b/tests/unit/datepicker/datepicker_test_helpers.js @@ -19,7 +19,7 @@ TestHelpers.datepicker = { return $( id ).datepicker( options ); }, initNewInput: function( options ) { - options = $.extend( { show: false }, options || {} ); + options = $.extend( { show: false, hide: false }, options || {} ); return $( "" ).datepicker( options ) .appendTo( "#qunit-fixture" ); } From 9672361209ae969ed69a6343e4b3a0352f85b25c Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 01:15:14 +0200 Subject: [PATCH 132/172] Datepicker: Fix alternate field demo --- demos/datepicker/alt-field.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/demos/datepicker/alt-field.html b/demos/datepicker/alt-field.html index 47d3d9f8984..8cfe4a20953 100644 --- a/demos/datepicker/alt-field.html +++ b/demos/datepicker/alt-field.html @@ -11,14 +11,15 @@ + + diff --git a/demos/datepicker/buttonbar.html b/demos/datepicker/buttonbar.html index cccc8c1d1ff..0343d36f523 100644 --- a/demos/datepicker/buttonbar.html +++ b/demos/datepicker/buttonbar.html @@ -11,6 +11,7 @@ + diff --git a/demos/datepicker/dropdown-month-year.html b/demos/datepicker/dropdown-month-year.html index 19845f8fb85..bd6a260162b 100644 --- a/demos/datepicker/dropdown-month-year.html +++ b/demos/datepicker/dropdown-month-year.html @@ -11,6 +11,7 @@ + diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index 4631e900cc0..b04dc04d753 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -10,6 +10,7 @@ + diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index 1caee8b9a46..94ba1790141 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -11,6 +11,7 @@ + diff --git a/demos/datepicker/multiple-calendars.html b/demos/datepicker/multiple-calendars.html index bba5082cff7..ad6d7218559 100644 --- a/demos/datepicker/multiple-calendars.html +++ b/demos/datepicker/multiple-calendars.html @@ -11,6 +11,7 @@ + diff --git a/demos/datepicker/other-months.html b/demos/datepicker/other-months.html index 4a0afb0bb33..e3eed39b5d1 100644 --- a/demos/datepicker/other-months.html +++ b/demos/datepicker/other-months.html @@ -11,6 +11,7 @@ + diff --git a/demos/datepicker/show-week.html b/demos/datepicker/show-week.html index 091fed4cdf6..9dbd09d6acb 100644 --- a/demos/datepicker/show-week.html +++ b/demos/datepicker/show-week.html @@ -11,6 +11,7 @@ + From 557dfbef4bda67737e82fb882ee7b78a19c5825e Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 01:35:51 +0200 Subject: [PATCH 134/172] Calendar: Fix multiple calendar styles (follow-up) --- themes/base/calendar.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/themes/base/calendar.css b/themes/base/calendar.css index 608afed4465..f7ff0645473 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -110,14 +110,14 @@ /* with multiple calendars */ .ui-calendar.ui-calendar-multi { - width: 100%; + width: auto } .ui-calendar-multi .ui-calendar-group { float: left; } .ui-calendar-multi .ui-calendar-group table { width: 95%; - margin: 0 auto .4em; + margin: 0 2.5% .4em; } .ui-calendar-multi-2 .ui-calendar-group { width: 50%; From 0b8ad82801ea4d5c0baca0ac06bc9cc0e82450ad Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 01:44:13 +0200 Subject: [PATCH 135/172] Calendar: Fix German localization --- external/localization.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/external/localization.js b/external/localization.js index 98d8f813052..75a661b4b04 100644 --- a/external/localization.js +++ b/external/localization.js @@ -2767,10 +2767,10 @@ var regions = { "dateFormat": "d" }, "de": { - "closeText": "schlie\u00dfen", + "closeText": "Schlie\u00dfen", "prevText": "<zur\u00fcck", "nextText": "Vor>", - "currentText": "heute", + "currentText": "Heute", "weekHeader": "Wo", "dateFormat": "d" }, From becc812135c5c9a98752c4a31f6085f434abfc6f Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 01:46:16 +0200 Subject: [PATCH 136/172] Datepicker: Sort and clean up demo index --- demos/datepicker/index.html | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/demos/datepicker/index.html b/demos/datepicker/index.html index d9c8dfc10da..75ecba67564 100644 --- a/demos/datepicker/index.html +++ b/demos/datepicker/index.html @@ -9,19 +9,18 @@ From a4ca2993ce90bfa8c17e81c4fb1e92e48a64c2bf Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 02:05:26 +0200 Subject: [PATCH 137/172] Datepicker: Improve date formats demo --- demos/datepicker/date-formats.html | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index d69f60da5ce..92e1d6ebedf 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -17,24 +17,17 @@ From b4d522d754912148654f67ceb77098903317ed74 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 02:29:11 +0200 Subject: [PATCH 139/172] Datepicker tests: Fix method test messages --- tests/unit/datepicker/datepicker_methods.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index a4209740ea6..cf41313922a 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -49,12 +49,12 @@ test( "open / close", function() { input.datepicker( "open" ); ok( calendar.is( ":visible" ), "open: calendar visible" ); - equal( calendar.attr( "aria-hidden" ), "false", "open: calendar aria-disabled" ); + equal( calendar.attr( "aria-hidden" ), "false", "open: calendar aria-hidden" ); equal( calendar.attr( "aria-expanded" ), "true", "close: calendar aria-expanded" ); input.datepicker( "close" ); ok( !calendar.is( ":visible" ), "close: calendar hidden" ); - equal( calendar.attr( "aria-hidden" ), "true", "close: calendar aria-disabled" ); + equal( calendar.attr( "aria-hidden" ), "true", "close: calendar aria-hidden" ); equal( calendar.attr( "aria-expanded" ), "false", "close: calendar aria-expanded" ); }); From ba11bf8c4dbff91c6a07464d688adff50b606b93 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 02:31:31 +0200 Subject: [PATCH 140/172] Datepicker: Several minor code improvements Several minor code improvements and make suppressExpandOnFocus an internal variable --- ui/datepicker.js | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 519cc477d3f..ac68de1e885 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -27,9 +27,7 @@ }(function( $ ) { var widget, - calendarOptions = [ "dateFormat", "eachDay", "max", "min", "numberOfMonths", "showWeek" ], - // TODO move this to the instance? - suppressExpandOnFocus = false; + calendarOptions = [ "dateFormat", "eachDay", "max", "min", "numberOfMonths", "showWeek" ]; widget = $.widget( "ui.datepicker", { version: "@VERSION", @@ -50,6 +48,8 @@ widget = $.widget( "ui.datepicker", { }, _create: function() { + this.suppressExpandOnFocus = false; + if ( typeof this.options.max === "string" ) { this.options.max = Globalize.parseDate( this.options.max , { pattern: "yyyy-MM-dd" } ); } @@ -93,9 +93,10 @@ widget = $.widget( "ui.datepicker", { this._setHiddenPicker(); - this.element - .attr( "aria-haspopup", "true" ) - .attr( "aria-owns", this.calendar.attr( "id" ) ); + this.element.attr({ + "aria-haspopup": true, + "aria-owns": this.calendar.attr( "id" ) + }); }, _inputEvents: { @@ -142,7 +143,7 @@ widget = $.widget( "ui.datepicker", { }, mousedown: function( event ) { if ( this.isOpen ) { - suppressExpandOnFocus = true; + this.suppressExpandOnFocus = true; this.close(); return; } @@ -150,19 +151,17 @@ widget = $.widget( "ui.datepicker", { clearTimeout( this.closeTimer ); }, focus: function( event ) { - if ( !suppressExpandOnFocus ) { + if ( !this.suppressExpandOnFocus && !this.isOpen ) { this._delay( function() { - if ( !this.isOpen ) { - this.open( event ); - } + this.open( event ); }, 1); } this._delay( function() { - suppressExpandOnFocus = false; + this.suppressExpandOnFocus = false; }, 100 ); }, blur: function() { - suppressExpandOnFocus = false; + this.suppressExpandOnFocus = false; } }, @@ -223,7 +222,7 @@ widget = $.widget( "ui.datepicker", { }, _focusTrigger: function() { - suppressExpandOnFocus = true; + this.suppressExpandOnFocus = true; this.element.focus(); }, @@ -241,14 +240,14 @@ widget = $.widget( "ui.datepicker", { } this.calendarInstance.refresh(); - this.calendar - .attr( "aria-hidden", "false" ) - .attr( "aria-expanded", "true" ) + .attr({ + "aria-hidden": false, + "aria-expanded": true + }) .show() .position( this._buildPosition() ) .hide(); - this._show( this.calendar, this.options.show ); // take trigger out of tab order to allow shift-tab to skip trigger @@ -270,9 +269,10 @@ widget = $.widget( "ui.datepicker", { }, _setHiddenPicker: function() { - this.calendar - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ); + this.calendar.attr({ + "aria-hidden": true, + "aria-expanded": false + }); }, _buildPosition: function() { @@ -305,9 +305,7 @@ widget = $.widget( "ui.datepicker", { _destroy: function() { this.calendarInstance.destroy(); this.calendar.remove(); - this.element - .removeAttr( "aria-haspopup" ) - .removeAttr( "aria-owns" ); + this.element.removeAttr( "aria-haspopup aria-owns" ); }, widget: function() { From 138fd3a041ae4d78032d09751a0868246ade8bd6 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 02:49:30 +0200 Subject: [PATCH 141/172] Calendar: Fix hover event setting and removing --- ui/calendar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index fc29da9027b..02fb4132c6d 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -73,8 +73,7 @@ return $.widget( "ui.calendar", { "keydown .ui-calendar-calendar": "_handleKeydown" }); - // TODO use hoverable (no delegation support)? convert to _on? - this.element.delegate( ".ui-calendar-header a, .ui-calendar-calendar a", "mouseenter.calendar mouseleave.calendar", function() { + this.element.on( "mouseenter.calendar mouseleave.calendar", ".ui-calendar-header a, .ui-calendar-calendar a", function() { $( this ).toggleClass( "ui-state-hover" ); }); @@ -453,6 +452,7 @@ return $.widget( "ui.calendar", { _destroy: function() { this.element + .off( ".calendar" ) .removeClass( "ui-calendar ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-calendar-multi" ) .removeAttr( "role aria-labelledby" ) .removeUniqueId() From 181b1dea3d9afd03bc27b8060384ee7919c0dbc0 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 15:12:27 +0200 Subject: [PATCH 142/172] Calendar: Improve code style and clean up --- ui/calendar.js | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 02fb4132c6d..595f5e33c7e 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -12,7 +12,7 @@ if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. - // ToDo Add globalize and $.date? + // TODO: Add globalize and $.date? define([ "jquery", "./core", @@ -30,7 +30,7 @@ return $.widget( "ui.calendar", { version: "@VERSION", options: { dateFormat: { date: "short" }, - // TODO review + // TODO: review eachDay: $.noop, max: null, min: null, @@ -65,8 +65,8 @@ return $.widget( "ui.calendar", { }, "mousedown .ui-calendar-calendar a": function( event ) { event.preventDefault(); - // TODO exclude clicks on lead days or handle them correctly - // TODO store/read more then just date, also required for multi month picker + // TODO: exclude clicks on lead days or handle them correctly + // TODO: store/read more then just date, also required for multi month picker this._select( event, $( event.currentTarget ).data( "timestamp" ) ); this.grid.focus( 1 ); }, @@ -133,12 +133,12 @@ return $.widget( "ui.calendar", { }, _setActiveDescendant: function() { - var newId = this.id + "-" + this.date.day(), - newCell = $( "#" + newId ); + var id = this.id + "-" + this.date.day(); - this.grid.attr( "aria-activedescendant", newId ); - this.grid.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); - newCell.children( "a" ).addClass( "ui-state-focus" ); + this.grid + .attr( "aria-activedescendant", id ) + .removeClass( "ui-state-focus" ); + $( "#" + id + " a" ).addClass( "ui-state-focus" ); }, _createCalendar: function() { @@ -173,7 +173,7 @@ return $.widget( "ui.calendar", { i = 0; for ( i; i < months.length; i++ ) { - // TODO Shouldn't we pass date as a parameter to build* fns instead of setting this.date? + // TODO: Shouldn't we pass date as a parameter to build* fns instead of setting this.date? this.date = months[ i ]; headerClass = months[ i ].first ? "ui-corner-left" : months[ i ].last ? "ui-corner-right" : ""; @@ -305,6 +305,7 @@ return $.widget( "ui.calendar", { for ( i; i < week.days.length; i++ ) { cells += this._buildDayCell( week.days[i] ); } + return "" + cells + ""; }, @@ -344,7 +345,7 @@ return $.widget( "ui.calendar", { if ( day.today ) { classes.push( "ui-state-highlight" ); } - // ToDo Explain and document this + // TODO: Explain and document this if ( day.extraClasses ) { classes.push( day.extraClasses.split( " " ) ); } @@ -389,9 +390,7 @@ return $.widget( "ui.calendar", { }, _refreshMultiplePicker: function() { - var i = 0; - - for ( ; i < this.options.numberOfMonths; i++ ) { + for (var i = 0 ; i < this.options.numberOfMonths; i++ ) { $( ".ui-calendar-title", this.element ).eq( i ).html( this._buildTitle() ); $( ".ui-calendar-calendar", this.element ).eq( i ).html( this._buildGrid() ); this.date.adjust( "M", 1 ); @@ -403,12 +402,6 @@ return $.widget( "ui.calendar", { $( this.element ).find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" ); }, - _setHiddenPicker: function() { - this.element - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ); - }, - _select: function( event, time ) { this._setOption( "value", new Date( time ) ); this._trigger( "select", event ); @@ -463,6 +456,7 @@ return $.widget( "ui.calendar", { if ( arguments.length === 0 || ( arguments.length === 1 && key === "value" ) ) { this.options.value = this.date.selectedDate(); } + return this._superApply( arguments ); }, From 732424b6cc5e20d56cb5ef1e3e838a292a319a4c Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 17:37:37 +0200 Subject: [PATCH 143/172] Calendar: Focus class is not removed when using arrow keys --- ui/calendar.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/calendar.js b/ui/calendar.js index 595f5e33c7e..7e21db2dd9a 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -137,8 +137,9 @@ return $.widget( "ui.calendar", { this.grid .attr( "aria-activedescendant", id ) + .find( ".ui-state-focus" ) .removeClass( "ui-state-focus" ); - $( "#" + id + " a" ).addClass( "ui-state-focus" ); + $( "#" + id + " > a" ).addClass( "ui-state-focus" ); }, _createCalendar: function() { From ac0f9da4cdbcb26aeba630c3a99416cb4160c3e2 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 17:42:21 +0200 Subject: [PATCH 144/172] Datepicker: Remove unwanted CTRL+HOME shortcut --- tests/unit/datepicker/datepicker_core.js | 9 +-------- ui/datepicker.js | 11 ----------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 1c336157485..b55267aa686 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -87,7 +87,7 @@ asyncTest( "baseStructure", function() { }); test( "Keyboard handling: input", function() { - expect( 8 ); + expect( 7 ); var input = $( "#datepicker" ).datepicker(), instance = input.datepicker( "instance" ), date = new Date(); @@ -107,13 +107,6 @@ test( "Keyboard handling: input", function() { TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke enter - preset" ); - // Control + Home = Change the calendar to the current month - input - .val( "1/1/14" ).datepicker( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+home" ); - input .val( "" ) .datepicker( "open" ); diff --git a/ui/datepicker.js b/ui/datepicker.js index ac68de1e885..d9a6e95a724 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -123,17 +123,6 @@ widget = $.widget( "ui.datepicker", { this.calendarInstance.grid.focus( 1 ); }, 1 ); break; - case $.ui.keyCode.HOME: - if ( event.ctrlKey ) { - this.valueAsDate( new Date() ); - event.preventDefault(); - if ( this.isOpen ) { - this.calendarInstance.refresh(); - } else { - this.open( event ); - } - } - break; } }, keyup: function() { From c0d9e8e593e900859b2aa3d119bcd98f634def1e Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 18:11:17 +0200 Subject: [PATCH 145/172] Datepicker: Rename multiple calendars demo to multiple months --- demos/datepicker/index.html | 2 +- .../{multiple-calendars.html => multiple-months.html} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename demos/datepicker/{multiple-calendars.html => multiple-months.html} (100%) diff --git a/demos/datepicker/index.html b/demos/datepicker/index.html index 75ecba67564..ec9e94788cf 100644 --- a/demos/datepicker/index.html +++ b/demos/datepicker/index.html @@ -19,7 +19,7 @@
        • Localize calendar
        • Restrict date range
        • Dates in other months
        • -
        • Display multiple months
        • +
        • Display multiple months
        • Show week of the year
        diff --git a/demos/datepicker/multiple-calendars.html b/demos/datepicker/multiple-months.html similarity index 100% rename from demos/datepicker/multiple-calendars.html rename to demos/datepicker/multiple-months.html From f498918d42f7aa7f1b5bcae4fc53c0b1bfe920b8 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 18:36:57 +0200 Subject: [PATCH 146/172] Datepicker: Remove support for enter key on input --- tests/unit/datepicker/datepicker_core.js | 11 ++--------- tests/unit/datepicker/datepicker_events.js | 19 +++++-------------- ui/datepicker.js | 3 --- 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index b55267aa686..786b89cb6df 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -87,16 +87,9 @@ asyncTest( "baseStructure", function() { }); test( "Keyboard handling: input", function() { - expect( 7 ); + expect( 6 ); var input = $( "#datepicker" ).datepicker(), - instance = input.datepicker( "instance" ), - date = new Date(); - - // Enter = Select today's date by default - input - .datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke enter" ); + instance = input.datepicker( "instance" ); // Enter = Select preset date input diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index 6739f843589..aacaa2a2f6c 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -76,7 +76,7 @@ test( "open", function() { }); asyncTest( "select", function() { - expect( 6 ); + expect( 4 ); var input = TestHelpers.datepicker.init( "#datepicker", { select: function( event ) { @@ -92,15 +92,6 @@ asyncTest( "select", function() { message = ""; function step1() { - message = "on input enter"; - input - .simulate( "focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - input.datepicker( "close" ); - step2(); - } - - function step2() { message = "on calendar cell click"; input .simulate( "focus" ) @@ -108,11 +99,11 @@ asyncTest( "select", function() { setTimeout(function() { widget.find( "tbody tr:first td:first a" ).simulate( "mousedown" ); input.datepicker( "close" ); - step3(); + step2(); }, 100 ); } - function step3() { + function step2() { message = "on calendar cell enter"; input .simulate( "focus" ) @@ -122,11 +113,11 @@ asyncTest( "select", function() { .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); input.datepicker( "close" ); - step4(); + step3(); }, 100 ); } - function step4() { + function step3() { message = "on calendar escape (not expected)"; input .simulate( "focus" ) diff --git a/ui/datepicker.js b/ui/datepicker.js index d9a6e95a724..e4424bd1597 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -112,9 +112,6 @@ widget = $.widget( "ui.datepicker", { this.close( event ); } break; - case $.ui.keyCode.ENTER: - this.calendarInstance._handleKeydown( event ); - break; case $.ui.keyCode.DOWN: case $.ui.keyCode.UP: clearTimeout( this.closeTimer ); From 772703e1a3a9823f1d23210e539c7c907922f61d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 18:59:28 +0200 Subject: [PATCH 147/172] Datepicker: Improve localization handling, fix return indenting --- ui/calendar.js | 63 +++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 7e21db2dd9a..4b1e1859ae4 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -44,6 +44,7 @@ return $.widget( "ui.calendar", { _create: function() { this.id = this.element.uniqueId().attr( "id" ); + this.labels = Globalize.translate( "datepicker" ); this.date = $.date( this.options.value, this.options.dateFormat ).select(); this.date.eachDay = this.options.eachDay; @@ -204,41 +205,39 @@ return $.widget( "ui.calendar", { _buildHeader: function() { return "
        " + - this._buildPreviousLink() + - this._buildNextLink() + - this._buildTitlebar() + - "
        "; + this._buildPreviousLink() + + this._buildNextLink() + + this._buildTitlebar() + + "
        "; }, _buildPreviousLink: function() { - var labels = Globalize.translate( "datepicker" ); - - return ""; }, _buildNextLink: function() { - var labels = Globalize.translate( "datepicker" ); - - return ""; }, _buildTitlebar: function() { - var labels = Globalize.translate( "datepicker" ); - return "
        " + - "
        " + - this._buildTitle() + - "
        " + - ", " + labels.datePickerRole + "" + - "
        "; + "
        " + + this._buildTitle() + + "
        " + + ", " + + this.labels.datePickerRole + + "" + + "
        "; }, _buildTitle: function() { @@ -260,27 +259,26 @@ return $.widget( "ui.calendar", { _buildGridHeading: function() { var cells = "", - i = 0, - labels = Globalize.translate( "datepicker" ); + i = 0; if ( this.options.showWeek ) { - cells += "" + labels.weekHeader + ""; + cells += "" + this.labels.weekHeader + ""; } for ( i; i < this.date.weekdays().length; i++ ) { cells += this._buildGridHeaderCell( this.date.weekdays()[i] ); } return "" + - "" + cells + "" + - ""; + "" + cells + "" + + ""; }, _buildGridHeaderCell: function( day ) { return "" + - "" + - day.shortname + - "" + - ""; + "" + + day.shortname + + "" + + ""; }, _buildGridBody: function() { @@ -334,7 +332,6 @@ return $.widget( "ui.calendar", { _buildDayElement: function( day, selectable ) { var classes = [ "ui-state-default" ], - labels = Globalize.translate( "datepicker" ), content = ""; if ( day === this.date && selectable ) { @@ -359,18 +356,16 @@ return $.widget( "ui.calendar", { } if ( day.today ) { - content += ", " + labels.currentText + ""; + content += ", " + this.labels.currentText + ""; } return content; }, _buildButtons: function() { - var labels = Globalize.translate( "datepicker" ); - return "
        " + - "" + - "
        "; + "" + + "
        "; }, // Refreshing the entire calendar during interaction confuses screen readers, specifically From 5513e14bcb0de48d2b21c31c655457fce8925f31 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 19:51:13 +0200 Subject: [PATCH 148/172] Calendar: Fix German localization --- external/localization.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/localization.js b/external/localization.js index 75a661b4b04..4fd436aca00 100644 --- a/external/localization.js +++ b/external/localization.js @@ -2768,7 +2768,7 @@ var regions = { }, "de": { "closeText": "Schlie\u00dfen", - "prevText": "<zur\u00fcck", + "prevText": "<Zur\u00fcck", "nextText": "Vor>", "currentText": "Heute", "weekHeader": "Wo", From 0c6a529f5c987b1bd8dfeba2ee4839a3e8fedaaf Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 19:52:01 +0200 Subject: [PATCH 149/172] Calendar: Update localization provided by Globalize on refresh --- ui/calendar.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/calendar.js b/ui/calendar.js index 4b1e1859ae4..c2991d7a32c 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -374,6 +374,7 @@ return $.widget( "ui.calendar", { // with the prev and next links would cause loss of focus issues because the links being // interacted with will disappear while focused. refresh: function() { + this.labels = Globalize.translate( "datepicker" ); // determine which day gridcell to focus after refresh // TODO: Prevent disabled cells from being focused if ( this.options.numberOfMonths === 1 ) { From 0819e586ad2928c0154bd3e481c9e1b0dcfad80c Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 19:56:31 +0200 Subject: [PATCH 150/172] Datepicker tests: Add basic localization unit tests --- tests/unit/datepicker/datepicker_core.js | 37 ++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 786b89cb6df..e442115e041 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -86,6 +86,43 @@ asyncTest( "baseStructure", function() { step1(); }); +test( "Localization", function() { + expect( 10 ); + + var defaultLocale = Globalize.locale(), + input = $( "#datepicker" ), + date = new Date( 2014, 0, 1 ), + initDatepicker = function() { + input + .datepicker() + .datepicker( "valueAsDate", date ) + .datepicker( "open" ); + }, + testLocalization = function( message ) { + picker = input.datepicker( "widget" ); + + equal( picker.find( ".ui-calendar-month" ).text(), "Januar", message + "titlebar year" ); + equal( picker.find( "thead th:first" ).text(), "Mo.", message + "teader first day" ); + equal( picker.find( "thead th:last" ).text(), "So.", message + "header last day" ); + equal( picker.find( ".ui-calendar-prev" ).text(), "", message + "header next" ); + }, + picker; + + Globalize.locale( "de-DE" ); + initDatepicker(); + testLocalization( "Init: " ); + input.datepicker( "destroy" ); + + Globalize.locale( defaultLocale.locale ); + initDatepicker(); + Globalize.locale( "de-DE" ); + input.datepicker( "refresh" ); + testLocalization( "After init: " ); + + Globalize.locale( defaultLocale.locale ); +}); + test( "Keyboard handling: input", function() { expect( 6 ); var input = $( "#datepicker" ).datepicker(), From 2b8c4d86141bf57b0fe71a116aafa6e38f4300fa Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 20:06:09 +0200 Subject: [PATCH 151/172] Calendar: Improve comment --- ui/calendar.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/calendar.js b/ui/calendar.js index c2991d7a32c..f4da98f1e01 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -282,7 +282,8 @@ return $.widget( "ui.calendar", { }, _buildGridBody: function() { - // this.date.days() is not cached, and it has O(n^2) complexity. It is run O(n) times. So, it equals O(n^3). Not good at all. Caching. + // TODO: this.date.days() is not cached, and it has O(n^2) complexity. It is run O(n) times. + // So, it equals O(n^3). Not good at all. Caching. var days = this.date.days(), i = 0, rows = ""; From a07e9f950be816ed1dfddf4215c8d36982cc42a7 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 22:50:30 +0200 Subject: [PATCH 152/172] Calendar: Rename multiple calendars demo to multiple months --- demos/calendar/index.html | 8 ++++---- .../{multiple-calendars.html => multiple-month.html} | 0 2 files changed, 4 insertions(+), 4 deletions(-) rename demos/calendar/{multiple-calendars.html => multiple-month.html} (100%) diff --git a/demos/calendar/index.html b/demos/calendar/index.html index 48097f5983e..cfdd15a6ac5 100644 --- a/demos/calendar/index.html +++ b/demos/calendar/index.html @@ -15,10 +15,10 @@
      10. Populate alternate field
      11. Display inline
      12. Display button bar
      13. -
      14. Display month & year menus
      15. -
      16. Dates in other months
      17. -
      18. Show week of the year
      19. -
      20. Display multiple months
      21. +
      22. Display month & year menus
      23. +
      24. Dates in other months
      25. +
      26. Show week of the year
      27. +
      28. Display multiple months
      29. Icon trigger
      30. Animations
      31. Date Range
      32. diff --git a/demos/calendar/multiple-calendars.html b/demos/calendar/multiple-month.html similarity index 100% rename from demos/calendar/multiple-calendars.html rename to demos/calendar/multiple-month.html From c63073f631cf1e7c01d00ba3f5461ac3f8b0f0dc Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 22:52:12 +0200 Subject: [PATCH 153/172] Calendar: Sort and clean up demo index --- demos/calendar/index.html | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/demos/calendar/index.html b/demos/calendar/index.html index cfdd15a6ac5..0335beacb74 100644 --- a/demos/calendar/index.html +++ b/demos/calendar/index.html @@ -9,19 +9,14 @@ From 66385d42270e5ad33b1fd0d0abdc8be5e636903a Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 23:04:04 +0200 Subject: [PATCH 154/172] Calendar: Fix demos after widget split --- demos/calendar/buttonbar.html | 2 +- demos/calendar/date-formats.html | 27 +++++++++---------------- demos/calendar/dropdown-month-year.html | 2 +- demos/calendar/localization.html | 17 ++++++++-------- demos/calendar/multiple-month.html | 2 +- demos/calendar/other-months.html | 2 +- demos/calendar/show-week.html | 2 +- 7 files changed, 24 insertions(+), 30 deletions(-) diff --git a/demos/calendar/buttonbar.html b/demos/calendar/buttonbar.html index 77da1ab5749..10162ebf1a2 100644 --- a/demos/calendar/buttonbar.html +++ b/demos/calendar/buttonbar.html @@ -24,7 +24,7 @@ -

        Date:

        +

        Display a button for selecting Today's date and a Done button for closing the calendar with the boolean showButtonPanel option. Each button is enabled by default when the bar is displayed, but can be turned off with additional options. Button text is customizable.

        diff --git a/demos/calendar/date-formats.html b/demos/calendar/date-formats.html index 95adf01fd64..33df9cacb59 100644 --- a/demos/calendar/date-formats.html +++ b/demos/calendar/date-formats.html @@ -16,24 +16,17 @@ -

        Date:   -

        +
        +

        Localize the calendar calendar language and format (English / Western formatting is the default). The calendar includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.

        diff --git a/demos/calendar/multiple-month.html b/demos/calendar/multiple-month.html index 9fe2b7ab526..40cc30e2d72 100644 --- a/demos/calendar/multiple-month.html +++ b/demos/calendar/multiple-month.html @@ -25,7 +25,7 @@ -

        Date:

        +

        Set the numberOfMonths option to an integer of 2 or more to show multiple months in a single calendar.

        diff --git a/demos/calendar/other-months.html b/demos/calendar/other-months.html index 3ad1aba37d9..4e3ee3e3b88 100644 --- a/demos/calendar/other-months.html +++ b/demos/calendar/other-months.html @@ -30,7 +30,7 @@ -

        Date:

        +

        The calendar can show dates that come from other than the main month diff --git a/demos/calendar/show-week.html b/demos/calendar/show-week.html index e7fcb84957b..bb9ae4cc9b6 100644 --- a/demos/calendar/show-week.html +++ b/demos/calendar/show-week.html @@ -24,7 +24,7 @@ -

        Date:

        +

        The calendar can show the week of the year. The calculation follows From 4110db0b46c9b05d7f640db7724a29a0811d60e0 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 00:13:20 +0200 Subject: [PATCH 155/172] Calendar: Add buttons option --- demos/calendar/buttonbar.html | 6 ++- ui/calendar.js | 70 ++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/demos/calendar/buttonbar.html b/demos/calendar/buttonbar.html index 10162ebf1a2..235192da1f8 100644 --- a/demos/calendar/buttonbar.html +++ b/demos/calendar/buttonbar.html @@ -17,7 +17,11 @@ diff --git a/ui/calendar.js b/ui/calendar.js index f4da98f1e01..b795a01e524 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -29,6 +29,7 @@ return $.widget( "ui.calendar", { version: "@VERSION", options: { + buttons: [], dateFormat: { date: "short" }, // TODO: review eachDay: $.noop, @@ -60,10 +61,6 @@ return $.widget( "ui.calendar", { this.date.adjust( "M", this.options.numberOfMonths ); this.refresh(); }, - "click .ui-calendar-current": function( event ) { - event.preventDefault(); - this._select( event, new Date().getTime() ); - }, "mousedown .ui-calendar-calendar a": function( event ) { event.preventDefault(); // TODO: exclude clicks on lead days or handle them correctly @@ -148,7 +145,7 @@ return $.widget( "ui.calendar", { pickerHtml = ""; if ( this.options.numberOfMonths === 1 ) { - pickerHtml = this._buildHeader() + this._buildGrid() + this._buildButtons(); + pickerHtml = this._buildHeader() + this._buildGrid(); } else { pickerHtml = this._buildMultiplePicker(); classes += " ui-calendar-multi"; @@ -162,6 +159,8 @@ return $.widget( "ui.calendar", { }) .html( pickerHtml ); + this._createButtonPane(); + this.element.find( "button" ).button(); this.grid = this.element.find( ".ui-calendar-calendar" ); @@ -196,7 +195,6 @@ return $.widget( "ui.calendar", { } html += "

        "; - html += this._buildButtons(); this.date = currentDate; @@ -363,10 +361,58 @@ return $.widget( "ui.calendar", { return content; }, - _buildButtons: function() { - return "
        " + - "" + - "
        "; + _createButtonPane: function() { + this.buttonPane = $( "
        " ) + .addClass( "ui-calendar-buttonpane ui-widget-content ui-helper-clearfix" ); + + this.buttonSet = $( "
        " ) + .addClass( "ui-calendar-buttonset" ) + .appendTo( this.buttonPane ); + + this._createButtons(); + }, + + _createButtons: function() { + var that = this, + buttons = this.options.buttons; + + // if we already have a button pane, remove it + this.buttonPane.remove(); + this.buttonSet.empty(); + + if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) { + this.element.removeClass( "ui-dialog-buttons" ); + return; + } + + $.each( buttons, function( name, props ) { + var click, buttonOptions; + props = $.isFunction( props ) ? + { click: props, text: name } : + props; + // Default to a non-submitting button + props = $.extend( { type: "button" }, props ); + // Change the context for the click callback to be the main element + click = props.click; + props.click = function() { + click.apply( that._buttonClickContext(), arguments ); + }; + buttonOptions = { + icons: props.icons, + text: props.showText + }; + delete props.icons; + delete props.showText; + $( "", props ) + .button( buttonOptions ) + .appendTo( that.buttonSet ); + }); + this.element.addClass( "ui-dialog-buttons" ); + this.buttonPane.appendTo( this.element ); + }, + + _buttonClickContext: function() { + return this.element[ 0 ]; }, // Refreshing the entire calendar during interaction confuses screen readers, specifically @@ -476,6 +522,10 @@ return $.widget( "ui.calendar", { this._super( key, value ); + if ( key === "buttons" ) { + this._createButtons(); + } + if ( key === "eachDay" ) { this.date.eachDay = value; this.refresh(); From 22e29af00184aa792a8782125effb622d135227d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 00:15:39 +0200 Subject: [PATCH 156/172] Datepicker: Add buttons option --- demos/datepicker/buttonbar.html | 11 ++++++++++- ui/datepicker.js | 6 +++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/demos/datepicker/buttonbar.html b/demos/datepicker/buttonbar.html index 0343d36f523..73e7c870ce5 100644 --- a/demos/datepicker/buttonbar.html +++ b/demos/datepicker/buttonbar.html @@ -18,7 +18,16 @@ diff --git a/ui/datepicker.js b/ui/datepicker.js index e4424bd1597..c58e4d47e4b 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -27,7 +27,7 @@ }(function( $ ) { var widget, - calendarOptions = [ "dateFormat", "eachDay", "max", "min", "numberOfMonths", "showWeek" ]; + calendarOptions = [ "buttons", "dateFormat", "eachDay", "max", "min", "numberOfMonths", "showWeek" ]; widget = $.widget( "ui.datepicker", { version: "@VERSION", @@ -91,6 +91,10 @@ widget = $.widget( "ui.datepicker", { }) ) .calendar( "instance" ); + this.calendarInstance._buttonClickContext = function() { + return that.element[ 0 ]; + }; + this._setHiddenPicker(); this.element.attr({ From 422f798a52a66c30eb17d427afb3c5866d906c3e Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 00:23:24 +0200 Subject: [PATCH 157/172] Datepicker tests: Rework structure unit tests for buttons option --- tests/unit/datepicker/datepicker_common.js | 1 + tests/unit/datepicker/datepicker_core.js | 43 ++++++++++++++-------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/tests/unit/datepicker/datepicker_common.js b/tests/unit/datepicker/datepicker_common.js index 4a2ece05da8..fb4f8d340fd 100644 --- a/tests/unit/datepicker/datepicker_common.js +++ b/tests/unit/datepicker/datepicker_common.js @@ -1,6 +1,7 @@ TestHelpers.commonWidgetTests( "datepicker", { defaults: { appendTo: null, + buttons: [], dateFormat: { date: "short" }, disabled: false, eachDay: $.noop, diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index e442115e041..342262d6074 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -20,9 +20,9 @@ test( "input's value determines starting date", function() { }); asyncTest( "baseStructure", function() { - expect( 23 ); + expect( 27 ); - var header, title, table, thead, week, child, + var header, title, table, thead, week, child, buttonpane, inp = TestHelpers.datepicker.initNewInput(), dp = inp.datepicker( "widget" ); @@ -33,7 +33,7 @@ asyncTest( "baseStructure", function() { ok( dp.is( ":visible" ), "Structure - datepicker visible" ); ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" ); ok( !dp.is( ".ui-calendar-multi" ), "Structure - not multi-month" ); - equal( dp.children().length, 3, "Structure - child count (header, calendar, buttonpane)" ); + equal( dp.children().length, 2, "Structure - child count (header, calendar)" ); header = dp.children( ":first" ); ok( header.is( "div.ui-calendar-header" ), "Structure - header division" ); @@ -61,19 +61,39 @@ asyncTest( "baseStructure", function() { ok( week.is( "tr" ), "Structure - month table week row" ); equal( week.children().length, 7, "Structure - week child count" ); - inp.datepicker( "close" ).datepicker( "destroy" ); + inp.datepicker( "close" ); step2(); }, 50 ); } function step2() { + inp.datepicker( "option", "buttons", { + "test": function() {}, + "test button": function() {} + }); + inp.focus(); + + setTimeout(function() { + equal( dp.children().length, 3, "Structure buttons - child count (header, calendar, buttonpane)" ); + + buttonpane = dp.children( ".ui-calendar-buttonpane" ); + equal( buttonpane.children( "div.ui-calendar-buttonset" ).length, 1, "Structure buttons - buttonset" ); + equal( buttonpane.find( "button.ui-button:first" ).text(), "test", "Structure buttons - buttonset" ); + equal( buttonpane.find( "button.ui-button:eq(1)" ).text(), "test button", "Structure buttons - buttonset" ); + + inp.datepicker( "close" ).datepicker( "destroy" ); + step3(); + }, 50 ); + } + + function step3() { // Multi-month 2 inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 2 } ); dp = inp.datepicker( "widget" ); inp.focus(); setTimeout(function() { ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" ); - equal( dp.children().length, 4, "Structure multi [2] - child count" ); + equal( dp.children().length, 3, "Structure multi [2] - child count" ); child = dp.children( ":eq(2)" ); ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" ); @@ -430,7 +450,7 @@ test( "ARIA", function() { }); asyncTest( "mouse", function() { - expect( 10 ); + expect( 9 ); var input = TestHelpers.datepicker.init( $( "#datepicker" ).val( "" ) ), picker = input.datepicker( "widget" ), @@ -477,16 +497,7 @@ asyncTest( "mouse", function() { "Mouse click - abandoned" ); - // Current/previous/next - input.val( "" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-current", picker ).simulate( "click", {} ); - date.setDate( new Date().getDate() ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - date, - "Mouse click - current" - ); - + // Previous/next input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); $( ".ui-calendar-prev", picker ).simulate( "click" ); $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); From 764305c4aa3884a268e74665be97007928f85182 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 00:26:04 +0200 Subject: [PATCH 158/172] Datepicker: Remove outdated localization tests --- tests/unit/datepicker/datepicker_options.js | 31 --------------------- 1 file changed, 31 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 6432c8eddcc..7ab21b9d4a2 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -469,37 +469,6 @@ test( "daylightSaving", function() { $( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" ); equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" ); }); - -// TODO: Move to calendar. Perhaps adda calendar_external test file? -test( "localization", function() { - expect( 24 ); - var dp, month, day, date, - inp = TestHelpers.datepicker.init( "#inp", $.datepicker.regional.fr); - inp.datepicker( "option", {dateFormat: "DD, d MM yy", showButtonPanel:true, changeMonth:true, changeYear:true}).val( "" ).datepicker( "show" ); - dp = $( "#ui-datepicker-div" ); - equal($( ".ui-calendar-close", dp).text(), "Fermer", "Localisation - close" ); - $( ".ui-calendar-close", dp).simulate( "mouseover" ); - equal($( ".ui-calendar-prev", dp).text(), "Précédent", "Localisation - previous" ); - equal($( ".ui-calendar-current", dp).text(), "Aujourd'hui", "Localisation - current" ); - equal($( ".ui-calendar-next", dp).text(), "Suivant", "Localisation - next" ); - month = 0; - $( ".ui-calendar-month option", dp).each(function() { - equal($(this).text(), $.datepicker.regional.fr.monthNamesShort[month], - "Localisation - month " + month); - month++; - }); - day = 1; - $( ".ui-calendar-calendar th", dp).each(function() { - equal($(this).text(), $.datepicker.regional.fr.dayNamesMin[day], - "Localisation - day " + day); - day = (day + 1) % 7; - }); - inp.simulate( "keydown", {keyCode: $.ui.keyCode.ENTER}); - date = new Date(); - equal(inp.val(), $.datepicker.regional.fr.dayNames[date.getDay()] + ", " + - date.getDate() + " " + $.datepicker.regional.fr.monthNames[date.getMonth()] + - " " + date.getFullYear(), "Localisation - formatting" ); -}); */ test( "Ticket 7602: Stop datepicker from appearing with beforeOpen event handler", function() { From fd88d79b5bed474c702b1b6aa3869c45e959b018 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 00:38:06 +0200 Subject: [PATCH 159/172] Calendar: Fix wrong class in _createButtons method --- ui/calendar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index b795a01e524..8043b11fbd9 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -381,7 +381,7 @@ return $.widget( "ui.calendar", { this.buttonSet.empty(); if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) { - this.element.removeClass( "ui-dialog-buttons" ); + this.element.removeClass( "ui-calendar-buttons" ); return; } @@ -407,7 +407,7 @@ return $.widget( "ui.calendar", { .button( buttonOptions ) .appendTo( that.buttonSet ); }); - this.element.addClass( "ui-dialog-buttons" ); + this.element.addClass( "ui-calendar-buttons" ); this.buttonPane.appendTo( this.element ); }, From 546565b9f4b58016acce422622dc6d021ff70f5a Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 00:38:39 +0200 Subject: [PATCH 160/172] Datepicker: Add option unit tests for buttons option --- tests/unit/datepicker/datepicker_options.js | 96 +++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 7ab21b9d4a2..1a32348cde9 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -40,6 +40,102 @@ test( "appendTo", function() { input.datepicker( "destroy" ); }); +test("buttons", function() { + expect(21); + + var btn, i, newButtons, + buttons = { + "Ok": function( ev ) { + ok(true, "button click fires callback"); + equal(this, element[0], "context of callback"); + equal(ev.target, btn[0], "event target"); + }, + "Cancel": function( ev ) { + ok(true, "button click fires callback"); + equal(this, element[0], "context of callback"); + equal(ev.target, btn[1], "event target"); + } + }, + element = $( "#datepicker" ).datepicker({ buttons: buttons }); + + btn = element.datepicker( "widget" ).find( ".ui-calendar-buttonpane button" ); + equal( btn.length, 2, "number of buttons" ); + + i = 0; + $.each( buttons, function( key ) { + equal( btn.eq( i ).text(), key, "text of button " + ( i + 1 ) ); + i++; + }); + + ok( btn.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container"); + ok( element.datepicker( "widget" ).hasClass( "ui-calendar-buttons" ), "calendar wrapper adds class about having buttons" ); + + btn.trigger("click"); + + newButtons = { + "Close": function( ev ) { + ok(true, "button click fires callback"); + equal(this, element[0], "context of callback"); + equal(ev.target, btn[0], "event target"); + } + }; + + deepEqual(element.datepicker( "option", "buttons" ), buttons, ".datepicker('option', 'buttons') getter" ); + element.datepicker( "option", "buttons", newButtons ); + deepEqual(element.datepicker( "option", "buttons" ), newButtons, ".datepicker('option', 'buttons', ...) setter" ); + + btn = element.datepicker( "widget" ).find( ".ui-calendar-buttonpane button" ); + equal(btn.length, 1, "number of buttons after setter"); + btn.trigger("click"); + + i = 0; + $.each(newButtons, function( key ) { + equal(btn.eq(i).text(), key, "text of button " + (i+1)); + i += 1; + }); + + element.datepicker( "option", "buttons", null ); + btn = element.datepicker( "widget" ).find( ".ui-calendar-buttonpane button" ); + equal( btn.length, 0, "all buttons have been removed" ); + equal( element.find( ".ui-calendar-buttonset").length, 0, "buttonset has been removed" ); + equal( element.parent().hasClass( "ui-calendar-buttons" ), false, "dialog wrapper removes class about having buttons" ); + + element.remove(); +}); + +test("buttons - advanced", function() { + expect( 7 ); + + var buttons, + element = $( "#datepicker" ).datepicker({ + buttons: [ + { + text: "a button", + "class": "additional-class", + id: "my-button-id", + click: function() { + equal(this, element[0], "correct context"); + }, + icons: { + primary: "ui-icon-cancel" + }, + showText: false + } + ] + }); + + buttons = element.datepicker( "widget" ).find( ".ui-calendar-buttonpane button" ); + equal(buttons.length, 1, "correct number of buttons"); + equal(buttons.attr("id"), "my-button-id", "correct id"); + equal(buttons.text(), "a button", "correct label"); + ok(buttons.hasClass("additional-class"), "additional classes added"); + deepEqual( buttons.button("option", "icons"), { primary: "ui-icon-cancel", secondary: null } ); + equal( buttons.button( "option", "text" ), false ); + buttons.click(); + + element.remove(); +}); + test( "dateFormat", function() { expect( 2 ); var input = $( "#datepicker" ).val( "1/1/14" ).datepicker(), From 37377a586ff637bd35ba3f431ff41ace70cf48a7 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 01:01:16 +0200 Subject: [PATCH 161/172] Datepicker: Fix multiple calendar styles (follow-up) --- themes/base/calendar.css | 3 ++- themes/base/datepicker.css | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/themes/base/calendar.css b/themes/base/calendar.css index f7ff0645473..5925814bbff 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -110,7 +110,8 @@ /* with multiple calendars */ .ui-calendar.ui-calendar-multi { - width: auto + width: auto; + display: inline-block; } .ui-calendar-multi .ui-calendar-group { float: left; diff --git a/themes/base/datepicker.css b/themes/base/datepicker.css index 4fde1fdcf56..ac84f640dee 100644 --- a/themes/base/datepicker.css +++ b/themes/base/datepicker.css @@ -8,7 +8,7 @@ * * http://api.jqueryui.com/datepicker/#theming */ -.ui-datepicker { +.ui-datepicker.ui-calendar { display: none; position: absolute; } \ No newline at end of file From 86ca70b35226d0a0ad2bdc12493b991dfbe9160d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 01:03:19 +0200 Subject: [PATCH 162/172] Datepicker: Remove duplicate demos --- demos/datepicker/buttonbar.html | 43 --------------------- demos/datepicker/date-range.html | 46 ----------------------- demos/datepicker/dropdown-month-year.html | 35 ----------------- demos/datepicker/index.html | 7 ---- demos/datepicker/min-max.html | 39 ------------------- demos/datepicker/multiple-months.html | 35 ----------------- demos/datepicker/other-months.html | 41 -------------------- demos/datepicker/show-week.html | 36 ------------------ 8 files changed, 282 deletions(-) delete mode 100644 demos/datepicker/buttonbar.html delete mode 100644 demos/datepicker/date-range.html delete mode 100644 demos/datepicker/dropdown-month-year.html delete mode 100644 demos/datepicker/min-max.html delete mode 100644 demos/datepicker/multiple-months.html delete mode 100644 demos/datepicker/other-months.html delete mode 100644 demos/datepicker/show-week.html diff --git a/demos/datepicker/buttonbar.html b/demos/datepicker/buttonbar.html deleted file mode 100644 index 73e7c870ce5..00000000000 --- a/demos/datepicker/buttonbar.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - jQuery UI Datepicker - Display button bar - - - - - - - - - - - - - - - - -

        Date:

        - -
        -

        Display a button for selecting Today's date and a Done button for closing the calendar with the boolean showButtonPanel option. Each button is enabled by default when the bar is displayed, but can be turned off with additional options. Button text is customizable.

        -
        - - diff --git a/demos/datepicker/date-range.html b/demos/datepicker/date-range.html deleted file mode 100644 index efc3652dcbc..00000000000 --- a/demos/datepicker/date-range.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - jQuery UI Datepicker - Select a Date Range - - - - - - - - - - - - - - - - - - - - - -
        -

        Select the date range to search for.

        -
        - - diff --git a/demos/datepicker/dropdown-month-year.html b/demos/datepicker/dropdown-month-year.html deleted file mode 100644 index bd6a260162b..00000000000 --- a/demos/datepicker/dropdown-month-year.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - jQuery UI Datepicker - Display month & year menus - - - - - - - - - - - - - - - - -

        Date:

        - -
        -

        Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes. Add the boolean changeMonth and changeYear options.

        -
        - - diff --git a/demos/datepicker/index.html b/demos/datepicker/index.html index ec9e94788cf..5587564831f 100644 --- a/demos/datepicker/index.html +++ b/demos/datepicker/index.html @@ -11,16 +11,9 @@
      33. Default functionality
      34. Populate alternate field
      35. Animations
      36. -
      37. Display button bar
      38. Format date
      39. -
      40. Date Range
      41. -
      42. Display month & year menus
      43. Icon trigger
      44. Localize calendar
      45. -
      46. Restrict date range
      47. -
      48. Dates in other months
      49. -
      50. Display multiple months
      51. -
      52. Show week of the year
      53. diff --git a/demos/datepicker/min-max.html b/demos/datepicker/min-max.html deleted file mode 100644 index 47343a19618..00000000000 --- a/demos/datepicker/min-max.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - jQuery UI Datepicker - Restrict date range - - - - - - - - - - - - - - - - -

        Date:

        - -
        -

        Restrict the range of selectable dates with the min and max options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)).

        -
        - - diff --git a/demos/datepicker/multiple-months.html b/demos/datepicker/multiple-months.html deleted file mode 100644 index ad6d7218559..00000000000 --- a/demos/datepicker/multiple-months.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - jQuery UI Datepicker - Display multiple months - - - - - - - - - - - - - - - - -

        Date:

        - -
        -

        Set the numberOfMonths option to an integer of 2 or more to show multiple months in a single datepicker.

        -
        - - diff --git a/demos/datepicker/other-months.html b/demos/datepicker/other-months.html deleted file mode 100644 index e3eed39b5d1..00000000000 --- a/demos/datepicker/other-months.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - jQuery UI Datepicker - Dates in other months - - - - - - - - - - - - - - - - -

        Date:

        - -
        -

        The datepicker can show dates that come from other than the main month - being displayed. These other dates can also be made selectable.

        -
        - - diff --git a/demos/datepicker/show-week.html b/demos/datepicker/show-week.html deleted file mode 100644 index 9dbd09d6acb..00000000000 --- a/demos/datepicker/show-week.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - jQuery UI Datepicker - Show week of the year - - - - - - - - - - - - - - - - -

        Date:

        - -
        -

        The datepicker can show the week of the year. The calculation follows - Unicode CLDR specification. - This means that some days from one year may be placed into weeks 'belonging' to another year.

        -
        - - From ef3a30cb6fe43315969e0f035da82faa34256d3e Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 01:04:34 +0200 Subject: [PATCH 163/172] Calendar: Rename multiple calendars demo to multiple months (follow-up) --- demos/calendar/index.html | 2 +- demos/calendar/{multiple-month.html => multiple-months.html} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename demos/calendar/{multiple-month.html => multiple-months.html} (100%) diff --git a/demos/calendar/index.html b/demos/calendar/index.html index 0335beacb74..a6f0f5e7ac5 100644 --- a/demos/calendar/index.html +++ b/demos/calendar/index.html @@ -14,7 +14,7 @@
      54. Display month & year menus
      55. Localize calendar
      56. Restrict date range
      57. -
      58. Display multiple months
      59. +
      60. Display multiple months
      61. Dates in other months
      62. Show week of the year
      63. diff --git a/demos/calendar/multiple-month.html b/demos/calendar/multiple-months.html similarity index 100% rename from demos/calendar/multiple-month.html rename to demos/calendar/multiple-months.html From b547f3a729a343590522f8a0fcde76fb06165c59 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 01:11:35 +0200 Subject: [PATCH 164/172] Calendar: Remove unneeded image --- demos/calendar/images/calendar.gif | Bin 258 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 demos/calendar/images/calendar.gif diff --git a/demos/calendar/images/calendar.gif b/demos/calendar/images/calendar.gif deleted file mode 100644 index 52f2863c90764cabb11ac926b3f7e02b9b9e5e49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 258 zcmZ?wbh9u|6ky<+Y9vrwbI($!DTUl#W73z|)4nX4`*rp5ZyQ#B-@379)%)KM@Be-M>hGtI|Gs_w|L4#D z|Nj|~fDVWavWtPW{Q*md3PbOU5QXTA``&Hf+-&MQNyN4Pv4TT$qr;4tz7x@TlA2nj z{VVh>rsSCQXN#@AXk#?9q4e^OX(ylcxawre$mLbEZVWhZ^wyuYi=i=Ui~?zCvD{J; zob`>l`Gve(T%4S?jg@f;{OB2!bOQWALGdFOQVvkR?QwQ_|pZzJQT&0DrAGFSru Doau8X From 632adc6f0b68689ec58e66f4745caaa9c2462d0e Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 17:46:24 +0200 Subject: [PATCH 165/172] Calendar tests: Rewrite core unit tests based on datepicker tests Remove duplicated core unit tests from datepicker tests. --- tests/unit/calendar/calendar.html | 9 +- tests/unit/calendar/calendar_core.js | 896 ++++++------------- tests/unit/calendar/calendar_test_helpers.js | 18 +- tests/unit/datepicker/datepicker_core.js | 407 +++------ 4 files changed, 402 insertions(+), 928 deletions(-) diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html index 5a5256a6bab..022dc42ded1 100644 --- a/tests/unit/calendar/calendar.html +++ b/tests/unit/calendar/calendar.html @@ -19,8 +19,7 @@ "ui/core.js", "ui/widget.js", "ui/button.js", - "ui/calendar.js", - "ui/position.js" + "ui/calendar.js" ] }); @@ -39,10 +38,8 @@
        - - - -
        +
        +
        diff --git a/tests/unit/calendar/calendar_core.js b/tests/unit/calendar/calendar_core.js index 18f00274ec3..49278345753 100644 --- a/tests/unit/calendar/calendar_core.js +++ b/tests/unit/calendar/calendar_core.js @@ -4,708 +4,388 @@ module( "calendar: core" ); TestHelpers.testJshint( "calendar" ); -test( "input's value determines starting date", function() { - expect( 3 ); +test( "baseStructure", function() { + expect( 26 ); - var input = $( "#calendar" ).val( "1/1/14" ).calendar(), - picker = input.calendar( "widget" ); - - input.calendar( "open" ); - - equal( picker.find( ".ui-calendar-month" ).html(), "January", "correct month displayed" ); - equal( picker.find( ".ui-calendar-year" ).html(), "2014", "correct year displayed" ); - equal( picker.find( ".ui-state-focus" ).html(), "1", "correct day highlighted" ); - - input.val( "" ).calendar( "destroy" ); -}); - -asyncTest( "baseStructure", function() { - expect( 42 ); - var header, title, table, thead, week, panel, inl, child, - inp = TestHelpers.calendar.initNewInput(), - dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + var header, title, table, thead, week, child, buttonpane, + element = $( "#calendar" ).calendar(), + dp = element.calendar( "widget" ); function step1() { - inp.focus(); - setTimeout(function() { - ok( dp.is( ":visible" ), "Structure - calendar visible" ); - ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" ); - ok( !dp.is( ".ui-calendar-multi" ), "Structure - not multi-month" ); - equal( dp.children().length, 3, "Structure - child count (header, calendar, buttonpane)" ); - - header = dp.children( ":first" ); - ok( header.is( "div.ui-calendar-header" ), "Structure - header division" ); - equal( header.children().length, 3, "Structure - header child count" ); - ok( header.children( ":first" ).is( ".ui-calendar-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); - ok( header.children( ":eq(1)" ).is( ".ui-calendar-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); - - title = header.children( ":last" ).children( ":first" ); - ok( title.is( "div.ui-calendar-title" ) && title.html() !== "", "Structure - title division" ); - equal( title.children().length, 2, "Structure - title child count" ); - ok( title.children( ":first" ).is( "span.ui-calendar-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); - ok( title.children( ":last" ).is( "span.ui-calendar-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); - - table = dp.children( ":eq(1)" ); - ok( table.is( "table.ui-calendar-calendar" ), "Structure - month table" ); - ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); - - thead = table.children( ":first" ).children( ":first" ); - ok( thead.is( "tr" ), "Structure - month table title row" ); - equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); - ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" ); - ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" ); - - week = table.children( ":eq(1)" ).children( ":first" ); - ok( week.is( "tr" ), "Structure - month table week row" ); - equal( week.children().length, 7, "Structure - week child count" ); - // TODO: Preserve these class names or let the user use :first-child and :last-child? - // ok( week.children( ":first" ).is( "td.ui-calendar-week-end" ), "Structure - month table first day cell" ); - // ok( week.children( ":last" ).is( "td.ui-calendar-week-end" ), "Structure - month table second day cell" ); - - inp.calendar( "close" ).calendar( "destroy" ); - step2(); - }); - } - - function step2() { - // Editable month/year and button panel - inp = TestHelpers.calendar.initNewInput({ - changeMonth: true, - changeYear: true, - showButtonPanel: true - }); - dp = inp.calendar( "widget" ).find( ".ui-calendar" ); - inp.focus(); - setTimeout(function() { - title = dp.find( "div.ui-calendar-title" ); - // TODO: Re-add tests when changeMonth and changeYear are re-implemented - //ok( title.children( ":first" ).is( "select.ui-calendar-month" ), "Structure - month selector" ); - //ok( title.children( ":last" ).is( "select.ui-calendar-year" ), "Structure - year selector" ); - - panel = dp.children( ":last" ); - ok( panel.is( "div.ui-calendar-buttonpane" ), "Structure - button panel division" ); - equal( panel.children().length, 2, "Structure - button panel child count" ); - ok( panel.children( ":first" ).is( "button.ui-calendar-current" ), "Structure - today button" ); - ok( panel.children( ":last" ).is( "button.ui-calendar-close" ), "Structure - close button" ); - - inp.calendar( "close" ).calendar( "destroy" ); - step3(); - }); - } - - function step3() { - // Multi-month 2 - inp = TestHelpers.calendar.initNewInput({ numberOfMonths: 2 } ); - dp = inp.calendar( "widget" ).find( ".ui-calendar" ); - inp.focus(); - setTimeout(function() { - ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" ); - equal( dp.children().length, 4, "Structure multi [2] - child count" ); - - child = dp.children( ":first" ); - // TODO: Implement ui-calendar-group-first class name - // ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-first" ), "Structure multi [2] - first month division" ); - - child = dp.children( ":eq(1)" ); - // TODO: Implement ui-calendar-group-last class name - // ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-last" ), "Structure multi [2] - second month division" ); - - child = dp.children( ":eq(2)" ); - ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" ); - ok( dp.is( ".ui-calendar-multi-2" ), "Structure multi [2] - multi-2" ); - - inp.calendar( "close" ).calendar( "destroy" ); - step4(); - }); - } - - function step4() { - // Multi-month 3 - inp = TestHelpers.calendar.initNewInput({ numberOfMonths: 3 } ); - dp = inp.calendar( "widget" ).find( ".ui-calendar" ); - inp.focus(); - setTimeout(function() { - ok( dp.is( ".ui-calendar-multi-3" ), "Structure multi [3] - multi-3" ); - ok( !dp.is( ".ui-calendar-multi-2" ), "Structure multi [3] - Trac #6704" ); - - inp.calendar( "close" ).calendar( "destroy" ); - step5(); - }); - } - - function step5() { - // Multi-month [2, 2] - inp = TestHelpers.calendar.initNewInput({ numberOfMonths: [ 2, 2 ] } ); - dp = inp.calendar( "widget" ).find( ".ui-calendar" ); - inp.focus(); - setTimeout(function() { - /* - TODO: Re-add after array form of the numberOfMonths option is implemented. - ok( dp.is( ".ui-calendar-multi" ), "Structure multi - multi-month" ); - equal( dp.children().length, 6, "Structure multi [2,2] - child count" ); - - child = dp.children( ":first" ); - ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-first" ), "Structure multi [2,2] - first month division" ); - - child = dp.children( ":eq(1)" ); - ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-last" ), "Structure multi [2,2] - second month division" ); - - child = dp.children( ":eq(2)" ); - ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2,2] - row break" ); - - child = dp.children( ":eq(3)" ); - ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-first" ), "Structure multi [2,2] - third month division" ); - - child = dp.children( ":eq(4)" ); - ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-last" ), "Structure multi [2,2] - fourth month division" ); - - child = dp.children( ":eq(5)" ); - ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2,2] - row break" ); - */ - inp.calendar( "close" ).calendar( "destroy" ); - step6(); - }); - } - - function step6() { - // Inline - inl = TestHelpers.calendar.init( "#inline" ); - dp = inl.children(); - - ok( dp.is( ".ui-calendar-inline" ), "Structure inline - main div" ); - ok( !dp.is( ".ui-calendar-rtl" ), "Structure inline - not right-to-left" ); - ok( !dp.is( ".ui-calendar-multi" ), "Structure inline - not multi-month" ); - equal( dp.children().length, 3, "Structure inline - child count (header, calendar, buttonpane)" ); + ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" ); + ok( !dp.is( ".ui-calendar-multi" ), "Structure - not multi-month" ); + equal( dp.children().length, 2, "Structure - child count (header, calendar)" ); header = dp.children( ":first" ); - ok( header.is( "div.ui-calendar-header" ), "Structure inline - header division" ); - equal( header.children().length, 3, "Structure inline - header child count" ); - - table = dp.children( ":eq(1)" ); - ok( table.is( "table.ui-calendar-calendar" ), "Structure inline - month table" ); - ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" ); - ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" ); - - inl.calendar( "destroy" ); - - step7(); - } - - function step7() { - // Inline multi-month - inl = TestHelpers.calendar.init( "#inline", { numberOfMonths: 2 } ); - dp = inl.calendar( "widget" ).find( ".ui-calendar" ); - - ok( dp.is( ".ui-calendar-inline" ) && dp.is( ".ui-calendar-multi" ), "Structure inline multi - main div" ); - equal( dp.children().length, 4, "Structure inline multi - child count" ); - - child = dp.children( ":first" ); - // TODO: Implement ui-calendar-group-first class name - // ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-first" ), "Structure inline multi - first month division" ); - - child = dp.children( ":eq(1)" ); - // TODO: Implement ui-calendar-group-last class name - // ok( child.is( "div.ui-calendar-group" ) && child.is( "div.ui-calendar-group-last" ), "Structure inline multi - second month division" ); - - child = dp.children( ":eq(2)" ); - ok( child.is( "div.ui-calendar-row-break" ), "Structure inline multi - row break" ); - - inl.calendar( "destroy" ); - start(); - } - - step1(); -}); + ok( header.is( "div.ui-calendar-header" ), "Structure - header division" ); + equal( header.children().length, 3, "Structure - header child count" ); + ok( header.children( ":first" ).is( ".ui-calendar-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); + ok( header.children( ":eq(1)" ).is( ".ui-calendar-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); -// Skip these tests for now as none are implemented yet. -/* -asyncTest( "customStructure", function() { - expect( 0 ); + title = header.children( ":last" ).children( ":first" ); + ok( title.is( "div.ui-calendar-title" ) && title.html() !== "", "Structure - title division" ); + equal( title.children().length, 2, "Structure - title child count" ); + ok( title.children( ":first" ).is( "span.ui-calendar-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); + ok( title.children( ":last" ).is( "span.ui-calendar-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); - var header, panel, title, - inp = TestHelpers.calendar.initNewInput(), - dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + table = dp.children( ":eq(1)" ); + ok( table.is( "table.ui-calendar-calendar" ), "Structure - month table" ); + ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); - start(); + thead = table.children( ":first" ).children( ":first" ); + ok( thead.is( "tr" ), "Structure - month table title row" ); + equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); + ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" ); + ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" ); - function step1() { - Globalize.culture( "he" ); - inp.focus(); + week = table.children( ":eq(1)" ).children( ":first" ); + ok( week.is( "tr" ), "Structure - month table week row" ); + equal( week.children().length, 7, "Structure - week child count" ); - setTimeout(function() { - ok( dp.is( ".ui-calendar-rtl" ), "Structure RTL - right-to-left" ); - - header = dp.children( ":first" ); - ok( header.is( "div.ui-calendar-header" ), "Structure RTL - header division" ); - equal( header.children().length, 3, "Structure RTL - header child count" ); - ok( header.children( ":first" ).is( "a.ui-calendar-next" ), "Structure RTL - prev link" ); - ok( header.children( ":eq(1)" ).is( "a.ui-calendar-prev" ), "Structure RTL - next link" ); - - panel = dp.children( ":last" ); - ok( panel.is( "div.ui-calendar-buttonpane" ), "Structure RTL - button division" ); - equal( panel.children().length, 2, "Structure RTL - button panel child count" ); - ok( panel.children( ":first" ).is( "button.ui-calendar-close" ), "Structure RTL - close button" ); - ok( panel.children( ":last" ).is( "button.ui-calendar-current" ), "Structure RTL - today button" ); - - inp.calendar( "close" ).calendar( "destroy" ); - Globalize.culture( "en-US" ); - step2(); - }); + step2(); } - // Hide prev/next - // TODO: If we decide the hideIfNoPrevNext option is being removed these tests can be as well. - function stepX() { - inp = TestHelpers.calendar.initNewInput({ - hideIfNoPrevNext: true, - minDate: new Date( 2008, 2 - 1, 4 ), - maxDate: new Date( 2008, 2 - 1, 14 ) - }); - inp.val( "02/10/2008" ); - - TestHelpers.calendar.onFocus( inp, function() { - header = dp.children( ":first" ); - ok( header.is( "div.ui-calendar-header" ), "Structure hide prev/next - header division" ); - equal( header.children().length, 1, "Structure hide prev/next - links child count" ); - ok( header.children( ":first" ).is( "div.ui-calendar-title" ), "Structure hide prev/next - title division" ); - - inp.calendar( "hide" ).calendar( "destroy" ); - step3(); - }); - } - - // Changeable Month with read-only year function step2() { - inp = TestHelpers.calendar.initNewInput({ changeMonth: true } ); - dp = inp.calendar( "widget" ).find( ".ui-calendar" ); + element.calendar( "option", "buttons", { + "test": function() {}, + "test button": function() {} + }); - inp.focus(); - setTimeout(function() { - title = dp.children( ":first" ).children( ":last" ); + equal( dp.children().length, 3, "Structure buttons - child count (header, calendar, buttonpane)" ); - // TODO: Implement changeMonth option - // equal( title.children().length, 2, "Structure changeable month - title child count" ); - // ok( title.children( ":first" ).is( "select.ui-calendar-month" ), "Structure changeable month - month selector" ); - // ok( title.children( ":last" ).is( "span.ui-calendar-year" ), "Structure changeable month - read-only year" ); + buttonpane = dp.children( ".ui-calendar-buttonpane" ); + equal( buttonpane.children( "div.ui-calendar-buttonset" ).length, 1, "Structure buttons - buttonset" ); + equal( buttonpane.find( "button.ui-button:first" ).text(), "test", "Structure buttons - buttonset" ); + equal( buttonpane.find( "button.ui-button:eq(1)" ).text(), "test button", "Structure buttons - buttonset" ); - inp.calendar( "close" ).calendar( "destroy" ); - step3(); - }); + element.calendar( "destroy" ); + step3(); } - // Changeable year with read-only month function step3() { - inp = TestHelpers.calendar.initNewInput({ changeYear: true } ); + // Multi-month 2 + element = $( "#calendar" ).calendar( { numberOfMonths: 2 } ); + dp = element.calendar( "widget" ); - TestHelpers.calendar.onFocus( inp, function() { - title = dp.children( ":first" ).children( ":last" ); + ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" ); + equal( dp.children().length, 3, "Structure multi [2] - child count" ); - // TODO: Implement changeYear option - // equal( title.children().length, 2, "Structure changeable year - title child count" ); - // ok( title.children( ":first" ).is( "span.ui-calendar-month" ), "Structure changeable year - read-only month" ); - // ok( title.children( ":last" ).is( "select.ui-calendar-year" ), "Structure changeable year - year selector" ); + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" ); - inp.calendar( "close" ).calendar( "destroy" ); - start(); - }); + element.calendar( "destroy" ); } - // TODO: figure out why this setTimeout is needed in IE, - // it only is necessary when the previous baseStructure tests runs first - // Support: IE - setTimeout( step1 ); + step1(); }); -*/ - -test( "Keyboard handling", function() { - expect( 9 ); - var input = $( "#calendar" ).calendar(), - instance = input.calendar( "instance" ), - date = new Date(); - input.calendar( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, "Keystroke enter" ); - - // Enter = Select today's date by default - input.val( "1/1/14" ).calendar( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), - "Keystroke enter - preset" ); - - // Control + Home = Change the calendar to the current month - input.val( "1/1/14" ).calendar( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, "Keystroke ctrl+home" ); - - // Control + End = Close the calendar and clear the input - input.val( "1/1/14" ).calendar( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); - equal( input.val(), "", "Keystroke ctrl+end" ); - - input.val( "" ).calendar( "open" ); - ok( instance.isOpen, "calendar is open before escape" ); - input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - ok( !instance.isOpen, "escape closes the calendar" ); - - input.val( "1/1/14" ).calendar( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), - "Keystroke esc - preset" ); - - input.val( "1/1/14" ).calendar( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), - "Keystroke esc - abandoned" ); - - input.val( "1/2/14" ) - .simulate( "keyup" ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2014, 0, 2 ), - "Picker updated as user types into input" ); - - input.calendar( "destroy" ); +test( "Localization", function() { + expect( 10 ); + + var defaultLocale = Globalize.locale(), + element = $( "#calendar" ), + date = new Date( 2014, 0, 1 ), + initCalendar = function() { + element + .calendar() + .calendar( "valueAsDate", date ); + }, + testLocalization = function( message ) { + equal( element.find( ".ui-calendar-month" ).text(), "Januar", message + "titlebar year" ); + equal( element.find( "thead th:first" ).text(), "Mo.", message + "teader first day" ); + equal( element.find( "thead th:last" ).text(), "So.", message + "header last day" ); + equal( element.find( ".ui-calendar-prev" ).text(), "", message + "header next" ); + }; + + Globalize.locale( "de-DE" ); + initCalendar(); + testLocalization( "Init: " ); + element.calendar( "destroy" ); + + Globalize.locale( defaultLocale.locale ); + initCalendar(); + Globalize.locale( "de-DE" ); + element.calendar( "refresh" ); + testLocalization( "After init: " ); + + Globalize.locale( defaultLocale.locale ); }); asyncTest( "keyboard handling", function() { - expect( 14 ); - var picker, - input = $( "#calendar" ), - date = new Date(); + expect( 10 ); + + var element = $( "#calendar" ); function step1() { - input.calendar(); - picker = input.calendar( "widget" ); - ok( !picker.is( ":visible" ), "calendar closed" ); - input.val( "" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); setTimeout(function() { - ok( picker.is( ":visible" ), "Keystroke down opens calendar" ); - input.calendar( "destroy" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2013, 12 - 1, 31 ), + "Keystroke left to switch to previous day" + ); + element.calendar( "destroy" ); step2(); - }); + }, 50 ); } function step2() { - input.calendar(); - picker = input.calendar( "widget" ); - ok( !picker.is( ":visible" ), "calendar closed" ); - input.val( "" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); - - setTimeout(function() { - ok( picker.is( ":visible" ), "Keystroke up opens calendar" ); - input.calendar( "destroy" ); - step3(); - }); + element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + + TestHelpers.calendar.focusGrid( element ) + .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2014, 1 - 1, 2 ), + "Keystroke right to switch to next day" + ); + step3(); } function step3() { - input.calendar() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2013, 12 - 1, 31 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke left to switch to previous day" ); - - input.calendar( "destroy" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2013, 12 - 1, 25 ), + "Keystroke up to move to the previous week" + ); + element.calendar( "destroy" ); step4(); - }, 100 ); + }, 50 ); } function step4() { - input.calendar() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2014, 1 - 1, 2 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke right to switch to next day" ); - - input.calendar( "destroy" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2014, 1 - 1, 8 ), + "Keystroke down to move to the next week" + ); + element.calendar( "destroy" ); step5(); - }, 100 ); + }, 50 ); } function step5() { - input.calendar() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2013, 12 - 1, 25 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke up to move to the previous week" ); - - input.calendar( "destroy" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2013, 12 - 1, 1 ), + "Keystroke Page Up moves date to previous month" + ); + element.calendar( "destroy" ); step6(); - }, 100 ); + }, 50 ); } function step6() { - input.calendar() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + TestHelpers.calendar.focusGrid( element ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2014, 1 - 1, 8 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke down to move to the next week" ); - - input.calendar( "destroy" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2013, 1 - 1, 1 ), + "Keystroke Page Up + Ctrl moves date to previous year" + ); + element.calendar( "destroy" ); step7(); - }, 100 ); + }, 50 ); } function step7() { - input.calendar() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2013, 12 - 1, 1 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke Page Up moves date to previous month" ); - - input.calendar( "destroy" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2014, 2 - 1, 1 ), + "Keystroke Page Down moves date to next month" + ); + element.calendar( "destroy" ); step8(); - }, 100 ); + }, 50 ); } function step8() { - input.calendar() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + TestHelpers.calendar.focusGrid( element ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2013, 1 - 1, 1 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke Page Up + Ctrl moves date to previous year" ); - - input.calendar( "destroy" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2015, 1 - 1, 1 ), + "Keystroke Page Down + Ctrl moves date to next year" + ); + element.calendar( "destroy" ); step9(); - }, 100 ); + }, 50 ); } + // Check for moving to short months function step9() { - input.calendar() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.calendar({ value: new Date( 2014, 3 - 1, 31 ) }); + TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2014, 2 - 1, 1 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke Page Down moves date to next month" ); - - input.calendar( "destroy" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2014, 2 - 1, 28 ), + "Keystroke Page Up and short months" + ); + element.calendar( "destroy" ); step10(); - }, 100 ); + }, 50 ); } function step10() { - input.calendar() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - - setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2015, 1 - 1, 1 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke Page Down + Ctrl moves date to next year" ); - - input.calendar( "destroy" ); - step11(); - }, 100 ); - } - - // Check for moving to short months - function step11() { - input.calendar() - .val( "3/31/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.calendar({ value: new Date( 2016, 1 - 1, 30 ) }); + TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2014, 2 - 1, 28 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke Page Up and short months" ); - - input.calendar( "destroy" ); - step12(); - }, 100 ); - } - - function step12() { - input.calendar() - .val( "1/30/16" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - - setTimeout(function() { - $( ":focus" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2016, 2 - 1, 29 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, - "Keystroke Page Down and leap years" ); - - input.calendar( "destroy" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2016, 2 - 1, 29 ), + "Keystroke Page Down and leap years" + ); + element.calendar( "destroy" ); start(); - }, 100 ); + }, 50 ); } step1(); }); /* - // TODO: Re-add tests if we implement a stepMonths option - input.calendar( "option", { stepMonths: 2, gotoCurrent: false } ) - .calendar( "close" ).val( "02/04/2008" ).calendar( "open" ) - .late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2007, 12 - 1, 4 ), - "Keystroke pgup step 2" ); - - input.val( "02/04/2008" ).calendar( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ), - "Keystroke pgdn step 2" ); -*/ - -test( "mouse", function() { - expect( 13 ); - var input = $( "#calendar" ).calendar(), - picker = input.calendar( "widget" ), - inline = $( "#inline" ).calendar, + // TODO: Re-add tests if we implement a stepMonths option + input.calendar( "option", { stepMonths: 2, gotoCurrent: false } ) + .calendar( "close" ).val( "02/04/2008" ).calendar( "open" ) + .late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( input.calendar( "valueAsDate" ), new Date( 2007, 12 - 1, 4 ), + "Keystroke pgup step 2" ); + + input.val( "02/04/2008" ).calendar( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ), + "Keystroke pgdn step 2" ); + */ + +// TODO: implement +test( "ARIA", function() { + expect( 0 ); +}); + +asyncTest( "mouse", function() { + expect( 6 ); + + var element = $( "#calendar" ).calendar(), date = new Date(); - input.val( "" ).calendar( "open" ); - $( ".ui-calendar-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} ); - date.setDate( 10 ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, "Mouse click" ); - - input.val( "2/4/08" ).calendar( "open" ); - $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), - "Mouse click - preset" ) ; - - input.val( "" ).calendar( "open" ); - $( "button.ui-calendar-close", picker ).simulate( "click", {} ); - ok( input.calendar( "valueAsDate" ) == null, "Mouse click - close" ); - - input.val( "2/4/08" ).calendar( "open" ); - $( "button.ui-calendar-close", picker ).simulate( "click", {} ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), - "Mouse click - close + preset" ); - - input.val( "2/4/08" ).calendar( "open" ); - $( "a.ui-calendar-prev", picker ).simulate( "click", {} ); - $( "button.ui-calendar-close", picker ).simulate( "click", {} ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ), - "Mouse click - abandoned" ); - - // Current/previous/next - input.val( "" ).calendar( "open" ); - $( ".ui-calendar-current", picker ).simulate( "click", {} ); - date.setDate( new Date().getDate() ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), date, "Mouse click - current" ); - - input.val( "2/4/08" ).calendar( "open" ); - $( ".ui-calendar-prev", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), - "Mouse click - previous" ); - - input.val( "2/4/08" ).calendar( "open" ); - $( ".ui-calendar-next", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), - "Mouse click - next" ); - - /* - // TODO: Re-add when min and max options are introduced. + function step1() { + $( "tbody a:contains(10)", element ).simulate( "mousedown", {} ); + date.setDate( 10 ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + date, + "Mouse click" + ); + + element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); + $( ".ui-calendar-calendar tbody a:contains(12)", element ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2008, 2 - 1, 12 ), + "Mouse click - preset" + ); + + // Previous/next + element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); + $( ".ui-calendar-prev", element ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(16)", element ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2008, 1 - 1, 16 ), + "Mouse click - previous" + ); + + element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); + $( ".ui-calendar-next", element ).simulate( "click" ); + $( ".ui-calendar-calendar tbody a:contains(18)", element ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2008, 3 - 1, 18 ), + "Mouse click - next" + ); + + step2(); + } + // Previous/next with minimum/maximum - input.calendar( "option", { - minDate: new Date( 2008, 2 - 1, 2 ), - maxDate: new Date( 2008, 2 - 1, 26 ) - }).val( "2/4/08" ).calendar( "open" ); - $( ".ui-calendar-prev", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 16 ), - "Mouse click - previous + min/max" ); - - input.val( "2/4/08" ).calendar( "open" ); - $( ".ui-calendar-next", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); - TestHelpers.calendar.equalsDate(input.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 18 ), - "Mouse click - next + min/max" ); - */ - - // Inline - inline = TestHelpers.calendar.init( "#inline" ); - picker = $( ".ui-calendar-inline", inline ); - date = new Date(); - inline.calendar( "valueAsDate", date ); - $( ".ui-calendar-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} ); - date.setDate( 10 ); - TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), date, "Mouse click inline" ); - - inline.calendar( "option", { showButtonPanel: true } ) - .calendar( "valueAsDate", new Date( 2008, 2 - 1, 4 )); - $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); - TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), - "Mouse click inline - preset" ); - - inline.calendar( "option", { showButtonPanel: true } ); - $( ".ui-calendar-current", picker ).simulate( "click", {} ); - $( ".ui-calendar-calendar tbody a:contains(14)", picker ).simulate( "mousedown", {} ); - date.setDate( 14 ); - TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), date, "Mouse click inline - current" ); - - inline.calendar( "valueAsDate", new Date( 2008, 2 - 1, 4) ); - $( ".ui-calendar-prev", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); - TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), - "Mouse click inline - previous" ); - - inline.calendar( "valueAsDate", new Date( 2008, 2 - 1, 4) ); - $( ".ui-calendar-next", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); - TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), - "Mouse click inline - next" ); - - input.calendar( "destroy" ); - inline.calendar( "destroy" ); + function step2() { + element.calendar( "destroy" ); + element.calendar({ + value: new Date( 2008, 3 - 1, 4), + min: new Date( 2008, 2 - 1, 2 ), + max: new Date( 2008, 2 - 1, 26 ) + }); + + $( ".ui-calendar-prev", element ).simulate( "click" ); + $( "tbody a:contains(16)", element ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2008, 2 - 1, 16 ), + "Mouse click - previous + min/max" + ); + step3(); + } + + function step3() { + element.calendar( "destroy" ); + element.calendar({ + value: new Date( 2008, 1 - 1, 4), + min: new Date( 2008, 2 - 1, 2 ), + max: new Date( 2008, 2 - 1, 26 ) + }); + + $( ".ui-calendar-next", element ).simulate( "click" ); + $( "tbody a:contains(18)", element ).simulate( "mousedown" ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2008, 2 - 1, 18 ), + "Mouse click - next + min/max" + ); + start(); + } + + step1(); }); })( jQuery ); diff --git a/tests/unit/calendar/calendar_test_helpers.js b/tests/unit/calendar/calendar_test_helpers.js index fa53c408fb6..032a2227ac6 100644 --- a/tests/unit/calendar/calendar_test_helpers.js +++ b/tests/unit/calendar/calendar_test_helpers.js @@ -14,15 +14,11 @@ TestHelpers.calendar = { d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() ); equal( d1.toString(), d2.toString(), message ); }, - init: function( id, options ) { - options = $.extend( { show: false }, options || {} ); - return $( id ).calendar( options ); - }, - initNewInput: function( options ) { - options = $.extend( { show: false }, options || {} ); - return $( "" ).calendar( options ) - .appendTo( "#qunit-fixture" ); - }, - onFocus: TestHelpers.onFocus, - PROP_NAME: "calendar" + focusGrid: function( element ) { + element.find( ":tabbable" ).last().simulate( "focus" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); + + return $( ":focus" ); + } }; \ No newline at end of file diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 342262d6074..71ac0d9cf73 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -20,9 +20,9 @@ test( "input's value determines starting date", function() { }); asyncTest( "baseStructure", function() { - expect( 27 ); + expect( 15 ); - var header, title, table, thead, week, child, buttonpane, + var header, title, table, child, buttonpane, inp = TestHelpers.datepicker.initNewInput(), dp = inp.datepicker( "widget" ); @@ -31,35 +31,19 @@ asyncTest( "baseStructure", function() { setTimeout(function() { ok( dp.is( ":visible" ), "Structure - datepicker visible" ); - ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" ); - ok( !dp.is( ".ui-calendar-multi" ), "Structure - not multi-month" ); equal( dp.children().length, 2, "Structure - child count (header, calendar)" ); header = dp.children( ":first" ); ok( header.is( "div.ui-calendar-header" ), "Structure - header division" ); equal( header.children().length, 3, "Structure - header child count" ); - ok( header.children( ":first" ).is( ".ui-calendar-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); - ok( header.children( ":eq(1)" ).is( ".ui-calendar-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); title = header.children( ":last" ).children( ":first" ); - ok( title.is( "div.ui-calendar-title" ) && title.html() !== "", "Structure - title division" ); equal( title.children().length, 2, "Structure - title child count" ); - ok( title.children( ":first" ).is( "span.ui-calendar-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); - ok( title.children( ":last" ).is( "span.ui-calendar-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); table = dp.children( ":eq(1)" ); ok( table.is( "table.ui-calendar-calendar" ), "Structure - month table" ); ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); - - thead = table.children( ":first" ).children( ":first" ); - ok( thead.is( "tr" ), "Structure - month table title row" ); - equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" ); - ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" ); - - week = table.children( ":eq(1)" ).children( ":first" ); - ok( week.is( "tr" ), "Structure - month table week row" ); - equal( week.children().length, 7, "Structure - week child count" ); inp.datepicker( "close" ); step2(); @@ -106,94 +90,10 @@ asyncTest( "baseStructure", function() { step1(); }); -test( "Localization", function() { +asyncTest( "Keyboard handling: input", function() { expect( 10 ); - - var defaultLocale = Globalize.locale(), - input = $( "#datepicker" ), - date = new Date( 2014, 0, 1 ), - initDatepicker = function() { - input - .datepicker() - .datepicker( "valueAsDate", date ) - .datepicker( "open" ); - }, - testLocalization = function( message ) { - picker = input.datepicker( "widget" ); - - equal( picker.find( ".ui-calendar-month" ).text(), "Januar", message + "titlebar year" ); - equal( picker.find( "thead th:first" ).text(), "Mo.", message + "teader first day" ); - equal( picker.find( "thead th:last" ).text(), "So.", message + "header last day" ); - equal( picker.find( ".ui-calendar-prev" ).text(), "", message + "header next" ); - }, - picker; - - Globalize.locale( "de-DE" ); - initDatepicker(); - testLocalization( "Init: " ); - input.datepicker( "destroy" ); - - Globalize.locale( defaultLocale.locale ); - initDatepicker(); - Globalize.locale( "de-DE" ); - input.datepicker( "refresh" ); - testLocalization( "After init: " ); - - Globalize.locale( defaultLocale.locale ); -}); - -test( "Keyboard handling: input", function() { - expect( 6 ); var input = $( "#datepicker" ).datepicker(), - instance = input.datepicker( "instance" ); - - // Enter = Select preset date - input - .val( "1/1/14" ) - .datepicker( "refresh" ) - .datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), - "Keystroke enter - preset" ); - - input - .val( "" ) - .datepicker( "open" ); - ok( instance.isOpen, "datepicker is open before escape" ); - - input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - ok( !instance.isOpen, "escape closes the datepicker" ); - - input - .val( "1/1/14" ) - .datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), - "Keystroke esc - preset" ); - - input - .val( "1/1/14" ) - .datepicker( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), - "Keystroke esc - abandoned" ); - - input - .val( "1/2/14" ) - .simulate( "keyup" ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ), - "Picker updated as user types into input" ); - - input.datepicker( "destroy" ); -}); - -asyncTest( "keyboard handling: calendar", function() { - expect( 14 ); - - var picker, - input = $( "#datepicker" ); + picker, instance; function step1() { TestHelpers.datepicker.init( input ); @@ -224,6 +124,60 @@ asyncTest( "keyboard handling: calendar", function() { } function step3() { + TestHelpers.datepicker.init( input ); + instance = input.datepicker( "instance" ); + + // Enter = Select preset date + input + .val( "1/1/14" ) + .datepicker( "refresh" ) + .datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke enter - preset" ); + + input + .val( "" ) + .datepicker( "open" ); + ok( instance.isOpen, "datepicker is open before escape" ); + + input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + ok( !instance.isOpen, "escape closes the datepicker" ); + + input + .val( "1/1/14" ) + .datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke esc - preset" ); + + input + .val( "1/1/14" ) + .datepicker( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke esc - abandoned" ); + + input + .val( "1/2/14" ) + .simulate( "keyup" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ), + "Picker updated as user types into input" ); + + input.datepicker( "destroy" ); + start(); + } + + step1(); +}); + +asyncTest( "keyboard handling: calendar", function() { + expect( 7 ); + + var input = $( "#datepicker" ); + + function step1() { input.val( "1/1/14" ); TestHelpers.datepicker.init( input ); input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -238,12 +192,12 @@ asyncTest( "keyboard handling: calendar", function() { "Keystroke left to switch to previous day" ); input.datepicker( "destroy" ); - step4(); + step2(); }, 50 ); }, 100 ); } - function step4() { + function step2() { input.val( "1/1/14" ); TestHelpers.datepicker.init( input ); input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -259,11 +213,11 @@ asyncTest( "keyboard handling: calendar", function() { "Keystroke right to switch to next day" ); input.datepicker( "destroy" ); - step5(); + step3(); }, 100 ); } - function step5() { + function step3() { input.val( "1/1/14" ); TestHelpers.datepicker.init( input ); input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -278,12 +232,12 @@ asyncTest( "keyboard handling: calendar", function() { "Keystroke up to move to the previous week" ); input.datepicker( "destroy" ); - step6(); + step4(); }, 50 ); }, 100 ); } - function step6() { + function step4() { input.val( "1/1/14" ); TestHelpers.datepicker.init( input ); input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -299,52 +253,12 @@ asyncTest( "keyboard handling: calendar", function() { "Keystroke down to move to the next week" ); input.datepicker( "destroy" ); - step7(); - }, 50 ); - }, 100 ); - } - - function step7() { - input.val( "1/1/14" ); - TestHelpers.datepicker.init( input ); - input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - - setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); - setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2013, 12 - 1, 1 ), - "Keystroke Page Up moves date to previous month" - ); - input.datepicker( "destroy" ); - step8(); - }, 50 ); - }, 100 ); - } - - function step8() { - input.val( "1/1/14" ); - TestHelpers.datepicker.init( input ); - input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - - setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ); - setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2013, 1 - 1, 1 ), - "Keystroke Page Up + Ctrl moves date to previous year" - ); - input.datepicker( "destroy" ); - step9(); + step5(); }, 50 ); }, 100 ); } - function step9() { + function step5() { input.val( "1/1/14" ); TestHelpers.datepicker.init( input ); input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -359,12 +273,12 @@ asyncTest( "keyboard handling: calendar", function() { "Keystroke Page Down moves date to next month" ); input.datepicker( "destroy" ); - step10(); + step6(); }, 50 ); }, 100 ); } - function step10() { + function step6() { input.val( "1/1/14" ); TestHelpers.datepicker.init( input ); input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -379,13 +293,13 @@ asyncTest( "keyboard handling: calendar", function() { "Keystroke Page Down + Ctrl moves date to next year" ); input.datepicker( "destroy" ); - step11(); + step7(); }, 50 ); }, 100 ); } // Check for moving to short months - function step11() { + function step7() { input.val( "3/31/14" ); TestHelpers.datepicker.init( input ); input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); @@ -400,26 +314,6 @@ asyncTest( "keyboard handling: calendar", function() { "Keystroke Page Up and short months" ); input.datepicker( "destroy" ); - step12(); - }, 50 ); - }, 100 ); - } - - function step12() { - input.val( "1/30/16" ); - TestHelpers.datepicker.init( input ); - input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - - setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); - setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2016, 2 - 1, 29 ), - "Keystroke Page Down and leap years" - ); - input.datepicker( "destroy" ); start(); }, 50 ); }, 100 ); @@ -428,144 +322,51 @@ asyncTest( "keyboard handling: calendar", function() { step1(); }); -/* - // TODO: Re-add tests if we implement a stepMonths option - input.datepicker( "option", { stepMonths: 2, gotoCurrent: false } ) - .datepicker( "close" ).val( "02/04/2008" ).datepicker( "open" ) - .late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2007, 12 - 1, 4 ), - "Keystroke pgup step 2" ); - - input.val( "02/04/2008" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ), - "Keystroke pgdn step 2" ); -*/ - // TODO: implement test( "ARIA", function() { expect( 0 ); }); asyncTest( "mouse", function() { - expect( 9 ); + expect( 4 ); var input = TestHelpers.datepicker.init( $( "#datepicker" ).val( "" ) ), - picker = input.datepicker( "widget" ), - date = new Date(); - - function step1() { - input.datepicker( "open" ); - - setTimeout(function() { - $( "tbody a:contains(10)", picker ).simulate( "mousedown", {} ); - date.setDate( 10 ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - date, - "Mouse click" - ); - - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2008, 2 - 1, 12 ), - "Mouse click - preset" - ); - - input.val( "" ).datepicker( "refresh" ).datepicker( "open" ); - $( "button.ui-calendar-close", picker ).simulate( "click", {} ); - ok( input.datepicker( "valueAsDate" ) == null, "Mouse click - close" ); - - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( "button.ui-calendar-close", picker ).simulate( "click", {} ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2008, 2 - 1, 4 ), - "Mouse click - close + preset" - ); - - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( "a.ui-calendar-prev", picker ).simulate( "click", {} ); - $( "button.ui-calendar-close", picker ).simulate( "click", {} ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2008, 2 - 1, 4 ), - "Mouse click - abandoned" - ); - - // Previous/next - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-prev", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(16)", picker ).simulate( "mousedown" ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2008, 1 - 1, 16 ), - "Mouse click - previous" - ); - - input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-next", picker ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(18)", picker ).simulate( "mousedown" ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2008, 3 - 1, 18 ), - "Mouse click - next" - ); - - step2(); - }, 100 ); - } - - // Previous/next with minimum/maximum - function step2() { - input - .datepicker( "destroy" ) - .val( "3/4/08" ); - input = TestHelpers.datepicker.init( "#datepicker", { - min: new Date( 2008, 2 - 1, 2 ), - max: new Date( 2008, 2 - 1, 26 ) - }); picker = input.datepicker( "widget" ); - input.datepicker( "open" ); - setTimeout(function() { - $( ".ui-calendar-prev", picker ).simulate( "click" ); - $( "tbody a:contains(16)", picker ).simulate( "mousedown" ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2008, 2 - 1, 16 ), - "Mouse click - previous + min/max" - ); - step3(); - }, 100 ); - } - function step3() { - input - .datepicker( "destroy" ) - .val( "1/4/08" ); - input = TestHelpers.datepicker.init( "#datepicker", { - min: new Date( 2008, 2 - 1, 2 ), - max: new Date( 2008, 2 - 1, 26 ) - }); - picker = input.datepicker( "widget" ); - input.datepicker( "open" ); - setTimeout(function() { - $( ".ui-calendar-next", picker ).simulate( "click" ); - $( "tbody a:contains(18)", picker ).simulate( "mousedown" ); - TestHelpers.datepicker.equalsDate( - input.datepicker( "valueAsDate" ), - new Date( 2008, 2 - 1, 18 ), - "Mouse click - next + min/max" - ); - start(); - }, 100 ); - } + input.datepicker( "open" ); - step1(); + setTimeout(function() { + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 2 - 1, 12 ), + "Mouse click - preset" + ); + + input.val( "" ).datepicker( "refresh" ); + input.simulate( "click" ); + ok( input.datepicker( "valueAsDate" ) === null, "Mouse click - close" ); + + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + input.simulate( "click" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 2 - 1, 4 ), + "Mouse click - close + preset" + ); + + input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + $( "a.ui-calendar-prev", picker ).simulate( "click", {} ); + input.simulate( "click" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 2 - 1, 4 ), + "Mouse click - abandoned" + ); + + start(); + }, 100 ); }); })( jQuery ); From c9fdefea2c816185daf29d73c7ff569ca15201b2 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 17:50:12 +0200 Subject: [PATCH 166/172] Calendar tests: Add common unit tests --- tests/unit/calendar/calendar_common.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/unit/calendar/calendar_common.js b/tests/unit/calendar/calendar_common.js index b0df728acb6..a669fdfc2c1 100644 --- a/tests/unit/calendar/calendar_common.js +++ b/tests/unit/calendar/calendar_common.js @@ -1,7 +1,17 @@ -/* TestHelpers.commonWidgetTests( "calendar", { defaults: { - disabled: false + buttons: [], + dateFormat: { date: "short" }, + disabled: false, + eachDay: $.noop, + max: null, + min: null, + numberOfMonths: 1, + showWeek: false, + value: null, + + // callbacks + create: null, + select: null } }); -*/ From 923a4b888c86732f8a065814e120904bfc24a884 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 17:52:17 +0200 Subject: [PATCH 167/172] Calendar tests: Remove unneeded image --- tests/unit/calendar/images/calendar.gif | Bin 258 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/unit/calendar/images/calendar.gif diff --git a/tests/unit/calendar/images/calendar.gif b/tests/unit/calendar/images/calendar.gif deleted file mode 100644 index 52f2863c90764cabb11ac926b3f7e02b9b9e5e49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 258 zcmZ?wbh9u|6ky<+Y9vrwbI($!DTUl#W73z|)4nX4`*rp5ZyQ#B-@379)%)KM@Be-M>hGtI|Gs_w|L4#D z|Nj|~fDVWavWtPW{Q*md3PbOU5QXTA``&Hf+-&MQNyN4Pv4TT$qr;4tz7x@TlA2nj z{VVh>rsSCQXN#@AXk#?9q4e^OX(ylcxawre$mLbEZVWhZ^wyuYi=i=Ui~?zCvD{J; zob`>l`Gve(T%4S?jg@f;{OB2!bOQWALGdFOQVvkR?QwQ_|pZzJQT&0DrAGFSru Doau8X From 98517b3681e812867a3eaff596f5390f1c2c92f4 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 28 Jun 2014 01:44:55 +0200 Subject: [PATCH 168/172] Calendar tests: Fix title --- tests/unit/calendar/all.html | 2 +- tests/unit/calendar/calendar.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/calendar/all.html b/tests/unit/calendar/all.html index 26c46415a6e..87683cf0605 100644 --- a/tests/unit/calendar/all.html +++ b/tests/unit/calendar/all.html @@ -2,7 +2,7 @@ - jQuery UI calendar Test Suite + jQuery UI Calendar Test Suite diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html index 022dc42ded1..e2527e02cf5 100644 --- a/tests/unit/calendar/calendar.html +++ b/tests/unit/calendar/calendar.html @@ -2,7 +2,7 @@ - jQuery UI calendar Test Suite + jQuery UI Calendar Test Suite From 9e8936d0cef0673669a72ec20728ee79c1840c1b Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 1 Jul 2014 22:43:06 +0200 Subject: [PATCH 169/172] Calendar: Set selected property to null by default --- external/date.js | 1 + 1 file changed, 1 insertion(+) diff --git a/external/date.js b/external/date.js index 1bc5b836038..edc47c161f6 100644 --- a/external/date.js +++ b/external/date.js @@ -32,6 +32,7 @@ $.date = function( date, globalFormat ) { this.dateObject = this.dateObject || new Date(); this.globalFormat = globalFormat; + this.selected = null; }; $.date.prototype = { From 2051a8d13a9fc240723b8bc51ec57604c416cb9c Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 1 Jul 2014 22:49:46 +0200 Subject: [PATCH 170/172] Calendar tests: Rewrite method unit tests based on datepicker tests --- tests/unit/calendar/calendar_methods.js | 175 +++++++++----------- tests/unit/datepicker/datepicker_methods.js | 12 +- 2 files changed, 84 insertions(+), 103 deletions(-) diff --git a/tests/unit/calendar/calendar_methods.js b/tests/unit/calendar/calendar_methods.js index 89547463cf8..59078e398cb 100644 --- a/tests/unit/calendar/calendar_methods.js +++ b/tests/unit/calendar/calendar_methods.js @@ -3,128 +3,107 @@ module( "calendar: methods" ); test( "destroy", function() { - expect( 10 ); - var input = $( "#calendar" ).calendar(), - inline = $( "#inline" ).calendar(); - - ok( input.calendar( "instance" ), "instance created" ); - ok( input.attr( "aria-owns" ), "aria-owns attribute added" ); - ok( input.attr( "aria-haspopup" ), "aria-haspopup attribute added" ); - input.calendar( "destroy" ); - ok( !input.calendar( "instance" ), "instance removed" ); - ok( !input.attr( "aria-owns" ), "aria-owns attribute removed" ); - ok( !input.attr( "aria-haspopup" ), "aria-haspopup attribute removed" ); - - ok( inline.calendar( "instance" ), "instance created" ); - ok( inline.children().length > 0, "inline calendar has children" ); - inline.calendar( "destroy" ); - ok( !inline.calendar( "instance" ), "instance removed" ); - ok( inline.children().length === 0, "inline picker no longer has children" ); + expect( 4 ); + + var element = $( "#calendar" ).calendar(); + + ok( element.calendar( "instance" ), "instance created" ); + element.calendar( "destroy" ); + ok( !element.calendar( "instance" ), "instance removed" ); + ok( !element.attr( "role" ), "role attribute removed" ); + ok( !element.attr( "aria-labelledby" ), "aria-labelledby attribute removed" ); }); test( "enable / disable", function() { expect( 6 ); - var inl, - inp = TestHelpers.calendar.init( "#calendar" ), - dp = inp.calendar( "widget" ); - - ok( !inp.calendar( "option", "disabled" ), "initially enabled" ); - ok( !dp.hasClass( "ui-calendar-disabled" ), "does not have disabled class name" ); - inp.calendar( "disable" ); - ok( inp.calendar( "option", "disabled" ), "disabled option is set" ); - ok( dp.hasClass( "ui-calendar-disabled" ), "calendar has disabled class name" ); + var element = $( "#calendar" ).calendar(); - inp.calendar( "enable" ); - ok( !inp.calendar( "option", "disabled" ), "enabled after enable() call" ); - ok( !dp.hasClass( "ui-calendar-disabled" ), "no longer has disabled class name" ); + ok( !element.calendar( "option", "disabled" ), "initially enabled" ); + ok( !element.hasClass( "ui-calendar-disabled" ), "does not have disabled class name" ); - // Inline - inl = TestHelpers.calendar.init( "#inline" ); - dp = inl.calendar( "instance" ); + element.calendar( "disable" ); + ok( element.calendar( "option", "disabled" ), "disabled option is set" ); + ok( element.hasClass( "ui-calendar-disabled" ), "calendar has disabled class name" ); - // TODO: Disabling inline pickers does not work. - // TODO: When changeMonth and changeYear options are implemented ensure their dropdowns - // are properly disabled when in an inline picker. + element.calendar( "enable" ); + ok( !element.calendar( "option", "disabled" ), "enabled after enable() call" ); + ok( !element.hasClass( "ui-calendar-disabled" ), "no longer has disabled class name" ); }); test( "widget", function() { expect( 1 ); - var actual = $( "#calendar" ).calendar().calendar( "widget" ); - deepEqual( $( "body > .ui-front" )[ 0 ], actual[ 0 ] ); - actual.remove(); -}); -test( "close", function() { - expect( 0 ); -}); + var element = $( "#calendar" ).calendar(), + widget = element.calendar( "widget" ); -test( "open", function() { - expect( 0 ); + deepEqual( widget[ 0 ], element[ 0 ] ); }); test( "value", function() { - expect( 6 ); - var input = $( "#calendar" ).calendar(), - picker = input.calendar( "widget" ), - inline = $( "#inline" ).calendar(); - - input.calendar( "value", "1/1/14" ); - equal( input.val(), "1/1/14", "input's value set" ); - ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), - "first day marked as selected" ); - equal( input.calendar( "value" ), "1/1/14", "getter" ); - - input.val( "abc" ); - equal( input.calendar( "value" ), "abc", - "Invalid values should be returned without formatting." ); - - inline.calendar( "value", "1/1/14" ); - ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), - "first day marked as selected" ); - equal( inline.calendar( "value" ), "1/1/14", "getter" ); - - input.calendar( "destroy" ); - inline.calendar( "destroy" ); + expect( 3 ); + var element = $( "#calendar" ).calendar(); + + element.calendar( "value", "1/1/14" ); + ok( element.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "first day marked as selected" ); + equal( element.calendar( "value" ), "1/1/14", "getter" ); + + element.calendar( "value", "abc" ); + equal( element.calendar( "value" ), "1/1/14", "Setting invalid values should be ignored." ); }); test( "valueAsDate", function() { - expect( 6 ); - var input = $( "#calendar" ).calendar(), - picker = input.calendar( "widget" ), - inline = $( "#inline" ).calendar(); - - input.calendar( "valueAsDate", new Date( 2014, 0, 1 ) ); - equal( input.val(), "1/1/14", "input's value set" ); - ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), - "first day marked as selected" ); - TestHelpers.calendar.equalsDate( input.calendar( "valueAsDate" ), - new Date( 2014, 0, 1 ), "getter" ); - - input.val( "a/b/c" ); - equal( input.calendar( "valueAsDate" ), null, "Invalid dates return null" ); - - inline.calendar( "valueAsDate", new Date( 2014, 0, 1 ) ); - ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ), - "first day marked as selected" ); - TestHelpers.calendar.equalsDate( inline.calendar( "valueAsDate" ), - new Date( 2014, 0, 1 ), "getter" ); - - input.calendar( "destroy" ); - inline.calendar( "destroy" ); -}); + expect( 12 ); + + var minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, + element = $( "#calendar" ).calendar(), + date1 = new Date(2008, 6 - 1, 4), + date2 = new Date(); + + element.calendar( "valueAsDate", new Date( 2014, 0, 1 ) ); + ok( element.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "First day marked as selected" ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" ); + + element.calendar( "destroy" ); + + element.calendar(); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date(), "Set date - default" ); + + element.calendar( "valueAsDate", date1 ); + TestHelpers.calendar.equalsDate(element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" ); + + element.calendar( "valueAsDate", date1, date2); + TestHelpers.calendar.equalsDate(element.calendar( "valueAsDate" ), date1, "Set date - two dates" ); + + // With minimum/maximum + element = $( "#calendar" ).calendar(); + date1 = new Date( 2008, 1 - 1, 4 ); + date2 = new Date( 2008, 6 - 1, 4 ); + minDate = new Date( 2008, 2 - 1, 29 ); + maxDate = new Date( 2008, 3 - 1, 28 ); + + element.calendar( "option", { min: minDate } ).calendar( "valueAsDate", date2 ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), date2, "Set date min/max - value > min" ); + + element.calendar( "valueAsDate", date1 ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), date2, "Set date min/max - value < min" ); + + element.calendar( "option", { max: maxDate, min: null } ).calendar( "valueAsDate", date1 ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), date1, "Set date min/max - value < max" ); -test( "isValid", function() { - expect( 2 ); - var input = $( "#calendar" ).calendar(); + element.calendar( "valueAsDate", date2 ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), date1, "Set date min/max - value > max" ); - input.val( "1/1/14" ); - ok( input.calendar( "isValid" ) ); + element.calendar( "option", { min: minDate } ).calendar( "valueAsDate", date1 ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), date1, "Set date min/max - value < min" ); - input.val( "1/1/abc" ); - ok( !input.calendar( "isValid" ) ); + element.calendar( "valueAsDate", date2 ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), date1, "Set date min/max - value > max" ); - input.calendar( "destroy" ); + dateAndTimeToSet = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); + dateAndTimeClone = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); + element.calendar( "valueAsDate", dateAndTimeToSet ); + equal( dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by valueAsDate" ); }); })( jQuery ); diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index cf41313922a..ebee9432640 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -4,6 +4,7 @@ module( "datepicker: methods" ); test( "destroy", function() { expect( 6 ); + var input = $( "#datepicker" ).datepicker(); ok( input.datepicker( "instance" ), "instance created" ); @@ -17,6 +18,7 @@ test( "destroy", function() { test( "enable / disable", function() { expect( 6 ); + var inp = TestHelpers.datepicker.init( "#datepicker" ), dp = inp.datepicker( "widget" ); @@ -34,6 +36,7 @@ test( "enable / disable", function() { test( "widget", function() { expect( 1 ); + var actual = $( "#datepicker" ).datepicker().datepicker( "widget" ); deepEqual( $( "body > .ui-front" )[ 0 ], actual[ 0 ] ); actual.remove(); @@ -60,11 +63,13 @@ test( "open / close", function() { test( "value", function() { expect( 4 ); + var input = $( "#datepicker" ).datepicker(), picker = input.datepicker( "widget" ); input.datepicker( "value", "1/1/14" ); equal( input.val(), "1/1/14", "input's value set" ); + input.datepicker( "open" ); ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "first day marked as selected" ); equal( input.datepicker( "value" ), "1/1/14", "getter" ); @@ -74,7 +79,7 @@ test( "value", function() { }); test( "valueAsDate", function() { - expect( 14 ); + expect( 13 ); var minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, input = TestHelpers.datepicker.init( "#datepicker" ), @@ -93,13 +98,10 @@ test( "valueAsDate", function() { input.val( "" ).datepicker( "destroy" ); input = TestHelpers.datepicker.init( "#datepicker" ); - ok(input.datepicker( "valueAsDate" ) == null, "Set date - default" ); + ok(input.datepicker( "valueAsDate" ) === null, "Set date - default" ); input.datepicker( "valueAsDate", date1); TestHelpers.datepicker.equalsDate(input.datepicker( "valueAsDate" ), date1, "Set date - 2008-06-04" ); - input.datepicker( "valueAsDate", date1, date2); - TestHelpers.datepicker.equalsDate(input.datepicker( "valueAsDate" ), date1, "Set date - two dates" ); - // With minimum/maximum input = TestHelpers.datepicker.init( "#datepicker" ); date1 = new Date( 2008, 1 - 1, 4 ); From 077e9aa7918bf9ae68d8bc7d1ebf9b2cd37fb284 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 2 Jul 2014 19:22:49 +0200 Subject: [PATCH 171/172] Calendar: Adjust files to match reorganization of external directory --- demos/calendar/buttonbar.html | 4 ++-- demos/calendar/date-formats.html | 4 ++-- demos/calendar/default.html | 4 ++-- demos/calendar/dropdown-month-year.html | 4 ++-- demos/calendar/localization.html | 4 ++-- demos/calendar/min-max.html | 4 ++-- demos/calendar/multiple-months.html | 4 ++-- demos/calendar/other-months.html | 4 ++-- demos/calendar/show-week.html | 4 ++-- tests/unit/date/all.html | 22 +++++++++++----------- tests/unit/date/date.html | 6 +++--- 11 files changed, 32 insertions(+), 32 deletions(-) diff --git a/demos/calendar/buttonbar.html b/demos/calendar/buttonbar.html index 235192da1f8..7a2098b3f6d 100644 --- a/demos/calendar/buttonbar.html +++ b/demos/calendar/buttonbar.html @@ -4,8 +4,8 @@ jQuery UI Calendar - Display button bar - - + + diff --git a/demos/calendar/date-formats.html b/demos/calendar/date-formats.html index 33df9cacb59..e3f4e045762 100644 --- a/demos/calendar/date-formats.html +++ b/demos/calendar/date-formats.html @@ -4,8 +4,8 @@ jQuery UI Calendar - Format date - - + + diff --git a/demos/calendar/default.html b/demos/calendar/default.html index b35e9e769bd..8c77174b435 100644 --- a/demos/calendar/default.html +++ b/demos/calendar/default.html @@ -4,8 +4,8 @@ jQuery UI Calendar - Default functionality - - + + diff --git a/demos/calendar/dropdown-month-year.html b/demos/calendar/dropdown-month-year.html index c5773894607..050a89157ff 100644 --- a/demos/calendar/dropdown-month-year.html +++ b/demos/calendar/dropdown-month-year.html @@ -4,8 +4,8 @@ jQuery UI Calendar - Display month & year menus - - + + diff --git a/demos/calendar/localization.html b/demos/calendar/localization.html index 64c51e22fd5..fa933fe11b5 100644 --- a/demos/calendar/localization.html +++ b/demos/calendar/localization.html @@ -4,8 +4,8 @@ jQuery UI Calendar - Localize calendar - - + + diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html index 067b6f02f66..5b9b5fd825f 100644 --- a/demos/calendar/min-max.html +++ b/demos/calendar/min-max.html @@ -4,8 +4,8 @@ jQuery UI Calendar - Restrict date range - - + + diff --git a/demos/calendar/multiple-months.html b/demos/calendar/multiple-months.html index 40cc30e2d72..f67609d143e 100644 --- a/demos/calendar/multiple-months.html +++ b/demos/calendar/multiple-months.html @@ -4,8 +4,8 @@ jQuery UI Calendar - Display multiple months - - + + diff --git a/demos/calendar/other-months.html b/demos/calendar/other-months.html index 4e3ee3e3b88..0228c62df5b 100644 --- a/demos/calendar/other-months.html +++ b/demos/calendar/other-months.html @@ -4,8 +4,8 @@ jQuery UI Calendar - Dates in other months - - + + diff --git a/demos/calendar/show-week.html b/demos/calendar/show-week.html index bb9ae4cc9b6..08687aa0dea 100644 --- a/demos/calendar/show-week.html +++ b/demos/calendar/show-week.html @@ -4,8 +4,8 @@ jQuery UI Calendar - Show week of the year - - + + diff --git a/tests/unit/date/all.html b/tests/unit/date/all.html index ca2d66e37d9..8f31592f14b 100644 --- a/tests/unit/date/all.html +++ b/tests/unit/date/all.html @@ -1,20 +1,20 @@ - - jQuery UI Date Test Suite + + jQuery UI Date Test Suite - + - - - - - + + + + + - + diff --git a/tests/unit/date/date.html b/tests/unit/date/date.html index d759fdeaee7..b2dd2c41e22 100644 --- a/tests/unit/date/date.html +++ b/tests/unit/date/date.html @@ -5,14 +5,14 @@ jQuery UI Date Test Suite - - + + - + + diff --git a/demos/datepicker/animation.html b/demos/datepicker/animation.html index 23be1d11e44..02c01c21f6a 100644 --- a/demos/datepicker/animation.html +++ b/demos/datepicker/animation.html @@ -4,8 +4,8 @@ jQuery UI Datepicker - Animations - - + + diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index 92e1d6ebedf..d8ff62d1c28 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -4,8 +4,8 @@ jQuery UI Datepicker - Format date - - + + diff --git a/demos/datepicker/default.html b/demos/datepicker/default.html index 6fb48dda2b6..08e93846f23 100644 --- a/demos/datepicker/default.html +++ b/demos/datepicker/default.html @@ -4,8 +4,8 @@ jQuery UI Datepicker - Default functionality - - + + diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index b04dc04d753..3df6f320e64 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -4,8 +4,8 @@ jQuery UI Datepicker - Icon trigger - - + + diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index 1dc8cd56679..34c35bff547 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -4,8 +4,8 @@ jQuery UI Datepicker - Localize calendar - - + + diff --git a/tests/unit/calendar/all.html b/tests/unit/calendar/all.html index 87683cf0605..ea5662fe8d8 100644 --- a/tests/unit/calendar/all.html +++ b/tests/unit/calendar/all.html @@ -6,9 +6,9 @@ - + - + diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html index e2527e02cf5..ed536414fbc 100644 --- a/tests/unit/calendar/calendar.html +++ b/tests/unit/calendar/calendar.html @@ -5,11 +5,11 @@ jQuery UI Calendar Test Suite - + - - + + - + - - + +