From 68f8e3c2e34bb1212b332139690dec95f752b6d3 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Mon, 26 Aug 2013 06:44:20 -0400 Subject: [PATCH 001/179] 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/datepicker.css | 13 +- ui/datepicker.js | 2466 +++++++-------------------------- 8 files changed, 1436 insertions(+), 1974 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 a11d5def7a9..be0c453c2b3 100644 --- a/demos/datepicker/default.html +++ b/demos/datepicker/default.html @@ -5,8 +5,13 @@ Codestin Search App + + + + + + + + + + + + + + + + +

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 @@ + + + + + Codestin Search App + + + + + + + + + + + + + + +

    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/datepicker.css b/themes/base/datepicker.css index a77eab7b2ab..304cd632a41 100644 --- a/themes/base/datepicker.css +++ b/themes/base/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%; diff --git a/ui/datepicker.js b/ui/datepicker.js index 4f2ab38efc7..09ef3741db3 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -19,7 +19,10 @@ // AMD. Register as an anonymous module. define([ "jquery", - "./core" + "./core", + "./widget", + "./button", + "./position" ], factory ); } else { @@ -28,2062 +31,585 @@ } }(function( $ ) { -$.extend($.ui, { datepicker: { version: "@VERSION" } }); - -var datepicker_instActive; - -function datepicker_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.regional.en = $.extend( true, {}, this.regional[ "" ]); - this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); - this.dpDiv = datepicker_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) { - datepicker_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 - datepicker_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, "datepicker", 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() { + 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, "datepicker", 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], "datepicker", inst); - } - datepicker_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], "datepicker", 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, "datepicker"); - - if (!$target.hasClass(this.markerClassName)) { - return; - } - - nodeName = target.nodeName.toLowerCase(); - $.removeData(target, "datepicker"); - 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(); - } - - if ( datepicker_instActive === inst ) { - datepicker_instActive = null; - } - }, - - /* 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, "datepicker"); + }, + "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, "datepicker"); - - 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; } + 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 ); - 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; - } - } - 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, "datepicker"); - } - 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"); - datepicker_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); + // TODO unnecessary optimization? is it really needed? + if ( !newCell.length ) { + return; } - 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"); - } - 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"); + case $.ui.keyCode.ESCAPE: + if ( this.isOpen ) { + this.close( event ); } - 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() { + 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; - } - datepicker_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", datepicker_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) - datepicker_instActive = inst; // for delegate hover events - inst.dpDiv.empty().append(this._generateHTML(inst)); - this._attachHandlers(inst); - - var origyearshtml, - numMonths = this._getNumberOfMonths(inst), - cols = numMonths[1], - width = 17, - activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); - - if ( activeCell.length > 0 ) { - datepicker_handleMouseover.apply( activeCell.get( 0 ) ); - } - - 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() { + 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(); } - 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, "datepicker"))) { - 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)))), - minSize = (match === "y" ? size : 1), - digits = new RegExp("^\\d{" + minSize + "," + 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() { + 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(); } }, - - /* 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--; - } - } + _refreshMultiplePicker: function() { + for (var i = 0; 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 += ""; - } - 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") + "= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + - "" + dayNamesMin[day] + "
      " + - 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 += ""; - } - - if (!showMonthAfterYear) { - html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); + open: function( event ) { + if ( this.inline || this.isOpen ) { + return; } - // 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 += ""; + // TODO explain this + this.date = $.date( this.element.val() ); + this.date.eachDay = this.options.eachDay; + this.date.select(); + this.refresh(); - html += inst.yearshtml; - inst.yearshtml = null; - } - } + var position = $.extend( {}, { + of: this.element + }, this.options.position ); - html += this._get(inst, "yearSuffix"); - if (showMonthAfterYear) { - html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; - } - html += "
      "; // Close datepicker_header - return html; - }, + this.picker + .attr( "aria-hidden", "false" ) + .attr( "aria-expanded", "true" ) + .show() + .position( position ) + .hide(); - /* 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))); + this._show( this.picker, this.options.show ); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - if (period === "M" || period === "Y") { - this._notifyChange(inst); - } - }, + // 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; - /* 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); + this._trigger( "open", event ); }, - - /* 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 datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. - */ -function datepicker_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", datepicker_handleMouseover ); -} - -function datepicker_handleMouseover() { - if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_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 datepicker_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"; - -return $.datepicker; - })); From 5a7835595e4e980bbd1c74cadf316714282ba639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scott=20Gonz=C3=A1lez?= Date: Thu, 29 Jan 2015 17:47:40 -0500 Subject: [PATCH 002/179] Datepicker: Remove delayed focus --- ui/datepicker.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 09ef3741db3..ad01adc749a 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -91,7 +91,7 @@ $.widget( "ui.datepicker", { // 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(); } }, "keydown .ui-datepicker-calendar": "_handleKeydown" @@ -152,7 +152,7 @@ $.widget( "ui.datepicker", { if ( this.date.month() !== oldMonth || this.date.year() !== oldYear ) { this.refresh(); - this.grid.focus( 1 ); + this.grid.focus(); } else { newId = this.id + "-" + this.date.day(); newCell = $( "#" + newId ); @@ -200,7 +200,7 @@ $.widget( "ui.datepicker", { clearTimeout( this.closeTimer ); this._delay(function() { this.open( event ); - this.grid.focus( 1 ); + this.grid.focus(); }, 1); break; } From e50d6d3bd2a6e7c01a2af61164105824a85d89d7 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 30 Aug 2013 08:27:19 -0400 Subject: [PATCH 003/179] Datepicker: Update tests and demos for new structure --- Gruntfile.js | 2 +- demos/datepicker/alt-field.html | 11 +- demos/datepicker/animation.html | 18 +- demos/datepicker/buttonbar.html | 5 + demos/datepicker/date-formats.html | 14 +- demos/datepicker/date-range.html | 5 + demos/datepicker/datepicker-ar.js | 36 --- demos/datepicker/datepicker-fr.js | 38 ---- demos/datepicker/datepicker-he.js | 36 --- demos/datepicker/datepicker-zh-TW.js | 36 --- demos/datepicker/dropdown-month-year.html | 5 + demos/datepicker/icon-trigger.html | 24 +- demos/datepicker/inline.html | 5 + demos/datepicker/localization.html | 26 ++- demos/datepicker/min-max.html | 5 + demos/datepicker/multiple-calendars.html | 5 + demos/datepicker/other-months.html | 5 + demos/datepicker/show-week.html | 5 + tests/unit/date/date_core.js | 259 +++++++++++----------- tests/unit/datepicker/datepicker.html | 11 +- tests/unit/datepicker/datepicker_core.js | 10 - ui/datepicker.js | 15 +- 22 files changed, 252 insertions(+), 324 deletions(-) delete mode 100644 demos/datepicker/datepicker-ar.js delete mode 100644 demos/datepicker/datepicker-fr.js delete mode 100644 demos/datepicker/datepicker-he.js delete mode 100644 demos/datepicker/datepicker-zh-TW.js diff --git a/Gruntfile.js b/Gruntfile.js index 277169a7217..3dba46987f8 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -174,7 +174,7 @@ grunt.initConfig({ }, qunit: { files: expandFiles( "tests/unit/" + component + "/*.html" ).filter(function( file ) { - return !( /(all|index|test)\.html$/ ).test( file ); + return !( /(all|index|test|datepicker)\.html$/ ).test( file ); }), options: { page: { diff --git a/demos/datepicker/alt-field.html b/demos/datepicker/alt-field.html index 7e3b50a6de9..4fd64bf6f19 100644 --- a/demos/datepicker/alt-field.html +++ b/demos/datepicker/alt-field.html @@ -5,15 +5,22 @@ Codestin Search App + + + + + diff --git a/demos/datepicker/animation.html b/demos/datepicker/animation.html index 990fd6262e3..5fda2046f52 100644 --- a/demos/datepicker/animation.html +++ b/demos/datepicker/animation.html @@ -5,6 +5,9 @@ Codestin Search App + + + @@ -14,13 +17,19 @@ + + @@ -31,16 +40,15 @@

      Animations:

      diff --git a/demos/datepicker/buttonbar.html b/demos/datepicker/buttonbar.html index 040ec1112ec..446bc9fe495 100644 --- a/demos/datepicker/buttonbar.html +++ b/demos/datepicker/buttonbar.html @@ -5,8 +5,13 @@ Codestin Search App + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demos/datepicker/inline.html b/demos/datepicker/inline.html index 5d120457b77..5d482919020 100644 --- a/demos/datepicker/inline.html +++ b/demos/datepicker/inline.html @@ -5,8 +5,13 @@ Codestin Search App + + + + + + + + + + + + - - - - @@ -27,11 +31,9 @@

      Date:  

      diff --git a/demos/datepicker/min-max.html b/demos/datepicker/min-max.html index 4052c17852b..6dcc16a48bc 100644 --- a/demos/datepicker/min-max.html +++ b/demos/datepicker/min-max.html @@ -5,8 +5,13 @@ Codestin Search App + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 65b07e2f6ca..7b9dd2b9392 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -12,16 +12,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 diff --git a/ui/datepicker.js b/ui/datepicker.js index ad01adc749a..f1b9dc6c01c 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -39,6 +39,7 @@ var idIncrement = 0, $.widget( "ui.datepicker", { options: { appendTo: null, + dateFormat: null, // TODO review eachDay: $.noop, numberOfMonths: 1, @@ -51,12 +52,13 @@ $.widget( "ui.datepicker", { hide: true, // callbacks + beforeOpen: null, close: null, open: null, select: null }, _create: function() { - this.date = $.date(); + this.date = $.date( null, this.options.dateFormat ); this.date.eachDay = this.options.eachDay; this.id = "ui-datepicker-" + idIncrement; idIncrement++; @@ -511,8 +513,8 @@ $.widget( "ui.datepicker", { 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() { @@ -529,7 +531,7 @@ $.widget( "ui.datepicker", { } }, _refreshMultiplePicker: function() { - for (var i = 0; i < this.options.numberOfMonths; i++ ) { + for ( var i = 0; 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 ); @@ -541,9 +543,12 @@ $.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.date = $.date( this.element.val(), this.options.dateFormat ); this.date.eachDay = this.options.eachDay; this.date.select(); this.refresh(); From 9ec69ccb73910af57a8457a65d19a98d34af2c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rn=20Zaefferer?= Date: Wed, 11 Sep 2013 18:19:27 +0200 Subject: [PATCH 004/179] Datepicker: Fix the `eachDay` option Use the `eachDay` option in the other-months demo. Fix handling of `extraClasses` property, split on space. --- demos/datepicker/other-months.html | 9 +++++++-- external/date.js | 5 +++-- ui/datepicker.js | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/demos/datepicker/other-months.html b/demos/datepicker/other-months.html index bad2b1977fa..bfb3f1af36f 100644 --- a/demos/datepicker/other-months.html +++ b/demos/datepicker/other-months.html @@ -17,8 +17,13 @@ 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/datepicker.js b/ui/datepicker.js index f1b9dc6c01c..625991d8842 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -476,7 +476,7 @@ $.widget( "ui.datepicker", { classes.push( "ui-state-highlight" ); } if ( day.extraClasses ) { - classes.push( day.extraClasses.split( "" ) ); + classes.push( day.extraClasses.split( " " ) ); } link = "" + @@ -495,7 +495,7 @@ $.widget( "ui.datepicker", { classes.push( "ui-state-highlight" ); } if ( day.extraClasses ) { - classes.push( day.extraClasses.split( "" ) ); + classes.push( day.extraClasses.split( " " ) ); } return "" + From 9bdb4783fd54fde15810f7f291f5011913d7338b Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 30 Oct 2013 09:11:06 -0400 Subject: [PATCH 005/179] 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 the focus logic off of that. --- ui/datepicker.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 625991d8842..55b6c0f74ac 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -166,8 +166,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() { @@ -538,6 +538,10 @@ $.widget( "ui.datepicker", { } 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 8983fee99174ab0a6b0f3262075f25178fa27430 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Sat, 2 Nov 2013 09:54:05 -0400 Subject: [PATCH 006/179] Datepicker: Clean up tests --- tests/unit/datepicker/datepicker.html | 6 +- tests/unit/datepicker/datepicker_core.js | 672 +++++++++--------- tests/unit/datepicker/datepicker_events.js | 56 +- tests/unit/datepicker/datepicker_methods.js | 181 ++--- tests/unit/datepicker/datepicker_options.js | 28 +- .../datepicker/datepicker_test_helpers.js | 9 +- 6 files changed, 443 insertions(+), 509 deletions(-) diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 2b3feb9e343..31fd709efbe 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -43,8 +43,10 @@
      -
      -

      + + + +
      diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 7b9dd2b9392..8795b5a7e89 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -12,38 +12,27 @@ module( "datepicker: core", { TestHelpers.testJshint( "datepicker" ); -test( "widget method - empty collection", function() { - expect( 1 ); - $( "#nonExist" ).datepicker(); // should create nothing - ok( !$( "#ui-datepicker-div" ).length, "Non init on empty collection" ); -}); - -test("widget method", function() { - expect( 1 ); - var actual = $("#inp").datepicker().datepicker("widget")[0]; - deepEqual($("body > #ui-datepicker-div:last-child")[0], actual); -}); - asyncTest( "baseStructure", function() { - expect( 58 ); + expect( 42 ); 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" ); @@ -62,10 +51,11 @@ 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( "hide" ).datepicker( "destroy" ); + inp.datepicker( "close" ).datepicker( "destroy" ); step2(); }); } @@ -77,10 +67,13 @@ asyncTest( "baseStructure", function() { changeYear: true, showButtonPanel: true }); - TestHelpers.datepicker.onFocus( inp, function() { + 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" ); @@ -88,7 +81,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(); }); } @@ -96,21 +89,25 @@ asyncTest( "baseStructure", function() { function step3() { // Multi-month 2 inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 2 }); - TestHelpers.datepicker.onFocus( inp, function() { + 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" ); ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + inp.datepicker( "close" ).datepicker( "destroy" ); step4(); }); } @@ -118,11 +115,13 @@ asyncTest( "baseStructure", function() { function step4() { // Multi-month 3 inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 3 }); - TestHelpers.datepicker.onFocus( inp, function() { + dp = inp.datepicker( "widget" ).find( ".ui-datepicker" ); + 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(); }); } @@ -130,7 +129,11 @@ asyncTest( "baseStructure", function() { function step5() { // Multi-month [2, 2] inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: [ 2, 2 ] }); - TestHelpers.datepicker.onFocus( inp, function() { + 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" ); @@ -151,368 +154,335 @@ 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" ); - - // 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" ); - - 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" ); - - inl.datepicker( "destroy" ); - - // Inline multi-month - inl = TestHelpers.datepicker.init( "#inl", { numberOfMonths: 2 } ); - dp = inl.children(); - - 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" ); - - child = dp.children( ":first" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" ); - - 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" ); - - child = dp.children( ":eq(2)" ); - ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" ); - - inl.datepicker( "destroy" ); - start(); + */ + inp.datepicker( "close" ).datepicker( "destroy" ); + step6(); }); } - step1(); -}); + function step6() { + // Inline + inl = TestHelpers.datepicker.init( "#inline" ); + dp = inl.children(); -asyncTest( "customStructure", function() { - expect( 20 ); - var header, panel, title, thead, - inp = TestHelpers.datepicker.initNewInput( $.datepicker.regional.he ), - dp = $( "#ui-datepicker-div" ); + 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)" ); - function step1() { - inp.datepicker( "option", "showButtonPanel", true ); + 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" ); - TestHelpers.datepicker.onFocus( inp, function() { - ok( dp.is( ".ui-datepicker-rtl" ), "Structure RTL - right-to-left" ); + 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" ); - header = dp.children( ":first" ); - ok( header.is( "div.ui-datepicker-header" ), "Structure RTL - header division" ); - equal( header.children().length, 3, "Structure RTL - header child count" ); - ok( header.children( ":first" ).is( "a.ui-datepicker-next" ), "Structure RTL - prev link" ); - ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-prev" ), "Structure RTL - next link" ); + inl.datepicker( "destroy" ); - panel = dp.children( ":last" ); - ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure RTL - button division" ); - equal( panel.children().length, 2, "Structure RTL - button panel child count" ); - 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" ); + // TODO: Calling destroy() on inline pickers currently does not work. + inl.empty(); - inp.datepicker( "hide" ).datepicker( "destroy" ); - step2(); - }); + step7(); } - // Hide prev/next - function step2() { - 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" ); + function step7() { + // Inline multi-month + inl = TestHelpers.datepicker.init( "#inline", { numberOfMonths: 2 } ); + dp = inl.datepicker( "widget" ).find( ".ui-datepicker" ); - TestHelpers.datepicker.onFocus( inp, function() { - header = dp.children( ":first" ); - ok( header.is( "div.ui-datepicker-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-datepicker-title" ), "Structure hide prev/next - title 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" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - step3(); - }); - } + 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" ); - // Changeable Month with read-only year - function step3() { - inp = TestHelpers.datepicker.initNewInput({ changeMonth: true }); + 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" ); - TestHelpers.datepicker.onFocus( inp, 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" ); + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - step4(); - }); + inl.datepicker( "destroy" ); + start(); } - // Changeable year with read-only month - function step4() { - inp = TestHelpers.datepicker.initNewInput({ changeYear: true }); + step1(); +}); - 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" ); +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; - inp.datepicker( "hide" ).datepicker( "destroy" ); - step5(); - }); - } + expect( 24 ); + var inp = TestHelpers.datepicker.init( "#datepicker" ), + date = new Date(); - // Read-only first day of week - function step5() { - inp = TestHelpers.datepicker.initNewInput({ changeFirstDay: false }); + inp.val( "" ).datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER }); + TestHelpers.datepicker.equalsDate( inp.val(), date, "Keystroke enter" ); - 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.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.datepicker( "hide" ).datepicker( "destroy" ); - start(); - }); - } + 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" ); - // 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 ); -}); + inp.val( "02/04/2008" ).datepicker( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END }); + ok( inp.datepicker( "getDate" ) == null, "Keystroke ctrl+end" ); -test("keystrokes", function() { - expect( 26 ); - 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.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() { +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( "#datepicker" ), + 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( "#inline" ); + 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); diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index dfc42ccf911..63e2b0e9cc7 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -1,10 +1,29 @@ -/* - * datepicker_events.js - */ -(function($) { +(function( $ ) { + +module( "datepicker: events" ); + +test( "beforeOpen", function() { + expect( 0 ); +}); + +test( "close", function() { + expect( 0 ); +}); -module("datepicker: events"); +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: +// 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 +144,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 ); diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index e52e126d2e6..e00f886444e 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -1,125 +1,72 @@ -/* - * 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( "#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" ); + + 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" ); }); -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( "#datepicker" ), + 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( "#inline" ); + 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. +}); + +test( "widget", function() { + expect( 1 ); + var actual = $( "#datepicker" ).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); +})( jQuery ); diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 08c31f5ad4a..fedfe7dd5ed 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -1,11 +1,28 @@ -/* - * datepicker_options.js - */ +(function( $ ) { + +module( "datepicker: options" ); + +test( "dateFormat", function() { + expect( 0 ); +}); -(function($) { +test( "eachDay", function() { + expect( 0 ); +}); -module("datepicker: options"); +test( "numberOfMonths", function() { + expect( 0 ); +}); +test( "position", function() { + expect( 0 ); +}); + +test( "showWeek", function() { + expect( 0 ); +}); + +/* test("setDefaults", function() { expect( 3 ); TestHelpers.datepicker.init("#inp"); @@ -1120,5 +1137,6 @@ test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler equal( dp.css( "display" ), "none","beforeShow returns false" ); inp.datepicker( "destroy" ); }); +*/ })(jQuery); diff --git a/tests/unit/datepicker/datepicker_test_helpers.js b/tests/unit/datepicker/datepicker_test_helpers.js index 82610393bec..e99014fc049 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 b5893906dfe62df4951d7bb55faf0f081390b633 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 15 Nov 2013 08:42:20 -0500 Subject: [PATCH 007/179] Datepicker: Support changing the `appendTo` option after init --- tests/unit/datepicker/datepicker_options.js | 38 +++++++++++++++++++++ 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 fedfe7dd5ed..72f459db0dc 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( "dateFormat", function() { expect( 0 ); }); diff --git a/ui/datepicker.js b/ui/datepicker.js index 55b6c0f74ac..28fd9191a1b 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -618,6 +618,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 5fbe668d8615b86aca58d7c0e36de133b63baa29 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 15 Nov 2013 09:17:13 -0500 Subject: [PATCH 008/179] 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/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 72f459db0dc..67302345c63 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/datepicker.js b/ui/datepicker.js index 28fd9191a1b..7264a556e2c 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -407,7 +407,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] ); @@ -436,7 +436,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] ); @@ -625,6 +625,10 @@ $.widget( "ui.datepicker", { if ( key === "appendTo" ) { this.picker.appendTo( this._appendTo() ); } + + if ( key === "showWeek" ) { + this.refresh(); + } } }); From 1a83120fff6e3c38cddea73292b929b1e3ff0bfd Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Mon, 18 Nov 2013 09:23:15 -0500 Subject: [PATCH 009/179] Datepicker: Support `position` option changes after init --- tests/unit/datepicker/datepicker_options.js | 28 +++++++++++++++++++-- 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 67302345c63..9218303edac 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 = $( "" ).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/datepicker.js b/ui/datepicker.js index 7264a556e2c..6839ca7e4d8 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -557,15 +557,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 ); @@ -595,6 +591,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(); @@ -629,6 +630,10 @@ $.widget( "ui.datepicker", { if ( key === "showWeek" ) { this.refresh(); } + + if ( key === "position" ) { + this.picker.position( this._buildPosition() ); + } } }); From 13cd6c2fe5f25181ea0fcea6f7a20f57469a317b Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Tue, 19 Nov 2013 08:35:19 -0500 Subject: [PATCH 010/179] Datepicker: Support changing `eachDay` after initialization --- tests/unit/datepicker/datepicker_options.js | 38 ++++++++++++++++++++- 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 9218303edac..52ae74a746e 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/datepicker.js b/ui/datepicker.js index 6839ca7e4d8..3afe5afd009 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -627,6 +627,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 ab94999105868ff7780f2a788452748c4e952be9 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 20 Nov 2013 08:37:24 -0500 Subject: [PATCH 011/179] Datepicker: Allow `dateFormat` to be changed after init --- tests/unit/datepicker/datepicker_options.js | 14 +++++++++++++- 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 52ae74a746e..3b69acf1a33 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/datepicker.js b/ui/datepicker.js index 3afe5afd009..abb18a44b98 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -632,6 +632,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 bfd8f26bb4de432cbf79a507a458a7530ea8c39b Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Wed, 20 Nov 2013 08:53:02 -0500 Subject: [PATCH 012/179] Datepicker: Add test to ensure the ``'s value is preselected --- tests/unit/datepicker/datepicker_core.js | 29 +++++++++++++++--------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 8795b5a7e89..cd1a64939b2 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -1,17 +1,24 @@ -/* - * datepicker_core.js - */ +(function( $ ) { -(function($) { - -module( "datepicker: core", { - setup: function() { - $( "body" ).focus(); - } -}); +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, @@ -485,4 +492,4 @@ test( "mouse", function() { "Mouse click inline - next" ); }); -})(jQuery); +})( jQuery ); From cc5a4bc5c88a682b862e0db1a44a9ecd40900c1c Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 22 Nov 2013 08:55:04 -0500 Subject: [PATCH 013/179] Datepicker: Support destroying inline datepickers --- tests/unit/datepicker/datepicker_core.js | 3 -- tests/unit/datepicker/datepicker_methods.js | 32 ++++++++++----------- ui/datepicker.js | 4 ++- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index cd1a64939b2..1e3ec1fb8e5 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(); } diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index e00f886444e..e204b804544 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" ); + expect( 10 ); + var input = $( "#datepicker" ).datepicker(), + inline = $( "#inline" ).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" ); + 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" ); - 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( 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/datepicker.js b/ui/datepicker.js index abb18a44b98..9d8813a29f5 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -610,7 +610,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 e87a5d8c0520e64cadbe5903b9ef803f526e698d Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 21 Nov 2013 09:03:08 -0500 Subject: [PATCH 014/179] Datepicker: Add `value()` and `valueAsDate()` methods --- tests/unit/datepicker/datepicker_methods.js | 46 ++++++++++++++++++++- ui/datepicker.js | 21 ++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index e204b804544..dcd6dc2c7aa 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -64,7 +64,51 @@ test( "open", function() { }); test( "value", function() { - expect( 0 ); + expect( 5 ); + var input = $( "#datepicker" ).datepicker(), + 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. + + input.datepicker( "destroy" ); + inline.datepicker( "destroy" ); +}); + +test( "valueAsDate", function() { + expect( 5 ); + var input = $( "#datepicker" ).datepicker(), + 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. + + input.datepicker( "destroy" ); + inline.datepicker( "destroy" ); }); })( jQuery ); diff --git a/ui/datepicker.js b/ui/datepicker.js index 9d8813a29f5..425e81a727c 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -609,6 +609,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._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.empty(); From ff4bfd643d4f30eb171ab8e40600fe8963ddfb1b Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 22 Nov 2013 09:30:11 -0500 Subject: [PATCH 015/179] Datepicker: Fix key handling implementation and tests --- tests/unit/datepicker/datepicker_core.js | 210 +++++++++++++++-------- ui/datepicker.js | 24 +++ 2 files changed, 158 insertions(+), 76 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 1e3ec1fb8e5..e32a0bb86a5 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -218,170 +218,228 @@ asyncTest( "baseStructure", 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( 8 ); + var input = $( "#datepicker" ).datepicker(), + instance = input.datepicker( "instance" ), 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" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + // Enter = Select today's date by default + 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" ) + // 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(inp.datepicker( "getDate" ), date, "Keystroke ctrl+home" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+home" ); - inp.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( inp.datepicker( "getDate" ) == null, "Keystroke ctrl+end" ); + equal( input.val(), "", "Keystroke ctrl+end" ); - inp.val( "" ).datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE }); - ok(inp.datepicker("getDate") == 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" ); - inp.val( "02/04/2008" ).datepicker( "open" ) + input.val( "1/1/2014" ).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( 2014, 0, 1 ), "Keystroke esc - preset" ); - inp.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( inp.datepicker( "getDate" ), new Date(2008, 2 - 1, 4), + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Keystroke esc - abandoned" ); - // Moving by day or week - 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}); + input.datepicker( "destroy" ); +}); + +asyncTest( "keyboard handling - arrow keys", function() { + expect( 6 ); + var picker, + input = $( "#datepicker" ), + date = new Date(); + + 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( 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" ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+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" ); -}); +*/ test( "mouse", function() { // TODO: These tests use the old getDate() and setDate() methods. Re-activate these diff --git a/ui/datepicker.js b/ui/datepicker.js index 425e81a727c..66220691211 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -59,6 +59,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++; @@ -197,6 +198,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 ); @@ -205,6 +209,26 @@ $.widget( "ui.datepicker", { this.grid.focus(); }, 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 ffc8ab2710c2cf9769cbdc8b253e7a82e9e8a53f Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Sat, 30 Nov 2013 10:22:17 -0200 Subject: [PATCH 016/179] Datepicker: Use Globalize 1.0.0 --- demos/datepicker/date-formats.html | 25 +- demos/datepicker/localization.html | 9 +- demos/datepicker/show-week.html | 10 +- external/date.js | 73 +- external/globalize/globalize.culture.de-DE.js | 81 - external/globalize/globalize.culture.ja-JP.js | 100 - external/globalize/globalize.js | 3065 +++++++------- external/localization.js | 3545 +++++++++++++++-- tests/unit/date/date.html | 6 +- tests/unit/date/date_core.js | 90 +- tests/unit/datepicker/datepicker.html | 6 +- tests/unit/datepicker/datepicker_core.js | 12 +- tests/unit/datepicker/datepicker_methods.js | 12 +- tests/unit/datepicker/datepicker_options.js | 8 +- ui/datepicker.js | 28 +- 15 files changed, 4863 insertions(+), 2207 deletions(-) delete mode 100644 external/globalize/globalize.culture.de-DE.js delete mode 100644 external/globalize/globalize.culture.ja-JP.js diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index 1b8874f8cf6..2c5045b6f33 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/localization.html b/demos/datepicker/localization.html index b8c99547b7b..61aa7c9a2da 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 e9a33d8da16..c7faf102052 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 fef4dcaeffe..b8d1ef30d33 100644 --- a/external/date.js +++ b/external/date.js @@ -6,25 +6,31 @@ */ (function( $, undefined ) { -$.date = function( datestring, formatstring ) { - //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 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" ); - if ( !date ) { - date = new Date(); +$.date = function( date, globalFormat ) { + //TODO: Need to refactor $.date to be a constructor, move the methods to a prototype. + if ( typeof date === "string" && date.length ) { + date = Globalize.parseDate( date, globalFormat ); } + date = date || new Date(); + return { - refresh: function() { - calendar = Globalize.culture().calendar; - format = formatstring || calendar.patterns.d; - return this; - }, - setFormat: function( formatstring ) { - if ( formatstring ) { - format = formatstring; + setFormat: function( format ) { + if ( format ) { + globalFormat = format; } return this; }, @@ -82,7 +88,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 +107,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,12 +119,12 @@ $.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++ ) { var week = result[ result.length ] = { - number: this.iso8601Week( printDate ), + number: Globalize.format( printDate, { pattern: "w" } ), days: [] }; for ( var dayx = 0; dayx < 7; dayx++ ) { @@ -153,16 +159,6 @@ $.date = function( datestring, formatstring ) { 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; @@ -170,27 +166,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()), globalFormat ); }, // 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 || globalFormat ); } }; }; diff --git a/external/globalize/globalize.culture.de-DE.js b/external/globalize/globalize.culture.de-DE.js deleted file mode 100644 index 5466bd75e3b..00000000000 --- a/external/globalize/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/globalize.culture.ja-JP.js b/external/globalize/globalize.culture.ja-JP.js deleted file mode 100644 index a9469d709f4..00000000000 --- a/external/globalize/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/globalize.js b/external/globalize/globalize.js index a38a32625d3..1086d339db9 100644 --- a/external/globalize/globalize.js +++ b/external/globalize/globalize.js @@ -1,1585 +1,1788 @@ /*! - * Globalize + * Globalize v1.0.0pre * * http://github.com/jquery/globalize * - * Copyright Software Freedom Conservancy, Inc. - * Dual licensed under the MIT or GPL Version 2 licenses. + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license * http://jquery.org/license + * + * Date: 2013-12-01T12:08Z */ - -(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; +(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(); } -}; -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; +}( this, function() { -Globalize.cultures.en = Globalize.cultures[ "default" ]; +/** + * 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() { -Globalize.cultureSelector = "en"; -// -// private variables -// -regexHex = /^0x[a-f0-9]+$/i; -regexInfinity = /^[+\-]?infinity$/i; -regexParseFloat = /^[+\-]?\d*\.?\d*(e[+\-]?\d+)?$/; -regexTrim = /^\s+|\s+$/g; + var alwaysArray = function( stringOrArray ) { + return typeof stringOrArray === "string" ? [ stringOrArray ] : stringOrArray; + }; -// -// 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; - } + var common = function( Cldr ) { - // 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 : []; + Cldr.prototype.main = function( path ) { + path = alwaysArray( path ); + return this.get( [ "main/{languageId}" ].concat( path ) ); + }; - } 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]"; -}; + var arrayIsArray = 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, "" ); -}; + 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 */ -truncate = function( value ) { - if ( isNaN( value ) ) { - return NaN; - } - return Math[ value < 0 ? "ceil" : "floor" ]( value ); -}; + // Replace {attribute}'s + path = path.replace( /{[a-zA-Z]+}/g, function( name ) { + name = name.replace( /^{([^}]*)}$/, "$1" ); + return attributes[ name ]; + }); -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 + "\'."; + return path.split( "/" ); + }; + + + + + var arraySome = function( array, callback ) { + var i, length; + if ( array.some ) { + return array.some( callback ); } - 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(); + for ( i = 0, length = array.length; i < length; i++ ) { + if ( callback( array[ i ], i, array ) ) { + return true; } } - else { - ret = value.toString(); - } - return ret; - } + return false; + }; - 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; + + // 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; } - } + }; + - 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 ); + // 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; + }; - // 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 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 ) + "\"" ); } - var current = ar[ 0 ], - clength = current.length; + // 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 - 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 ); + 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; - case "f": - // Deciseconds - case "ff": - // Centiseconds - case "fff": - // Milliseconds - ret.push( - padZeros( value.getMilliseconds(), 3 ).substr( 0, clength ) - ); + + // 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; - 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 ) - ); + + // 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; - 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 ) - ); + + // language.., or root + case /^([a-z]{2}|root)(\b|_)/.test( unicodeLanguageId ): + language = unicodeLanguageId.split( "_" )[ 0 ]; + script = "Zzzz"; + territory = "ZZ"; + variant = unicodeLanguageId.split( "_" )[ 1 ]; break; - case "g": - case "gg": - if ( cal.eras ) { - ret.push( - cal.eras[ getEra(value, eras) ].name - ); - } + + default: + language = "und"; 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 ); + + // 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; + } } - else if ( exponent < 0 ) { - exponent = -exponent; - numberString = zeroPad( numberString, exponent + 1, true ); - right = numberString.slice( -exponent, numberString.length ) + right; - numberString = numberString.slice( 0, -exponent ); + return node[ path[ i ] ]; + }; + + + + + var bundleParentLookup = function( Cldr, locale ) { + var parent; + + if ( locale === "root" ) { + return; } - if ( precision > 0 ) { - right = formatInfo[ "." ] + - ( (right.length > precision) ? right.slice(0, precision) : zeroPad(right, precision) ); + // First, try to find parent on supplemental data. + parent = resourceGet( Cldr._resolved, pathNormalize( [ "supplemental/parentLocales/parentLocale", locale ] ) ); + if ( parent ) { + return parent; } - else { - right = ""; + + // Or truncate locale. + parent = locale.substr( 0, locale.lastIndexOf( "_" ) ); + if ( !parent ) { + return "root"; } - var stringIndex = numberString.length - 1, - sep = formatInfo[ "," ], - ret = ""; + return parent; + }; + - 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++; + // @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 ] ]; } - - return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right; + node[ path[ i ] ] = value; }; - 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; + + + + var arrayForEach = function( array, callback ) { + var i, length; + if ( array.forEach ) { + return array.forEach( callback ); } - if ( !format || format === "i" ) { - return culture.name.length ? value.toLocaleString() : value.toString(); + for ( i = 0, length = array.length; i < length; i++ ) { + callback( array[ i ], i, array ); } - 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 ); + }; + + + 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 ]; + } - 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; + } + }); + 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; } - var patternParts = /n|\$|-|%/g, - ret = ""; - for ( ; ; ) { - var index = patternParts.lastIndex, - ar = patternParts.exec( pattern ); + // Resolve path + normalizedPath = pathNormalize( path, attributes ); - ret += pattern.slice( index, ar ? ar.index : pattern.length ); + // Check resolved (cached) data first + value = resourceGet( Cldr._resolved, normalizedPath ); + if ( value ) { + return value; + } - if ( !ar ) { - break; - } + // Check raw data + value = resourceGet( Cldr._raw, normalizedPath ); - 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; - } + if ( !value ) { + // Or, lookup at parent locale + parent = bundleParentLookup( Cldr, locale ); + value = lookup( Cldr, parent, path, jsonMerge( attributes, { languageId: parent }), locale ); } - return ret; + // Set resolved (cached) + resourceSet( Cldr._resolved, normalizedPath, value ); + + return value; }; + return lookup; + }()); -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; + + var itemGetResolved = function( Cldr, path, attributes ) { + // Resolve path + var normalizedPath = pathNormalize( path, attributes ); + + return resourceGet( Cldr._resolved, normalizedPath ); }; - 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 ); + + + + 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" ); } - return ret; + Cldr._raw = jsonMerge( Cldr._raw, json ); }; - 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 ) - ]; + 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 ); } - value = toUpper( value ); - var i = arrayIndexOf( abbr ? upperMonths[1] : upperMonths[0], value ); - if ( i < 0 ) { - i = arrayIndexOf( abbr ? upperMonthsGen[1] : upperMonthsGen[0], value ); + for ( clone = [], i = 0, length = array.length; i < length; i++ ) { + clone[ i ] = callback( array[ i ], i, array ); } - return i; + return clone; }; - 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; - } + + + + var objectValues = function( object ) { + var i, + result = []; + + for ( i in object ) { + result.push( object[ i ] ); } - // 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; + 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 }; + }); + }; - // 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?)"; + + + + /** + * 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 "zzz": - add = "([+-]?\\d\\d?:\\d{2})"; + + 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 "zz": case "z": - add = "([+-]?\\d\\d?)"; + + 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 "/": - add = "(\\/)"; + + case "pattern" in pattern: + result = pattern.pattern; break; + default: - throw "Invalid date format pattern \'" + m + "\'."; + throw new Error( "Invalid pattern" ); } - if ( add ) { - regexp.push( add ); - } - groups.push( match[0] ); + + } else { + throw new Error( "Invalid pattern" ); } - 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 }; + if ( !result ) { + throw new Error( "Pattern not found" ); + } - // cache the regex for this format. - return re[ format ] = parseRegExp; + return result; }; - outOfRange = function( value, low, high ) { - return value < low || value > high; + + + 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; }; - toUpper = function( value ) { - // "he-IL" has non-breaking space in weekday names. - return value.split( "\u00A0" ).join( " " ).toUpperCase(); + + + + /** + * firstDayOfWeek + */ + var datetimeFirstDayOfWeek = function( cldr ) { + return arrayIndexOf( datetimeWeekDays, cldr.supplemental.weekData.firstDay() ); }; - toUpperArray = function( arr ) { - var results = []; - for ( var i = 0, l = arr.length; i < l; i++ ) { - results[ i ] = toUpper( arr[i] ); - } - return results; + + + + /** + * 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; }; - 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; - } + + + + /** + * 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 ); } - // if pm designator token was found make sure the hours fit the 24-hour clock. - if ( pmHour && hour < 12 ) { - hour += 12; + 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 ); } - 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 ); + for ( length = str.length; length < count; length += 1 ) { + str = ( right ? ( str + "0" ) : ( "0" + str ) ); } - return result; + return str; }; -}()); -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; + + /** + * 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(); } - 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; - } + + 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; } - 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; + if ( pad ) { + ret = stringPad( ret, length ); } - return 0; + return ret; }); - // exact match - for ( i = 0; i < l; i++ ) { - lang = prioritized[ i ].lang; - match = cultures[ lang ]; - if ( match ) { - return match; + }; + + + + + 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; + }; - // neutral language match - for ( i = 0; i < l; i++ ) { - lang = prioritized[ i ].lang; - do { - var index = lang.lastIndexOf( "-" ); - if ( index === -1 ) { - break; + + + + /** + * 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/; } - // strip off the last part. e.g. en-US => en - lang = lang.substr( 0, index ); - match = cultures[ lang ]; - if ( match ) { - return match; + } + + function oneOrTwoDigitsIfLengthOne() { + if ( length === 1 ) { + return tokenRe = /\d\d?/; } } - 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; + function twoDigitsIfLengthTwo() { + if ( length === 2 ) { + return tokenRe = /\d\d/; } } - } - } - 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; -}; + // 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; + } -Globalize.localize = function( key, cultureSelector ) { - return this.findClosestCulture( cultureSelector ).messages[ key ] || - this.cultures[ "default" ].messages[ key ]; -}; + token.type = current; + chr = current.charAt( 0 ), + length = current.length; -Globalize.parseDate = function( value, formats, culture ) { - culture = this.findClosestCulture( culture ); + switch ( chr ) { - 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 ) { + // 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; } - } - } - } - } else { - patterns = culture.calendar.patterns; - for ( prop in patterns ) { - date = parseExact( value, patterns[prop], culture ); - if ( date ) { - 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 = /./; } - } - } - return date || null; -}; + if ( !tokenRe ) { + return false; + } -Globalize.parseInt = function( value, radix, cultureSelector ) { - return truncate( Globalize.parseFloat(value, radix, cultureSelector) ); -}; + // Get lexeme and consume it. + value = value.replace( new RegExp( "^" + tokenRe.source ), function( lexeme ) { + token.lexeme = lexeme; + return ""; + }); -Globalize.parseFloat = function( value, radix, cultureSelector ) { - // radix argument is optional - if ( typeof radix !== "number" ) { - cultureSelector = radix; - radix = 10; - } + if ( !token.lexeme ) { + return false; + } - var culture = this.findClosestCulture( cultureSelector ); - var ret = NaN, - nf = culture.numberFormat; + tokens.push( token ); + return true; + }); - 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["."] ); - } + return valid ? tokens : []; + }; - //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, "" ); + var datetimeParse = (function() { - // allow infinity or hexidecimal - if ( regexInfinity.test(value) ) { - ret = parseFloat( value ); - } - else if ( !radix && regexHex.test(value) ) { - ret = parseInt( value, 16 ); + function outOfRange( value, low, high ) { + return value < low || value > high; } - 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 ]; + /** + * 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; } - sign = sign || "+"; + valid = arrayEvery( tokens, function( token ) { + var century, chr, value, length; - // 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 ); + 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; } - // 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( "" ); + + if ( era === 0 ) { + // 1 BC = year 0 + date.setFullYear( date.getFullYear() * -1 + 1 ); } - // build a natively parsable number string - var p = sign + integer; - if ( fraction !== null ) { - p += "." + fraction; + + if ( amPm === "pm" && date.getHours() !== 12 ) { + date.setHours( date.getHours() + 12 ); } - if ( exponent !== null ) { - // exponent itself may have a number patternd - var expSignInfo = parseNegativePattern( exponent, nf, "-n" ); - p += "e" + ( expSignInfo[0] || "+" ) + expSignInfo[ 1 ]; + + // 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 ); } - if ( regexParseFloat.test(p) ) { - ret = parseFloat( p ); + for ( i = 0, length = array.length; i < length; i++ ) { + if ( callback( array[ i ], i, array ) ) { + return true; + } } - } - return ret; -}; + return false; + }; + -Globalize.culture = function( cultureSelector ) { - // setter - if ( typeof cultureSelector !== "undefined" ) { - this.cultureSelector = cultureSelector; + + + var defaultLocale; + + function getLocale( locale ) { + return locale ? new Cldr( locale ) : defaultLocale; } - // getter - return this.findClosestCulture( cultureSelector ) || this.cultures[ "default" ]; -}; -}( this )); \ No newline at end of file + 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 d81e997b5e7..98d8f813052 100644 --- a/external/localization.js +++ b/external/localization.js @@ -1,436 +1,3119 @@ -// 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" + } + } + } + } + } + } + } + } +}); + +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 + */ + +// 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/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 31fd709efbe..b49fe5a4b41 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -8,8 +8,8 @@ - + diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index e32a0bb86a5..92687178060 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" ); @@ -228,19 +228,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" ); @@ -249,12 +249,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 3b69acf1a33..e541b7e7020 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/datepicker.js b/ui/datepicker.js index 66220691211..6ee7aaed173 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -58,6 +58,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; @@ -309,8 +310,6 @@ $.widget( "ui.datepicker", { return element; }, _createTmpl: function() { - this.date.refresh(); - this._createDatepicker(); this.picker.find( "button" ).button(); @@ -351,6 +350,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" : ""; @@ -384,7 +384,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() + @@ -428,7 +428,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 + ""; @@ -448,10 +448,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 + ""; }, @@ -488,7 +490,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" ); @@ -526,7 +528,7 @@ $.widget( "ui.datepicker", { day.date + ""; }, _buildButtons: function() { - var labels = Globalize.localize( "datepicker" ); + var labels = Globalize.translate( "datepicker" ); return "
      " + "" + "" + @@ -544,8 +546,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 605387d6fc8b81f23e376755c4ea20c428b9e003 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 27 Dec 2013 08:28:00 -0500 Subject: [PATCH 017/179] Datepicker: Update key handling implementation and tests --- tests/unit/datepicker/datepicker_core.js | 238 ++++++++++++++--------- ui/datepicker.js | 4 +- 2 files changed, 149 insertions(+), 93 deletions(-) diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 92687178060..1138d7e2eaf 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -263,8 +263,8 @@ test( "Keyboard handling", function() { input.datepicker( "destroy" ); }); -asyncTest( "keyboard handling - arrow keys", function() { - expect( 6 ); +asyncTest( "keyboard handling", function() { + expect( 14 ); var picker, input = $( "#datepicker" ), date = new Date(); @@ -299,134 +299,190 @@ asyncTest( "keyboard handling - arrow keys", 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" ); input.datepicker( "destroy" ); step4(); - }, 100); + }, 100 ); }; 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" ); input.datepicker( "destroy" ); - start(); - }, 100); + step5(); + }, 100 ); }; - step1(); -}); + function step5() { + input.datepicker() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); -/* - 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" ); + setTimeout(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" ); - // 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.datepicker( "destroy" ); + step6(); + }, 100 ); + }; - 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" ); + function step6() { + input.datepicker() + .val( "1/1/14" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN }); - 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" ); + setTimeout(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" ); - 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" ); + 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 previous 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_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 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" ); + step11(); + }, 100 ); + }; // 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 }) diff --git a/ui/datepicker.js b/ui/datepicker.js index 6ee7aaed173..43f640e4efa 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -127,10 +127,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 104f3e6be032d33d8339e0dc7f192b16cf41a867 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 2 Jan 2014 16:25:38 -0500 Subject: [PATCH 018/179] 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 1138d7e2eaf..c9d0403b240 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -498,109 +498,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 b4fe65a1347ebeb47d6deb05e5c49d76be01bb0b Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 3 Jan 2014 09:07:38 -0500 Subject: [PATCH 019/179] Datepicker: Add an `isValid()` method --- tests/unit/datepicker/datepicker_methods.js | 13 +++++++++++++ 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/datepicker.js b/ui/datepicker.js index 43f640e4efa..9f0e1905e82 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -654,6 +654,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 feedc57486debc7db9154dae3e507218f8acb135 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 3 Jan 2014 09:16:03 -0500 Subject: [PATCH 020/179] Datepicker: Handle invalid values in `value()` and `valueAsDate()` --- tests/unit/datepicker/datepicker_methods.js | 15 +++++++++------ 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/datepicker.js b/ui/datepicker.js index 9f0e1905e82..8711b5329d0 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -644,17 +644,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 fd215f18638556c739469ca481edd03246ec1eb6 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Fri, 3 Jan 2014 09:55:06 -0500 Subject: [PATCH 021/179] Datepicker: Update the picker as the user types valid dates --- tests/unit/datepicker/datepicker_core.js | 7 ++++++- 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 c9d0403b240..377c4c201dd 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -218,7 +218,7 @@ asyncTest( "baseStructure", function() { }); test( "Keyboard handling", function() { - expect( 8 ); + expect( 9 ); var input = $( "#datepicker" ).datepicker(), instance = input.datepicker( "instance" ), date = new Date(); @@ -260,6 +260,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/datepicker.js b/ui/datepicker.js index 8711b5329d0..5a3d9a19132 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -232,6 +232,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 a9d6a65651de3116067114f1c71da2be89622314 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 9 Jan 2014 09:15:42 -0500 Subject: [PATCH 022/179] Date: Update 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 77d7dd21a74f0b7097732d6316a49665d4716691 Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Thu, 9 Jan 2014 09:48:43 -0500 Subject: [PATCH 023/179] 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 cfea8df90a78109fd0a332376ea1d2065782c33b Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 23 Apr 2014 17:49:03 +0200 Subject: [PATCH 024/179] Datepicker: Fix code style issues --- demos/datepicker/show-week.html | 2 +- external/date.js | 2 +- tests/unit/datepicker/datepicker_core.js | 142 +- tests/unit/datepicker/datepicker_events.js | 151 +- tests/unit/datepicker/datepicker_methods.js | 2 +- tests/unit/datepicker/datepicker_options.js | 1218 ++++++++--------- .../datepicker/datepicker_test_helpers.js | 20 +- ui/datepicker.js | 62 +- 8 files changed, 821 insertions(+), 778 deletions(-) diff --git a/demos/datepicker/show-week.html b/demos/datepicker/show-week.html index c7faf102052..321698373ce 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/external/date.js b/external/date.js index 101afb17581..e7c17a58dcf 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/abbreviated", 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; diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 377c4c201dd..189f03d932a 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() { @@ -224,39 +224,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" ); @@ -279,38 +279,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" ); @@ -318,17 +318,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" ); @@ -336,17 +336,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" ); @@ -354,17 +354,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" ); @@ -372,17 +372,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" ); @@ -390,17 +390,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" ); @@ -408,17 +408,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" ); @@ -426,17 +426,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" ); @@ -444,18 +444,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" ); @@ -463,17 +463,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" ); @@ -481,23 +481,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" ); */ @@ -516,8 +516,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", {} ); @@ -547,15 +547,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" ); @@ -580,13 +580,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 e541b7e7020..17cc79f9a40 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: "-7Y", yearRange: "1900:-7" }).val( "" ); - ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - relative - next button disabled"); - ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - relative - prev button enabled"); + ok(dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - relative - next button disabled" ); + ok(!dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - relative - 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 - absolute - next button disabled"); - ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - absolute - prev button enabled"); + ok(dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - absolute - next button disabled" ); + ok(!dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - absolute - 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, @@ -927,86 +927,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++) { @@ -1016,7 +1016,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); @@ -1044,69 +1044,69 @@ 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 avr. 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 avr. 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() { @@ -1158,80 +1158,80 @@ test("parseDateErrors", function() { 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. avr. 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. avr. 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() { @@ -1266,7 +1266,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 e99014fc049..0023422e2ff 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 5a3d9a19132..929138c79b2 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -57,6 +57,7 @@ $.widget( "ui.datepicker", { open: null, select: null }, + _create: function() { this.options.dateFormat = this.options.dateFormat || { date: "short" }; this.date = $.date( null, this.options.dateFormat ); @@ -172,6 +173,7 @@ $.widget( "ui.datepicker", { newCell.children( "a" ).addClass( "ui-state-focus" ); } }, + _createPicker: function() { this.picker = $( "
      " ) .addClass( "ui-front" ) @@ -205,10 +207,10 @@ $.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 ); break; case $.ui.keyCode.HOME: if ( event.ctrlKey ) { @@ -257,7 +259,7 @@ $.widget( "ui.datepicker", { } this._delay( function() { suppressExpandOnFocus = false; - }, 100); + }, 100 ); }, blur: function() { suppressExpandOnFocus = false; @@ -271,7 +273,7 @@ $.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 ); @@ -296,6 +298,7 @@ $.widget( "ui.datepicker", { } }); }, + _appendTo: function() { var element = this.options.appendTo; @@ -310,7 +313,7 @@ $.widget( "ui.datepicker", { } if ( !element.length ) { - element = this.document[0].body; + element = this.document[ 0 ].body; } return element; @@ -363,10 +366,10 @@ $.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(); } @@ -380,8 +383,10 @@ $.widget( "ui.datepicker", { html += this._buildButtons(); this.date = currentDate; + return html; }, + _buildHeader: function() { return "
      " + this._buildPreviousLink() + @@ -389,8 +394,10 @@ $.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() + @@ -416,6 +427,7 @@ $.widget( "ui.datepicker", { ", " + labels.datePickerRole + "" + "
      "; }, + _buildTitle: function() { return "" + this.date.monthName() + @@ -424,6 +436,7 @@ $.widget( "ui.datepicker", { this.date.year() + ""; }, + _buildGrid: function() { return "" + @@ -431,6 +444,7 @@ $.widget( "ui.datepicker", { this._buildGridBody() + "
      "; }, + _buildGridHeading: function() { var cells = "", i = 0, @@ -442,10 +456,12 @@ $.widget( "ui.datepicker", { for ( i; i < this.date.weekdays().length; i++ ) { cells += this._buildGridHeaderCell( this.date.weekdays()[i] ); } + return "" + "" + cells + "" + ""; }, + _buildGridHeaderCell: function( day ) { return "" + "" + @@ -453,16 +469,20 @@ $.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; @@ -475,6 +495,7 @@ $.widget( "ui.datepicker", { } return "" + cells + ""; }, + _buildDayCell: function( day ) { var contents = "", idAttribute = day.render ? ( "id=" + this.id + "-" + day.date ) : "", @@ -493,6 +514,7 @@ $.widget( "ui.datepicker", { contents + ""; }, + _buildDayLink: function( day ) { var link, classes = [ "ui-state-default" ], @@ -516,10 +538,13 @@ $.widget( "ui.datepicker", { if ( day.today ) { link += ", " + labels.currentText + ""; } + return link; }, + _buildDayDisplay: function( day ) { var classes = []; + if ( day.current ) { classes.push( "ui-state-active" ); } @@ -530,20 +555,23 @@ $.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 @@ -560,6 +588,7 @@ $.widget( "ui.datepicker", { this._refreshMultiplePicker(); } }, + _refreshMultiplePicker: function() { for ( var i = 0; i < this.options.numberOfMonths; i++ ) { $( ".ui-datepicker-title", this.picker ).eq( i ).html( this._buildTitle() ); @@ -573,6 +602,7 @@ $.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; @@ -603,6 +633,7 @@ $.widget( "ui.datepicker", { this._trigger( "open", event ); }, + close: function( event ) { if ( this.inline ) { return; @@ -616,16 +647,19 @@ $.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(); @@ -639,6 +673,7 @@ $.widget( "ui.datepicker", { date: this.date.format() }); }, + _value: function( value ) { this.date.setTime( value ).select(); if ( !this.inline ) { @@ -646,6 +681,7 @@ $.widget( "ui.datepicker", { } this.refresh(); }, + value: function( value ) { if ( arguments.length ) { this._value( value ); @@ -653,6 +689,7 @@ $.widget( "ui.datepicker", { return this.isValid() ? this.date.format() : this.element.val(); } }, + valueAsDate: function( value ) { if ( arguments.length ) { this._value( value ); @@ -660,12 +697,15 @@ $.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(); @@ -676,9 +716,11 @@ $.widget( "ui.datepicker", { .removeAttr( "aria-owns" ); } }, + widget: function() { return this.picker; }, + _setOption: function( key, value ) { this._super( key, value ); From f28b70eb7a121bba06bb4043d97d4ee2d7d48fb6 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 13:30:09 +0200 Subject: [PATCH 025/179] 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 929138c79b2..2722c37b6f8 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -84,7 +84,7 @@ $.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(); @@ -94,7 +94,7 @@ $.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(); } @@ -660,7 +660,7 @@ $.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 9c66d2e92fd254c9e16964e26e3e8bf6a0a77483 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 14:31:28 +0200 Subject: [PATCH 026/179] 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 +- tests/unit/date/date_core.js | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/external/date.js b/external/date.js index e7c17a58dcf..06a67553205 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 ] ]) }); } 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 ab2cb90240a484d83bb456e35c22d06ad9c16f5b Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 14:44:31 +0200 Subject: [PATCH 027/179] Datepicker: Properly define default for `dateFormat` option --- ui/datepicker.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 2722c37b6f8..df454444783 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -39,7 +39,7 @@ var idIncrement = 0, $.widget( "ui.datepicker", { options: { appendTo: null, - dateFormat: null, + dateFormat: { date: "short" }, // TODO review eachDay: $.noop, numberOfMonths: 1, @@ -59,7 +59,6 @@ $.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 6324828ba0ef60f19fa1931fff49c7b748b99248 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 15:07:32 +0200 Subject: [PATCH 028/179] 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 4fd64bf6f19..89463fcdad9 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 a11e87c98e22a35153e0812defde407703a865c3 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 26 Apr 2014 14:05:56 +0200 Subject: [PATCH 029/179] Datepicker: Fix icon trigger demo --- demos/datepicker/icon-trigger.html | 31 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index e880df27e7f..03fb91f812f 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -16,21 +16,22 @@ From 35b52a0dfca4654c96db7b0c2871328404b6bee8 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 16 May 2014 00:19:32 +0200 Subject: [PATCH 030/179] Datepicker: Introduce value option Change status caching, fix existing value related methods, introduce $.date construction with date object, selected property is null by default, add selected getter --- external/date.js | 7 + tests/unit/datepicker/datepicker_core.js | 479 ++++++++------------ tests/unit/datepicker/datepicker_methods.js | 47 +- ui/datepicker.js | 119 +++-- 4 files changed, 279 insertions(+), 373 deletions(-) diff --git a/external/date.js b/external/date.js index 06a67553205..8df3f63de92 100644 --- a/external/date.js +++ b/external/date.js @@ -26,9 +26,13 @@ $.date = function( date, globalFormat ) { if ( typeof date === "string" && date.length ) { this.dateObject = Globalize.parseDate( date, globalFormat ); } + if ( $.type( date ) === "date" ) { + this.dateObject = date; + } this.dateObject = this.dateObject || new Date(); this.globalFormat = globalFormat; + this.selected = null; }; $.date.prototype = { @@ -180,6 +184,9 @@ $.date.prototype = { this.selected = this.clone(); return this; }, + selectedDate: function() { + return this.selected.date(); + }, clone: function() { var date = this.dateObject; return new $.date( new Date( date.getFullYear(), date.getMonth(), diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index 189f03d932a..e93836194c8 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -64,7 +64,7 @@ asyncTest( "baseStructure", function() { inp.datepicker( "close" ).datepicker( "destroy" ); step2(); - }); + }, 50 ); } function step2() { @@ -217,269 +217,223 @@ asyncTest( "baseStructure", function() { step1(); }); -test( "Keyboard handling", function() { +asyncTest( "Keyboard handling: input", function() { expect( 9 ); - var input = $( "#datepicker" ).datepicker(), - instance = input.datepicker( "instance" ), - date = new Date(); - - 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" ) - .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 } ); - 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 } ); - 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", function() { - expect( 14 ); - var picker, - input = $( "#datepicker" ), - date = new Date(); + var picker, instance, + input = $( "#datepicker" ).datepicker(); function step1() { - input.datepicker(); + TestHelpers.datepicker.init( input ); 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" ); step2(); - }); + }, 100 ); } function step2() { - input.datepicker(); + TestHelpers.datepicker.init( input ); 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" ); step3(); - }); + }, 100 ); } function step3() { - input.datepicker() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + TestHelpers.datepicker.init( input ); + instance = input.datepicker( "instance" ); - setTimeout(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" ); + input + .val( "" ) + .datepicker( "open" ); + ok( instance.isOpen, "datepicker is open before escape" ); - input.datepicker( "destroy" ); - step4(); - }, 100 ); - } + input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + ok( !instance.isOpen, "escape closes the datepicker" ); - function step4() { - input.datepicker() + input .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + .datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke esc - preset" ); - setTimeout(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" ); - - input.datepicker( "destroy" ); - step5(); - }, 100 ); + 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(); } - function step5() { - input.datepicker() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + step1(); +}); - setTimeout(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" ); +asyncTest( "keyboard handling: calendar", function() { + expect( 7 ); - input.datepicker( "destroy" ); - step6(); - }, 100 ); - } + var input = $( "#datepicker" ); - function step6() { - input.datepicker() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + function step1() { + 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 } ); - date = new Date( 2014, 1 - 1, 8 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke down to move to the next week" ); - - input.datepicker( "destroy" ); - step7(); + $( ":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" ); + step2(); + }, 50 ); }, 100 ); } - function step7() { - input.datepicker() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + function step2() { + 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.RIGHT } ) .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( 2014, 1 - 1, 2 ), + "Keystroke right to switch to next day" + ); input.datepicker( "destroy" ); - step8(); + step3(); }, 100 ); } - function step8() { - input.datepicker() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + function step3() { + 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 } ); - 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(); + $( ":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" ); + step4(); + }, 50 ); }, 100 ); } - function step9() { - input.datepicker() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + function step4() { + 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 } ); - date = new Date( 2014, 2 - 1, 1 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Down moves date to next month" ); - - input.datepicker( "destroy" ); - step10(); + $( ":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" ); + step5(); + }, 50 ); }, 100 ); } - function step10() { - input.datepicker() - .val( "1/1/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + function step5() { + 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 } ); - 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" ); - step11(); + $( ":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" ); + step6(); + }, 50 ); }, 100 ); } - // Check for moving to short months - function step11() { - input.datepicker() - .val( "3/31/14" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + function step6() { + 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 } ); - date = new Date( 2014, 2 - 1, 28 ); - TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, - "Keystroke Page Up and short months" ); - - input.datepicker( "destroy" ); - step12(); + $( ":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" ); + step7(); + }, 50 ); }, 100 ); } - function step12() { - input.datepicker() - .val( "1/30/16" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + // Check for moving to short months + function step7() { + 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_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" ); - - input.datepicker( "destroy" ); - start(); + $( ":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" ); + start(); + }, 50 ); }, 100 ); } @@ -502,110 +456,37 @@ asyncTest( "keyboard handling", function() { "Keystroke pgdn step 2" ); */ -test( "mouse", function() { - expect( 13 ); - var input = $( "#datepicker" ).datepicker(), - picker = input.datepicker( "widget" ), - inline = $( "#inline" ).datepicker, - date = new Date(); - - input.val( "" ).datepicker( "open" ); - $( ".ui-datepicker-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( "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" ) ; - - 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" ); - - 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 - 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" ); - - 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 - input.datepicker( "option", { - minDate: new Date( 2008, 2 - 1, 2 ), - maxDate: new Date( 2008, 2 - 1, 26 ) - }).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" ); - - 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 - inline = TestHelpers.datepicker.init( "#inline" ); - picker = $( ".ui-datepicker-inline", inline ); - date = new Date(); - inline.datepicker( "valueAsDate", date ); - $( ".ui-datepicker-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} ); - date.setDate( 10 ); - TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), date, "Mouse click inline" ); - - 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 } ); - $( ".ui-datepicker-current", picker ).simulate( "click", {} ); - $( ".ui-datepicker-calendar tbody a:contains(14)", picker ).simulate( "mousedown", {} ); - date.setDate( 14 ); - TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), date, "Mouse click inline - current" ); - - 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" ); - - 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" ); +asyncTest( "mouse", function() { + expect( 3 ); + + var input = TestHelpers.datepicker.init( $( "#datepicker" ).val( "" ) ), + picker = input.datepicker( "widget" ); + + input.datepicker( "open" ); + + setTimeout(function() { + input.simulate( "click" ); + strictEqual( 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" ); + picker.find( "a.ui-calendar-prev" ).simulate( "click" ); + input.simulate( "click" ); + TestHelpers.datepicker.equalsDate( + input.datepicker( "valueAsDate" ), + new Date( 2008, 2 - 1, 4 ), + "Mouse click - abandoned" + ); + + start(); + }, 100 ); }); })( jQuery ); diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 7efea106918..79a9d64e758 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -64,54 +64,43 @@ test( "open", function() { }); test( "value", function() { - expect( 6 ); + expect( 4 ); + var input = $( "#datepicker" ).datepicker(), - picker = input.datepicker( "widget" ), - inline = $( "#inline" ).datepicker(); + picker = input.datepicker( "widget" ); 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" ); + + input.datepicker( "open" ); + ok( picker.find( "a[data-timestamp]" ).eq( 0 ).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", - "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" ); - - input.datepicker( "destroy" ); - inline.datepicker( "destroy" ); + equal( input.datepicker( "value" ), "abc", "Invalid values should be returned without formatting." ); }); test( "valueAsDate", function() { expect( 6 ); - var input = $( "#datepicker" ).datepicker(), + + var input = TestHelpers.datepicker.init( "#datepicker" ), picker = input.datepicker( "widget" ), - inline = $( "#inline" ).datepicker(); + date1 = new Date( 2008, 6 - 1, 4 ); 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" ), - "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]" ).eq( 0 ).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" ); - 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" ); + input.val( "" ).datepicker( "destroy" ); + input = TestHelpers.datepicker.init( "#datepicker" ); - input.datepicker( "destroy" ); - inline.datepicker( "destroy" ); + strictEqual( input.datepicker( "valueAsDate" ), null, "Set date - default" ); + input.datepicker( "valueAsDate", date1 ); + TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date1, "Set date - 2008-06-04" ); }); test( "isValid", function() { diff --git a/ui/datepicker.js b/ui/datepicker.js index df454444783..b9ac17ac16f 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -33,14 +33,14 @@ // TODO use uniqueId, if possible var idIncrement = 0, - // TODO move this to the instance + // TODO Move this to the instance suppressExpandOnFocus = false; $.widget( "ui.datepicker", { options: { appendTo: null, dateFormat: { date: "short" }, - // TODO review + // TODO Review eachDay: $.noop, numberOfMonths: 1, position: { @@ -50,6 +50,7 @@ $.widget( "ui.datepicker", { showWeek: false, show: true, hide: true, + value: null, // callbacks beforeOpen: null, @@ -59,17 +60,22 @@ $.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(); @@ -91,8 +97,9 @@ $.widget( "ui.datepicker", { }, "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 + + // 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(); @@ -101,7 +108,7 @@ $.widget( "ui.datepicker", { "keydown .ui-datepicker-calendar": "_handleKeydown" }); - // TODO use hoverable (no delegation support)? convert to _on? + // 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" ); }); @@ -111,7 +118,8 @@ $.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(); @@ -161,7 +169,7 @@ $.widget( "ui.datepicker", { newId = this.id + "-" + this.date.day(); newCell = $( "#" + newId ); - // TODO unnecessary optimization? is it really needed? + // TODO Unnecessary optimization? is it really needed? if ( !newCell.length ) { return; } @@ -176,7 +184,8 @@ $.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(); @@ -191,6 +200,7 @@ $.widget( "ui.datepicker", { 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 ); @@ -235,12 +245,12 @@ $.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; @@ -267,7 +277,8 @@ $.widget( "ui.datepicker", { this._on( this.picker, { focusout: function( event ) { - // use a timer to allow click to clear it and letting that + + // 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() { @@ -280,7 +291,8 @@ $.widget( "ui.datepicker", { mouseup: function() { clearTimeout( this.closeTimer ); }, - // TODO on TAB (or shift TAB), make sure it ends up on something useful in DOM order + + // 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 ); @@ -317,6 +329,7 @@ $.widget( "ui.datepicker", { return element; }, + _createTmpl: function() { this._createDatepicker(); this.picker.find( "button" ).button(); @@ -324,10 +337,12 @@ $.widget( "ui.datepicker", { if ( this.inline ) { this.picker.children().addClass( "ui-datepicker-inline" ); } - // against display:none in datepicker.css + + // 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 = ""; @@ -350,6 +365,7 @@ $.widget( "ui.datepicker", { .html( pickerHtml ) .appendTo( this.picker ); }, + _buildMultiplePicker: function() { var headerClass, html = "", @@ -358,6 +374,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" : @@ -470,6 +487,7 @@ $.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, @@ -577,8 +595,9 @@ $.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() ); @@ -610,10 +629,6 @@ $.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 @@ -625,8 +640,8 @@ $.widget( "ui.datepicker", { 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 + // 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; @@ -654,46 +669,39 @@ $.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() - }); - }, - _value: function( value ) { - this.date.setTime( value ).select(); - if ( !this.inline ) { - this.element.val( this.date.format() ); - } - this.refresh(); + // TODO Replace with value option to initialise and read + date: this.value() + }); }, 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" ); } }, @@ -702,7 +710,7 @@ $.widget( "ui.datepicker", { return true; } - return Globalize.parseDate( this.element.val(), this.options.dateFormat ) !== null; + return this._getParsedValue() !== null; }, _destroy: function() { @@ -720,7 +728,28 @@ $.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 ( $.type( value ) === "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 510ba08cff1656775d7a4625624686fe07de926c Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 3 Jun 2014 23:18:51 +0200 Subject: [PATCH 031/179] Calendar: Add calendar widget Add calendar widget by copying and renaming datepicker widget files. Remove datepicker functionality, options and methods from Calendar. Remove calendar functionality, options and methods from Datepicker. Adjust tests due to split and changed specification. Remove duplicated demo files and fix some demos. Simplify calendar generation, use CSS instead of inline styles. Fix destroy method. Make use of uniqueId method. Fix focus highlighting when month is changed. Add version property. Add common unit tests. Fix input keyboard handling. --- Gruntfile.js | 1 + build/tasks/testswarm.js | 1 + demos/{datepicker => calendar}/buttonbar.html | 8 +- .../inline.html => calendar/default.html} | 10 +- .../dropdown-month-year.html | 8 +- demos/calendar/index.html | 22 + demos/calendar/localization.html | 41 + demos/{datepicker => calendar}/min-max.html | 8 +- .../multiple-calendars.html | 10 +- demos/calendar/multiple-months.html | 33 + .../other-months.html | 10 +- demos/{datepicker => calendar}/show-week.html | 10 +- demos/datepicker/alt-field.html | 36 - demos/datepicker/animation.html | 1 + demos/datepicker/date-formats.html | 30 +- demos/datepicker/date-range.html | 49 - demos/datepicker/default.html | 1 + demos/datepicker/icon-trigger.html | 1 + demos/datepicker/index.html | 13 +- demos/datepicker/localization.html | 1 + demos/index.html | 1 + tests/unit/all.html | 1 + tests/unit/calendar/all.html | 26 + tests/unit/calendar/calendar.html | 46 + tests/unit/calendar/calendar_common.js | 14 + tests/unit/calendar/calendar_core.js | 365 ++++++ tests/unit/calendar/calendar_events.js | 0 tests/unit/calendar/calendar_methods.js | 71 ++ tests/unit/calendar/calendar_options.js | 175 +++ tests/unit/calendar/calendar_test_helpers.js | 22 + tests/unit/datepicker/datepicker.html | 5 +- tests/unit/datepicker/datepicker_common.js | 22 +- tests/unit/datepicker/datepicker_core.js | 408 +----- tests/unit/datepicker/datepicker_methods.js | 65 +- tests/unit/datepicker/datepicker_options.js | 1131 +---------------- .../datepicker/datepicker_test_helpers.js | 2 +- tests/unit/index.html | 1 + themes/base/base.css | 1 + themes/base/calendar.css | 178 +++ themes/base/datepicker.css | 170 +-- ui/calendar.js | 497 ++++++++ ui/datepicker.js | 570 +-------- 42 files changed, 1723 insertions(+), 2342 deletions(-) rename demos/{datepicker => calendar}/buttonbar.html (84%) rename demos/{datepicker/inline.html => calendar/default.html} (69%) rename demos/{datepicker => calendar}/dropdown-month-year.html (82%) create mode 100644 demos/calendar/index.html create mode 100644 demos/calendar/localization.html rename demos/{datepicker => calendar}/min-max.html (81%) rename demos/{datepicker => calendar}/multiple-calendars.html (75%) create mode 100644 demos/calendar/multiple-months.html rename demos/{datepicker => calendar}/other-months.html (77%) rename demos/{datepicker => calendar}/show-week.html (77%) delete mode 100644 demos/datepicker/alt-field.html delete mode 100644 demos/datepicker/date-range.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 themes/base/calendar.css create mode 100644 ui/calendar.js diff --git a/Gruntfile.js b/Gruntfile.js index 3dba46987f8..6f5000c6fb8 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 bcbd764f829..957153777fa 100644 --- a/build/tasks/testswarm.js +++ b/build/tasks/testswarm.js @@ -13,6 +13,7 @@ var versions = { "Accordion": "accordion/accordion.html", "Autocomplete": "autocomplete/autocomplete.html", "Button": "button/button.html", + "Calendar": "calendar/calendar.html", "Core": "core/core.html", "Datepicker": "datepicker/datepicker.html", "Dialog": "dialog/dialog.html", diff --git a/demos/datepicker/buttonbar.html b/demos/calendar/buttonbar.html similarity index 84% rename from demos/datepicker/buttonbar.html rename to demos/calendar/buttonbar.html index 446bc9fe495..498fe1041f4 100644 --- a/demos/datepicker/buttonbar.html +++ b/demos/calendar/buttonbar.html @@ -2,7 +2,7 @@ - Codestin Search App + Codestin Search App @@ -11,12 +11,12 @@ + - @@ -11,21 +11,21 @@ + - -Date:
      +
      -

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

      +

      The calendar is a widget for selecting a date using a visual calendar representation.

      diff --git a/demos/datepicker/dropdown-month-year.html b/demos/calendar/dropdown-month-year.html similarity index 82% rename from demos/datepicker/dropdown-month-year.html rename to demos/calendar/dropdown-month-year.html index c6102917f43..050a89157ff 100644 --- a/demos/datepicker/dropdown-month-year.html +++ b/demos/calendar/dropdown-month-year.html @@ -2,7 +2,7 @@ - Codestin Search App + Codestin Search App @@ -11,12 +11,12 @@ + - + + + + + + + + + + + + + +
      + + +
      +

      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/datepicker/min-max.html b/demos/calendar/min-max.html similarity index 81% rename from demos/datepicker/min-max.html rename to demos/calendar/min-max.html index 6dcc16a48bc..c449bbdd55c 100644 --- a/demos/datepicker/min-max.html +++ b/demos/calendar/min-max.html @@ -2,7 +2,7 @@ - Codestin Search App + Codestin Search App @@ -11,18 +11,18 @@ + - -

      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/datepicker/multiple-calendars.html b/demos/calendar/multiple-calendars.html similarity index 75% rename from demos/datepicker/multiple-calendars.html rename to demos/calendar/multiple-calendars.html index 3d8278cd625..f67609d143e 100644 --- a/demos/datepicker/multiple-calendars.html +++ b/demos/calendar/multiple-calendars.html @@ -2,7 +2,7 @@ - Codestin Search App + Codestin Search App @@ -11,12 +11,12 @@ + - + + + + + + + + + + + + + +
      + +
      +

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

      +
      + + diff --git a/demos/datepicker/other-months.html b/demos/calendar/other-months.html similarity index 77% rename from demos/datepicker/other-months.html rename to demos/calendar/other-months.html index bfb3f1af36f..0228c62df5b 100644 --- a/demos/datepicker/other-months.html +++ b/demos/calendar/other-months.html @@ -2,7 +2,7 @@ - Codestin Search App + Codestin Search App @@ -11,12 +11,12 @@ + - @@ -11,12 +11,12 @@ + - - - - - - - - - - - - - - -

      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/datepicker/animation.html b/demos/datepicker/animation.html index 5fda2046f52..6fbc31ff92e 100644 --- a/demos/datepicker/animation.html +++ b/demos/datepicker/animation.html @@ -18,6 +18,7 @@ + diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index 2c5045b6f33..7c39de85eff 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -12,29 +12,21 @@ + - - - - - - - - - - - - - - - - - - -
      -

      Select the date range to search for.

      -
      - - diff --git a/demos/datepicker/default.html b/demos/datepicker/default.html index be0c453c2b3..b2439b29ab3 100644 --- a/demos/datepicker/default.html +++ b/demos/datepicker/default.html @@ -12,6 +12,7 @@ + + diff --git a/demos/datepicker/index.html b/demos/datepicker/index.html index d9c8dfc10da..a56df7bd6e1 100644 --- a/demos/datepicker/index.html +++ b/demos/datepicker/index.html @@ -9,19 +9,10 @@ diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index 61aa7c9a2da..701e5c36b66 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -11,6 +11,7 @@ + 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 043304f76d8..fc22e0e9906 100644 --- a/tests/unit/all.html +++ b/tests/unit/all.html @@ -20,6 +20,7 @@ "autocomplete/autocomplete.html", "button/button.html", "core/core.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..5b22b047024 --- /dev/null +++ b/tests/unit/calendar/all.html @@ -0,0 +1,26 @@ + + + + + Codestin Search App + + + + + + + + + + + + + +
      +
      + +
      + + diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html new file mode 100644 index 00000000000..4c97eec8629 --- /dev/null +++ b/tests/unit/calendar/calendar.html @@ -0,0 +1,46 @@ + + + + + Codestin Search App + + + + + + + + + + + + + + + + + + + + + + +
      +
      + +
      +
      + +
      + + diff --git a/tests/unit/calendar/calendar_common.js b/tests/unit/calendar/calendar_common.js new file mode 100644 index 00000000000..f3a01171ba5 --- /dev/null +++ b/tests/unit/calendar/calendar_common.js @@ -0,0 +1,14 @@ +TestHelpers.commonWidgetTests( "calendar", { + defaults: { + dateFormat: { date: "short" }, + disabled: false, + eachDay: $.noop, + numberOfMonths: 1, + showWeek: false, + value: null, + + // callbacks + create: null, + select: null + } +}); diff --git a/tests/unit/calendar/calendar_core.js b/tests/unit/calendar/calendar_core.js new file mode 100644 index 00000000000..6485587ed9e --- /dev/null +++ b/tests/unit/calendar/calendar_core.js @@ -0,0 +1,365 @@ +(function( $ ) { + +module( "calendar: core" ); + +TestHelpers.testJshint( "calendar" ); + +test( "base structure", function() { + expect( 22 ); + + var header, title, table, thead, week, child, buttonpane, + element = $( "#calendar" ).calendar(), + dp = element.calendar( "widget" ); + + function step1() { + 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)" ); + + 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" ); + + element.calendar( "destroy" ); + + step2(); + } + + function step2() { + element = $( "#calendar" ).calendar( { numberOfMonths: 2 } ); + dp = element.calendar( "widget" ); + + ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" ); + equal( dp.children().length, 4, "Structure multi [2] - child count" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" ); + + element.calendar( "destroy" ); + } + + step1(); +}); + +test( "Localization", function() { + expect( 5 ); + + 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 ); +}); + +asyncTest( "keyboard handling", function() { + expect( 10 ); + + var element = $( "#calendar" ); + + function step1() { + element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + + TestHelpers.calendar + .focusGrid( element ) + .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); + setTimeout(function() { + $( ":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() { + 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() { + 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.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(); + }, 50 ); + } + + function step4() { + 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.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(); + }, 50 ); + } + + function step5() { + 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.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(); + }, 50 ); + } + + function step6() { + 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.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2013, 1 - 1, 1 ), + "Keystroke Page Up + ALT moves date to previous year" + ); + element.calendar( "destroy" ); + step7(); + }, 50 ); + } + + function step7() { + 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.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(); + }, 50 ); + } + + function step8() { + 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.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2015, 1 - 1, 1 ), + "Keystroke Page Down + ALT moves date to next year" + ); + element.calendar( "destroy" ); + step9(); + }, 50 ); + } + + // Check for moving to short months + function step9() { + 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.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2014, 2 - 1, 28 ), + "Keystroke Page Up and short months" + ); + element.calendar( "destroy" ); + step10(); + }, 50 ); + } + + function step10() { + 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.ENTER } ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + new Date( 2016, 2 - 1, 29 ), + "Keystroke Page Down and leap years" + ); + element.calendar( "destroy" ); + start(); + }, 50 ); + } + + step1(); +}); + +asyncTest( "mouse", function() { + expect( 6 ); + + var element = $( "#calendar" ).calendar(), + date = new Date(); + + 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 + 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_events.js b/tests/unit/calendar/calendar_events.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/unit/calendar/calendar_methods.js b/tests/unit/calendar/calendar_methods.js new file mode 100644 index 00000000000..0603f5d9551 --- /dev/null +++ b/tests/unit/calendar/calendar_methods.js @@ -0,0 +1,71 @@ +(function( $ ) { + +module( "calendar: methods" ); + +test( "destroy", function() { + expect( 1 ); + + domEqual( "#calendar", function() { + $( "#calendar" ).calendar().calendar( "destroy" ); + }); +}); + +test( "enable / disable", function() { + expect( 6 ); + + var element = $( "#calendar" ).calendar(); + + ok( !element.calendar( "option", "disabled" ), "initially enabled" ); + ok( !element.hasClass( "ui-calendar-disabled" ), "does not have disabled class name" ); + + element.calendar( "disable" ); + ok( element.calendar( "option", "disabled" ), "disabled option is set" ); + ok( element.hasClass( "ui-calendar-disabled" ), "calendar has disabled class name" ); + + 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 element = $( "#calendar" ).calendar(), + widget = element.calendar( "widget" ); + + strictEqual( widget[ 0 ], element[ 0 ] ); +}); + +test( "value", function() { + 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( 4 ); + + var 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" ), date2, "Set date - default" ); + + element.calendar( "valueAsDate", date1 ); + TestHelpers.calendar.equalsDate(element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" ); +}); + +})( jQuery ); diff --git a/tests/unit/calendar/calendar_options.js b/tests/unit/calendar/calendar_options.js new file mode 100644 index 00000000000..454e7400579 --- /dev/null +++ b/tests/unit/calendar/calendar_options.js @@ -0,0 +1,175 @@ +(function( $ ) { + +module( "calendar: options" ); + +test( "dateFormat", function() { + expect( 2 ); + var element = $( "#calendar" ).calendar({ + value: "1/1/14" + }), + firstDayLink = element.calendar( "widget" ).find( "td[id]:first a" ); + + firstDayLink.trigger( "mousedown" ); + equal( element.calendar( "value" ), "1/1/14", "default formatting" ); + + element.calendar( "option", "dateFormat", { date: "full" } ); + equal( element.calendar( "value" ), "Wednesday, January 1, 2014", "updated formatting" ); +}); + +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( "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-datepicker-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( "min / max", function() { + expect( 0 ); +}); + +/* +// TODO: Move this to $.date, Globalize or calendar widget +test( "daylightSaving", function() { + expect( 25 ); + var inp = TestHelpers.calendar.init( "#inp" ), + dp = $( "#ui-datepicker-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" ); + }); + */ + +})(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..94f3644c3a2 --- /dev/null +++ b/tests/unit/calendar/calendar_test_helpers.js @@ -0,0 +1,22 @@ +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 ); + }, + focusGrid: function( element ) { + element.find( "table:tabbable" ).simulate( "focus" ); + + return $( ":focus" ); + } +}; diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index b49fe5a4b41..24593a7ff52 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -14,11 +14,12 @@ @@ -25,7 +32,7 @@
      -

      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/tests/unit/calendar/calendar_common.js b/tests/unit/calendar/calendar_common.js index f3a01171ba5..49f8b5f05f6 100644 --- a/tests/unit/calendar/calendar_common.js +++ b/tests/unit/calendar/calendar_common.js @@ -3,6 +3,8 @@ TestHelpers.commonWidgetTests( "calendar", { dateFormat: { date: "short" }, disabled: false, eachDay: $.noop, + max: null, + min: null, numberOfMonths: 1, showWeek: false, value: null, diff --git a/tests/unit/calendar/calendar_methods.js b/tests/unit/calendar/calendar_methods.js index 0603f5d9551..a60ed3c4c76 100644 --- a/tests/unit/calendar/calendar_methods.js +++ b/tests/unit/calendar/calendar_methods.js @@ -49,9 +49,10 @@ test( "value", function() { }); test( "valueAsDate", function() { - expect( 4 ); + expect( 11 ); - var element = $( "#calendar" ).calendar(), + var minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, + element = $( "#calendar" ).calendar(), date1 = new Date( 2008, 6 - 1, 4 ), date2 = new Date(); @@ -66,6 +67,68 @@ test( "valueAsDate", function() { element.calendar( "valueAsDate", date1 ); TestHelpers.calendar.equalsDate(element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" ); + + // 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" + ); + + element.calendar( "valueAsDate", date2 ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + date1, + "Set date min/max - value > max" + ); + + element + .calendar( "option", { min: minDate } ) + .calendar( "valueAsDate", date1 ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + date1, + "Set date min/max - value < min" + ); + + element.calendar( "valueAsDate", date2 ); + TestHelpers.calendar.equalsDate( + element.calendar( "valueAsDate" ), + date1, "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 ); + element.calendar( "valueAsDate", dateAndTimeToSet ); + equal( + dateAndTimeToSet.getTime(), + dateAndTimeClone.getTime(), + "Date object passed should not be changed by valueAsDate" + ); }); })( jQuery ); diff --git a/tests/unit/calendar/calendar_options.js b/tests/unit/calendar/calendar_options.js index 454e7400579..6be4f8733e8 100644 --- a/tests/unit/calendar/calendar_options.js +++ b/tests/unit/calendar/calendar_options.js @@ -83,8 +83,48 @@ test( "showWeek", function() { }); test( "min / max", function() { - expect( 0 ); -}); + expect( 7 ); + + // With existing date + var element = $( "#calendar" ).calendar(), + minDate = new Date( 2008, 2 - 1, 29 ), + maxDate = new Date( 2008, 12 - 1, 7 ); + + element + .calendar( "option", { min: minDate } ) + .calendar( "value", "6/4/08" ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min" ); + + element + .calendar( "option", { min: minDate } ) + .calendar( "value", "1/4/08" ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < min" ); + + element + .calendar( "option", { min: null } ) + .calendar( "value", "6/4/08" ) + .calendar( "option", { max: maxDate } ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < max" ); + + element + .calendar( "option", { max: maxDate } ) + .calendar( "value", "1/4/09" ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > max" ); + + element + .calendar( "option", { min: minDate, max: maxDate } ) + .calendar( "value", "1/4/08" ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < min" ); + + element + .calendar( "option", { min: minDate, max: maxDate } ) + .calendar( "value", "6/4/08" ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min, < max" ); + + element + .calendar( "option", { min: minDate, max: maxDate } ) + .calendar( "value", "1/4/09" ); + TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > max" );}); /* // TODO: Move this to $.date, Globalize or calendar widget diff --git a/tests/unit/datepicker/datepicker_common.js b/tests/unit/datepicker/datepicker_common.js index 4bf06d3ad14..1544db58e84 100644 --- a/tests/unit/datepicker/datepicker_common.js +++ b/tests/unit/datepicker/datepicker_common.js @@ -4,6 +4,8 @@ TestHelpers.commonWidgetTests( "datepicker", { dateFormat: { date: "short" }, disabled: false, eachDay: $.noop, + max: null, + min: null, numberOfMonths: 1, position: { my: "left top", diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index c6cb184a2c9..b129fdb1192 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -58,11 +58,13 @@ test( "value", function() { }); test( "valueAsDate", function() { - expect( 6 ); + expect( 13 ); - var input = TestHelpers.datepicker.init( "#datepicker" ), + var minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, + input = TestHelpers.datepicker.init( "#datepicker" ), picker = input.datepicker( "widget" ), - date1 = new Date( 2008, 6 - 1, 4 ); + 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" ); @@ -78,6 +80,36 @@ test( "valueAsDate", function() { strictEqual( input.datepicker( "valueAsDate" ), null, "Set date - default" ); input.datepicker( "valueAsDate", date1 ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date1, "Set date - 2008-06-04" ); + + // 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 9b2845fec09..16546424dac 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -149,6 +149,42 @@ test( "showWeek", function() { input.datepicker( "option", "showWeek", true ); equal( container.find( "thead th" ).length, 8, "supports changing option after init" ); }); + +test( "min / max", function() { + expect( 14 ); + + 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" ); + ok( inp.datepicker( "isValid" ) ); + + inp.datepicker( "option", { min: null } ).val( "1/4/08" ).datepicker( "option", { min: minDate } ); + 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" ), 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" ), 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" ), new Date( 2009, 1 - 1, 4 ), "Min/max - value > max" ); + ok( !inp.datepicker( "isValid" ) ); +}); test( "Stop datepicker from appearing with beforeOpen event handler", function() { expect( 3 ); diff --git a/ui/calendar.js b/ui/calendar.js index 2f8b39bb245..8a5a1e8ad8a 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -31,6 +31,8 @@ return $.widget( "ui.calendar", { options: { dateFormat: { date: "short" }, eachDay: $.noop, + max: null, + min: null, numberOfMonths: 1, showWeek: false, value: null, @@ -308,38 +310,33 @@ return $.widget( "ui.calendar", { }, _buildDayCell: function( day ) { - var contents = "", + var content = "", attributes = [ - "aria-selected" + ( day.current ? "\"true\"" : "\"false\"" ) - ]; + "role='gridcell'", + "aria-selected='" + day.current ? true : false + "'" + ], + selectable = ( day.selectable && this._isValid( new Date( day.timestamp ) ) ); if ( day.render ) { - attributes.push( "id=\"" + this.id + "-" + day.date + "\"" ); - } - - if ( day.selectable ) { - attributes.push( "aria-disabled=\"true\"" ); - } + attributes.push( "id='" + this.id + "-" + day.date + "'" ); - if ( day.render ) { - if ( day.selectable ) { - contents = this._buildDayLink( day ); - } else { - contents = this._buildDayDisplay( day ); + 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 ) { @@ -353,30 +350,18 @@ return $.widget( "ui.calendar", { 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() { @@ -452,6 +437,26 @@ return $.widget( "ui.calendar", { } }, + _isValid: function( value ) { + if ( $.type( value ) !== "date" ) { + return false; + } + + if ( $.type( this.options.max ) === "date" ) { + if ( value > this.options.max ) { + return false; + } + } + + if ( $.type( this.options.min ) === "date" ) { + if ( value < this.options.min ) { + return false; + } + } + + return true; + }, + _destroy: function() { this.element .off( ".calendar" ) @@ -471,21 +476,29 @@ return $.widget( "ui.calendar", { _setOption: function( key, value ) { if ( key === "value" ) { - if ( $.type( value ) === "date" ) { + if ( this._isValid( value ) ) { this.date.setTime( value.getTime() ).select(); this.refresh(); } } + if ( key === "max" || key === "min" ) { + if ( $.type( value ) === "date" || value === null ) { + this._super( key, value ); + this.refresh(); + } + return; + } + this._super( key, value ); if ( key === "eachDay" ) { - this.date.eachDay = this.options.eachDay; + this.date.eachDay = value; this.refresh(); } if ( key === "dateFormat" ) { - this.date.setFormat( this.options.dateFormat ); + this.date.setFormat( value ); } if ( key === "showWeek" ) { diff --git a/ui/datepicker.js b/ui/datepicker.js index 867b26e8fe2..98877545286 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -43,6 +43,8 @@ $.widget( "ui.datepicker", { dateFormat: { date: "short" }, // TODO Review eachDay: $.noop, + max: null, + min: null, numberOfMonths: 1, position: { my: "left top", @@ -63,6 +65,22 @@ $.widget( "ui.datepicker", { this._createCalendar(); }, + _getCreateOptions: function() { + var max = this.element.attr( "max" ), + min = this.element.attr( "min" ), + options = {}; + + if ( max !== undefined ) { + options.max = Globalize.parseDate( max, { pattern: "yyyy-MM-dd" } ); + } + + if ( min !== undefined ) { + options.min = Globalize.parseDate( min, { pattern: "yyyy-MM-dd" } ); + } + + return options; + }, + _createCalendar: function() { var that = this; @@ -75,6 +93,8 @@ $.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(), @@ -284,11 +304,7 @@ $.widget( "ui.datepicker", { value: function( value ) { if ( arguments.length ) { - var date = Globalize.parseDate( value, this.options.dateFormat ); - if ( $.type( date ) === "date" ) { - this.valueAsDate( date ); - this.element.val( value ); - } + this.valueAsDate( Globalize.parseDate( value , this.options.dateFormat ) ); } else { return this._getParsedValue() ? this.element.val() : null; } @@ -296,7 +312,7 @@ $.widget( "ui.datepicker", { valueAsDate: function( value ) { if ( arguments.length ) { - if ( $.type( value ) === "date" ) { + if ( this.calendarInstance._isValid( value ) ) { this.calendarInstance.valueAsDate( value ); this.element.val( Globalize.format( value, this.options.dateFormat ) ); } @@ -306,7 +322,7 @@ $.widget( "ui.datepicker", { }, isValid: function() { - return this._getParsedValue() !== null; + return this.calendarInstance._isValid( this._getParsedValue() ); }, _destroy: function() { @@ -345,5 +361,4 @@ $.widget( "ui.datepicker", { } } }); - })); From 6ef023f0e4a8f341ff05552c7c70b9095bc031b7 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 4 Jun 2014 23:40:39 +0200 Subject: [PATCH 033/179] Calendar: Remove select callback reference --- ui/calendar.js | 6 +----- ui/datepicker.js | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 8a5a1e8ad8a..ab4733653f3 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -414,11 +414,7 @@ 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() - }); + this._trigger( "select", event ); }, value: function( value ) { diff --git a/ui/datepicker.js b/ui/datepicker.js index 98877545286..cc75673634e 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -98,11 +98,11 @@ $.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 57736406f1e49da1f7b0c4fd2a9d04d437c63087 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 5 Jun 2014 02:39:46 +0200 Subject: [PATCH 034/179] Datepicker: Code clean up for events --- ui/datepicker.js | 203 ++++++++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 101 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index cc75673634e..0e4dde7fb27 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -63,6 +63,10 @@ $.widget( "ui.datepicker", { _create: function() { this._createCalendar(); + + this._on( this._inputEvents ); + this._on( this.calendar, this._calendarEvents ); + this._on( this.document, this._documentEvents ); }, _getCreateOptions: function() { @@ -112,118 +116,115 @@ $.widget( "ui.datepicker", { this.element .attr( "aria-haspopup", "true" ) .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.calendar.hide(); - this.close( event ); - break; - case $.ui.keyCode.ESCAPE: - if ( this.isOpen ) { - this.close( event ); - } - break; - case $.ui.keyCode.ENTER: - this.calendarInstance._handleKeydown( event ); - break; - case $.ui.keyCode.DOWN: - case $.ui.keyCode.UP: - clearTimeout( this.closeTimer ); - this._delay( function() { - this.open( event ); - this.calendarInstance.grid.focus(); - }, 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; - 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.refresh(); - } - }, - mousedown: function( event ) { + _inputEvents: { + 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.calendar.hide(); + this.close( event ); + break; + case $.ui.keyCode.ESCAPE: if ( this.isOpen ) { - suppressExpandOnFocus = true; - this.close(); - return; + this.close( event ); } - this.open( event ); + break; + case $.ui.keyCode.ENTER: + this.calendarInstance._handleKeydown( event ); + break; + case $.ui.keyCode.DOWN: + case $.ui.keyCode.UP: clearTimeout( this.closeTimer ); - }, - focus: function( event ) { - if ( !suppressExpandOnFocus ) { - this._delay( function() { - if ( !this.isOpen ) { - this.open( event ); - } - }, 1); + this._delay( function() { + this.open( event ); + this.calendarInstance.grid.focus(); + }, 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; + 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.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() { - suppressExpandOnFocus = false; - }, 100 ); - }, - blur: function() { - suppressExpandOnFocus = false; + if ( !this.isOpen ) { + this.open( event ); + } + }); } - }); - - 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 - // 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 ); - }, + this._delay( function() { + suppressExpandOnFocus = false; + }, 100 ); + }, + blur: function() { + suppressExpandOnFocus = false; + } + }, - // 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.calendar.is( ":visible" ) ) { - this.close( event ); - this._focusTrigger(); - } + _calendarEvents: { + 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.calendar.is( ":visible" ) ) { + this.close( event ); + this._focusTrigger(); } - }); + } + }, - this._on( this.document, { - click: function( event ) { - if ( this.isOpen && !$( event.target ).closest( this.element.add( this.calendar ) ).length ) { - this.close( event ); - } + _documentEvents: { + click: function( event ) { + if ( this.isOpen && !$( event.target ).closest( this.element.add( this.calendar ) ).length ) { + this.close( event ); } - }); + } }, _appendTo: function() { From 63bdc3ef81831d6099d8960109afb34d67bd957f Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 5 Jun 2014 20:32:27 +0200 Subject: [PATCH 035/179] Datepicker: Remove unwanted keyboard shortcut Remove shortcut for closing the calendar and erasing the date (CTRL+END). Remove unwanted CTRL+HOME shortcut and support for enter key on input. --- ui/datepicker.js | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 0e4dde7fb27..d03d1b8b2f3 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -131,9 +131,6 @@ $.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 ); @@ -142,26 +139,6 @@ $.widget( "ui.datepicker", { this.calendarInstance.grid.focus(); }, 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; - case $.ui.keyCode.END: - if ( event.ctrlKey ) { - this.element.val( "" ); - event.preventDefault(); - if ( this.isOpen ) { - this.close( event ); - } - } - break; } }, keyup: function() { From 258a3ff4e5989caddd56d15e19463c4b5943e3c8 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 12 Jun 2014 14:36:45 +0200 Subject: [PATCH 036/179] Datepicker: Simplify usage of calendar options and avoid duplications --- ui/datepicker.js | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index d03d1b8b2f3..15e979c34f9 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -31,26 +31,19 @@ } }(function( $ ) { -// TODO Use uniqueId, if possible -var idIncrement = 0, - // TODO Move this to the instance +var widget, + calendarOptions = [ "dateFormat", "eachDay", "max", "min", "numberOfMonths", "showWeek" ], + // TODO Move this to the instance? suppressExpandOnFocus = false; -$.widget( "ui.datepicker", { +widget = $.widget( "ui.datepicker", { version: "@VERSION", options: { appendTo: null, - dateFormat: { date: "short" }, - // TODO Review - eachDay: $.noop, - max: null, - min: null, - numberOfMonths: 1, position: { my: "left top", at: "left bottom" }, - showWeek: false, show: true, hide: true, @@ -94,13 +87,7 @@ $.widget( "ui.datepicker", { // Initialize calendar widget this.calendarInstance = this.calendar - .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, + .calendar( $.extend( {}, this.options, { value: this._getParsedValue(), select: function( event ) { that.element.val( that.calendarInstance.value() ); @@ -108,7 +95,7 @@ $.widget( "ui.datepicker", { that._focusTrigger(); that._trigger( "select", event ); } - }) + }) ) .calendar( "instance" ); this._setHiddenPicker(); @@ -322,7 +309,7 @@ $.widget( "ui.datepicker", { _setOption: function( key, value ) { this._super( key, value ); - if ( $.inArray( key, [ "showWeek", "numberOfMonths", "dateFormat", "eachDay", "min", "max" ] ) !== -1 ) { + if ( $.inArray( key, calendarOptions ) !== -1 ) { this.calendarInstance.option( key, value ); } @@ -339,4 +326,11 @@ $.widget( "ui.datepicker", { } } }); + +$.each( calendarOptions, function( index, option ) { + $.ui.datepicker.prototype.options[ option ] = $.ui.calendar.prototype.options[ option ]; +}); + +return widget; + })); From 6dfcd937f9924990a28c35a2f11aae97cb77a128 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 00:46:08 +0200 Subject: [PATCH 037/179] Datepicker tests: Add open and close unit tests --- tests/unit/datepicker/datepicker_events.js | 43 ++++++++++++++++++--- tests/unit/datepicker/datepicker_methods.js | 19 +++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index 9ee254e5351..ac3d41c13d6 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -14,15 +14,48 @@ test( "beforeOpen", function() { }); 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 a:first" ).simulate( "mousedown" ); }); test( "open", function() { - expect( 0 ); -}); + expect( 2 ); -test( "select", function() { - expect( 0 ); + 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" ); + + input.datepicker( "open" ); }); var selectedThis = null, diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index b129fdb1192..8a3c2b38429 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -40,6 +40,25 @@ test( "widget", function() { actual.remove(); }); +test( "open / close", function() { + expect( 7 ); + + var input = TestHelpers.datepicker.initNewInput({ show: false, hide: false }), + calendar = input.datepicker( "widget" ); + + 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-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-hidden" ); + equal( calendar.attr( "aria-expanded" ), "false", "close: calendar aria-expanded" ); +}); + test( "value", function() { expect( 4 ); From 43025392c5b4fd737560c7ed859e7176b4b41063 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 16:25:24 +0200 Subject: [PATCH 038/179] 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 15e979c34f9..0f89e853b44 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -184,8 +184,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 90c704f1a810b2222991ba8f57ac571d9e8a8ee4 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 19:05:06 +0200 Subject: [PATCH 039/179] 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 ab4733653f3..945fed07d04 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 398ce1bd828266172b2354f8228b733fb0e63a2f Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 17 Jun 2014 19:53:08 +0200 Subject: [PATCH 040/179] Datepicker tests: Rewrite event unit tests --- tests/unit/datepicker/datepicker_events.js | 207 +++++++----------- .../datepicker/datepicker_test_helpers.js | 6 +- 2 files changed, 81 insertions(+), 132 deletions(-) diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index ac3d41c13d6..ff5438cd2f1 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -1,16 +1,32 @@ -// 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() { @@ -58,126 +74,61 @@ test( "open", function() { 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( 4 ); + + 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 calendar cell click"; + input + .simulate( "focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout(function() { + widget.find( "tbody tr:first a:first" ).simulate( "mousedown" ); + input.datepicker( "close" ); + step2(); + }, 100 ); + } + + function step2() { + 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" ); + step3(); + }, 100 ); + } + + function step3() { + 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 e8048725d6a..3548f6ea360 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, hide: false }, options || {} ); return $( "" ).datepicker( options ) .appendTo( "#qunit-fixture" ); - }, - onFocus: TestHelpers.onFocus, - PROP_NAME: "datepicker" + } }; From 35842c8125056d5c33c42be2ab78971ca3379def Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 01:35:51 +0200 Subject: [PATCH 041/179] Calendar: Fix multiple calendar styles --- themes/base/calendar.css | 8 +++++--- themes/base/datepicker.css | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/themes/base/calendar.css b/themes/base/calendar.css index 608afed4465..af889551672 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -109,15 +109,16 @@ } /* with multiple calendars */ -.ui-calendar.ui-calendar-multi { - width: 100%; +.ui-calendar-multi { + width: auto; + display: inline-block; } .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%; @@ -176,3 +177,4 @@ border-right-width: 0; border-left-width: 1px; } + diff --git a/themes/base/datepicker.css b/themes/base/datepicker.css index 526c11bd961..b19f5bda8d8 100644 --- a/themes/base/datepicker.css +++ b/themes/base/datepicker.css @@ -9,6 +9,7 @@ * http://api.jqueryui.com/datepicker/#theming */ .ui-datepicker { - display: none; - position: absolute; + display: none; + position: absolute; } + From fd3a68cfa357585e651c615aa480e7edf17b7616 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 01:44:13 +0200 Subject: [PATCH 042/179] Calendar: Fix German localization --- external/localization.js | 6 +++--- tests/unit/calendar/calendar_core.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/external/localization.js b/external/localization.js index 98d8f813052..4fd436aca00 100644 --- a/external/localization.js +++ b/external/localization.js @@ -2767,10 +2767,10 @@ var regions = { "dateFormat": "d" }, "de": { - "closeText": "schlie\u00dfen", - "prevText": "<zur\u00fcck", + "closeText": "Schlie\u00dfen", + "prevText": "<Zur\u00fcck", "nextText": "Vor>", - "currentText": "heute", + "currentText": "Heute", "weekHeader": "Wo", "dateFormat": "d" }, diff --git a/tests/unit/calendar/calendar_core.js b/tests/unit/calendar/calendar_core.js index 6485587ed9e..ba424b7b8ed 100644 --- a/tests/unit/calendar/calendar_core.js +++ b/tests/unit/calendar/calendar_core.js @@ -89,7 +89,7 @@ test( "Localization", function() { ); equal( element.find( ".ui-calendar-prev" ).text(), - " Date: Wed, 18 Jun 2014 02:05:42 +0200 Subject: [PATCH 043/179] Datepicker: Fix localization demo --- demos/calendar/localization.html | 11 +++++++---- demos/datepicker/localization.html | 14 +++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/demos/calendar/localization.html b/demos/calendar/localization.html index 75822cf32df..1f607f7a4c5 100644 --- a/demos/calendar/localization.html +++ b/demos/calendar/localization.html @@ -16,12 +16,15 @@ diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index 701e5c36b66..01f90531eca 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -17,11 +17,15 @@ From b9d8f624ba899b76e0672e0a70bc74f333467f1e Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 02:31:31 +0200 Subject: [PATCH 044/179] Datepicker: Several minor code improvements Several minor code improvements and make suppressExpandOnFocus an internal variable, remove partial button widget usage in header --- themes/base/calendar.css | 1 + ui/calendar.js | 4 +--- ui/datepicker.js | 47 +++++++++++++++++++--------------------- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/themes/base/calendar.css b/themes/base/calendar.css index af889551672..7dc8e182929 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -18,6 +18,7 @@ } .ui-calendar .ui-calendar-prev, .ui-calendar .ui-calendar-next { + cursor: pointer; position: absolute; top: 2px; width: 19px; diff --git a/ui/calendar.js b/ui/calendar.js index 945fed07d04..3b15287eb09 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -74,7 +74,7 @@ return $.widget( "ui.calendar", { }); // 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.delegate( ".ui-calendar-header button, .ui-calendar-calendar a", "mouseenter.calendar mouseleave.calendar", function() { $( this ).toggleClass( "ui-state-hover" ); }); @@ -158,8 +158,6 @@ return $.widget( "ui.calendar", { }) .html( pickerHtml ); - this.element.find( "button" ).button(); - this.grid = this.element.find( ".ui-calendar-calendar" ); }, diff --git a/ui/datepicker.js b/ui/datepicker.js index 0f89e853b44..1adb08bd4da 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -32,9 +32,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", @@ -55,6 +53,7 @@ widget = $.widget( "ui.datepicker", { }, _create: function() { + this.suppressExpandOnFocus = false; this._createCalendar(); this._on( this._inputEvents ); @@ -100,9 +99,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: { @@ -135,7 +135,7 @@ widget = $.widget( "ui.datepicker", { }, mousedown: function( event ) { if ( this.isOpen ) { - suppressExpandOnFocus = true; + this.suppressExpandOnFocus = true; this.close(); return; } @@ -143,19 +143,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 ); }); } this._delay( function() { - suppressExpandOnFocus = false; + this.suppressExpandOnFocus = false; }, 100 ); }, blur: function() { - suppressExpandOnFocus = false; + this.suppressExpandOnFocus = false; } }, @@ -216,7 +214,7 @@ widget = $.widget( "ui.datepicker", { }, _focusTrigger: function() { - suppressExpandOnFocus = true; + this.suppressExpandOnFocus = true; this.element.focus(); }, @@ -233,14 +231,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 @@ -262,9 +260,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() { @@ -297,9 +296,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() { @@ -330,7 +327,7 @@ widget = $.widget( "ui.datepicker", { } } }); - + $.each( calendarOptions, function( index, option ) { $.ui.datepicker.prototype.options[ option ] = $.ui.calendar.prototype.options[ option ]; }); From 2e2787dcfefb22fb96edf260cac04ffb37f93676 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Jun 2014 02:49:30 +0200 Subject: [PATCH 045/179] Calendar: Fix hover event setting and removing --- ui/calendar.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 3b15287eb09..8e228146ae4 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 button, .ui-calendar-calendar a", "mouseenter.calendar mouseleave.calendar", function() { + this.element.on( "mouseenter.calendar mouseleave.calendar", ".ui-calendar-header button, .ui-calendar-calendar a", function() { $( this ).toggleClass( "ui-state-hover" ); }); From 5df6d39d13e707eee9f5147abd424dfd47eff367 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 19 Jun 2014 18:59:28 +0200 Subject: [PATCH 046/179] Datepicker: Improve localization handling, code style --- tests/unit/calendar/calendar_core.js | 8 ++- ui/calendar.js | 79 ++++++++++++++++------------ 2 files changed, 52 insertions(+), 35 deletions(-) diff --git a/tests/unit/calendar/calendar_core.js b/tests/unit/calendar/calendar_core.js index ba424b7b8ed..0a33363c9af 100644 --- a/tests/unit/calendar/calendar_core.js +++ b/tests/unit/calendar/calendar_core.js @@ -64,7 +64,7 @@ test( "base structure", function() { }); test( "Localization", function() { - expect( 5 ); + expect( 10 ); var defaultLocale = Globalize.locale(), element = $( "#calendar" ), @@ -102,6 +102,12 @@ test( "Localization", function() { testLocalization( "Init: " ); element.calendar( "destroy" ); + Globalize.locale( defaultLocale.locale ); + initCalendar(); + Globalize.locale( "de-DE" ); + element.calendar( "refresh" ); + testLocalization( "After init: " ); + Globalize.locale( defaultLocale.locale ); }); diff --git a/ui/calendar.js b/ui/calendar.js index 8e228146ae4..0d96d4030b0 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -43,6 +43,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; @@ -198,41 +199,43 @@ 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" ); + var prevText = this._getTranslation( "prevText" ); - return ""; }, _buildNextLink: function() { - var labels = Globalize.translate( "datepicker" ); + var nextText = this._getTranslation( "nextText" ); - return ""; }, _buildTitlebar: function() { - var labels = Globalize.translate( "datepicker" ); - return "
      " + "
      " + - this._buildTitle() + - "
      " + - ", " + labels.datePickerRole + "" + - "
      "; + this._buildTitle() + + "
      " + + ", " + + this._getTranslation( "datePickerRole" ) + + "" + + "
      "; }, _buildTitle: function() { @@ -246,36 +249,36 @@ return $.widget( "ui.calendar", { _buildGrid: function() { return "" + - this._buildGridHeading() + - this._buildGridBody() + - "
      "; + "aria-labelledby='" + this.id + "-month-label' tabindex='0' " + + "aria-activedescendant='" + this.id + "-" + this.date.day() + "'>" + + this._buildGridHeading() + + this._buildGridBody() + + ""; }, _buildGridHeading: function() { var cells = "", i = 0, - labels = Globalize.translate( "datepicker" ), weekDayLength = this.date.weekdays().length; if ( this.options.showWeek ) { - cells += "" + labels.weekHeader + ""; + cells += "" + this._getTranslation( "weekHeader" ) + ""; } for ( ; i < weekDayLength; i++ ) { cells += this._buildGridHeaderCell( this.date.weekdays()[ i ] ); } return "" + - "" + cells + "" + - ""; + "" + cells + "" + + ""; }, _buildGridHeaderCell: function( day ) { return "" + - "" + - day.shortname + - "" + - ""; + "" + + day.shortname + + "" + + ""; }, _buildGridBody: function() { @@ -330,7 +333,6 @@ return $.widget( "ui.calendar", { _buildDayElement: function( day, selectable ) { var classes = [ "ui-state-default" ], - labels = Globalize.translate( "datepicker" ), content = ""; if ( day === this.date && selectable ) { @@ -355,18 +357,18 @@ return $.widget( "ui.calendar", { } if ( day.today ) { - content += ", " + labels.currentText + ""; + content += ", " + this._getTranslation( "currentText" ) + ""; } return content; }, _buildButtons: function() { - var labels = Globalize.translate( "datepicker" ); - return "
      " + - "" + - "
      "; + "" + + "
      "; }, // Refreshing the entire calendar during interaction confuses screen readers, specifically @@ -375,6 +377,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 @@ -382,6 +385,10 @@ return $.widget( "ui.calendar", { this.grid = $( this._buildGrid() ); this.element.find( ".ui-calendar-title" ).html( this._buildTitle() ); this.element.find( ".ui-calendar-calendar" ).replaceWith( this.grid ); + $( ".ui-calendar-prev", this.element ).attr( "title", this.labels.prevText ) + .children().html( this.labels.prevText ); + $( ".ui-calendar-next", this.element ).attr( "title", this.labels.nextText ) + .children().html( this.labels.nextText ); } else { this._refreshMultiplePicker(); } @@ -402,6 +409,10 @@ return $.widget( "ui.calendar", { this.element.find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" ); }, + _getTranslation: function( key ) { + return $( "" ).text( this.labels[ key ] ).html(); + }, + _setHiddenPicker: function() { this.element.attr({ "aria-hidden": "true", From 9461f6680b5b3b05cdb2dffe3b6d3b004f2666b7 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Fri, 20 Jun 2014 00:13:20 +0200 Subject: [PATCH 047/179] Calendar: Add buttons option --- demos/calendar/buttonbar.html | 8 +- tests/unit/calendar/calendar_common.js | 1 + tests/unit/calendar/calendar_core.js | 26 ++++- tests/unit/calendar/calendar_options.js | 105 +++++++++++++++++++ tests/unit/calendar/calendar_test_helpers.js | 4 +- tests/unit/datepicker/datepicker_common.js | 1 + tests/unit/datepicker/datepicker_core.js | 2 +- tests/unit/datepicker/datepicker_options.js | 18 +++- ui/calendar.js | 73 ++++++++++--- ui/datepicker.js | 4 +- 10 files changed, 219 insertions(+), 23 deletions(-) diff --git a/demos/calendar/buttonbar.html b/demos/calendar/buttonbar.html index 498fe1041f4..7ed390b25d1 100644 --- a/demos/calendar/buttonbar.html +++ b/demos/calendar/buttonbar.html @@ -17,7 +17,11 @@ @@ -27,7 +31,7 @@
      -

      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.

      +

      Display a button for selecting Today's date with the buttons option.

      diff --git a/tests/unit/calendar/calendar_common.js b/tests/unit/calendar/calendar_common.js index 49f8b5f05f6..a669fdfc2c1 100644 --- a/tests/unit/calendar/calendar_common.js +++ b/tests/unit/calendar/calendar_common.js @@ -1,5 +1,6 @@ TestHelpers.commonWidgetTests( "calendar", { defaults: { + buttons: [], dateFormat: { date: "short" }, disabled: false, eachDay: $.noop, diff --git a/tests/unit/calendar/calendar_core.js b/tests/unit/calendar/calendar_core.js index 0a33363c9af..8e39843838c 100644 --- a/tests/unit/calendar/calendar_core.js +++ b/tests/unit/calendar/calendar_core.js @@ -5,7 +5,7 @@ module( "calendar: core" ); TestHelpers.testJshint( "calendar" ); test( "base structure", function() { - expect( 22 ); + expect( 26 ); var header, title, table, thead, week, child, buttonpane, element = $( "#calendar" ).calendar(), @@ -14,7 +14,7 @@ test( "base structure", function() { function step1() { 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)" ); + equal( dp.children().length, 2, "Structure - child count (header, calendar)" ); header = dp.children( ":first" ); ok( header.is( "div.ui-calendar-header" ), "Structure - header division" ); @@ -42,17 +42,33 @@ test( "base structure", function() { ok( week.is( "tr" ), "Structure - month table week row" ); equal( week.children().length, 7, "Structure - week child count" ); - element.calendar( "destroy" ); - step2(); } function step2() { + element.calendar( "option", "buttons", { + "test": function() {}, + "test button": 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" ); + + element.calendar( "destroy" ); + step3(); + } + + function step3() { + // Multi-month 2 element = $( "#calendar" ).calendar( { numberOfMonths: 2 } ); dp = element.calendar( "widget" ); 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" ); diff --git a/tests/unit/calendar/calendar_options.js b/tests/unit/calendar/calendar_options.js index 6be4f8733e8..e5a09d3d89e 100644 --- a/tests/unit/calendar/calendar_options.js +++ b/tests/unit/calendar/calendar_options.js @@ -2,6 +2,111 @@ module( "calendar: options" ); +test("buttons", function() { + expect( 21 ); + + var button, i, newButtons, + buttons = { + "Ok": function( event ) { + ok(true, "button click fires callback" ); + equal( this, element[ 0 ], "context of callback" ); + equal( event.target, button[ 0 ], "event target" ); + }, + "Cancel": function( event ) { + ok( true, "button click fires callback" ); + equal( this, element[ 0 ], "context of callback" ); + equal( event.target, button[ 1 ], "event target" ); + } + }, + element = $( "#calendar" ).calendar({ buttons: buttons }); + + button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); + equal( button.length, 2, "number of buttons" ); + + i = 0; + $.each( buttons, function( key ) { + equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) ); + i++; + }); + + ok( button.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container" ); + ok( + element.calendar( "widget" ).hasClass( "ui-calendar-buttons" ), + "calendar wrapper adds class about having buttons" + ); + + button.trigger( "click" ); + + newButtons = { + "Close": function( event ) { + ok( true, "button click fires callback" ); + equal( this, element[ 0 ], "context of callback" ); + equal( event.target, button[ 0 ], "event target" ); + } + }; + + deepEqual( + element.calendar( "option", "buttons" ), + buttons, + ".calendar('option', 'buttons') getter" + ); + element.calendar( "option", "buttons", newButtons ); + deepEqual( + element.calendar( "option", "buttons" ), + newButtons, + ".calendar('option', 'buttons', ...) setter" + ); + + button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); + equal( button.length, 1, "number of buttons after setter" ); + button.trigger( "click" ); + + i = 0; + $.each( newButtons, function( key ) { + equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) ); + i += 1; + }); + + element.calendar( "option", "buttons", null ); + button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); + equal( button.length, 0, "all buttons have been removed" ); + equal( element.find( ".ui-calendar-buttonset" ).length, 0, "buttonset has been removed" ); + equal( element.hasClass( "ui-calendar-buttons" ), false, "calendar element removes class about having buttons" ); + + element.remove(); +}); + +test( "buttons - advanced", function() { + expect( 7 ); + + var buttons, + element = $( "#calendar" ).calendar({ + 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.calendar( "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 element = $( "#calendar" ).calendar({ diff --git a/tests/unit/calendar/calendar_test_helpers.js b/tests/unit/calendar/calendar_test_helpers.js index 94f3644c3a2..c5dfbd4a271 100644 --- a/tests/unit/calendar/calendar_test_helpers.js +++ b/tests/unit/calendar/calendar_test_helpers.js @@ -15,7 +15,9 @@ TestHelpers.calendar = { equal( d1.toString(), d2.toString(), message ); }, focusGrid: function( element ) { - element.find( "table:tabbable" ).simulate( "focus" ); + element.find( ":tabbable" ).last().simulate( "focus" ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); + $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); return $( ":focus" ); } diff --git a/tests/unit/datepicker/datepicker_common.js b/tests/unit/datepicker/datepicker_common.js index 1544db58e84..25c6d429893 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 f0d93c781a9..ffb7ab6c4f2 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -29,7 +29,7 @@ asyncTest( "base structure", function() { setTimeout(function() { ok( widget.is( ":visible" ), "Datepicker visible" ); - equal( widget.children().length, 3, "Child count" ); + equal( widget.children().length, 2, "Child count" ); ok( widget.is( ".ui-calendar" ), "Class ui-calendar" ); ok( widget.is( ".ui-datepicker" ), "Class ui-datepicker" ); ok( widget.is( ".ui-front" ), "Class ui-front" ); diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 16546424dac..01b1b65569a 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -40,6 +40,22 @@ test( "appendTo", function() { input.datepicker( "destroy" ); }); +test("buttons", function() { + expect( 3 ); + + var button, + buttons = { + "Ok": function() {}, + "Cancel": function() {} + }, + element = $( "#datepicker" ).datepicker({ buttons: buttons }); + + button = element.datepicker( "widget" ).find( ".ui-calendar-buttonpane button" ); + equal( button.length, 2, "number of buttons" ); + ok( button.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container"); + ok( element.datepicker( "widget" ).hasClass( "ui-calendar-buttons" ), "calendar wrapper adds class about having buttons" ); +}); + test( "dateFormat", function() { expect( 2 ); var input = $( "#datepicker" ).val( "1/1/14" ).datepicker(), @@ -149,7 +165,7 @@ test( "showWeek", function() { input.datepicker( "option", "showWeek", true ); equal( container.find( "thead th" ).length, 8, "supports changing option after init" ); }); - + test( "min / max", function() { expect( 14 ); diff --git a/ui/calendar.js b/ui/calendar.js index 0d96d4030b0..370f7012313 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -13,6 +13,7 @@ // AMD. Register as an anonymous module. // TODO Add globalize and $.date + // TODO: Keep button even if its optional? define([ "jquery", "./core", @@ -29,6 +30,7 @@ return $.widget( "ui.calendar", { version: "@VERSION", options: { + buttons: [], dateFormat: { date: "short" }, eachDay: $.noop, max: null, @@ -44,6 +46,7 @@ return $.widget( "ui.calendar", { _create: function() { this.id = this.element.uniqueId().attr( "id" ); this.labels = Globalize.translate( "datepicker" ); + this.buttonClickContext = this.element[ 0 ]; this.date = $.date( this.options.value, this.options.dateFormat ).select(); this.date.eachDay = this.options.eachDay; @@ -59,10 +62,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(); @@ -144,7 +143,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"; @@ -158,6 +157,8 @@ return $.widget( "ui.calendar", { }) .html( pickerHtml ); + this._createButtonPane(); + this.grid = this.element.find( ".ui-calendar-calendar" ); }, @@ -190,7 +191,7 @@ return $.widget( "ui.calendar", { html += this._buildTitlebar() + "
      " + this._buildGrid() + "
      "; } - html += "
      " + this._buildButtons(); + html += "
      "; this.date = currentDate; @@ -363,12 +364,55 @@ 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; + + this.buttonPane.remove(); + this.buttonSet.empty(); + + if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) { + this.element.removeClass( "ui-calendar-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-calendar-buttons" ); + this.buttonPane.appendTo( this.element ); }, // Refreshing the entire calendar during interaction confuses screen readers, specifically @@ -389,6 +433,7 @@ return $.widget( "ui.calendar", { .children().html( this.labels.prevText ); $( ".ui-calendar-next", this.element ).attr( "title", this.labels.nextText ) .children().html( this.labels.nextText ); + this._createButtons(); } else { this._refreshMultiplePicker(); } @@ -496,6 +541,10 @@ return $.widget( "ui.calendar", { this._super( key, value ); + if ( key === "buttons" ) { + this._createButtons(); + } + if ( key === "eachDay" ) { this.date.eachDay = value; this.refresh(); diff --git a/ui/datepicker.js b/ui/datepicker.js index 1adb08bd4da..c7df60adc57 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -32,7 +32,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", @@ -97,6 +97,8 @@ widget = $.widget( "ui.datepicker", { }) ) .calendar( "instance" ); + this.calendarInstance.buttonClickContext = that.element[ 0 ]; + this._setHiddenPicker(); this.element.attr({ From 50f477f847b2bea8d279a0e21a655480606b0cdb Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 2 Jul 2014 19:22:49 +0200 Subject: [PATCH 048/179] Calendar: Adjust files to match reorganization of external directory --- tests/unit/date/all.html | 22 +++++++++++----------- tests/unit/date/date.html | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) 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 @@ - - Codestin Search App + + Codestin Search App - + - - - - - + + + + + - + 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 @@ Codestin Search App - - + + - - - - - - - - - - - - - -
      - -
      -

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

      -
      - - From cc91adf4b6b07e300396433d03fedbe18eb3e532 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 19 Jan 2015 17:56:11 +0100 Subject: [PATCH 056/179] Calendar: Use document.activeElement for retrieving focused element Fixes unit tests in phantom. --- tests/unit/calendar/calendar_core.js | 18 +++++++++--------- tests/unit/calendar/calendar_test_helpers.js | 6 +++--- tests/unit/datepicker/datepicker_events.js | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/unit/calendar/calendar_core.js b/tests/unit/calendar/calendar_core.js index 8e39843838c..9ffbe50925c 100644 --- a/tests/unit/calendar/calendar_core.js +++ b/tests/unit/calendar/calendar_core.js @@ -139,7 +139,7 @@ asyncTest( "keyboard handling", function() { .focusGrid( element ) .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2013, 12 - 1, 31 ), @@ -170,7 +170,7 @@ asyncTest( "keyboard handling", function() { TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2013, 12 - 1, 25 ), @@ -186,7 +186,7 @@ asyncTest( "keyboard handling", function() { TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2014, 1 - 1, 8 ), @@ -202,7 +202,7 @@ asyncTest( "keyboard handling", function() { TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2013, 12 - 1, 1 ), @@ -219,7 +219,7 @@ asyncTest( "keyboard handling", function() { TestHelpers.calendar.focusGrid( element ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2013, 1 - 1, 1 ), @@ -235,7 +235,7 @@ asyncTest( "keyboard handling", function() { TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2014, 2 - 1, 1 ), @@ -252,7 +252,7 @@ asyncTest( "keyboard handling", function() { TestHelpers.calendar.focusGrid( element ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2015, 1 - 1, 1 ), @@ -269,7 +269,7 @@ asyncTest( "keyboard handling", function() { TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2014, 2 - 1, 28 ), @@ -285,7 +285,7 @@ asyncTest( "keyboard handling", function() { TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2016, 2 - 1, 29 ), diff --git a/tests/unit/calendar/calendar_test_helpers.js b/tests/unit/calendar/calendar_test_helpers.js index c5dfbd4a271..630fff350f7 100644 --- a/tests/unit/calendar/calendar_test_helpers.js +++ b/tests/unit/calendar/calendar_test_helpers.js @@ -16,9 +16,9 @@ TestHelpers.calendar = { }, focusGrid: function( element ) { element.find( ":tabbable" ).last().simulate( "focus" ); - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); - return $( ":focus" ); + return $( document.activeElement ); } }; diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index ff5438cd2f1..6b2cc200727 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -108,7 +108,7 @@ asyncTest( "select", function() { .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ) + $( document.activeElement ) .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); input.datepicker( "close" ); @@ -122,7 +122,7 @@ asyncTest( "select", function() { .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - $( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); input.datepicker( "close" ); start(); }, 100 ); From 91ff2cac466c8d817268ea24c395448b04886d18 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 19 Jan 2015 17:58:58 +0100 Subject: [PATCH 057/179] Datepicker: Run datepicker tests in Grunt qunit task --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 6f5000c6fb8..81c3a26187e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -175,7 +175,7 @@ grunt.initConfig({ }, qunit: { files: expandFiles( "tests/unit/" + component + "/*.html" ).filter(function( file ) { - return !( /(all|index|test|datepicker)\.html$/ ).test( file ); + return !( /(all|index|test)\.html$/ ).test( file ); }), options: { page: { From 4778efc2c653f136cc7f4df9cd833bf8e6e35a8d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 20 Jan 2015 15:38:06 +0100 Subject: [PATCH 058/179] Datepicker: Fix visual tests --- tests/visual/compound/datepicker_dialog.html | 4 ++++ tests/visual/compound/dialog_widgets.html | 4 ++++ tests/visual/dialog/complex-dialogs.html | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/tests/visual/compound/datepicker_dialog.html b/tests/visual/compound/datepicker_dialog.html index 52c91a0835b..374b2aeb573 100644 --- a/tests/visual/compound/datepicker_dialog.html +++ b/tests/visual/compound/datepicker_dialog.html @@ -6,6 +6,9 @@ + + + @@ -13,6 +16,7 @@ + + + + @@ -16,6 +19,7 @@ + diff --git a/tests/visual/dialog/complex-dialogs.html b/tests/visual/dialog/complex-dialogs.html index fdc00322e37..8b17a3389b2 100644 --- a/tests/visual/dialog/complex-dialogs.html +++ b/tests/visual/dialog/complex-dialogs.html @@ -15,6 +15,10 @@ + + + + From c1b6891c9ace567524cda48def6be3d45cbaae39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scott=20Gonz=C3=A1lez?= Date: Thu, 29 Jan 2015 13:41:42 -0500 Subject: [PATCH 059/179] Datepicker: Update description metadata --- ui/datepicker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index f94247ae1ff..09f89cd252d 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -9,7 +9,7 @@ //>>label: Datepicker //>>group: Widgets -//>>description: Displays a calendar from an input or inline for selecting dates. +//>>description: Displays a calendar for input-based date selection. //>>docs: http://api.jqueryui.com/datepicker/ //>>demos: http://jqueryui.com/datepicker/ From 2ea46ae1afaa777aa129c1a06e8ea0152fa616be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scott=20Gonz=C3=A1lez?= Date: Thu, 29 Jan 2015 13:41:50 -0500 Subject: [PATCH 060/179] Calendar: Add build metadata --- ui/calendar.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index d7a89746cbe..44d07a285db 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -5,9 +5,14 @@ * Copyright 2014 jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/calendar/ */ + +//>>label: Datepicker +//>>group: Widgets +//>>description: Displays a calendar for inline date selection. +//>>docs: http://api.jqueryui.com/calendar/ +//>>demos: http://jqueryui.com/calendar/ + (function( factory ) { if ( typeof define === "function" && define.amd ) { From 876aed3cd5c93df110e804caa7a2257e0d47c79f Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 20 Jan 2015 17:43:03 +0100 Subject: [PATCH 061/179] Datepicker: Make Calendar pass-through options more dynamic Move calendarOptions variable into datepicker prototype. Ref gh-1432 --- ui/datepicker.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 09f89cd252d..8e9aca716f9 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -31,10 +31,7 @@ } }(function( $ ) { -var widget, - calendarOptions = [ "buttons", "dateFormat", "disabled", "eachDay", "max", "min", "numberOfMonths", "showWeek" ]; - -widget = $.widget( "ui.datepicker", { +var widget = $.widget( "ui.datepicker", { version: "@VERSION", options: { appendTo: null, @@ -52,6 +49,9 @@ widget = $.widget( "ui.datepicker", { select: null }, + calendarOptions: [ "buttons", "dateFormat", "disabled", "eachDay", "max", + "min", "numberOfMonths", "showWeek" ], + _create: function() { this.suppressExpandOnFocus = false; this._createCalendar(); @@ -312,7 +312,7 @@ widget = $.widget( "ui.datepicker", { _setOption: function( key, value ) { this._super( key, value ); - if ( $.inArray( key, calendarOptions ) !== -1 ) { + if ( $.inArray( key, this.calendarOptions ) !== -1 ) { this.calendarInstance.option( key, value ); } @@ -341,7 +341,7 @@ widget = $.widget( "ui.datepicker", { } }); -$.each( calendarOptions, function( index, option ) { +$.each( $.ui.datepicker.prototype.calendarOptions, function( index, option ) { $.ui.datepicker.prototype.options[ option ] = $.ui.calendar.prototype.options[ option ]; }); From a5734cdd4d9aef0148aa3ffae8313db8f6190cd1 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 20 Jan 2015 17:51:06 +0100 Subject: [PATCH 062/179] Datepicker: Remove whitespace Ref gh-1432 --- ui/datepicker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 8e9aca716f9..4a1c486f594 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -255,7 +255,7 @@ var widget = $.widget( "ui.datepicker", { this._setHiddenPicker(); this._hide( this.calendar, this.options.hide ); - this.element.attr( "tabindex" , 0 ); + this.element.attr( "tabindex", 0 ); this.isOpen = false; this._trigger( "close", event ); @@ -274,7 +274,7 @@ var widget = $.widget( "ui.datepicker", { value: function( value ) { if ( arguments.length ) { - this.valueAsDate( Globalize.parseDate( value , this.options.dateFormat ) ); + this.valueAsDate( Globalize.parseDate( value, this.options.dateFormat ) ); } else { return this._getParsedValue() ? this.element.val() : null; } From 11c1735275eb91e92398401012e4967d0067cbcf Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 20 Jan 2015 18:23:49 +0100 Subject: [PATCH 063/179] Calendar: Use button instead of link elements for day items Ref gh-1432 --- tests/unit/calendar/calendar_core.js | 12 ++++++------ tests/unit/calendar/calendar_methods.js | 10 ++++++++-- tests/unit/calendar/calendar_options.js | 12 ++++++------ tests/unit/datepicker/datepicker_core.js | 2 +- tests/unit/datepicker/datepicker_events.js | 4 ++-- tests/unit/datepicker/datepicker_methods.js | 10 ++++++++-- themes/base/calendar.css | 13 ++++++++++--- ui/calendar.js | 19 ++++++++++--------- 8 files changed, 51 insertions(+), 31 deletions(-) diff --git a/tests/unit/calendar/calendar_core.js b/tests/unit/calendar/calendar_core.js index 9ffbe50925c..dbcdda8eae1 100644 --- a/tests/unit/calendar/calendar_core.js +++ b/tests/unit/calendar/calendar_core.js @@ -306,7 +306,7 @@ asyncTest( "mouse", function() { date = new Date(); function step1() { - $( "tbody a:contains(10)", element ).simulate( "mousedown" ); + $( "tbody button:contains(10)", element ).simulate( "mousedown" ); date.setDate( 10 ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), @@ -315,7 +315,7 @@ asyncTest( "mouse", function() { ); element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); - $( ".ui-calendar-calendar tbody a:contains(12)", element ).simulate( "mousedown" ); + $( ".ui-calendar-calendar tbody button:contains(12)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), @@ -325,7 +325,7 @@ asyncTest( "mouse", function() { // 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" ); + $( ".ui-calendar-calendar tbody button:contains(16)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), @@ -334,7 +334,7 @@ asyncTest( "mouse", function() { 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" ); + $( ".ui-calendar-calendar tbody button:contains(18)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), @@ -354,7 +354,7 @@ asyncTest( "mouse", function() { }); $( ".ui-calendar-prev", element ).simulate( "click" ); - $( "tbody a:contains(16)", element ).simulate( "mousedown" ); + $( "tbody button:contains(16)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 16 ), @@ -372,7 +372,7 @@ asyncTest( "mouse", function() { }); $( ".ui-calendar-next", element ).simulate( "click" ); - $( "tbody a:contains(18)", element ).simulate( "mousedown" ); + $( "tbody button:contains(18)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 18 ), diff --git a/tests/unit/calendar/calendar_methods.js b/tests/unit/calendar/calendar_methods.js index c7b7bf8dc8f..d447e4eab8b 100644 --- a/tests/unit/calendar/calendar_methods.js +++ b/tests/unit/calendar/calendar_methods.js @@ -42,7 +42,10 @@ test( "value", function() { 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" ); + ok( element.find( "button[data-timestamp]:first" ) + .hasClass( "ui-state-active" ), + "first day marked as selected" + ); equal( element.calendar( "value" ), "1/1/14", "getter" ); element.calendar( "value", "abc" ); @@ -58,7 +61,10 @@ test( "valueAsDate", function() { date2; element.calendar( "valueAsDate", new Date( 2014, 0, 1 ) ); - ok( element.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "First day marked as selected" ); + ok( element.find( "button[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" ); diff --git a/tests/unit/calendar/calendar_options.js b/tests/unit/calendar/calendar_options.js index e5a09d3d89e..f1ec947550f 100644 --- a/tests/unit/calendar/calendar_options.js +++ b/tests/unit/calendar/calendar_options.js @@ -112,7 +112,7 @@ test( "dateFormat", function() { var element = $( "#calendar" ).calendar({ value: "1/1/14" }), - firstDayLink = element.calendar( "widget" ).find( "td[id]:first a" ); + firstDayLink = element.calendar( "widget" ).find( "td[id]:first button" ); firstDayLink.trigger( "mousedown" ); equal( element.calendar( "value" ), "1/1/14", "default formatting" ); @@ -128,8 +128,8 @@ test( "eachDay", function() { 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( firstCell.find( "button" ).length, 1, "days are selectable by default" ); + timestamp = parseInt( firstCell.find( "button" ).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 @@ -139,7 +139,7 @@ test( "eachDay", function() { } }); firstCell = picker.find( "td[id]:first" ); - timestamp = parseInt( firstCell.find( "a" ).attr( "data-timestamp" ), 10 ); + timestamp = parseInt( firstCell.find( "button" ).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. @@ -149,14 +149,14 @@ test( "eachDay", function() { } }); firstCell = picker.find( "td[id]:first" ); - equal( firstCell.find( "a" ).length, 0, "the 1st is not selectable" ); + ok( firstCell.find( "button" ).prop( "disabled" ), "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" ); + ok( picker.find( "td[id]:first button" ).hasClass( "ui-custom" ), "extraClasses applied" ); input.calendar( "destroy" ); }); diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index ffb7ab6c4f2..f7b508d7ad3 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -136,7 +136,7 @@ asyncTest( "mouse", function() { setTimeout(function() { input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); + $( ".ui-calendar-calendar tbody button:contains(12)", picker ).simulate( "mousedown", {} ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 12 ), diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index 6b2cc200727..35720ebf6c7 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -57,7 +57,7 @@ test( "close", function() { shouldFire = false; input.datepicker( "open" ); shouldFire = true; - input.datepicker( "widget" ).find( "tbody tr:first a:first" ).simulate( "mousedown" ); + input.datepicker( "widget" ).find( "tbody tr:first button:first" ).simulate( "mousedown" ); }); test( "open", function() { @@ -96,7 +96,7 @@ asyncTest( "select", function() { .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - widget.find( "tbody tr:first a:first" ).simulate( "mousedown" ); + widget.find( "tbody tr:first button:first" ).simulate( "mousedown" ); input.datepicker( "close" ); step2(); }, 100 ); diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 76b76813c4f..b969c00f493 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -72,7 +72,10 @@ test( "value", function() { equal( input.val(), "1/1/14", "input's value set" ); input.datepicker( "open" ); - ok( picker.find( "a[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), "first day marked as selected" ); + ok( + picker.find( "button[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), + "first day marked as selected" + ); equal( input.datepicker( "value" ), "1/1/14", "getter" ); input.val( "abc" ); @@ -88,7 +91,10 @@ 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]" ).eq( 0 ).hasClass( "ui-state-active" ), "First day marked as selected" ); + ok( + picker.find( "button[data-timestamp]" ).eq( 0 ).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" ); diff --git a/themes/base/calendar.css b/themes/base/calendar.css index 7dc8e182929..2262e97a9e5 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -82,12 +82,19 @@ border: 0; padding: 1px; } -.ui-calendar td span, -.ui-calendar td a { +.ui-calendar td button { display: block; padding: .2em; text-align: right; - text-decoration: none; + cursor: pointer; + width: 100%; +} +.ui-calendar td button::-moz-focus-inner { + padding: 0; + border: 0; +} +.ui-calendar .ui-state-disabled button { + cursor: default; } .ui-calendar .ui-calendar-buttonpane { background-image: none; diff --git a/ui/calendar.js b/ui/calendar.js index 44d07a285db..6cb0dd343e6 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -75,7 +75,7 @@ return $.widget( "ui.calendar", { this.date.adjust( "M", this.options.numberOfMonths ); this.refresh(); }, - "mousedown .ui-calendar-calendar a": function( event ) { + "mousedown .ui-calendar-calendar button": function( event ) { event.preventDefault(); // TODO Exclude clicks on lead days or handle them correctly @@ -85,8 +85,8 @@ return $.widget( "ui.calendar", { }, "mouseenter .ui-calendar-header button": "_hover", "mouseleave .ui-calendar-header button": "_hover", - "mouseenter .ui-calendar-calendar a": "_hover", - "mouseleave .ui-calendar-calendar a": "_hover", + "mouseenter .ui-calendar-calendar button": "_hover", + "mouseleave .ui-calendar-calendar button": "_hover", "keydown .ui-calendar-calendar": "_handleKeydown" }); @@ -152,7 +152,7 @@ return $.widget( "ui.calendar", { .removeClass( "ui-state-focus" ); this.activeDescendant = this.grid.find( - this._sanitizeSelector( "#" + id ) + " > a" + this._sanitizeSelector( "#" + id ) + " > button" ).addClass( "ui-state-focus" ); }, @@ -351,8 +351,8 @@ return $.widget( "ui.calendar", { }, _buildDayElement: function( day, selectable ) { - var classes = [ "ui-state-default" ], - content = ""; + var attributes, content, + classes = [ "ui-state-default" ]; if ( day === this.date && selectable ) { classes.push( "ui-state-focus" ); @@ -368,12 +368,13 @@ return $.widget( "ui.calendar", { classes.push( day.extraClasses.split( " " ) ); } - classes = " class='" + classes.join( " " ) + "'"; + attributes = " class='" + classes.join( " " ) + "'"; if ( selectable ) { - content = "
      " + day.date + ""; + attributes += " tabindex='-1' data-timestamp='" + day.timestamp + "'"; } else { - content = "" + day.date + ""; + attributes += " disabled='disabled'"; } + content = "" + day.date + ""; if ( day.today ) { content += ", " + this._getTranslation( "currentText" ) + ""; From c29b5e465d9a2ab863df080373a5131a5608c1fa Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 20 Jan 2015 18:35:59 +0100 Subject: [PATCH 064/179] Calendar: Fix border style for multiple months Ref gh-1432 --- ui/calendar.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 6cb0dd343e6..ced58bc528d 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -191,15 +191,15 @@ return $.widget( "ui.calendar", { // TODO: Shouldn't we pass date as a parameter to build* fns instead of setting this.date? this.date = months[ i ]; + headerClass = "ui-calendar-header ui-widget-header ui-helper-clearfix"; if ( months[ i ].first ) { - headerClass = "ui-corner-left"; + headerClass += " ui-corner-left"; } else if ( months[ i ].last ) { - headerClass = "ui-corner-right"; + headerClass += " ui-corner-right"; } html += "
      " + - "
      "; + "
      "; if ( months[ i ].first ) { html += this._buildPreviousLink(); } else if ( months[ i ].last ) { From d96ad14284b0457bf1f2e2a94cf2295ec63a9a24 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 31 Jan 2015 00:42:40 +0100 Subject: [PATCH 065/179] Calendar: Clean up styles, add comments Ref gh-1432 --- themes/base/calendar.css | 43 ++++++---------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/themes/base/calendar.css b/themes/base/calendar.css index 2262e97a9e5..b8e99baf545 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -12,6 +12,8 @@ width: 17em; padding: .2em .2em 0; } + +/* calendar header */ .ui-calendar .ui-calendar-header { position: relative; padding: .2em 0; @@ -29,22 +31,12 @@ 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; @@ -58,14 +50,8 @@ 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%; -} + +/* calendar grid */ .ui-calendar table { width: 100%; font-size: .9em; @@ -96,6 +82,8 @@ .ui-calendar .ui-state-disabled button { cursor: default; } + +/* button pane */ .ui-calendar .ui-calendar-buttonpane { background-image: none; margin: .7em 0 0 0; @@ -128,19 +116,6 @@ width: 95%; margin: 0 2.5% .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; } @@ -180,9 +155,3 @@ .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; -} - From bbe1eff498ac7129b0240d0ff17c7d20685bf2a3 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 31 Jan 2015 00:53:14 +0100 Subject: [PATCH 066/179] Calendar: Adjust styles to match theme changes Ref gh-1432 --- themes/base/calendar.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/themes/base/calendar.css b/themes/base/calendar.css index b8e99baf545..def9fe4fffb 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -23,8 +23,8 @@ cursor: pointer; position: absolute; top: 2px; - width: 19px; - height: 18px; + width: 36px; + height: 31px; } .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) { @@ -110,6 +110,7 @@ display: inline-block; } .ui-calendar-multi .ui-calendar-group { + width: 17em; float: left; } .ui-calendar-multi .ui-calendar-group table { From ec0d679e648d8ff949b348d511c91ce727e0ed2f Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 24 Jan 2015 02:23:24 +0100 Subject: [PATCH 067/179] Calendar: Remove selected property from $.date --- external/date.js | 9 --------- ui/calendar.js | 13 +++++++++---- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/external/date.js b/external/date.js index 8df3f63de92..fd473fbbf18 100644 --- a/external/date.js +++ b/external/date.js @@ -32,7 +32,6 @@ $.date = function( date, globalFormat ) { this.dateObject = this.dateObject || new Date(); this.globalFormat = globalFormat; - this.selected = null; }; $.date.prototype = { @@ -153,7 +152,6 @@ $.date.prototype = { 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; @@ -180,13 +178,6 @@ $.date.prototype = { result[ result.length - 1 ].last = true; return result; }, - select: function() { - this.selected = this.clone(); - return this; - }, - selectedDate: function() { - return this.selected.date(); - }, clone: function() { var date = this.dateObject; return new $.date( new Date( date.getFullYear(), date.getMonth(), diff --git a/ui/calendar.js b/ui/calendar.js index ced58bc528d..c1ce10b6bdb 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -61,8 +61,9 @@ return $.widget( "ui.calendar", { this.labels = Globalize.translate( "datepicker" ); this.buttonClickContext = this.element[ 0 ]; - this.date = $.date( this.options.value, this.options.dateFormat ).select(); + this.date = $.date( this.options.value, this.options.dateFormat ); this.date.eachDay = this.options.eachDay; + this.options.value = this.date.date(); this._on( this.element, { "click .ui-calendar-prev": function( event ) { @@ -332,7 +333,7 @@ return $.widget( "ui.calendar", { var content = "", attributes = [ "role='gridcell'", - "aria-selected='" + ( day.current ? true : false ) + "'" + "aria-selected='" + ( this._isCurrent( day ) ? true : false ) + "'" ], selectable = ( day.selectable && this._isValid( new Date( day.timestamp ) ) ); @@ -357,7 +358,7 @@ return $.widget( "ui.calendar", { if ( day === this.date && selectable ) { classes.push( "ui-state-focus" ); } - if ( day.current ) { + if ( this._isCurrent( day ) ) { classes.push( "ui-state-active" ); } if ( day.today ) { @@ -383,6 +384,10 @@ return $.widget( "ui.calendar", { return content; }, + _isCurrent: function( day ) { + return day.timestamp === this.options.value.getTime(); + }, + _createButtonPane: function() { this.buttonPane = $( "
      " ) .addClass( "ui-calendar-buttonpane ui-widget-content ui-helper-clearfix" ); @@ -558,7 +563,7 @@ return $.widget( "ui.calendar", { _setOption: function( key, value ) { if ( key === "value" ) { if ( this._isValid( value ) ) { - this.date.setTime( value.getTime() ).select(); + this.date.setTime( value.getTime() ); this._super( key, value ); } return; From 4c2229fc51dbb70e1dcb96afdaef92d7c41a44eb Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 24 Jan 2015 02:23:24 +0100 Subject: [PATCH 068/179] Calendar: Fix month jumping WIP Fixes multiple-month demo and other-month demo. --- external/date.js | 2 ++ ui/calendar.js | 79 +++++++++++++++++++++++++++--------------------- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/external/date.js b/external/date.js index fd473fbbf18..7ddf4c53a56 100644 --- a/external/date.js +++ b/external/date.js @@ -151,6 +151,8 @@ $.date.prototype = { var day = week.days[ week.days.length ] = { lead: printDate.getMonth() != date.getMonth(), date: printDate.getDate(), + month: printDate.getMonth(), + year: printDate.getFullYear(), timestamp: printDate.getTime(), today: today.equal( printDate ) }; diff --git a/ui/calendar.js b/ui/calendar.js index c1ce10b6bdb..05d4c229b80 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -62,26 +62,26 @@ return $.widget( "ui.calendar", { this.buttonClickContext = this.element[ 0 ]; this.date = $.date( this.options.value, this.options.dateFormat ); - this.date.eachDay = this.options.eachDay; - this.options.value = this.date.date(); + this.viewDate = this.date.clone(); + this.viewDate.eachDay = this.options.eachDay; this._on( this.element, { "click .ui-calendar-prev": function( event ) { event.preventDefault(); this.date.adjust( "M", -this.options.numberOfMonths ); - this.refresh(); + this._refresh(); }, "click .ui-calendar-next": function( event ) { event.preventDefault(); this.date.adjust( "M", this.options.numberOfMonths ); - this.refresh(); + this._refresh(); }, "mousedown .ui-calendar-calendar button": 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" ) ); + this._setOption( "value", new Date( $( event.currentTarget ).data( "timestamp" ) ) ); + this.refresh(); + this._trigger( "select", event ); this.grid.focus(); }, "mouseenter .ui-calendar-header button": "_hover", @@ -99,10 +99,6 @@ return $.widget( "ui.calendar", { }, _handleKeydown: function( event ) { - var oldMonth = this.date.month(), - oldYear = this.date.year(); - - // TODO: Handle for pickers with multiple months switch ( event.keyCode ) { case $.ui.keyCode.ENTER: this.activeDescendant.mousedown(); @@ -136,16 +132,26 @@ return $.widget( "ui.calendar", { return; } - if ( this.date.month() !== oldMonth || this.date.year() !== oldYear ) { - this.refresh(); + if ( this._needsRefresh() ) { + this._refresh(); this.grid.focus(); } this._setActiveDescendant(); }, + _needsRefresh: function() { + if ( this.date.month() !== this.viewDate.month() || this.date.year() !== this.viewDate.year() ) { + return !this.grid.find( + this._sanitizeSelector( "#" + this._getDayId( this.date ) ) + ).length; + } + + return false; + }, + _setActiveDescendant: function() { - var id = this.id + "-" + this.date.day(); + var id = this._getDayId( this.date ); this.grid .attr( "aria-activedescendant", id ) @@ -184,14 +190,14 @@ return $.widget( "ui.calendar", { _buildMultiplePicker: function() { var headerClass, html = "", - currentDate = this.date, - months = this.date.months( this.options.numberOfMonths - 1 ), + currentDate = this.viewDate, + months = this.viewDate.months( this.options.numberOfMonths - 1 ), i = 0; for ( ; 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 ]; + this.viewDate = months[ i ]; headerClass = "ui-calendar-header ui-widget-header ui-helper-clearfix"; if ( months[ i ].first ) { headerClass += " ui-corner-left"; @@ -212,7 +218,7 @@ return $.widget( "ui.calendar", { html += "
      "; - this.date = currentDate; + this.viewDate = currentDate; return html; }, @@ -260,17 +266,17 @@ return $.widget( "ui.calendar", { _buildTitle: function() { return "" + - this.date.monthName() + + this.viewDate.monthName() + " " + "" + - this.date.year() + + this.viewDate.year() + ""; }, _buildGrid: function() { return "" + + "aria-activedescendant='" + this._getDayId( this.date ) + "'>" + this._buildGridHeading() + this._buildGridBody() + "
      "; @@ -279,7 +285,7 @@ return $.widget( "ui.calendar", { _buildGridHeading: function() { var cells = "", i = 0, - weekDayLength = this.date.weekdays().length; + weekDayLength = this.viewDate.weekdays().length; if ( this.options.showWeek ) { cells += "" + this._getTranslation( "weekHeader" ) + ""; @@ -304,7 +310,7 @@ return $.widget( "ui.calendar", { _buildGridBody: function() { // this.date.days() needs caching as it has O(n^2) complexity. - var days = this.date.days(), + var days = this.viewDate.days(), i = 0, rows = ""; @@ -338,7 +344,7 @@ return $.widget( "ui.calendar", { selectable = ( day.selectable && this._isValid( new Date( day.timestamp ) ) ); if ( day.render ) { - attributes.push( "id='" + this.id + "-" + day.date + "'" ); + attributes.push( "id='" + this.id + "-" + day.year + "-" + day.month + "-" + day.date + "'" ); if ( !selectable ) { attributes.push( "aria-disabled='true'" ); @@ -351,6 +357,10 @@ return $.widget( "ui.calendar", { return "" + content + ""; }, + _getDayId: function( date ) { + return this.id + "-" + date.year() + "-" + date.month() + "-" + date.day(); + }, + _buildDayElement: function( day, selectable ) { var attributes, content, classes = [ "ui-state-default" ]; @@ -364,7 +374,6 @@ 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( " " ) ); } @@ -385,7 +394,7 @@ return $.widget( "ui.calendar", { }, _isCurrent: function( day ) { - return day.timestamp === this.options.value.getTime(); + return this.options.value && day.timestamp === this.options.value.getTime(); }, _createButtonPane: function() { @@ -439,6 +448,11 @@ return $.widget( "ui.calendar", { this.buttonPane.appendTo( this.element ); }, + _refresh: function() { + this.viewDate.setTime( this.date.date().getTime() ); + this.refresh(); + }, + // 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 @@ -469,9 +483,9 @@ return $.widget( "ui.calendar", { for ( ; i < this.options.numberOfMonths; i++ ) { this.element.find( ".ui-calendar-title" ).eq( i ).html( this._buildTitle() ); this.element.find( ".ui-calendar-calendar" ).eq( i ).html( this._buildGrid() ); - this.date.adjust( "M", 1 ); + this.viewDate.adjust( "M", 1 ); } - this.date.adjust( "M", -this.options.numberOfMonths ); + this.viewDate.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. @@ -493,11 +507,6 @@ return $.widget( "ui.calendar", { }); }, - _select: function( event, time ) { - this.valueAsDate( new Date( time ) ); - this._trigger( "select", event ); - }, - value: function( value ) { if ( arguments.length ) { this.valueAsDate( Globalize.parseDate( value, this.options.dateFormat ) ); @@ -556,7 +565,7 @@ return $.widget( "ui.calendar", { }); if ( refresh ) { - this.refresh(); + this._refresh(); } }, @@ -589,7 +598,7 @@ return $.widget( "ui.calendar", { } if ( key === "eachDay" ) { - this.date.eachDay = value; + this.viewDate.eachDay = value; } if ( key === "dateFormat" ) { From d9ee3a1ec4e03a46de86adf4db6ce8cd95d88247 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 24 Mar 2015 20:06:32 +0100 Subject: [PATCH 069/179] Calendar tests: Fix dateFormat option test Do not use value option to pass in a string but value method. --- tests/unit/calendar/calendar_options.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/unit/calendar/calendar_options.js b/tests/unit/calendar/calendar_options.js index f1ec947550f..f8e942e037c 100644 --- a/tests/unit/calendar/calendar_options.js +++ b/tests/unit/calendar/calendar_options.js @@ -109,12 +109,11 @@ test( "buttons - advanced", function() { test( "dateFormat", function() { expect( 2 ); - var element = $( "#calendar" ).calendar({ - value: "1/1/14" - }), - firstDayLink = element.calendar( "widget" ).find( "td[id]:first button" ); + var element = $( "#calendar" ).calendar(); - firstDayLink.trigger( "mousedown" ); + element.calendar( "value", "1/1/14" ); + + element.calendar( "widget" ).find( "td[id]:first button" ).trigger( "mousedown" ); equal( element.calendar( "value" ), "1/1/14", "default formatting" ); element.calendar( "option", "dateFormat", { date: "full" } ); From a3df6dd8a8e363a276392acd7744f7db1e75eb61 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 11 Apr 2015 00:04:33 +0200 Subject: [PATCH 070/179] Calendar: Add comment in _needsRefresh method --- ui/calendar.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/calendar.js b/ui/calendar.js index 05d4c229b80..40884c28315 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -142,6 +142,9 @@ return $.widget( "ui.calendar", { _needsRefresh: function() { if ( this.date.month() !== this.viewDate.month() || this.date.year() !== this.viewDate.year() ) { + + // Check if the needed day is already present in our grid due + // to eachDay option changes (eg. other-months demo) return !this.grid.find( this._sanitizeSelector( "#" + this._getDayId( this.date ) ) ).length; From b5bae456a2ab92be358f085b38d2b2c94d825d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scott=20Gonz=C3=A1lez?= Date: Wed, 15 Jul 2015 10:24:21 -0400 Subject: [PATCH 071/179] Spinner: Fix demos to use old Globalize --- demos/spinner/currency.html | 6 +++--- demos/spinner/decimal.html | 6 +++--- demos/spinner/time.html | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/demos/spinner/currency.html b/demos/spinner/currency.html index 0509e80a084..1f2ef8c24a2 100644 --- a/demos/spinner/currency.html +++ b/demos/spinner/currency.html @@ -6,9 +6,9 @@ - - - + + + diff --git a/demos/spinner/decimal.html b/demos/spinner/decimal.html index 6c3df9439fd..40ce5b2238c 100644 --- a/demos/spinner/decimal.html +++ b/demos/spinner/decimal.html @@ -6,9 +6,9 @@ - - - + + + diff --git a/demos/spinner/time.html b/demos/spinner/time.html index 229b0e6b4bb..e3cf6a66d7d 100644 --- a/demos/spinner/time.html +++ b/demos/spinner/time.html @@ -6,8 +6,8 @@ - - + + From d0a5a7a0e63c1becd3c76f00d0af219458d93861 Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Wed, 3 Sep 2014 15:59:37 -0300 Subject: [PATCH 072/179] Datepicker: Use Globalize 1.0.0 - Update Globalize to 1.0.0-alpha.6 --- Gruntfile.js | 10 + bower.json | 19 +- external/cldrjs/LICENSE-MIT/LICENSE-MIT | 22 + external/cldrjs/cldr.js | 549 +++ external/cldrjs/cldr/event.js | 585 ++++ external/cldrjs/cldr/supplemental.js | 101 + external/date.js | 8 +- external/globalize/{LICENSE => LICENSE.txt} | 27 +- external/globalize/globalize.js | 1904 ++-------- external/globalize/globalize/date.js | 1254 +++++++ external/globalize/globalize/message.js | 86 + external/localization.js | 3467 ++++++++++--------- tests/unit/datepicker/datepicker.html | 38 +- ui/calendar.js | 2 +- ui/datepicker.js | 2 +- 15 files changed, 4720 insertions(+), 3354 deletions(-) create mode 100644 external/cldrjs/LICENSE-MIT/LICENSE-MIT create mode 100644 external/cldrjs/cldr.js create mode 100644 external/cldrjs/cldr/event.js create mode 100644 external/cldrjs/cldr/supplemental.js rename external/globalize/{LICENSE => LICENSE.txt} (56%) create mode 100644 external/globalize/globalize/date.js create mode 100644 external/globalize/globalize/message.js diff --git a/Gruntfile.js b/Gruntfile.js index 5d77e739306..f4c59f6d301 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -276,6 +276,16 @@ grunt.initConfig({ destPrefix: "external" }, files: { + "cldrjs/cldr.js": "cldrjs/dist/cldr.js", + "cldrjs/cldr/event.js": "cldrjs/dist/cldr/event.js", + "cldrjs/cldr/supplemental.js": "cldrjs/dist/cldr/supplemental.js", + "cldrjs/LICENSE-MIT": "cldrjs/LICENSE-MIT", + + "globalize/globalize.js": "globalize/dist/globalize.js", + "globalize/globalize/date.js": "globalize/dist/globalize/date.js", + "globalize/globalize/message.js": "globalize/dist/globalize/message.js", + "globalize/LICENSE.txt": "globalize/LICENSE.txt", + "qunit/qunit.js": "qunit/qunit/qunit.js", "qunit/qunit.css": "qunit/qunit/qunit.css", "qunit/LICENSE.txt": "qunit/LICENSE.txt", diff --git a/bower.json b/bower.json index 2c8b5a6baee..ab99b8062c2 100644 --- a/bower.json +++ b/bower.json @@ -14,11 +14,8 @@ "jquery-mousewheel": "3.1.12", "jquery-simulate": "1.0.0", "jshint": "2.4.4", - "qunit": "1.18.0", - "qunit-assert-classes": "1.0.2", - "qunit-assert-close": "JamesMGreene/qunit-assert-close#v1.1.1", - "qunit-composite": "JamesMGreene/qunit-composite#v1.1.0", - "requirejs": "2.1.14", + "qunit": "1.17.1", + "globalize": "1.0.0-alpha.6", "jquery-1.7.0": "jquery#1.7.0", "jquery-1.7.1": "jquery#1.7.1", @@ -32,18 +29,10 @@ "jquery-1.10.0": "jquery#1.10.0", "jquery-1.10.1": "jquery#1.10.1", "jquery-1.10.2": "jquery#1.10.2", - "jquery-1.11.0": "jquery#1.11.0", - "jquery-1.11.1": "jquery#1.11.1", - "jquery-1.11.2": "jquery#1.11.2", - "jquery-1.11.3": "jquery#1.11.3", - "jquery-1.x": "jquery#1.11.3", + "jquery-1.x": "jquery#1.10.2", "jquery-2.0.0": "jquery#2.0.0", "jquery-2.0.1": "jquery#2.0.1", "jquery-2.0.2": "jquery#2.0.2", - "jquery-2.0.3": "jquery#2.0.3", - "jquery-2.1.0": "jquery#2.1.0", - "jquery-2.1.1": "jquery#2.1.1", - "jquery-2.1.2": "jquery#2.1.2", - "jquery-2.1.3": "jquery#2.1.3" + "jquery-2.0.3": "jquery#2.0.3" } } diff --git a/external/cldrjs/LICENSE-MIT/LICENSE-MIT b/external/cldrjs/LICENSE-MIT/LICENSE-MIT new file mode 100644 index 00000000000..6db134a6952 --- /dev/null +++ b/external/cldrjs/LICENSE-MIT/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2013 Rafael Xavier de Souza http://rafael.xavier.blog.br + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/external/cldrjs/cldr.js b/external/cldrjs/cldr.js new file mode 100644 index 00000000000..95515ba857d --- /dev/null +++ b/external/cldrjs/cldr.js @@ -0,0 +1,549 @@ +/** + * CLDR JavaScript Library v0.3.8 + * http://jquery.com/ + * + * Copyright 2013 Rafael Xavier de Souza + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-07-13T05:05Z + */ +/*! + * CLDR JavaScript Library v0.3.8 2014-07-13T05:05Z MIT license © Rafael Xavier + * http://git.io/h4lmVg + */ +(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.Cldr = factory(); + } + +}( this, function() { + + + + 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 objectKeys = function( object ) { + var i, + result = []; + + if ( Object.keys ) { + return Object.keys( object ); + } + + for ( i in object ) { + result.push( i ); + } + + return result; + }; + + + + + var createError = function( code, attributes ) { + var error, message; + + message = code + ( attributes && JSON ? ": " + JSON.stringify( attributes ) : "" ); + error = new Error( message ); + error.code = code; + + // extend( error, attributes ); + arrayForEach( objectKeys( attributes ), function( attribute ) { + error[ attribute ] = attributes[ attribute ]; + }); + + return error; + }; + + + + + var validate = function( code, check, attributes ) { + if ( !check ) { + throw createError( code, attributes ); + } + }; + + + + + var validatePresence = function( value, name ) { + validate( "E_MISSING_PARAMETER", typeof value !== "undefined", { + name: name + }); + }; + + + + + var validateType = function( value, name, check, expected ) { + validate( "E_INVALID_PAR_TYPE", check, { + expected: expected, + name: name, + value: value + }); + }; + + + + + var arrayIsArray = Array.isArray || function( obj ) { + return Object.prototype.toString.call( obj ) === "[object Array]"; + }; + + + + + var validateTypePath = function( value, name ) { + validateType( value, name, typeof value === "string" || arrayIsArray( value ), "String or Array" ); + }; + + + + + /** + * Function inspired by jQuery Core, but reduced to our use case. + */ + var isPlainObject = function( obj ) { + return obj !== null && "" + obj === "[object Object]"; + }; + + + + + var validateTypePlainObject = function( value, name ) { + validateType( value, name, typeof value === "undefined" || isPlainObject( value ), "Plain Object" ); + }; + + + + + var validateTypeString = function( value, name ) { + validateType( value, name, typeof value === "string", "a string" ); + }; + + + + + 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 coreLikelySubtags = function( Cldr, cldr, subtags, options ) { + var match, matchFound, + language = subtags[ 0 ], + script = subtags[ 1 ], + sep = Cldr.localeSep, + 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( sep ) ) /* [1.4] */ && cldr.get( [ "supplemental/likelySubtags", test.join( sep ) ] ); + }); + + // [3] + if ( matchFound ) { + // [3.2 .. 3.4] + match = match.split( sep ); + 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( sep ); + } 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 coreRemoveLikelySubtags = function( Cldr, 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 = coreLikelySubtags( Cldr, 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; + }; + + + + + // @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 itemGetResolved = function( Cldr, path, attributes ) { + // Resolve path + var normalizedPath = pathNormalize( path, attributes ); + + return resourceGet( Cldr._resolved, normalizedPath ); + }; + + + + + var alwaysArray = function( stringOrArray ) { + return typeof stringOrArray === "string" ? [ stringOrArray ] : stringOrArray; + }; + + + 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; + +}()); + + + /** + * new Cldr() + */ + var Cldr = function( locale ) { + this.init( locale ); + }; + + // Build optimization hack to avoid duplicating functions across modules. + Cldr._alwaysArray = alwaysArray; + Cldr._createError = createError; + Cldr._itemGetResolved = itemGetResolved; + Cldr._jsonMerge = jsonMerge; + Cldr._pathNormalize = pathNormalize; + Cldr._resourceGet = resourceGet; + Cldr._validatePresence = validatePresence; + Cldr._validateType = validateType; + Cldr._validateTypePath = validateTypePath; + Cldr._validateTypePlainObject = validateTypePlainObject; + + Cldr._resolved = {}; + + // Allow user to override locale separator "-" (default) | "_". According to http://www.unicode.org/reports/tr35/#Unicode_language_identifier, both "-" and "_" are valid locale separators (eg. "en_GB", "en-GB"). According to http://unicode.org/cldr/trac/ticket/6786 its usage must be consistent throughout the data set. + Cldr.localeSep = "-"; + + // Load resolved cldr data + // @json [JSON] + Cldr.load = function( json ) { + validatePresence( json, "json" ); + validateTypePlainObject( json, "json" ); + Cldr._resolved = jsonMerge( Cldr._resolved, json ); + }; + + /** + * .init() automatically run on instantiation/construction. + */ + Cldr.prototype.init = function( locale ) { + var language, languageId, maxLanguageId, script, territory, unicodeLanguageId, variant, + sep = Cldr.localeSep; + + validatePresence( locale, "locale" ); + validateTypeString( locale, "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,3}_[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,3}_[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,3}_[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,3}|root)(\b|_)/.test( unicodeLanguageId ): + language = unicodeLanguageId.split( "_" )[ 0 ]; + script = "Zzzz"; + territory = "ZZ"; + variant = unicodeLanguageId.split( "_" )[ 1 ]; + break; + + default: + language = "und"; + script = "Zzzz"; + territory = "ZZ"; + break; + } + + // When a locale id does not specify a language, or territory (region), or script, they are obtained by Likely Subtags. + maxLanguageId = coreLikelySubtags( Cldr, this, [ language, script, territory ], { force: true } ) || unicodeLanguageId.split( "_" ); + language = maxLanguageId[ 0 ]; + script = maxLanguageId[ 1 ]; + territory = maxLanguageId[ 2 ]; + + languageId = coreRemoveLikelySubtags( Cldr, this, maxLanguageId ).join( sep ); + + // Set attributes + this.attributes = { + + // Unicode Language Id + languageId: languageId, + maxLanguageId: maxLanguageId.join( sep ), + + // Unicode Language Id Subtabs + language: language, + script: script, + territory: territory, + region: territory, /* alias */ + variant: variant + }; + + this.locale = variant ? [ languageId, variant ].join( sep ) : languageId; + }; + + /** + * .get() + */ + Cldr.prototype.get = function( path ) { + + validatePresence( path, "path" ); + validateTypePath( path, "path" ); + + return itemGetResolved( Cldr, path, this.attributes ); + }; + + /** + * .main() + */ + Cldr.prototype.main = function( path ) { + validatePresence( path, "path" ); + validateTypePath( path, "path" ); + + path = alwaysArray( path ); + return this.get( [ "main/{languageId}" ].concat( path ) ); + }; + + return Cldr; + + + +})); diff --git a/external/cldrjs/cldr/event.js b/external/cldrjs/cldr/event.js new file mode 100644 index 00000000000..46c95af53b5 --- /dev/null +++ b/external/cldrjs/cldr/event.js @@ -0,0 +1,585 @@ +/** + * CLDR JavaScript Library v0.3.8 + * http://jquery.com/ + * + * Copyright 2013 Rafael Xavier de Souza + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-07-13T05:05Z + */ +/*! + * CLDR JavaScript Library v0.3.8 2014-07-13T05:05Z MIT license © Rafael Xavier + * http://git.io/h4lmVg + */ +(function( factory ) { + + if ( typeof define === "function" && define.amd ) { + // AMD. + define( [ "../cldr" ], factory ); + } else if ( typeof module === "object" && typeof module.exports === "object" ) { + // Node. CommonJS. + module.exports = factory( require( "cldrjs" ) ); + } else { + // Global + factory( Cldr ); + } + +}(function( Cldr ) { + + // Build optimization hack to avoid duplicating functions across modules. + var pathNormalize = Cldr._pathNormalize, + validatePresence = Cldr._validatePresence, + validateType = Cldr._validateType; + + +/*! + * EventEmitter v4.2.7 - git.io/ee + * Oliver Caldwell + * MIT license + * @preserve + */ + +var EventEmitter; +/* jshint ignore:start */ +EventEmitter = (function () { + + + /** + * Class for managing events. + * Can be extended to provide event functionality in other classes. + * + * @class EventEmitter Manages event registering and emitting. + */ + function EventEmitter() {} + + // Shortcuts to improve speed and size + var proto = EventEmitter.prototype; + var exports = this; + var originalGlobalValue = exports.EventEmitter; + + /** + * Finds the index of the listener for the event in it's storage array. + * + * @param {Function[]} listeners Array of listeners to search through. + * @param {Function} listener Method to look for. + * @return {Number} Index of the specified listener, -1 if not found + * @api private + */ + function indexOfListener(listeners, listener) { + var i = listeners.length; + while (i--) { + if (listeners[i].listener === listener) { + return i; + } + } + + return -1; + } + + /** + * Alias a method while keeping the context correct, to allow for overwriting of target method. + * + * @param {String} name The name of the target method. + * @return {Function} The aliased method + * @api private + */ + function alias(name) { + return function aliasClosure() { + return this[name].apply(this, arguments); + }; + } + + /** + * Returns the listener array for the specified event. + * Will initialise the event object and listener arrays if required. + * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. + * Each property in the object response is an array of listener functions. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Function[]|Object} All listener functions for the event. + */ + proto.getListeners = function getListeners(evt) { + var events = this._getEvents(); + var response; + var key; + + // Return a concatenated array of all matching events if + // the selector is a regular expression. + if (evt instanceof RegExp) { + response = {}; + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + response[key] = events[key]; + } + } + } + else { + response = events[evt] || (events[evt] = []); + } + + return response; + }; + + /** + * Takes a list of listener objects and flattens it into a list of listener functions. + * + * @param {Object[]} listeners Raw listener objects. + * @return {Function[]} Just the listener functions. + */ + proto.flattenListeners = function flattenListeners(listeners) { + var flatListeners = []; + var i; + + for (i = 0; i < listeners.length; i += 1) { + flatListeners.push(listeners[i].listener); + } + + return flatListeners; + }; + + /** + * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. + * + * @param {String|RegExp} evt Name of the event to return the listeners from. + * @return {Object} All listener functions for an event in an object. + */ + proto.getListenersAsObject = function getListenersAsObject(evt) { + var listeners = this.getListeners(evt); + var response; + + if (listeners instanceof Array) { + response = {}; + response[evt] = listeners; + } + + return response || listeners; + }; + + /** + * Adds a listener function to the specified event. + * The listener will not be added if it is a duplicate. + * If the listener returns true then it will be removed after it is called. + * If you pass a regular expression as the event name then the listener will be added to all events that match it. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListener = function addListener(evt, listener) { + var listeners = this.getListenersAsObject(evt); + var listenerIsWrapped = typeof listener === 'object'; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { + listeners[key].push(listenerIsWrapped ? listener : { + listener: listener, + once: false + }); + } + } + + return this; + }; + + /** + * Alias of addListener + */ + proto.on = alias('addListener'); + + /** + * Semi-alias of addListener. It will add a listener that will be + * automatically removed after it's first execution. + * + * @param {String|RegExp} evt Name of the event to attach the listener to. + * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addOnceListener = function addOnceListener(evt, listener) { + return this.addListener(evt, { + listener: listener, + once: true + }); + }; + + /** + * Alias of addOnceListener. + */ + proto.once = alias('addOnceListener'); + + /** + * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. + * You need to tell it what event names should be matched by a regex. + * + * @param {String} evt Name of the event to create. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvent = function defineEvent(evt) { + this.getListeners(evt); + return this; + }; + + /** + * Uses defineEvent to define multiple events. + * + * @param {String[]} evts An array of event names to define. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.defineEvents = function defineEvents(evts) { + for (var i = 0; i < evts.length; i += 1) { + this.defineEvent(evts[i]); + } + return this; + }; + + /** + * Removes a listener function from the specified event. + * When passed a regular expression as the event name, it will remove the listener from all events that match it. + * + * @param {String|RegExp} evt Name of the event to remove the listener from. + * @param {Function} listener Method to remove from the event. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListener = function removeListener(evt, listener) { + var listeners = this.getListenersAsObject(evt); + var index; + var key; + + for (key in listeners) { + if (listeners.hasOwnProperty(key)) { + index = indexOfListener(listeners[key], listener); + + if (index !== -1) { + listeners[key].splice(index, 1); + } + } + } + + return this; + }; + + /** + * Alias of removeListener + */ + proto.off = alias('removeListener'); + + /** + * Adds listeners in bulk using the manipulateListeners method. + * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. + * You can also pass it a regular expression to add the array of listeners to all events that match it. + * Yeah, this function does quite a bit. That's probably a bad thing. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.addListeners = function addListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(false, evt, listeners); + }; + + /** + * Removes listeners in bulk using the manipulateListeners method. + * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be removed. + * You can also pass it a regular expression to remove the listeners from all events that match it. + * + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeListeners = function removeListeners(evt, listeners) { + // Pass through to manipulateListeners + return this.manipulateListeners(true, evt, listeners); + }; + + /** + * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. + * The first argument will determine if the listeners are removed (true) or added (false). + * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. + * You can also pass it an event name and an array of listeners to be added/removed. + * You can also pass it a regular expression to manipulate the listeners of all events that match it. + * + * @param {Boolean} remove True if you want to remove listeners, false if you want to add. + * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. + * @param {Function[]} [listeners] An optional array of listener functions to add/remove. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { + var i; + var value; + var single = remove ? this.removeListener : this.addListener; + var multiple = remove ? this.removeListeners : this.addListeners; + + // If evt is an object then pass each of it's properties to this method + if (typeof evt === 'object' && !(evt instanceof RegExp)) { + for (i in evt) { + if (evt.hasOwnProperty(i) && (value = evt[i])) { + // Pass the single listener straight through to the singular method + if (typeof value === 'function') { + single.call(this, i, value); + } + else { + // Otherwise pass back to the multiple function + multiple.call(this, i, value); + } + } + } + } + else { + // So evt must be a string + // And listeners must be an array of listeners + // Loop over it and pass each one to the multiple method + i = listeners.length; + while (i--) { + single.call(this, evt, listeners[i]); + } + } + + return this; + }; + + /** + * Removes all listeners from a specified event. + * If you do not specify an event then all listeners will be removed. + * That means every event will be emptied. + * You can also pass a regex to remove all events that match it. + * + * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.removeEvent = function removeEvent(evt) { + var type = typeof evt; + var events = this._getEvents(); + var key; + + // Remove different things depending on the state of evt + if (type === 'string') { + // Remove all listeners for the specified event + delete events[evt]; + } + else if (evt instanceof RegExp) { + // Remove all events matching the regex. + for (key in events) { + if (events.hasOwnProperty(key) && evt.test(key)) { + delete events[key]; + } + } + } + else { + // Remove all listeners in all events + delete this._events; + } + + return this; + }; + + /** + * Alias of removeEvent. + * + * Added to mirror the node API. + */ + proto.removeAllListeners = alias('removeEvent'); + + /** + * Emits an event of your choice. + * When emitted, every listener attached to that event will be executed. + * If you pass the optional argument array then those arguments will be passed to every listener upon execution. + * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. + * So they will not arrive within the array on the other side, they will be separate. + * You can also pass a regular expression to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {Array} [args] Optional array of arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emitEvent = function emitEvent(evt, args) { + var listeners = this.getListenersAsObject(evt); + var listener; + var i; + var key; + var response; + + for (key in listeners) { + if (listeners.hasOwnProperty(key)) { + i = listeners[key].length; + + while (i--) { + // If the listener returns true then it shall be removed from the event + // The function is executed either with a basic call or an apply if there is an args array + listener = listeners[key][i]; + + if (listener.once === true) { + this.removeListener(evt, listener.listener); + } + + response = listener.listener.apply(this, args || []); + + if (response === this._getOnceReturnValue()) { + this.removeListener(evt, listener.listener); + } + } + } + } + + return this; + }; + + /** + * Alias of emitEvent + */ + proto.trigger = alias('emitEvent'); + + /** + * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. + * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. + * + * @param {String|RegExp} evt Name of the event to emit and execute listeners for. + * @param {...*} Optional additional arguments to be passed to each listener. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.emit = function emit(evt) { + var args = Array.prototype.slice.call(arguments, 1); + return this.emitEvent(evt, args); + }; + + /** + * Sets the current value to check against when executing listeners. If a + * listeners return value matches the one set here then it will be removed + * after execution. This value defaults to true. + * + * @param {*} value The new value to check for when executing listeners. + * @return {Object} Current instance of EventEmitter for chaining. + */ + proto.setOnceReturnValue = function setOnceReturnValue(value) { + this._onceReturnValue = value; + return this; + }; + + /** + * Fetches the current value to check against when executing listeners. If + * the listeners return value matches this one then it should be removed + * automatically. It will return true by default. + * + * @return {*|Boolean} The current value to check for or the default, true. + * @api private + */ + proto._getOnceReturnValue = function _getOnceReturnValue() { + if (this.hasOwnProperty('_onceReturnValue')) { + return this._onceReturnValue; + } + else { + return true; + } + }; + + /** + * Fetches the events object and creates one if required. + * + * @return {Object} The events storage object. + * @api private + */ + proto._getEvents = function _getEvents() { + return this._events || (this._events = {}); + }; + + /** + * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. + * + * @return {Function} Non conflicting EventEmitter class. + */ + EventEmitter.noConflict = function noConflict() { + exports.EventEmitter = originalGlobalValue; + return EventEmitter; + }; + + return EventEmitter; +}()); +/* jshint ignore:end */ + + + + var validateTypeFunction = function( value, name ) { + validateType( value, name, typeof value === "undefined" || typeof value === "function", "Function" ); + }; + + + + + var superGet, superInit, + globalEe = new EventEmitter(); + + function validateTypeEvent( value, name ) { + validateType( value, name, typeof value === "string" || value instanceof RegExp, "String or RegExp" ); + } + + function validateThenCall( method, self ) { + return function( event, listener ) { + validatePresence( event, "event" ); + validateTypeEvent( event, "event" ); + + validatePresence( listener, "listener" ); + validateTypeFunction( listener, "listener" ); + + return self[ method ].apply( self, arguments ); + }; + } + + function off( self ) { + return validateThenCall( "off", self ); + } + + function on( self ) { + return validateThenCall( "on", self ); + } + + function once( self ) { + return validateThenCall( "once", self ); + } + + Cldr.off = off( globalEe ); + Cldr.on = on( globalEe ); + Cldr.once = once( globalEe ); + + /** + * Overload Cldr.prototype.init(). + */ + superInit = Cldr.prototype.init; + Cldr.prototype.init = function() { + var ee; + this.ee = ee = new EventEmitter(); + this.off = off( ee ); + this.on = on( ee ); + this.once = once( ee ); + superInit.apply( this, arguments ); + }; + + /** + * getOverload is encapsulated, because of cldr/unresolved. If it's loaded + * after cldr/event (and note it overwrites .get), it can trigger this + * overload again. + */ + function getOverload() { + + /** + * Overload Cldr.prototype.get(). + */ + superGet = Cldr.prototype.get; + Cldr.prototype.get = function( path ) { + var value = superGet.apply( this, arguments ); + path = pathNormalize( path, this.attributes ).join( "/" ); + globalEe.trigger( "get", [ path, value ] ); + this.ee.trigger( "get", [ path, value ] ); + return value; + }; + } + + Cldr._eventInit = getOverload; + getOverload(); + + return Cldr; + + + +})); diff --git a/external/cldrjs/cldr/supplemental.js b/external/cldrjs/cldr/supplemental.js new file mode 100644 index 00000000000..989344b6198 --- /dev/null +++ b/external/cldrjs/cldr/supplemental.js @@ -0,0 +1,101 @@ +/** + * CLDR JavaScript Library v0.3.8 + * http://jquery.com/ + * + * Copyright 2013 Rafael Xavier de Souza + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-07-13T05:05Z + */ +/*! + * CLDR JavaScript Library v0.3.8 2014-07-13T05:05Z MIT license © Rafael Xavier + * http://git.io/h4lmVg + */ +(function( factory ) { + + if ( typeof define === "function" && define.amd ) { + // AMD. + define( [ "../cldr" ], factory ); + } else if ( typeof module === "object" && typeof module.exports === "object" ) { + // Node. CommonJS. + module.exports = factory( require( "cldrjs" ) ); + } else { + // Global + factory( Cldr ); + } + +}(function( Cldr ) { + + // Build optimization hack to avoid duplicating functions across modules. + var alwaysArray = Cldr._alwaysArray; + + + + + var supplementalMain = 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 initSuper = Cldr.prototype.init; + + /** + * .init() automatically ran on construction. + * + * Overload .init(). + */ + Cldr.prototype.init = function() { + initSuper.apply( this, arguments ); + this.supplemental = supplementalMain( this ); + }; + + return Cldr; + + + +})); diff --git a/external/date.js b/external/date.js index 4d404efe123..6e532b008fe 100644 --- a/external/date.js +++ b/external/date.js @@ -121,7 +121,7 @@ $.date.prototype = { return 32 - new Date( year, month, 32 ).getDate(); }, monthName: function() { - return Globalize.format( this.dateObject, { pattern: "MMMM" } ); + return Globalize.formatDate( this.dateObject, { pattern: "MMMM" } ); }, day: function() { return this.dateObject.getDate(); @@ -157,7 +157,7 @@ $.date.prototype = { 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" } ), + number: Globalize.formatDate( printDate, { pattern: "w" } ), days: [] }; for ( var dayx = 0; dayx < 7; dayx++ ) { @@ -202,7 +202,7 @@ $.date.prototype = { // TODO compare year, month, day each for better performance equal: function( other ) { function format( date ) { - return Globalize.format( date, { pattern: "yyyyMMdd" } ); + return Globalize.formatDate( date, { pattern: "yyyyMMdd" } ); } return format( this.dateObject ) === format( other ); }, @@ -210,7 +210,7 @@ $.date.prototype = { return this.dateObject; }, format: function( format ) { - return Globalize.format( this.dateObject, format || this.globalFormat ); + return Globalize.formatDate( this.dateObject, format || this.globalFormat ); } }; diff --git a/external/globalize/LICENSE b/external/globalize/LICENSE.txt similarity index 56% rename from external/globalize/LICENSE rename to external/globalize/LICENSE.txt index 9c8b022405c..5dee5ca452c 100644 --- a/external/globalize/LICENSE +++ b/external/globalize/LICENSE.txt @@ -1,5 +1,14 @@ -Copyright Software Freedom Conservancy, Inc. -http://jquery.org/license +Copyright 2010, 2014 jQuery Foundation and other contributors, +https://jquery.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/globalize + +The following license applies to all parts of this software except as +documented below: + +==== Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -19,3 +28,17 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code contained within the doc directory. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. diff --git a/external/globalize/globalize.js b/external/globalize/globalize.js index 1086d339db9..436729a91a7 100644 --- a/external/globalize/globalize.js +++ b/external/globalize/globalize.js @@ -1,1787 +1,313 @@ /*! - * Globalize v1.0.0pre + * Globalize v1.0.0-alpha.6 * * http://github.com/jquery/globalize * - * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2013-12-01T12:08Z + * Date: 2014-09-01T21:32Z */ (function( root, factory ) { + // UMD returnExports if ( typeof define === "function" && define.amd ) { - // AMD. - define( factory ); - } else if ( typeof module === "object" && typeof module.exports === "object" ) { - // Node. CommonJS. - module.exports = factory(); + + // AMD + define([ + "cldr", + "cldr/event" + ], factory ); + } else if ( typeof exports === "object" ) { + + // Node, CommonJS + module.exports = factory( require( "cldrjs" ) ); } else { + // Global - root.Globalize = factory(); + root.Globalize = factory( root.Cldr ); } +}( this, function( Cldr ) { -}( 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 + * A toString method that outputs meaningful values for objects or arrays and + * still performs as fast as a plain string in case variable is string, or as + * fast as `"" + number` in case variable is a number. + * Ref: http://jsperf.com/my-stringify */ - 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; - }; - +var toString = function( variable ) { + return typeof variable === "string" ? variable : ( typeof variable === "number" ? "" + + variable : JSON.stringify( variable ) ); +}; - // @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" ) { +/** + * formatMessage( message, data ) + * + * @message [String] A message with optional {vars} to be replaced. + * + * @data [Array or JSON] Object with replacing-variables content. + * + * Return the formatted message. For example: + * + * - formatMessage( "{0} second", 1 ); // 1 second + * + * - formatMessage( "{0}/{1}", ["m", "s"] ); // m/s + * + * - formatMessage( "{name} <{email}>", { + * name: "Foo", + * email: "bar@baz.qux" + * }); // Foo + */ +var formatMessage = function( message, data ) { - // Merge Objects - destination[ prop ] = merge( destination[ prop ], source[ prop ] ); + // Replace {attribute}'s + message = message.replace( /{[0-9a-zA-Z-_. ]+}/g, function( name ) { + name = name.replace( /^{([^}]*)}$/, "$1" ); + return toString( data[ name ] ); + }); - } else { + return message; +}; - // Set new values - destination[ prop ] = source[ prop ]; - } - } - }); - return destination; - }; - return merge; -}()); - var itemLookup = (function() { +var createError = function( code, message, attributes ) { + var error; - var lookup; + message = code + ( message ? ": " + formatMessage( message, attributes ) : "" ); + error = new Error( message ); + error.code = code; - lookup = function( Cldr, locale, path, attributes, childLocale ) { - var normalizedPath, parent, value; + // extend( error, attributes ); + Object.keys( attributes ).forEach(function( attribute ) { + error[ attribute ] = attributes[ attribute ]; + }); - // 1: Finish recursion - // 2: Avoid infinite loop - if ( typeof locale === "undefined" /* 1 */ || locale === childLocale /* 2 */ ) { - return; - } + return error; +}; - // 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 ); - } +var validate = function( code, message, check, attributes ) { + if ( !check ) { + throw createError( code, message, attributes ); + } +}; - // Set resolved (cached) - resourceSet( Cldr._resolved, normalizedPath, value ); - return value; - }; - return lookup; -}()); +var alwaysArray = function( stringOrArray ) { + return Array.isArray( stringOrArray ) ? stringOrArray : stringOrArray ? [ stringOrArray ] : []; +}; - var itemGetResolved = function( Cldr, path, attributes ) { - // Resolve path - var normalizedPath = pathNormalize( path, attributes ); - return resourceGet( Cldr._resolved, normalizedPath ); - }; +var validateCldr = function( path, value, options ) { + var skipBoolean; + options = options || {}; + skipBoolean = alwaysArray( options.skip ).some(function( pathRe ) { + return pathRe.test( path ); + }); + validate( "E_MISSING_CLDR", "Missing required CLDR content `{path}`.", value || skipBoolean, { + path: path + }); +}; - 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 */; +var validateDefaultLocale = function( value ) { + validate( "E_DEFAULT_LOCALE_NOT_DEFINED", "Default locale has not been defined.", + value !== undefined, {} ); +}; - return itemGetResolved( Cldr, path, this.attributes ) || - itemLookup( Cldr, locale, path, this.attributes ); - }; - common( Cldr ); - return Cldr; +var validateParameterPresence = function( value, name ) { + validate( "E_MISSING_PARAMETER", "Missing required parameter `{name}`.", + value !== undefined, { name: name }); +}; -}()); - 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 ); +/** + * range( value, name, minimum, maximum ) + * + * @value [Number]. + * + * @name [String] name of variable. + * + * @minimum [Number]. The lowest valid value, inclusive. + * + * @maximum [Number]. The greatest valid value, inclusive. + */ +var validateParameterRange = function( value, name, minimum, maximum ) { + validate( + "E_PAR_OUT_OF_RANGE", + "Parameter `{name}` has value `{value}` out of range [{minimum}, {maximum}].", + value === undefined || value >= minimum && value <= maximum, + { + maximum: maximum, + minimum: minimum, + name: name, + value: value } - return clone; - }; + ); +}; - var objectValues = function( object ) { - var i, - result = []; - - for ( i in object ) { - result.push( object[ i ] ); +var validateParameterType = function( value, name, check, expected ) { + validate( + "E_INVALID_PAR_TYPE", + "Invalid `{name}` parameter ({value}). {expected} expected.", + check, + { + expected: expected, + name: name, + value: value } + ); +}; - 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 validateParameterTypeLocale = function( value, name ) { + validateParameterType( + value, + name, + value === undefined || typeof value === "string" || value instanceof Cldr, + "String or Cldr instance" + ); +}; - 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; - }; - +/** + * Function inspired by jQuery Core, but reduced to our use case. + */ +var isPlainObject = function( obj ) { + return obj !== null && "" + obj === "[object Object]"; +}; - /** - * 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 ) ); - }; +var validateParameterTypePlainObject = function( value, name ) { + validateParameterType( + value, + name, + value === undefined || isPlainObject( value ), + "Plain Object" + ); +}; - /** - * millisecondsInDay - */ - var datetimeMillisecondsInDay = function( date ) { - // TODO Handle daylight savings discontinuities - return date - datetimeStartOf( date, "day" ); - }; +var alwaysCldr = function( localeOrCldr ) { + return localeOrCldr instanceof Cldr ? localeOrCldr : new Cldr( localeOrCldr ); +}; - var datetimePatternRe = (/([a-z])\1*|'[^']+'|''|./ig); +function validateLikelySubtags( cldr ) { + cldr.once( "get", validateCldr ); + cldr.get( "supplemental/likelySubtags" ); +} - 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; +/** + * [new] Globalize( locale|cldr ) + * + * @locale [String] + * + * @cldr [Cldr instance] + * + * Create a Globalize instance. + */ +function Globalize( locale ) { + if ( !( this instanceof Globalize ) ) { + return new Globalize( locale ); } - /** - * 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 ]; - }; + validateParameterPresence( locale, "locale" ); + validateParameterTypeLocale( locale, "locale" ); + this.cldr = alwaysCldr( locale ); + validateLikelySubtags( this.cldr ); +} +/** + * Globalize.load( json ) + * + * @json [JSON] + * + * Load resolved or unresolved cldr data. + * Somewhat equivalent to previous Globalize.addCultureInfo(...). + */ +Globalize.load = function( json ) { + validateParameterPresence( json, "json" ); + validateParameterTypePlainObject( json, "json" ); - 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; - }; - - - + Cldr.load( json ); +}; - var defaultLocale; +/** + * Globalize.locale( [locale|cldr] ) + * + * @locale [String] + * + * @cldr [Cldr instance] + * + * Set default Cldr instance if locale or cldr argument is passed. + * + * Return the default Cldr instance. + */ +Globalize.locale = function( locale ) { + validateParameterTypeLocale( locale, "locale" ); - function getLocale( locale ) { - return locale ? new Cldr( locale ) : defaultLocale; + if ( arguments.length ) { + this.cldr = alwaysCldr( locale ); + validateLikelySubtags( this.cldr ); } + return this.cldr; +}; - 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 ); - } +/** + * Optimization to avoid duplicating some internal functions across modules. + */ +Globalize._alwaysArray = alwaysArray; +Globalize._createError = createError; +Globalize._formatMessage = formatMessage; +Globalize._isPlainObject = isPlainObject; +Globalize._validate = validate; +Globalize._validateCldr = validateCldr; +Globalize._validateDefaultLocale = validateDefaultLocale; +Globalize._validateParameterPresence = validateParameterPresence; +Globalize._validateParameterRange = validateParameterRange; +Globalize._validateParameterTypePlainObject = validateParameterTypePlainObject; +Globalize._validateParameterType = validateParameterType; + +return Globalize; - 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/globalize/globalize/date.js b/external/globalize/globalize/date.js new file mode 100644 index 00000000000..194328aeb2a --- /dev/null +++ b/external/globalize/globalize/date.js @@ -0,0 +1,1254 @@ +/*! + * Globalize v1.0.0-alpha.6 + * + * http://github.com/jquery/globalize + * + * Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-09-01T21:32Z + */ +(function( root, factory ) { + + // UMD returnExports + if ( typeof define === "function" && define.amd ) { + + // AMD + define([ + "cldr", + "../globalize", + "cldr/event", + "cldr/supplemental" + ], factory ); + } else if ( typeof exports === "object" ) { + + // Node, CommonJS + module.exports = factory( require( "cldrjs" ), require( "globalize" ) ); + } else { + + // Extend global + factory( root.Cldr, root.Globalize ); + } +}(this, function( Cldr, Globalize ) { + +var alwaysArray = Globalize._alwaysArray, + createError = Globalize._createError, + formatMessage = Globalize._formatMessage, + isPlainObject = Globalize._isPlainObject, + validateCldr = Globalize._validateCldr, + validateDefaultLocale = Globalize._validateDefaultLocale, + validateParameterPresence = Globalize._validateParameterPresence, + validateParameterType = Globalize._validateParameterType; + + +var validateParameterTypeDate = function( value, name ) { + validateParameterType( value, name, value === undefined || value instanceof Date, "Date" ); +}; + + + + +var validateParameterTypeDatePattern = function( value, name ) { + validateParameterType( + value, + name, + value === undefined || typeof value === "string" || isPlainObject( value ), + "String or plain Object" + ); +}; + + + + +var validateParameterTypeString = function( value, name ) { + validateParameterType( + value, + name, + value === undefined || typeof value === "string", + "a string" + ); +}; + + + + +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 dateAllPresets = 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( + objectValues( cldr.main( + "dates/calendars/gregorian/dateTimeFormats" + )).map(function( datetimeFormat, key ) { + if ( typeof datetimeFormat !== "string" ) { + return datetimeFormat; + } + return formatMessage( datetimeFormat, [ + cldr.main([ + "dates/calendars/gregorian/timeFormats", + key + ]), + cldr.main([ + "dates/calendars/gregorian/dateFormats", + key + ]) + ]); + }) + ); + + return result.map(function( pattern ) { + return { pattern: pattern }; + }); +}; + + + + +var createErrorInvalidParameterValue = function( name, value ) { + return createError( "E_INVALID_PAR_VALUE", "Invalid `{name}` value ({value}).", { + name: name, + value: value + }); +}; + + + + +/** + * 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 dateExpandPattern = function( pattern, cldr ) { + var result; + + if ( typeof pattern === "string" ) { + pattern = { skeleton: pattern }; + } + + 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 = formatMessage( result, [ + cldr.main([ + "dates/calendars/gregorian/timeFormats", + pattern.datetime + ]), + cldr.main([ + "dates/calendars/gregorian/dateFormats", + pattern.datetime + ]) + ]); + } + break; + + case "pattern" in pattern: + result = pattern.pattern; + break; + + default: + throw createErrorInvalidParameterValue({ + name: "pattern", + value: pattern + }); + } + + return result; +}; + + + + +var dateWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ]; + + + + +/** + * firstDayOfWeek + */ +var dateFirstDayOfWeek = function( cldr ) { + return dateWeekDays.indexOf( 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 dateDayOfWeek = function( date, cldr ) { + return ( date.getDay() - dateFirstDayOfWeek( cldr ) + 7 ) % 7; +}; + + + + +/** + * distanceInDays( from, to ) + * + * Return the distance in days between from and to Dates. + */ +var dateDistanceInDays = function( from, to ) { + var inDays = 864e5; + return ( to.getTime() - from.getTime() ) / inDays; +}; + + + + +/** + * startOf changes the input to the beginning of the given unit. + * + * For example, starting at the start of a day, resets hours, minutes + * seconds and milliseconds to 0. Starting at the month does the same, but + * also sets the date to 1. + * + * Returns the modified date + */ +var dateStartOf = 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 dateDayOfYear = function( date ) { + return Math.floor( dateDistanceInDays( dateStartOf( date, "year" ), date ) ); +}; + + + + +/** + * millisecondsInDay + */ +var dateMillisecondsInDay = function( date ) { + // TODO Handle daylight savings discontinuities + return date - dateStartOf( date, "day" ); +}; + + + + +var datePatternRe = (/([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 dateFormat = function( date, pattern, cldr ) { + var widths = [ "abbreviated", "wide", "narrow" ]; + return pattern.replace( datePatternRe, 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 - + dateDayOfWeek( date, cldr ) - + dateFirstDayOfWeek( 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 = dateDayOfWeek( dateStartOf( date, "year" ), cldr ); + ret = Math.ceil( ( dateDayOfYear( 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 = dateDayOfWeek( dateStartOf( 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 = dateDayOfYear( 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 = dateDayOfWeek( date, cldr ) + 1; + pad = true; + break; + } + + /* falls through */ + case "E": + ret = dateWeekDays[ 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( dateMillisecondsInDay( 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; + }); +}; + + + + +/** + * 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 dateTokenizer = function( value, pattern, cldr ) { + var valid, + tokens = [], + widths = [ "abbreviated", "wide", "narrow" ]; + + valid = pattern.match( datePatternRe ).every(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 : []; +}; + + + + +/** + * Differently from native date.setDate(), this function returns a date whose + * day remains inside the month boundaries. For example: + * + * setDate( FebDate, 31 ): a "Feb 28" date. + * setDate( SepDate, 31 ): a "Sep 30" date. + */ +var dateSetDate = function( date, day ) { + var lastDay = new Date( date.getFullYear(), date.getMonth() + 1, 0 ).getDate(); + + date.setDate( day < 1 ? 1 : day < lastDay ? day : lastDay ); +}; + + + + +/** + * Differently from native date.setMonth(), this function adjusts date if + * needed, so final month is always the one set. + * + * setMonth( Jan31Date, 1 ): a "Feb 28" date. + * setDate( Jan31Date, 8 ): a "Sep 30" date. + */ +var dateSetMonth = function( date, month ) { + var originalDate = date.getDate(); + + date.setDate( 1 ); + date.setMonth( month ); + dateSetDate( date, originalDate ); +}; + + +var dateParse = (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, hour, hour12, valid, + YEAR = 0, + MONTH = 1, + DAY = 2, + HOUR = 3, + MINUTE = 4, + SECOND = 5, + MILLISECONDS = 6, + date = new Date(), + tokens = dateTokenizer( value, pattern, cldr ), + truncateAt = [], + units = [ "year", "month", "day", "hour", "minute", "second", "milliseconds" ]; + + if ( !tokens.length ) { + return null; + } + + valid = tokens.every(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; + } + dateSetMonth( date, 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; + } + dateSetDate( date, 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( dateWeekDays, token.value ); + break; + + // Period (AM or PM) + case "a": + amPm = token.value; + break; + + // Hour + case "h": // 1-12 + value = +token.lexeme; + if ( outOfRange( value, 1, 12 ) ) { + return false; + } + hour = hour12 = true; + date.setHours( value === 12 ? 0 : value ); + truncateAt.push( HOUR ); + break; + + case "K": // 0-11 + value = +token.lexeme; + if ( outOfRange( value, 0, 11 ) ) { + return false; + } + hour = hour12 = true; + date.setHours( value ); + truncateAt.push( HOUR ); + break; + + case "k": // 1-24 + value = +token.lexeme; + if ( outOfRange( value, 1, 24 ) ) { + return false; + } + hour = true; + date.setHours( value === 24 ? 0 : value ); + truncateAt.push( HOUR ); + break; + + case "H": // 0-23 + value = +token.lexeme; + if ( outOfRange( value, 0, 23 ) ) { + return false; + } + hour = true; + 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 ) { + return null; + } + + // 12-hour format needs AM or PM, 24-hour format doesn't, ie. return null + // if amPm && !hour12 || !amPm && hour12. + if ( hour && !( !amPm ^ hour12 ) ) { + return null; + } + + if ( era === 0 ) { + // 1 BC = year 0 + date.setFullYear( date.getFullYear() * -1 + 1 ); + } + + if ( hour12 && amPm === "pm" ) { + 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 = dateStartOf( date, units[ truncateAt ] ); + + return date; +}; + +}()); + + +function validateRequiredCldr( path, value ) { + validateCldr( path, value, { + skip: [ + /dates\/calendars\/gregorian\/days\/.*\/short/, + /supplemental\/timeData\/(?!001)/, + /supplemental\/weekData\/(?!001)/ + ] + }); +} + +/** + * .formatDate( value, pattern ) + * + * @value [Date] + * + * @pattern [String or Object] see date/expand_pattern for more info. + * + * Formats a date or number according to the given pattern string and the default/instance locale. + */ +Globalize.formatDate = +Globalize.prototype.formatDate = function( value, pattern ) { + var cldr, ret; + + validateParameterPresence( value, "value" ); + validateParameterPresence( pattern, "pattern" ); + validateParameterTypeDate( value, "value" ); + validateParameterTypeDatePattern( pattern, "pattern" ); + + cldr = this.cldr; + + validateDefaultLocale( cldr ); + + cldr.on( "get", validateRequiredCldr ); + pattern = dateExpandPattern( pattern, cldr ); + ret = dateFormat( value, pattern, cldr ); + cldr.off( "get", validateRequiredCldr ); + + return ret; +}; + +/** + * .parseDate( value, patterns ) + * + * @value [String] + * + * @patterns [Array] Optional. See date/expand_pattern for more info about each pattern. Defaults + * to the list of all presets defined in the locale (see date/all_presets for more info). + * + * Return a Date instance or null. + */ +Globalize.parseDate = +Globalize.prototype.parseDate = function( value, patterns ) { + var cldr, date; + + validateParameterPresence( value, "value" ); + validateParameterTypeString( value, "value" ); + + cldr = this.cldr; + + validateDefaultLocale( cldr ); + + cldr.on( "get", validateRequiredCldr ); + + if ( !patterns ) { + patterns = dateAllPresets( cldr ); + } else { + patterns = alwaysArray( patterns ); + } + + patterns.some(function( pattern ) { + validateParameterTypeDatePattern( pattern, "patterns" ); + pattern = dateExpandPattern( pattern, cldr ); + date = dateParse( value, pattern, cldr ); + return !!date; + }); + + cldr.off( "get", validateRequiredCldr ); + + return date || null; +}; + +return Globalize; + + + + +})); diff --git a/external/globalize/globalize/message.js b/external/globalize/globalize/message.js new file mode 100644 index 00000000000..e2783990070 --- /dev/null +++ b/external/globalize/globalize/message.js @@ -0,0 +1,86 @@ +/*! + * Globalize v1.0.0-alpha.6 + * + * http://github.com/jquery/globalize + * + * Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-09-01T21:32Z + */ +(function( root, factory ) { + + // UMD returnExports + if ( typeof define === "function" && define.amd ) { + + // AMD + define([ + "cldr", + "../globalize" + ], factory ); + } else if ( typeof exports === "object" ) { + + // Node, CommonJS + module.exports = factory( require( "cldrjs" ), require( "globalize" ) ); + } else { + + // Extend global + factory( root.Cldr, root.Globalize ); + } +}(this, function( Cldr, Globalize ) { + +var alwaysArray = Globalize._alwaysArray, + validateDefaultLocale = Globalize._validateDefaultLocale, + validateParameterPresence = Globalize._validateParameterPresence, + validateParameterType = Globalize._validateParameterType, + validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject; + + +/** + * .loadTranslations( json ) + * + * @json [JSON] + * + * Load translation data. + */ +Globalize.loadTranslations = function( json ) { + var customData = { + "globalize-translations": json + }; + + validateParameterPresence( json, "json" ); + validateParameterTypePlainObject( json, "json" ); + + Cldr.load( customData ); +}; + +/** + * .translate( path ) + * + * @path [String or Array] + * + * Translate item given its path. + */ +Globalize.translate = +Globalize.prototype.translate = function( path ) { + var cldr; + + validateParameterPresence( path, "path" ); + validateParameterType( path, "path", typeof path === "string" || Array.isArray( path ), + "a String nor an Array" ); + + path = alwaysArray( path ); + cldr = this.cldr; + + validateDefaultLocale( cldr ); + + return cldr.get( [ "globalize-translations/{languageId}" ].concat( path ) ); +}; + +return Globalize; + + + + +})); diff --git a/external/localization.js b/external/localization.js index a03fcd9b473..5ca10eea55a 100644 --- a/external/localization.js +++ b/external/localization.js @@ -1,30 +1,17 @@ /** - * CLDR locale data + * CLDR data */ -( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "globalize" - ], factory ); - } else { - - // Browser globals - factory( Globalize ); - } -}( function( Globalize ) { Globalize.load({ "main": { "en": { "identity": { "version": { - "_cldrVersion": "24", - "_number": "$Revision: 9287 $" + "_cldrVersion": "25", + "_number": "$Revision: 91 $" }, "generation": { - "_date": "$Date: 2013-08-28 21:32:04 -0500 (Wed, 28 Aug 2013) $" + "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" }, "language": "en" }, @@ -245,47 +232,43 @@ Globalize.load({ "format": { "abbreviated": { "am": "AM", - "am-alt-variant": "a.m.", + "am-alt-variant": "am", "noon": "noon", "pm": "PM", - "pm-alt-variant": "p.m." + "pm-alt-variant": "pm" }, "narrow": { "am": "a", - "am-alt-variant": "a.m.", "noon": "n", - "pm": "p", - "pm-alt-variant": "p.m." + "pm": "p" }, "wide": { "am": "AM", - "am-alt-variant": "a.m.", + "am-alt-variant": "am", "noon": "noon", "pm": "PM", - "pm-alt-variant": "p.m." + "pm-alt-variant": "pm" } }, "stand-alone": { "abbreviated": { "am": "AM", - "am-alt-variant": "a.m.", + "am-alt-variant": "am", "noon": "noon", "pm": "PM", - "pm-alt-variant": "p.m." + "pm-alt-variant": "pm" }, "narrow": { "am": "a", - "am-alt-variant": "a.m.", "noon": "n", - "pm": "p", - "pm-alt-variant": "p.m." + "pm": "p" }, "wide": { "am": "AM", - "am-alt-variant": "a.m.", + "am-alt-variant": "am", "noon": "noon", "pm": "PM", - "pm-alt-variant": "p.m." + "pm-alt-variant": "pm" } } }, @@ -327,36 +310,36 @@ Globalize.load({ "medium": "{1}, {0}", "short": "{1}, {0}", "availableFormats": { - "d": "d", + "EHm": "E HH:mm", + "EHms": "E HH:mm:ss", "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", + "GyMMMd": "MMM d, y G", "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", + "MMMd": "MMM d", + "Md": "M/d", + "d": "d", + "h": "h a", + "hm": "h:mm a", + "hms": "h:mm:ss a", "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", + "yMMMd": "MMM d, y", + "yMd": "M/d/y", "yQQQ": "QQQ y", "yQQQQ": "QQQQ y" }, @@ -375,62 +358,62 @@ Globalize.load({ }, "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" + "M": "E, M/d – E, M/d", + "d": "E, M/d – E, M/d" }, "MMM": { "M": "MMM – MMM" }, + "MMMEd": { + "M": "E, MMM d – E, MMM d", + "d": "E, MMM d – E, MMM d" + }, "MMMd": { - "d": "MMM d – d", - "M": "MMM d – MMM d" + "M": "MMM d – MMM d", + "d": "MMM d – d" }, - "MMMEd": { - "d": "E, MMM d – E, MMM d", - "M": "E, MMM d – E, MMM d" + "Md": { + "M": "M/d – M/d", + "d": "M/d – M/d" + }, + "d": { + "d": "d – d" + }, + "h": { + "a": "h a – h a", + "h": "h – h a" + }, + "hm": { + "a": "h:mm a – h:mm a", + "h": "h:mm – h:mm a", + "m": "h:mm – h:mm a" + }, + "hmv": { + "a": "h:mm a – h:mm a v", + "h": "h:mm – h:mm a v", + "m": "h:mm – h:mm a v" + }, + "hv": { + "a": "h a – h a v", + "h": "h – h a v" }, "y": { "y": "y – y" @@ -439,33 +422,33 @@ Globalize.load({ "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", + "d": "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", + "d": "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" + }, + "yMMMd": { + "M": "MMM d – MMM d, y", + "d": "MMM d – d, y", + "y": "MMM d, y – MMM d, y" + }, + "yMd": { + "M": "M/d/y – M/d/y", + "d": "M/d/y – M/d/y", + "y": "M/d/y – M/d/y" } } } @@ -481,11 +464,11 @@ Globalize.load({ "de": { "identity": { "version": { - "_cldrVersion": "24", - "_number": "$Revision: 9287 $" + "_cldrVersion": "25", + "_number": "$Revision: 91 $" }, "generation": { - "_date": "$Date: 2013-08-28 21:32:04 -0500 (Wed, 28 Aug 2013) $" + "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" }, "language": "de" }, @@ -715,14 +698,9 @@ Globalize.load({ "pm": "nachm." }, "narrow": { - "afternoon": "nachmittags", - "am": "vorm.", - "earlyMorning": "morgens", - "evening": "abends", - "morning": "vormittags", - "night": "nachts", - "noon": "Mittag", - "pm": "nachm." + "am": "a", + "noon": "n", + "pm": "p" }, "wide": { "afternoon": "nachmittags", @@ -747,14 +725,9 @@ Globalize.load({ "pm": "nachm." }, "narrow": { - "afternoon": "nachmittags", - "am": "vorm.", - "earlyMorning": "morgens", - "evening": "abends", - "morning": "vormittags", - "night": "nachts", - "noon": "Mittag", - "pm": "nachm." + "am": "a", + "noon": "n", + "pm": "p" }, "wide": { "afternoon": "Nachmittag", @@ -806,43 +779,42 @@ Globalize.load({ "medium": "{1} {0}", "short": "{1} {0}", "availableFormats": { - "d": "d", + "EHm": "E, HH:mm", + "EHms": "E, HH:mm:ss", "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", + "GyMMMd": "d. MMM y G", "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", + "MMMd": "d. MMM", + "MMd": "d.MM.", + "MMdd": "dd.MM.", + "Md": "d.M.", + "d": "d", + "h": "h a", + "hm": "h:mm a", + "hms": "h:mm:ss a", "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", + "yMMMd": "d. MMM y", + "yMMdd": "dd.MM.y", + "yMd": "d.M.y", "yQQQ": "QQQ y", "yQQQQ": "QQQQ y" }, @@ -861,66 +833,66 @@ Globalize.load({ }, "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." + "M": "E, dd.MM. - E, dd.MM.", + "d": "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" + "M": "E, d. MMM - E, d. MMM", + "d": "E, d. - E, d. MMM" }, "MMMM": { "M": "LLLL-LLLL" }, + "MMMd": { + "M": "d. MMM - d. MMM", + "d": "d.-d. MMM" + }, + "Md": { + "M": "dd.MM. - dd.MM.", + "d": "dd.MM. - dd.MM." + }, + "d": { + "d": "d.-d." + }, + "h": { + "a": "h a - h a", + "h": "h-h a" + }, + "hm": { + "a": "h:mm a - h:mm a", + "h": "h:mm-h:mm a", + "m": "h:mm-h:mm a" + }, + "hmv": { + "a": "h:mm a - h:mm a v", + "h": "h:mm-h:mm a v", + "m": "h:mm-h:mm a v" + }, + "hv": { + "a": "h a - h a v", + "h": "h-h a v" + }, "y": { "y": "y-y" }, @@ -928,33 +900,33 @@ Globalize.load({ "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", + "d": "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", + "d": "E, d. - E, d. MMM y", "y": "E, d. MMM y - E, d. MMM y" }, "yMMMM": { "M": "MMMM-MMMM y", "y": "MMMM y - MMMM y" + }, + "yMMMd": { + "M": "d. MMM - d. MMM y", + "d": "d.-d. MMM y", + "y": "d. MMM y - d. MMM y" + }, + "yMd": { + "M": "dd.MM.y - dd.MM.y", + "d": "dd.MM.y - dd.MM.y", + "y": "dd.MM.y - dd.MM.y" } } } @@ -965,1134 +937,985 @@ Globalize.load({ } }); -/** - * 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" - } + "supplemental": { + "version": { + "_cldrVersion": "25", + "_number": "$Revision: 91 $" + }, + "generation": { + "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + }, + "likelySubtags": { + "aa": "aa-Latn-ET", + "ab": "ab-Cyrl-GE", + "ace": "ace-Latn-ID", + "ach": "ach-Latn-UG", + "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", + "aoz": "aoz-Latn-ID", + "ar": "ar-Arab-EG", + "as": "as-Beng-IN", + "asa": "asa-Latn-TZ", + "ast": "ast-Latn-ES", + "atj": "atj-Latn-CA", + "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", + "bap": "bap-Deva-NP", + "bas": "bas-Latn-CM", + "bax": "bax-Bamu-CM", + "bbc": "bbc-Latn-ID", + "bbj": "bbj-Latn-CM", + "be": "be-Cyrl-BY", + "bem": "bem-Latn-ZM", + "bez": "bez-Latn-TZ", + "bfd": "bfd-Latn-CM", + "bfq": "bfq-Taml-IN", + "bft": "bft-Arab-PK", + "bfy": "bfy-Deva-IN", + "bg": "bg-Cyrl-BG", + "bgx": "bgx-Grek-TR", + "bhb": "bhb-Deva-IN", + "bho": "bho-Deva-IN", + "bi": "bi-Latn-VU", + "bik": "bik-Latn-PH", + "bin": "bin-Latn-NG", + "bjj": "bjj-Deva-IN", + "bkm": "bkm-Latn-CM", + "bku": "bku-Latn-PH", + "bm": "bm-Latn-ML", + "bmq": "bmq-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", + "bto": "bto-Latn-PH", + "btv": "btv-Deva-PK", + "bua": "bua-Cyrl-RU", + "buc": "buc-Latn-YT", + "bug": "bug-Latn-ID", + "bum": "bum-Latn-CM", + "bvb": "bvb-Latn-GQ", + "bya": "bya-Latn-ID", + "byn": "byn-Ethi-ER", + "byv": "byv-Latn-CM", + "bze": "bze-Latn-ML", + "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", + "crj": "crj-Cans-CA", + "crk": "crk-Cans-CA", + "crl": "crl-Cans-CA", + "crm": "crm-Cans-CA", + "cs": "cs-Latn-CZ", + "csb": "csb-Latn-PL", + "csw": "csw-Cans-CA", + "cu": "cu-Cyrl-RU", + "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", + "dnj": "dnj-Latn-CI", + "doi": "doi-Arab-IN", + "dsb": "dsb-Latn-DE", + "dtm": "dtm-Latn-ML", + "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", + "fit": "fit-Latn-SE", + "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", + "ggn": "ggn-Deva-NP", + "gil": "gil-Latn-KI", + "gjk": "gjk-Arab-PK", + "gju": "gju-Arab-PK", + "gl": "gl-Latn-ES", + "gn": "gn-Latn-PY", + "gon": "gon-Telu-IN", + "gor": "gor-Latn-ID", + "gos": "gos-Latn-NL", + "grt": "grt-Beng-IN", + "gsw": "gsw-Latn-CH", + "gu": "gu-Gujr-IN", + "gub": "gub-Latn-BR", + "guz": "guz-Latn-KE", + "gv": "gv-Latn-IM", + "gvr": "gvr-Deva-NP", + "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", + "hnd": "hnd-Arab-PK", + "hne": "hne-Deva-IN", + "hnn": "hnn-Latn-PH", + "ho": "ho-Latn-PG", + "hoc": "hoc-Deva-IN", + "hoj": "hoj-Deva-IN", + "hr": "hr-Latn-HR", + "hsb": "hsb-Latn-DE", + "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", + "jml": "jml-Deva-NP", + "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", + "kao": "kao-Latn-ML", + "kbd": "kbd-Cyrl-RU", + "kcg": "kcg-Latn-NG", + "kck": "kck-Latn-ZW", + "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", + "kge": "kge-Latn-ID", + "kgp": "kgp-Latn-BR", + "kha": "kha-Latn-IN", + "khb": "khb-Talu-CN", + "khq": "khq-Latn-ML", + "kht": "kht-Mymr-IN", + "khw": "khw-Arab-PK", + "ki": "ki-Latn-KE", + "kj": "kj-Latn-NA", + "kjg": "kjg-Laoo-LA", + "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", + "kvr": "kvr-Latn-ID", + "kvx": "kvx-Arab-PK", + "kw": "kw-Latn-GB", + "kxp": "kxp-Arab-PK", + "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", + "lbw": "lbw-Latn-ID", + "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", + "lmo": "lmo-Latn-CH", + "ln": "ln-Latn-CD", + "lo": "lo-Laoo-LA", + "lol": "lol-Latn-CD", + "loz": "loz-Latn-ZM", + "lt": "lt-Latn-LT", + "lu": "lu-Latn-CD", + "lua": "lua-Latn-CD", + "luo": "luo-Latn-KE", + "luy": "luy-Latn-KE", + "luz": "luz-Arab-IR", + "lv": "lv-Latn-LV", + "lwl": "lwl-Thai-TH", + "mad": "mad-Latn-ID", + "maf": "maf-Latn-CM", + "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", + "maz": "maz-Latn-MX", + "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", + "mgp": "mgp-Deva-NP", + "mgy": "mgy-Latn-TZ", + "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", + "moe": "moe-Latn-CA", + "mos": "mos-Latn-BF", + "mr": "mr-Deva-IN", + "mrd": "mrd-Deva-NP", + "mrj": "mrj-Cyrl-RU", + "ms": "ms-Latn-MY", + "ms-CC": "ms-Arab-CC", + "ms-ID": "ms-Arab-ID", + "mt": "mt-Latn-MT", + "mua": "mua-Latn-CM", + "mvy": "mvy-Arab-PK", + "mwk": "mwk-Latn-ML", + "mwr": "mwr-Deva-IN", + "mxc": "mxc-Latn-ZW", + "my": "my-Mymr-MM", + "myv": "myv-Cyrl-RU", + "na": "na-Latn-NR", + "nap": "nap-Latn-IT", + "naq": "naq-Latn-NA", + "nb": "nb-Latn-NO", + "nch": "nch-Latn-MX", + "nd": "nd-Latn-ZW", + "nds": "nds-Latn-DE", + "ne": "ne-Deva-NP", + "new": "new-Deva-NP", + "ng": "ng-Latn-NA", + "nhe": "nhe-Latn-MX", + "nhw": "nhw-Latn-MX", + "nij": "nij-Latn-ID", + "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", + "nsk": "nsk-Cans-CA", + "nso": "nso-Latn-ZA", + "nus": "nus-Latn-SD", + "nv": "nv-Latn-US", + "nxq": "nxq-Latn-CN", + "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", + "pcm": "pcm-Latn-NG", + "pko": "pko-Latn-KE", + "pl": "pl-Latn-PL", + "pon": "pon-Latn-FM", + "prd": "prd-Arab-IR", + "prg": "prg-Latn-001", + "ps": "ps-Arab-AF", + "pt": "pt-Latn-BR", + "puu": "puu-Latn-GA", + "qu": "qu-Latn-PE", + "raj": "raj-Latn-IN", + "rcf": "rcf-Latn-RE", + "rej": "rej-Latn-ID", + "ria": "ria-Latn-IN", + "rjs": "rjs-Deva-NP", + "rkt": "rkt-Beng-BD", + "rm": "rm-Latn-CH", + "rmf": "rmf-Latn-FI", + "rmo": "rmo-Latn-CH", + "rmt": "rmt-Arab-IR", + "rmu": "rmu-Latn-SE", + "rn": "rn-Latn-BI", + "rng": "rng-Latn-MZ", + "ro": "ro-Latn-RO", + "rob": "rob-Latn-ID", + "rof": "rof-Latn-TZ", + "ru": "ru-Cyrl-RU", + "rue": "rue-Cyrl-UA", + "rw": "rw-Latn-RW", + "rwk": "rwk-Latn-TZ", + "ryu": "ryu-Kana-JP", + "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", + "scs": "scs-Latn-CA", + "sd": "sd-Arab-PK", + "sd-Deva": "sd-Deva-IN", + "sdh": "sdh-Arab-IR", + "se": "se-Latn-NO", + "sef": "sef-Latn-CI", + "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", + "srx": "srx-Deva-IN", + "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", + "sxn": "sxn-Latn-ID", + "syl": "syl-Beng-BD", + "syr": "syr-Syrc-IQ", + "ta": "ta-Taml-IN", + "taj": "taj-Deva-NP", + "tbw": "tbw-Latn-PH", + "tcy": "tcy-Knda-IN", + "tdd": "tdd-Tale-CN", + "tdg": "tdg-Deva-NP", + "tdh": "tdh-Deva-NP", + "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", + "thl": "thl-Deva-NP", + "thq": "thq-Deva-NP", + "thr": "thr-Deva-NP", + "ti": "ti-Ethi-ET", + "tig": "tig-Ethi-ER", + "tiv": "tiv-Latn-NG", + "tk": "tk-Latn-TM", + "tkl": "tkl-Latn-TK", + "tkt": "tkt-Deva-NP", + "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", + "tsf": "tsf-Deva-NP", + "tsg": "tsg-Latn-PH", + "tsj": "tsj-Tibt-BT", + "tt": "tt-Cyrl-RU", + "ttj": "ttj-Latn-UG", + "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-002": "en-Latn-NG", + "und-003": "en-Latn-US", + "und-005": "pt-Latn-BR", + "und-009": "en-Latn-AU", + "und-011": "en-Latn-NG", + "und-013": "es-Latn-MX", + "und-014": "en-Latn-KE", + "und-015": "ar-Arab-EG", + "und-017": "sw-Latn-CD", + "und-018": "en-Latn-ZA", + "und-019": "en-Latn-US", + "und-021": "en-Latn-US", + "und-029": "es-Latn-CU", + "und-030": "zh-Hans-CN", + "und-034": "hi-Deva-IN", + "und-035": "id-Latn-ID", + "und-039": "it-Latn-IT", + "und-053": "en-Latn-AU", + "und-054": "en-Latn-PG", + "und-057": "en-Latn-KI", + "und-061": "sm-Latn-WS", + "und-142": "zh-Hans-CN", + "und-143": "uz-Latn-UZ", + "und-145": "ar-Arab-SA", + "und-150": "ru-Cyrl-RU", + "und-151": "ru-Cyrl-RU", + "und-154": "en-Latn-GB", + "und-155": "de-Latn-DE", + "und-419": "es-Latn-419", + "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-AS": "sm-Latn-AS", + "und-AT": "de-Latn-AT", + "und-AW": "nl-Latn-AW", + "und-AX": "sv-Latn-AX", + "und-AZ": "az-Latn-AZ", + "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-Avst": "ae-Avst-IR", + "und-BA": "bs-Latn-BA", + "und-BD": "bn-Beng-BD", + "und-BE": "nl-Latn-BE", + "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-BQ": "pap-Latn-BQ", + "und-BR": "pt-Latn-BR", + "und-BT": "dz-Tibt-BT", + "und-BV": "und-Latn-BV", + "und-BY": "be-Cyrl-BY", + "und-Bali": "ban-Bali-ID", + "und-Bamu": "bax-Bamu-CM", + "und-Batk": "bbc-Batk-ID", + "und-Beng": "bn-Beng-BD", + "und-Bopo": "zh-Bopo-TW", + "und-Brah": "pra-Brah-IN", + "und-Brai": "und-Brai-FR", + "und-Bugi": "bug-Bugi-ID", + "und-Buhd": "bku-Buhd-PH", + "und-CD": "sw-Latn-CD", + "und-CF": "fr-Latn-CF", + "und-CG": "fr-Latn-CG", + "und-CH": "de-Latn-CH", + "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-CP": "und-Latn-CP", + "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-CZ": "cs-Latn-CZ", + "und-Cakm": "ccp-Cakm-BD", + "und-Cans": "cr-Cans-CA", + "und-Cari": "xcr-Cari-TR", + "und-Cham": "cjm-Cham-VN", + "und-Cher": "chr-Cher-US", + "und-Copt": "cop-Copt-EG", + "und-Cprt": "grc-Cprt-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-DE": "de-Latn-DE", + "und-DJ": "aa-Latn-DJ", + "und-DK": "da-Latn-DK", + "und-DO": "es-Latn-DO", + "und-DZ": "ar-Arab-DZ", + "und-Deva": "hi-Deva-IN", + "und-Deva-BT": "ne-Deva-BT", + "und-Deva-MU": "bho-Deva-MU", + "und-Deva-PK": "btv-Deva-PK", + "und-EA": "es-Latn-EA", + "und-EC": "es-Latn-EC", + "und-EE": "et-Latn-EE", + "und-EG": "ar-Arab-EG", + "und-EH": "ar-Arab-EH", + "und-ER": "ti-Ethi-ER", + "und-ES": "es-Latn-ES", + "und-ET": "am-Ethi-ET", + "und-EU": "en-Latn-GB", + "und-Egyp": "egy-Egyp-EG", + "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-GF": "fr-Latn-GF", + "und-GH": "ak-Latn-GH", + "und-GL": "kl-Latn-GL", + "und-GN": "fr-Latn-GN", + "und-GP": "fr-Latn-GP", + "und-GQ": "es-Latn-GQ", + "und-GR": "el-Grek-GR", + "und-GS": "und-Latn-GS", + "und-GT": "es-Latn-GT", + "und-GW": "pt-Latn-GW", + "und-Geor": "ka-Geor-GE", + "und-Glag": "cu-Glag-BG", + "und-Goth": "got-Goth-UA", + "und-Grek": "el-Grek-GR", + "und-Grek-TR": "bgx-Grek-TR", + "und-Gujr": "gu-Gujr-IN", + "und-Guru": "pa-Guru-IN", + "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-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-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-JO": "ar-Arab-JO", + "und-JP": "ja-Jpan-JP", + "und-Java": "jv-Java-ID", + "und-Jpan": "ja-Jpan-JP", + "und-KG": "ky-Cyrl-KG", + "und-KH": "km-Khmr-KH", + "und-KM": "ar-Arab-KM", + "und-KP": "ko-Kore-KP", + "und-KR": "ko-Kore-KR", + "und-KW": "ar-Arab-KW", + "und-KZ": "ru-Cyrl-KZ", + "und-Kali": "eky-Kali-MM", + "und-Kana": "ja-Kana-JP", + "und-Khar": "pra-Khar-PK", + "und-Khmr": "km-Khmr-KH", + "und-Knda": "kn-Knda-IN", + "und-Kore": "ko-Kore-KR", + "und-Kthi": "bh-Kthi-IN", + "und-LA": "lo-Laoo-LA", + "und-LB": "ar-Arab-LB", + "und-LI": "de-Latn-LI", + "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-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-Lepc": "lep-Lepc-IN", + "und-Limb": "lif-Limb-IN", + "und-Linb": "grc-Linb-GR", + "und-Lisu": "lis-Lisu-CN", + "und-Lyci": "xlc-Lyci-TR", + "und-Lydi": "xld-Lydi-TR", + "und-MA": "ar-Arab-MA", + "und-MC": "fr-Latn-MC", + "und-MD": "ro-Latn-MD", + "und-ME": "sr-Latn-ME", + "und-MF": "fr-Latn-MF", + "und-MG": "mg-Latn-MG", + "und-MK": "mk-Cyrl-MK", + "und-ML": "bm-Latn-ML", + "und-MM": "my-Mymr-MM", + "und-MN": "mn-Cyrl-MN", + "und-MO": "zh-Hant-MO", + "und-MQ": "fr-Latn-MQ", + "und-MR": "ar-Arab-MR", + "und-MT": "mt-Latn-MT", + "und-MU": "mfe-Latn-MU", + "und-MV": "dv-Thaa-MV", + "und-MX": "es-Latn-MX", + "und-MY": "ms-Latn-MY", + "und-MZ": "pt-Latn-MZ", + "und-Mand": "myz-Mand-IR", + "und-Merc": "xmr-Merc-SD", + "und-Mero": "xmr-Mero-SD", + "und-Mlym": "ml-Mlym-IN", + "und-Mong": "mn-Mong-CN", + "und-Mtei": "mni-Mtei-IN", + "und-Mymr": "my-Mymr-MM", + "und-Mymr-IN": "kht-Mymr-IN", + "und-Mymr-TH": "mnw-Mymr-TH", + "und-NA": "af-Latn-NA", + "und-NC": "fr-Latn-NC", + "und-NE": "ha-Latn-NE", + "und-NI": "es-Latn-NI", + "und-NL": "nl-Latn-NL", + "und-NO": "nb-Latn-NO", + "und-NP": "ne-Deva-NP", + "und-Nkoo": "man-Nkoo-GN", + "und-OM": "ar-Arab-OM", + "und-Ogam": "sga-Ogam-IE", + "und-Olck": "sat-Olck-IN", + "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-PK": "ur-Arab-PK", + "und-PL": "pl-Latn-PL", + "und-PM": "fr-Latn-PM", + "und-PR": "es-Latn-PR", + "und-PS": "ar-Arab-PS", + "und-PT": "pt-Latn-PT", + "und-PW": "pau-Latn-PW", + "und-PY": "gn-Latn-PY", + "und-Phag": "lzh-Phag-CN", + "und-Phli": "pal-Phli-IR", + "und-Phnx": "phn-Phnx-LB", + "und-Plrd": "hmd-Plrd-CN", + "und-Prti": "xpr-Prti-IR", + "und-QA": "ar-Arab-QA", + "und-QO": "en-Latn-IO", + "und-RE": "fr-Latn-RE", + "und-RO": "ro-Latn-RO", + "und-RS": "sr-Cyrl-RS", + "und-RU": "ru-Cyrl-RU", + "und-RW": "rw-Latn-RW", + "und-Rjng": "rej-Rjng-ID", + "und-Runr": "non-Runr-SE", + "und-SA": "ar-Arab-SA", + "und-SC": "fr-Latn-SC", + "und-SD": "ar-Arab-SD", + "und-SE": "sv-Latn-SE", + "und-SI": "sl-Latn-SI", + "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-SR": "nl-Latn-SR", + "und-ST": "pt-Latn-ST", + "und-SV": "es-Latn-SV", + "und-SY": "ar-Arab-SY", + "und-Samr": "smp-Samr-IL", + "und-Sarb": "xsa-Sarb-YE", + "und-Saur": "saz-Saur-IN", + "und-Shaw": "en-Shaw-GB", + "und-Shrd": "sa-Shrd-IN", + "und-Sinh": "si-Sinh-LK", + "und-Sora": "srb-Sora-IN", + "und-Sund": "su-Sund-ID", + "und-Sylo": "syl-Sylo-BD", + "und-Syrc": "syr-Syrc-IQ", + "und-TD": "fr-Latn-TD", + "und-TF": "fr-Latn-TF", + "und-TG": "fr-Latn-TG", + "und-TH": "th-Thai-TH", + "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-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-Telu": "te-Telu-IN", + "und-Tfng": "zgh-Tfng-MA", + "und-Tglg": "fil-Tglg-PH", + "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-UA": "uk-Cyrl-UA", + "und-UG": "sw-Latn-UG", + "und-UY": "es-Latn-UY", + "und-UZ": "uz-Latn-UZ", + "und-Ugar": "uga-Ugar-SY", + "und-VA": "la-Latn-VA", + "und-VE": "es-Latn-VE", + "und-VN": "vi-Latn-VN", + "und-VU": "bi-Latn-VU", + "und-Vaii": "vai-Vaii-LR", + "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-YT": "fr-Latn-YT", + "und-Yiii": "ii-Yiii-CN", + "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", + "vic": "vic-Latn-SX", + "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", + "xav": "xav-Latn-BR", + "xh": "xh-Latn-ZA", + "xog": "xog-Latn-UG", + "xsr": "xsr-Deva-NP", + "yao": "yao-Latn-MZ", + "yap": "yap-Latn-FM", + "yav": "yav-Latn-CM", + "ybb": "ybb-Latn-CM", + "yi": "yi-Hebr-UA", + "yo": "yo-Latn-NG", + "yua": "yua-Latn-MX", + "za": "za-Latn-CN", + "zea": "zea-Latn-NL", + "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-HK": "zh-Hant-HK", + "zh-Hant": "zh-Hant-TW", + "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", + "zmi": "zmi-Latn-MY", + "zu": "zu-Latn-ZA", + "zza": "zza-Arab-TR" } + } }); -// weekData Globalize.load({ "supplemental": { "version": { - "_cldrVersion": "24", - "_number": "$Revision: 9270 $" + "_cldrVersion": "25", + "_number": "$Revision: 91 $" }, "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) $" + "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" }, "timeData": { "001": { @@ -2343,6 +2166,10 @@ Globalize.load({ "_allowed": "H", "_preferred": "H" }, + "ID": { + "_allowed": "H", + "_preferred": "H" + }, "IL": { "_allowed": "H", "_preferred": "H" @@ -2695,443 +2522,805 @@ Globalize.load({ } }); -/** - * 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" - }, +Globalize.load({ + "supplemental": { + "version": { + "_cldrVersion": "25", + "_number": "$Revision: 91 $" + }, + "generation": { + "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + }, + "weekData": { + "minDays": { + "001": "1", + "GU": "1", + "UM": "1", + "US": "1", + "VI": "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", + "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", + "VA": "4" + }, + "firstDay": { + "001": "mon", + "AD": "mon", + "AI": "mon", + "AL": "mon", + "AM": "mon", + "AN": "mon", + "AT": "mon", + "AX": "mon", + "AZ": "mon", + "BA": "mon", + "BE": "mon", + "BG": "mon", + "BM": "mon", + "BN": "mon", + "BY": "mon", + "CH": "mon", + "CL": "mon", + "CM": "mon", + "CR": "mon", + "CY": "mon", + "CZ": "mon", + "DE": "mon", + "DK": "mon", + "EC": "mon", + "EE": "mon", + "ES": "mon", + "FI": "mon", + "FJ": "mon", + "FO": "mon", + "FR": "mon", + "GB": "mon", + "GE": "mon", + "GF": "mon", + "GP": "mon", + "GR": "mon", + "HR": "mon", + "HU": "mon", + "IS": "mon", + "IT": "mon", + "KG": "mon", + "KZ": "mon", + "LB": "mon", + "LI": "mon", + "LK": "mon", + "LT": "mon", + "LU": "mon", + "LV": "mon", + "MC": "mon", + "MD": "mon", + "ME": "mon", + "MK": "mon", + "MN": "mon", + "MQ": "mon", + "MY": "mon", + "NL": "mon", + "NO": "mon", + "PL": "mon", + "PT": "mon", + "RE": "mon", + "RO": "mon", + "RS": "mon", + "RU": "mon", + "SE": "mon", + "SI": "mon", + "SK": "mon", + "SM": "mon", + "TJ": "mon", + "TM": "mon", + "TR": "mon", + "UA": "mon", + "UY": "mon", + "UZ": "mon", + "VA": "mon", + "VN": "mon", + "XK": "mon", + "AE": "sat", + "AF": "sat", + "BH": "sat", + "DJ": "sat", + "DZ": "sat", + "EG": "sat", + "IQ": "sat", + "IR": "sat", + "JO": "sat", + "KW": "sat", + "LY": "sat", + "MA": "sat", + "OM": "sat", + "QA": "sat", + "SD": "sat", + "SY": "sat", + "AG": "sun", + "AR": "sun", + "AS": "sun", + "AU": "sun", + "BR": "sun", + "BS": "sun", + "BT": "sun", + "BW": "sun", + "BZ": "sun", + "CA": "sun", + "CN": "sun", + "CO": "sun", + "DM": "sun", + "DO": "sun", + "ET": "sun", + "GT": "sun", + "GU": "sun", + "HK": "sun", + "HN": "sun", + "ID": "sun", + "IE": "sun", + "IL": "sun", + "IN": "sun", + "JM": "sun", + "JP": "sun", + "KE": "sun", + "KH": "sun", + "KR": "sun", + "LA": "sun", + "MH": "sun", + "MM": "sun", + "MO": "sun", + "MT": "sun", + "MX": "sun", + "MZ": "sun", + "NI": "sun", + "NP": "sun", + "NZ": "sun", + "PA": "sun", + "PE": "sun", + "PH": "sun", + "PK": "sun", + "PR": "sun", + "PY": "sun", + "SA": "sun", + "SG": "sun", + "SV": "sun", + "TH": "sun", + "TN": "sun", + "TT": "sun", + "TW": "sun", + "UM": "sun", + "US": "sun", + "VE": "sun", + "VI": "sun", + "WS": "sun", + "YE": "sun", + "ZA": "sun", + "ZW": "sun", + "BD": "fri", + "MV": "fri" + }, + "firstDay-alt-variant": { + "GB": "sun" + }, + "weekendStart": { + "001": "sat", + "AE": "fri", + "BH": "fri", + "EG": "fri", + "IL": "fri", + "IQ": "fri", + "JO": "fri", + "KW": "fri", + "LY": "fri", + "MA": "fri", + "QA": "fri", + "SA": "fri", + "SD": "fri", + "SY": "fri", + "TN": "fri", + "YE": "fri", + "AF": "thu", + "DZ": "thu", + "IR": "thu", + "OM": "thu", + "IN": "sun" + }, + "weekendEnd": { + "001": "sun", + "AE": "sat", + "BH": "sat", + "EG": "sat", + "IL": "sat", + "IQ": "sat", + "JO": "sat", + "KW": "sat", + "LY": "sat", + "MA": "sat", + "QA": "sat", + "SA": "sat", + "SD": "sat", + "SY": "sat", + "TN": "sat", + "YE": "sat", + "AF": "fri", + "DZ": "fri", + "IR": "fri", + "OM": "fri" + } + } + } +}); + +/** + * jQuery UI translation data + */ +Globalize.loadTranslations({ + "en": { + "datepicker": { + "closeText": "Done", + "prevText": "Prev", + "nextText": "Next", + "currentText": "Today", + "weekHeader": "Wk", + "dateFormat": "d", + "datePickerRole": "date picker" + } + }, + "af": { + "datepicker": { + "closeText": "Selekteer", + "prevText": "Vorige", + "nextText": "Volgende", + "currentText": "Vandag", + "weekHeader": "Wk", + "dateFormat": "d" + } + }, + "zh-TW": { + "datepicker": { + "closeText": "\u95dc\u9589", + "prevText": "<\u4e0a\u6708", + "nextText": "\u4e0b\u6708>", + "currentText": "\u4eca\u5929", + "weekHeader": "\u5468", + "dateFormat": "d" + } + }, + "ar": { + "datepicker": { + "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": { + "datepicker": { + "closeText": "Ba\u011fla", + "prevText": "<Geri", + "nextText": "\u0130r\u0259li>", + "currentText": "Bug\u00fcn", + "weekHeader": "Hf", + "dateFormat": "d" + } + }, + "bg": { + "datepicker": { + "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": { + "datepicker": { + "closeText": "Zatvori", + "prevText": "<", + "nextText": ">", + "currentText": "Danas", + "weekHeader": "Wk", + "dateFormat": "d" + } + }, + "ca": { + "datepicker": { + "closeText": "Tancar", + "prevText": "<Ant", + "nextText": "Seg>", + "currentText": "Avui", + "weekHeader": "Sm", + "dateFormat": "d" + } + }, + "cs": { + "datepicker": { + "closeText": "Zav\u0159\u00edt", + "prevText": "<D\u0159\u00edve", + "nextText": "Pozd\u011bji>", + "currentText": "Nyn\u00ed", + "weekHeader": "T\u00fdd", + "dateFormat": "d" + } + }, + "da": { + "datepicker": { + "closeText": "Luk", + "prevText": "<Forrige", + "nextText": "N\u00e6ste>", + "currentText": "Idag", + "weekHeader": "Uge", + "dateFormat": "d" + } + }, + "de": { + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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" + "datepicker": { + "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 ) { - Globalize.loadTranslations( name, { - datepicker : value - }); }); - -return Globalize; - -} ) ); diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 3b20272b13c..be4ff78934f 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -4,9 +4,41 @@ Codestin Search App - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/calendar.js b/ui/calendar.js index a358f69a035..31de5837f77 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -515,7 +515,7 @@ return $.widget( "ui.calendar", { if ( arguments.length ) { this.valueAsDate( Globalize.parseDate( value, this.options.dateFormat ) ); } else { - return Globalize.format( this.option( "value" ), this.options.dateFormat ); + return Globalize.formatDate( this.option( "value" ), this.options.dateFormat ); } }, diff --git a/ui/datepicker.js b/ui/datepicker.js index dc8154e32cd..6f4dd3c9b3d 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -285,7 +285,7 @@ var widget = $.widget( "ui.datepicker", { if ( arguments.length ) { if ( this.calendarInstance._isValid( value ) ) { this.calendarInstance.valueAsDate( value ); - this.element.val( Globalize.format( value, this.options.dateFormat ) ); + this.element.val( Globalize.formatDate( value, this.options.dateFormat ) ); } } else { return this._getParsedValue(); From b39bb7250e8d462f7cd031b6b5845ff0e0765998 Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 16:04:04 -0300 Subject: [PATCH 073/179] Datepicker: Use Globalize 1.0.0 - Remove unneeded territory DE from de-DE locale; --- tests/unit/calendar/core.js | 4 ++-- tests/unit/date/core.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/calendar/core.js b/tests/unit/calendar/core.js index 92753748f94..c35eff4ebb4 100644 --- a/tests/unit/calendar/core.js +++ b/tests/unit/calendar/core.js @@ -116,14 +116,14 @@ test( "Localization", function() { ); }; - Globalize.locale( "de-DE" ); + Globalize.locale( "de" ); initCalendar(); testLocalization( "Init: " ); element.calendar( "destroy" ); Globalize.locale( defaultLocale.locale ); initCalendar(); - Globalize.locale( "de-DE" ); + Globalize.locale( "de" ); element.calendar( "refresh" ); testLocalization( "After init: " ); diff --git a/tests/unit/date/core.js b/tests/unit/date/core.js index e6dc16dcf69..d5895a91df3 100644 --- a/tests/unit/date/core.js +++ b/tests/unit/date/core.js @@ -89,7 +89,7 @@ test( "List days of Week", 2, function() { ]; deepEqual( date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)" ); - Globalize.locale( "de-DE" ); + Globalize.locale( "de" ); deepEqual( date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)" ); // Revert Globalize changes back to English @@ -119,7 +119,7 @@ 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.locale( "de-DE" ); + Globalize.locale( "de" ); equal( date.setMonth( 2 ).monthName(), "März", "Month name return March (German)" ); Globalize.locale( "en" ); }); From a16a7889430578433ce8c2c744fe7321d98be48f Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 15:47:48 -0300 Subject: [PATCH 074/179] Datepicker: Use Globalize 1.0.0 - Update demos --- demos/datepicker/animation.html | 7 +- demos/datepicker/date-formats.html | 7 +- demos/datepicker/default.html | 7 +- demos/datepicker/icon-trigger.html | 7 +- demos/datepicker/localization.html | 12 +- external/localization.js | 1403 +++++++++++++++++++++++++++- 6 files changed, 1436 insertions(+), 7 deletions(-) diff --git a/demos/datepicker/animation.html b/demos/datepicker/animation.html index 04b19662785..d4549289e75 100644 --- a/demos/datepicker/animation.html +++ b/demos/datepicker/animation.html @@ -4,10 +4,15 @@ Codestin Search App + + + - ++ ++ + diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index f00310a47d0..d2b07a796fe 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -4,10 +4,15 @@ Codestin Search App + + + - ++ ++ + diff --git a/demos/datepicker/default.html b/demos/datepicker/default.html index b2439b29ab3..8dc56a505f7 100644 --- a/demos/datepicker/default.html +++ b/demos/datepicker/default.html @@ -4,10 +4,15 @@ Codestin Search App + + + - ++ ++ + diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index c694631e1ab..e95b7857e50 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -4,10 +4,15 @@ Codestin Search App + + + - ++ ++ + diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index 36449a5161d..ed0f374a64c 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -4,10 +4,15 @@ Codestin Search App + + + - + + + @@ -34,8 +39,11 @@

      Date:  

      diff --git a/external/localization.js b/external/localization.js index 5ca10eea55a..22c2350ecc9 100644 --- a/external/localization.js +++ b/external/localization.js @@ -2,6 +2,918 @@ * CLDR data */ +Globalize.load({ + "main": { + "ar": { + "identity": { + "version": { + "_cldrVersion": "25", + "_number": "$Revision: 91 $" + }, + "generation": { + "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + }, + "language": "ar" + }, + "dates": { + "calendars": { + "gregorian": { + "months": { + "format": { + "abbreviated": { + "1": "يناير", + "2": "فبراير", + "3": "مارس", + "4": "أبريل", + "5": "مايو", + "6": "يونيو", + "7": "يوليو", + "8": "أغسطس", + "9": "سبتمبر", + "10": "أكتوبر", + "11": "نوفمبر", + "12": "ديسمبر" + }, + "narrow": { + "1": "ي", + "2": "ف", + "3": "م", + "4": "أ", + "5": "و", + "6": "ن", + "7": "ل", + "8": "غ", + "9": "س", + "10": "ك", + "11": "ب", + "12": "د" + }, + "wide": { + "1": "يناير", + "2": "فبراير", + "3": "مارس", + "4": "أبريل", + "5": "مايو", + "6": "يونيو", + "7": "يوليو", + "8": "أغسطس", + "9": "سبتمبر", + "10": "أكتوبر", + "11": "نوفمبر", + "12": "ديسمبر" + } + }, + "stand-alone": { + "abbreviated": { + "1": "يناير", + "2": "فبراير", + "3": "مارس", + "4": "أبريل", + "5": "مايو", + "6": "يونيو", + "7": "يوليو", + "8": "أغسطس", + "9": "سبتمبر", + "10": "أكتوبر", + "11": "نوفمبر", + "12": "ديسمبر" + }, + "narrow": { + "1": "ي", + "2": "ف", + "3": "م", + "4": "أ", + "5": "و", + "6": "ن", + "7": "ل", + "8": "غ", + "9": "س", + "10": "ك", + "11": "ب", + "12": "د" + }, + "wide": { + "1": "يناير", + "2": "فبراير", + "3": "مارس", + "4": "أبريل", + "5": "مايو", + "6": "يونيو", + "7": "يوليو", + "8": "أغسطس", + "9": "سبتمبر", + "10": "أكتوبر", + "11": "نوفمبر", + "12": "ديسمبر" + } + } + }, + "days": { + "format": { + "abbreviated": { + "sun": "الأحد", + "mon": "الاثنين", + "tue": "الثلاثاء", + "wed": "الأربعاء", + "thu": "الخميس", + "fri": "الجمعة", + "sat": "السبت" + }, + "narrow": { + "sun": "ح", + "mon": "ن", + "tue": "ث", + "wed": "ر", + "thu": "خ", + "fri": "ج", + "sat": "س" + }, + "short": { + "sun": "الأحد", + "mon": "الاثنين", + "tue": "الثلاثاء", + "wed": "الأربعاء", + "thu": "الخميس", + "fri": "الجمعة", + "sat": "السبت" + }, + "wide": { + "sun": "الأحد", + "mon": "الاثنين", + "tue": "الثلاثاء", + "wed": "الأربعاء", + "thu": "الخميس", + "fri": "الجمعة", + "sat": "السبت" + } + }, + "stand-alone": { + "abbreviated": { + "sun": "الأحد", + "mon": "الاثنين", + "tue": "الثلاثاء", + "wed": "الأربعاء", + "thu": "الخميس", + "fri": "الجمعة", + "sat": "السبت" + }, + "narrow": { + "sun": "ح", + "mon": "ن", + "tue": "ث", + "wed": "ر", + "thu": "خ", + "fri": "ج", + "sat": "س" + }, + "short": { + "sun": "الأحد", + "mon": "الاثنين", + "tue": "الثلاثاء", + "wed": "الأربعاء", + "thu": "الخميس", + "fri": "الجمعة", + "sat": "السبت" + }, + "wide": { + "sun": "الأحد", + "mon": "الاثنين", + "tue": "الثلاثاء", + "wed": "الأربعاء", + "thu": "الخميس", + "fri": "الجمعة", + "sat": "السبت" + } + } + }, + "quarters": { + "format": { + "abbreviated": { + "1": "الربع الأول", + "2": "الربع الثاني", + "3": "الربع الثالث", + "4": "الربع الرابع" + }, + "narrow": { + "1": "١", + "2": "٢", + "3": "٣", + "4": "٤" + }, + "wide": { + "1": "الربع الأول", + "2": "الربع الثاني", + "3": "الربع الثالث", + "4": "الربع الرابع" + } + }, + "stand-alone": { + "abbreviated": { + "1": "الربع الأول", + "2": "الربع الثاني", + "3": "الربع الثالث", + "4": "الربع الرابع" + }, + "narrow": { + "1": "١", + "2": "٢", + "3": "٣", + "4": "٤" + }, + "wide": { + "1": "الربع الأول", + "2": "الربع الثاني", + "3": "الربع الثالث", + "4": "الربع الرابع" + } + } + }, + "dayPeriods": { + "format": { + "abbreviated": { + "am": "ص", + "noon": "noon", + "pm": "م" + }, + "narrow": { + "am": "a", + "noon": "n", + "pm": "p" + }, + "wide": { + "am": "ص", + "noon": "noon", + "pm": "م" + } + }, + "stand-alone": { + "abbreviated": { + "am": "ص", + "noon": "noon", + "pm": "م" + }, + "narrow": { + "am": "a", + "noon": "n", + "pm": "p" + }, + "wide": { + "am": "ص", + "noon": "noon", + "pm": "م" + } + } + }, + "eras": { + "eraNames": { + "0": "قبل الميلاد", + "0-alt-variant": "BCE", + "1": "ميلادي", + "1-alt-variant": "CE" + }, + "eraAbbr": { + "0": "ق.م", + "0-alt-variant": "BCE", + "1": "م", + "1-alt-variant": "CE" + }, + "eraNarrow": { + "0": "ق.م", + "0-alt-variant": "BCE", + "1": "م", + "1-alt-variant": "CE" + } + }, + "dateFormats": { + "full": "EEEE، d MMMM، y", + "long": "d MMMM، y", + "medium": "dd‏/MM‏/y", + "short": "d‏/M‏/y" + }, + "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} {0}", + "long": "{1} {0}", + "medium": "{1} {0}", + "short": "{1} {0}", + "availableFormats": { + "EHm": "E HH:mm", + "EHms": "E HH:mm:ss", + "Ed": "E، d", + "Ehm": "E h:mm a", + "Ehms": "E h:mm:ss a", + "Gy": "y G", + "GyMMM": "MMM y G", + "GyMMMEd": "E، d MMM، y G", + "GyMMMd": "d MMM، y G", + "H": "HH", + "Hm": "HH:mm", + "Hms": "HH:mm:ss", + "M": "L", + "MEd": "E، d/M", + "MMM": "LLL", + "MMMEd": "E، d MMM", + "MMMMEd": "E، d MMMM", + "MMMMd": "d MMMM", + "MMMd": "d MMM", + "MMdd": "dd‏/MM", + "Md": "d/‏M", + "d": "d", + "h": "h a", + "hm": "h:mm a", + "hms": "h:mm:ss a", + "ms": "mm:ss", + "y": "y", + "yM": "M‏/y", + "yMEd": "E، d/‏M/‏y", + "yMM": "MM‏/y", + "yMMM": "MMM y", + "yMMMEd": "E، d MMM، y", + "yMMMM": "MMMM y", + "yMMMd": "d MMM، y", + "yMd": "d‏/M‏/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}", + "H": { + "H": "HH–HH" + }, + "Hm": { + "H": "HH:mm–HH:mm", + "m": "HH:mm–HH:mm" + }, + "Hmv": { + "H": "HH:mm–HH:mm v", + "m": "HH:mm–HH:mm v" + }, + "Hv": { + "H": "HH–HH v" + }, + "M": { + "M": "M–M" + }, + "MEd": { + "M": "E، d/‏M – E، d/‏M", + "d": "E، d/‏M –‏ E، d/‏M" + }, + "MMM": { + "M": "MMM–MMM" + }, + "MMMEd": { + "M": "E، d MMM – E، d MMM", + "d": "E، d – E، d MMM" + }, + "MMMM": { + "M": "LLLL–LLLL" + }, + "MMMd": { + "M": "d MMM – d MMM", + "d": "d–d MMM" + }, + "Md": { + "M": "M/d – M/d", + "d": "M/d – M/d" + }, + "d": { + "d": "d–d" + }, + "h": { + "a": "h a – h a", + "h": "h–h a" + }, + "hm": { + "a": "h:mm a – h:mm a", + "h": "h:mm–h:mm a", + "m": "h:mm–h:mm a" + }, + "hmv": { + "a": "h:mm a – h:mm a v", + "h": "h:mm–h:mm a v", + "m": "h:mm–h:mm a v" + }, + "hv": { + "a": "h a – h a v", + "h": "h–h a v" + }, + "y": { + "y": "y–y" + }, + "yM": { + "M": "M‏/y – M‏/y", + "y": "M‏/y – M‏/y" + }, + "yMEd": { + "M": "E، d‏/M‏/y – E، d‏/M‏/y", + "d": "E، dd‏/MM‏/y – E، dd‏/MM‏/y", + "y": "E، d‏/M‏/y – E، d‏/M‏/y" + }, + "yMMM": { + "M": "MMM – MMM، y", + "y": "MMM، y – MMM، y" + }, + "yMMMEd": { + "M": "E، d MMM – E، d MMM، y", + "d": "E، d – E، d MMM، y", + "y": "E، d MMM، y – E، d MMM، y" + }, + "yMMMM": { + "M": "MMMM – MMMM، y", + "y": "MMMM، y – MMMM، y" + }, + "yMMMd": { + "M": "d MMM – d MMM، y", + "d": "d–d MMM، y", + "y": "d MMM، y – d MMM، y" + }, + "yMd": { + "M": "d‏/M‏/y – d‏/M‏/y", + "d": "d‏/M‏/y – d‏/M‏/y", + "y": "d‏/M‏/y – d‏/M‏/y" + } + } + } + } + } + } + } + } +}); + +Globalize.load({ + "main": { + "es": { + "identity": { + "version": { + "_cldrVersion": "25", + "_number": "$Revision: 91 $" + }, + "generation": { + "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + }, + "language": "es" + }, + "dates": { + "calendars": { + "gregorian": { + "months": { + "format": { + "abbreviated": { + "1": "ene.", + "2": "feb.", + "3": "mar.", + "4": "abr.", + "5": "may.", + "6": "jun.", + "7": "jul.", + "8": "ago.", + "9": "sept.", + "10": "oct.", + "11": "nov.", + "12": "dic." + }, + "narrow": { + "1": "E", + "2": "F", + "3": "M", + "4": "A", + "5": "M", + "6": "J", + "7": "J", + "8": "A", + "9": "S", + "10": "O", + "11": "N", + "12": "D" + }, + "wide": { + "1": "enero", + "2": "febrero", + "3": "marzo", + "4": "abril", + "5": "mayo", + "6": "junio", + "7": "julio", + "8": "agosto", + "9": "septiembre", + "10": "octubre", + "11": "noviembre", + "12": "diciembre" + } + }, + "stand-alone": { + "abbreviated": { + "1": "Ene.", + "2": "Feb.", + "3": "Mar.", + "4": "Abr.", + "5": "May.", + "6": "Jun.", + "7": "Jul.", + "8": "Ago.", + "9": "Sept.", + "10": "Oct.", + "11": "Nov.", + "12": "Dic." + }, + "narrow": { + "1": "E", + "2": "F", + "3": "M", + "4": "A", + "5": "M", + "6": "J", + "7": "J", + "8": "A", + "9": "S", + "10": "O", + "11": "N", + "12": "D" + }, + "wide": { + "1": "Enero", + "2": "Febrero", + "3": "Marzo", + "4": "Abril", + "5": "Mayo", + "6": "Junio", + "7": "Julio", + "8": "Agosto", + "9": "Septiembre", + "10": "Octubre", + "11": "Noviembre", + "12": "Diciembre" + } + } + }, + "days": { + "format": { + "abbreviated": { + "sun": "dom.", + "mon": "lun.", + "tue": "mar.", + "wed": "mié.", + "thu": "jue.", + "fri": "vie.", + "sat": "sáb." + }, + "narrow": { + "sun": "D", + "mon": "L", + "tue": "M", + "wed": "X", + "thu": "J", + "fri": "V", + "sat": "S" + }, + "short": { + "sun": "DO", + "mon": "LU", + "tue": "MA", + "wed": "MI", + "thu": "JU", + "fri": "VI", + "sat": "SA" + }, + "wide": { + "sun": "domingo", + "mon": "lunes", + "tue": "martes", + "wed": "miércoles", + "thu": "jueves", + "fri": "viernes", + "sat": "sábado" + } + }, + "stand-alone": { + "abbreviated": { + "sun": "Dom.", + "mon": "Lun.", + "tue": "Mar.", + "wed": "Mié.", + "thu": "Jue.", + "fri": "Vie.", + "sat": "Sáb." + }, + "narrow": { + "sun": "D", + "mon": "L", + "tue": "M", + "wed": "X", + "thu": "J", + "fri": "V", + "sat": "S" + }, + "short": { + "sun": "DO", + "mon": "LU", + "tue": "MA", + "wed": "MI", + "thu": "JU", + "fri": "VI", + "sat": "SA" + }, + "wide": { + "sun": "Domingo", + "mon": "Lunes", + "tue": "Martes", + "wed": "Miércoles", + "thu": "Jueves", + "fri": "Viernes", + "sat": "Sábado" + } + } + }, + "quarters": { + "format": { + "abbreviated": { + "1": "T1", + "2": "T2", + "3": "T3", + "4": "T4" + }, + "narrow": { + "1": "1T", + "2": "2T", + "3": "3T", + "4": "4T" + }, + "wide": { + "1": "1.er trimestre", + "2": "2.º trimestre", + "3": "3.er trimestre", + "4": "4.º trimestre" + } + }, + "stand-alone": { + "abbreviated": { + "1": "T1", + "2": "T2", + "3": "T3", + "4": "T4" + }, + "narrow": { + "1": "1T", + "2": "2T", + "3": "3T", + "4": "4T" + }, + "wide": { + "1": "1.er trimestre", + "2": "2.º trimestre", + "3": "3.er trimestre", + "4": "4.º trimestre" + } + } + }, + "dayPeriods": { + "format": { + "abbreviated": { + "am": "a. m.", + "noon": "noon", + "pm": "p. m." + }, + "narrow": { + "am": "a.m.", + "noon": "n", + "pm": "p.m." + }, + "wide": { + "am": "a. m.", + "noon": "noon", + "pm": "p. m." + } + }, + "stand-alone": { + "abbreviated": { + "am": "a. m.", + "noon": "noon", + "pm": "p. m." + }, + "narrow": { + "am": "a.m.", + "noon": "n", + "pm": "p.m." + }, + "wide": { + "am": "a. m.", + "noon": "noon", + "pm": "p. m." + } + } + }, + "eras": { + "eraNames": { + "0": "antes de Cristo", + "0-alt-variant": "a. e. c.", + "1": "anno Dómini", + "1-alt-variant": "e. c." + }, + "eraAbbr": { + "0": "a. C.", + "0-alt-variant": "a. e. c.", + "1": "d. C.", + "1-alt-variant": "e. c." + }, + "eraNarrow": { + "0": "a. C.", + "0-alt-variant": "a. e. c.", + "1": "d. C.", + "1-alt-variant": "e. c." + } + }, + "dateFormats": { + "full": "EEEE, d 'de' MMMM 'de' y", + "long": "d 'de' MMMM 'de' y", + "medium": "d/M/y", + "short": "d/M/yy" + }, + "timeFormats": { + "full": "H:mm:ss (zzzz)", + "long": "H:mm:ss z", + "medium": "H:mm:ss", + "short": "H:mm" + }, + "dateTimeFormats": { + "full": "{1}, {0}", + "long": "{1}, {0}", + "medium": "{1} {0}", + "short": "{1} {0}", + "availableFormats": { + "EHm": "E, H:mm", + "EHms": "E, H:mm:ss", + "Ed": "E d", + "Ehm": "E, h:mm a", + "Ehms": "E, h:mm:ss a", + "Gy": "y G", + "GyMMM": "MMM 'de' y G", + "GyMMMEd": "E, d 'de' MMMM 'de' y G", + "GyMMMd": "d MMM 'de' y G", + "H": "H", + "Hm": "H:mm", + "Hms": "H:mm:ss", + "M": "L", + "MEd": "E, d/M", + "MMM": "LLL", + "MMMEd": "E d 'de' MMM", + "MMMMd": "d 'de' MMMM", + "MMMd": "d 'de' MMM", + "MMMdd": "dd-MMM", + "MMd": "d/M", + "MMdd": "d/M", + "Md": "d/M", + "d": "d", + "h": "h a", + "hm": "h:mm a", + "hms": "h:mm:ss a", + "ms": "mm:ss", + "y": "y", + "yM": "M/y", + "yMEd": "EEE, d/M/y", + "yMM": "M/y", + "yMMM": "MMM 'de' y", + "yMMMEd": "EEE, d 'de' MMMM 'de' y", + "yMMMM": "MMMM 'de' y", + "yMMMd": "d 'de' MMM 'de' y", + "yMd": "d/M/y", + "yQQQ": "QQQ y", + "yQQQQ": "QQQQ 'de' 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}", + "H": { + "H": "H–H" + }, + "Hm": { + "H": "H:mm–H:mm", + "m": "H:mm–H:mm" + }, + "Hmv": { + "H": "H:mm–H:mm v", + "m": "H:mm–H:mm v" + }, + "Hv": { + "H": "H–H v" + }, + "M": { + "M": "M–M" + }, + "MEd": { + "M": "E, d/M–E, d/M", + "d": "E, d/M–E, d/M" + }, + "MMM": { + "M": "MMM–MMM" + }, + "MMMEd": { + "M": "E, d MMM–E, d MMM", + "d": "E, d MMM–E, d MMM" + }, + "MMMd": { + "M": "d MMM–d MMM", + "d": "d–d MMM" + }, + "Md": { + "M": "d/M–d/M", + "d": "d/M–d/M" + }, + "d": { + "d": "d–d" + }, + "h": { + "a": "h a–h a", + "h": "h–h a" + }, + "hm": { + "a": "h:mm a – h:mm a", + "h": "h:mm – h:mm a", + "m": "h:mm – h:mm a" + }, + "hmv": { + "a": "h:mm a–h:mm a v", + "h": "h:mm–h:mm a v", + "m": "h:mm–h:mm a v" + }, + "hv": { + "a": "h a–h a v", + "h": "h–h a v" + }, + "y": { + "y": "y–y" + }, + "yM": { + "M": "M/y–M/y", + "y": "M/y–M/y" + }, + "yMEd": { + "M": "E, d/M/y–E, d/M/y", + "d": "E, d/M/y–E, d/M/y", + "y": "E, d/M/y–E, d/M/y" + }, + "yMMM": { + "M": "MMM–MMM y", + "y": "MMM y–MMM y" + }, + "yMMMEd": { + "M": "E, d MMM–E, d MMM 'de' y", + "d": "E, d MMM–E, d MMM 'de' y", + "y": "E, d MMM 'de' y–E, d MMM 'de' y" + }, + "yMMMM": { + "M": "MMMM–MMMM 'de' y", + "y": "MMMM 'de' y–MMMM 'de' y" + }, + "yMMMd": { + "M": "d MMM–d MMM 'de' y", + "d": "d–d MMM y", + "y": "d MMM 'de' y–d MMM 'de' y" + }, + "yMd": { + "M": "d/M/y–d/M/y", + "d": "d/M/y–d/M/y", + "y": "d/M/y–d/M/y" + } + } + } + } + } + } + } + } +}); + Globalize.load({ "main": { "en": { @@ -937,6 +1849,495 @@ Globalize.load({ } }); +Globalize.load({ + "main": { + "zh": { + "identity": { + "version": { + "_cldrVersion": "25", + "_number": "$Revision: 91 $" + }, + "generation": { + "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + }, + "language": "root" + }, + "dates": { + "calendars": { + "gregorian": { + "months": { + "format": { + "abbreviated": { + "1": "1月", + "2": "2月", + "3": "3月", + "4": "4月", + "5": "5月", + "6": "6月", + "7": "7月", + "8": "8月", + "9": "9月", + "10": "10月", + "11": "11月", + "12": "12月" + }, + "narrow": { + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7", + "8": "8", + "9": "9", + "10": "10", + "11": "11", + "12": "12" + }, + "wide": { + "1": "一月", + "2": "二月", + "3": "三月", + "4": "四月", + "5": "五月", + "6": "六月", + "7": "七月", + "8": "八月", + "9": "九月", + "10": "十月", + "11": "十一月", + "12": "十二月" + } + }, + "stand-alone": { + "abbreviated": { + "1": "1月", + "2": "2月", + "3": "3月", + "4": "4月", + "5": "5月", + "6": "6月", + "7": "7月", + "8": "8月", + "9": "9月", + "10": "10月", + "11": "11月", + "12": "12月" + }, + "narrow": { + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7", + "8": "8", + "9": "9", + "10": "10", + "11": "11", + "12": "12" + }, + "wide": { + "1": "一月", + "2": "二月", + "3": "三月", + "4": "四月", + "5": "五月", + "6": "六月", + "7": "七月", + "8": "八月", + "9": "九月", + "10": "十月", + "11": "十一月", + "12": "十二月" + } + } + }, + "days": { + "format": { + "abbreviated": { + "sun": "周日", + "mon": "周一", + "tue": "周二", + "wed": "周三", + "thu": "周四", + "fri": "周五", + "sat": "周六" + }, + "narrow": { + "sun": "日", + "mon": "一", + "tue": "二", + "wed": "三", + "thu": "四", + "fri": "五", + "sat": "六" + }, + "short": { + "sun": "周日", + "mon": "周一", + "tue": "周二", + "wed": "周三", + "thu": "周四", + "fri": "周五", + "sat": "周六" + }, + "wide": { + "sun": "星期日", + "mon": "星期一", + "tue": "星期二", + "wed": "星期三", + "thu": "星期四", + "fri": "星期五", + "sat": "星期六" + } + }, + "stand-alone": { + "abbreviated": { + "sun": "周日", + "mon": "周一", + "tue": "周二", + "wed": "周三", + "thu": "周四", + "fri": "周五", + "sat": "周六" + }, + "narrow": { + "sun": "日", + "mon": "一", + "tue": "二", + "wed": "三", + "thu": "四", + "fri": "五", + "sat": "六" + }, + "short": { + "sun": "周日", + "mon": "周一", + "tue": "周二", + "wed": "周三", + "thu": "周四", + "fri": "周五", + "sat": "周六" + }, + "wide": { + "sun": "星期日", + "mon": "星期一", + "tue": "星期二", + "wed": "星期三", + "thu": "星期四", + "fri": "星期五", + "sat": "星期六" + } + } + }, + "quarters": { + "format": { + "abbreviated": { + "1": "1季度", + "2": "2季度", + "3": "3季度", + "4": "4季度" + }, + "narrow": { + "1": "1", + "2": "2", + "3": "3", + "4": "4" + }, + "wide": { + "1": "第一季度", + "2": "第二季度", + "3": "第三季度", + "4": "第四季度" + } + }, + "stand-alone": { + "abbreviated": { + "1": "1季度", + "2": "2季度", + "3": "3季度", + "4": "4季度" + }, + "narrow": { + "1": "1", + "2": "2", + "3": "3", + "4": "4" + }, + "wide": { + "1": "第一季度", + "2": "第二季度", + "3": "第三季度", + "4": "第四季度" + } + } + }, + "dayPeriods": { + "format": { + "abbreviated": { + "afternoon": "下午", + "am": "上午", + "earlyMorning": "清晨", + "midDay": "中午", + "morning": "上午", + "night": "晚上", + "noon": "中午", + "pm": "下午", + "weeHours": "凌晨" + }, + "narrow": { + "afternoon": "下午", + "am": "上午", + "earlyMorning": "清晨", + "midDay": "中午", + "morning": "上午", + "night": "晚上", + "noon": "中午", + "pm": "下午", + "weeHours": "凌晨" + }, + "wide": { + "afternoon": "下午", + "am": "上午", + "earlyMorning": "清晨", + "midDay": "中午", + "morning": "上午", + "night": "晚上", + "noon": "中午", + "pm": "下午", + "weeHours": "凌晨" + } + }, + "stand-alone": { + "abbreviated": { + "afternoon": "下午", + "am": "上午", + "earlyMorning": "清晨", + "midDay": "中午", + "morning": "上午", + "night": "晚上", + "noon": "中午", + "pm": "下午", + "weeHours": "凌晨" + }, + "narrow": { + "afternoon": "下午", + "am": "上午", + "earlyMorning": "清晨", + "midDay": "中午", + "morning": "上午", + "night": "晚上", + "noon": "中午", + "pm": "下午", + "weeHours": "凌晨" + }, + "wide": { + "afternoon": "下午", + "am": "上午", + "earlyMorning": "清晨", + "midDay": "中午", + "morning": "上午", + "night": "晚上", + "noon": "中午", + "pm": "下午", + "weeHours": "凌晨" + } + } + }, + "eras": { + "eraNames": { + "0": "公元前", + "0-alt-variant": "BCE", + "1": "公元", + "1-alt-variant": "CE" + }, + "eraAbbr": { + "0": "公元前", + "0-alt-variant": "BCE", + "1": "公元", + "1-alt-variant": "CE" + }, + "eraNarrow": { + "0": "公元前", + "0-alt-variant": "BCE", + "1": "公元", + "1-alt-variant": "CE" + } + }, + "dateFormats": { + "full": "y年M月d日EEEE", + "long": "y年M月d日", + "medium": "y年M月d日", + "short": "yy/M/d" + }, + "timeFormats": { + "full": "zzzzah:mm:ss", + "long": "zah:mm:ss", + "medium": "ah:mm:ss", + "short": "ah:mm" + }, + "dateTimeFormats": { + "full": "{1} {0}", + "long": "{1} {0}", + "medium": "{1} {0}", + "short": "{1} {0}", + "availableFormats": { + "EHm": "EHH:mm", + "EHms": "EHH:mm:ss", + "Ed": "d日E", + "Ehm": "Eah:mm", + "Ehms": "Eah:mm:ss", + "Gy": "Gy年", + "GyMMM": "Gy年M月", + "GyMMMEd": "Gy年M月d日E", + "GyMMMd": "Gy年M月d日", + "H": "H时", + "Hm": "HH:mm", + "Hms": "HH:mm:ss", + "M": "M月", + "MEd": "M/dE", + "MMM": "LLL", + "MMMEd": "M月d日E", + "MMMMdd": "M月dd日", + "MMMd": "M月d日", + "MMdd": "MM/dd", + "Md": "M/d", + "d": "d日", + "h": "ah时", + "hm": "ah:mm", + "hms": "ah:mm:ss", + "ms": "mm:ss", + "y": "y年", + "yM": "y/M", + "yMEd": "y/M/dE", + "yMM": "y年M月", + "yMMM": "y年M月", + "yMMMEd": "y年M月d日E", + "yMMMM": "y年M月", + "yMMMd": "y年M月d日", + "yMd": "y/M/d", + "yQQQ": "y年第Q季度", + "yQQQQ": "y年第Q季度" + }, + "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": "{1}{0}", + "Week": "{0} ({2}: {1})", + "Year": "{1} {0}" + }, + "intervalFormats": { + "intervalFormatFallback": "{0} – {1}", + "H": { + "H": "HH–HH" + }, + "Hm": { + "H": "HH:mm–HH:mm", + "m": "HH:mm–HH:mm" + }, + "Hmv": { + "H": "v HH:mm–HH:mm", + "m": "v HH:mm–HH:mm" + }, + "Hv": { + "H": "v HH–HH" + }, + "M": { + "M": "M–M月" + }, + "MEd": { + "M": "M/dE至M/dE", + "d": "M/dE至M/dE" + }, + "MMM": { + "M": "LLL至LLL" + }, + "MMMEd": { + "M": "M月d日E至M月d日E", + "d": "M月d日E至d日E" + }, + "MMMd": { + "M": "M月d日至M月d日", + "d": "M月d日至d日" + }, + "Md": { + "M": "M/d – M/d", + "d": "M/d – M/d" + }, + "d": { + "d": "d–d日" + }, + "h": { + "a": "ah时至ah时", + "h": "ah时至h时" + }, + "hm": { + "a": "ah:mm至ah:mm", + "h": "ah:mm至h:mm", + "m": "ah:mm至h:mm" + }, + "hmv": { + "a": "vah:mm至ah:mm", + "h": "vah:mm至h:mm", + "m": "vah:mm至h:mm" + }, + "hv": { + "a": "vah时至ah时", + "h": "vah时至h时" + }, + "y": { + "y": "y–y年" + }, + "yM": { + "M": "y年M月至M月", + "y": "y年M月至y年M月" + }, + "yMEd": { + "M": "y/M/dE至y/M/dE", + "d": "y/M/dE至y/M/dE", + "y": "y/M/dE至y/M/dE" + }, + "yMMM": { + "M": "y年M月至M月", + "y": "y年M月至y年M月" + }, + "yMMMEd": { + "M": "y年M月d日E至M月d日E", + "d": "y年M月d日E至d日E", + "y": "y年M月d日E至y年M月d日E" + }, + "yMMMM": { + "M": "y年M月至M月", + "y": "y年M月至y年M月" + }, + "yMMMd": { + "M": "y年M月d日至M月d日", + "d": "y年M月d日至d日", + "y": "y年M月d日至y年M月d日" + }, + "yMd": { + "M": "y/M/d – y/M/d", + "d": "y/M/d – y/M/d", + "y": "y/M/d – y/M/d" + } + } + } + } + } + } + } + } +}); + Globalize.load({ "supplemental": { "version": { @@ -3303,7 +4704,7 @@ Globalize.loadTranslations({ "dateFormat": "d" } }, - "zh-CN": { + "zh": { "datepicker": { "closeText": "\u00e5\u2026\u00b3\u00e9\u2014\u00ad", "prevText": "<\u00e4\u00b8\u0160\u00e6\u0153\u02c6", From 846852a2503e9d6ae12a674f66f31f4241a5ee53 Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 15:47:48 -0300 Subject: [PATCH 075/179] Datepicker: Use Globalize 1.0.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix Use narrow day names (e.g., "ﺥ" EEEEE) if short (e.g., "ﺎﻠﺨﻤﻴﺳ" EEE) if too lengthy; --- external/date.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/external/date.js b/external/date.js index 6e532b008fe..958b53d0701 100644 --- a/external/date.js +++ b/external/date.js @@ -137,12 +137,16 @@ $.date.prototype = { return new Date( year, 1, 29 ).getMonth() == 1; }, weekdays: function() { - var result = []; + var cldr = Globalize.locale(), + result = []; for ( var dow = 0; dow < 7; dow++ ) { - var day = ( dow + weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] ) % 7; + var day = ( dow + weekdaysRev[ cldr.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 ] ]) + shortname: + cldr.main([ "dates/calendars/gregorian/days/format/short", weekdays[ day ] ]).length > 3 ? + cldr.main([ "dates/calendars/gregorian/days/format/narrow", weekdays[ day ] ]) : + cldr.main([ "dates/calendars/gregorian/days/format/short", weekdays[ day ] ]), + fullname: cldr.main([ "dates/calendars/gregorian/days/format/wide", weekdays[ day ] ]) }); } return result; From 9d552b71989af93e96d1af493ef6a3c3fd20e1b5 Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 15:47:48 -0300 Subject: [PATCH 076/179] Datepicker: Use Globalize 1.0.0 - Fix "I never liked that we attempted to translate the language https://github.com/jquery/jquery-ui/pull/1341#discussion_r17171152 --- demos/datepicker/localization.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index ed0f374a64c..5ca763450ca 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -39,15 +39,15 @@

      Date:  

      -

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

      +

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

      From fda7a7e98fe376e04f66a122a82b209a2c628cfd Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 15:47:48 -0300 Subject: [PATCH 077/179] Datepicker: Use Globalize 1.0.0 - \o/ \o/ \o/ get rid of all name translations --- external/localization.js | 537 ------------------------------------ ui/calendar.js | 10 +- ui/i18n/datepicker-af.js | 37 --- ui/i18n/datepicker-ar-DZ.js | 37 --- ui/i18n/datepicker-ar.js | 38 --- ui/i18n/datepicker-az.js | 37 --- ui/i18n/datepicker-be.js | 37 --- ui/i18n/datepicker-bg.js | 38 --- ui/i18n/datepicker-bs.js | 37 --- ui/i18n/datepicker-ca.js | 37 --- ui/i18n/datepicker-cs.js | 37 --- ui/i18n/datepicker-cy-GB.js | 37 --- ui/i18n/datepicker-da.js | 37 --- ui/i18n/datepicker-de.js | 37 --- ui/i18n/datepicker-el.js | 37 --- ui/i18n/datepicker-en-AU.js | 37 --- ui/i18n/datepicker-en-GB.js | 37 --- ui/i18n/datepicker-en-NZ.js | 37 --- ui/i18n/datepicker-eo.js | 37 --- ui/i18n/datepicker-es.js | 37 --- ui/i18n/datepicker-et.js | 37 --- ui/i18n/datepicker-eu.js | 36 --- ui/i18n/datepicker-fa.js | 73 ----- ui/i18n/datepicker-fi.js | 37 --- ui/i18n/datepicker-fo.js | 37 --- ui/i18n/datepicker-fr-CA.js | 37 --- ui/i18n/datepicker-fr-CH.js | 37 --- ui/i18n/datepicker-fr.js | 39 --- ui/i18n/datepicker-gl.js | 37 --- ui/i18n/datepicker-he.js | 37 --- ui/i18n/datepicker-hi.js | 37 --- ui/i18n/datepicker-hr.js | 37 --- ui/i18n/datepicker-hu.js | 36 --- ui/i18n/datepicker-hy.js | 37 --- ui/i18n/datepicker-id.js | 37 --- ui/i18n/datepicker-is.js | 37 --- ui/i18n/datepicker-it-CH.js | 37 --- ui/i18n/datepicker-it.js | 37 --- ui/i18n/datepicker-ja.js | 37 --- ui/i18n/datepicker-ka.js | 35 --- ui/i18n/datepicker-kk.js | 37 --- ui/i18n/datepicker-km.js | 37 --- ui/i18n/datepicker-ko.js | 37 --- ui/i18n/datepicker-ky.js | 38 --- ui/i18n/datepicker-lb.js | 37 --- ui/i18n/datepicker-lt.js | 37 --- ui/i18n/datepicker-lv.js | 37 --- ui/i18n/datepicker-mk.js | 37 --- ui/i18n/datepicker-ml.js | 37 --- ui/i18n/datepicker-ms.js | 37 --- ui/i18n/datepicker-nb.js | 36 --- ui/i18n/datepicker-nl-BE.js | 37 --- ui/i18n/datepicker-nl.js | 37 --- ui/i18n/datepicker-nn.js | 36 --- ui/i18n/datepicker-no.js | 37 --- ui/i18n/datepicker-pl.js | 37 --- ui/i18n/datepicker-pt-BR.js | 37 --- ui/i18n/datepicker-pt.js | 36 --- ui/i18n/datepicker-rm.js | 35 --- ui/i18n/datepicker-ro.js | 40 --- ui/i18n/datepicker-ru.js | 37 --- ui/i18n/datepicker-sk.js | 37 --- ui/i18n/datepicker-sl.js | 38 --- ui/i18n/datepicker-sq.js | 37 --- ui/i18n/datepicker-sr-SR.js | 37 --- ui/i18n/datepicker-sr.js | 37 --- ui/i18n/datepicker-sv.js | 37 --- ui/i18n/datepicker-ta.js | 37 --- ui/i18n/datepicker-th.js | 37 --- ui/i18n/datepicker-tj.js | 37 --- ui/i18n/datepicker-tr.js | 37 --- ui/i18n/datepicker-uk.js | 38 --- ui/i18n/datepicker-vi.js | 37 --- ui/i18n/datepicker-zh-CN.js | 37 --- ui/i18n/datepicker-zh-HK.js | 37 --- ui/i18n/datepicker-zh-TW.js | 37 --- 76 files changed, 8 insertions(+), 3314 deletions(-) delete mode 100644 ui/i18n/datepicker-af.js delete mode 100644 ui/i18n/datepicker-ar-DZ.js delete mode 100644 ui/i18n/datepicker-ar.js delete mode 100644 ui/i18n/datepicker-az.js delete mode 100644 ui/i18n/datepicker-be.js delete mode 100644 ui/i18n/datepicker-bg.js delete mode 100644 ui/i18n/datepicker-bs.js delete mode 100644 ui/i18n/datepicker-ca.js delete mode 100644 ui/i18n/datepicker-cs.js delete mode 100644 ui/i18n/datepicker-cy-GB.js delete mode 100644 ui/i18n/datepicker-da.js delete mode 100644 ui/i18n/datepicker-de.js delete mode 100644 ui/i18n/datepicker-el.js delete mode 100644 ui/i18n/datepicker-en-AU.js delete mode 100644 ui/i18n/datepicker-en-GB.js delete mode 100644 ui/i18n/datepicker-en-NZ.js delete mode 100644 ui/i18n/datepicker-eo.js delete mode 100644 ui/i18n/datepicker-es.js delete mode 100644 ui/i18n/datepicker-et.js delete mode 100644 ui/i18n/datepicker-eu.js delete mode 100644 ui/i18n/datepicker-fa.js delete mode 100644 ui/i18n/datepicker-fi.js delete mode 100644 ui/i18n/datepicker-fo.js delete mode 100644 ui/i18n/datepicker-fr-CA.js delete mode 100644 ui/i18n/datepicker-fr-CH.js delete mode 100644 ui/i18n/datepicker-fr.js delete mode 100644 ui/i18n/datepicker-gl.js delete mode 100644 ui/i18n/datepicker-he.js delete mode 100644 ui/i18n/datepicker-hi.js delete mode 100644 ui/i18n/datepicker-hr.js delete mode 100644 ui/i18n/datepicker-hu.js delete mode 100644 ui/i18n/datepicker-hy.js delete mode 100644 ui/i18n/datepicker-id.js delete mode 100644 ui/i18n/datepicker-is.js delete mode 100644 ui/i18n/datepicker-it-CH.js delete mode 100644 ui/i18n/datepicker-it.js delete mode 100644 ui/i18n/datepicker-ja.js delete mode 100644 ui/i18n/datepicker-ka.js delete mode 100644 ui/i18n/datepicker-kk.js delete mode 100644 ui/i18n/datepicker-km.js delete mode 100644 ui/i18n/datepicker-ko.js delete mode 100644 ui/i18n/datepicker-ky.js delete mode 100644 ui/i18n/datepicker-lb.js delete mode 100644 ui/i18n/datepicker-lt.js delete mode 100644 ui/i18n/datepicker-lv.js delete mode 100644 ui/i18n/datepicker-mk.js delete mode 100644 ui/i18n/datepicker-ml.js delete mode 100644 ui/i18n/datepicker-ms.js delete mode 100644 ui/i18n/datepicker-nb.js delete mode 100644 ui/i18n/datepicker-nl-BE.js delete mode 100644 ui/i18n/datepicker-nl.js delete mode 100644 ui/i18n/datepicker-nn.js delete mode 100644 ui/i18n/datepicker-no.js delete mode 100644 ui/i18n/datepicker-pl.js delete mode 100644 ui/i18n/datepicker-pt-BR.js delete mode 100644 ui/i18n/datepicker-pt.js delete mode 100644 ui/i18n/datepicker-rm.js delete mode 100644 ui/i18n/datepicker-ro.js delete mode 100644 ui/i18n/datepicker-ru.js delete mode 100644 ui/i18n/datepicker-sk.js delete mode 100644 ui/i18n/datepicker-sl.js delete mode 100644 ui/i18n/datepicker-sq.js delete mode 100644 ui/i18n/datepicker-sr-SR.js delete mode 100644 ui/i18n/datepicker-sr.js delete mode 100644 ui/i18n/datepicker-sv.js delete mode 100644 ui/i18n/datepicker-ta.js delete mode 100644 ui/i18n/datepicker-th.js delete mode 100644 ui/i18n/datepicker-tj.js delete mode 100644 ui/i18n/datepicker-tr.js delete mode 100644 ui/i18n/datepicker-uk.js delete mode 100644 ui/i18n/datepicker-vi.js delete mode 100644 ui/i18n/datepicker-zh-CN.js delete mode 100644 ui/i18n/datepicker-zh-HK.js delete mode 100644 ui/i18n/datepicker-zh-TW.js diff --git a/external/localization.js b/external/localization.js index 22c2350ecc9..d1be977be45 100644 --- a/external/localization.js +++ b/external/localization.js @@ -4188,540 +4188,3 @@ Globalize.load({ } } }); - -/** - * jQuery UI translation data - */ -Globalize.loadTranslations({ - "en": { - "datepicker": { - "closeText": "Done", - "prevText": "Prev", - "nextText": "Next", - "currentText": "Today", - "weekHeader": "Wk", - "dateFormat": "d", - "datePickerRole": "date picker" - } - }, - "af": { - "datepicker": { - "closeText": "Selekteer", - "prevText": "Vorige", - "nextText": "Volgende", - "currentText": "Vandag", - "weekHeader": "Wk", - "dateFormat": "d" - } - }, - "zh-TW": { - "datepicker": { - "closeText": "\u95dc\u9589", - "prevText": "<\u4e0a\u6708", - "nextText": "\u4e0b\u6708>", - "currentText": "\u4eca\u5929", - "weekHeader": "\u5468", - "dateFormat": "d" - } - }, - "ar": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "Ba\u011fla", - "prevText": "<Geri", - "nextText": "\u0130r\u0259li>", - "currentText": "Bug\u00fcn", - "weekHeader": "Hf", - "dateFormat": "d" - } - }, - "bg": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "Zatvori", - "prevText": "<", - "nextText": ">", - "currentText": "Danas", - "weekHeader": "Wk", - "dateFormat": "d" - } - }, - "ca": { - "datepicker": { - "closeText": "Tancar", - "prevText": "<Ant", - "nextText": "Seg>", - "currentText": "Avui", - "weekHeader": "Sm", - "dateFormat": "d" - } - }, - "cs": { - "datepicker": { - "closeText": "Zav\u0159\u00edt", - "prevText": "<D\u0159\u00edve", - "nextText": "Pozd\u011bji>", - "currentText": "Nyn\u00ed", - "weekHeader": "T\u00fdd", - "dateFormat": "d" - } - }, - "da": { - "datepicker": { - "closeText": "Luk", - "prevText": "<Forrige", - "nextText": "N\u00e6ste>", - "currentText": "Idag", - "weekHeader": "Uge", - "dateFormat": "d" - } - }, - "de": { - "datepicker": { - "closeText": "Schlie\u00dfen", - "prevText": "<Zur\u00fcck", - "nextText": "Vor>", - "currentText": "Heute", - "weekHeader": "Wo", - "dateFormat": "d" - } - }, - "el": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "Done", - "prevText": "Prev", - "nextText": "Next", - "currentText": "Today", - "weekHeader": "Wk", - "dateFormat": "d" - } - }, - "eo": { - "datepicker": { - "closeText": "Fermi", - "prevText": "<Anta", - "nextText": "Sekv>", - "currentText": "Nuna", - "weekHeader": "Sb", - "dateFormat": "dd/MM/yyyy" - } - }, - "es": { - "datepicker": { - "closeText": "Cerrar", - "prevText": "<Ant", - "nextText": "Sig>", - "currentText": "Hoy", - "weekHeader": "Sm", - "dateFormat": "d" - } - }, - "et": { - "datepicker": { - "closeText": "Sulge", - "prevText": "Eelnev", - "nextText": "J\u00e4rgnev", - "currentText": "T\u00e4na", - "weekHeader": "Sm", - "dateFormat": "d" - } - }, - "eu": { - "datepicker": { - "closeText": "Egina", - "prevText": "<Aur", - "nextText": "Hur>", - "currentText": "Gaur", - "weekHeader": "Wk", - "dateFormat": "d" - } - }, - "fa": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "Sulje", - "prevText": "«Edellinen", - "nextText": "Seuraava»", - "currentText": "Tänään", - "weekHeader": "Vk", - "dateFormat": "d" - } - }, - "fo": { - "datepicker": { - "closeText": "Lat aftur", - "prevText": "<Fyrra", - "nextText": "N\u00e6sta>", - "currentText": "\u00cd dag", - "weekHeader": "Vk", - "dateFormat": "d" - } - }, - "fr-CH": { - "datepicker": { - "closeText": "Fermer", - "prevText": "<Pr\u00e9c", - "nextText": "Suiv>", - "currentText": "Courant", - "weekHeader": "Sm", - "dateFormat": "d" - } - }, - "fr": { - "datepicker": { - "closeText": "Fermer", - "prevText": "<Pr\u00e9c", - "nextText": "Suiv>", - "currentText": "Courant", - "weekHeader": "Sm", - "dateFormat": "d" - } - }, - "he": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "Zatvori", - "prevText": "<", - "nextText": ">", - "currentText": "Danas", - "weekHeader": "Tje", - "dateFormat": "d" - } - }, - "hu": { - "datepicker": { - "closeText": "bez\u00c3\u00a1r\u00c3\u00a1s", - "prevText": "« vissza", - "nextText": "el\u00c5\u2018re »", - "currentText": "ma", - "weekHeader": "H\u00c3\u00a9", - "dateFormat": "d" - } - }, - "hy": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "Tutup", - "prevText": "<mundur", - "nextText": "maju>", - "currentText": "hari ini", - "weekHeader": "Mg", - "dateFormat": "d" - } - }, - "is": { - "datepicker": { - "closeText": "Loka", - "prevText": "< Fyrri", - "nextText": "Næsti >", - "currentText": "Í dag", - "weekHeader": "Vika", - "dateFormat": "d" - } - }, - "it": { - "datepicker": { - "closeText": "Chiudi", - "prevText": "<Prec", - "nextText": "Succ>", - "currentText": "Oggi", - "weekHeader": "Sm", - "dateFormat": "d" - } - }, - "ja": { - "datepicker": { - "closeText": "\u9589\u3058\u308b", - "prevText": "<\u524d", - "nextText": "\u6b21>", - "currentText": "\u4eca\u65e5", - "weekHeader": "\u9031", - "dateFormat": "d" - } - }, - "ko": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "U\u00c5\u00bedaryti", - "prevText": "<Atgal", - "nextText": "Pirmyn>", - "currentText": "\u00c5\u00a0iandien", - "weekHeader": "Wk", - "dateFormat": "d" - } - }, - "lv": { - "datepicker": { - "closeText": "Aizv\u00c4\u201crt", - "prevText": "Iepr", - "nextText": "N\u00c4\u0081ka", - "currentText": "\u00c5\u00a0odien", - "weekHeader": "Nav", - "dateFormat": "d" - } - }, - "ms": { - "datepicker": { - "closeText": "Tutup", - "prevText": "<Sebelum", - "nextText": "Selepas>", - "currentText": "hari ini", - "weekHeader": "Mg", - "dateFormat": "d" - } - }, - "nl": { - "datepicker": { - "closeText": "Sluiten", - "prevText": "\u2190", - "nextText": "\u2192", - "currentText": "Vandaag", - "weekHeader": "Wk", - "dateFormat": "d" - } - }, - "no": { - "datepicker": { - "closeText": "Lukk", - "prevText": "«Forrige", - "nextText": "Neste»", - "currentText": "I dag", - "weekHeader": "Uke", - "dateFormat": "d" - } - }, - "pl": { - "datepicker": { - "closeText": "Zamknij", - "prevText": "<Poprzedni", - "nextText": "Nast\u00c4\u2122pny>", - "currentText": "Dzi\u00c5\u203a", - "weekHeader": "Tydz", - "dateFormat": "d" - } - }, - "pt-BR": { - "datepicker": { - "closeText": "Fechar", - "prevText": "<Anterior", - "nextText": "Próximo>", - "currentText": "Hoje", - "weekHeader": "Sm", - "dateFormat": "d" - } - }, - "ro": { - "datepicker": { - "closeText": "\u00cenchide", - "prevText": "« Luna precedent\u0103", - "nextText": "Luna urm\u0103toare »", - "currentText": "Azi", - "weekHeader": "S\u0103pt", - "dateFormat": "d" - } - }, - "ru": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "Zavrie\u00c5\u00a5", - "prevText": "<Predch\u00c3\u00a1dzaj\u00c3\u00baci", - "nextText": "Nasleduj\u00c3\u00baci>", - "currentText": "Dnes", - "weekHeader": "Ty", - "dateFormat": "d" - } - }, - "sl": { - "datepicker": { - "closeText": "Zapri", - "prevText": "<Prejšnji", - "nextText": "Naslednji>", - "currentText": "Trenutni", - "weekHeader": "Teden", - "dateFormat": "d" - } - }, - "sq": { - "datepicker": { - "closeText": "mbylle", - "prevText": "<mbrapa", - "nextText": "P\u00ebrpara>", - "currentText": "sot", - "weekHeader": "Ja", - "dateFormat": "d" - } - }, - "sr-SR": { - "datepicker": { - "closeText": "Zatvori", - "prevText": "<", - "nextText": ">", - "currentText": "Danas", - "weekHeader": "Sed", - "dateFormat": "dd/MM/yyyy" - } - }, - "sr": { - "datepicker": { - "closeText": "\u0417\u0430\u0442\u0432\u043e\u0440\u0438", - "prevText": "<", - "nextText": ">", - "currentText": "\u0414\u0430\u043d\u0430\u0441", - "weekHeader": "\u0421\u0435\u0434", - "dateFormat": "d" - } - }, - "sv": { - "datepicker": { - "closeText": "St\u00e4ng", - "prevText": "«F\u00f6rra", - "nextText": "N\u00e4sta»", - "currentText": "Idag", - "weekHeader": "Ve", - "dateFormat": "d" - } - }, - "ta": { - "datepicker": { - "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": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "kapat", - "prevText": "<geri", - "nextText": "ileri>", - "currentText": "bug\u00c3\u00bcn", - "weekHeader": "Hf", - "dateFormat": "d" - } - }, - "uk": { - "datepicker": { - "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": { - "datepicker": { - "closeText": "\u0110\u00f3ng", - "prevText": "<Tr\u01b0\u1edbc", - "nextText": "Ti\u1ebfp>", - "currentText": "H\u00f4m nay", - "weekHeader": "Tu", - "dateFormat": "d" - } - }, - "zh": { - "datepicker": { - "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": { - "datepicker": { - "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" - } - } -}); diff --git a/ui/calendar.js b/ui/calendar.js index 31de5837f77..35a8dcea8c9 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -39,6 +39,13 @@ return $.widget( "ui.calendar", { buttons: [], dateFormat: { date: "short" }, eachDay: $.noop, + labels: { + "currentText": "Today", + "datePickerRole": "date picker", + "nextText": "Next", + "prevText": "Prev", + "weekHeader": "Wk" + }, max: null, min: null, numberOfMonths: 1, @@ -59,7 +66,7 @@ return $.widget( "ui.calendar", { _create: function() { this.id = this.element.uniqueId().attr( "id" ); - this.labels = Globalize.translate( "datepicker" ); + this.labels = this.options.labels; this.buttonClickContext = this.element[ 0 ]; this.date = $.date( this.options.value, this.options.dateFormat ); @@ -463,7 +470,6 @@ 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 diff --git a/ui/i18n/datepicker-af.js b/ui/i18n/datepicker-af.js deleted file mode 100644 index ec86242d615..00000000000 --- a/ui/i18n/datepicker-af.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Afrikaans initialisation for the jQuery UI date picker plugin. */ -/* Written by Renier Pretorius. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['af'] = { - closeText: 'Selekteer', - prevText: 'Vorige', - nextText: 'Volgende', - currentText: 'Vandag', - monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie', - 'Julie','Augustus','September','Oktober','November','Desember'], - monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', - 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'], - dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'], - dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'], - dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['af']); - -return datepicker.regional['af']; - -})); diff --git a/ui/i18n/datepicker-ar-DZ.js b/ui/i18n/datepicker-ar-DZ.js deleted file mode 100644 index 5adf2476e87..00000000000 --- a/ui/i18n/datepicker-ar-DZ.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/ -/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */ - -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ar-DZ'] = { - 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-DZ']); - -return datepicker.regional['ar-DZ']; - -})); diff --git a/ui/i18n/datepicker-ar.js b/ui/i18n/datepicker-ar.js deleted file mode 100644 index c9ee84a5435..00000000000 --- a/ui/i18n/datepicker-ar.js +++ /dev/null @@ -1,38 +0,0 @@ -/* Arabic Translation for jQuery UI date picker plugin. */ -/* Used in most of Arab countries, primarily in Bahrain, Kuwait, Oman, Qatar, Saudi Arabia and the United Arab Emirates, Egypt, Sudan and Yemen. */ -/* Written by Mohammed Alshehri -- m@dralshehri.com */ - -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -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: 0, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['ar']); - -return datepicker.regional['ar']; - -})); diff --git a/ui/i18n/datepicker-az.js b/ui/i18n/datepicker-az.js deleted file mode 100644 index be87ad41151..00000000000 --- a/ui/i18n/datepicker-az.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Jamil Najafov (necefov33@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['az'] = { - closeText: 'Bağla', - prevText: '<Geri', - nextText: 'İrəli>', - currentText: 'Bugün', - monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun', - 'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'], - monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun', - 'İyul','Avq','Sen','Okt','Noy','Dek'], - dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'], - dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'], - dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'], - weekHeader: 'Hf', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['az']); - -return datepicker.regional['az']; - -})); diff --git a/ui/i18n/datepicker-be.js b/ui/i18n/datepicker-be.js deleted file mode 100644 index cac5f491125..00000000000 --- a/ui/i18n/datepicker-be.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Belarusian initialisation for the jQuery UI date picker plugin. */ -/* Written by Pavel Selitskas */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['be'] = { - closeText: 'Зачыніць', - prevText: '←Папяр.', - nextText: 'Наст.→', - currentText: 'Сёньня', - monthNames: ['Студзень','Люты','Сакавік','Красавік','Травень','Чэрвень', - 'Ліпень','Жнівень','Верасень','Кастрычнік','Лістапад','Сьнежань'], - monthNamesShort: ['Сту','Лют','Сак','Кра','Тра','Чэр', - 'Ліп','Жні','Вер','Кас','Ліс','Сьн'], - dayNames: ['нядзеля','панядзелак','аўторак','серада','чацьвер','пятніца','субота'], - dayNamesShort: ['ндз','пнд','аўт','срд','чцв','птн','сбт'], - dayNamesMin: ['Нд','Пн','Аў','Ср','Чц','Пт','Сб'], - weekHeader: 'Тд', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['be']); - -return datepicker.regional['be']; - -})); diff --git a/ui/i18n/datepicker-bg.js b/ui/i18n/datepicker-bg.js deleted file mode 100644 index 0ee1b171db9..00000000000 --- a/ui/i18n/datepicker-bg.js +++ /dev/null @@ -1,38 +0,0 @@ -/* Bulgarian initialisation for the jQuery UI date picker plugin. */ -/* Written by Stoyan Kyosev (http://svest.org). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['bg'] = { - closeText: 'затвори', - prevText: '<назад', - nextText: 'напред>', - nextBigText: '>>', - currentText: 'днес', - monthNames: ['Януари','Февруари','Март','Април','Май','Юни', - 'Юли','Август','Септември','Октомври','Ноември','Декември'], - monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни', - 'Юли','Авг','Сеп','Окт','Нов','Дек'], - dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'], - dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'], - dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'], - weekHeader: 'Wk', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['bg']); - -return datepicker.regional['bg']; - -})); diff --git a/ui/i18n/datepicker-bs.js b/ui/i18n/datepicker-bs.js deleted file mode 100644 index 142608ff3ef..00000000000 --- a/ui/i18n/datepicker-bs.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Bosnian i18n for the jQuery UI date picker plugin. */ -/* Written by Kenan Konjo. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['bs'] = { - closeText: 'Zatvori', - prevText: '<', - nextText: '>', - currentText: 'Danas', - monthNames: ['Januar','Februar','Mart','April','Maj','Juni', - 'Juli','August','Septembar','Oktobar','Novembar','Decembar'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Aug','Sep','Okt','Nov','Dec'], - dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], - dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], - dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], - weekHeader: 'Wk', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['bs']); - -return datepicker.regional['bs']; - -})); diff --git a/ui/i18n/datepicker-ca.js b/ui/i18n/datepicker-ca.js deleted file mode 100644 index ab1dbc34d14..00000000000 --- a/ui/i18n/datepicker-ca.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Inicialització en català per a l'extensió 'UI date picker' per jQuery. */ -/* Writers: (joan.leon@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ca'] = { - closeText: 'Tanca', - prevText: 'Anterior', - nextText: 'Següent', - currentText: 'Avui', - monthNames: ['gener','febrer','març','abril','maig','juny', - 'juliol','agost','setembre','octubre','novembre','desembre'], - monthNamesShort: ['gen','feb','març','abr','maig','juny', - 'jul','ag','set','oct','nov','des'], - dayNames: ['diumenge','dilluns','dimarts','dimecres','dijous','divendres','dissabte'], - dayNamesShort: ['dg','dl','dt','dc','dj','dv','ds'], - dayNamesMin: ['dg','dl','dt','dc','dj','dv','ds'], - weekHeader: 'Set', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['ca']); - -return datepicker.regional['ca']; - -})); diff --git a/ui/i18n/datepicker-cs.js b/ui/i18n/datepicker-cs.js deleted file mode 100644 index 34dae5ecded..00000000000 --- a/ui/i18n/datepicker-cs.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Czech initialisation for the jQuery UI date picker plugin. */ -/* Written by Tomas Muller (tomas@tomas-muller.net). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['cs'] = { - closeText: 'Zavřít', - prevText: '<Dříve', - nextText: 'Později>', - currentText: 'Nyní', - monthNames: ['leden','únor','březen','duben','květen','červen', - 'červenec','srpen','září','říjen','listopad','prosinec'], - monthNamesShort: ['led','úno','bře','dub','kvě','čer', - 'čvc','srp','zář','říj','lis','pro'], - dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'], - dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'], - dayNamesMin: ['ne','po','út','st','čt','pá','so'], - weekHeader: 'Týd', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['cs']); - -return datepicker.regional['cs']; - -})); diff --git a/ui/i18n/datepicker-cy-GB.js b/ui/i18n/datepicker-cy-GB.js deleted file mode 100644 index f56cbef76ff..00000000000 --- a/ui/i18n/datepicker-cy-GB.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Welsh/UK initialisation for the jQuery UI date picker plugin. */ -/* Written by William Griffiths. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['cy-GB'] = { - closeText: 'Done', - prevText: 'Prev', - nextText: 'Next', - currentText: 'Today', - monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin', - 'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'], - monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh', - 'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'], - dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'], - dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'], - dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'], - weekHeader: 'Wy', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['cy-GB']); - -return datepicker.regional['cy-GB']; - -})); diff --git a/ui/i18n/datepicker-da.js b/ui/i18n/datepicker-da.js deleted file mode 100644 index d8881e1b627..00000000000 --- a/ui/i18n/datepicker-da.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Danish initialisation for the jQuery UI date picker plugin. */ -/* Written by Jan Christensen ( deletestuff@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['da'] = { - closeText: 'Luk', - prevText: '<Forrige', - nextText: 'Næste>', - currentText: 'Idag', - monthNames: ['Januar','Februar','Marts','April','Maj','Juni', - 'Juli','August','September','Oktober','November','December'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Aug','Sep','Okt','Nov','Dec'], - dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'], - dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'], - dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'], - weekHeader: 'Uge', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['da']); - -return datepicker.regional['da']; - -})); diff --git a/ui/i18n/datepicker-de.js b/ui/i18n/datepicker-de.js deleted file mode 100644 index bc92a931b84..00000000000 --- a/ui/i18n/datepicker-de.js +++ /dev/null @@ -1,37 +0,0 @@ -/* German initialisation for the jQuery UI date picker plugin. */ -/* Written by Milian Wolff (mail@milianw.de). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['de'] = { - closeText: 'Schließen', - prevText: '<Zurück', - nextText: 'Vor>', - currentText: 'Heute', - monthNames: ['Januar','Februar','März','April','Mai','Juni', - 'Juli','August','September','Oktober','November','Dezember'], - monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', - 'Jul','Aug','Sep','Okt','Nov','Dez'], - dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], - dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], - dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], - weekHeader: 'KW', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['de']); - -return datepicker.regional['de']; - -})); diff --git a/ui/i18n/datepicker-el.js b/ui/i18n/datepicker-el.js deleted file mode 100644 index 362e248f8e4..00000000000 --- a/ui/i18n/datepicker-el.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Greek (el) initialisation for the jQuery UI date picker plugin. */ -/* Written by Alex Cicovic (http://www.alexcicovic.com) */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['el'] = { - closeText: 'Κλείσιμο', - prevText: 'Προηγούμενος', - nextText: 'Επόμενος', - currentText: 'Σήμερα', - monthNames: ['Ιανουάριος','Φεβρουάριος','Μάρτιος','Απρίλιος','Μάιος','Ιούνιος', - 'Ιούλιος','Αύγουστος','Σεπτέμβριος','Οκτώβριος','Νοέμβριος','Δεκέμβριος'], - monthNamesShort: ['Ιαν','Φεβ','Μαρ','Απρ','Μαι','Ιουν', - 'Ιουλ','Αυγ','Σεπ','Οκτ','Νοε','Δεκ'], - dayNames: ['Κυριακή','Δευτέρα','Τρίτη','Τετάρτη','Πέμπτη','Παρασκευή','Σάββατο'], - dayNamesShort: ['Κυρ','Δευ','Τρι','Τετ','Πεμ','Παρ','Σαβ'], - dayNamesMin: ['Κυ','Δε','Τρ','Τε','Πε','Πα','Σα'], - weekHeader: 'Εβδ', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['el']); - -return datepicker.regional['el']; - -})); diff --git a/ui/i18n/datepicker-en-AU.js b/ui/i18n/datepicker-en-AU.js deleted file mode 100644 index 21a7abcd5e9..00000000000 --- a/ui/i18n/datepicker-en-AU.js +++ /dev/null @@ -1,37 +0,0 @@ -/* English/Australia initialisation for the jQuery UI date picker plugin. */ -/* Based on the en-GB initialisation. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['en-AU'] = { - closeText: 'Done', - prevText: 'Prev', - nextText: 'Next', - currentText: 'Today', - monthNames: ['January','February','March','April','May','June', - 'July','August','September','October','November','December'], - monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['en-AU']); - -return datepicker.regional['en-AU']; - -})); diff --git a/ui/i18n/datepicker-en-GB.js b/ui/i18n/datepicker-en-GB.js deleted file mode 100644 index e152bbc6a28..00000000000 --- a/ui/i18n/datepicker-en-GB.js +++ /dev/null @@ -1,37 +0,0 @@ -/* English/UK initialisation for the jQuery UI date picker plugin. */ -/* Written by Stuart. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['en-GB'] = { - closeText: 'Done', - prevText: 'Prev', - nextText: 'Next', - currentText: 'Today', - monthNames: ['January','February','March','April','May','June', - 'July','August','September','October','November','December'], - monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['en-GB']); - -return datepicker.regional['en-GB']; - -})); diff --git a/ui/i18n/datepicker-en-NZ.js b/ui/i18n/datepicker-en-NZ.js deleted file mode 100644 index ea840bd1c72..00000000000 --- a/ui/i18n/datepicker-en-NZ.js +++ /dev/null @@ -1,37 +0,0 @@ -/* English/New Zealand initialisation for the jQuery UI date picker plugin. */ -/* Based on the en-GB initialisation. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['en-NZ'] = { - closeText: 'Done', - prevText: 'Prev', - nextText: 'Next', - currentText: 'Today', - monthNames: ['January','February','March','April','May','June', - 'July','August','September','October','November','December'], - monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['en-NZ']); - -return datepicker.regional['en-NZ']; - -})); diff --git a/ui/i18n/datepicker-eo.js b/ui/i18n/datepicker-eo.js deleted file mode 100644 index ebbb7238bc7..00000000000 --- a/ui/i18n/datepicker-eo.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Esperanto initialisation for the jQuery UI date picker plugin. */ -/* Written by Olivier M. (olivierweb@ifrance.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['eo'] = { - closeText: 'Fermi', - prevText: '<Anta', - nextText: 'Sekv>', - currentText: 'Nuna', - monthNames: ['Januaro','Februaro','Marto','Aprilo','Majo','Junio', - 'Julio','Aŭgusto','Septembro','Oktobro','Novembro','Decembro'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Aŭg','Sep','Okt','Nov','Dec'], - dayNames: ['Dimanĉo','Lundo','Mardo','Merkredo','Ĵaŭdo','Vendredo','Sabato'], - dayNamesShort: ['Dim','Lun','Mar','Mer','Ĵaŭ','Ven','Sab'], - dayNamesMin: ['Di','Lu','Ma','Me','Ĵa','Ve','Sa'], - weekHeader: 'Sb', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['eo']); - -return datepicker.regional['eo']; - -})); diff --git a/ui/i18n/datepicker-es.js b/ui/i18n/datepicker-es.js deleted file mode 100644 index c51475e30f6..00000000000 --- a/ui/i18n/datepicker-es.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Inicialización en español para la extensión 'UI date picker' para jQuery. */ -/* Traducido por Vester (xvester@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['es'] = { - closeText: 'Cerrar', - prevText: '<Ant', - nextText: 'Sig>', - currentText: 'Hoy', - monthNames: ['enero','febrero','marzo','abril','mayo','junio', - 'julio','agosto','septiembre','octubre','noviembre','diciembre'], - monthNamesShort: ['ene','feb','mar','abr','may','jun', - 'jul','ago','sep','oct','nov','dic'], - dayNames: ['domingo','lunes','martes','miércoles','jueves','viernes','sábado'], - dayNamesShort: ['dom','lun','mar','mié','jue','vie','sáb'], - dayNamesMin: ['D','L','M','X','J','V','S'], - weekHeader: 'Sm', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['es']); - -return datepicker.regional['es']; - -})); diff --git a/ui/i18n/datepicker-et.js b/ui/i18n/datepicker-et.js deleted file mode 100644 index 2a57212526b..00000000000 --- a/ui/i18n/datepicker-et.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Estonian initialisation for the jQuery UI date picker plugin. */ -/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['et'] = { - closeText: 'Sulge', - prevText: 'Eelnev', - nextText: 'Järgnev', - currentText: 'Täna', - monthNames: ['Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni', - 'Juuli','August','September','Oktoober','November','Detsember'], - monthNamesShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni', - 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'], - dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'], - dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'], - dayNamesMin: ['P','E','T','K','N','R','L'], - weekHeader: 'näd', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['et']); - -return datepicker.regional['et']; - -})); diff --git a/ui/i18n/datepicker-eu.js b/ui/i18n/datepicker-eu.js deleted file mode 100644 index 25b95981f8e..00000000000 --- a/ui/i18n/datepicker-eu.js +++ /dev/null @@ -1,36 +0,0 @@ -/* Karrikas-ek itzulia (karrikas@karrikas.com) */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['eu'] = { - closeText: 'Egina', - prevText: '<Aur', - nextText: 'Hur>', - currentText: 'Gaur', - monthNames: ['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina', - 'uztaila','abuztua','iraila','urria','azaroa','abendua'], - monthNamesShort: ['urt.','ots.','mar.','api.','mai.','eka.', - 'uzt.','abu.','ira.','urr.','aza.','abe.'], - dayNames: ['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'], - dayNamesShort: ['ig.','al.','ar.','az.','og.','ol.','lr.'], - dayNamesMin: ['ig','al','ar','az','og','ol','lr'], - weekHeader: 'As', - dateFormat: 'yy-mm-dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['eu']); - -return datepicker.regional['eu']; - -})); diff --git a/ui/i18n/datepicker-fa.js b/ui/i18n/datepicker-fa.js deleted file mode 100644 index 71f8a285204..00000000000 --- a/ui/i18n/datepicker-fa.js +++ /dev/null @@ -1,73 +0,0 @@ -/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */ -/* Javad Mowlanezhad -- jmowla@gmail.com */ -/* Jalali calendar should supported soon! (Its implemented but I have to test it) */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['fa'] = { - closeText: 'بستن', - prevText: '<قبلی', - nextText: 'بعدی>', - currentText: 'امروز', - monthNames: [ - 'ژانویه', - 'فوریه', - 'مارس', - 'آوریل', - 'مه', - 'ژوئن', - 'ژوئیه', - 'اوت', - 'سپتامبر', - 'اکتبر', - 'نوامبر', - 'دسامبر' - ], - monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], - dayNames: [ - 'يکشنبه', - 'دوشنبه', - 'سه‌شنبه', - 'چهارشنبه', - 'پنجشنبه', - 'جمعه', - 'شنبه' - ], - dayNamesShort: [ - 'ی', - 'د', - 'س', - 'چ', - 'پ', - 'ج', - 'ش' - ], - dayNamesMin: [ - 'ی', - 'د', - 'س', - 'چ', - 'پ', - 'ج', - 'ش' - ], - weekHeader: 'هف', - dateFormat: 'yy/mm/dd', - firstDay: 6, - isRTL: true, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['fa']); - -return datepicker.regional['fa']; - -})); diff --git a/ui/i18n/datepicker-fi.js b/ui/i18n/datepicker-fi.js deleted file mode 100644 index eac170496f9..00000000000 --- a/ui/i18n/datepicker-fi.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Finnish initialisation for the jQuery UI date picker plugin. */ -/* Written by Harri Kilpiö (harrikilpio@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['fi'] = { - closeText: 'Sulje', - prevText: '«Edellinen', - nextText: 'Seuraava»', - currentText: 'Tänään', - monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu', - 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'], - monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä', - 'Heinä','Elo','Syys','Loka','Marras','Joulu'], - dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','La'], - dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'], - dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'], - weekHeader: 'Vk', - dateFormat: 'd.m.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['fi']); - -return datepicker.regional['fi']; - -})); diff --git a/ui/i18n/datepicker-fo.js b/ui/i18n/datepicker-fo.js deleted file mode 100644 index 1754f7be790..00000000000 --- a/ui/i18n/datepicker-fo.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Faroese initialisation for the jQuery UI date picker plugin */ -/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['fo'] = { - closeText: 'Lat aftur', - prevText: '<Fyrra', - nextText: 'Næsta>', - currentText: 'Í dag', - monthNames: ['Januar','Februar','Mars','Apríl','Mei','Juni', - 'Juli','August','September','Oktober','November','Desember'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', - 'Jul','Aug','Sep','Okt','Nov','Des'], - dayNames: ['Sunnudagur','Mánadagur','Týsdagur','Mikudagur','Hósdagur','Fríggjadagur','Leyardagur'], - dayNamesShort: ['Sun','Mán','Týs','Mik','Hós','Frí','Ley'], - dayNamesMin: ['Su','Má','Tý','Mi','Hó','Fr','Le'], - weekHeader: 'Vk', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['fo']); - -return datepicker.regional['fo']; - -})); diff --git a/ui/i18n/datepicker-fr-CA.js b/ui/i18n/datepicker-fr-CA.js deleted file mode 100644 index ca0f3eb11e6..00000000000 --- a/ui/i18n/datepicker-fr-CA.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Canadian-French initialisation for the jQuery UI date picker plugin. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['fr-CA'] = { - 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: 'yy-mm-dd', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: '' -}; -datepicker.setDefaults(datepicker.regional['fr-CA']); - -return datepicker.regional['fr-CA']; - -})); diff --git a/ui/i18n/datepicker-fr-CH.js b/ui/i18n/datepicker-fr-CH.js deleted file mode 100644 index ddc56fbfc4e..00000000000 --- a/ui/i18n/datepicker-fr-CH.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Swiss-French initialisation for the jQuery UI date picker plugin. */ -/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['fr-CH'] = { - closeText: 'Fermer', - prevText: '<Préc', - nextText: 'Suiv>', - currentText: 'Courant', - 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: 'Sm', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['fr-CH']); - -return datepicker.regional['fr-CH']; - -})); diff --git a/ui/i18n/datepicker-fr.js b/ui/i18n/datepicker-fr.js deleted file mode 100644 index 6b6e0b35fc7..00000000000 --- a/ui/i18n/datepicker-fr.js +++ /dev/null @@ -1,39 +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([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -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', 'avr.', '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']); - -return datepicker.regional['fr']; - -})); diff --git a/ui/i18n/datepicker-gl.js b/ui/i18n/datepicker-gl.js deleted file mode 100644 index ed5b2d2fc2f..00000000000 --- a/ui/i18n/datepicker-gl.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Galician localization for 'UI date picker' jQuery extension. */ -/* Translated by Jorge Barreiro . */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['gl'] = { - closeText: 'Pechar', - prevText: '<Ant', - nextText: 'Seg>', - currentText: 'Hoxe', - monthNames: ['Xaneiro','Febreiro','Marzo','Abril','Maio','Xuño', - 'Xullo','Agosto','Setembro','Outubro','Novembro','Decembro'], - monthNamesShort: ['Xan','Feb','Mar','Abr','Mai','Xuñ', - 'Xul','Ago','Set','Out','Nov','Dec'], - dayNames: ['Domingo','Luns','Martes','Mércores','Xoves','Venres','Sábado'], - dayNamesShort: ['Dom','Lun','Mar','Mér','Xov','Ven','Sáb'], - dayNamesMin: ['Do','Lu','Ma','Mé','Xo','Ve','Sá'], - weekHeader: 'Sm', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['gl']); - -return datepicker.regional['gl']; - -})); diff --git a/ui/i18n/datepicker-he.js b/ui/i18n/datepicker-he.js deleted file mode 100644 index 9b166135298..00000000000 --- a/ui/i18n/datepicker-he.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Hebrew initialisation for the UI Datepicker 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([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -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']); - -return datepicker.regional['he']; - -})); diff --git a/ui/i18n/datepicker-hi.js b/ui/i18n/datepicker-hi.js deleted file mode 100644 index f20a900cab8..00000000000 --- a/ui/i18n/datepicker-hi.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Hindi initialisation for the jQuery UI date picker plugin. */ -/* Written by Michael Dawart. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['hi'] = { - closeText: 'बंद', - prevText: 'पिछला', - nextText: 'अगला', - currentText: 'आज', - monthNames: ['जनवरी ','फरवरी','मार्च','अप्रेल','मई','जून', - 'जूलाई','अगस्त ','सितम्बर','अक्टूबर','नवम्बर','दिसम्बर'], - monthNamesShort: ['जन', 'फर', 'मार्च', 'अप्रेल', 'मई', 'जून', - 'जूलाई', 'अग', 'सित', 'अक्ट', 'नव', 'दि'], - dayNames: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'], - dayNamesShort: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], - dayNamesMin: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], - weekHeader: 'हफ्ता', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['hi']); - -return datepicker.regional['hi']; - -})); diff --git a/ui/i18n/datepicker-hr.js b/ui/i18n/datepicker-hr.js deleted file mode 100644 index e8b0414b561..00000000000 --- a/ui/i18n/datepicker-hr.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Croatian i18n for the jQuery UI date picker plugin. */ -/* Written by Vjekoslav Nesek. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['hr'] = { - closeText: 'Zatvori', - prevText: '<', - nextText: '>', - currentText: 'Danas', - monthNames: ['Siječanj','Veljača','Ožujak','Travanj','Svibanj','Lipanj', - 'Srpanj','Kolovoz','Rujan','Listopad','Studeni','Prosinac'], - monthNamesShort: ['Sij','Velj','Ožu','Tra','Svi','Lip', - 'Srp','Kol','Ruj','Lis','Stu','Pro'], - dayNames: ['Nedjelja','Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], - dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], - dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], - weekHeader: 'Tje', - dateFormat: 'dd.mm.yy.', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['hr']); - -return datepicker.regional['hr']; - -})); diff --git a/ui/i18n/datepicker-hu.js b/ui/i18n/datepicker-hu.js deleted file mode 100644 index 8ea85506e79..00000000000 --- a/ui/i18n/datepicker-hu.js +++ /dev/null @@ -1,36 +0,0 @@ -/* Hungarian initialisation for the jQuery UI date picker plugin. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['hu'] = { - closeText: 'bezár', - prevText: 'vissza', - nextText: 'előre', - currentText: 'ma', - monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június', - 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'], - monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', - 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'], - dayNames: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'], - dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'], - dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'], - weekHeader: 'Hét', - dateFormat: 'yy.mm.dd.', - firstDay: 1, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['hu']); - -return datepicker.regional['hu']; - -})); diff --git a/ui/i18n/datepicker-hy.js b/ui/i18n/datepicker-hy.js deleted file mode 100644 index ab6e362d6c7..00000000000 --- a/ui/i18n/datepicker-hy.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['hy'] = { - closeText: 'Փակել', - prevText: '<Նախ.', - nextText: 'Հաջ.>', - currentText: 'Այսօր', - monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս', - 'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'], - monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս', - 'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'], - dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'], - dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], - dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], - weekHeader: 'ՇԲՏ', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['hy']); - -return datepicker.regional['hy']; - -})); diff --git a/ui/i18n/datepicker-id.js b/ui/i18n/datepicker-id.js deleted file mode 100644 index 0db693fafc8..00000000000 --- a/ui/i18n/datepicker-id.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Indonesian initialisation for the jQuery UI date picker plugin. */ -/* Written by Deden Fathurahman (dedenf@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['id'] = { - closeText: 'Tutup', - prevText: '<mundur', - nextText: 'maju>', - currentText: 'hari ini', - monthNames: ['Januari','Februari','Maret','April','Mei','Juni', - 'Juli','Agustus','September','Oktober','Nopember','Desember'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', - 'Jul','Agus','Sep','Okt','Nop','Des'], - dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'], - dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'], - dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'], - weekHeader: 'Mg', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['id']); - -return datepicker.regional['id']; - -})); diff --git a/ui/i18n/datepicker-is.js b/ui/i18n/datepicker-is.js deleted file mode 100644 index 16bc79ad8e5..00000000000 --- a/ui/i18n/datepicker-is.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Icelandic initialisation for the jQuery UI date picker plugin. */ -/* Written by Haukur H. Thorsson (haukur@eskill.is). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['is'] = { - closeText: 'Loka', - prevText: '< Fyrri', - nextText: 'Næsti >', - currentText: 'Í dag', - monthNames: ['Janúar','Febrúar','Mars','Apríl','Maí','Júní', - 'Júlí','Ágúst','September','Október','Nóvember','Desember'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maí','Jún', - 'Júl','Ágú','Sep','Okt','Nóv','Des'], - dayNames: ['Sunnudagur','Mánudagur','Þriðjudagur','Miðvikudagur','Fimmtudagur','Föstudagur','Laugardagur'], - dayNamesShort: ['Sun','Mán','Þri','Mið','Fim','Fös','Lau'], - dayNamesMin: ['Su','Má','Þr','Mi','Fi','Fö','La'], - weekHeader: 'Vika', - dateFormat: 'dd.mm.yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['is']); - -return datepicker.regional['is']; - -})); diff --git a/ui/i18n/datepicker-it-CH.js b/ui/i18n/datepicker-it-CH.js deleted file mode 100644 index 30d5a418081..00000000000 --- a/ui/i18n/datepicker-it-CH.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Italian initialisation for the jQuery UI date picker plugin. */ -/* Written by Antonello Pasella (antonello.pasella@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['it-CH'] = { - closeText: 'Chiudi', - prevText: '<Prec', - nextText: 'Succ>', - currentText: 'Oggi', - monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno', - 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'], - monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu', - 'Lug','Ago','Set','Ott','Nov','Dic'], - dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'], - dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'], - dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'], - weekHeader: 'Sm', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['it-CH']); - -return datepicker.regional['it-CH']; - -})); diff --git a/ui/i18n/datepicker-it.js b/ui/i18n/datepicker-it.js deleted file mode 100644 index 4d4d62f9b61..00000000000 --- a/ui/i18n/datepicker-it.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Italian initialisation for the jQuery UI date picker plugin. */ -/* Written by Antonello Pasella (antonello.pasella@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['it'] = { - closeText: 'Chiudi', - prevText: '<Prec', - nextText: 'Succ>', - currentText: 'Oggi', - monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno', - 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'], - monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu', - 'Lug','Ago','Set','Ott','Nov','Dic'], - dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'], - dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'], - dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'], - weekHeader: 'Sm', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['it']); - -return datepicker.regional['it']; - -})); diff --git a/ui/i18n/datepicker-ja.js b/ui/i18n/datepicker-ja.js deleted file mode 100644 index 381f41b5d70..00000000000 --- a/ui/i18n/datepicker-ja.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Japanese initialisation for the jQuery UI date picker plugin. */ -/* Written by Kentaro SATO (kentaro@ranvis.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ja'] = { - closeText: '閉じる', - prevText: '<前', - nextText: '次>', - currentText: '今日', - monthNames: ['1月','2月','3月','4月','5月','6月', - '7月','8月','9月','10月','11月','12月'], - monthNamesShort: ['1月','2月','3月','4月','5月','6月', - '7月','8月','9月','10月','11月','12月'], - dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'], - dayNamesShort: ['日','月','火','水','木','金','土'], - dayNamesMin: ['日','月','火','水','木','金','土'], - weekHeader: '週', - dateFormat: 'yy/mm/dd', - firstDay: 0, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '年'}; -datepicker.setDefaults(datepicker.regional['ja']); - -return datepicker.regional['ja']; - -})); diff --git a/ui/i18n/datepicker-ka.js b/ui/i18n/datepicker-ka.js deleted file mode 100644 index 69103542ba7..00000000000 --- a/ui/i18n/datepicker-ka.js +++ /dev/null @@ -1,35 +0,0 @@ -/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Lado Lomidze (lado.lomidze@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ka'] = { - closeText: 'დახურვა', - prevText: '< წინა', - nextText: 'შემდეგი >', - currentText: 'დღეს', - monthNames: ['იანვარი','თებერვალი','მარტი','აპრილი','მაისი','ივნისი', 'ივლისი','აგვისტო','სექტემბერი','ოქტომბერი','ნოემბერი','დეკემბერი'], - monthNamesShort: ['იან','თებ','მარ','აპრ','მაი','ივნ', 'ივლ','აგვ','სექ','ოქტ','ნოე','დეკ'], - dayNames: ['კვირა','ორშაბათი','სამშაბათი','ოთხშაბათი','ხუთშაბათი','პარასკევი','შაბათი'], - dayNamesShort: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], - dayNamesMin: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], - weekHeader: 'კვირა', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['ka']); - -return datepicker.regional['ka']; - -})); diff --git a/ui/i18n/datepicker-kk.js b/ui/i18n/datepicker-kk.js deleted file mode 100644 index e85fd8354a5..00000000000 --- a/ui/i18n/datepicker-kk.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['kk'] = { - closeText: 'Жабу', - prevText: '<Алдыңғы', - nextText: 'Келесі>', - currentText: 'Бүгін', - monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым', - 'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'], - monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау', - 'Шіл','Там','Қыр','Қаз','Қар','Жел'], - dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'], - dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'], - dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'], - weekHeader: 'Не', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['kk']); - -return datepicker.regional['kk']; - -})); diff --git a/ui/i18n/datepicker-km.js b/ui/i18n/datepicker-km.js deleted file mode 100644 index 599a4771393..00000000000 --- a/ui/i18n/datepicker-km.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Khmer initialisation for the jQuery calendar extension. */ -/* Written by Chandara Om (chandara.teacher@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['km'] = { - closeText: 'ធ្វើ​រួច', - prevText: 'មុន', - nextText: 'បន្ទាប់', - currentText: 'ថ្ងៃ​នេះ', - monthNames: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', - 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], - monthNamesShort: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', - 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], - dayNames: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៍', 'សុក្រ', 'សៅរ៍'], - dayNamesShort: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], - dayNamesMin: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], - weekHeader: 'សប្ដាហ៍', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['km']); - -return datepicker.regional['km']; - -})); diff --git a/ui/i18n/datepicker-ko.js b/ui/i18n/datepicker-ko.js deleted file mode 100644 index 991b5727e02..00000000000 --- a/ui/i18n/datepicker-ko.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Korean initialisation for the jQuery calendar extension. */ -/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ko'] = { - closeText: '닫기', - prevText: '이전달', - nextText: '다음달', - currentText: '오늘', - monthNames: ['1월','2월','3월','4월','5월','6월', - '7월','8월','9월','10월','11월','12월'], - monthNamesShort: ['1월','2월','3월','4월','5월','6월', - '7월','8월','9월','10월','11월','12월'], - dayNames: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'], - dayNamesShort: ['일','월','화','수','목','금','토'], - dayNamesMin: ['일','월','화','수','목','금','토'], - weekHeader: 'Wk', - dateFormat: 'yy-mm-dd', - firstDay: 0, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '년'}; -datepicker.setDefaults(datepicker.regional['ko']); - -return datepicker.regional['ko']; - -})); diff --git a/ui/i18n/datepicker-ky.js b/ui/i18n/datepicker-ky.js deleted file mode 100644 index a09bc0c6aa2..00000000000 --- a/ui/i18n/datepicker-ky.js +++ /dev/null @@ -1,38 +0,0 @@ -/* Kyrgyz (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Sergey Kartashov (ebishkek@yandex.ru). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ky'] = { - closeText: 'Жабуу', - prevText: '<Мур', - nextText: 'Кий>', - currentText: 'Бүгүн', - monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь', - 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], - monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', - 'Июл','Авг','Сен','Окт','Ноя','Дек'], - dayNames: ['жекшемби', 'дүйшөмбү', 'шейшемби', 'шаршемби', 'бейшемби', 'жума', 'ишемби'], - dayNamesShort: ['жек', 'дүй', 'шей', 'шар', 'бей', 'жум', 'ише'], - dayNamesMin: ['Жк','Дш','Шш','Шр','Бш','Жм','Иш'], - weekHeader: 'Жум', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: '' -}; -datepicker.setDefaults(datepicker.regional['ky']); - -return datepicker.regional['ky']; - -})); diff --git a/ui/i18n/datepicker-lb.js b/ui/i18n/datepicker-lb.js deleted file mode 100644 index 4f2e414be9c..00000000000 --- a/ui/i18n/datepicker-lb.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Luxembourgish initialisation for the jQuery UI date picker plugin. */ -/* Written by Michel Weimerskirch */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['lb'] = { - closeText: 'Fäerdeg', - prevText: 'Zréck', - nextText: 'Weider', - currentText: 'Haut', - monthNames: ['Januar','Februar','Mäerz','Abrëll','Mee','Juni', - 'Juli','August','September','Oktober','November','Dezember'], - monthNamesShort: ['Jan', 'Feb', 'Mäe', 'Abr', 'Mee', 'Jun', - 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], - dayNames: ['Sonndeg', 'Méindeg', 'Dënschdeg', 'Mëttwoch', 'Donneschdeg', 'Freideg', 'Samschdeg'], - dayNamesShort: ['Son', 'Méi', 'Dën', 'Mët', 'Don', 'Fre', 'Sam'], - dayNamesMin: ['So','Mé','Dë','Më','Do','Fr','Sa'], - weekHeader: 'W', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['lb']); - -return datepicker.regional['lb']; - -})); diff --git a/ui/i18n/datepicker-lt.js b/ui/i18n/datepicker-lt.js deleted file mode 100644 index 60ccbefe7a1..00000000000 --- a/ui/i18n/datepicker-lt.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* @author Arturas Paleicikas */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['lt'] = { - closeText: 'Uždaryti', - prevText: '<Atgal', - nextText: 'Pirmyn>', - currentText: 'Šiandien', - monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis', - 'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'], - monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir', - 'Lie','Rugp','Rugs','Spa','Lap','Gru'], - dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'], - dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'], - dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'], - weekHeader: 'SAV', - dateFormat: 'yy-mm-dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['lt']); - -return datepicker.regional['lt']; - -})); diff --git a/ui/i18n/datepicker-lv.js b/ui/i18n/datepicker-lv.js deleted file mode 100644 index b9e28853535..00000000000 --- a/ui/i18n/datepicker-lv.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* @author Arturas Paleicikas */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['lv'] = { - closeText: 'Aizvērt', - prevText: 'Iepr.', - nextText: 'Nāk.', - currentText: 'Šodien', - monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs', - 'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn', - 'Jūl','Aug','Sep','Okt','Nov','Dec'], - dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'], - dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'], - dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'], - weekHeader: 'Ned.', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['lv']); - -return datepicker.regional['lv']; - -})); diff --git a/ui/i18n/datepicker-mk.js b/ui/i18n/datepicker-mk.js deleted file mode 100644 index 15942e28107..00000000000 --- a/ui/i18n/datepicker-mk.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Macedonian i18n for the jQuery UI date picker plugin. */ -/* Written by Stojce Slavkovski. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['mk'] = { - closeText: 'Затвори', - prevText: '<', - nextText: '>', - currentText: 'Денес', - monthNames: ['Јануари','Февруари','Март','Април','Мај','Јуни', - 'Јули','Август','Септември','Октомври','Ноември','Декември'], - monthNamesShort: ['Јан','Фев','Мар','Апр','Мај','Јун', - 'Јул','Авг','Сеп','Окт','Ное','Дек'], - dayNames: ['Недела','Понеделник','Вторник','Среда','Четврток','Петок','Сабота'], - dayNamesShort: ['Нед','Пон','Вто','Сре','Чет','Пет','Саб'], - dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Са'], - weekHeader: 'Сед', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['mk']); - -return datepicker.regional['mk']; - -})); diff --git a/ui/i18n/datepicker-ml.js b/ui/i18n/datepicker-ml.js deleted file mode 100644 index ffcc15fa96c..00000000000 --- a/ui/i18n/datepicker-ml.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Saji Nediyanchath (saji89@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ml'] = { - closeText: 'ശരി', - prevText: 'മുന്നത്തെ', - nextText: 'അടുത്തത് ', - currentText: 'ഇന്ന്', - monthNames: ['ജനുവരി','ഫെബ്രുവരി','മാര്‍ച്ച്','ഏപ്രില്‍','മേയ്','ജൂണ്‍', - 'ജൂലൈ','ആഗസ്റ്റ്','സെപ്റ്റംബര്‍','ഒക്ടോബര്‍','നവംബര്‍','ഡിസംബര്‍'], - monthNamesShort: ['ജനു', 'ഫെബ്', 'മാര്‍', 'ഏപ്രി', 'മേയ്', 'ജൂണ്‍', - 'ജൂലാ', 'ആഗ', 'സെപ്', 'ഒക്ടോ', 'നവം', 'ഡിസ'], - dayNames: ['ഞായര്‍', 'തിങ്കള്‍', 'ചൊവ്വ', 'ബുധന്‍', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], - dayNamesShort: ['ഞായ', 'തിങ്ക', 'ചൊവ്വ', 'ബുധ', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], - dayNamesMin: ['ഞാ','തി','ചൊ','ബു','വ്യാ','വെ','ശ'], - weekHeader: 'ആ', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['ml']); - -return datepicker.regional['ml']; - -})); diff --git a/ui/i18n/datepicker-ms.js b/ui/i18n/datepicker-ms.js deleted file mode 100644 index d452df3efbb..00000000000 --- a/ui/i18n/datepicker-ms.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Malaysian initialisation for the jQuery UI date picker plugin. */ -/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ms'] = { - closeText: 'Tutup', - prevText: '<Sebelum', - nextText: 'Selepas>', - currentText: 'hari ini', - monthNames: ['Januari','Februari','Mac','April','Mei','Jun', - 'Julai','Ogos','September','Oktober','November','Disember'], - monthNamesShort: ['Jan','Feb','Mac','Apr','Mei','Jun', - 'Jul','Ogo','Sep','Okt','Nov','Dis'], - dayNames: ['Ahad','Isnin','Selasa','Rabu','Khamis','Jumaat','Sabtu'], - dayNamesShort: ['Aha','Isn','Sel','Rab','kha','Jum','Sab'], - dayNamesMin: ['Ah','Is','Se','Ra','Kh','Ju','Sa'], - weekHeader: 'Mg', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['ms']); - -return datepicker.regional['ms']; - -})); diff --git a/ui/i18n/datepicker-nb.js b/ui/i18n/datepicker-nb.js deleted file mode 100644 index afe429f471b..00000000000 --- a/ui/i18n/datepicker-nb.js +++ /dev/null @@ -1,36 +0,0 @@ -/* Norwegian Bokmål initialisation for the jQuery UI date picker plugin. */ -/* Written by Bjørn Johansen (post@bjornjohansen.no). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['nb'] = { - closeText: 'Lukk', - prevText: '«Forrige', - nextText: 'Neste»', - currentText: 'I dag', - monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], - monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], - dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], - dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], - dayNamesMin: ['sø','ma','ti','on','to','fr','lø'], - weekHeader: 'Uke', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: '' -}; -datepicker.setDefaults(datepicker.regional['nb']); - -return datepicker.regional['nb']; - -})); diff --git a/ui/i18n/datepicker-nl-BE.js b/ui/i18n/datepicker-nl-BE.js deleted file mode 100644 index 47634d920ea..00000000000 --- a/ui/i18n/datepicker-nl-BE.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */ -/* David De Sloovere @DavidDeSloovere */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['nl-BE'] = { - closeText: 'Sluiten', - prevText: '←', - nextText: '→', - currentText: 'Vandaag', - monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', - 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], - monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', - 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], - dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], - dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], - dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['nl-BE']); - -return datepicker.regional['nl-BE']; - -})); diff --git a/ui/i18n/datepicker-nl.js b/ui/i18n/datepicker-nl.js deleted file mode 100644 index 9be14bb2aa6..00000000000 --- a/ui/i18n/datepicker-nl.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Mathias Bynens */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional.nl = { - closeText: 'Sluiten', - prevText: '←', - nextText: '→', - currentText: 'Vandaag', - monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', - 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], - monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', - 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], - dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], - dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], - dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], - weekHeader: 'Wk', - dateFormat: 'dd-mm-yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional.nl); - -return datepicker.regional.nl; - -})); diff --git a/ui/i18n/datepicker-nn.js b/ui/i18n/datepicker-nn.js deleted file mode 100644 index 37965e82278..00000000000 --- a/ui/i18n/datepicker-nn.js +++ /dev/null @@ -1,36 +0,0 @@ -/* Norwegian Nynorsk initialisation for the jQuery UI date picker plugin. */ -/* Written by Bjørn Johansen (post@bjornjohansen.no). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['nn'] = { - closeText: 'Lukk', - prevText: '«Førre', - nextText: 'Neste»', - currentText: 'I dag', - monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], - monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], - dayNamesShort: ['sun','mån','tys','ons','tor','fre','lau'], - dayNames: ['sundag','måndag','tysdag','onsdag','torsdag','fredag','laurdag'], - dayNamesMin: ['su','må','ty','on','to','fr','la'], - weekHeader: 'Veke', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: '' -}; -datepicker.setDefaults(datepicker.regional['nn']); - -return datepicker.regional['nn']; - -})); diff --git a/ui/i18n/datepicker-no.js b/ui/i18n/datepicker-no.js deleted file mode 100644 index 8917b6a26c3..00000000000 --- a/ui/i18n/datepicker-no.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Norwegian initialisation for the jQuery UI date picker plugin. */ -/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */ - -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['no'] = { - closeText: 'Lukk', - prevText: '«Forrige', - nextText: 'Neste»', - currentText: 'I dag', - monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], - monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], - dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], - dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], - dayNamesMin: ['sø','ma','ti','on','to','fr','lø'], - weekHeader: 'Uke', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: '' -}; -datepicker.setDefaults(datepicker.regional['no']); - -return datepicker.regional['no']; - -})); diff --git a/ui/i18n/datepicker-pl.js b/ui/i18n/datepicker-pl.js deleted file mode 100644 index a04de8e8a00..00000000000 --- a/ui/i18n/datepicker-pl.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Polish initialisation for the jQuery UI date picker plugin. */ -/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['pl'] = { - closeText: 'Zamknij', - prevText: '<Poprzedni', - nextText: 'Następny>', - currentText: 'Dziś', - monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec', - 'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'], - monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze', - 'Lip','Sie','Wrz','Pa','Lis','Gru'], - dayNames: ['Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'], - dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'], - dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'], - weekHeader: 'Tydz', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['pl']); - -return datepicker.regional['pl']; - -})); diff --git a/ui/i18n/datepicker-pt-BR.js b/ui/i18n/datepicker-pt-BR.js deleted file mode 100644 index d6bd8990715..00000000000 --- a/ui/i18n/datepicker-pt-BR.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Brazilian initialisation for the jQuery UI date picker plugin. */ -/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['pt-BR'] = { - closeText: 'Fechar', - prevText: '<Anterior', - nextText: 'Próximo>', - currentText: 'Hoje', - monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', - 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], - monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', - 'Jul','Ago','Set','Out','Nov','Dez'], - dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], - dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], - dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], - weekHeader: 'Sm', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['pt-BR']); - -return datepicker.regional['pt-BR']; - -})); diff --git a/ui/i18n/datepicker-pt.js b/ui/i18n/datepicker-pt.js deleted file mode 100644 index bb46838e2da..00000000000 --- a/ui/i18n/datepicker-pt.js +++ /dev/null @@ -1,36 +0,0 @@ -/* Portuguese initialisation for the jQuery UI date picker plugin. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['pt'] = { - closeText: 'Fechar', - prevText: 'Anterior', - nextText: 'Seguinte', - currentText: 'Hoje', - monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', - 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], - monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', - 'Jul','Ago','Set','Out','Nov','Dez'], - dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], - dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], - dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], - weekHeader: 'Sem', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['pt']); - -return datepicker.regional['pt']; - -})); diff --git a/ui/i18n/datepicker-rm.js b/ui/i18n/datepicker-rm.js deleted file mode 100644 index 1e39eb0ee19..00000000000 --- a/ui/i18n/datepicker-rm.js +++ /dev/null @@ -1,35 +0,0 @@ -/* Romansh initialisation for the jQuery UI date picker plugin. */ -/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['rm'] = { - closeText: 'Serrar', - prevText: '<Suandant', - nextText: 'Precedent>', - currentText: 'Actual', - monthNames: ['Schaner','Favrer','Mars','Avrigl','Matg','Zercladur', 'Fanadur','Avust','Settember','October','November','December'], - monthNamesShort: ['Scha','Fev','Mar','Avr','Matg','Zer', 'Fan','Avu','Sett','Oct','Nov','Dec'], - dayNames: ['Dumengia','Glindesdi','Mardi','Mesemna','Gievgia','Venderdi','Sonda'], - dayNamesShort: ['Dum','Gli','Mar','Mes','Gie','Ven','Som'], - dayNamesMin: ['Du','Gl','Ma','Me','Gi','Ve','So'], - weekHeader: 'emna', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['rm']); - -return datepicker.regional['rm']; - -})); diff --git a/ui/i18n/datepicker-ro.js b/ui/i18n/datepicker-ro.js deleted file mode 100644 index 66ee1099f4d..00000000000 --- a/ui/i18n/datepicker-ro.js +++ /dev/null @@ -1,40 +0,0 @@ -/* Romanian initialisation for the jQuery UI date picker plugin. - * - * Written by Edmond L. (ll_edmond@walla.com) - * and Ionut G. Stan (ionut.g.stan@gmail.com) - */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ro'] = { - closeText: 'Închide', - prevText: '« Luna precedentă', - nextText: 'Luna următoare »', - currentText: 'Azi', - monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie', - 'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'], - monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', - 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - dayNames: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'], - dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'], - dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sâ'], - weekHeader: 'Săpt', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['ro']); - -return datepicker.regional['ro']; - -})); diff --git a/ui/i18n/datepicker-ru.js b/ui/i18n/datepicker-ru.js deleted file mode 100644 index c3fda5d5943..00000000000 --- a/ui/i18n/datepicker-ru.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Andrew Stromnov (stromnov@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ru'] = { - closeText: 'Закрыть', - prevText: '<Пред', - nextText: 'След>', - currentText: 'Сегодня', - monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь', - 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], - monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', - 'Июл','Авг','Сен','Окт','Ноя','Дек'], - dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], - dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], - dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'], - weekHeader: 'Нед', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['ru']); - -return datepicker.regional['ru']; - -})); diff --git a/ui/i18n/datepicker-sk.js b/ui/i18n/datepicker-sk.js deleted file mode 100644 index 1f924f820a0..00000000000 --- a/ui/i18n/datepicker-sk.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Slovak initialisation for the jQuery UI date picker plugin. */ -/* Written by Vojtech Rinik (vojto@hmm.sk). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['sk'] = { - closeText: 'Zavrieť', - prevText: '<Predchádzajúci', - nextText: 'Nasledujúci>', - currentText: 'Dnes', - monthNames: ['január','február','marec','apríl','máj','jún', - 'júl','august','september','október','november','december'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún', - 'Júl','Aug','Sep','Okt','Nov','Dec'], - dayNames: ['nedeľa','pondelok','utorok','streda','štvrtok','piatok','sobota'], - dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'], - dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'], - weekHeader: 'Ty', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['sk']); - -return datepicker.regional['sk']; - -})); diff --git a/ui/i18n/datepicker-sl.js b/ui/i18n/datepicker-sl.js deleted file mode 100644 index 88d7f2b1953..00000000000 --- a/ui/i18n/datepicker-sl.js +++ /dev/null @@ -1,38 +0,0 @@ -/* Slovenian initialisation for the jQuery UI date picker plugin. */ -/* Written by Jaka Jancar (jaka@kubje.org). */ -/* c = č, s = š z = ž C = Č S = Š Z = Ž */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['sl'] = { - closeText: 'Zapri', - prevText: '<Prejšnji', - nextText: 'Naslednji>', - currentText: 'Trenutni', - monthNames: ['Januar','Februar','Marec','April','Maj','Junij', - 'Julij','Avgust','September','Oktober','November','December'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Avg','Sep','Okt','Nov','Dec'], - dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','Četrtek','Petek','Sobota'], - dayNamesShort: ['Ned','Pon','Tor','Sre','Čet','Pet','Sob'], - dayNamesMin: ['Ne','Po','To','Sr','Če','Pe','So'], - weekHeader: 'Teden', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['sl']); - -return datepicker.regional['sl']; - -})); diff --git a/ui/i18n/datepicker-sq.js b/ui/i18n/datepicker-sq.js deleted file mode 100644 index f88c22c56c0..00000000000 --- a/ui/i18n/datepicker-sq.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Albanian initialisation for the jQuery UI date picker plugin. */ -/* Written by Flakron Bytyqi (flakron@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['sq'] = { - closeText: 'mbylle', - prevText: '<mbrapa', - nextText: 'Përpara>', - currentText: 'sot', - monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor', - 'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'], - monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer', - 'Kor','Gus','Sht','Tet','Nën','Dhj'], - dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'], - dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'], - dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'], - weekHeader: 'Ja', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['sq']); - -return datepicker.regional['sq']; - -})); diff --git a/ui/i18n/datepicker-sr-SR.js b/ui/i18n/datepicker-sr-SR.js deleted file mode 100644 index 239e940988c..00000000000 --- a/ui/i18n/datepicker-sr-SR.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Serbian i18n for the jQuery UI date picker plugin. */ -/* Written by Dejan Dimić. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['sr-SR'] = { - closeText: 'Zatvori', - prevText: '<', - nextText: '>', - currentText: 'Danas', - monthNames: ['Januar','Februar','Mart','April','Maj','Jun', - 'Jul','Avgust','Septembar','Oktobar','Novembar','Decembar'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Avg','Sep','Okt','Nov','Dec'], - dayNames: ['Nedelja','Ponedeljak','Utorak','Sreda','Četvrtak','Petak','Subota'], - dayNamesShort: ['Ned','Pon','Uto','Sre','Čet','Pet','Sub'], - dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], - weekHeader: 'Sed', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['sr-SR']); - -return datepicker.regional['sr-SR']; - -})); diff --git a/ui/i18n/datepicker-sr.js b/ui/i18n/datepicker-sr.js deleted file mode 100644 index 0f6d9e240dc..00000000000 --- a/ui/i18n/datepicker-sr.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Serbian i18n for the jQuery UI date picker plugin. */ -/* Written by Dejan Dimić. */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['sr'] = { - closeText: 'Затвори', - prevText: '<', - nextText: '>', - currentText: 'Данас', - monthNames: ['Јануар','Фебруар','Март','Април','Мај','Јун', - 'Јул','Август','Септембар','Октобар','Новембар','Децембар'], - monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун', - 'Јул','Авг','Сеп','Окт','Нов','Дец'], - dayNames: ['Недеља','Понедељак','Уторак','Среда','Четвртак','Петак','Субота'], - dayNamesShort: ['Нед','Пон','Уто','Сре','Чет','Пет','Суб'], - dayNamesMin: ['Не','По','Ут','Ср','Че','Пе','Су'], - weekHeader: 'Сед', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['sr']); - -return datepicker.regional['sr']; - -})); diff --git a/ui/i18n/datepicker-sv.js b/ui/i18n/datepicker-sv.js deleted file mode 100644 index 4874738904a..00000000000 --- a/ui/i18n/datepicker-sv.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Swedish initialisation for the jQuery UI date picker plugin. */ -/* Written by Anders Ekdahl ( anders@nomadiz.se). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['sv'] = { - closeText: 'Stäng', - prevText: '«Förra', - nextText: 'Nästa»', - currentText: 'Idag', - monthNames: ['Januari','Februari','Mars','April','Maj','Juni', - 'Juli','Augusti','September','Oktober','November','December'], - monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', - 'Jul','Aug','Sep','Okt','Nov','Dec'], - dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'], - dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'], - dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'], - weekHeader: 'Ve', - dateFormat: 'yy-mm-dd', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['sv']); - -return datepicker.regional['sv']; - -})); diff --git a/ui/i18n/datepicker-ta.js b/ui/i18n/datepicker-ta.js deleted file mode 100644 index 113a2084948..00000000000 --- a/ui/i18n/datepicker-ta.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by S A Sureshkumar (saskumar@live.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['ta'] = { - closeText: 'மூடு', - prevText: 'முன்னையது', - nextText: 'அடுத்தது', - currentText: 'இன்று', - monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி', - 'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'], - monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி', - 'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'], - dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'], - dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'], - dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'], - weekHeader: 'Не', - dateFormat: 'dd/mm/yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['ta']); - -return datepicker.regional['ta']; - -})); diff --git a/ui/i18n/datepicker-th.js b/ui/i18n/datepicker-th.js deleted file mode 100644 index 9314268c2f4..00000000000 --- a/ui/i18n/datepicker-th.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Thai initialisation for the jQuery UI date picker plugin. */ -/* Written by pipo (pipo@sixhead.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['th'] = { - closeText: 'ปิด', - prevText: '« ย้อน', - nextText: 'ถัดไป »', - currentText: 'วันนี้', - monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน', - 'กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'], - monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.', - 'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'], - dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'], - dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], - dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], - weekHeader: 'Wk', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['th']); - -return datepicker.regional['th']; - -})); diff --git a/ui/i18n/datepicker-tj.js b/ui/i18n/datepicker-tj.js deleted file mode 100644 index b6a995e3759..00000000000 --- a/ui/i18n/datepicker-tj.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Abdurahmon Saidov (saidovab@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['tj'] = { - closeText: 'Идома', - prevText: '<Қафо', - nextText: 'Пеш>', - currentText: 'Имрӯз', - monthNames: ['Январ','Феврал','Март','Апрел','Май','Июн', - 'Июл','Август','Сентябр','Октябр','Ноябр','Декабр'], - monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', - 'Июл','Авг','Сен','Окт','Ноя','Дек'], - dayNames: ['якшанбе','душанбе','сешанбе','чоршанбе','панҷшанбе','ҷумъа','шанбе'], - dayNamesShort: ['якш','душ','сеш','чор','пан','ҷум','шан'], - dayNamesMin: ['Як','Дш','Сш','Чш','Пш','Ҷм','Шн'], - weekHeader: 'Хф', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['tj']); - -return datepicker.regional['tj']; - -})); diff --git a/ui/i18n/datepicker-tr.js b/ui/i18n/datepicker-tr.js deleted file mode 100644 index c366eb16a75..00000000000 --- a/ui/i18n/datepicker-tr.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Turkish initialisation for the jQuery UI date picker plugin. */ -/* Written by Izzet Emre Erkan (kara@karalamalar.net). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['tr'] = { - closeText: 'kapat', - prevText: '<geri', - nextText: 'ileri>', - currentText: 'bugün', - monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran', - 'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'], - monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz', - 'Tem','Ağu','Eyl','Eki','Kas','Ara'], - dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'], - dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], - dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], - weekHeader: 'Hf', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['tr']); - -return datepicker.regional['tr']; - -})); diff --git a/ui/i18n/datepicker-uk.js b/ui/i18n/datepicker-uk.js deleted file mode 100644 index ab4adb9ddb9..00000000000 --- a/ui/i18n/datepicker-uk.js +++ /dev/null @@ -1,38 +0,0 @@ -/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */ -/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */ -/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['uk'] = { - closeText: 'Закрити', - prevText: '<', - nextText: '>', - currentText: 'Сьогодні', - monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень', - 'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'], - monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер', - 'Лип','Сер','Вер','Жов','Лис','Гру'], - dayNames: ['неділя','понеділок','вівторок','середа','четвер','п’ятниця','субота'], - dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'], - dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'], - weekHeader: 'Тиж', - dateFormat: 'dd.mm.yy', - firstDay: 1, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['uk']); - -return datepicker.regional['uk']; - -})); diff --git a/ui/i18n/datepicker-vi.js b/ui/i18n/datepicker-vi.js deleted file mode 100644 index 187ec15e4ab..00000000000 --- a/ui/i18n/datepicker-vi.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Vietnamese initialisation for the jQuery UI date picker plugin. */ -/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['vi'] = { - closeText: 'Đóng', - prevText: '<Trước', - nextText: 'Tiếp>', - currentText: 'Hôm nay', - monthNames: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu', - 'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'], - monthNamesShort: ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', - 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'], - dayNames: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'], - dayNamesShort: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], - dayNamesMin: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], - weekHeader: 'Tu', - dateFormat: 'dd/mm/yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: false, - yearSuffix: ''}; -datepicker.setDefaults(datepicker.regional['vi']); - -return datepicker.regional['vi']; - -})); diff --git a/ui/i18n/datepicker-zh-CN.js b/ui/i18n/datepicker-zh-CN.js deleted file mode 100644 index b62090a6309..00000000000 --- a/ui/i18n/datepicker-zh-CN.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Chinese initialisation for the jQuery UI date picker plugin. */ -/* Written by Cloudream (cloudream@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['zh-CN'] = { - 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-CN']); - -return datepicker.regional['zh-CN']; - -})); diff --git a/ui/i18n/datepicker-zh-HK.js b/ui/i18n/datepicker-zh-HK.js deleted file mode 100644 index ca5517ece43..00000000000 --- a/ui/i18n/datepicker-zh-HK.js +++ /dev/null @@ -1,37 +0,0 @@ -/* Chinese initialisation for the jQuery UI date picker plugin. */ -/* Written by SCCY (samuelcychan@gmail.com). */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -datepicker.regional['zh-HK'] = { - closeText: '關閉', - prevText: '<上月', - nextText: '下月>', - currentText: '今天', - monthNames: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - monthNamesShort: ['一月','二月','三月','四月','五月','六月', - '七月','八月','九月','十月','十一月','十二月'], - dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], - dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], - dayNamesMin: ['日','一','二','三','四','五','六'], - weekHeader: '周', - dateFormat: 'dd-mm-yy', - firstDay: 0, - isRTL: false, - showMonthAfterYear: true, - yearSuffix: '年'}; -datepicker.setDefaults(datepicker.regional['zh-HK']); - -return datepicker.regional['zh-HK']; - -})); diff --git a/ui/i18n/datepicker-zh-TW.js b/ui/i18n/datepicker-zh-TW.js deleted file mode 100644 index c9e6dfcb6b0..00000000000 --- a/ui/i18n/datepicker-zh-TW.js +++ /dev/null @@ -1,37 +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([ "../datepicker" ], factory ); - } else { - - // Browser globals - factory( jQuery.datepicker ); - } -}(function( datepicker ) { - -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']); - -return datepicker.regional['zh-TW']; - -})); From 82ea79ce5f3a86606b4d8cca5c8b9065b45d50e4 Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 15:47:48 -0300 Subject: [PATCH 078/179] Datepicker: Use Globalize 1.0.0 - Move external/date.js -> ui/calendar/date.js and UMDify it; - Create a locale option as discussed during Chicago's meeting: - [String] A String with locale value, e.g. "en"; or - [Object] An object with all the formatters. TODO: Use the Globalize to-be-created generators instead of these wrap functions. --- demos/datepicker/localization.html | 14 +- ui/calendar.js | 99 +++++++++--- ui/calendar/date.js | 245 +++++++++++++++++++++++++++++ ui/datepicker.js | 41 ++++- 4 files changed, 362 insertions(+), 37 deletions(-) create mode 100644 ui/calendar/date.js diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index 5ca763450ca..e049c2c735a 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -10,9 +10,8 @@ - - + @@ -25,11 +24,14 @@ var datepicker = $( "#datepicker" ), select = $( "#locale" ); - Globalize.locale( select.val() ); - datepicker.datepicker(); + datepicker.datepicker({ + locale: select.val() + }); - select.on( "change", function() { - Globalize.locale( $( this ).val() ); + select.change( function() { + datepicker.datepicker( "option", { + locale: select.val() + }); datepicker.datepicker( "valueAsDate", datepicker.datepicker( "valueAsDate" ) ); }); }); diff --git a/ui/calendar.js b/ui/calendar.js index 35a8dcea8c9..40f90fe7bd2 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -13,39 +13,39 @@ //>>docs: http://api.jqueryui.com/calendar/ //>>demos: http://jqueryui.com/calendar/ -( function( factory ) { +(function( factory ) { if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. // TODO: Keep button even if its optional? - define( [ + define([ "jquery", "globalize", - "./core", - "./widget", + "globalize/date", "./button", - "date" + "./calendar/date", + "./core", + "./widget" ], factory ); } else { // Browser globals factory( jQuery, Globalize ); } -}( function( $, Globalize ) { +}(function( $, Globalize ) { return $.widget( "ui.calendar", { version: "@VERSION", options: { buttons: [], - dateFormat: { date: "short" }, eachDay: $.noop, labels: { - "currentText": "Today", "datePickerRole": "date picker", "nextText": "Next", "prevText": "Prev", "weekHeader": "Wk" }, + locale: "en", max: null, min: null, numberOfMonths: 1, @@ -69,6 +69,9 @@ return $.widget( "ui.calendar", { this.labels = this.options.labels; this.buttonClickContext = this.element[ 0 ]; + this._setLocale( this.options.locale ); + + this.date = new $.ui.calendarDate( this.options.value, this.options.locale ); this.date = $.date( this.options.value, this.options.dateFormat ); this.viewDate = this.date.clone(); this.viewDate.eachDay = this.options.eachDay; @@ -97,7 +100,7 @@ return $.widget( "ui.calendar", { "mouseenter .ui-calendar-calendar button": "_hover", "mouseleave .ui-calendar-calendar button": "_hover", "keydown .ui-calendar-calendar": "_handleKeydown" - } ); + }); this._createCalendar(); }, @@ -174,6 +177,48 @@ return $.widget( "ui.calendar", { ).addClass( "ui-state-focus" ); }, + _setLocale: function( locale ) { + var globalize; + + if ( typeof locale === "string" ) { + globalize = new Globalize( locale ); + locale = { + format: function( date ) { + return globalize.formatDate( date, { date: "short" } ); + }, + parse: function( stringDate ) { + return globalize.parseDate( stringDate, { date: "short" } ); + } + }; + } + + if ( !locale.firstDay ) { + globalize = globalize || new Globalize( locale._locale ); + $.extend( locale, { + firstDay: globalize.cldr.supplemental.weekData.firstDay(), + formatWeekdayShort: function( date ) { + + // Return the short weekday if its length is < 3. Otherwise, its narrow form. + var shortWeekday = globalize.formatDate( date, { pattern: "EEEEEE" } ); + return shortWeekday.length > 3 ? + globalize.formatDate( date, { pattern: "EEEEE" } ) : + shortWeekday; + }, + formatWeekdayFull: function( date ) { + return globalize.formatDate( date, { pattern: "EEEE" } ); + }, + formatMonth: function( date ) { + return globalize.formatDate( date, { pattern: "MMMM" } ); + }, + formatWeekOfYear: function( date ) { + return globalize.formatDate( date, { pattern: "w" } ); + } + }); + } + + this.options.locale = locale; + }, + _createCalendar: function() { var classes = "ui-calendar ui-widget ui-widget-content ui-helper-clearfix ui-corner-all", pickerHtml = ""; @@ -187,10 +232,10 @@ return $.widget( "ui.calendar", { this.element .addClass( classes ) - .attr( { + .attr({ role: "region", "aria-labelledby": this.id + "-title" - } ) + }) .html( pickerHtml ); this._createButtonPane(); @@ -296,13 +341,14 @@ return $.widget( "ui.calendar", { _buildGridHeading: function() { var cells = "", i = 0, - weekDayLength = this.viewDate.weekdays().length; + weekDayLength = this.viewDate.weekdays().length, + weekdays = this.date.weekdays(); if ( this.options.showWeek ) { cells += "" + this._getTranslation( "weekHeader" ) + ""; } - for ( ; i < weekDayLength; i++ ) { - cells += this._buildGridHeaderCell( this.date.weekdays()[ i ] ); + for ( i; i < weekDayLength; i++ ) { + cells += this._buildGridHeaderCell( weekdays[ i ] ); } return "" + @@ -319,8 +365,6 @@ return $.widget( "ui.calendar", { }, _buildGridBody: function() { - - // this.date.days() needs caching as it has O(n^2) complexity. var days = this.viewDate.days(), i = 0, rows = ""; @@ -454,7 +498,7 @@ return $.widget( "ui.calendar", { $( "", props ) .button( buttonOptions ) .appendTo( that.buttonSet ); - } ); + }); this.element.addClass( "ui-calendar-buttons" ); this.buttonPane.appendTo( this.element ); }, @@ -511,17 +555,18 @@ return $.widget( "ui.calendar", { }, _setHiddenPicker: function() { - this.element.attr( { + this.element.attr({ "aria-hidden": "true", "aria-expanded": "false" - } ); + }); }, value: function( value ) { + var locale = this.options.locale; if ( arguments.length ) { - this.valueAsDate( Globalize.parseDate( value, this.options.dateFormat ) ); + this.valueAsDate( locale.parse( value ) ); } else { - return Globalize.formatDate( this.option( "value" ), this.options.dateFormat ); + return locale.format( this.option( "value" ) ); } }, @@ -572,7 +617,7 @@ return $.widget( "ui.calendar", { if ( key in that.refreshRelatedOptions ) { refresh = true; } - } ); + }); if ( refresh ) { this._refresh(); @@ -611,10 +656,12 @@ return $.widget( "ui.calendar", { this.viewDate.eachDay = value; } - if ( key === "dateFormat" ) { - this.date.setFormat( value ); + if ( key === "locale" ) { + this._setLocale( value ); + this.date.setAttributes( this.options.locale ); + this.refresh(); } } -} ); +}); -} ) ); +})); diff --git a/ui/calendar/date.js b/ui/calendar/date.js new file mode 100644 index 00000000000..80ebdaf7a1d --- /dev/null +++ b/ui/calendar/date.js @@ -0,0 +1,245 @@ +/* + * jQuery UI Calendar/Date @VERSION + * http://jqueryui.com + * + * Based on Marc Grabanski's jQuery Date Plugin + * http://marcgrabanski.com/articles/jquery-date-plugin + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ +(function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define([ + "jquery" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}(function( $ ) { + +$.ui = $.ui || {}; + +var _Date, + weekdaysRev = { + "sun": 0, + "mon": 1, + "tue": 2, + "wed": 3, + "thu": 4, + "fri": 5, + "sat": 6 + }; + +_Date = function( date, attributes ) { + if ( !( this instanceof _Date ) ) { + return new _Date( date, options ); + } + + this.setAttributes( attributes ); + + if ( typeof date === "string" && date.length ) { + this.dateObject = attributes.parse( date ); + } else if ( $.type( date ) === "date" ) { + this.dateObject = date; + } + + this.dateObject = this.dateObject || new Date(); +}; + +$.extend( _Date.prototype, { + + setAttributes: function( attributes ) { + this.attributes = attributes; + this.firstDay = weekdaysRev[ this.attributes.firstDay ]; + }, + + //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; + // FIXME: Why not to use .setDate? + 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 ) ) { + + // 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 this.attributes.formatMonth( this.dateObject ); + }, + + 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 date, + firstDay = this.firstDay, + result = []; + + // date = firstDay + date = new Date( this.dateObject.getTime() ); + date.setDate( date.getDate() + firstDay - date.getDay() ); + + for ( var dow = 0; dow < 7; dow++ && date.setDate( date.getDate() + 1 ) ) { + result.push({ + shortname: this.attributes.formatWeekdayShort( date ), + fullname: this.attributes.formatWeekdayFull( date ) + }); + } + return result; + }, + + days: function() { + var result = [], + today = new _Date( new Date(), this.attributes ), + date = this.dateObject, + firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(), + leadDays = ( firstDayOfMonth - this.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: this.attributes.formatWeekOfYear( printDate ), + days: [] + }; + for ( var dayx = 0; dayx < 7; dayx++ ) { + var day = week.days[ week.days.length ] = { + lead: printDate.getMonth() !== date.getMonth(), + date: printDate.getDate(), + month: printDate.getMonth(), + year: printDate.getFullYear(), + timestamp: printDate.getTime(), + 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 ); + } + } + 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; + }, + + clone: function() { + var date = this.dateObject; + return new _Date( new Date( date.getTime() ), this.attributes ); + }, + + // TODO compare year, month, day each for better performance + equal: function( other ) { + var format = function( date ) { + return "" + date.getFullYear() + date.getMonth() + date.getDate(); + } + return format( this.dateObject ) === format( other ); + }, + + date: function() { + return this.dateObject; + } +}); + +return $.ui.calendarDate = _Date; + +})); diff --git a/ui/datepicker.js b/ui/datepicker.js index 6f4dd3c9b3d..d4d9d397a9a 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -20,6 +20,7 @@ define([ "jquery", "globalize", + "globalize/date", "./core", "./widget", "./calendar", @@ -36,6 +37,7 @@ var widget = $.widget( "ui.datepicker", { version: "@VERSION", options: { appendTo: null, + locale: "en", position: { my: "left top", at: "left bottom" @@ -54,7 +56,19 @@ var widget = $.widget( "ui.datepicker", { "min", "numberOfMonths", "showWeek" ], _create: function() { + var globalize; this.suppressExpandOnFocus = false; + + this._setLocale( this.options.locale ); + + // FIXME: can we use Date instead? + if ( $.type( this.options.max ) === "string" ) { + this.options.max = globalize.parseDate( this.options.max , { pattern: "yyyy-MM-dd" } ); + } + if ( $.type( this.options.min ) === "string" ) { + this.options.min = globalize.parseDate( this.options.min , { pattern: "yyyy-MM-dd" } ); + } + this._createCalendar(); this._on( this._inputEvents ); @@ -206,7 +220,7 @@ var widget = $.widget( "ui.datepicker", { } if ( !element || !element[ 0 ] ) { - element = this.element.closest( ".ui-front, dialog" ); + element = this.element.closest( ".ui-front" ); } if ( !element.length ) { @@ -269,13 +283,29 @@ var widget = $.widget( "ui.datepicker", { }); }, + _setLocale: function( locale ) { + if ( typeof locale === "string" ) { + globalize = new Globalize( locale ); + locale = { + _locale: locale, + format: function( date ) { + return globalize.formatDate( date, { date: "short" } ); + }, + parse: function( stringDate ) { + return globalize.parseDate( stringDate, { date: "short" } ); + } + }; + } + this.options.locale = locale; + }, + _buildPosition: function() { return $.extend( { of: this.element }, this.options.position ); }, value: function( value ) { if ( arguments.length ) { - this.valueAsDate( Globalize.parseDate( value, this.options.dateFormat ) ); + this.valueAsDate( this.options.locale.parse( value ) ); } else { return this._getParsedValue() ? this.element.val() : null; } @@ -285,7 +315,7 @@ var widget = $.widget( "ui.datepicker", { if ( arguments.length ) { if ( this.calendarInstance._isValid( value ) ) { this.calendarInstance.valueAsDate( value ); - this.element.val( Globalize.formatDate( value, this.options.dateFormat ) ); + this.element.val( this.options.locale.format( value ) ); } } else { return this._getParsedValue(); @@ -307,7 +337,7 @@ var widget = $.widget( "ui.datepicker", { }, _getParsedValue: function() { - return Globalize.parseDate( this.element.val(), this.options.dateFormat ); + return this.options.locale.parse( this.element.val() ); }, _setOption: function( key, value ) { @@ -321,7 +351,8 @@ var widget = $.widget( "ui.datepicker", { this.calendar.appendTo( this._appendTo() ); } - if ( key === "dateFormat" ) { + if ( key === "locale" ) { + this._setLocale( value ); this.element.val( this.calendarInstance.value() ); } From b6d74367561f5508e72691277e18b6a9d919144e Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 15:47:48 -0300 Subject: [PATCH 079/179] (fix) Datepicker: Use Globalize 1.0.0 - parseYMD --- ui/datepicker.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index d4d9d397a9a..8faf67babb2 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -56,17 +56,15 @@ var widget = $.widget( "ui.datepicker", { "min", "numberOfMonths", "showWeek" ], _create: function() { - var globalize; this.suppressExpandOnFocus = false; this._setLocale( this.options.locale ); - // FIXME: can we use Date instead? if ( $.type( this.options.max ) === "string" ) { - this.options.max = globalize.parseDate( this.options.max , { pattern: "yyyy-MM-dd" } ); + this.options.max = this.options.locale.parseYMD( this.options.max ); } if ( $.type( this.options.min ) === "string" ) { - this.options.min = globalize.parseDate( this.options.min , { pattern: "yyyy-MM-dd" } ); + this.options.min = this.options.locale.parseYMD( this.options.min ); } this._createCalendar(); @@ -293,6 +291,9 @@ var widget = $.widget( "ui.datepicker", { }, parse: function( stringDate ) { return globalize.parseDate( stringDate, { date: "short" } ); + }, + parseYMD: function( stringDate ) { + return globalize.parseDate( stringDate, { pattern: "yyyy-MM-dd" } ); } }; } From 5d044dd88c2f83855aaed5bb0164e7fabd2e98f0 Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 15:47:48 -0300 Subject: [PATCH 080/179] (fix) Datepicker: Use Globalize 1.0.0 - user cannot provide locale: {fn1: ..., fn2:...} with all the formatters and parsers --- ui/calendar.js | 34 ++++++++++++---------------------- ui/calendar/date.js | 2 +- ui/datepicker.js | 39 ++++++++++++++++++--------------------- 3 files changed, 31 insertions(+), 44 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 40f90fe7bd2..da860445810 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -71,8 +71,7 @@ return $.widget( "ui.calendar", { this._setLocale( this.options.locale ); - this.date = new $.ui.calendarDate( this.options.value, this.options.locale ); - this.date = $.date( this.options.value, this.options.dateFormat ); + this.date = new $.ui.calendarDate( this.options.value, this._calendarDateOptions ); this.viewDate = this.date.clone(); this.viewDate.eachDay = this.options.eachDay; @@ -178,23 +177,17 @@ return $.widget( "ui.calendar", { }, _setLocale: function( locale ) { - var globalize; + var globalize = new Globalize( locale ); - if ( typeof locale === "string" ) { - globalize = new Globalize( locale ); - locale = { - format: function( date ) { + this._format = function( date ) { return globalize.formatDate( date, { date: "short" } ); - }, - parse: function( stringDate ) { + }; + + this._parse = function( stringDate ) { return globalize.parseDate( stringDate, { date: "short" } ); - } }; - } - if ( !locale.firstDay ) { - globalize = globalize || new Globalize( locale._locale ); - $.extend( locale, { + this._calendarDateOptions = { firstDay: globalize.cldr.supplemental.weekData.firstDay(), formatWeekdayShort: function( date ) { @@ -212,11 +205,9 @@ return $.widget( "ui.calendar", { }, formatWeekOfYear: function( date ) { return globalize.formatDate( date, { pattern: "w" } ); - } - }); - } - - this.options.locale = locale; + }, + parse: this._parse + }; }, _createCalendar: function() { @@ -562,11 +553,10 @@ return $.widget( "ui.calendar", { }, value: function( value ) { - var locale = this.options.locale; if ( arguments.length ) { this.valueAsDate( locale.parse( value ) ); } else { - return locale.format( this.option( "value" ) ); + return this._format( this.option( "value" ) ); } }, @@ -658,7 +648,7 @@ return $.widget( "ui.calendar", { if ( key === "locale" ) { this._setLocale( value ); - this.date.setAttributes( this.options.locale ); + this.date.setAttributes( this._calendarDateOptions ); this.refresh(); } } diff --git a/ui/calendar/date.js b/ui/calendar/date.js index 80ebdaf7a1d..dcace34a935 100644 --- a/ui/calendar/date.js +++ b/ui/calendar/date.js @@ -38,7 +38,7 @@ var _Date, _Date = function( date, attributes ) { if ( !( this instanceof _Date ) ) { - return new _Date( date, options ); + return new _Date( date, attributes ); } this.setAttributes( attributes ); diff --git a/ui/datepicker.js b/ui/datepicker.js index 8faf67babb2..b95d5a4f100 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -61,10 +61,10 @@ var widget = $.widget( "ui.datepicker", { this._setLocale( this.options.locale ); if ( $.type( this.options.max ) === "string" ) { - this.options.max = this.options.locale.parseYMD( this.options.max ); + this.options.max = this._parseYMD( this.options.max ); } if ( $.type( this.options.min ) === "string" ) { - this.options.min = this.options.locale.parseYMD( this.options.min ); + this.options.min = this._parseYMD( this.options.min ); } this._createCalendar(); @@ -282,22 +282,19 @@ var widget = $.widget( "ui.datepicker", { }, _setLocale: function( locale ) { - if ( typeof locale === "string" ) { - globalize = new Globalize( locale ); - locale = { - _locale: locale, - format: function( date ) { - return globalize.formatDate( date, { date: "short" } ); - }, - parse: function( stringDate ) { - return globalize.parseDate( stringDate, { date: "short" } ); - }, - parseYMD: function( stringDate ) { - return globalize.parseDate( stringDate, { pattern: "yyyy-MM-dd" } ); - } - }; - } - this.options.locale = locale; + var globalize = new Globalize( locale ); + + this._format = function( date ) { + return globalize.formatDate( date, { date: "short" } ); + }; + + this._parse = function( stringDate ) { + return globalize.parseDate( stringDate, { date: "short" } ); + }; + + this._parseYMD = function( stringDate ) { + return globalize.parseDate( stringDate, { pattern: "yyyy-MM-dd" } ); + }; }, _buildPosition: function() { @@ -306,7 +303,7 @@ var widget = $.widget( "ui.datepicker", { value: function( value ) { if ( arguments.length ) { - this.valueAsDate( this.options.locale.parse( value ) ); + this.valueAsDate( this._parse( value ) ); } else { return this._getParsedValue() ? this.element.val() : null; } @@ -316,7 +313,7 @@ var widget = $.widget( "ui.datepicker", { if ( arguments.length ) { if ( this.calendarInstance._isValid( value ) ) { this.calendarInstance.valueAsDate( value ); - this.element.val( this.options.locale.format( value ) ); + this.element.val( this._format( value ) ); } } else { return this._getParsedValue(); @@ -338,7 +335,7 @@ var widget = $.widget( "ui.datepicker", { }, _getParsedValue: function() { - return this.options.locale.parse( this.element.val() ); + return this._parse( this.element.val() ); }, _setOption: function( key, value ) { From 7f432eddb044239505cb504bd9ad7231736c438a Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 15:47:48 -0300 Subject: [PATCH 081/179] (fix) Datepicker: Use Globalize 1.0.0 - Update Globalize to 1.0.0-alpha.7 --- Gruntfile.js | 1 - bower.json | 2 +- external/globalize/globalize.js | 4 +- external/globalize/globalize/date.js | 950 +++++++++++++++--------- external/globalize/globalize/message.js | 86 --- 5 files changed, 591 insertions(+), 452 deletions(-) delete mode 100644 external/globalize/globalize/message.js diff --git a/Gruntfile.js b/Gruntfile.js index f4c59f6d301..90f64092e76 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -283,7 +283,6 @@ grunt.initConfig({ "globalize/globalize.js": "globalize/dist/globalize.js", "globalize/globalize/date.js": "globalize/dist/globalize/date.js", - "globalize/globalize/message.js": "globalize/dist/globalize/message.js", "globalize/LICENSE.txt": "globalize/LICENSE.txt", "qunit/qunit.js": "qunit/qunit/qunit.js", diff --git a/bower.json b/bower.json index ab99b8062c2..e0b3f627479 100644 --- a/bower.json +++ b/bower.json @@ -15,7 +15,7 @@ "jquery-simulate": "1.0.0", "jshint": "2.4.4", "qunit": "1.17.1", - "globalize": "1.0.0-alpha.6", + "globalize": "1.0.0-alpha.7", "jquery-1.7.0": "jquery#1.7.0", "jquery-1.7.1": "jquery#1.7.1", diff --git a/external/globalize/globalize.js b/external/globalize/globalize.js index 436729a91a7..f9ff0185119 100644 --- a/external/globalize/globalize.js +++ b/external/globalize/globalize.js @@ -1,5 +1,5 @@ /*! - * Globalize v1.0.0-alpha.6 + * Globalize v1.0.0-alpha.7 * * http://github.com/jquery/globalize * @@ -7,7 +7,7 @@ * Released under the MIT license * http://jquery.org/license * - * Date: 2014-09-01T21:32Z + * Date: 2014-09-30T12:31Z */ (function( root, factory ) { diff --git a/external/globalize/globalize/date.js b/external/globalize/globalize/date.js index 194328aeb2a..48d0080ac41 100644 --- a/external/globalize/globalize/date.js +++ b/external/globalize/globalize/date.js @@ -1,5 +1,5 @@ /*! - * Globalize v1.0.0-alpha.6 + * Globalize v1.0.0-alpha.7 * * http://github.com/jquery/globalize * @@ -7,7 +7,7 @@ * Released under the MIT license * http://jquery.org/license * - * Date: 2014-09-01T21:32Z + * Date: 2014-09-30T12:31Z */ (function( root, factory ) { @@ -32,8 +32,7 @@ } }(this, function( Cldr, Globalize ) { -var alwaysArray = Globalize._alwaysArray, - createError = Globalize._createError, +var createError = Globalize._createError, formatMessage = Globalize._formatMessage, isPlainObject = Globalize._isPlainObject, validateCldr = Globalize._validateCldr, @@ -73,69 +72,6 @@ var validateParameterTypeString = function( value, name ) { -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 dateAllPresets = 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( - objectValues( cldr.main( - "dates/calendars/gregorian/dateTimeFormats" - )).map(function( datetimeFormat, key ) { - if ( typeof datetimeFormat !== "string" ) { - return datetimeFormat; - } - return formatMessage( datetimeFormat, [ - cldr.main([ - "dates/calendars/gregorian/timeFormats", - key - ]), - cldr.main([ - "dates/calendars/gregorian/dateFormats", - key - ]) - ]); - }) - ); - - return result.map(function( pattern ) { - return { pattern: pattern }; - }); -}; - - - - var createErrorInvalidParameterValue = function( name, value ) { return createError( "E_INVALID_PAR_VALUE", "Invalid `{name}` value ({value}).", { name: name, @@ -227,23 +163,12 @@ var dateExpandPattern = function( pattern, cldr ) { -var dateWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ]; - - - - -/** - * firstDayOfWeek - */ -var dateFirstDayOfWeek = function( cldr ) { - return dateWeekDays.indexOf( cldr.supplemental.weekData.firstDay() ); -}; - - - - /** - * dayOfWeek + * dayOfWeek( date, firstDay ) + * + * @date + * + * @firstDay the result of `dateFirstDayOfWeek( cldr )` * * Return the day of the week normalized by the territory's firstDay [0-6]. * Eg for "mon": @@ -251,8 +176,8 @@ var dateFirstDayOfWeek = function( cldr ) { * - return 1 if territory is US (week starts on "sun"); * - return 2 if territory is EG (week starts on "sat"); */ -var dateDayOfWeek = function( date, cldr ) { - return ( date.getDay() - dateFirstDayOfWeek( cldr ) + 7 ) % 7; +var dateDayOfWeek = function( date, firstDay ) { + return ( date.getDay() - firstDay + 7 ) % 7; }; @@ -319,6 +244,21 @@ var dateDayOfYear = function( date ) { +var dateWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ]; + + + + +/** + * firstDayOfWeek + */ +var dateFirstDayOfWeek = function( cldr ) { + return dateWeekDays.indexOf( cldr.supplemental.weekData.firstDay() ); +}; + + + + /** * millisecondsInDay */ @@ -350,22 +290,18 @@ var stringPad = function( str, count, right ) { /** - * format( date, pattern, cldr ) + * format( date, properties ) * * @date [Date instance]. * - * @pattern [String] raw pattern. - * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns - * - * @cldr [Cldr instance]. + * @properties * * TODO Support other calendar types. * * Disclosure: this function borrows excerpts of dojo/date/locale. */ -var dateFormat = function( date, pattern, cldr ) { - var widths = [ "abbreviated", "wide", "narrow" ]; - return pattern.replace( datePatternRe, function( current ) { +var dateFormat = function( date, properties ) { + return properties.pattern.replace( datePatternRe, function( current ) { var pad, ret, chr = current.charAt( 0 ), length = current.length; @@ -373,18 +309,14 @@ var dateFormat = function( date, pattern, cldr ) { if ( chr === "j" ) { // Locale preferred hHKk. // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data - chr = cldr.supplemental.timeData.preferred(); + chr = properties.preferredTime; } switch ( chr ) { // Era case "G": - ret = cldr.main([ - "dates/calendars/gregorian/eras", - length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" ), - date.getFullYear() < 0 ? 0 : 1 - ]); + ret = properties.eras[ date.getFullYear() < 0 ? 0 : 1 ]; break; // Year @@ -407,9 +339,9 @@ var dateFormat = function( date, pattern, cldr ) { ret = new Date( date.getTime() ); ret.setDate( ret.getDate() + 7 - - dateDayOfWeek( date, cldr ) - - dateFirstDayOfWeek( cldr ) - - cldr.supplemental.weekData.minDays() + dateDayOfWeek( date, properties.firstDay ) - + properties.firstDay - + properties.minDays ); ret = String( ret.getFullYear() ); pad = true; @@ -429,13 +361,7 @@ var dateFormat = function( date, pattern, cldr ) { 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 - ]); + ret = properties.quarters[ chr ][ length ][ ret ]; } break; @@ -446,12 +372,7 @@ var dateFormat = function( date, pattern, cldr ) { if ( length <= 2 ) { pad = true; } else { - ret = cldr.main([ - "dates/calendars/gregorian/months", - chr === "M" ? "format" : "stand-alone", - widths[ length - 3 ], - ret - ]); + ret = properties.months[ chr ][ length ][ ret ]; } break; @@ -460,18 +381,18 @@ var dateFormat = function( date, pattern, cldr ) { // 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 = dateDayOfWeek( dateStartOf( date, "year" ), cldr ); + ret = dateDayOfWeek( dateStartOf( date, "year" ), properties.firstDay ); ret = Math.ceil( ( dateDayOfYear( date ) + ret ) / 7 ) - - ( 7 - ret >= cldr.supplemental.weekData.minDays() ? 0 : 1 ); + ( 7 - ret >= properties.minDays ? 0 : 1 ); pad = true; break; case "W": // Week of Month. // wom = ceil( ( dom + dow of `1/month` ) / 7 ) - minDaysStuff ? 1 : 0. - ret = dateDayOfWeek( dateStartOf( date, "month" ), cldr ); + ret = dateDayOfWeek( dateStartOf( date, "month" ), properties.firstDay ); ret = Math.ceil( ( date.getDate() + ret ) / 7 ) - - ( 7 - ret >= cldr.supplemental.weekData.minDays() ? 0 : 1 ); + ( 7 - ret >= properties.minDays ? 0 : 1 ); break; // Day @@ -500,7 +421,7 @@ var dateFormat = function( date, pattern, cldr ) { if ( length <= 2 ) { // Range is [1-7] (deduced by example provided on documentation) // TODO Should pad with zeros (not specified in the docs)? - ret = dateDayOfWeek( date, cldr ) + 1; + ret = dateDayOfWeek( date, properties.firstDay ) + 1; pad = true; break; } @@ -508,38 +429,12 @@ var dateFormat = function( date, pattern, cldr ) { /* falls through */ case "E": ret = dateWeekDays[ 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 - ]); - } + ret = properties.days[ chr ][ length ][ ret ]; break; // Period (AM or PM) case "a": - ret = cldr.main([ - "dates/calendars/gregorian/dayPeriods/format/wide", - date.getHours() < 12 ? "am" : "pm" - ]); + ret = properties.dayPeriods[ date.getHours() < 12 ? "am" : "pm" ]; break; // Hour @@ -613,99 +508,46 @@ var dateFormat = function( date, pattern, cldr ) { /** - * tokenizer( value, pattern ) + * properties( pattern, cldr ) * - * 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" - * }] + * @pattern [String] raw pattern. + * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns * - * OBS: lexeme's are always String and may return invalid ranges depending of the token type. - * Eg. "99" for month number. + * @cldr [Cldr instance]. * - * Return an empty Array when not successfully parsed. + * Return the properties given the pattern and cldr. + * + * TODO Support other calendar types. */ -var dateTokenizer = function( value, pattern, cldr ) { - var valid, - tokens = [], +var dateFormatProperties = function( pattern, cldr ) { + var properties = {}, widths = [ "abbreviated", "wide", "narrow" ]; - valid = pattern.match( datePatternRe ).every(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/; - } - } + properties.pattern = pattern; + pattern.replace( datePatternRe, function( current ) { + var chr = current.charAt( 0 ), + length = current.length; - // 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; + if ( chr === "j" ) { + // Locale preferred hHKk. + // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data + properties.preferredTime = chr = cldr.supplemental.timeData.preferred(); } - token.type = current; - chr = current.charAt( 0 ), - length = current.length; - switch ( chr ) { // Era case "G": - lookup([ + properties.eras = cldr.main([ "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 + ",}" ); - } + // Year in "Week of Year" + properties.firstDay = dateFirstDayOfWeek( cldr ); + properties.minDays = cldr.supplemental.weekData.minDays(); break; case "u": // Extended year. Need to be implemented. @@ -715,73 +557,81 @@ var dateTokenizer = function( value, pattern, cldr ) { // 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 ] - ]); + if ( length > 2 ) { + if ( !properties.quarters ) { + properties.quarters = {}; + } + if ( !properties.quarters[ chr ] ) { + properties.quarters[ chr ] = {}; + } + properties.quarters[ chr ][ length ] = cldr.main([ + "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}" ); + if ( length > 2 ) { + if ( !properties.months ) { + properties.months = {}; + } + if ( !properties.months[ chr ] ) { + properties.months[ chr ] = {}; + } + properties.months[ chr ][ length ] = cldr.main([ + "dates/calendars/gregorian/months", + chr === "M" ? "format" : "stand-alone", + widths[ length - 3 ] + ]); } break; + // Week - Week of Year (w) or Week of Month (W). + case "w": case "W": - case "F": - // number l=1:{1}. - oneDigitIfLengthOne(); + properties.firstDay = dateFirstDayOfWeek( cldr ); + properties.minDays = cldr.supplemental.weekData.minDays(); 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(); + properties.firstDay = dateFirstDayOfWeek( cldr ); break; } /* falls through */ case "E": + if ( !properties.days ) { + properties.days = {}; + } + if ( !properties.days[ chr ] ) { + properties.days[ chr ] = {}; + } 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" - ]); + + // 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 + properties.days[ chr ][ length ] = cldr.main([ + "dates/calendars/gregorian/days", + chr === "c" ? "stand-alone" : "format", + "short" + ]) || cldr.main([ + "dates/calendars/gregorian/days", + chr === "c" ? "stand-alone" : "format", + "abbreviated" + ]); } else { - lookup([ + properties.days[ chr ][ length ] = cldr.main([ "dates/calendars/gregorian/days", - [ chr === "c" ? "stand-alone" : "format" ], + chr === "c" ? "stand-alone" : "format", widths[ length < 3 ? 0 : length - 3 ] ]); } @@ -789,33 +639,9 @@ var dateTokenizer = function( value, pattern, cldr ) { // Period (AM or PM) case "a": - lookup([ + properties.dayPeriods = cldr.main( "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 @@ -829,40 +655,10 @@ var dateTokenizer = function( value, pattern, cldr ) { 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 : []; + return properties; }; @@ -907,11 +703,17 @@ function outOfRange( value, low, high ) { } /** - * parse + * parse( value, tokens, properties ) + * + * @value [String] string date. + * + * @tokens [Object] tokens returned by date/tokenizer. + * + * @properties [Object] output returned by date/tokenizer-properties. * * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns */ -return function( value, pattern, cldr ) { +return function( value, tokens, properties ) { var amPm, era, hour, hour12, valid, YEAR = 0, MONTH = 1, @@ -921,7 +723,6 @@ return function( value, pattern, cldr ) { SECOND = 5, MILLISECONDS = 6, date = new Date(), - tokens = dateTokenizer( value, pattern, cldr ), truncateAt = [], units = [ "year", "month", "day", "hour", "minute", "second", "milliseconds" ]; @@ -943,7 +744,7 @@ return function( value, pattern, cldr ) { if ( chr === "j" ) { // Locale preferred hHKk. // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data - chr = cldr.supplemental.timeData.preferred(); + chr = properties.preferredTimeData; } switch ( chr ) { @@ -1165,6 +966,394 @@ return function( value, pattern, cldr ) { }()); +/** + * parseProperties( cldr ) + * + * @cldr [Cldr instance]. + * + * Return parser properties. + */ +var dateParseProperties = function( cldr ) { + return { + preferredTimeData: cldr.supplemental.timeData.preferred() + }; +}; + + + + +/** + * tokenizer( value, pattern, properties ) + * + * @value [String] string date. + * + * @properties [Object] output returned by date/tokenizer-properties. + * + * 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 dateTokenizer = function( value, properties ) { + var valid, + tokens = [], + widths = [ "abbreviated", "wide", "narrow" ]; + + valid = properties.pattern.match( datePatternRe ).every(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 = properties[ path.join( "/" ).replace( /^.*calendars\//, "" ) ]; + + 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 : []; +}; + + + + +/** + * tokenizerProperties( pattern, cldr ) + * + * @pattern [String] raw pattern. + * + * @cldr [Cldr instance]. + * + * Return Object with data that will be used by tokenizer. + */ +var dateTokenizerProperties = function( pattern, cldr ) { + var properties = { + pattern: pattern + }, + widths = [ "abbreviated", "wide", "narrow" ]; + + function populateProperties( path, value ) { + properties[ path.replace( /^.*calendars\//, "" ) ] = value; + } + + cldr.on( "get", populateProperties ); + + pattern.match( datePatternRe ).forEach(function( current ) { + var chr, length; + + chr = current.charAt( 0 ), + length = current.length; + + switch ( chr ) { + + // Era + case "G": + cldr.main([ + "dates/calendars/gregorian/eras", + length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" ) + ]); + break; + + // Quarter + case "Q": + case "q": + if ( length > 2 ) { + cldr.main([ + "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... + if ( length > 2 ) { + cldr.main([ + "dates/calendars/gregorian/months", + chr === "M" ? "format" : "stand-alone", + widths[ length - 3 ] + ]); + } + break; + + // Week day + case "e": + case "c": + // lookup for length >=3. + if ( length <= 2 ) { + 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 + cldr.main([ + "dates/calendars/gregorian/days", + [ chr === "c" ? "stand-alone" : "format" ], + "short" + ]) || cldr.main([ + "dates/calendars/gregorian/days", + [ chr === "c" ? "stand-alone" : "format" ], + "abbreviated" + ]); + } else { + cldr.main([ + "dates/calendars/gregorian/days", + [ chr === "c" ? "stand-alone" : "format" ], + widths[ length < 3 ? 0 : length - 3 ] + ]); + } + break; + + // Period (AM or PM) + case "a": + cldr.main([ + "dates/calendars/gregorian/dayPeriods/format/wide" + ]); + break; + } + }); + + cldr.off( "get", populateProperties ); + + return properties; +}; + + + + function validateRequiredCldr( path, value ) { validateCldr( path, value, { skip: [ @@ -1176,21 +1365,25 @@ function validateRequiredCldr( path, value ) { } /** - * .formatDate( value, pattern ) - * - * @value [Date] + * .dateFormatter( pattern ) * * @pattern [String or Object] see date/expand_pattern for more info. * - * Formats a date or number according to the given pattern string and the default/instance locale. + * Return a date formatter function (of the form below) according to the given pattern and the + * default/instance locale. + * + * fn( value ) + * + * @value [Date] + * + * Return a function that formats a date according to the given `format` and the default/instance + * locale. */ -Globalize.formatDate = -Globalize.prototype.formatDate = function( value, pattern ) { - var cldr, ret; +Globalize.dateFormatter = +Globalize.prototype.dateFormatter = function( pattern ) { + var cldr, properties; - validateParameterPresence( value, "value" ); validateParameterPresence( pattern, "pattern" ); - validateParameterTypeDate( value, "value" ); validateParameterTypeDatePattern( pattern, "pattern" ); cldr = this.cldr; @@ -1199,51 +1392,84 @@ Globalize.prototype.formatDate = function( value, pattern ) { cldr.on( "get", validateRequiredCldr ); pattern = dateExpandPattern( pattern, cldr ); - ret = dateFormat( value, pattern, cldr ); + properties = dateFormatProperties( pattern, cldr ); cldr.off( "get", validateRequiredCldr ); - return ret; + return function( value ) { + validateParameterPresence( value, "value" ); + validateParameterTypeDate( value, "value" ); + return dateFormat( value, properties ); + }; }; /** - * .parseDate( value, patterns ) - * - * @value [String] + * .dateParser( pattern ) * - * @patterns [Array] Optional. See date/expand_pattern for more info about each pattern. Defaults - * to the list of all presets defined in the locale (see date/all_presets for more info). + * @pattern [String or Object] see date/expand_pattern for more info. * - * Return a Date instance or null. + * Return a function that parses a string date according to the given `formats` and the + * default/instance locale. */ -Globalize.parseDate = -Globalize.prototype.parseDate = function( value, patterns ) { - var cldr, date; +Globalize.dateParser = +Globalize.prototype.dateParser = function( pattern ) { + var cldr, parseProperties, tokenizerProperties; - validateParameterPresence( value, "value" ); - validateParameterTypeString( value, "value" ); + validateParameterPresence( pattern, "pattern" ); + validateParameterTypeDatePattern( pattern, "pattern" ); cldr = this.cldr; validateDefaultLocale( cldr ); cldr.on( "get", validateRequiredCldr ); + pattern = dateExpandPattern( pattern, cldr ); + tokenizerProperties = dateTokenizerProperties( pattern, cldr ); + parseProperties = dateParseProperties( cldr ); + cldr.off( "get", validateRequiredCldr ); - if ( !patterns ) { - patterns = dateAllPresets( cldr ); - } else { - patterns = alwaysArray( patterns ); - } + return function( value ) { + var tokens; - patterns.some(function( pattern ) { - validateParameterTypeDatePattern( pattern, "patterns" ); - pattern = dateExpandPattern( pattern, cldr ); - date = dateParse( value, pattern, cldr ); - return !!date; - }); + validateParameterPresence( value, "value" ); + validateParameterTypeString( value, "value" ); - cldr.off( "get", validateRequiredCldr ); + tokens = dateTokenizer( value, tokenizerProperties ); + return dateParse( value, tokens, parseProperties ) || null; + }; +}; + +/** + * .formatDate( value, pattern ) + * + * @value [Date] + * + * @pattern [String or Object] see date/expand_pattern for more info. + * + * Formats a date or number according to the given pattern string and the default/instance locale. + */ +Globalize.formatDate = +Globalize.prototype.formatDate = function( value, pattern ) { + validateParameterPresence( value, "value" ); + validateParameterTypeDate( value, "value" ); + + return this.dateFormatter( pattern )( value ); +}; + +/** + * .parseDate( value, pattern ) + * + * @value [String] + * + * @pattern [String or Object] see date/expand_pattern for more info. + * + * Return a Date instance or null. + */ +Globalize.parseDate = +Globalize.prototype.parseDate = function( value, pattern ) { + validateParameterPresence( value, "value" ); + validateParameterTypeString( value, "value" ); - return date || null; + return this.dateParser( pattern )( value ); }; return Globalize; diff --git a/external/globalize/globalize/message.js b/external/globalize/globalize/message.js deleted file mode 100644 index e2783990070..00000000000 --- a/external/globalize/globalize/message.js +++ /dev/null @@ -1,86 +0,0 @@ -/*! - * Globalize v1.0.0-alpha.6 - * - * http://github.com/jquery/globalize - * - * Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-09-01T21:32Z - */ -(function( root, factory ) { - - // UMD returnExports - if ( typeof define === "function" && define.amd ) { - - // AMD - define([ - "cldr", - "../globalize" - ], factory ); - } else if ( typeof exports === "object" ) { - - // Node, CommonJS - module.exports = factory( require( "cldrjs" ), require( "globalize" ) ); - } else { - - // Extend global - factory( root.Cldr, root.Globalize ); - } -}(this, function( Cldr, Globalize ) { - -var alwaysArray = Globalize._alwaysArray, - validateDefaultLocale = Globalize._validateDefaultLocale, - validateParameterPresence = Globalize._validateParameterPresence, - validateParameterType = Globalize._validateParameterType, - validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject; - - -/** - * .loadTranslations( json ) - * - * @json [JSON] - * - * Load translation data. - */ -Globalize.loadTranslations = function( json ) { - var customData = { - "globalize-translations": json - }; - - validateParameterPresence( json, "json" ); - validateParameterTypePlainObject( json, "json" ); - - Cldr.load( customData ); -}; - -/** - * .translate( path ) - * - * @path [String or Array] - * - * Translate item given its path. - */ -Globalize.translate = -Globalize.prototype.translate = function( path ) { - var cldr; - - validateParameterPresence( path, "path" ); - validateParameterType( path, "path", typeof path === "string" || Array.isArray( path ), - "a String nor an Array" ); - - path = alwaysArray( path ); - cldr = this.cldr; - - validateDefaultLocale( cldr ); - - return cldr.get( [ "globalize-translations/{languageId}" ].concat( path ) ); -}; - -return Globalize; - - - - -})); From e56c2b4812ec0c79c63e9849f9a2e5f700bd2714 Mon Sep 17 00:00:00 2001 From: Rafael Xavier de Souza Date: Thu, 4 Sep 2014 15:47:48 -0300 Subject: [PATCH 082/179] (fix) Datepicker: Use Globalize 1.0.0 - Use format/parse generators --- ui/calendar.js | 33 ++++++++++----------------------- ui/datepicker.js | 15 +++------------ 2 files changed, 13 insertions(+), 35 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index da860445810..b773281ab3a 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -177,35 +177,22 @@ return $.widget( "ui.calendar", { }, _setLocale: function( locale ) { - var globalize = new Globalize( locale ); - - this._format = function( date ) { - return globalize.formatDate( date, { date: "short" } ); - }; - - this._parse = function( stringDate ) { - return globalize.parseDate( stringDate, { date: "short" } ); - }; - + var globalize = new Globalize( locale ), + weekdayShortFormatter = globalize.dateFormatter({ pattern: "EEEEEE" }), + weekdayNarrowFormatter = globalize.dateFormatter({ pattern: "EEEEE" }); + this._format = globalize.dateFormatter({ date: "short" }); + this._parse = globalize.dateParser({ date: "short" }); this._calendarDateOptions = { firstDay: globalize.cldr.supplemental.weekData.firstDay(), formatWeekdayShort: function( date ) { // Return the short weekday if its length is < 3. Otherwise, its narrow form. - var shortWeekday = globalize.formatDate( date, { pattern: "EEEEEE" } ); - return shortWeekday.length > 3 ? - globalize.formatDate( date, { pattern: "EEEEE" } ) : - shortWeekday; - }, - formatWeekdayFull: function( date ) { - return globalize.formatDate( date, { pattern: "EEEE" } ); + var shortWeekday = weekdayShortFormatter( date ); + return shortWeekday.length > 3 ? weekdayNarrowFormatter( date ) : shortWeekday; }, - formatMonth: function( date ) { - return globalize.formatDate( date, { pattern: "MMMM" } ); - }, - formatWeekOfYear: function( date ) { - return globalize.formatDate( date, { pattern: "w" } ); - }, + formatWeekdayFull: globalize.dateFormatter({ pattern: "EEEE" }), + formatMonth: globalize.dateFormatter({ pattern: "MMMM" }), + formatWeekOfYear: globalize.dateFormatter({ pattern: "w" }), parse: this._parse }; }, diff --git a/ui/datepicker.js b/ui/datepicker.js index b95d5a4f100..8139782154a 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -283,18 +283,9 @@ var widget = $.widget( "ui.datepicker", { _setLocale: function( locale ) { var globalize = new Globalize( locale ); - - this._format = function( date ) { - return globalize.formatDate( date, { date: "short" } ); - }; - - this._parse = function( stringDate ) { - return globalize.parseDate( stringDate, { date: "short" } ); - }; - - this._parseYMD = function( stringDate ) { - return globalize.parseDate( stringDate, { pattern: "yyyy-MM-dd" } ); - }; + this._format = globalize.dateFormatter({ date: "short" }); + this._parse = globalize.dateParser({ date: "short" }); + this._parseYMD = globalize.dateParser({ pattern: "yyyy-MM-dd" }); }, _buildPosition: function() { From e0acb2da4885d456841f96a7c13368c4eb562a95 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 25 Apr 2015 19:36:10 +0200 Subject: [PATCH 083/179] Datepicker: Use Globalize 1.0.0 - Make unit tests work --- tests/unit/calendar/calendar.html | 35 ++++++++++++++++++++++++--- tests/unit/datepicker/datepicker.html | 5 ++-- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html index 0d28b635151..14bae7a4e00 100644 --- a/tests/unit/calendar/calendar.html +++ b/tests/unit/calendar/calendar.html @@ -4,9 +4,38 @@ Codestin Search App - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index be4ff78934f..374b2c1fd8d 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -8,15 +8,14 @@ + - - - + + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - -+ -+ + - + diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index d2b07a796fe..e17252901b5 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -9,15 +9,14 @@ -+ -+ + - + - + -+ -+ + - + - + -+ -+ + - + - + From 8238c25980e59a683d36af3ba754a4c4ab01f369 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 30 Apr 2015 17:38:01 +0200 Subject: [PATCH 086/179] Merge branch 'datepicker' into datepicker-globalize-1.x --- Gruntfile.js | 1 + bower.json | 20 +- demos/calendar/buttonbar.html | 2 +- demos/calendar/default.html | 2 +- demos/calendar/dropdown-month-year.html | 2 +- demos/calendar/localization.html | 2 +- demos/calendar/min-max.html | 2 +- demos/calendar/multiple-months.html | 2 +- demos/calendar/other-months.html | 2 +- demos/calendar/show-week.html | 2 +- demos/datepicker/animation.html | 2 +- demos/datepicker/date-formats.html | 2 +- demos/datepicker/default.html | 2 +- demos/datepicker/icon-trigger.html | 2 +- demos/datepicker/localization.html | 4 +- external/date.js | 103 ++++++---- external/localization.js | 17 ++ tests/lib/bootstrap.js | 1 + tests/unit/calendar/calendar.html | 35 +--- tests/unit/calendar/common.js | 11 +- tests/unit/datepicker/common.js | 11 +- tests/unit/datepicker/datepicker.html | 37 +--- ui/calendar.js | 30 +-- ui/calendar/date.js | 245 ------------------------ ui/datepicker.js | 2 +- 25 files changed, 153 insertions(+), 388 deletions(-) delete mode 100644 ui/calendar/date.js diff --git a/Gruntfile.js b/Gruntfile.js index 90f64092e76..ee949a3f500 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -282,6 +282,7 @@ grunt.initConfig({ "cldrjs/LICENSE-MIT": "cldrjs/LICENSE-MIT", "globalize/globalize.js": "globalize/dist/globalize.js", + "globalize/globalize/number.js": "globalize/dist/globalize/number.js", "globalize/globalize/date.js": "globalize/dist/globalize/date.js", "globalize/LICENSE.txt": "globalize/LICENSE.txt", diff --git a/bower.json b/bower.json index e0b3f627479..3070b753364 100644 --- a/bower.json +++ b/bower.json @@ -14,8 +14,12 @@ "jquery-mousewheel": "3.1.12", "jquery-simulate": "1.0.0", "jshint": "2.4.4", - "qunit": "1.17.1", - "globalize": "1.0.0-alpha.7", + "qunit": "1.18.0", + "qunit-assert-classes": "1.0.2", + "qunit-assert-close": "JamesMGreene/qunit-assert-close#v1.1.1", + "qunit-composite": "JamesMGreene/qunit-composite#v1.1.0", + "requirejs": "2.1.14", + "globalize": "1.0.0-alpha.7", "jquery-1.7.0": "jquery#1.7.0", "jquery-1.7.1": "jquery#1.7.1", @@ -29,10 +33,18 @@ "jquery-1.10.0": "jquery#1.10.0", "jquery-1.10.1": "jquery#1.10.1", "jquery-1.10.2": "jquery#1.10.2", - "jquery-1.x": "jquery#1.10.2", + "jquery-1.11.0": "jquery#1.11.0", + "jquery-1.11.1": "jquery#1.11.1", + "jquery-1.11.2": "jquery#1.11.2", + "jquery-1.11.3": "jquery#1.11.3", + "jquery-1.x": "jquery#1.11.3", "jquery-2.0.0": "jquery#2.0.0", "jquery-2.0.1": "jquery#2.0.1", "jquery-2.0.2": "jquery#2.0.2", - "jquery-2.0.3": "jquery#2.0.3" + "jquery-2.0.3": "jquery#2.0.3", + "jquery-2.1.0": "jquery#2.1.0", + "jquery-2.1.1": "jquery#2.1.1", + "jquery-2.1.2": "jquery#2.1.2", + "jquery-2.1.3": "jquery#2.1.3" } } diff --git a/demos/calendar/buttonbar.html b/demos/calendar/buttonbar.html index ac519247ccc..6af0072b73c 100644 --- a/demos/calendar/buttonbar.html +++ b/demos/calendar/buttonbar.html @@ -11,7 +11,7 @@ - + diff --git a/demos/calendar/default.html b/demos/calendar/default.html index e22cc797fb2..301d49eeb1c 100644 --- a/demos/calendar/default.html +++ b/demos/calendar/default.html @@ -11,7 +11,7 @@ - + diff --git a/demos/calendar/dropdown-month-year.html b/demos/calendar/dropdown-month-year.html index 71b8777cb3a..49fb10c19cf 100644 --- a/demos/calendar/dropdown-month-year.html +++ b/demos/calendar/dropdown-month-year.html @@ -11,7 +11,7 @@ - + diff --git a/demos/calendar/localization.html b/demos/calendar/localization.html index 5c325d0a071..105b41c026a 100644 --- a/demos/calendar/localization.html +++ b/demos/calendar/localization.html @@ -11,7 +11,7 @@ - + diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html index 953e7888355..e1af1c997c6 100644 --- a/demos/calendar/min-max.html +++ b/demos/calendar/min-max.html @@ -11,7 +11,7 @@ - + diff --git a/demos/calendar/multiple-months.html b/demos/calendar/multiple-months.html index 99248d8c2ed..dd0e435a205 100644 --- a/demos/calendar/multiple-months.html +++ b/demos/calendar/multiple-months.html @@ -11,7 +11,7 @@ - + diff --git a/demos/calendar/other-months.html b/demos/calendar/other-months.html index 5f891b2021e..492777e3889 100644 --- a/demos/calendar/other-months.html +++ b/demos/calendar/other-months.html @@ -11,7 +11,7 @@ - + diff --git a/demos/calendar/show-week.html b/demos/calendar/show-week.html index 6443b6de1b3..63e8b9fcd4c 100644 --- a/demos/calendar/show-week.html +++ b/demos/calendar/show-week.html @@ -11,7 +11,7 @@ - + diff --git a/demos/datepicker/animation.html b/demos/datepicker/animation.html index eda91738617..5f5fc6825aa 100644 --- a/demos/datepicker/animation.html +++ b/demos/datepicker/animation.html @@ -11,7 +11,7 @@ - + diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index e17252901b5..a98c99e7eff 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -11,7 +11,7 @@ - + diff --git a/demos/datepicker/default.html b/demos/datepicker/default.html index 89f1ceaa925..f57cd41bc61 100644 --- a/demos/datepicker/default.html +++ b/demos/datepicker/default.html @@ -11,7 +11,7 @@ - + diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index 4faeb31c761..933b38b9d66 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -11,7 +11,7 @@ - + diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index e049c2c735a..71070c168cf 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -11,7 +11,7 @@ - + @@ -28,7 +28,7 @@ locale: select.val() }); - select.change( function() { + select.on( "change", function() { datepicker.datepicker( "option", { locale: select.val() }); diff --git a/external/date.js b/external/date.js index 958b53d0701..4cb29ef27d5 100644 --- a/external/date.js +++ b/external/date.js @@ -9,17 +9,18 @@ // AMD. Register as an anonymous module. define( [ - "jquery", - "globalize" + "jquery" ], factory ); } else { // Browser globals - factory( jQuery, Globalize ); + factory( jQuery ); } -}( function( $, Globalize ) { +}( function( $ ) { -var weekdays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ], +$.ui = $.ui || {}; + +var _Date, weekdaysRev = { "sun": 0, "mon": 1, @@ -30,43 +31,46 @@ var weekdays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ], "sat": 6 }; -Globalize.locale( "en" ); - -$.date = function( date, globalFormat ) { - if ( !( this instanceof $.date ) ) { - return new $.date( date, globalFormat ); +_Date = function( date, attributes ) { + if ( !( this instanceof _Date ) ) { + return new _Date( date, attributes ); } + + this.setAttributes( attributes ); + if ( typeof date === "string" && date.length ) { - this.dateObject = Globalize.parseDate( date, globalFormat ); - } - if ( $.type( date ) === "date" ) { + this.dateObject = attributes.parse( date ); + } else if ( $.type( date ) === "date" ) { this.dateObject = date; } this.dateObject = this.dateObject || new Date(); - this.globalFormat = globalFormat; }; -$.date.prototype = { - setFormat: function( format ) { - if ( format ) { - this.globalFormat = format; - } - return this; +$.extend( _Date.prototype, { + + setAttributes: function( attributes ) { + this.attributes = attributes; + this.firstDay = weekdaysRev[ this.attributes.firstDay ]; }, + //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; + // FIXME: Why not to use .setDate? 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. @@ -81,6 +85,7 @@ $.date.prototype = { date.getMinutes(), date.getSeconds() ); return this; }, + setYear: function( year ) { var date = this.dateObject, day = date.getDate(), @@ -96,10 +101,12 @@ $.date.prototype = { 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(), @@ -114,59 +121,71 @@ $.date.prototype = { 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.formatDate( this.dateObject, { pattern: "MMMM" } ); + return this.attributes.formatMonth( this.dateObject ); }, + 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 cldr = Globalize.locale(), + var date, + firstDay = this.firstDay, result = []; + + // date = firstDay + date = new Date( this.dateObject.getTime() ); + date.setDate( date.getDate() + firstDay - 1 - date.getDay() ); + for ( var dow = 0; dow < 7; dow++ ) { - var day = ( dow + weekdaysRev[ cldr.supplemental.weekData.firstDay() ] ) % 7; + date.setTime( date.getTime() + 86400000 ); result.push({ - shortname: - cldr.main([ "dates/calendars/gregorian/days/format/short", weekdays[ day ] ]).length > 3 ? - cldr.main([ "dates/calendars/gregorian/days/format/narrow", weekdays[ day ] ]) : - cldr.main([ "dates/calendars/gregorian/days/format/short", weekdays[ day ] ]), - fullname: cldr.main([ "dates/calendars/gregorian/days/format/wide", weekdays[ day ] ]) + shortname: this.attributes.formatWeekdayShort( date ), + fullname: this.attributes.formatWeekdayFull( date ) }); } + return result; }, + days: function() { var result = [], - today = $.date(), + today = new _Date( new Date(), this.attributes ), date = this.dateObject, firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(), - leadDays = ( firstDayOfMonth - weekdaysRev[ Globalize.locale().supplemental.weekData.firstDay() ] + 7 ) % 7, + leadDays = ( firstDayOfMonth - this.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.formatDate( printDate, { pattern: "w" } ), + number: this.attributes.formatWeekOfYear( printDate ), days: [] }; for ( var dayx = 0; dayx < 7; dayx++ ) { var day = week.days[ week.days.length ] = { - lead: printDate.getMonth() != date.getMonth(), + lead: printDate.getMonth() !== date.getMonth(), date: printDate.getDate(), month: printDate.getMonth(), year: printDate.getFullYear(), @@ -177,12 +196,14 @@ $.date.prototype = { 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, @@ -197,25 +218,25 @@ $.date.prototype = { result[ result.length - 1 ].last = true; return result; }, + 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 ); + return new _Date( new Date( date.getTime() ), this.attributes ); }, + // TODO compare year, month, day each for better performance equal: function( other ) { - function format( date ) { - return Globalize.formatDate( date, { pattern: "yyyyMMdd" } ); + var format = function( date ) { + return "" + date.getFullYear() + date.getMonth() + date.getDate(); } return format( this.dateObject ) === format( other ); }, + date: function() { return this.dateObject; - }, - format: function( format ) { - return Globalize.formatDate( this.dateObject, format || this.globalFormat ); } -}; +}); + +return $.ui.calendarDate = _Date; } ) ); diff --git a/external/localization.js b/external/localization.js index d1be977be45..2db980a586f 100644 --- a/external/localization.js +++ b/external/localization.js @@ -1,6 +1,19 @@ /** * CLDR data */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "globalize" + ], factory ); + } else { + + // Browser globals + factory( Globalize ); + } +}( function( Globalize ) { Globalize.load({ "main": { @@ -4188,3 +4201,7 @@ Globalize.load({ } } }); + +return Globalize; + +} ) ); diff --git a/tests/lib/bootstrap.js b/tests/lib/bootstrap.js index 2829c66396b..571621fa44e 100644 --- a/tests/lib/bootstrap.js +++ b/tests/lib/bootstrap.js @@ -3,6 +3,7 @@ requirejs.config({ paths: { "date": "../../../external/date", + "cldr": "../../../external/cldrjs/cldr", "globalize": "../../../external/globalize/globalize", "globalize-locales": "../../../external/localization", "globalize-old": "../../../external/globalize-old/globalize", diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html index 14bae7a4e00..0d28b635151 100644 --- a/tests/unit/calendar/calendar.html +++ b/tests/unit/calendar/calendar.html @@ -4,38 +4,9 @@ Codestin Search App - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/tests/unit/calendar/common.js b/tests/unit/calendar/common.js index 8402cc8c70c..3bb3b4e589d 100644 --- a/tests/unit/calendar/common.js +++ b/tests/unit/calendar/common.js @@ -1,6 +1,13 @@ -TestHelpers.commonWidgetTests( "calendar", { +define( [ + "lib/common", + "ui/calendar", + "globalize-locales" +], function( common ) { + +common.testWidget( "calendar", { defaults: { buttons: [], + classes: {}, disabled: false, eachDay: $.noop, labels: { @@ -21,3 +28,5 @@ TestHelpers.commonWidgetTests( "calendar", { select: null } }); + +} ); diff --git a/tests/unit/datepicker/common.js b/tests/unit/datepicker/common.js index 31ab5abef70..84b97fa3a3c 100644 --- a/tests/unit/datepicker/common.js +++ b/tests/unit/datepicker/common.js @@ -1,7 +1,14 @@ -TestHelpers.commonWidgetTests( "datepicker", { +define( [ + "lib/common", + "ui/datepicker", + "globalize-locales" +], function( common ) { + +common.testWidget( "datepicker", { defaults: { appendTo: null, buttons: [], + classes: {}, disabled: false, eachDay: $.noop, labels: { @@ -30,3 +37,5 @@ TestHelpers.commonWidgetTests( "datepicker", { select: null } }); + +} ); diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 374b2c1fd8d..3b20272b13c 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -4,40 +4,9 @@ Codestin Search App - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/ui/calendar.js b/ui/calendar.js index 78eccb51b76..966e4c99271 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -13,26 +13,26 @@ //>>docs: http://api.jqueryui.com/calendar/ //>>demos: http://jqueryui.com/calendar/ -(function( factory ) { +( function( factory ) { if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. // TODO: Keep button even if its optional? - define([ + define( [ "jquery", "globalize", "globalize/date", + "globalize-locales", + "date", "./button", - "./calendar/date", "./core", - "./widget" - ], factory ); + "./button" ], factory ); } else { // Browser globals factory( jQuery, Globalize ); } -}(function( $, Globalize ) { +}( function( $, Globalize ) { return $.widget( "ui.calendar", { version: "@VERSION", @@ -99,7 +99,7 @@ return $.widget( "ui.calendar", { "mouseenter .ui-calendar-calendar button": "_hover", "mouseleave .ui-calendar-calendar button": "_hover", "keydown .ui-calendar-calendar": "_handleKeydown" - }); + } ); this._createCalendar(); }, @@ -212,10 +212,10 @@ return $.widget( "ui.calendar", { this.element .addClass( classes ) - .attr({ + .attr( { role: "region", "aria-labelledby": this.id + "-title" - }) + } ) .html( pickerHtml ); this._createButtonPane(); @@ -478,7 +478,7 @@ return $.widget( "ui.calendar", { $( "", props ) .button( buttonOptions ) .appendTo( that.buttonSet ); - }); + } ); this.element.addClass( "ui-calendar-buttons" ); this.buttonPane.appendTo( this.element ); }, @@ -536,10 +536,10 @@ return $.widget( "ui.calendar", { }, _setHiddenPicker: function() { - this.element.attr({ + this.element.attr( { "aria-hidden": "true", "aria-expanded": "false" - }); + } ); }, value: function( value ) { @@ -597,7 +597,7 @@ return $.widget( "ui.calendar", { if ( key in that.refreshRelatedOptions ) { refresh = true; } - }); + } ); if ( refresh ) { this._refresh(); @@ -642,6 +642,6 @@ return $.widget( "ui.calendar", { this.refresh(); } } -}); +} ); -})); +} ) ); diff --git a/ui/calendar/date.js b/ui/calendar/date.js deleted file mode 100644 index dcace34a935..00000000000 --- a/ui/calendar/date.js +++ /dev/null @@ -1,245 +0,0 @@ -/* - * jQuery UI Calendar/Date @VERSION - * http://jqueryui.com - * - * Based on Marc Grabanski's jQuery Date Plugin - * http://marcgrabanski.com/articles/jquery-date-plugin - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ - "jquery" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } -}(function( $ ) { - -$.ui = $.ui || {}; - -var _Date, - weekdaysRev = { - "sun": 0, - "mon": 1, - "tue": 2, - "wed": 3, - "thu": 4, - "fri": 5, - "sat": 6 - }; - -_Date = function( date, attributes ) { - if ( !( this instanceof _Date ) ) { - return new _Date( date, attributes ); - } - - this.setAttributes( attributes ); - - if ( typeof date === "string" && date.length ) { - this.dateObject = attributes.parse( date ); - } else if ( $.type( date ) === "date" ) { - this.dateObject = date; - } - - this.dateObject = this.dateObject || new Date(); -}; - -$.extend( _Date.prototype, { - - setAttributes: function( attributes ) { - this.attributes = attributes; - this.firstDay = weekdaysRev[ this.attributes.firstDay ]; - }, - - //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; - // FIXME: Why not to use .setDate? - 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 ) ) { - - // 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 this.attributes.formatMonth( this.dateObject ); - }, - - 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 date, - firstDay = this.firstDay, - result = []; - - // date = firstDay - date = new Date( this.dateObject.getTime() ); - date.setDate( date.getDate() + firstDay - date.getDay() ); - - for ( var dow = 0; dow < 7; dow++ && date.setDate( date.getDate() + 1 ) ) { - result.push({ - shortname: this.attributes.formatWeekdayShort( date ), - fullname: this.attributes.formatWeekdayFull( date ) - }); - } - return result; - }, - - days: function() { - var result = [], - today = new _Date( new Date(), this.attributes ), - date = this.dateObject, - firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(), - leadDays = ( firstDayOfMonth - this.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: this.attributes.formatWeekOfYear( printDate ), - days: [] - }; - for ( var dayx = 0; dayx < 7; dayx++ ) { - var day = week.days[ week.days.length ] = { - lead: printDate.getMonth() !== date.getMonth(), - date: printDate.getDate(), - month: printDate.getMonth(), - year: printDate.getFullYear(), - timestamp: printDate.getTime(), - 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 ); - } - } - 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; - }, - - clone: function() { - var date = this.dateObject; - return new _Date( new Date( date.getTime() ), this.attributes ); - }, - - // TODO compare year, month, day each for better performance - equal: function( other ) { - var format = function( date ) { - return "" + date.getFullYear() + date.getMonth() + date.getDate(); - } - return format( this.dateObject ) === format( other ); - }, - - date: function() { - return this.dateObject; - } -}); - -return $.ui.calendarDate = _Date; - -})); diff --git a/ui/datepicker.js b/ui/datepicker.js index df61becb5e9..c1cced4ed7a 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -217,7 +217,7 @@ var widget = $.widget( "ui.datepicker", { } if ( !element || !element[ 0 ] ) { - element = this.element.closest( ".ui-front" ); + element = this.element.closest( ".ui-front, dialog" ); } if ( !element.length ) { From f9ba50df661f5cf6c1e30320e8f943dd7018e0c8 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 27 Jul 2015 20:53:16 +0200 Subject: [PATCH 087/179] Calendar: Update Globalize to 1.0.0 --- bower.json | 2 +- demos/calendar/buttonbar.html | 1 + demos/calendar/default.html | 1 + demos/calendar/dropdown-month-year.html | 1 + demos/calendar/localization.html | 1 + demos/calendar/min-max.html | 1 + demos/calendar/multiple-months.html | 1 + demos/calendar/other-months.html | 1 + demos/calendar/show-week.html | 1 + external/cldrjs/LICENSE-MIT/LICENSE-MIT | 2 +- external/cldrjs/cldr.js | 496 +++++--- external/cldrjs/cldr/event.js | 8 +- external/cldrjs/cldr/supplemental.js | 8 +- external/globalize/LICENSE.txt | 3 +- external/globalize/globalize.js | 71 +- external/globalize/globalize/date.js | 833 +++++++++---- external/globalize/globalize/number.js | 1266 +++++++++++++++++++ external/localization.js | 1486 ++++++++++++++++++++--- ui/calendar.js | 13 +- 19 files changed, 3572 insertions(+), 624 deletions(-) create mode 100644 external/globalize/globalize/number.js diff --git a/bower.json b/bower.json index 3070b753364..614e4f78a03 100644 --- a/bower.json +++ b/bower.json @@ -19,7 +19,7 @@ "qunit-assert-close": "JamesMGreene/qunit-assert-close#v1.1.1", "qunit-composite": "JamesMGreene/qunit-composite#v1.1.0", "requirejs": "2.1.14", - "globalize": "1.0.0-alpha.7", + "globalize": "1.0.0", "jquery-1.7.0": "jquery#1.7.0", "jquery-1.7.1": "jquery#1.7.1", diff --git a/demos/calendar/buttonbar.html b/demos/calendar/buttonbar.html index 6af0072b73c..52a07a32fc6 100644 --- a/demos/calendar/buttonbar.html +++ b/demos/calendar/buttonbar.html @@ -9,6 +9,7 @@ + diff --git a/demos/calendar/default.html b/demos/calendar/default.html index 301d49eeb1c..c83b8f85de7 100644 --- a/demos/calendar/default.html +++ b/demos/calendar/default.html @@ -9,6 +9,7 @@ + diff --git a/demos/calendar/dropdown-month-year.html b/demos/calendar/dropdown-month-year.html index 49fb10c19cf..fbb4b7b8512 100644 --- a/demos/calendar/dropdown-month-year.html +++ b/demos/calendar/dropdown-month-year.html @@ -9,6 +9,7 @@ + diff --git a/demos/calendar/localization.html b/demos/calendar/localization.html index 105b41c026a..1307052ef5b 100644 --- a/demos/calendar/localization.html +++ b/demos/calendar/localization.html @@ -9,6 +9,7 @@ + diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html index e1af1c997c6..f8af39bd2b8 100644 --- a/demos/calendar/min-max.html +++ b/demos/calendar/min-max.html @@ -9,6 +9,7 @@ + diff --git a/demos/calendar/multiple-months.html b/demos/calendar/multiple-months.html index dd0e435a205..22118abaad6 100644 --- a/demos/calendar/multiple-months.html +++ b/demos/calendar/multiple-months.html @@ -9,6 +9,7 @@ + diff --git a/demos/calendar/other-months.html b/demos/calendar/other-months.html index 492777e3889..ef43f7b82ce 100644 --- a/demos/calendar/other-months.html +++ b/demos/calendar/other-months.html @@ -9,6 +9,7 @@ + diff --git a/demos/calendar/show-week.html b/demos/calendar/show-week.html index 63e8b9fcd4c..dfa76240529 100644 --- a/demos/calendar/show-week.html +++ b/demos/calendar/show-week.html @@ -9,6 +9,7 @@ + diff --git a/external/cldrjs/LICENSE-MIT/LICENSE-MIT b/external/cldrjs/LICENSE-MIT/LICENSE-MIT index 6db134a6952..6123defa8aa 100644 --- a/external/cldrjs/LICENSE-MIT/LICENSE-MIT +++ b/external/cldrjs/LICENSE-MIT/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2013 Rafael Xavier de Souza http://rafael.xavier.blog.br +Copyright (c) Rafael Xavier de Souza http://rafael.xavier.blog.br Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/external/cldrjs/cldr.js b/external/cldrjs/cldr.js index 95515ba857d..5b3c637a89d 100644 --- a/external/cldrjs/cldr.js +++ b/external/cldrjs/cldr.js @@ -1,15 +1,15 @@ /** - * CLDR JavaScript Library v0.3.8 + * CLDR JavaScript Library v0.4.1 * http://jquery.com/ * * Copyright 2013 Rafael Xavier de Souza * Released under the MIT license * http://jquery.org/license * - * Date: 2014-07-13T05:05Z + * Date: 2015-02-25T13:51Z */ /*! - * CLDR JavaScript Library v0.3.8 2014-07-13T05:05Z MIT license © Rafael Xavier + * CLDR JavaScript Library v0.4.1 2015-02-25T13:51Z MIT license © Rafael Xavier * http://git.io/h4lmVg */ (function( root, factory ) { @@ -28,85 +28,6 @@ }( this, function() { - - 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 objectKeys = function( object ) { - var i, - result = []; - - if ( Object.keys ) { - return Object.keys( object ); - } - - for ( i in object ) { - result.push( i ); - } - - return result; - }; - - - - - var createError = function( code, attributes ) { - var error, message; - - message = code + ( attributes && JSON ? ": " + JSON.stringify( attributes ) : "" ); - error = new Error( message ); - error.code = code; - - // extend( error, attributes ); - arrayForEach( objectKeys( attributes ), function( attribute ) { - error[ attribute ] = attributes[ attribute ]; - }); - - return error; - }; - - - - - var validate = function( code, check, attributes ) { - if ( !check ) { - throw createError( code, attributes ); - } - }; - - - - - var validatePresence = function( value, name ) { - validate( "E_MISSING_PARAMETER", typeof value !== "undefined", { - name: name - }); - }; - - - - - var validateType = function( value, name, check, expected ) { - validate( "E_INVALID_PAR_TYPE", check, { - expected: expected, - name: name, - value: value - }); - }; - - - - var arrayIsArray = Array.isArray || function( obj ) { return Object.prototype.toString.call( obj ) === "[object Array]"; }; @@ -114,37 +35,6 @@ - var validateTypePath = function( value, name ) { - validateType( value, name, typeof value === "string" || arrayIsArray( value ), "String or Array" ); - }; - - - - - /** - * Function inspired by jQuery Core, but reduced to our use case. - */ - var isPlainObject = function( obj ) { - return obj !== null && "" + obj === "[object Object]"; - }; - - - - - var validateTypePlainObject = function( value, name ) { - validateType( value, name, typeof value === "undefined" || isPlainObject( value ), "Plain Object" ); - }; - - - - - var validateTypeString = function( value, name ) { - validateType( value, name, typeof value === "string", "a string" ); - }; - - - - var pathNormalize = function( path, attributes ) { if ( arrayIsArray( path ) ) { path = path.join( "/" ); @@ -315,6 +205,200 @@ + /** + * subtags( locale ) + * + * @locale [String] + */ + var coreSubtags = function( locale ) { + var aux, unicodeLanguageId, + subtags = []; + + locale = locale.replace( /_/, "-" ); + + // Unicode locale extensions. + aux = locale.split( "-u-" ); + if ( aux[ 1 ] ) { + aux[ 1 ] = aux[ 1 ].split( "-t-" ); + locale = aux[ 0 ] + ( aux[ 1 ][ 1 ] ? "-t-" + aux[ 1 ][ 1 ] : ""); + subtags[ 4 /* unicodeLocaleExtensions */ ] = aux[ 1 ][ 0 ]; + } + + // TODO normalize transformed extensions. Currently, skipped. + // subtags[ x ] = locale.split( "-t-" )[ 1 ]; + unicodeLanguageId = locale.split( "-t-" )[ 0 ]; + + // unicode_language_id = "root" + // | unicode_language_subtag + // (sep unicode_script_subtag)? + // (sep unicode_region_subtag)? + // (sep unicode_variant_subtag)* ; + // + // Although unicode_language_subtag = alpha{2,8}, I'm using alpha{2,3}. Because, there's no language on CLDR lengthier than 3. + aux = unicodeLanguageId.match( /^(([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?)(-[a-zA-Z0-9]{5,8}|[0-9][a-zA-Z0-9]{3})*$|^(root)$/ ); + if ( aux === null ) { + return [ "und", "Zzzz", "ZZ" ]; + } + subtags[ 0 /* language */ ] = aux[ 9 ] /* root */ || aux[ 2 ] || "und"; + subtags[ 1 /* script */ ] = aux[ 4 ] || "Zzzz"; + subtags[ 2 /* territory */ ] = aux[ 6 ] || "ZZ"; + subtags[ 3 /* variant */ ] = aux[ 7 ]; + + // 0: language + // 1: script + // 2: territory (aka region) + // 3: variant + // 4: unicodeLocaleExtensions + return subtags; + }; + + + + + 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 ); + } + }; + + + + + /** + * bundleLookup( minLanguageId ) + * + * @Cldr [Cldr class] + * + * @cldr [Cldr instance] + * + * @minLanguageId [String] requested languageId after applied remove likely subtags. + */ + var bundleLookup = function( Cldr, cldr, minLanguageId ) { + var availableBundleMap = Cldr._availableBundleMap, + availableBundleMapQueue = Cldr._availableBundleMapQueue; + + if ( availableBundleMapQueue.length ) { + arrayForEach( availableBundleMapQueue, function( bundle ) { + var existing, maxBundle, minBundle, subtags; + subtags = coreSubtags( bundle ); + maxBundle = coreLikelySubtags( Cldr, cldr, subtags, { force: true } ) || subtags; + minBundle = coreRemoveLikelySubtags( Cldr, cldr, maxBundle ); + minBundle = minBundle.join( Cldr.localeSep ); + existing = availableBundleMapQueue[ minBundle ]; + if ( existing && existing.length < bundle.length ) { + return; + } + availableBundleMap[ minBundle ] = bundle; + }); + Cldr._availableBundleMapQueue = []; + } + + return availableBundleMap[ minLanguageId ] || null; + }; + + + + + var objectKeys = function( object ) { + var i, + result = []; + + if ( Object.keys ) { + return Object.keys( object ); + } + + for ( i in object ) { + result.push( i ); + } + + return result; + }; + + + + + var createError = function( code, attributes ) { + var error, message; + + message = code + ( attributes && JSON ? ": " + JSON.stringify( attributes ) : "" ); + error = new Error( message ); + error.code = code; + + // extend( error, attributes ); + arrayForEach( objectKeys( attributes ), function( attribute ) { + error[ attribute ] = attributes[ attribute ]; + }); + + return error; + }; + + + + + var validate = function( code, check, attributes ) { + if ( !check ) { + throw createError( code, attributes ); + } + }; + + + + + var validatePresence = function( value, name ) { + validate( "E_MISSING_PARAMETER", typeof value !== "undefined", { + name: name + }); + }; + + + + + var validateType = function( value, name, check, expected ) { + validate( "E_INVALID_PAR_TYPE", check, { + expected: expected, + name: name, + value: value + }); + }; + + + + + var validateTypePath = function( value, name ) { + validateType( value, name, typeof value === "string" || arrayIsArray( value ), "String or Array" ); + }; + + + + + /** + * Function inspired by jQuery Core, but reduced to our use case. + */ + var isPlainObject = function( obj ) { + return obj !== null && "" + obj === "[object Object]"; + }; + + + + + var validateTypePlainObject = function( value, name ) { + validateType( value, name, typeof value === "undefined" || isPlainObject( value ), "Plain Object" ); + }; + + + + + var validateTypeString = function( value, name ) { + validateType( value, name, typeof value === "string", "a string" ); + }; + + + + // @path: normalized path var resourceGet = function( data, path ) { var i, @@ -333,18 +417,33 @@ - var itemGetResolved = function( Cldr, path, attributes ) { - // Resolve path - var normalizedPath = pathNormalize( path, attributes ); - - return resourceGet( Cldr._resolved, normalizedPath ); + /** + * setAvailableBundles( Cldr, json ) + * + * @Cldr [Cldr class] + * + * @json resolved/unresolved cldr data. + * + * Set available bundles queue based on passed json CLDR data. Considers a bundle as any String at /main/{bundle}. + */ + var coreSetAvailableBundles = function( Cldr, json ) { + var bundle, + availableBundleMapQueue = Cldr._availableBundleMapQueue, + main = resourceGet( json, [ "main" ] ); + + if ( main ) { + for ( bundle in main ) { + if ( main.hasOwnProperty( bundle ) && bundle !== "root" ) { + availableBundleMapQueue.push( bundle ); + } + } + } }; - - var alwaysArray = function( stringOrArray ) { - return typeof stringOrArray === "string" ? [ stringOrArray ] : stringOrArray; + var alwaysArray = function( somethingOrArray ) { + return arrayIsArray( somethingOrArray ) ? somethingOrArray : [ somethingOrArray ]; }; @@ -390,6 +489,48 @@ }()); + /** + * load( Cldr, source, jsons ) + * + * @Cldr [Cldr class] + * + * @source [Object] + * + * @jsons [arguments] + */ + var coreLoad = function( Cldr, source, jsons ) { + var i, j, json; + + validatePresence( jsons[ 0 ], "json" ); + + // Support arbitrary parameters, e.g., `Cldr.load({...}, {...})`. + for ( i = 0; i < jsons.length; i++ ) { + + // Support array parameters, e.g., `Cldr.load([{...}, {...}])`. + json = alwaysArray( jsons[ i ] ); + + for ( j = 0; j < json.length; j++ ) { + validateTypePlainObject( json[ j ], "json" ); + source = jsonMerge( source, json[ j ] ); + coreSetAvailableBundles( Cldr, json[ j ] ); + } + } + + return source; + }; + + + + var itemGetResolved = function( Cldr, path, attributes ) { + // Resolve path + var normalizedPath = pathNormalize( path, attributes ); + + return resourceGet( Cldr._resolved, normalizedPath ); + }; + + + + /** * new Cldr() */ @@ -399,6 +540,7 @@ // Build optimization hack to avoid duplicating functions across modules. Cldr._alwaysArray = alwaysArray; + Cldr._coreLoad = coreLoad; Cldr._createError = createError; Cldr._itemGetResolved = itemGetResolved; Cldr._jsonMerge = jsonMerge; @@ -409,29 +551,39 @@ Cldr._validateTypePath = validateTypePath; Cldr._validateTypePlainObject = validateTypePlainObject; + Cldr._availableBundleMap = {}; + Cldr._availableBundleMapQueue = []; Cldr._resolved = {}; // Allow user to override locale separator "-" (default) | "_". According to http://www.unicode.org/reports/tr35/#Unicode_language_identifier, both "-" and "_" are valid locale separators (eg. "en_GB", "en-GB"). According to http://unicode.org/cldr/trac/ticket/6786 its usage must be consistent throughout the data set. Cldr.localeSep = "-"; - // Load resolved cldr data - // @json [JSON] - Cldr.load = function( json ) { - validatePresence( json, "json" ); - validateTypePlainObject( json, "json" ); - Cldr._resolved = jsonMerge( Cldr._resolved, json ); + /** + * Cldr.load( json [, json, ...] ) + * + * @json [JSON] CLDR data or [Array] Array of @json's. + * + * Load resolved cldr data. + */ + Cldr.load = function() { + Cldr._resolved = coreLoad( Cldr, Cldr._resolved, arguments ); }; /** * .init() automatically run on instantiation/construction. */ Cldr.prototype.init = function( locale ) { - var language, languageId, maxLanguageId, script, territory, unicodeLanguageId, variant, + var attributes, language, maxLanguageId, minLanguageId, script, subtags, territory, unicodeLocaleExtensions, variant, sep = Cldr.localeSep; validatePresence( locale, "locale" ); validateTypeString( locale, "locale" ); + subtags = coreSubtags( locale ); + + unicodeLocaleExtensions = subtags[ 4 ]; + variant = subtags[ 3 ]; + // 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). @@ -440,73 +592,20 @@ // - 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,3}_[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,3}_[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,3}_[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,3}|root)(\b|_)/.test( unicodeLanguageId ): - language = unicodeLanguageId.split( "_" )[ 0 ]; - script = "Zzzz"; - territory = "ZZ"; - variant = unicodeLanguageId.split( "_" )[ 1 ]; - break; - - default: - language = "und"; - script = "Zzzz"; - territory = "ZZ"; - break; - } - // When a locale id does not specify a language, or territory (region), or script, they are obtained by Likely Subtags. - maxLanguageId = coreLikelySubtags( Cldr, this, [ language, script, territory ], { force: true } ) || unicodeLanguageId.split( "_" ); + maxLanguageId = coreLikelySubtags( Cldr, this, subtags, { force: true } ) || subtags; language = maxLanguageId[ 0 ]; script = maxLanguageId[ 1 ]; - territory = maxLanguageId[ 2 ]; + territory = maxLanguageId[ 2 ]; - languageId = coreRemoveLikelySubtags( Cldr, this, maxLanguageId ).join( sep ); + minLanguageId = coreRemoveLikelySubtags( Cldr, this, maxLanguageId ).join( sep ); // Set attributes - this.attributes = { + this.attributes = attributes = { + bundle: bundleLookup( Cldr, this, minLanguageId ), // Unicode Language Id - languageId: languageId, + minlanguageId: minLanguageId, maxLanguageId: maxLanguageId.join( sep ), // Unicode Language Id Subtabs @@ -517,7 +616,21 @@ variant: variant }; - this.locale = variant ? [ languageId, variant ].join( sep ) : languageId; + // Unicode locale extensions. + unicodeLocaleExtensions && ( "-" + unicodeLocaleExtensions ).replace( /-[a-z]{3,8}|(-[a-z]{2})-([a-z]{3,8})/g, function( attribute, key, type ) { + + if ( key ) { + + // Extension is in the `keyword` form. + attributes[ "u" + key ] = type; + } else { + + // Extension is in the `attribute` form. + attributes[ "u" + attribute ] = true; + } + }); + + this.locale = locale; }; /** @@ -538,12 +651,17 @@ validatePresence( path, "path" ); validateTypePath( path, "path" ); + validate( "E_MISSING_BUNDLE", this.attributes.bundle !== null, { + locale: this.locale + }); + path = alwaysArray( path ); - return this.get( [ "main/{languageId}" ].concat( path ) ); + return this.get( [ "main/{bundle}" ].concat( path ) ); }; return Cldr; + })); diff --git a/external/cldrjs/cldr/event.js b/external/cldrjs/cldr/event.js index 46c95af53b5..f9eaa368ba2 100644 --- a/external/cldrjs/cldr/event.js +++ b/external/cldrjs/cldr/event.js @@ -1,15 +1,15 @@ /** - * CLDR JavaScript Library v0.3.8 + * CLDR JavaScript Library v0.4.1 * http://jquery.com/ * * Copyright 2013 Rafael Xavier de Souza * Released under the MIT license * http://jquery.org/license * - * Date: 2014-07-13T05:05Z + * Date: 2015-02-25T13:51Z */ /*! - * CLDR JavaScript Library v0.3.8 2014-07-13T05:05Z MIT license © Rafael Xavier + * CLDR JavaScript Library v0.4.1 2015-02-25T13:51Z MIT license © Rafael Xavier * http://git.io/h4lmVg */ (function( factory ) { @@ -32,7 +32,6 @@ validatePresence = Cldr._validatePresence, validateType = Cldr._validateType; - /*! * EventEmitter v4.2.7 - git.io/ee * Oliver Caldwell @@ -582,4 +581,5 @@ EventEmitter = (function () { + })); diff --git a/external/cldrjs/cldr/supplemental.js b/external/cldrjs/cldr/supplemental.js index 989344b6198..87153683c70 100644 --- a/external/cldrjs/cldr/supplemental.js +++ b/external/cldrjs/cldr/supplemental.js @@ -1,15 +1,15 @@ /** - * CLDR JavaScript Library v0.3.8 + * CLDR JavaScript Library v0.4.1 * http://jquery.com/ * * Copyright 2013 Rafael Xavier de Souza * Released under the MIT license * http://jquery.org/license * - * Date: 2014-07-13T05:05Z + * Date: 2015-02-25T13:51Z */ /*! - * CLDR JavaScript Library v0.3.8 2014-07-13T05:05Z MIT license © Rafael Xavier + * CLDR JavaScript Library v0.4.1 2015-02-25T13:51Z MIT license © Rafael Xavier * http://git.io/h4lmVg */ (function( factory ) { @@ -32,7 +32,6 @@ - var supplementalMain = function( cldr ) { var prepend, supplemental; @@ -98,4 +97,5 @@ + })); diff --git a/external/globalize/LICENSE.txt b/external/globalize/LICENSE.txt index 5dee5ca452c..0f9f2e51ca9 100644 --- a/external/globalize/LICENSE.txt +++ b/external/globalize/LICENSE.txt @@ -1,5 +1,4 @@ -Copyright 2010, 2014 jQuery Foundation and other contributors, -https://jquery.org/ +Copyright jQuery Foundation and other contributors, https://jquery.org/ This software consists of voluntary contributions made by many individuals. For exact contribution history, see the revision history diff --git a/external/globalize/globalize.js b/external/globalize/globalize.js index f9ff0185119..2f744ac649f 100644 --- a/external/globalize/globalize.js +++ b/external/globalize/globalize.js @@ -1,13 +1,17 @@ -/*! - * Globalize v1.0.0-alpha.7 +/** + * Globalize v1.0.0 * * http://github.com/jquery/globalize * - * Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors + * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2014-09-30T12:31Z + * Date: 2015-04-23T12:02Z + */ +/*! + * Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license + * http://git.io/TrdQbw */ (function( root, factory ) { @@ -54,7 +58,7 @@ var toString = function( variable ) { * * Return the formatted message. For example: * - * - formatMessage( "{0} second", 1 ); // 1 second + * - formatMessage( "{0} second", [ 1 ] ); // 1 second * * - formatMessage( "{0}/{1}", ["m", "s"] ); // m/s * @@ -77,6 +81,23 @@ var formatMessage = function( message, data ) { +var objectExtend = function() { + var destination = arguments[ 0 ], + sources = [].slice.call( arguments, 1 ); + + sources.forEach(function( source ) { + var prop; + for ( prop in source ) { + destination[ prop ] = source[ prop ]; + } + }); + + return destination; +}; + + + + var createError = function( code, message, attributes ) { var error; @@ -84,10 +105,7 @@ var createError = function( code, message, attributes ) { error = new Error( message ); error.code = code; - // extend( error, attributes ); - Object.keys( attributes ).forEach(function( attribute ) { - error[ attribute ] = attributes[ attribute ]; - }); + objectExtend( error, attributes ); return error; }; @@ -228,6 +246,28 @@ var alwaysCldr = function( localeOrCldr ) { +// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions +var regexpEscape = function( string ) { + return string.replace( /([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1" ); +}; + + + + +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; +}; + + + + function validateLikelySubtags( cldr ) { cldr.once( "get", validateCldr ); cldr.get( "supplemental/likelySubtags" ); @@ -256,18 +296,16 @@ function Globalize( locale ) { } /** - * Globalize.load( json ) + * Globalize.load( json, ... ) * * @json [JSON] * * Load resolved or unresolved cldr data. * Somewhat equivalent to previous Globalize.addCultureInfo(...). */ -Globalize.load = function( json ) { - validateParameterPresence( json, "json" ); - validateParameterTypePlainObject( json, "json" ); - - Cldr.load( json ); +Globalize.load = function() { + // validations are delegated to Cldr.load(). + Cldr.load.apply( Cldr, arguments ); }; /** @@ -298,6 +336,9 @@ Globalize._alwaysArray = alwaysArray; Globalize._createError = createError; Globalize._formatMessage = formatMessage; Globalize._isPlainObject = isPlainObject; +Globalize._objectExtend = objectExtend; +Globalize._regexpEscape = regexpEscape; +Globalize._stringPad = stringPad; Globalize._validate = validate; Globalize._validateCldr = validateCldr; Globalize._validateDefaultLocale = validateDefaultLocale; diff --git a/external/globalize/globalize/date.js b/external/globalize/globalize/date.js index 48d0080ac41..9f26a105de5 100644 --- a/external/globalize/globalize/date.js +++ b/external/globalize/globalize/date.js @@ -1,13 +1,17 @@ -/*! - * Globalize v1.0.0-alpha.7 +/** + * Globalize v1.0.0 * * http://github.com/jquery/globalize * - * Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors + * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2014-09-30T12:31Z + * Date: 2015-04-23T12:02Z + */ +/*! + * Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license + * http://git.io/TrdQbw */ (function( root, factory ) { @@ -18,6 +22,7 @@ define([ "cldr", "../globalize", + "./number", "cldr/event", "cldr/supplemental" ], factory ); @@ -33,12 +38,17 @@ }(this, function( Cldr, Globalize ) { var createError = Globalize._createError, + createErrorUnsupportedFeature = Globalize._createErrorUnsupportedFeature, formatMessage = Globalize._formatMessage, - isPlainObject = Globalize._isPlainObject, + numberSymbol = Globalize._numberSymbol, + regexpEscape = Globalize._regexpEscape, + stringPad = Globalize._stringPad, validateCldr = Globalize._validateCldr, validateDefaultLocale = Globalize._validateDefaultLocale, validateParameterPresence = Globalize._validateParameterPresence, - validateParameterType = Globalize._validateParameterType; + validateParameterType = Globalize._validateParameterType, + validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject, + validateParameterTypeString = Globalize._validateParameterTypeString; var validateParameterTypeDate = function( value, name ) { @@ -48,30 +58,6 @@ var validateParameterTypeDate = function( value, name ) { -var validateParameterTypeDatePattern = function( value, name ) { - validateParameterType( - value, - name, - value === undefined || typeof value === "string" || isPlainObject( value ), - "String or plain Object" - ); -}; - - - - -var validateParameterTypeString = function( value, name ) { - validateParameterType( - value, - name, - value === undefined || typeof value === "string", - "a string" - ); -}; - - - - var createErrorInvalidParameterValue = function( name, value ) { return createError( "E_INVALID_PAR_VALUE", "Invalid `{name}` value ({value}).", { name: name, @@ -83,14 +69,14 @@ var createErrorInvalidParameterValue = function( name, value ) { /** - * expandPattern( pattern, cldr ) + * expandPattern( options, cldr ) * - * @pattern [String or Object] if String, it's considered a skeleton. Object accepts: + * @options [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. + * - raw: [String] For more info see datetime/format.js. * * @cldr [Cldr instance]. * @@ -101,59 +87,78 @@ var createErrorInvalidParameterValue = function( name, value ) { * - { 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"; + * - { raw: "dd/mm" } returns "dd/mm"; */ -var dateExpandPattern = function( pattern, cldr ) { - var result; - if ( typeof pattern === "string" ) { - pattern = { skeleton: pattern }; +var dateExpandPattern = function( options, cldr ) { + var dateSkeleton, result, skeleton, timeSkeleton, type; + + function combineDateTime( type, datePattern, timePattern ) { + return formatMessage( + cldr.main([ + "dates/calendars/gregorian/dateTimeFormats", + type + ]), + [ timePattern, datePattern ] + ); } switch ( true ) { - case "skeleton" in pattern: + case "skeleton" in options: + skeleton = options.skeleton; result = cldr.main([ "dates/calendars/gregorian/dateTimeFormats/availableFormats", - pattern.skeleton + skeleton ]); + if ( !result ) { + timeSkeleton = skeleton.split( /[^hHKkmsSAzZOvVXx]/ ).slice( -1 )[ 0 ]; + dateSkeleton = skeleton.split( /[^GyYuUrQqMLlwWdDFgEec]/ )[ 0 ]; + if ( /(MMMM|LLLL).*[Ec]/.test( dateSkeleton ) ) { + type = "full"; + } else if ( /MMMM/g.test( dateSkeleton ) ) { + type = "long"; + } else if ( /MMM/g.test( dateSkeleton ) || /LLL/g.test( dateSkeleton ) ) { + type = "medium"; + } else { + type = "short"; + } + result = combineDateTime( type, + cldr.main([ + "dates/calendars/gregorian/dateTimeFormats/availableFormats", + dateSkeleton + ]), + cldr.main([ + "dates/calendars/gregorian/dateTimeFormats/availableFormats", + timeSkeleton + ]) + ); + } break; - case "date" in pattern: - case "time" in pattern: + case "date" in options: + case "time" in options: result = cldr.main([ "dates/calendars/gregorian", - "date" in pattern ? "dateFormats" : "timeFormats", - ( pattern.date || pattern.time ) + "date" in options ? "dateFormats" : "timeFormats", + ( options.date || options.time ) ]); break; - case "datetime" in pattern: - result = cldr.main([ - "dates/calendars/gregorian/dateTimeFormats", - pattern.datetime - ]); - if ( result ) { - result = formatMessage( result, [ - cldr.main([ - "dates/calendars/gregorian/timeFormats", - pattern.datetime - ]), - cldr.main([ - "dates/calendars/gregorian/dateFormats", - pattern.datetime - ]) - ]); - } + case "datetime" in options: + result = combineDateTime( options.datetime, + cldr.main([ "dates/calendars/gregorian/dateFormats", options.datetime ]), + cldr.main([ "dates/calendars/gregorian/timeFormats", options.datetime ]) + ); break; - case "pattern" in pattern: - result = pattern.pattern; + case "raw" in options: + result = options.raw; break; default: throw createErrorInvalidParameterValue({ - name: "pattern", - value: pattern + name: "options", + value: options }); } @@ -270,20 +275,51 @@ var dateMillisecondsInDay = function( date ) { -var datePatternRe = (/([a-z])\1*|'[^']+'|''|./ig); +var datePatternRe = (/([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; +/** + * hourFormat( date, format, timeSeparator, formatNumber ) + * + * Return date's timezone offset according to the format passed. + * Eg for format when timezone offset is 180: + * - "+H;-H": -3 + * - "+HHmm;-HHmm": -0300 + * - "+HH:mm;-HH:mm": -03:00 + */ +var dateTimezoneHourFormat = function( date, format, timeSeparator, formatNumber ) { + var absOffset, + offset = date.getTimezoneOffset(); + + absOffset = Math.abs( offset ); + formatNumber = formatNumber || { + 1: function( value ) { + return stringPad( value, 1 ); + }, + 2: function( value ) { + return stringPad( value, 2 ); + } + }; + + return format + + // Pick the correct sign side (+ or -). + .split( ";" )[ offset > 0 ? 1 : 0 ] + + // Localize time separator + .replace( ":", timeSeparator ) + + // Update hours offset. + .replace( /HH?/, function( match ) { + return formatNumber[ match.length ]( Math.floor( absOffset / 60 ) ); + }) + + // Update minutes offset and return. + .replace( /mm/, function() { + return formatNumber[ 2 ]( absOffset % 60 ); + }); }; @@ -300,9 +336,11 @@ var stringPad = function( str, count, right ) { * * Disclosure: this function borrows excerpts of dojo/date/locale. */ -var dateFormat = function( date, properties ) { +var dateFormat = function( date, numberFormatters, properties ) { + var timeSeparator = properties.timeSeparator; + return properties.pattern.replace( datePatternRe, function( current ) { - var pad, ret, + var ret, chr = current.charAt( 0 ), length = current.length; @@ -312,6 +350,24 @@ var dateFormat = function( date, properties ) { chr = properties.preferredTime; } + if ( chr === "Z" ) { + // Z..ZZZ: same as "xxxx". + if ( length < 4 ) { + chr = "x"; + length = 4; + + // ZZZZ: same as "OOOO". + } else if ( length < 5 ) { + chr = "O"; + length = 4; + + // ZZZZZ: same as "XXXXX" + } else { + chr = "X"; + length = 5; + } + } + switch ( chr ) { // Era @@ -324,10 +380,10 @@ var dateFormat = function( date, properties ) { // Plain year. // The length specifies the padding, but for two letters it also specifies the // maximum length. - ret = String( date.getFullYear() ); - pad = true; + ret = date.getFullYear(); if ( length === 2 ) { - ret = ret.substr( ret.length - 2 ); + ret = String( ret ); + ret = +ret.substr( ret.length - 2 ); } break; @@ -343,24 +399,18 @@ var dateFormat = function( date, properties ) { properties.firstDay - properties.minDays ); - ret = String( ret.getFullYear() ); - pad = true; + ret = ret.getFullYear(); if ( length === 2 ) { - ret = ret.substr( ret.length - 2 ); + ret = String( ret ); + 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 { + if ( length > 2 ) { ret = properties.quarters[ chr ][ length ][ ret ]; } break; @@ -369,9 +419,7 @@ var dateFormat = function( date, properties ) { case "M": case "L": ret = date.getMonth() + 1; - if ( length <= 2 ) { - pad = true; - } else { + if ( length > 2 ) { ret = properties.months[ chr ][ length ][ ret ]; } break; @@ -384,7 +432,6 @@ var dateFormat = function( date, properties ) { ret = dateDayOfWeek( dateStartOf( date, "year" ), properties.firstDay ); ret = Math.ceil( ( dateDayOfYear( date ) + ret ) / 7 ) - ( 7 - ret >= properties.minDays ? 0 : 1 ); - pad = true; break; case "W": @@ -398,12 +445,10 @@ var dateFormat = function( date, properties ) { // Day case "d": ret = date.getDate(); - pad = true; break; case "D": ret = dateDayOfYear( date ) + 1; - pad = true; break; case "F": @@ -411,10 +456,6 @@ var dateFormat = function( date, properties ) { 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": @@ -422,7 +463,6 @@ var dateFormat = function( date, properties ) { // Range is [1-7] (deduced by example provided on documentation) // TODO Should pad with zeros (not specified in the docs)? ret = dateDayOfWeek( date, properties.firstDay ) + 1; - pad = true; break; } @@ -440,65 +480,93 @@ var dateFormat = function( date, properties ) { // 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( dateMillisecondsInDay( 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": + // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT". + // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT". + if ( date.getTimezoneOffset() === 0 ) { + ret = properties.gmtZeroFormat; + } else { + ret = dateTimezoneHourFormat( + date, + length < 4 ? "+H;-H" : properties.tzLongHourFormat, + timeSeparator, + numberFormatters + ); + ret = properties.gmtFormat.replace( /\{0\}/, ret ); + } + break; + case "X": + // Same as x*, except it uses "Z" for zero offset. + if ( date.getTimezoneOffset() === 0 ) { + ret = "Z"; + break; + } + + /* falls through */ case "x": - throw new Error( "Not implemented" ); + // x: hourFormat("+HH;-HH") + // xx or xxxx: hourFormat("+HHmm;-HHmm") + // xxx or xxxxx: hourFormat("+HH:mm;-HH:mm") + ret = length === 1 ? "+HH;-HH" : ( length % 2 ? "+HH:mm;-HH:mm" : "+HHmm;-HHmm" ); + ret = dateTimezoneHourFormat( date, ret, ":" ); + break; + + // timeSeparator + case ":": + ret = timeSeparator; + break; - // Anything else is considered a literal, including [ ,:/.'@#], chinese, japonese, and + // ' literals. + case "'": + current = current.replace( /''/, "'" ); + if ( length > 2 ) { + current = current.slice( 1, -1 ); + } + ret = current; + break; + + // Anything else is considered a literal, including [ ,:/.@#], chinese, japonese, and // arabic characters. default: - return current; + ret = current; } - if ( pad ) { - ret = stringPad( ret, length ); + if ( typeof ret === "number" ) { + ret = numberFormatters[ length ]( ret ); } return ret; }); @@ -520,12 +588,22 @@ var dateFormat = function( date, properties ) { * TODO Support other calendar types. */ var dateFormatProperties = function( pattern, cldr ) { - var properties = {}, + var properties = { + pattern: pattern, + timeSeparator: numberSymbol( "timeSeparator", cldr ) + }, widths = [ "abbreviated", "wide", "narrow" ]; - properties.pattern = pattern; + function setNumberFormatterPattern( pad ) { + if ( !properties.numberFormatters ) { + properties.numberFormatters = {}; + } + properties.numberFormatters[ pad ] = stringPad( "", pad ); + } + pattern.replace( datePatternRe, function( current ) { - var chr = current.charAt( 0 ), + var formatNumber, + chr = current.charAt( 0 ), length = current.length; if ( chr === "j" ) { @@ -534,6 +612,12 @@ var dateFormatProperties = function( pattern, cldr ) { properties.preferredTime = chr = cldr.supplemental.timeData.preferred(); } + // ZZZZ: same as "OOOO". + if ( chr === "Z" && length === 4 ) { + chr = "O"; + length = 4; + } + switch ( chr ) { // Era @@ -544,15 +628,24 @@ var dateFormatProperties = function( pattern, cldr ) { ]); break; + // Year + case "y": + // Plain year. + formatNumber = true; + break; + case "Y": // Year in "Week of Year" properties.firstDay = dateFirstDayOfWeek( cldr ); properties.minDays = cldr.supplemental.weekData.minDays(); + formatNumber = true; break; case "u": // Extended year. Need to be implemented. case "U": // Cyclic year name. Need to be implemented. - throw new Error( "Not implemented" ); + throw createErrorUnsupportedFeature({ + feature: "year pattern `" + chr + "`" + }); // Quarter case "Q": @@ -569,6 +662,8 @@ var dateFormatProperties = function( pattern, cldr ) { chr === "Q" ? "format" : "stand-alone", widths[ length - 3 ] ]); + } else { + formatNumber = true; } break; @@ -587,6 +682,8 @@ var dateFormatProperties = function( pattern, cldr ) { chr === "M" ? "format" : "stand-alone", widths[ length - 3 ] ]); + } else { + formatNumber = true; } break; @@ -595,13 +692,28 @@ var dateFormatProperties = function( pattern, cldr ) { case "W": properties.firstDay = dateFirstDayOfWeek( cldr ); properties.minDays = cldr.supplemental.weekData.minDays(); + formatNumber = true; break; + // Day + case "d": + case "D": + case "F": + formatNumber = true; + break; + + case "g": + // Modified Julian day. Need to be implemented. + throw createErrorUnsupportedFeature({ + feature: "Julian day pattern `g`" + }); + // Week day case "e": case "c": if ( length <= 2 ) { properties.firstDay = dateFirstDayOfWeek( cldr ); + formatNumber = true; break; } @@ -644,17 +756,48 @@ var dateFormatProperties = function( pattern, cldr ) { ); break; + // Hour + case "h": // 1-12 + case "H": // 0-23 + case "K": // 0-11 + case "k": // 1-24 + + // Minute + case "m": + + // Second + case "s": + case "S": + case "A": + formatNumber = 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": + // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT". + // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT". + properties.gmtFormat = cldr.main( "dates/timeZoneNames/gmtFormat" ); + properties.gmtZeroFormat = cldr.main( "dates/timeZoneNames/gmtZeroFormat" ); + properties.tzLongHourFormat = cldr.main( "dates/timeZoneNames/hourFormat" ); + + /* falls through */ + case "Z": case "X": case "x": - throw new Error( "Not implemented" ); + setNumberFormatterPattern( 1 ); + setNumberFormatterPattern( 2 ); + break; + + case "v": + case "V": + throw createErrorUnsupportedFeature({ + feature: "timezone pattern `" + chr + "`" + }); + } + + if ( formatNumber ) { + setNumberFormatterPattern( length ); } }); @@ -664,6 +807,34 @@ var dateFormatProperties = function( pattern, cldr ) { +/** + * isLeapYear( year ) + * + * @year [Number] + * + * Returns an indication whether the specified year is a leap year. + */ +var dateIsLeapYear = function( year ) { + return new Date(year, 1, 29).getMonth() === 1; +}; + + + + +/** + * lastDayOfMonth( date ) + * + * @date [Date] + * + * Return the last day of the given date's month + */ +var dateLastDayOfMonth = function( date ) { + return new Date( date.getFullYear(), date.getMonth() + 1, 0).getDate(); +}; + + + + /** * Differently from native date.setDate(), this function returns a date whose * day remains inside the month boundaries. For example: @@ -696,11 +867,14 @@ var dateSetMonth = function( date, month ) { }; -var dateParse = (function() { -function outOfRange( value, low, high ) { + +var outOfRange = function( value, low, high ) { return value < low || value > high; -} +}; + + + /** * parse( value, tokens, properties ) @@ -713,8 +887,8 @@ function outOfRange( value, low, high ) { * * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns */ -return function( value, tokens, properties ) { - var amPm, era, hour, hour12, valid, +var dateParse = function( value, tokens, properties ) { + var amPm, day, daysOfYear, era, hour, hour12, timezoneOffset, valid, YEAR = 0, MONTH = 1, DAY = 2, @@ -757,7 +931,7 @@ return function( value, tokens, properties ) { // Year case "y": - value = +token.lexeme; + value = token.value; if ( length === 2 ) { if ( outOfRange( value, 0, 99 ) ) { return false; @@ -775,9 +949,9 @@ return function( value, tokens, properties ) { 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" ); + throw createErrorUnsupportedFeature({ + feature: "year pattern `" + chr + "`" + }); // Quarter (skip) case "Q": @@ -788,7 +962,7 @@ return function( value, tokens, properties ) { case "M": case "L": if ( length <= 2 ) { - value = +token.lexeme; + value = token.value; } else { value = +token.value; } @@ -806,21 +980,12 @@ return function( value, tokens, properties ) { // Day case "d": - value = +token.lexeme; - if ( outOfRange( value, 1, 31 ) ) { - return false; - } - dateSetDate( date, value ); + day = token.value; truncateAt.push( DAY ); break; case "D": - value = +token.lexeme; - if ( outOfRange( value, 1, 366 ) ) { - return false; - } - date.setMonth(0); - date.setDate( value ); + daysOfYear = token.value; truncateAt.push( DAY ); break; @@ -829,10 +994,6 @@ return function( value, tokens, properties ) { // Skip break; - case "g+": - // Modified Julian day. Need to be implemented. - throw new Error( "Not implemented" ); - // Week day case "e": case "c": @@ -848,7 +1009,7 @@ return function( value, tokens, properties ) { // Hour case "h": // 1-12 - value = +token.lexeme; + value = token.value; if ( outOfRange( value, 1, 12 ) ) { return false; } @@ -858,7 +1019,7 @@ return function( value, tokens, properties ) { break; case "K": // 0-11 - value = +token.lexeme; + value = token.value; if ( outOfRange( value, 0, 11 ) ) { return false; } @@ -868,7 +1029,7 @@ return function( value, tokens, properties ) { break; case "k": // 1-24 - value = +token.lexeme; + value = token.value; if ( outOfRange( value, 1, 24 ) ) { return false; } @@ -878,7 +1039,7 @@ return function( value, tokens, properties ) { break; case "H": // 0-23 - value = +token.lexeme; + value = token.value; if ( outOfRange( value, 0, 23 ) ) { return false; } @@ -889,7 +1050,7 @@ return function( value, tokens, properties ) { // Minute case "m": - value = +token.lexeme; + value = token.value; if ( outOfRange( value, 0, 59 ) ) { return false; } @@ -899,7 +1060,7 @@ return function( value, tokens, properties ) { // Second case "s": - value = +token.lexeme; + value = token.value; if ( outOfRange( value, 0, 59 ) ) { return false; } @@ -914,22 +1075,19 @@ return function( value, tokens, properties ) { /* falls through */ case "S": - value = Math.round( +token.lexeme * Math.pow( 10, 3 - length ) ); + value = Math.round( token.value * 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 "z": case "O": - case "v": - case "V": case "X": case "x": - throw new Error( "Not implemented" ); + timezoneOffset = token.value - date.getTimezoneOffset(); + break; } return true; @@ -950,10 +1108,27 @@ return function( value, tokens, properties ) { date.setFullYear( date.getFullYear() * -1 + 1 ); } + if ( day !== undefined ) { + if ( outOfRange( day, 1, dateLastDayOfMonth( date ) ) ) { + return null; + } + date.setDate( day ); + } else if ( daysOfYear !== undefined ) { + if ( outOfRange( daysOfYear, 1, dateIsLeapYear( date.getFullYear() ) ? 366 : 365 ) ) { + return null; + } + date.setMonth(0); + date.setDate( daysOfYear ); + } + if ( hour12 && amPm === "pm" ) { date.setHours( date.getHours() + 12 ); } + if ( timezoneOffset ) { + date.setMinutes( date.getMinutes() + timezoneOffset ); + } + // 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 ); @@ -963,7 +1138,7 @@ return function( value, tokens, properties ) { return date; }; -}()); + /** @@ -982,6 +1157,19 @@ var dateParseProperties = function( cldr ) { +/** + * Generated by: + * + * regenerate().add( require( "unicode-7.0.0/categories/N/symbols" ) ).toString(); + * + * https://github.com/mathiasbynens/regenerate + * https://github.com/mathiasbynens/unicode-7.0.0 + */ +var regexpN = /[0-9\xB2\xB3\xB9\xBC-\xBE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]|\uD800[\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDEE1-\uDEFB\uDF20-\uDF23\uDF41\uDF4A\uDFD1-\uDFD5]|\uD801[\uDCA0-\uDCA9]|\uD802[\uDC58-\uDC5F\uDC79-\uDC7F\uDCA7-\uDCAF\uDD16-\uDD1B\uDE40-\uDE47\uDE7D\uDE7E\uDE9D-\uDE9F\uDEEB-\uDEEF\uDF58-\uDF5F\uDF78-\uDF7F\uDFA9-\uDFAF]|\uD803[\uDE60-\uDE7E]|\uD804[\uDC52-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9\uDDE1-\uDDF4\uDEF0-\uDEF9]|\uD805[\uDCD0-\uDCD9\uDE50-\uDE59\uDEC0-\uDEC9]|\uD806[\uDCE0-\uDCF2]|\uD809[\uDC00-\uDC6E]|\uD81A[\uDE60-\uDE69\uDF50-\uDF59\uDF5B-\uDF61]|\uD834[\uDF60-\uDF71]|\uD835[\uDFCE-\uDFFF]|\uD83A[\uDCC7-\uDCCF]|\uD83C[\uDD00-\uDD0C]/; + + + + /** * tokenizer( value, pattern, properties ) * @@ -1013,30 +1201,100 @@ var dateParseProperties = function( cldr ) { * * Return an empty Array when not successfully parsed. */ -var dateTokenizer = function( value, properties ) { +var dateTokenizer = function( value, numberParser, properties ) { var valid, + timeSeparator = properties.timeSeparator, tokens = [], widths = [ "abbreviated", "wide", "narrow" ]; valid = properties.pattern.match( datePatternRe ).every(function( current ) { - var chr, length, tokenRe, + var chr, length, numeric, tokenRe, token = {}; + function hourFormatParse( tokenRe, numberParser ) { + var aux = value.match( tokenRe ); + numberParser = numberParser || function( value ) { + return +value; + }; + + if ( !aux ) { + return false; + } + + // hourFormat containing H only, e.g., `+H;-H` + if ( aux.length < 8 ) { + token.value = + ( aux[ 1 ] ? -numberParser( aux[ 1 ] ) : numberParser( aux[ 4 ] ) ) * 60; + + // hourFormat containing H and m, e.g., `+HHmm;-HHmm` + } else { + token.value = + ( aux[ 1 ] ? -numberParser( aux[ 1 ] ) : numberParser( aux[ 7 ] ) ) * 60 + + ( aux[ 1 ] ? -numberParser( aux[ 4 ] ) : numberParser( aux[ 10 ] ) ); + } + + return true; + } + + // Transform: + // - "+H;-H" -> /\+(\d\d?)|-(\d\d?)/ + // - "+HH;-HH" -> /\+(\d\d)|-(\d\d)/ + // - "+HHmm;-HHmm" -> /\+(\d\d)(\d\d)|-(\d\d)(\d\d)/ + // - "+HH:mm;-HH:mm" -> /\+(\d\d):(\d\d)|-(\d\d):(\d\d)/ + // + // If gmtFormat is GMT{0}, the regexp must fill {0} in each side, e.g.: + // - "+H;-H" -> /GMT\+(\d\d?)|GMT-(\d\d?)/ + function hourFormatRe( hourFormat, gmtFormat, timeSeparator ) { + var re; + + if ( !gmtFormat ) { + gmtFormat = "{0}"; + } + + re = hourFormat + .replace( "+", "\\+" ) + + // Unicode equivalent to (\\d\\d) + .replace( /HH|mm/g, "((" + regexpN.source + ")(" + regexpN.source + "))" ) + + // Unicode equivalent to (\\d\\d?) + .replace( /H|m/g, "((" + regexpN.source + ")(" + regexpN.source + ")?)" ); + + if ( timeSeparator ) { + re = re.replace( /:/g, timeSeparator ); + } + + re = re.split( ";" ).map(function( part ) { + return gmtFormat.replace( "{0}", part ); + }).join( "|" ); + + return new RegExp( re ); + } + function oneDigitIfLengthOne() { if ( length === 1 ) { - return tokenRe = /\d/; + + // Unicode equivalent to /\d/ + numeric = true; + return tokenRe = regexpN; } } function oneOrTwoDigitsIfLengthOne() { if ( length === 1 ) { - return tokenRe = /\d\d?/; + + // Unicode equivalent to /\d\d?/ + numeric = true; + return tokenRe = new RegExp( "(" + regexpN.source + ")(" + regexpN.source + ")?" ); } } function twoDigitsIfLengthTwo() { if ( length === 2 ) { - return tokenRe = /\d\d/; + + // Unicode equivalent to /\d\d/ + numeric = true; + return tokenRe = new RegExp( "(" + regexpN.source + ")(" + regexpN.source + ")" ); } } @@ -1044,7 +1302,7 @@ var dateTokenizer = function( value, properties ) { // Return the first found one (and set token accordingly), or null. function lookup( path ) { var i, re, - data = properties[ path.join( "/" ).replace( /^.*calendars\//, "" ) ]; + data = properties[ path.join( "/" ) ]; for ( i in data ) { re = new RegExp( "^" + data[ i ] ); @@ -1060,12 +1318,30 @@ var dateTokenizer = function( value, properties ) { chr = current.charAt( 0 ), length = current.length; + if ( chr === "Z" ) { + // Z..ZZZ: same as "xxxx". + if ( length < 4 ) { + chr = "x"; + length = 4; + + // ZZZZ: same as "OOOO". + } else if ( length < 5 ) { + chr = "O"; + length = 4; + + // ZZZZZ: same as "XXXXX" + } else { + chr = "X"; + length = 5; + } + } + switch ( chr ) { // Era case "G": lookup([ - "dates/calendars/gregorian/eras", + "gregorian/eras", length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" ) ]); break; @@ -1073,27 +1349,31 @@ var dateTokenizer = function( value, properties ) { // Year case "y": case "Y": + numeric = true; + // number l=1:+, l=2:{2}, l=3:{3,}, l=4:{4,}, ... if ( length === 1 ) { - tokenRe = /\d+/; + + // Unicode equivalent to /\d+/. + tokenRe = new RegExp( "(" + regexpN.source + ")+" ); } else if ( length === 2 ) { - tokenRe = /\d\d/; + + // Unicode equivalent to /\d\d/ + tokenRe = new RegExp( "(" + regexpN.source + ")(" + regexpN.source + ")" ); } else { - tokenRe = new RegExp( "\\d{" + length + ",}" ); + + // Unicode equivalent to /\d{length,}/ + tokenRe = new RegExp( "(" + regexpN.source + "){" + 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", + "gregorian/quarters", chr === "Q" ? "format" : "stand-alone", widths[ length - 3 ] ]); @@ -1105,17 +1385,20 @@ var dateTokenizer = function( value, properties ) { // number l=1:{1,2}, l=2:{2}. // lookup l=3... oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo() || lookup([ - "dates/calendars/gregorian/months", + "gregorian/months", chr === "M" ? "format" : "stand-alone", widths[ length - 3 ] ]); break; - // Day (see d below) + // Day case "D": // number {l,3}. if ( length <= 3 ) { - tokenRe = new RegExp( "\\d{" + length + ",3}" ); + + // Unicode equivalent to /\d{length,3}/ + numeric = true; + tokenRe = new RegExp( "(" + regexpN.source + "){" + length + ",3}" ); } break; @@ -1125,10 +1408,6 @@ var dateTokenizer = function( value, properties ) { oneDigitIfLengthOne(); break; - case "g+": - // Modified Julian day. Need to be implemented. - throw new Error( "Not implemented" ); - // Week day case "e": case "c": @@ -1145,17 +1424,17 @@ var dateTokenizer = function( value, properties ) { // 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", + "gregorian/days", [ chr === "c" ? "stand-alone" : "format" ], "short" ]) || lookup([ - "dates/calendars/gregorian/days", + "gregorian/days", [ chr === "c" ? "stand-alone" : "format" ], "abbreviated" ]); } else { lookup([ - "dates/calendars/gregorian/days", + "gregorian/days", [ chr === "c" ? "stand-alone" : "format" ], widths[ length < 3 ? 0 : length - 3 ] ]); @@ -1165,7 +1444,7 @@ var dateTokenizer = function( value, properties ) { // Period (AM or PM) case "a": lookup([ - "dates/calendars/gregorian/dayPeriods/format/wide" + "gregorian/dayPeriods/format/wide" ]); break; @@ -1185,33 +1464,68 @@ var dateTokenizer = function( value, properties ) { case "S": // number {l}. - tokenRe = new RegExp( "\\d{" + length + "}" ); + + // Unicode equivalent to /\d{length}/ + numeric = true; + tokenRe = new RegExp( "(" + regexpN.source + "){" + length + "}" ); break; case "A": // number {l+5}. - tokenRe = new RegExp( "\\d{" + ( length + 5 ) + "}" ); + + // Unicode equivalent to /\d{length+5}/ + numeric = true; + tokenRe = new RegExp( "(" + regexpN.source + "){" + ( 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": + // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT". + // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT". + if ( value === properties[ "timeZoneNames/gmtZeroFormat" ] ) { + token.value = 0; + tokenRe = new RegExp( properties[ "timeZoneNames/gmtZeroFormat" ] ); + } else { + tokenRe = hourFormatRe( + length < 4 ? "+H;-H" : properties[ "timeZoneNames/hourFormat" ], + properties[ "timeZoneNames/gmtFormat" ], + timeSeparator + ); + if ( !hourFormatParse( tokenRe, numberParser ) ) { + return null; + } + } + break; + case "X": + // Same as x*, except it uses "Z" for zero offset. + if ( value === "Z" ) { + token.value = 0; + tokenRe = /Z/; + break; + } + + /* falls through */ case "x": - throw new Error( "Not implemented" ); + // x: hourFormat("+HH;-HH") + // xx or xxxx: hourFormat("+HHmm;-HHmm") + // xxx or xxxxx: hourFormat("+HH:mm;-HH:mm") + tokenRe = hourFormatRe( + length === 1 ? "+HH;-HH" : ( length % 2 ? "+HH:mm;-HH:mm" : "+HHmm;-HHmm" ) + ); + if ( !hourFormatParse( tokenRe ) ) { + return null; + } + break; case "'": token.type = "literal"; - if ( current.charAt( 1 ) === "'" ) { - tokenRe = /'/; - } else { - tokenRe = /'[^']+'/; + current = current.replace( /''/, "'" ); + if ( length > 2 ) { + current = current.slice( 1, -1 ); } + tokenRe = new RegExp( regexpEscape( current ) ); break; default: @@ -1226,6 +1540,9 @@ var dateTokenizer = function( value, properties ) { // Get lexeme and consume it. value = value.replace( new RegExp( "^" + tokenRe.source ), function( lexeme ) { token.lexeme = lexeme; + if ( numeric ) { + token.value = numberParser( lexeme ); + } return ""; }); @@ -1254,12 +1571,15 @@ var dateTokenizer = function( value, properties ) { */ var dateTokenizerProperties = function( pattern, cldr ) { var properties = { - pattern: pattern + pattern: pattern, + timeSeparator: numberSymbol( "timeSeparator", cldr ) }, widths = [ "abbreviated", "wide", "narrow" ]; function populateProperties( path, value ) { - properties[ path.replace( /^.*calendars\//, "" ) ] = value; + + // The `dates` and `calendars` trim's purpose is to reduce properties' key size only. + properties[ path.replace( /^.*\/dates\//, "" ).replace( /calendars\//, "" ) ] = value; } cldr.on( "get", populateProperties ); @@ -1270,6 +1590,11 @@ var dateTokenizerProperties = function( pattern, cldr ) { chr = current.charAt( 0 ), length = current.length; + if ( chr === "Z" && length < 5 ) { + chr = "O"; + length = 4; + } + switch ( chr ) { // Era @@ -1280,6 +1605,13 @@ var dateTokenizerProperties = function( pattern, cldr ) { ]); break; + // Year + case "u": // Extended year. Need to be implemented. + case "U": // Cyclic year name. Need to be implemented. + throw createErrorUnsupportedFeature({ + feature: "year pattern `" + chr + "`" + }); + // Quarter case "Q": case "q": @@ -1306,6 +1638,13 @@ var dateTokenizerProperties = function( pattern, cldr ) { } break; + // Day + case "g": + // Modified Julian day. Need to be implemented. + throw createErrorUnsupportedFeature({ + feature: "Julian day pattern `g`" + }); + // Week day case "e": case "c": @@ -1343,6 +1682,20 @@ var dateTokenizerProperties = function( pattern, cldr ) { "dates/calendars/gregorian/dayPeriods/format/wide" ]); break; + + // Zone + case "z": + case "O": + cldr.main( "dates/timeZoneNames/gmtFormat" ); + cldr.main( "dates/timeZoneNames/gmtZeroFormat" ); + cldr.main( "dates/timeZoneNames/hourFormat" ); + break; + + case "v": + case "V": + throw createErrorUnsupportedFeature({ + feature: "timezone pattern `" + chr + "`" + }); } }); @@ -1357,6 +1710,7 @@ var dateTokenizerProperties = function( pattern, cldr ) { function validateRequiredCldr( path, value ) { validateCldr( path, value, { skip: [ + /dates\/calendars\/gregorian\/dateTimeFormats\/availableFormats/, /dates\/calendars\/gregorian\/days\/.*\/short/, /supplemental\/timeData\/(?!001)/, /supplemental\/weekData\/(?!001)/ @@ -1365,11 +1719,11 @@ function validateRequiredCldr( path, value ) { } /** - * .dateFormatter( pattern ) + * .dateFormatter( options ) * - * @pattern [String or Object] see date/expand_pattern for more info. + * @options [Object] see date/expand_pattern for more info. * - * Return a date formatter function (of the form below) according to the given pattern and the + * Return a date formatter function (of the form below) according to the given options and the * default/instance locale. * * fn( value ) @@ -1380,96 +1734,107 @@ function validateRequiredCldr( path, value ) { * locale. */ Globalize.dateFormatter = -Globalize.prototype.dateFormatter = function( pattern ) { - var cldr, properties; +Globalize.prototype.dateFormatter = function( options ) { + var cldr, numberFormatters, pad, pattern, properties; - validateParameterPresence( pattern, "pattern" ); - validateParameterTypeDatePattern( pattern, "pattern" ); + validateParameterTypePlainObject( options, "options" ); cldr = this.cldr; + options = options || { skeleton: "yMd" }; validateDefaultLocale( cldr ); cldr.on( "get", validateRequiredCldr ); - pattern = dateExpandPattern( pattern, cldr ); + pattern = dateExpandPattern( options, cldr ); properties = dateFormatProperties( pattern, cldr ); cldr.off( "get", validateRequiredCldr ); + // Create needed number formatters. + numberFormatters = properties.numberFormatters; + delete properties.numberFormatters; + for ( pad in numberFormatters ) { + numberFormatters[ pad ] = this.numberFormatter({ + raw: numberFormatters[ pad ] + }); + } + return function( value ) { validateParameterPresence( value, "value" ); validateParameterTypeDate( value, "value" ); - return dateFormat( value, properties ); + return dateFormat( value, numberFormatters, properties ); }; }; /** - * .dateParser( pattern ) + * .dateParser( options ) * - * @pattern [String or Object] see date/expand_pattern for more info. + * @options [Object] see date/expand_pattern for more info. * * Return a function that parses a string date according to the given `formats` and the * default/instance locale. */ Globalize.dateParser = -Globalize.prototype.dateParser = function( pattern ) { - var cldr, parseProperties, tokenizerProperties; +Globalize.prototype.dateParser = function( options ) { + var cldr, numberParser, parseProperties, pattern, tokenizerProperties; - validateParameterPresence( pattern, "pattern" ); - validateParameterTypeDatePattern( pattern, "pattern" ); + validateParameterTypePlainObject( options, "options" ); cldr = this.cldr; + options = options || { skeleton: "yMd" }; validateDefaultLocale( cldr ); cldr.on( "get", validateRequiredCldr ); - pattern = dateExpandPattern( pattern, cldr ); + pattern = dateExpandPattern( options, cldr ); tokenizerProperties = dateTokenizerProperties( pattern, cldr ); parseProperties = dateParseProperties( cldr ); cldr.off( "get", validateRequiredCldr ); + numberParser = this.numberParser({ raw: "0" }); + return function( value ) { var tokens; validateParameterPresence( value, "value" ); validateParameterTypeString( value, "value" ); - tokens = dateTokenizer( value, tokenizerProperties ); + tokens = dateTokenizer( value, numberParser, tokenizerProperties ); return dateParse( value, tokens, parseProperties ) || null; }; }; /** - * .formatDate( value, pattern ) + * .formatDate( value, options ) * * @value [Date] * - * @pattern [String or Object] see date/expand_pattern for more info. + * @options [Object] see date/expand_pattern for more info. * - * Formats a date or number according to the given pattern string and the default/instance locale. + * Formats a date or number according to the given options string and the default/instance locale. */ Globalize.formatDate = -Globalize.prototype.formatDate = function( value, pattern ) { +Globalize.prototype.formatDate = function( value, options ) { validateParameterPresence( value, "value" ); validateParameterTypeDate( value, "value" ); - return this.dateFormatter( pattern )( value ); + return this.dateFormatter( options )( value ); }; /** - * .parseDate( value, pattern ) + * .parseDate( value, options ) * * @value [String] * - * @pattern [String or Object] see date/expand_pattern for more info. + * @options [Object] see date/expand_pattern for more info. * * Return a Date instance or null. */ Globalize.parseDate = -Globalize.prototype.parseDate = function( value, pattern ) { +Globalize.prototype.parseDate = function( value, options ) { validateParameterPresence( value, "value" ); validateParameterTypeString( value, "value" ); - return this.dateParser( pattern )( value ); + return this.dateParser( options )( value ); }; return Globalize; diff --git a/external/globalize/globalize/number.js b/external/globalize/globalize/number.js new file mode 100644 index 00000000000..7ab4256d48c --- /dev/null +++ b/external/globalize/globalize/number.js @@ -0,0 +1,1266 @@ +/** + * Globalize v1.0.0 + * + * http://github.com/jquery/globalize + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-04-23T12:02Z + */ +/*! + * Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license + * http://git.io/TrdQbw + */ +(function( root, factory ) { + + // UMD returnExports + if ( typeof define === "function" && define.amd ) { + + // AMD + define([ + "cldr", + "../globalize", + "cldr/event", + "cldr/supplemental" + ], factory ); + } else if ( typeof exports === "object" ) { + + // Node, CommonJS + module.exports = factory( require( "cldrjs" ), require( "globalize" ) ); + } else { + + // Global + factory( root.Cldr, root.Globalize ); + } +}(this, function( Cldr, Globalize ) { + +var createError = Globalize._createError, + objectExtend = Globalize._objectExtend, + regexpEscape = Globalize._regexpEscape, + stringPad = Globalize._stringPad, + validateCldr = Globalize._validateCldr, + validateDefaultLocale = Globalize._validateDefaultLocale, + validateParameterPresence = Globalize._validateParameterPresence, + validateParameterRange = Globalize._validateParameterRange, + validateParameterType = Globalize._validateParameterType, + validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject; + + +var createErrorUnsupportedFeature = function( feature ) { + return createError( "E_UNSUPPORTED", "Unsupported {feature}.", { + feature: feature + }); +}; + + + + +var validateParameterTypeNumber = function( value, name ) { + validateParameterType( + value, + name, + value === undefined || typeof value === "number", + "Number" + ); +}; + + + + +var validateParameterTypeString = function( value, name ) { + validateParameterType( + value, + name, + value === undefined || typeof value === "string", + "a string" + ); +}; + + + + +/** + * goupingSeparator( number, primaryGroupingSize, secondaryGroupingSize ) + * + * @number [Number]. + * + * @primaryGroupingSize [Number] + * + * @secondaryGroupingSize [Number] + * + * Return the formatted number with group separator. + */ +var numberFormatGroupingSeparator = function( number, primaryGroupingSize, secondaryGroupingSize ) { + var index, + currentGroupingSize = primaryGroupingSize, + ret = "", + sep = ",", + switchToSecondary = secondaryGroupingSize ? true : false; + + number = String( number ).split( "." ); + index = number[ 0 ].length; + + while ( index > currentGroupingSize ) { + ret = number[ 0 ].slice( index - currentGroupingSize, index ) + + ( ret.length ? sep : "" ) + ret; + index -= currentGroupingSize; + if ( switchToSecondary ) { + currentGroupingSize = secondaryGroupingSize; + switchToSecondary = false; + } + } + + number[ 0 ] = number[ 0 ].slice( 0, index ) + ( ret.length ? sep : "" ) + ret; + return number.join( "." ); +}; + + + + +/** + * integerFractionDigits( number, minimumIntegerDigits, minimumFractionDigits, + * maximumFractionDigits, round, roundIncrement ) + * + * @number [Number] + * + * @minimumIntegerDigits [Number] + * + * @minimumFractionDigits [Number] + * + * @maximumFractionDigits [Number] + * + * @round [Function] + * + * @roundIncrement [Function] + * + * Return the formatted integer and fraction digits. + */ +var numberFormatIntegerFractionDigits = function( number, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, round, + roundIncrement ) { + + // Fraction + if ( maximumFractionDigits ) { + + // Rounding + if ( roundIncrement ) { + number = round( number, roundIncrement ); + + // Maximum fraction digits + } else { + number = round( number, { exponent: -maximumFractionDigits } ); + } + + // Minimum fraction digits + if ( minimumFractionDigits ) { + number = String( number ).split( "." ); + number[ 1 ] = stringPad( number[ 1 ] || "", minimumFractionDigits, true ); + number = number.join( "." ); + } + } else { + number = round( number ); + } + + number = String( number ); + + // Minimum integer digits + if ( minimumIntegerDigits ) { + number = number.split( "." ); + number[ 0 ] = stringPad( number[ 0 ], minimumIntegerDigits ); + number = number.join( "." ); + } + + return number; +}; + + + + +/** + * toPrecision( number, precision, round ) + * + * @number (Number) + * + * @precision (Number) significant figures precision (not decimal precision). + * + * @round (Function) + * + * Return number.toPrecision( precision ) using the given round function. + */ +var numberToPrecision = function( number, precision, round ) { + var roundOrder; + + // Get number at two extra significant figure precision. + number = number.toPrecision( precision + 2 ); + + // Then, round it to the required significant figure precision. + roundOrder = Math.ceil( Math.log( Math.abs( number ) ) / Math.log( 10 ) ); + roundOrder -= precision; + + return round( number, { exponent: roundOrder } ); +}; + + + + +/** + * toPrecision( number, minimumSignificantDigits, maximumSignificantDigits, round ) + * + * @number [Number] + * + * @minimumSignificantDigits [Number] + * + * @maximumSignificantDigits [Number] + * + * @round [Function] + * + * Return the formatted significant digits number. + */ +var numberFormatSignificantDigits = function( number, minimumSignificantDigits, maximumSignificantDigits, round ) { + var atMinimum, atMaximum; + + // Sanity check. + if ( minimumSignificantDigits > maximumSignificantDigits ) { + maximumSignificantDigits = minimumSignificantDigits; + } + + atMinimum = numberToPrecision( number, minimumSignificantDigits, round ); + atMaximum = numberToPrecision( number, maximumSignificantDigits, round ); + + // Use atMaximum only if it has more significant digits than atMinimum. + number = +atMinimum === +atMaximum ? atMinimum : atMaximum; + + // Expand integer numbers, eg. 123e5 to 12300. + number = ( +number ).toString( 10 ); + + if ( (/e/).test( number ) ) { + throw createErrorUnsupportedFeature({ + feature: "integers out of (1e21, 1e-7)" + }); + } + + // Add trailing zeros if necessary. + if ( minimumSignificantDigits - number.replace( /^0+|\./g, "" ).length > 0 ) { + number = number.split( "." ); + number[ 1 ] = stringPad( number[ 1 ] || "", minimumSignificantDigits - number[ 0 ].replace( /^0+/, "" ).length, true ); + number = number.join( "." ); + } + + return number; +}; + + + + +/** + * format( number, properties ) + * + * @number [Number]. + * + * @properties [Object] Output of number/format-properties. + * + * Return the formatted number. + * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html + */ +var numberFormat = function( number, properties ) { + var infinitySymbol, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits, + minimumIntegerDigits, minimumSignificantDigits, nanSymbol, nuDigitsMap, padding, prefix, + primaryGroupingSize, pattern, ret, round, roundIncrement, secondaryGroupingSize, suffix, + symbolMap; + + padding = properties[ 1 ]; + minimumIntegerDigits = properties[ 2 ]; + minimumFractionDigits = properties[ 3 ]; + maximumFractionDigits = properties[ 4 ]; + minimumSignificantDigits = properties[ 5 ]; + maximumSignificantDigits = properties[ 6 ]; + roundIncrement = properties[ 7 ]; + primaryGroupingSize = properties[ 8 ]; + secondaryGroupingSize = properties[ 9 ]; + round = properties[ 15 ]; + infinitySymbol = properties[ 16 ]; + nanSymbol = properties[ 17 ]; + symbolMap = properties[ 18 ]; + nuDigitsMap = properties[ 19 ]; + + // NaN + if ( isNaN( number ) ) { + return nanSymbol; + } + + if ( number < 0 ) { + pattern = properties[ 12 ]; + prefix = properties[ 13 ]; + suffix = properties[ 14 ]; + } else { + pattern = properties[ 11 ]; + prefix = properties[ 0 ]; + suffix = properties[ 10 ]; + } + + // Infinity + if ( !isFinite( number ) ) { + return prefix + infinitySymbol + suffix; + } + + ret = prefix; + + // Percent + if ( pattern.indexOf( "%" ) !== -1 ) { + number *= 100; + + // Per mille + } else if ( pattern.indexOf( "\u2030" ) !== -1 ) { + number *= 1000; + } + + // Significant digit format + if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) { + number = numberFormatSignificantDigits( number, minimumSignificantDigits, + maximumSignificantDigits, round ); + + // Integer and fractional format + } else { + number = numberFormatIntegerFractionDigits( number, minimumIntegerDigits, + minimumFractionDigits, maximumFractionDigits, round, roundIncrement ); + } + + // Remove the possible number minus sign + number = number.replace( /^-/, "" ); + + // Grouping separators + if ( primaryGroupingSize ) { + number = numberFormatGroupingSeparator( number, primaryGroupingSize, + secondaryGroupingSize ); + } + + ret += number; + + // Scientific notation + // TODO implement here + + // Padding/'([^']|'')+'|''|[.,\-+E%\u2030]/g + // TODO implement here + + ret += suffix; + + return ret.replace( /('([^']|'')+'|'')|./g, function( character, literal ) { + + // Literals + if ( literal ) { + literal = literal.replace( /''/, "'" ); + if ( literal.length > 2 ) { + literal = literal.slice( 1, -1 ); + } + return literal; + } + + // Symbols + character = character.replace( /[.,\-+E%\u2030]/, function( symbol ) { + return symbolMap[ symbol ]; + }); + + // Numbering system + if ( nuDigitsMap ) { + character = character.replace( /[0-9]/, function( digit ) { + return nuDigitsMap[ +digit ]; + }); + } + + return character; + }); +}; + + + + +/** + * NumberingSystem( cldr ) + * + * - http://www.unicode.org/reports/tr35/tr35-numbers.html#otherNumberingSystems + * - http://cldr.unicode.org/index/bcp47-extension + * - http://www.unicode.org/reports/tr35/#u_Extension + */ +var numberNumberingSystem = function( cldr ) { + var nu = cldr.attributes[ "u-nu" ]; + + if ( nu ) { + if ( nu === "traditio" ) { + nu = "traditional"; + } + if ( [ "native", "traditional", "finance" ].indexOf( nu ) !== -1 ) { + + // Unicode locale extension `u-nu` is set using either (native, traditional or + // finance). So, lookup the respective locale's numberingSystem and return it. + return cldr.main([ "numbers/otherNumberingSystems", nu ]); + } + + // Unicode locale extension `u-nu` is set with an explicit numberingSystem. Return it. + return nu; + } + + // Return the default numberingSystem. + return cldr.main( "numbers/defaultNumberingSystem" ); +}; + + + + +/** + * nuMap( cldr ) + * + * @cldr [Cldr instance]. + * + * Return digits map if numbering system is different than `latn`. + */ +var numberNumberingSystemDigitsMap = function( cldr ) { + var aux, + nu = numberNumberingSystem( cldr ); + + if ( nu === "latn" ) { + return; + } + + aux = cldr.supplemental([ "numberingSystems", nu ]); + + if ( aux._type !== "numeric" ) { + throw createErrorUnsupportedFeature( "`" + aux._type + "` numbering system" ); + } + + return aux._digits; +}; + + + + +/** + * EBNF representation: + * + * number_pattern_re = prefix? + * padding? + * (integer_fraction_pattern | significant_pattern) + * scientific_notation? + * suffix? + * + * prefix = non_number_stuff + * + * padding = "*" regexp(.) + * + * integer_fraction_pattern = integer_pattern + * fraction_pattern? + * + * integer_pattern = regexp([#,]*[0,]*0+) + * + * fraction_pattern = "." regexp(0*[0-9]*#*) + * + * significant_pattern = regexp([#,]*@+#*) + * + * scientific_notation = regexp(E\+?0+) + * + * suffix = non_number_stuff + * + * non_number_stuff = regexp(('[^']+'|''|[^*#@0,.E])*) + * + * + * Regexp groups: + * + * 0: number_pattern_re + * 1: prefix + * 2: - + * 3: padding + * 4: (integer_fraction_pattern | significant_pattern) + * 5: integer_fraction_pattern + * 6: integer_pattern + * 7: fraction_pattern + * 8: significant_pattern + * 9: scientific_notation + * 10: suffix + * 11: - + */ +var numberPatternRe = (/^(('[^']+'|''|[^*#@0,.E])*)(\*.)?((([#,]*[0,]*0+)(\.0*[0-9]*#*)?)|([#,]*@+#*))(E\+?0+)?(('[^']+'|''|[^*#@0,.E])*)$/); + + + + +/** + * format( number, pattern ) + * + * @number [Number]. + * + * @pattern [String] raw pattern for numbers. + * + * Return the formatted number. + * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html + */ +var numberPatternProperties = function( pattern ) { + var aux1, aux2, fractionPattern, integerFractionOrSignificantPattern, integerPattern, + maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits, + minimumIntegerDigits, minimumSignificantDigits, padding, prefix, primaryGroupingSize, + roundIncrement, scientificNotation, secondaryGroupingSize, significantPattern, suffix; + + pattern = pattern.match( numberPatternRe ); + if ( !pattern ) { + throw new Error( "Invalid pattern: " + pattern ); + } + + prefix = pattern[ 1 ]; + padding = pattern[ 3 ]; + integerFractionOrSignificantPattern = pattern[ 4 ]; + significantPattern = pattern[ 8 ]; + scientificNotation = pattern[ 9 ]; + suffix = pattern[ 10 ]; + + // Significant digit format + if ( significantPattern ) { + significantPattern.replace( /(@+)(#*)/, function( match, minimumSignificantDigitsMatch, maximumSignificantDigitsMatch ) { + minimumSignificantDigits = minimumSignificantDigitsMatch.length; + maximumSignificantDigits = minimumSignificantDigits + + maximumSignificantDigitsMatch.length; + }); + + // Integer and fractional format + } else { + fractionPattern = pattern[ 7 ]; + integerPattern = pattern[ 6 ]; + + if ( fractionPattern ) { + + // Minimum fraction digits, and rounding. + fractionPattern.replace( /[0-9]+/, function( match ) { + minimumFractionDigits = match; + }); + if ( minimumFractionDigits ) { + roundIncrement = +( "0." + minimumFractionDigits ); + minimumFractionDigits = minimumFractionDigits.length; + } else { + minimumFractionDigits = 0; + } + + // Maximum fraction digits + // 1: ignore decimal character + maximumFractionDigits = fractionPattern.length - 1 /* 1 */; + } + + // Minimum integer digits + integerPattern.replace( /0+$/, function( match ) { + minimumIntegerDigits = match.length; + }); + } + + // Scientific notation + if ( scientificNotation ) { + throw createErrorUnsupportedFeature({ + feature: "scientific notation (not implemented)" + }); + } + + // Padding + if ( padding ) { + throw createErrorUnsupportedFeature({ + feature: "padding (not implemented)" + }); + } + + // Grouping + if ( ( aux1 = integerFractionOrSignificantPattern.lastIndexOf( "," ) ) !== -1 ) { + + // Primary grouping size is the interval between the last group separator and the end of + // the integer (or the end of the significant pattern). + aux2 = integerFractionOrSignificantPattern.split( "." )[ 0 ]; + primaryGroupingSize = aux2.length - aux1 - 1; + + // Secondary grouping size is the interval between the last two group separators. + if ( ( aux2 = integerFractionOrSignificantPattern.lastIndexOf( ",", aux1 - 1 ) ) !== -1 ) { + secondaryGroupingSize = aux1 - 1 - aux2; + } + } + + // Return: + // 0: @prefix String + // 1: @padding Array [ , ] TODO + // 2: @minimumIntegerDigits non-negative integer Number value indicating the minimum integer + // digits to be used. Numbers will be padded with leading zeroes if necessary. + // 3: @minimumFractionDigits and + // 4: @maximumFractionDigits are non-negative integer Number values indicating the minimum and + // maximum fraction digits to be used. Numbers will be rounded or padded with trailing + // zeroes if necessary. + // 5: @minimumSignificantDigits and + // 6: @maximumSignificantDigits are positive integer Number values indicating the minimum and + // maximum fraction digits to be shown. Either none or both of these properties are + // present; if they are, they override minimum and maximum integer and fraction digits + // – the formatter uses however many integer and fraction digits are required to display + // the specified number of significant digits. + // 7: @roundIncrement Decimal round increment or null + // 8: @primaryGroupingSize + // 9: @secondaryGroupingSize + // 10: @suffix String + return [ + prefix, + padding, + minimumIntegerDigits, + minimumFractionDigits, + maximumFractionDigits, + minimumSignificantDigits, + maximumSignificantDigits, + roundIncrement, + primaryGroupingSize, + secondaryGroupingSize, + suffix + ]; +}; + + + + +/** + * Symbol( name, cldr ) + * + * @name [String] Symbol name. + * + * @cldr [Cldr instance]. + * + * Return the localized symbol given its name. + */ +var numberSymbol = function( name, cldr ) { + return cldr.main([ + "numbers/symbols-numberSystem-" + numberNumberingSystem( cldr ), + name + ]); +}; + + + + +var numberSymbolName = { + ".": "decimal", + ",": "group", + "%": "percentSign", + "+": "plusSign", + "-": "minusSign", + "E": "exponential", + "\u2030": "perMille" +}; + + + + +/** + * symbolMap( cldr ) + * + * @cldr [Cldr instance]. + * + * Return the (localized symbol, pattern symbol) key value pair, eg. { + * ".": "٫", + * ",": "٬", + * "%": "٪", + * ... + * }; + */ +var numberSymbolMap = function( cldr ) { + var symbol, + symbolMap = {}; + + for ( symbol in numberSymbolName ) { + symbolMap[ symbol ] = numberSymbol( numberSymbolName[ symbol ], cldr ); + } + + return symbolMap; +}; + + + + +var numberTruncate = function( value ) { + if ( isNaN( value ) ) { + return NaN; + } + return Math[ value < 0 ? "ceil" : "floor" ]( value ); +}; + + + + +/** + * round( method ) + * + * @method [String] with either "round", "ceil", "floor", or "truncate". + * + * Return function( value, incrementOrExp ): + * + * @value [Number] eg. 123.45. + * + * @incrementOrExp [Number] optional, eg. 0.1; or + * [Object] Either { increment: } or { exponent: } + * + * Return the rounded number, eg: + * - round( "round" )( 123.45 ): 123; + * - round( "ceil" )( 123.45 ): 124; + * - round( "floor" )( 123.45 ): 123; + * - round( "truncate" )( 123.45 ): 123; + * - round( "round" )( 123.45, 0.1 ): 123.5; + * - round( "round" )( 123.45, 10 ): 120; + * + * Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round + * Ref: #376 + */ +var numberRound = function( method ) { + method = method || "round"; + method = method === "truncate" ? numberTruncate : Math[ method ]; + + return function( value, incrementOrExp ) { + var exp, increment; + + value = +value; + + // If the value is not a number, return NaN. + if ( isNaN( value ) ) { + return NaN; + } + + // Exponent given. + if ( typeof incrementOrExp === "object" && incrementOrExp.exponent ) { + exp = +incrementOrExp.exponent; + increment = 1; + + if ( exp === 0 ) { + return method( value ); + } + + // If the exp is not an integer, return NaN. + if ( !( typeof exp === "number" && exp % 1 === 0 ) ) { + return NaN; + } + + // Increment given. + } else { + increment = +incrementOrExp || 1; + + if ( increment === 1 ) { + return method( value ); + } + + // If the increment is not a number, return NaN. + if ( isNaN( increment ) ) { + return NaN; + } + + increment = increment.toExponential().split( "e" ); + exp = +increment[ 1 ]; + increment = +increment[ 0 ]; + } + + // Shift & Round + value = value.toString().split( "e" ); + value[ 0 ] = +value[ 0 ] / increment; + value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] - exp ) : -exp; + value = method( +(value[ 0 ] + "e" + value[ 1 ] ) ); + + // Shift back + value = value.toString().split( "e" ); + value[ 0 ] = +value[ 0 ] * increment; + value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] + exp ) : exp; + return +( value[ 0 ] + "e" + value[ 1 ] ); + }; +}; + + + + +/** + * formatProperties( pattern, cldr [, options] ) + * + * @pattern [String] raw pattern for numbers. + * + * @cldr [Cldr instance]. + * + * @options [Object]: + * - minimumIntegerDigits [Number] + * - minimumFractionDigits, maximumFractionDigits [Number] + * - minimumSignificantDigits, maximumSignificantDigits [Number] + * - round [String] "ceil", "floor", "round" (default), or "truncate". + * - useGrouping [Boolean] default true. + * + * Return the processed properties that will be used in number/format. + * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html + */ +var numberFormatProperties = function( pattern, cldr, options ) { + var negativePattern, negativePrefix, negativeProperties, negativeSuffix, positivePattern, + properties; + + function getOptions( attribute, propertyIndex ) { + if ( attribute in options ) { + properties[ propertyIndex ] = options[ attribute ]; + } + } + + options = options || {}; + pattern = pattern.split( ";" ); + + positivePattern = pattern[ 0 ]; + + negativePattern = pattern[ 1 ] || "-" + positivePattern; + negativeProperties = numberPatternProperties( negativePattern ); + negativePrefix = negativeProperties[ 0 ]; + negativeSuffix = negativeProperties[ 10 ]; + + properties = numberPatternProperties( positivePattern ).concat([ + positivePattern, + negativePrefix + positivePattern + negativeSuffix, + negativePrefix, + negativeSuffix, + numberRound( options.round ), + numberSymbol( "infinity", cldr ), + numberSymbol( "nan", cldr ), + numberSymbolMap( cldr ), + numberNumberingSystemDigitsMap( cldr ) + ]); + + getOptions( "minimumIntegerDigits", 2 ); + getOptions( "minimumFractionDigits", 3 ); + getOptions( "maximumFractionDigits", 4 ); + getOptions( "minimumSignificantDigits", 5 ); + getOptions( "maximumSignificantDigits", 6 ); + + // Grouping separators + if ( options.useGrouping === false ) { + properties[ 8 ] = null; + } + + // Normalize number of digits if only one of either minimumFractionDigits or + // maximumFractionDigits is passed in as an option + if ( "minimumFractionDigits" in options && !( "maximumFractionDigits" in options ) ) { + // maximumFractionDigits = Math.max( minimumFractionDigits, maximumFractionDigits ); + properties[ 4 ] = Math.max( properties[ 3 ], properties[ 4 ] ); + } else if ( !( "minimumFractionDigits" in options ) && + "maximumFractionDigits" in options ) { + // minimumFractionDigits = Math.min( minimumFractionDigits, maximumFractionDigits ); + properties[ 3 ] = Math.min( properties[ 3 ], properties[ 4 ] ); + } + + // Return: + // 0-10: see number/pattern-properties. + // 11: @positivePattern [String] Positive pattern. + // 12: @negativePattern [String] Negative pattern. + // 13: @negativePrefix [String] Negative prefix. + // 14: @negativeSuffix [String] Negative suffix. + // 15: @round [Function] Round function. + // 16: @infinitySymbol [String] Infinity symbol. + // 17: @nanSymbol [String] NaN symbol. + // 18: @symbolMap [Object] A bunch of other symbols. + // 19: @nuDigitsMap [Array] Digits map if numbering system is different than `latn`. + return properties; +}; + + + + +/** + * EBNF representation: + * + * number_pattern_re = prefix_including_padding? + * number + * scientific_notation? + * suffix? + * + * number = integer_including_group_separator fraction_including_decimal_separator + * + * integer_including_group_separator = + * regexp([0-9,]*[0-9]+) + * + * fraction_including_decimal_separator = + * regexp((\.[0-9]+)?) + + * prefix_including_padding = non_number_stuff + * + * scientific_notation = regexp(E[+-]?[0-9]+) + * + * suffix = non_number_stuff + * + * non_number_stuff = regexp([^0-9]*) + * + * + * Regexp groups: + * + * 0: number_pattern_re + * 1: prefix + * 2: integer_including_group_separator fraction_including_decimal_separator + * 3: integer_including_group_separator + * 4: fraction_including_decimal_separator + * 5: scientific_notation + * 6: suffix + */ +var numberNumberRe = (/^([^0-9]*)(([0-9,]*[0-9]+)(\.[0-9]+)?)(E[+-]?[0-9]+)?([^0-9]*)$/); + + + + +/** + * parse( value, properties ) + * + * @value [String]. + * + * @properties [Object] Parser properties is a reduced pre-processed cldr + * data set returned by numberParserProperties(). + * + * Return the parsed Number (including Infinity) or NaN when value is invalid. + * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html + */ +var numberParse = function( value, properties ) { + var aux, infinitySymbol, invertedNuDigitsMap, invertedSymbolMap, localizedDigitRe, + localizedSymbolsRe, negativePrefix, negativeSuffix, number, prefix, suffix; + + infinitySymbol = properties[ 0 ]; + invertedSymbolMap = properties[ 1 ]; + negativePrefix = properties[ 2 ]; + negativeSuffix = properties[ 3 ]; + invertedNuDigitsMap = properties[ 4 ]; + + // Infinite number. + if ( aux = value.match( infinitySymbol ) ) { + + number = Infinity; + prefix = value.slice( 0, aux.length ); + suffix = value.slice( aux.length + 1 ); + + // Finite number. + } else { + + // TODO: Create it during setup, i.e., make it a property. + localizedSymbolsRe = new RegExp( + Object.keys( invertedSymbolMap ).map(function( localizedSymbol ) { + return regexpEscape( localizedSymbol ); + }).join( "|" ), + "g" + ); + + // Reverse localized symbols. + value = value.replace( localizedSymbolsRe, function( localizedSymbol ) { + return invertedSymbolMap[ localizedSymbol ]; + }); + + // Reverse localized numbering system. + if ( invertedNuDigitsMap ) { + + // TODO: Create it during setup, i.e., make it a property. + localizedDigitRe = new RegExp( + Object.keys( invertedNuDigitsMap ).map(function( localizedDigit ) { + return regexpEscape( localizedDigit ); + }).join( "|" ), + "g" + ); + value = value.replace( localizedDigitRe, function( localizedDigit ) { + return invertedNuDigitsMap[ localizedDigit ]; + }); + } + + // Is it a valid number? + value = value.match( numberNumberRe ); + if ( !value ) { + + // Invalid number. + return NaN; + } + + prefix = value[ 1 ]; + suffix = value[ 6 ]; + + // Remove grouping separators. + number = value[ 2 ].replace( /,/g, "" ); + + // Scientific notation + if ( value[ 5 ] ) { + number += value[ 5 ]; + } + + number = +number; + + // Is it a valid number? + if ( isNaN( number ) ) { + + // Invalid number. + return NaN; + } + + // Percent + if ( value[ 0 ].indexOf( "%" ) !== -1 ) { + number /= 100; + suffix = suffix.replace( "%", "" ); + + // Per mille + } else if ( value[ 0 ].indexOf( "\u2030" ) !== -1 ) { + number /= 1000; + suffix = suffix.replace( "\u2030", "" ); + } + } + + // Negative number + // "If there is an explicit negative subpattern, it serves only to specify the negative prefix + // and suffix. If there is no explicit negative subpattern, the negative subpattern is the + // localized minus sign prefixed to the positive subpattern" UTS#35 + if ( prefix === negativePrefix && suffix === negativeSuffix ) { + number *= -1; + } + + return number; +}; + + + + +/** + * symbolMap( cldr ) + * + * @cldr [Cldr instance]. + * + * Return the (localized symbol, pattern symbol) key value pair, eg. { + * "٫": ".", + * "٬": ",", + * "٪": "%", + * ... + * }; + */ +var numberSymbolInvertedMap = function( cldr ) { + var symbol, + symbolMap = {}; + + for ( symbol in numberSymbolName ) { + symbolMap[ numberSymbol( numberSymbolName[ symbol ], cldr ) ] = symbol; + } + + return symbolMap; +}; + + + + +/** + * parseProperties( pattern, cldr ) + * + * @pattern [String] raw pattern for numbers. + * + * @cldr [Cldr instance]. + * + * Return parser properties, used to feed parser function. + */ +var numberParseProperties = function( pattern, cldr ) { + var invertedNuDigitsMap, invertedNuDigitsMapSanityCheck, negativePattern, negativeProperties, + nuDigitsMap = numberNumberingSystemDigitsMap( cldr ); + + pattern = pattern.split( ";" ); + negativePattern = pattern[ 1 ] || "-" + pattern[ 0 ]; + negativeProperties = numberPatternProperties( negativePattern ); + if ( nuDigitsMap ) { + invertedNuDigitsMap = nuDigitsMap.split( "" ).reduce(function( object, localizedDigit, i ) { + object[ localizedDigit ] = String( i ); + return object; + }, {} ); + invertedNuDigitsMapSanityCheck = "0123456789".split( "" ).reduce(function( object, digit ) { + object[ digit ] = "invalid"; + return object; + }, {} ); + invertedNuDigitsMap = objectExtend( + invertedNuDigitsMapSanityCheck, + invertedNuDigitsMap + ); + } + + // 0: @infinitySymbol [String] Infinity symbol. + // 1: @invertedSymbolMap [Object] Inverted symbol map augmented with sanity check. + // The sanity check prevents permissive parsing, i.e., it prevents symbols that doesn't + // belong to the localized set to pass through. This is obtained with the result of the + // inverted map object overloading symbol name map object (the remaining symbol name + // mappings will invalidate parsing, working as the sanity check). + // 2: @negativePrefix [String] Negative prefix. + // 3: @negativeSuffix [String] Negative suffix with percent or per mille stripped out. + // 4: @invertedNuDigitsMap [Object] Inverted digits map if numbering system is different than + // `latn` augmented with sanity check (similar to invertedSymbolMap). + return [ + numberSymbol( "infinity", cldr ), + objectExtend( {}, numberSymbolName, numberSymbolInvertedMap( cldr ) ), + negativeProperties[ 0 ], + negativeProperties[ 10 ].replace( "%", "" ).replace( "\u2030", "" ), + invertedNuDigitsMap + ]; +}; + + + + +/** + * Pattern( style ) + * + * @style [String] "decimal" (default) or "percent". + * + * @cldr [Cldr instance]. + */ +var numberPattern = function( style, cldr ) { + if ( style !== "decimal" && style !== "percent" ) { + throw new Error( "Invalid style" ); + } + + return cldr.main([ + "numbers", + style + "Formats-numberSystem-" + numberNumberingSystem( cldr ), + "standard" + ]); +}; + + + + +/** + * .numberFormatter( [options] ) + * + * @options [Object]: + * - style: [String] "decimal" (default) or "percent". + * - see also number/format options. + * + * Return a function that formats a number according to the given options and default/instance + * locale. + */ +Globalize.numberFormatter = +Globalize.prototype.numberFormatter = function( options ) { + var cldr, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits, + minimumIntegerDigits, minimumSignificantDigits, pattern, properties; + + validateParameterTypePlainObject( options, "options" ); + + options = options || {}; + cldr = this.cldr; + + validateDefaultLocale( cldr ); + + cldr.on( "get", validateCldr ); + + if ( options.raw ) { + pattern = options.raw; + } else { + pattern = numberPattern( options.style || "decimal", cldr ); + } + + properties = numberFormatProperties( pattern, cldr, options ); + + cldr.off( "get", validateCldr ); + + minimumIntegerDigits = properties[ 2 ]; + minimumFractionDigits = properties[ 3 ]; + maximumFractionDigits = properties[ 4 ]; + + minimumSignificantDigits = properties[ 5 ]; + maximumSignificantDigits = properties[ 6 ]; + + // Validate significant digit format properties + if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) { + validateParameterRange( minimumSignificantDigits, "minimumSignificantDigits", 1, 21 ); + validateParameterRange( maximumSignificantDigits, "maximumSignificantDigits", + minimumSignificantDigits, 21 ); + + } else if ( !isNaN( minimumSignificantDigits ) || !isNaN( maximumSignificantDigits ) ) { + throw new Error( "Neither or both the minimum and maximum significant digits must be " + + "present" ); + + // Validate integer and fractional format + } else { + validateParameterRange( minimumIntegerDigits, "minimumIntegerDigits", 1, 21 ); + validateParameterRange( minimumFractionDigits, "minimumFractionDigits", 0, 20 ); + validateParameterRange( maximumFractionDigits, "maximumFractionDigits", + minimumFractionDigits, 20 ); + } + + return function( value ) { + validateParameterPresence( value, "value" ); + validateParameterTypeNumber( value, "value" ); + return numberFormat( value, properties ); + }; +}; + +/** + * .numberParser( [options] ) + * + * @options [Object]: + * - style: [String] "decimal" (default) or "percent". + * + * Return the number parser according to the default/instance locale. + */ +Globalize.numberParser = +Globalize.prototype.numberParser = function( options ) { + var cldr, pattern, properties; + + validateParameterTypePlainObject( options, "options" ); + + options = options || {}; + cldr = this.cldr; + + validateDefaultLocale( cldr ); + + cldr.on( "get", validateCldr ); + + if ( options.raw ) { + pattern = options.raw; + } else { + pattern = numberPattern( options.style || "decimal", cldr ); + } + + properties = numberParseProperties( pattern, cldr ); + + cldr.off( "get", validateCldr ); + + return function( value ) { + validateParameterPresence( value, "value" ); + validateParameterTypeString( value, "value" ); + return numberParse( value, properties ); + }; +}; + +/** + * .formatNumber( value [, options] ) + * + * @value [Number] number to be formatted. + * + * @options [Object]: see number/format-properties. + * + * Format a number according to the given options and default/instance locale. + */ +Globalize.formatNumber = +Globalize.prototype.formatNumber = function( value, options ) { + validateParameterPresence( value, "value" ); + validateParameterTypeNumber( value, "value" ); + + return this.numberFormatter( options )( value ); +}; + +/** + * .parseNumber( value [, options] ) + * + * @value [String] + * + * @options [Object]: See numberParser(). + * + * Return the parsed Number (including Infinity) or NaN when value is invalid. + */ +Globalize.parseNumber = +Globalize.prototype.parseNumber = function( value, options ) { + validateParameterPresence( value, "value" ); + validateParameterTypeString( value, "value" ); + + return this.numberParser( options )( value ); +}; + +/** + * Optimization to avoid duplicating some internal functions across modules. + */ +Globalize._createErrorUnsupportedFeature = createErrorUnsupportedFeature; +Globalize._numberNumberingSystem = numberNumberingSystem; +Globalize._numberPattern = numberPattern; +Globalize._numberSymbol = numberSymbol; +Globalize._stringPad = stringPad; +Globalize._validateParameterTypeNumber = validateParameterTypeNumber; +Globalize._validateParameterTypeString = validateParameterTypeString; + +return Globalize; + + + + +})); diff --git a/external/localization.js b/external/localization.js index 2db980a586f..2879601f800 100644 --- a/external/localization.js +++ b/external/localization.js @@ -20,11 +20,11 @@ Globalize.load({ "ar": { "identity": { "version": { - "_cldrVersion": "25", - "_number": "$Revision: 91 $" + "_cldrVersion": "27.0.1", + "_number": "$Revision: 11294 $" }, "generation": { - "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + "_date": "$Date: 2015-02-23 16:50:24 -0600 (Mon, 23 Feb 2015) $" }, "language": "ar" }, @@ -245,34 +245,34 @@ Globalize.load({ "format": { "abbreviated": { "am": "ص", - "noon": "noon", + "noon": "ظهرا", "pm": "م" }, "narrow": { - "am": "a", - "noon": "n", - "pm": "p" + "am": "ص", + "noon": "ظ", + "pm": "م" }, "wide": { "am": "ص", - "noon": "noon", + "noon": "ظهرا", "pm": "م" } }, "stand-alone": { "abbreviated": { "am": "ص", - "noon": "noon", + "noon": "ظهرا", "pm": "م" }, "narrow": { - "am": "a", - "noon": "n", - "pm": "p" + "am": "ص", + "noon": "ظ", + "pm": "م" }, "wide": { "am": "ص", - "noon": "noon", + "noon": "ظهرا", "pm": "م" } } @@ -282,19 +282,19 @@ Globalize.load({ "0": "قبل الميلاد", "0-alt-variant": "BCE", "1": "ميلادي", - "1-alt-variant": "CE" + "1-alt-variant": "بعد الميلاد" }, "eraAbbr": { "0": "ق.م", "0-alt-variant": "BCE", "1": "م", - "1-alt-variant": "CE" + "1-alt-variant": "ب.م" }, "eraNarrow": { "0": "ق.م", "0-alt-variant": "BCE", "1": "م", - "1-alt-variant": "CE" + "1-alt-variant": "ب.م" } }, "dateFormats": { @@ -315,6 +315,7 @@ Globalize.load({ "medium": "{1} {0}", "short": "{1} {0}", "availableFormats": { + "E": "ccc", "EHm": "E HH:mm", "EHms": "E HH:mm:ss", "Ed": "E، d", @@ -327,6 +328,8 @@ Globalize.load({ "H": "HH", "Hm": "HH:mm", "Hms": "HH:mm:ss", + "Hmsv": "HH:mm:ss v", + "Hmv": "HH:mm v", "M": "L", "MEd": "E، d/M", "MMM": "LLL", @@ -340,6 +343,8 @@ Globalize.load({ "h": "h a", "hm": "h:mm a", "hms": "h:mm:ss a", + "hmsv": "h:mm:ss a v", + "hmv": "h:mm a v", "ms": "mm:ss", "y": "y", "yM": "M‏/y", @@ -467,6 +472,415 @@ Globalize.load({ } } } + }, + "numbers": { + "defaultNumberingSystem": "arab", + "otherNumberingSystems": { + "native": "arab" + }, + "minimumGroupingDigits": "1", + "symbols-numberSystem-arab": { + "decimal": "٫", + "group": "٬", + "list": "؛", + "percentSign": "٪", + "plusSign": "‏+", + "minusSign": "‏-", + "exponential": "اس", + "superscriptingExponent": "×", + "perMille": "؉", + "infinity": "∞", + "nan": "ليس رقم", + "timeSeparator": "،" + }, + "symbols-numberSystem-latn": { + "decimal": ".", + "group": ",", + "list": ";", + "percentSign": "%", + "plusSign": "‎+", + "minusSign": "‎-", + "exponential": "E", + "superscriptingExponent": "×", + "perMille": "‰", + "infinity": "∞", + "nan": "NaN", + "timeSeparator": ":" + }, + "decimalFormats-numberSystem-arab": { + "standard": "#,##0.###", + "long": { + "decimalFormat": { + "1000-count-zero": "0 ألف", + "1000-count-one": "0 ألف", + "1000-count-two": "0 ألف", + "1000-count-few": "0 ألف", + "1000-count-many": "0 ألف", + "1000-count-other": "0 ألف", + "10000-count-zero": "00 ألف", + "10000-count-one": "00 ألف", + "10000-count-two": "00 ألف", + "10000-count-few": "00 ألف", + "10000-count-many": "00 ألف", + "10000-count-other": "00 ألف", + "100000-count-zero": "000 ألف", + "100000-count-one": "000 ألف", + "100000-count-two": "000 ألف", + "100000-count-few": "000 ألف", + "100000-count-many": "000 ألف", + "100000-count-other": "000 ألف", + "1000000-count-zero": "0 مليون", + "1000000-count-one": "0 مليون", + "1000000-count-two": "0 مليون", + "1000000-count-few": "0 مليون", + "1000000-count-many": "0 مليون", + "1000000-count-other": "0 مليون", + "10000000-count-zero": "00 مليون", + "10000000-count-one": "00 مليون", + "10000000-count-two": "00 مليون", + "10000000-count-few": "00 مليون", + "10000000-count-many": "00 مليون", + "10000000-count-other": "00 مليون", + "100000000-count-zero": "000 مليون", + "100000000-count-one": "000 مليون", + "100000000-count-two": "000 مليون", + "100000000-count-few": "000 مليون", + "100000000-count-many": "000 مليون", + "100000000-count-other": "000 مليون", + "1000000000-count-zero": "0 بليون", + "1000000000-count-one": "0 بليون", + "1000000000-count-two": "0 بليون", + "1000000000-count-few": "0 بليون", + "1000000000-count-many": "0 بليون", + "1000000000-count-other": "0 بليون", + "10000000000-count-zero": "00 بليون", + "10000000000-count-one": "00 بليون", + "10000000000-count-two": "00 بليون", + "10000000000-count-few": "00 بليون", + "10000000000-count-many": "00 بليون", + "10000000000-count-other": "00 بليون", + "100000000000-count-zero": "000 بليون", + "100000000000-count-one": "000 بليون", + "100000000000-count-two": "000 بليون", + "100000000000-count-few": "000 بليون", + "100000000000-count-many": "000 بليون", + "100000000000-count-other": "000 بليون", + "1000000000000-count-zero": "0 تريليون", + "1000000000000-count-one": "0 تريليون", + "1000000000000-count-two": "0 تريليون", + "1000000000000-count-few": "0 تريليون", + "1000000000000-count-many": "0 تريليون", + "1000000000000-count-other": "0 تريليون", + "10000000000000-count-zero": "00 تريليون", + "10000000000000-count-one": "00 تريليون", + "10000000000000-count-two": "00 تريليون", + "10000000000000-count-few": "00 تريليون", + "10000000000000-count-many": "00 تريليون", + "10000000000000-count-other": "00 تريليون", + "100000000000000-count-zero": "000 تريليون", + "100000000000000-count-one": "000 تريليون", + "100000000000000-count-two": "000 تريليون", + "100000000000000-count-few": "000 تريليون", + "100000000000000-count-many": "000 تريليون", + "100000000000000-count-other": "000 تريليون" + } + }, + "short": { + "decimalFormat": { + "1000-count-zero": "0 ألف", + "1000-count-one": "0 ألف", + "1000-count-two": "0 ألف", + "1000-count-few": "0 ألف", + "1000-count-many": "0 ألف", + "1000-count-other": "0 ألف", + "10000-count-zero": "00 ألف", + "10000-count-one": "00 ألف", + "10000-count-two": "00 ألف", + "10000-count-few": "00 ألف", + "10000-count-many": "00 ألف", + "10000-count-other": "00 ألف", + "100000-count-zero": "000 ألف", + "100000-count-one": "000 ألف", + "100000-count-two": "000 ألف", + "100000-count-few": "000 ألف", + "100000-count-many": "000 ألف", + "100000-count-other": "000 ألف", + "1000000-count-zero": "0 مليو", + "1000000-count-one": "0 مليو", + "1000000-count-two": "0 مليو", + "1000000-count-few": "0 مليو", + "1000000-count-many": "0 مليو", + "1000000-count-other": "0 مليو", + "10000000-count-zero": "00 مليو", + "10000000-count-one": "00 مليو", + "10000000-count-two": "00 مليو", + "10000000-count-few": "00 مليو", + "10000000-count-many": "00 مليو", + "10000000-count-other": "00 مليو", + "100000000-count-zero": "000 مليو", + "100000000-count-one": "000 مليو", + "100000000-count-two": "000 مليو", + "100000000-count-few": "000 مليو", + "100000000-count-many": "000 مليو", + "100000000-count-other": "000 مليو", + "1000000000-count-zero": "0 بليو", + "1000000000-count-one": "0 بليو", + "1000000000-count-two": "0 بليو", + "1000000000-count-few": "0 بليو", + "1000000000-count-many": "0 بليو", + "1000000000-count-other": "0 بليو", + "10000000000-count-zero": "00 بليو", + "10000000000-count-one": "00 بليو", + "10000000000-count-two": "00 بليو", + "10000000000-count-few": "00 بليو", + "10000000000-count-many": "00 بليو", + "10000000000-count-other": "00 بليو", + "100000000000-count-zero": "000 بليو", + "100000000000-count-one": "000 بليو", + "100000000000-count-two": "000 بليو", + "100000000000-count-few": "000 بليو", + "100000000000-count-many": "000 بليو", + "100000000000-count-other": "000 بليو", + "1000000000000-count-zero": "0 ترليو", + "1000000000000-count-one": "0 ترليو", + "1000000000000-count-two": "0 ترليو", + "1000000000000-count-few": "0 ترليو", + "1000000000000-count-many": "0 ترليو", + "1000000000000-count-other": "0 ترليو", + "10000000000000-count-zero": "00 ترليو", + "10000000000000-count-one": "00 ترليو", + "10000000000000-count-two": "00 ترليو", + "10000000000000-count-few": "00 ترليو", + "10000000000000-count-many": "00 ترليو", + "10000000000000-count-other": "00 ترليو", + "100000000000000-count-zero": "000 ترليو", + "100000000000000-count-one": "000 ترليو", + "100000000000000-count-two": "000 ترليو", + "100000000000000-count-few": "000 ترليو", + "100000000000000-count-many": "000 ترليو", + "100000000000000-count-other": "000 ترليو" + } + } + }, + "decimalFormats-numberSystem-latn": { + "standard": "#,##0.###", + "long": { + "decimalFormat": { + "1000-count-zero": "0 ألف", + "1000-count-one": "0 ألف", + "1000-count-two": "0 ألف", + "1000-count-few": "0 آلاف", + "1000-count-many": "0 ألف", + "1000-count-other": "0 ألف", + "10000-count-zero": "00 ألف", + "10000-count-one": "00 ألف", + "10000-count-two": "00 ألف", + "10000-count-few": "00 ألف", + "10000-count-many": "00 ألف", + "10000-count-other": "00 ألف", + "100000-count-zero": "000 ألف", + "100000-count-one": "000 ألف", + "100000-count-two": "000 ألف", + "100000-count-few": "000 ألف", + "100000-count-many": "000 ألف", + "100000-count-other": "000 ألف", + "1000000-count-zero": "0 مليون", + "1000000-count-one": "0 مليون", + "1000000-count-two": "0 مليون", + "1000000-count-few": "0 ملايين", + "1000000-count-many": "0 مليون", + "1000000-count-other": "0 مليون", + "10000000-count-zero": "00 مليون", + "10000000-count-one": "00 مليون", + "10000000-count-two": "00 مليون", + "10000000-count-few": "00 ملايين", + "10000000-count-many": "00 مليون", + "10000000-count-other": "00 مليون", + "100000000-count-zero": "000 مليون", + "100000000-count-one": "000 مليون", + "100000000-count-two": "000 مليون", + "100000000-count-few": "000 مليون", + "100000000-count-many": "000 مليون", + "100000000-count-other": "000 مليون", + "1000000000-count-zero": "0 بليون", + "1000000000-count-one": "0 بليون", + "1000000000-count-two": "0 بليون", + "1000000000-count-few": "0 بلايين", + "1000000000-count-many": "0 بليون", + "1000000000-count-other": "0 بليون", + "10000000000-count-zero": "00 بليون", + "10000000000-count-one": "00 بليون", + "10000000000-count-two": "00 بليون", + "10000000000-count-few": "00 بليون", + "10000000000-count-many": "00 بليون", + "10000000000-count-other": "00 بليون", + "100000000000-count-zero": "000 بليون", + "100000000000-count-one": "000 بليون", + "100000000000-count-two": "000 بليون", + "100000000000-count-few": "000 بليون", + "100000000000-count-many": "000 بليون", + "100000000000-count-other": "000 بليون", + "1000000000000-count-zero": "0 تريليون", + "1000000000000-count-one": "0 تريليون", + "1000000000000-count-two": "0 تريليون", + "1000000000000-count-few": "0 تريليونات", + "1000000000000-count-many": "0 تريليون", + "1000000000000-count-other": "0 تريليون", + "10000000000000-count-zero": "00 تريليون", + "10000000000000-count-one": "00 تريليون", + "10000000000000-count-two": "00 تريليون", + "10000000000000-count-few": "00 تريليون", + "10000000000000-count-many": "00 تريليون", + "10000000000000-count-other": "00 تريليون", + "100000000000000-count-zero": "000 تريليون", + "100000000000000-count-one": "000 تريليون", + "100000000000000-count-two": "000 تريليون", + "100000000000000-count-few": "000 تريليون", + "100000000000000-count-many": "000 تريليون", + "100000000000000-count-other": "000 تريليون" + } + }, + "short": { + "decimalFormat": { + "1000-count-zero": "0 ألف", + "1000-count-one": "0 ألف", + "1000-count-two": "0 ألف", + "1000-count-few": "0 آلاف", + "1000-count-many": "0 ألف", + "1000-count-other": "0 ألف", + "10000-count-zero": "00 ألف", + "10000-count-one": "00 ألف", + "10000-count-two": "00 ألف", + "10000-count-few": "00 ألف", + "10000-count-many": "00 ألف", + "10000-count-other": "00 ألف", + "100000-count-zero": "000 ألف", + "100000-count-one": "000 ألف", + "100000-count-two": "000 ألف", + "100000-count-few": "000 ألف", + "100000-count-many": "000 ألف", + "100000-count-other": "000 ألف", + "1000000-count-zero": "0 مليو", + "1000000-count-one": "0 مليو", + "1000000-count-two": "0 مليو", + "1000000-count-few": "0 مليو", + "1000000-count-many": "0 مليو", + "1000000-count-other": "0 مليو", + "10000000-count-zero": "00 مليو", + "10000000-count-one": "00 مليو", + "10000000-count-two": "00 مليو", + "10000000-count-few": "00 مليو", + "10000000-count-many": "00 مليو", + "10000000-count-other": "00 مليو", + "100000000-count-zero": "000 مليو", + "100000000-count-one": "000 مليو", + "100000000-count-two": "000 مليو", + "100000000-count-few": "000 مليو", + "100000000-count-many": "000 مليو", + "100000000-count-other": "000 مليو", + "1000000000-count-zero": "0 بليو", + "1000000000-count-one": "0 بليو", + "1000000000-count-two": "0 بليو", + "1000000000-count-few": "0 بليو", + "1000000000-count-many": "0 بليو", + "1000000000-count-other": "0 بليو", + "10000000000-count-zero": "00 بليو", + "10000000000-count-one": "00 بليو", + "10000000000-count-two": "00 بليو", + "10000000000-count-few": "00 بليو", + "10000000000-count-many": "00 بليو", + "10000000000-count-other": "00 بليو", + "100000000000-count-zero": "000 بليو", + "100000000000-count-one": "000 بليو", + "100000000000-count-two": "000 بليو", + "100000000000-count-few": "000 بليو", + "100000000000-count-many": "000 بليو", + "100000000000-count-other": "000 بليو", + "1000000000000-count-zero": "0 ترليو", + "1000000000000-count-one": "0 ترليو", + "1000000000000-count-two": "0 ترليو", + "1000000000000-count-few": "0 ترليو", + "1000000000000-count-many": "0 ترليو", + "1000000000000-count-other": "0 ترليو", + "10000000000000-count-zero": "00 ترليو", + "10000000000000-count-one": "00 ترليو", + "10000000000000-count-two": "00 ترليو", + "10000000000000-count-few": "00 ترليو", + "10000000000000-count-many": "00 ترليو", + "10000000000000-count-other": "00 ترليو", + "100000000000000-count-zero": "000 ترليو", + "100000000000000-count-one": "000 ترليو", + "100000000000000-count-two": "000 ترليو", + "100000000000000-count-few": "000 ترليو", + "100000000000000-count-many": "000 ترليو", + "100000000000000-count-other": "000 ترليو" + } + } + }, + "scientificFormats-numberSystem-arab": { + "standard": "#E0" + }, + "scientificFormats-numberSystem-latn": { + "standard": "#E0" + }, + "percentFormats-numberSystem-arab": { + "standard": "#,##0%" + }, + "percentFormats-numberSystem-latn": { + "standard": "#,##0%" + }, + "currencyFormats-numberSystem-arab": { + "currencySpacing": { + "beforeCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + }, + "afterCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + } + }, + "accounting": "¤#,##0.00;(¤#,##0.00)", + "standard": "¤ #,##0.00", + "unitPattern-count-zero": "{0} {1}", + "unitPattern-count-one": "{0} {1}", + "unitPattern-count-two": "{0} {1}", + "unitPattern-count-few": "{0} {1}", + "unitPattern-count-many": "{0} {1}", + "unitPattern-count-other": "{0} {1}" + }, + "currencyFormats-numberSystem-latn": { + "currencySpacing": { + "beforeCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + }, + "afterCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + } + }, + "accounting": "¤#,##0.00;(¤#,##0.00)", + "standard": "¤ #,##0.00", + "unitPattern-count-zero": "{0} {1}", + "unitPattern-count-one": "{0} {1}", + "unitPattern-count-two": "{0} {1}", + "unitPattern-count-few": "{0} {1}", + "unitPattern-count-many": "{0} {1}", + "unitPattern-count-other": "{0} {1}" + }, + "miscPatterns-numberSystem-arab": { + "atLeast": "+{0}", + "range": "{0}–{1}" + }, + "miscPatterns-numberSystem-latn": { + "atLeast": "+{0}", + "range": "{0}–{1}" + } } } } @@ -477,11 +891,11 @@ Globalize.load({ "es": { "identity": { "version": { - "_cldrVersion": "25", - "_number": "$Revision: 91 $" + "_cldrVersion": "27.0.1", + "_number": "$Revision: 11321 $" }, "generation": { - "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + "_date": "$Date: 2015-02-26 14:20:05 -0600 (Thu, 26 Feb 2015) $" }, "language": "es" }, @@ -665,10 +1079,10 @@ Globalize.load({ "4": "T4" }, "narrow": { - "1": "1T", - "2": "2T", - "3": "3T", - "4": "4T" + "1": "1", + "2": "2", + "3": "3", + "4": "4" }, "wide": { "1": "1.er trimestre", @@ -685,10 +1099,10 @@ Globalize.load({ "4": "T4" }, "narrow": { - "1": "1T", - "2": "2T", - "3": "3T", - "4": "4T" + "1": "1", + "2": "2", + "3": "3", + "4": "4" }, "wide": { "1": "1.er trimestre", @@ -702,34 +1116,34 @@ Globalize.load({ "format": { "abbreviated": { "am": "a. m.", - "noon": "noon", + "noon": "mediodía", "pm": "p. m." }, "narrow": { "am": "a.m.", - "noon": "n", + "noon": "m.", "pm": "p.m." }, "wide": { "am": "a. m.", - "noon": "noon", + "noon": "mediodía", "pm": "p. m." } }, "stand-alone": { "abbreviated": { "am": "a. m.", - "noon": "noon", + "noon": "mediodía", "pm": "p. m." }, "narrow": { "am": "a.m.", - "noon": "n", + "noon": "m.", "pm": "p.m." }, "wide": { "am": "a. m.", - "noon": "noon", + "noon": "mediodía", "pm": "p. m." } } @@ -737,9 +1151,9 @@ Globalize.load({ "eras": { "eraNames": { "0": "antes de Cristo", - "0-alt-variant": "a. e. c.", - "1": "anno Dómini", - "1-alt-variant": "e. c." + "0-alt-variant": "antes de la era común", + "1": "después de Cristo", + "1-alt-variant": "era común" }, "eraAbbr": { "0": "a. C.", @@ -757,7 +1171,7 @@ Globalize.load({ "dateFormats": { "full": "EEEE, d 'de' MMMM 'de' y", "long": "d 'de' MMMM 'de' y", - "medium": "d/M/y", + "medium": "d MMM y", "short": "d/M/yy" }, "timeFormats": { @@ -772,25 +1186,32 @@ Globalize.load({ "medium": "{1} {0}", "short": "{1} {0}", "availableFormats": { + "E": "ccc", "EHm": "E, H:mm", "EHms": "E, H:mm:ss", "Ed": "E d", "Ehm": "E, h:mm a", "Ehms": "E, h:mm:ss a", "Gy": "y G", - "GyMMM": "MMM 'de' y G", - "GyMMMEd": "E, d 'de' MMMM 'de' y G", - "GyMMMd": "d MMM 'de' y G", + "GyMMM": "MMM y G", + "GyMMMEd": "E, d MMM y G", + "GyMMMM": "MMMM 'de' y G", + "GyMMMMEd": "E, d 'de' MMMM 'de' y G", + "GyMMMMd": "d 'de' MMMM 'de' y G", + "GyMMMd": "d MMM y G", "H": "H", "Hm": "H:mm", "Hms": "H:mm:ss", + "Hmsv": "H:mm:ss v", + "Hmsvvvv": "H:mm:ss (vvvv)", + "Hmv": "H:mm v", "M": "L", "MEd": "E, d/M", "MMM": "LLL", - "MMMEd": "E d 'de' MMM", + "MMMEd": "E, d MMM", + "MMMMEd": "E, d 'de' MMMM", "MMMMd": "d 'de' MMMM", - "MMMd": "d 'de' MMM", - "MMMdd": "dd-MMM", + "MMMd": "d MMM", "MMd": "d/M", "MMdd": "d/M", "Md": "d/M", @@ -798,15 +1219,20 @@ Globalize.load({ "h": "h a", "hm": "h:mm a", "hms": "h:mm:ss a", + "hmsv": "h:mm:ss a v", + "hmsvvvv": "h:mm:ss a (vvvv)", + "hmv": "h:mm a v", "ms": "mm:ss", "y": "y", "yM": "M/y", "yMEd": "EEE, d/M/y", "yMM": "M/y", - "yMMM": "MMM 'de' y", - "yMMMEd": "EEE, d 'de' MMMM 'de' y", + "yMMM": "MMM y", + "yMMMEd": "EEE, d MMM y", "yMMMM": "MMMM 'de' y", - "yMMMd": "d 'de' MMM 'de' y", + "yMMMMEd": "EEE, d 'de' MMMM 'de' y", + "yMMMMd": "d 'de' MMMM 'de' y", + "yMMMd": "d MMM y", "yMd": "d/M/y", "yQQQ": "QQQ y", "yQQQQ": "QQQQ 'de' y" @@ -854,6 +1280,14 @@ Globalize.load({ "M": "E, d MMM–E, d MMM", "d": "E, d MMM–E, d MMM" }, + "MMMMEd": { + "M": "E, d 'de' MMMM–E, d 'de' MMMM", + "d": "E, d 'de' MMMM–E, d 'de' MMMM" + }, + "MMMMd": { + "M": "d 'de' MMMM–d 'de' MMMM", + "d": "d–d 'de' MMMM" + }, "MMMd": { "M": "d MMM–d MMM", "d": "d–d MMM" @@ -900,18 +1334,28 @@ Globalize.load({ "y": "MMM y–MMM y" }, "yMMMEd": { - "M": "E, d MMM–E, d MMM 'de' y", - "d": "E, d MMM–E, d MMM 'de' y", - "y": "E, d MMM 'de' y–E, d MMM 'de' y" + "M": "E, d MMM–E, d MMM y", + "d": "E, d MMM–E, d MMM y", + "y": "E, d MMM y–E, d MMM y" }, "yMMMM": { "M": "MMMM–MMMM 'de' y", "y": "MMMM 'de' y–MMMM 'de' y" }, + "yMMMMEd": { + "M": "E, d 'de' MMMM–E, d 'de' MMMM 'de' y", + "d": "E, d 'de' MMMM–E, d 'de' MMMM 'de' y", + "y": "E, d 'de' MMMM 'de' y–E, d 'de' MMMM 'de' y" + }, + "yMMMMd": { + "M": "d 'de' MMMM–d 'de' MMMM 'de' y", + "d": "d–d 'de' MMMM 'de' y", + "y": "d 'de' MMMM 'de' y–d 'de' MMMM 'de' y" + }, "yMMMd": { - "M": "d MMM–d MMM 'de' y", + "M": "d MMM–d MMM y", "d": "d–d MMM y", - "y": "d MMM 'de' y–d MMM 'de' y" + "y": "d MMM y–d MMM y" }, "yMd": { "M": "d/M/y–d/M/y", @@ -922,6 +1366,114 @@ Globalize.load({ } } } + }, + "numbers": { + "defaultNumberingSystem": "latn", + "otherNumberingSystems": { + "native": "latn" + }, + "minimumGroupingDigits": "1", + "symbols-numberSystem-latn": { + "decimal": ",", + "group": ".", + "list": ";", + "percentSign": "%", + "plusSign": "+", + "minusSign": "-", + "exponential": "E", + "superscriptingExponent": "×", + "perMille": "‰", + "infinity": "∞", + "nan": "NaN", + "timeSeparator": ":" + }, + "decimalFormats-numberSystem-latn": { + "standard": "#,##0.###", + "long": { + "decimalFormat": { + "1000-count-one": "0 mil", + "1000-count-other": "0 mil", + "10000-count-one": "00 mil", + "10000-count-other": "00 mil", + "100000-count-one": "000 mil", + "100000-count-other": "000 mil", + "1000000-count-one": "0 millón", + "1000000-count-other": "0 millones", + "10000000-count-one": "00 millones", + "10000000-count-other": "00 millones", + "100000000-count-one": "000 millones", + "100000000-count-other": "000 millones", + "1000000000-count-one": "0 mil millones", + "1000000000-count-other": "0 mil millones", + "10000000000-count-one": "00 mil millones", + "10000000000-count-other": "00 mil millones", + "100000000000-count-one": "000 mil millones", + "100000000000-count-other": "000 mil millones", + "1000000000000-count-one": "0 billón", + "1000000000000-count-other": "0 billones", + "10000000000000-count-one": "00 billones", + "10000000000000-count-other": "00 billones", + "100000000000000-count-one": "000 billones", + "100000000000000-count-other": "000 billones" + } + }, + "short": { + "decimalFormat": { + "1000-count-one": "0 K", + "1000-count-other": "0 K", + "10000-count-one": "00 K", + "10000-count-other": "00 K", + "100000-count-one": "000 K", + "100000-count-other": "000 K", + "1000000-count-one": "0 M", + "1000000-count-other": "0 M", + "10000000-count-one": "00 M", + "10000000-count-other": "00 M", + "100000000-count-one": "000 M", + "100000000-count-other": "000 M", + "1000000000-count-one": "0000 M", + "1000000000-count-other": "0000 M", + "10000000000-count-one": "00 MRD", + "10000000000-count-other": "00 MRD", + "100000000000-count-one": "000 MRD", + "100000000000-count-other": "000 MRD", + "1000000000000-count-one": "0 B", + "1000000000000-count-other": "0 B", + "10000000000000-count-one": "00 B", + "10000000000000-count-other": "00 B", + "100000000000000-count-one": "000 B", + "100000000000000-count-other": "000 B" + } + } + }, + "scientificFormats-numberSystem-latn": { + "standard": "#E0" + }, + "percentFormats-numberSystem-latn": { + "standard": "#,##0 %" + }, + "currencyFormats-numberSystem-latn": { + "currencySpacing": { + "beforeCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + }, + "afterCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + } + }, + "accounting": "#,##0.00 ¤", + "standard": "#,##0.00 ¤", + "unitPattern-count-one": "{0} {1}", + "unitPattern-count-other": "{0} {1}" + }, + "miscPatterns-numberSystem-latn": { + "atLeast": "Más de {0}", + "range": "{0}-{1}" + } } } } @@ -932,14 +1484,122 @@ Globalize.load({ "en": { "identity": { "version": { - "_cldrVersion": "25", - "_number": "$Revision: 91 $" + "_cldrVersion": "27.0.1", + "_number": "$Revision: 11348 $" }, "generation": { - "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + "_date": "$Date: 2015-03-05 01:15:52 -0600 (Thu, 05 Mar 2015) $" }, "language": "en" }, + "numbers": { + "defaultNumberingSystem": "latn", + "otherNumberingSystems": { + "native": "latn" + }, + "minimumGroupingDigits": "1", + "symbols-numberSystem-latn": { + "decimal": ".", + "group": ",", + "list": ";", + "percentSign": "%", + "plusSign": "+", + "minusSign": "-", + "exponential": "E", + "superscriptingExponent": "×", + "perMille": "‰", + "infinity": "∞", + "nan": "NaN", + "timeSeparator": ":" + }, + "decimalFormats-numberSystem-latn": { + "standard": "#,##0.###", + "long": { + "decimalFormat": { + "1000-count-one": "0 thousand", + "1000-count-other": "0 thousand", + "10000-count-one": "00 thousand", + "10000-count-other": "00 thousand", + "100000-count-one": "000 thousand", + "100000-count-other": "000 thousand", + "1000000-count-one": "0 million", + "1000000-count-other": "0 million", + "10000000-count-one": "00 million", + "10000000-count-other": "00 million", + "100000000-count-one": "000 million", + "100000000-count-other": "000 million", + "1000000000-count-one": "0 billion", + "1000000000-count-other": "0 billion", + "10000000000-count-one": "00 billion", + "10000000000-count-other": "00 billion", + "100000000000-count-one": "000 billion", + "100000000000-count-other": "000 billion", + "1000000000000-count-one": "0 trillion", + "1000000000000-count-other": "0 trillion", + "10000000000000-count-one": "00 trillion", + "10000000000000-count-other": "00 trillion", + "100000000000000-count-one": "000 trillion", + "100000000000000-count-other": "000 trillion" + } + }, + "short": { + "decimalFormat": { + "1000-count-one": "0K", + "1000-count-other": "0K", + "10000-count-one": "00K", + "10000-count-other": "00K", + "100000-count-one": "000K", + "100000-count-other": "000K", + "1000000-count-one": "0M", + "1000000-count-other": "0M", + "10000000-count-one": "00M", + "10000000-count-other": "00M", + "100000000-count-one": "000M", + "100000000-count-other": "000M", + "1000000000-count-one": "0B", + "1000000000-count-other": "0B", + "10000000000-count-one": "00B", + "10000000000-count-other": "00B", + "100000000000-count-one": "000B", + "100000000000-count-other": "000B", + "1000000000000-count-one": "0T", + "1000000000000-count-other": "0T", + "10000000000000-count-one": "00T", + "10000000000000-count-other": "00T", + "100000000000000-count-one": "000T", + "100000000000000-count-other": "000T" + } + } + }, + "scientificFormats-numberSystem-latn": { + "standard": "#E0" + }, + "percentFormats-numberSystem-latn": { + "standard": "#,##0%" + }, + "currencyFormats-numberSystem-latn": { + "currencySpacing": { + "beforeCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + }, + "afterCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + } + }, + "accounting": "¤#,##0.00;(¤#,##0.00)", + "standard": "¤#,##0.00", + "unitPattern-count-one": "{0} {1}", + "unitPattern-count-other": "{0} {1}" + }, + "miscPatterns-numberSystem-latn": { + "atLeast": "{0}+", + "range": "{0}–{1}" + } + }, "dates": { "calendars": { "gregorian": { @@ -1235,6 +1895,7 @@ Globalize.load({ "medium": "{1}, {0}", "short": "{1}, {0}", "availableFormats": { + "E": "ccc", "EHm": "E HH:mm", "EHms": "E HH:mm:ss", "Ed": "d E", @@ -1247,6 +1908,8 @@ Globalize.load({ "H": "HH", "Hm": "HH:mm", "Hms": "HH:mm:ss", + "Hmsv": "HH:mm:ss v", + "Hmv": "HH:mm v", "M": "L", "MEd": "E, M/d", "MMM": "LLL", @@ -1257,6 +1920,8 @@ Globalize.load({ "h": "h a", "hm": "h:mm a", "hms": "h:mm:ss a", + "hmsv": "h:mm:ss a v", + "hmv": "h:mm a v", "ms": "mm:ss", "y": "y", "yM": "M/y", @@ -1389,11 +2054,11 @@ Globalize.load({ "de": { "identity": { "version": { - "_cldrVersion": "25", - "_number": "$Revision: 91 $" + "_cldrVersion": "27.0.1", + "_number": "$Revision: 11304 $" }, "generation": { - "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + "_date": "$Date: 2015-02-24 11:35:18 -0600 (Tue, 24 Feb 2015) $" }, "language": "de" }, @@ -1619,13 +2284,13 @@ Globalize.load({ "evening": "abends", "morning": "vormittags", "night": "nachts", - "noon": "Mittag", + "noon": "mittags", "pm": "nachm." }, "narrow": { - "am": "a", - "noon": "n", - "pm": "p" + "am": "vm.", + "noon": "m.", + "pm": "nm." }, "wide": { "afternoon": "nachmittags", @@ -1634,7 +2299,7 @@ Globalize.load({ "evening": "abends", "morning": "vormittags", "night": "nachts", - "noon": "Mittag", + "noon": "mittags", "pm": "nachm." } }, @@ -1646,22 +2311,22 @@ Globalize.load({ "evening": "abends", "morning": "vormittags", "night": "nachts", - "noon": "Mittag", + "noon": "mittags", "pm": "nachm." }, "narrow": { - "am": "a", - "noon": "n", - "pm": "p" + "am": "vm.", + "noon": "m.", + "pm": "nm." }, "wide": { - "afternoon": "Nachmittag", + "afternoon": "nachmittags", "am": "vorm.", - "earlyMorning": "Morgen", - "evening": "Abend", - "morning": "Vormittag", - "night": "Nacht", - "noon": "Mittag", + "earlyMorning": "morgens", + "evening": "abends", + "morning": "vormittags", + "night": "nachts", + "noon": "mittags", "pm": "nachm." } } @@ -1669,9 +2334,9 @@ Globalize.load({ "eras": { "eraNames": { "0": "v. Chr.", - "0-alt-variant": "vor der gewöhnlichen Zeitrechnung", + "0-alt-variant": "vor unserer Zeitrechnung", "1": "n. Chr.", - "1-alt-variant": "der gewöhnlichen Zeitrechnung" + "1-alt-variant": "unserer Zeitrechnung" }, "eraAbbr": { "0": "v. Chr.", @@ -1681,9 +2346,9 @@ Globalize.load({ }, "eraNarrow": { "0": "v. Chr.", - "0-alt-variant": "vdZ", + "0-alt-variant": "v. u. Z.", "1": "n. Chr.", - "1-alt-variant": "dZ" + "1-alt-variant": "u. Z." } }, "dateFormats": { @@ -1699,11 +2364,12 @@ Globalize.load({ "short": "HH:mm" }, "dateTimeFormats": { - "full": "{1} {0}", - "long": "{1} {0}", - "medium": "{1} {0}", - "short": "{1} {0}", + "full": "{1} 'um' {0}", + "long": "{1} 'um' {0}", + "medium": "{1}, {0}", + "short": "{1}, {0}", "availableFormats": { + "E": "ccc", "EHm": "E, HH:mm", "EHms": "E, HH:mm:ss", "Ed": "E, d.", @@ -1716,6 +2382,8 @@ Globalize.load({ "H": "HH 'Uhr'", "Hm": "HH:mm", "Hms": "HH:mm:ss", + "Hmsv": "HH:mm:ss v", + "Hmv": "HH:mm v", "M": "L", "MEd": "E, d.M.", "MMM": "LLL", @@ -1729,6 +2397,8 @@ Globalize.load({ "h": "h a", "hm": "h:mm a", "hms": "h:mm:ss a", + "hmsv": "h:mm:ss a v", + "hmv": "h:mm a v", "ms": "mm:ss", "y": "y", "yM": "M.y", @@ -1757,106 +2427,214 @@ Globalize.load({ "Year": "{1} {0}" }, "intervalFormats": { - "intervalFormatFallback": "{0} - {1}", + "intervalFormatFallback": "{0} – {1}", "H": { - "H": "HH-HH 'Uhr'" + "H": "HH–HH 'Uhr'" }, "Hm": { - "H": "HH:mm-HH:mm", - "m": "HH:mm-HH:mm" + "H": "HH:mm–HH:mm", + "m": "HH:mm–HH:mm" }, "Hmv": { - "H": "HH:mm-HH:mm v", - "m": "HH:mm-HH:mm v" + "H": "HH:mm–HH:mm v", + "m": "HH:mm–HH:mm v" }, "Hv": { - "H": "HH-HH 'Uhr' v" + "H": "HH–HH 'Uhr' v" }, "M": { - "M": "M.-M." + "M": "M.–M." }, "MEd": { - "M": "E, dd.MM. - E, dd.MM.", - "d": "E, dd.MM. - E, dd.MM." + "M": "E, dd.MM. – E, dd.MM.", + "d": "E, dd.MM. – E, dd.MM." }, "MMM": { - "M": "MMM-MMM" + "M": "MMM–MMM" }, "MMMEd": { - "M": "E, d. MMM - E, d. MMM", - "d": "E, d. - E, d. MMM" + "M": "E, d. MMM – E, d. MMM", + "d": "E, d. – E, d. MMM" }, "MMMM": { - "M": "LLLL-LLLL" + "M": "LLLL–LLLL" }, "MMMd": { - "M": "d. MMM - d. MMM", - "d": "d.-d. MMM" + "M": "d. MMM – d. MMM", + "d": "d.–d. MMM" }, "Md": { - "M": "dd.MM. - dd.MM.", - "d": "dd.MM. - dd.MM." + "M": "dd.MM. – dd.MM.", + "d": "dd.MM. – dd.MM." }, "d": { - "d": "d.-d." + "d": "d.–d." }, "h": { - "a": "h a - h a", - "h": "h-h a" + "a": "h a – h a", + "h": "h–h a" }, "hm": { - "a": "h:mm a - h:mm a", - "h": "h:mm-h:mm a", - "m": "h:mm-h:mm a" + "a": "h:mm a – h:mm a", + "h": "h:mm–h:mm a", + "m": "h:mm–h:mm a" }, "hmv": { - "a": "h:mm a - h:mm a v", - "h": "h:mm-h:mm a v", - "m": "h:mm-h:mm a v" + "a": "h:mm a – h:mm a v", + "h": "h:mm–h:mm a v", + "m": "h:mm–h:mm a v" }, "hv": { - "a": "h a - h a v", - "h": "h-h a v" + "a": "h a – h a v", + "h": "h–h a v" }, "y": { - "y": "y-y" + "y": "y–y" }, "yM": { - "M": "MM.y - MM.y", - "y": "MM.y - MM.y" + "M": "MM.y – MM.y", + "y": "MM.y – MM.y" }, "yMEd": { - "M": "E, dd.MM.y - E, dd.MM.y", - "d": "E, dd.MM.y - E, dd.MM.y", - "y": "E, dd.MM.y - E, dd.MM.y" + "M": "E, dd.MM.y – E, dd.MM.y", + "d": "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" + "M": "MMM–MMM y", + "y": "MMM y – MMM y" }, "yMMMEd": { - "M": "E, d. MMM - E, d. MMM y", - "d": "E, d. - E, d. MMM y", - "y": "E, d. MMM y - E, d. MMM y" + "M": "E, d. MMM – E, d. MMM y", + "d": "E, d. – E, d. MMM y", + "y": "E, d. MMM y – E, d. MMM y" }, "yMMMM": { - "M": "MMMM-MMMM y", - "y": "MMMM y - MMMM y" + "M": "MMMM–MMMM y", + "y": "MMMM y – MMMM y" }, "yMMMd": { - "M": "d. MMM - d. MMM y", - "d": "d.-d. MMM y", - "y": "d. MMM y - d. MMM y" + "M": "d. MMM – d. MMM y", + "d": "d.–d. MMM y", + "y": "d. MMM y – d. MMM y" }, "yMd": { - "M": "dd.MM.y - dd.MM.y", - "d": "dd.MM.y - dd.MM.y", - "y": "dd.MM.y - dd.MM.y" + "M": "dd.MM.y – dd.MM.y", + "d": "dd.MM.y – dd.MM.y", + "y": "dd.MM.y – dd.MM.y" } } } } } + }, + "numbers": { + "defaultNumberingSystem": "latn", + "otherNumberingSystems": { + "native": "latn" + }, + "minimumGroupingDigits": "1", + "symbols-numberSystem-latn": { + "decimal": ",", + "group": ".", + "list": ";", + "percentSign": "%", + "plusSign": "+", + "minusSign": "-", + "exponential": "E", + "superscriptingExponent": "·", + "perMille": "‰", + "infinity": "∞", + "nan": "NaN", + "timeSeparator": ":" + }, + "decimalFormats-numberSystem-latn": { + "standard": "#,##0.###", + "long": { + "decimalFormat": { + "1000-count-one": "0 Tausend", + "1000-count-other": "0 Tausend", + "10000-count-one": "00 Tausend", + "10000-count-other": "00 Tausend", + "100000-count-one": "000 Tausend", + "100000-count-other": "000 Tausend", + "1000000-count-one": "0 Million", + "1000000-count-other": "0 Millionen", + "10000000-count-one": "00 Millionen", + "10000000-count-other": "00 Millionen", + "100000000-count-one": "000 Millionen", + "100000000-count-other": "000 Millionen", + "1000000000-count-one": "0 Milliarde", + "1000000000-count-other": "0 Milliarden", + "10000000000-count-one": "00 Milliarden", + "10000000000-count-other": "00 Milliarden", + "100000000000-count-one": "000 Milliarden", + "100000000000-count-other": "000 Milliarden", + "1000000000000-count-one": "0 Billion", + "1000000000000-count-other": "0 Billionen", + "10000000000000-count-one": "00 Billionen", + "10000000000000-count-other": "00 Billionen", + "100000000000000-count-one": "000 Billionen", + "100000000000000-count-other": "000 Billionen" + } + }, + "short": { + "decimalFormat": { + "1000-count-one": "0 Tsd'.'", + "1000-count-other": "0 Tsd'.'", + "10000-count-one": "00 Tsd'.'", + "10000-count-other": "00 Tsd'.'", + "100000-count-one": "000 Tsd'.'", + "100000-count-other": "000 Tsd'.'", + "1000000-count-one": "0 Mio'.'", + "1000000-count-other": "0 Mio'.'", + "10000000-count-one": "00 Mio'.'", + "10000000-count-other": "00 Mio'.'", + "100000000-count-one": "000 Mio'.'", + "100000000-count-other": "000 Mio'.'", + "1000000000-count-one": "0 Mrd'.'", + "1000000000-count-other": "0 Mrd'.'", + "10000000000-count-one": "00 Mrd'.'", + "10000000000-count-other": "00 Mrd'.'", + "100000000000-count-one": "000 Mrd'.'", + "100000000000-count-other": "000 Mrd'.'", + "1000000000000-count-one": "0 Bio'.'", + "1000000000000-count-other": "0 Bio'.'", + "10000000000000-count-one": "00 Bio'.'", + "10000000000000-count-other": "00 Bio'.'", + "100000000000000-count-one": "000 Bio'.'", + "100000000000000-count-other": "000 Bio'.'" + } + } + }, + "scientificFormats-numberSystem-latn": { + "standard": "#E0" + }, + "percentFormats-numberSystem-latn": { + "standard": "#,##0 %" + }, + "currencyFormats-numberSystem-latn": { + "currencySpacing": { + "beforeCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + }, + "afterCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + } + }, + "accounting": "#,##0.00 ¤", + "standard": "#,##0.00 ¤", + "unitPattern-count-one": "{0} {1}", + "unitPattern-count-other": "{0} {1}" + }, + "miscPatterns-numberSystem-latn": { + "atLeast": "{0}+", + "range": "{0}–{1}" + } } } } @@ -1867,13 +2645,13 @@ Globalize.load({ "zh": { "identity": { "version": { - "_cldrVersion": "25", - "_number": "$Revision: 91 $" + "_cldrVersion": "27.0.1", + "_number": "$Revision: 11294 $" }, "generation": { - "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + "_date": "$Date: 2015-02-23 16:50:24 -0600 (Mon, 23 Feb 2015) $" }, - "language": "root" + "language": "zh" }, "dates": { "calendars": { @@ -2187,8 +2965,8 @@ Globalize.load({ "short": "yy/M/d" }, "timeFormats": { - "full": "zzzzah:mm:ss", - "long": "zah:mm:ss", + "full": "zzzz ah:mm:ss", + "long": "z ah:mm:ss", "medium": "ah:mm:ss", "short": "ah:mm" }, @@ -2198,6 +2976,7 @@ Globalize.load({ "medium": "{1} {0}", "short": "{1} {0}", "availableFormats": { + "E": "ccc", "EHm": "EHH:mm", "EHms": "EHH:mm:ss", "Ed": "d日E", @@ -2210,6 +2989,8 @@ Globalize.load({ "H": "H时", "Hm": "HH:mm", "Hms": "HH:mm:ss", + "Hmsv": "v HH:mm:ss", + "Hmv": "v HH:mm", "M": "M月", "MEd": "M/dE", "MMM": "LLL", @@ -2222,9 +3003,11 @@ Globalize.load({ "h": "ah时", "hm": "ah:mm", "hms": "ah:mm:ss", + "hmsv": "v ah:mm:ss", + "hmv": "v ah:mm", "ms": "mm:ss", "y": "y年", - "yM": "y/M", + "yM": "y年M月", "yMEd": "y/M/dE", "yMM": "y年M月", "yMMM": "y年M月", @@ -2346,6 +3129,167 @@ Globalize.load({ } } } + }, + "numbers": { + "defaultNumberingSystem": "latn", + "otherNumberingSystems": { + "native": "hanidec", + "traditional": "hans", + "finance": "hansfin" + }, + "minimumGroupingDigits": "1", + "symbols-numberSystem-hanidec": { + "decimal": ".", + "group": ",", + "list": ";", + "percentSign": "%", + "plusSign": "+", + "minusSign": "-", + "exponential": "E", + "superscriptingExponent": "×", + "perMille": "‰", + "infinity": "∞", + "nan": "NaN", + "timeSeparator": ":" + }, + "symbols-numberSystem-latn": { + "decimal": ".", + "group": ",", + "list": ";", + "percentSign": "%", + "plusSign": "+", + "minusSign": "-", + "exponential": "E", + "superscriptingExponent": "×", + "perMille": "‰", + "infinity": "∞", + "nan": "NaN", + "timeSeparator": ":" + }, + "decimalFormats-numberSystem-hanidec": { + "standard": "#,##0.###", + "long": { + "decimalFormat": { + "1000-count-other": "0千", + "10000-count-other": "0万", + "100000-count-other": "00万", + "1000000-count-other": "000万", + "10000000-count-other": "0000万", + "100000000-count-other": "0亿", + "1000000000-count-other": "00亿", + "10000000000-count-other": "000亿", + "100000000000-count-other": "0000亿", + "1000000000000-count-other": "0兆", + "10000000000000-count-other": "00兆", + "100000000000000-count-other": "000兆" + } + }, + "short": { + "decimalFormat": { + "1000-count-other": "0千", + "10000-count-other": "0万", + "100000-count-other": "00万", + "1000000-count-other": "000万", + "10000000-count-other": "0000万", + "100000000-count-other": "0亿", + "1000000000-count-other": "00亿", + "10000000000-count-other": "000亿", + "100000000000-count-other": "0000亿", + "1000000000000-count-other": "0兆", + "10000000000000-count-other": "00兆", + "100000000000000-count-other": "000兆" + } + } + }, + "decimalFormats-numberSystem-latn": { + "standard": "#,##0.###", + "long": { + "decimalFormat": { + "1000-count-other": "0千", + "10000-count-other": "0万", + "100000-count-other": "00万", + "1000000-count-other": "000万", + "10000000-count-other": "0000万", + "100000000-count-other": "0亿", + "1000000000-count-other": "00亿", + "10000000000-count-other": "000亿", + "100000000000-count-other": "0000亿", + "1000000000000-count-other": "0兆", + "10000000000000-count-other": "00兆", + "100000000000000-count-other": "000兆" + } + }, + "short": { + "decimalFormat": { + "1000-count-other": "0千", + "10000-count-other": "0万", + "100000-count-other": "00万", + "1000000-count-other": "000万", + "10000000-count-other": "0000万", + "100000000-count-other": "0亿", + "1000000000-count-other": "00亿", + "10000000000-count-other": "000亿", + "100000000000-count-other": "0000亿", + "1000000000000-count-other": "0兆", + "10000000000000-count-other": "00兆", + "100000000000000-count-other": "000兆" + } + } + }, + "scientificFormats-numberSystem-hanidec": { + "standard": "#E0" + }, + "scientificFormats-numberSystem-latn": { + "standard": "#E0" + }, + "percentFormats-numberSystem-hanidec": { + "standard": "#,##0%" + }, + "percentFormats-numberSystem-latn": { + "standard": "#,##0%" + }, + "currencyFormats-numberSystem-hanidec": { + "currencySpacing": { + "beforeCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + }, + "afterCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + } + }, + "accounting": "¤#,##0.00;(¤#,##0.00)", + "standard": "¤ #,##0.00", + "unitPattern-count-other": "{0}{1}" + }, + "currencyFormats-numberSystem-latn": { + "currencySpacing": { + "beforeCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + }, + "afterCurrency": { + "currencyMatch": "[:^S:]", + "surroundingMatch": "[:digit:]", + "insertBetween": " " + } + }, + "accounting": "¤#,##0.00;(¤#,##0.00)", + "standard": "¤ #,##0.00", + "unitPattern-count-other": "{0}{1}" + }, + "miscPatterns-numberSystem-hanidec": { + "atLeast": "{0}+", + "range": "{0}-{1}" + }, + "miscPatterns-numberSystem-latn": { + "atLeast": "{0}+", + "range": "{0}-{1}" + } } } } @@ -2354,26 +3298,40 @@ Globalize.load({ Globalize.load({ "supplemental": { "version": { - "_cldrVersion": "25", - "_number": "$Revision: 91 $" + "_unicodeVersion": "7.0.0", + "_number": "$Revision: 11318 $" }, "generation": { - "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + "_date": "$Date: 2015-02-25 23:47:56 -0600 (Wed, 25 Feb 2015) $" }, "likelySubtags": { "aa": "aa-Latn-ET", "ab": "ab-Cyrl-GE", + "abr": "abr-Latn-GH", "ace": "ace-Latn-ID", "ach": "ach-Latn-UG", + "ada": "ada-Latn-GH", "ady": "ady-Cyrl-RU", + "ae": "ae-Avst-IR", + "aeb": "aeb-Arab-TN", "af": "af-Latn-ZA", "agq": "agq-Latn-CM", "ak": "ak-Latn-GH", + "akk": "akk-Xsux-IQ", + "aln": "aln-Latn-XK", "alt": "alt-Cyrl-RU", "am": "am-Ethi-ET", "amo": "amo-Latn-NG", "aoz": "aoz-Latn-ID", "ar": "ar-Arab-EG", + "arc": "arc-Armi-IR", + "arc-Nbat": "arc-Nbat-JO", + "arc-Palm": "arc-Palm-SY", + "arn": "arn-Latn-CL", + "aro": "aro-Latn-BO", + "arq": "arq-Arab-DZ", + "ary": "ary-Arab-MA", + "arz": "arz-Arab-EG", "as": "as-Beng-IN", "asa": "asa-Latn-TZ", "ast": "ast-Latn-ES", @@ -2385,40 +3343,54 @@ Globalize.load({ "az-Arab": "az-Arab-IR", "az-IR": "az-Arab-IR", "az-RU": "az-Cyrl-RU", + "azb": "azb-Arab-IR", "ba": "ba-Cyrl-RU", "bal": "bal-Arab-PK", "ban": "ban-Latn-ID", "bap": "bap-Deva-NP", + "bar": "bar-Latn-AT", "bas": "bas-Latn-CM", "bax": "bax-Bamu-CM", "bbc": "bbc-Latn-ID", "bbj": "bbj-Latn-CM", + "bci": "bci-Latn-CI", "be": "be-Cyrl-BY", "bem": "bem-Latn-ZM", + "bew": "bew-Latn-ID", "bez": "bez-Latn-TZ", "bfd": "bfd-Latn-CM", "bfq": "bfq-Taml-IN", "bft": "bft-Arab-PK", "bfy": "bfy-Deva-IN", "bg": "bg-Cyrl-BG", + "bgc": "bgc-Deva-IN", "bgx": "bgx-Grek-TR", + "bh": "bh-Kthi-IN", "bhb": "bhb-Deva-IN", + "bhi": "bhi-Deva-IN", + "bhk": "bhk-Latn-PH", "bho": "bho-Deva-IN", "bi": "bi-Latn-VU", "bik": "bik-Latn-PH", "bin": "bin-Latn-NG", "bjj": "bjj-Deva-IN", + "bjn": "bjn-Latn-ID", "bkm": "bkm-Latn-CM", "bku": "bku-Latn-PH", + "blt": "blt-Tavt-VN", "bm": "bm-Latn-ML", "bmq": "bmq-Latn-ML", "bn": "bn-Beng-BD", "bo": "bo-Tibt-CN", + "bpy": "bpy-Beng-IN", + "bqi": "bqi-Arab-IR", "bqv": "bqv-Latn-CI", "br": "br-Latn-FR", "bra": "bra-Deva-IN", + "brh": "brh-Arab-PK", "brx": "brx-Deva-IN", "bs": "bs-Latn-BA", + "bsq": "bsq-Bass-LR", "bss": "bss-Latn-CM", "bto": "bto-Latn-PH", "btv": "btv-Deva-PK", @@ -2427,39 +3399,47 @@ Globalize.load({ "bug": "bug-Latn-ID", "bum": "bum-Latn-CM", "bvb": "bvb-Latn-GQ", - "bya": "bya-Latn-ID", "byn": "byn-Ethi-ER", "byv": "byv-Latn-CM", "bze": "bze-Latn-ML", "ca": "ca-Latn-ES", "cch": "cch-Latn-NG", "ccp": "ccp-Beng-IN", + "ccp-Cakm": "ccp-Cakm-BD", "ce": "ce-Cyrl-RU", "ceb": "ceb-Latn-PH", "cgg": "cgg-Latn-UG", "ch": "ch-Latn-GU", "chk": "chk-Latn-FM", "chm": "chm-Cyrl-RU", + "cho": "cho-Latn-US", "chp": "chp-Latn-CA", "chr": "chr-Cher-US", "cja": "cja-Arab-KH", "cjm": "cjm-Cham-VN", "ckb": "ckb-Arab-IQ", "co": "co-Latn-FR", + "cop": "cop-Copt-EG", + "cps": "cps-Latn-PH", "cr": "cr-Cans-CA", "crj": "crj-Cans-CA", "crk": "crk-Cans-CA", "crl": "crl-Cans-CA", "crm": "crm-Cans-CA", + "crs": "crs-Latn-SC", "cs": "cs-Latn-CZ", "csb": "csb-Latn-PL", "csw": "csw-Cans-CA", + "ctd": "ctd-Pauc-MM", "cu": "cu-Cyrl-RU", + "cu-Glag": "cu-Glag-BG", "cv": "cv-Cyrl-RU", "cy": "cy-Latn-GB", "da": "da-Latn-DK", + "dak": "dak-Latn-US", "dar": "dar-Cyrl-RU", "dav": "dav-Latn-KE", + "dcc": "dcc-Arab-IN", "de": "de-Latn-DE", "den": "den-Latn-CA", "dgr": "dgr-Latn-CA", @@ -2468,6 +3448,7 @@ Globalize.load({ "doi": "doi-Arab-IN", "dsb": "dsb-Latn-DE", "dtm": "dtm-Latn-ML", + "dtp": "dtp-Latn-MY", "dua": "dua-Latn-CM", "dv": "dv-Thaa-MV", "dyo": "dyo-Latn-SN", @@ -2476,16 +3457,24 @@ Globalize.load({ "ebu": "ebu-Latn-KE", "ee": "ee-Latn-GH", "efi": "efi-Latn-NG", + "egl": "egl-Latn-IT", + "egy": "egy-Egyp-EG", + "eky": "eky-Kali-MM", "el": "el-Grek-GR", "en": "en-Latn-US", + "en-Shaw": "en-Shaw-GB", "eo": "eo-Latn-001", "es": "es-Latn-ES", + "esu": "esu-Latn-US", "et": "et-Latn-EE", + "ett": "ett-Ital-IT", "eu": "eu-Latn-ES", "ewo": "ewo-Latn-CM", + "ext": "ext-Latn-ES", "fa": "fa-Arab-IR", "fan": "fan-Latn-GQ", "ff": "ff-Latn-SN", + "ffm": "ffm-Latn-ML", "fi": "fi-Latn-FI", "fil": "fil-Latn-PH", "fit": "fit-Latn-SE", @@ -2493,12 +3482,22 @@ Globalize.load({ "fo": "fo-Latn-FO", "fon": "fon-Latn-BJ", "fr": "fr-Latn-FR", + "frc": "frc-Latn-US", + "frp": "frp-Latn-FR", + "frr": "frr-Latn-DE", + "frs": "frs-Latn-DE", + "fud": "fud-Latn-WF", + "fuq": "fuq-Latn-NE", "fur": "fur-Latn-IT", + "fuv": "fuv-Latn-NG", "fy": "fy-Latn-NL", "ga": "ga-Latn-IE", "gaa": "gaa-Latn-GH", "gag": "gag-Latn-MD", + "gan": "gan-Hans-CN", + "gay": "gay-Latn-ID", "gbm": "gbm-Deva-IN", + "gbz": "gbz-Arab-IR", "gcr": "gcr-Latn-GF", "gd": "gd-Latn-GB", "gez": "gez-Ethi-ET", @@ -2507,14 +3506,21 @@ Globalize.load({ "gjk": "gjk-Arab-PK", "gju": "gju-Arab-PK", "gl": "gl-Latn-ES", + "glk": "glk-Arab-IR", "gn": "gn-Latn-PY", + "gom": "gom-Deva-IN", "gon": "gon-Telu-IN", "gor": "gor-Latn-ID", "gos": "gos-Latn-NL", + "got": "got-Goth-UA", + "grc": "grc-Cprt-CY", + "grc-Linb": "grc-Linb-GR", "grt": "grt-Beng-IN", "gsw": "gsw-Latn-CH", "gu": "gu-Gujr-IN", "gub": "gub-Latn-BR", + "guc": "guc-Latn-CO", + "gur": "gur-Latn-GH", "guz": "guz-Latn-KE", "gv": "gv-Latn-IM", "gvr": "gvr-Deva-NP", @@ -2522,27 +3528,37 @@ Globalize.load({ "ha": "ha-Latn-NG", "ha-CM": "ha-Arab-CM", "ha-SD": "ha-Arab-SD", + "hak": "hak-Hans-CN", "haw": "haw-Latn-US", + "haz": "haz-Arab-AF", "he": "he-Hebr-IL", "hi": "hi-Deva-IN", + "hif": "hif-Deva-FJ", "hil": "hil-Latn-PH", + "hmd": "hmd-Plrd-CN", "hnd": "hnd-Arab-PK", "hne": "hne-Deva-IN", + "hnj": "hnj-Hmng-LA", "hnn": "hnn-Latn-PH", + "hno": "hno-Arab-PK", "ho": "ho-Latn-PG", "hoc": "hoc-Deva-IN", "hoj": "hoj-Deva-IN", "hr": "hr-Latn-HR", "hsb": "hsb-Latn-DE", + "hsn": "hsn-Hans-CN", "ht": "ht-Latn-HT", "hu": "hu-Latn-HU", "hy": "hy-Armn-AM", + "hz": "hz-Latn-NA", "ia": "ia-Latn-FR", + "iba": "iba-Latn-MY", "ibb": "ibb-Latn-NG", "id": "id-Latn-ID", "ig": "ig-Latn-NG", "ii": "ii-Yiii-CN", "ik": "ik-Latn-US", + "ikt": "ikt-Latn-CA", "ilo": "ilo-Latn-PH", "in": "in-Latn-ID", "inh": "inh-Cyrl-RU", @@ -2550,16 +3566,20 @@ Globalize.load({ "it": "it-Latn-IT", "iu": "iu-Cans-CA", "iw": "iw-Hebr-IL", + "izh": "izh-Latn-RU", "ja": "ja-Jpan-JP", + "jam": "jam-Latn-JM", "jgo": "jgo-Latn-CM", "ji": "ji-Hebr-UA", "jmc": "jmc-Latn-TZ", "jml": "jml-Deva-NP", + "jut": "jut-Latn-DK", "jv": "jv-Latn-ID", "jw": "jw-Latn-ID", "ka": "ka-Geor-GE", "kaa": "kaa-Cyrl-UZ", "kab": "kab-Latn-DZ", + "kac": "kac-Latn-MM", "kaj": "kaj-Latn-NG", "kam": "kam-Latn-KE", "kao": "kao-Latn-ML", @@ -2572,15 +3592,18 @@ Globalize.load({ "ken": "ken-Latn-CM", "kfo": "kfo-Latn-CI", "kfr": "kfr-Deva-IN", + "kfy": "kfy-Deva-IN", "kg": "kg-Latn-CD", "kge": "kge-Latn-ID", "kgp": "kgp-Latn-BR", "kha": "kha-Latn-IN", "khb": "khb-Talu-CN", + "khn": "khn-Deva-IN", "khq": "khq-Latn-ML", "kht": "kht-Mymr-IN", "khw": "khw-Arab-PK", "ki": "ki-Latn-KE", + "kiu": "kiu-Latn-TR", "kj": "kj-Latn-NA", "kjg": "kjg-Laoo-LA", "kk": "kk-Cyrl-KZ", @@ -2602,6 +3625,7 @@ Globalize.load({ "kpe": "kpe-Latn-LR", "krc": "krc-Cyrl-RU", "kri": "kri-Latn-SL", + "krj": "krj-Latn-PH", "krl": "krl-Latn-RU", "kru": "kru-Deva-IN", "ks": "ks-Arab-IN", @@ -2616,6 +3640,7 @@ Globalize.load({ "kvr": "kvr-Latn-ID", "kvx": "kvx-Arab-PK", "kw": "kw-Latn-GB", + "kxm": "kxm-Thai-TH", "kxp": "kxp-Arab-PK", "ky": "ky-Cyrl-KG", "ky-Arab": "ky-Arab-CN", @@ -2623,8 +3648,11 @@ Globalize.load({ "ky-Latn": "ky-Latn-TR", "ky-TR": "ky-Latn-TR", "la": "la-Latn-VA", + "lab": "lab-Lina-GR", + "lad": "lad-Hebr-IL", "lag": "lag-Latn-TZ", "lah": "lah-Arab-PK", + "laj": "laj-Latn-UG", "lb": "lb-Latn-LU", "lbe": "lbe-Cyrl-RU", "lbw": "lbw-Latn-ID", @@ -2634,16 +3662,21 @@ Globalize.load({ "lg": "lg-Latn-UG", "li": "li-Latn-NL", "lif": "lif-Deva-NP", + "lif-Limb": "lif-Limb-IN", + "lij": "lij-Latn-IT", "lis": "lis-Lisu-CN", + "ljp": "ljp-Latn-ID", "lki": "lki-Arab-IR", "lkt": "lkt-Latn-US", "lmn": "lmn-Telu-IN", - "lmo": "lmo-Latn-CH", + "lmo": "lmo-Latn-IT", "ln": "ln-Latn-CD", "lo": "lo-Laoo-LA", "lol": "lol-Latn-CD", "loz": "loz-Latn-ZM", + "lrc": "lrc-Arab-IR", "lt": "lt-Latn-LT", + "ltg": "ltg-Latn-LV", "lu": "lu-Latn-CD", "lua": "lua-Latn-CD", "luo": "luo-Latn-KE", @@ -2651,6 +3684,8 @@ Globalize.load({ "luz": "luz-Arab-IR", "lv": "lv-Latn-LV", "lwl": "lwl-Thai-TH", + "lzh": "lzh-Hans-CN", + "lzz": "lzz-Latn-TR", "mad": "mad-Latn-ID", "maf": "maf-Latn-CM", "mag": "mag-Deva-IN", @@ -2666,6 +3701,7 @@ Globalize.load({ "mdr": "mdr-Latn-ID", "men": "men-Latn-SL", "mer": "mer-Latn-KE", + "mfa": "mfa-Arab-TH", "mfe": "mfe-Latn-MU", "mg": "mg-Latn-MG", "mgh": "mgh-Latn-MZ", @@ -2683,41 +3719,56 @@ Globalize.load({ "mni": "mni-Beng-IN", "mnw": "mnw-Mymr-MM", "moe": "moe-Latn-CA", + "moh": "moh-Latn-CA", "mos": "mos-Latn-BF", "mr": "mr-Deva-IN", "mrd": "mrd-Deva-NP", "mrj": "mrj-Cyrl-RU", + "mru": "mru-Mroo-BD", "ms": "ms-Latn-MY", "ms-CC": "ms-Arab-CC", "ms-ID": "ms-Arab-ID", "mt": "mt-Latn-MT", + "mtr": "mtr-Deva-IN", "mua": "mua-Latn-CM", + "mus": "mus-Latn-US", "mvy": "mvy-Arab-PK", "mwk": "mwk-Latn-ML", "mwr": "mwr-Deva-IN", + "mwv": "mwv-Latn-ID", "mxc": "mxc-Latn-ZW", "my": "my-Mymr-MM", "myv": "myv-Cyrl-RU", + "myx": "myx-Latn-UG", + "myz": "myz-Mand-IR", + "mzn": "mzn-Arab-IR", "na": "na-Latn-NR", + "nan": "nan-Hans-CN", "nap": "nap-Latn-IT", "naq": "naq-Latn-NA", "nb": "nb-Latn-NO", "nch": "nch-Latn-MX", "nd": "nd-Latn-ZW", + "ndc": "ndc-Latn-MZ", "nds": "nds-Latn-DE", "ne": "ne-Deva-NP", "new": "new-Deva-NP", "ng": "ng-Latn-NA", + "ngl": "ngl-Latn-MZ", "nhe": "nhe-Latn-MX", "nhw": "nhw-Latn-MX", "nij": "nij-Latn-ID", "niu": "niu-Latn-NU", + "njo": "njo-Latn-IN", "nl": "nl-Latn-NL", "nmg": "nmg-Latn-CM", "nn": "nn-Latn-NO", "nnh": "nnh-Latn-CM", "no": "no-Latn-NO", "nod": "nod-Lana-TH", + "noe": "noe-Deva-IN", + "non": "non-Runr-SE", + "nqo": "nqo-Nkoo-GN", "nr": "nr-Latn-ZA", "nsk": "nsk-Cans-CA", "nso": "nso-Latn-ZA", @@ -2727,31 +3778,50 @@ Globalize.load({ "ny": "ny-Latn-MW", "nym": "nym-Latn-TZ", "nyn": "nyn-Latn-UG", + "nzi": "nzi-Latn-GH", "oc": "oc-Latn-FR", "om": "om-Latn-ET", "or": "or-Orya-IN", "os": "os-Cyrl-GE", + "otk": "otk-Orkh-MN", "pa": "pa-Guru-IN", "pa-Arab": "pa-Arab-PK", "pa-PK": "pa-Arab-PK", "pag": "pag-Latn-PH", + "pal": "pal-Phli-IR", + "pal-Phlp": "pal-Phlp-CN", "pam": "pam-Latn-PH", "pap": "pap-Latn-AW", "pau": "pau-Latn-PW", + "pcd": "pcd-Latn-FR", "pcm": "pcm-Latn-NG", + "pdc": "pdc-Latn-US", + "pdt": "pdt-Latn-CA", + "peo": "peo-Xpeo-IR", + "pfl": "pfl-Latn-DE", + "phn": "phn-Phnx-LB", + "pka": "pka-Brah-IN", "pko": "pko-Latn-KE", "pl": "pl-Latn-PL", + "pms": "pms-Latn-IT", + "pnt": "pnt-Grek-GR", "pon": "pon-Latn-FM", + "pra": "pra-Khar-PK", "prd": "prd-Arab-IR", "prg": "prg-Latn-001", "ps": "ps-Arab-AF", "pt": "pt-Latn-BR", "puu": "puu-Latn-GA", "qu": "qu-Latn-PE", + "quc": "quc-Latn-GT", + "qug": "qug-Latn-EC", "raj": "raj-Latn-IN", "rcf": "rcf-Latn-RE", "rej": "rej-Latn-ID", + "rgn": "rgn-Latn-IT", "ria": "ria-Latn-IN", + "rif": "rif-Tfng-MA", + "rif-NL": "rif-Latn-NL", "rjs": "rjs-Deva-NP", "rkt": "rkt-Beng-BD", "rm": "rm-Latn-CH", @@ -2764,8 +3834,10 @@ Globalize.load({ "ro": "ro-Latn-RO", "rob": "rob-Latn-ID", "rof": "rof-Latn-TZ", + "rtm": "rtm-Latn-FJ", "ru": "ru-Cyrl-RU", "rue": "rue-Cyrl-UA", + "rug": "rug-Latn-SB", "rw": "rw-Latn-RW", "rwk": "rwk-Latn-TZ", "ryu": "ryu-Kana-JP", @@ -2777,43 +3849,57 @@ Globalize.load({ "sat": "sat-Latn-IN", "saz": "saz-Saur-IN", "sbp": "sbp-Latn-TZ", + "sc": "sc-Latn-IT", + "sck": "sck-Deva-IN", "scn": "scn-Latn-IT", "sco": "sco-Latn-GB", "scs": "scs-Latn-CA", "sd": "sd-Arab-PK", "sd-Deva": "sd-Deva-IN", - "sdh": "sdh-Arab-IR", + "sd-Khoj": "sd-Khoj-IN", + "sd-Sind": "sd-Sind-IN", + "sdc": "sdc-Latn-IT", "se": "se-Latn-NO", "sef": "sef-Latn-CI", "seh": "seh-Latn-MZ", + "sei": "sei-Latn-MX", "ses": "ses-Latn-ML", "sg": "sg-Latn-CF", + "sga": "sga-Ogam-IE", + "sgs": "sgs-Latn-LT", "shi": "shi-Tfng-MA", "shn": "shn-Mymr-MM", "si": "si-Sinh-LK", "sid": "sid-Latn-ET", "sk": "sk-Latn-SK", + "skr": "skr-Arab-PK", "sl": "sl-Latn-SI", + "sli": "sli-Latn-PL", + "sly": "sly-Latn-ID", "sm": "sm-Latn-WS", "sma": "sma-Latn-SE", "smj": "smj-Latn-SE", "smn": "smn-Latn-FI", + "smp": "smp-Samr-IL", "sms": "sms-Latn-FI", "sn": "sn-Latn-ZW", "snk": "snk-Latn-ML", "so": "so-Latn-SO", + "sou": "sou-Thai-TH", "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", + "srb": "srb-Sora-IN", "srn": "srn-Latn-SR", "srr": "srr-Latn-SN", "srx": "srx-Deva-IN", "ss": "ss-Latn-ZA", "ssy": "ssy-Latn-ER", "st": "st-Latn-ZA", + "stq": "stq-Latn-DE", "su": "su-Latn-ID", "suk": "suk-Latn-TZ", "sus": "sus-Latn-GN", @@ -2821,9 +3907,11 @@ Globalize.load({ "sw": "sw-Latn-TZ", "swb": "swb-Arab-YT", "swc": "swc-Latn-CD", + "swv": "swv-Deva-IN", "sxn": "sxn-Latn-ID", "syl": "syl-Beng-BD", "syr": "syr-Syrc-IQ", + "szl": "szl-Latn-PL", "ta": "ta-Taml-IN", "taj": "taj-Deva-NP", "tbw": "tbw-Latn-PH", @@ -2847,21 +3935,27 @@ Globalize.load({ "tiv": "tiv-Latn-NG", "tk": "tk-Latn-TM", "tkl": "tkl-Latn-TK", + "tkr": "tkr-Latn-AZ", "tkt": "tkt-Deva-NP", "tl": "tl-Latn-PH", + "tly": "tly-Latn-AZ", "tmh": "tmh-Latn-NE", "tn": "tn-Latn-ZA", "to": "to-Latn-TO", + "tog": "tog-Latn-MW", "tpi": "tpi-Latn-PG", "tr": "tr-Latn-TR", + "tru": "tru-Latn-TR", "trv": "trv-Latn-TW", "ts": "ts-Latn-ZA", + "tsd": "tsd-Grek-GR", "tsf": "tsf-Deva-NP", "tsg": "tsg-Latn-PH", "tsj": "tsj-Tibt-BT", "tt": "tt-Cyrl-RU", "ttj": "ttj-Latn-UG", "tts": "tts-Thai-TH", + "ttt": "ttt-Latn-AZ", "tum": "tum-Latn-MW", "tvl": "tvl-Latn-TV", "twq": "twq-Latn-NE", @@ -2873,6 +3967,7 @@ Globalize.load({ "ug-Cyrl": "ug-Cyrl-KZ", "ug-KZ": "ug-Cyrl-KZ", "ug-MN": "ug-Cyrl-MN", + "uga": "uga-Ugar-SY", "uk": "uk-Cyrl-UA", "uli": "uli-Latn-FM", "umb": "umb-Latn-AO", @@ -2883,7 +3978,7 @@ Globalize.load({ "und-009": "en-Latn-AU", "und-011": "en-Latn-NG", "und-013": "es-Latn-MX", - "und-014": "en-Latn-KE", + "und-014": "sw-Latn-TZ", "und-015": "ar-Arab-EG", "und-017": "sw-Latn-CD", "und-018": "en-Latn-ZA", @@ -2896,7 +3991,7 @@ Globalize.load({ "und-039": "it-Latn-IT", "und-053": "en-Latn-AU", "und-054": "en-Latn-PG", - "und-057": "en-Latn-KI", + "und-057": "en-Latn-GU", "und-061": "sm-Latn-WS", "und-142": "zh-Hans-CN", "und-143": "uz-Latn-UZ", @@ -2919,6 +4014,7 @@ Globalize.load({ "und-AW": "nl-Latn-AW", "und-AX": "sv-Latn-AX", "und-AZ": "az-Latn-AZ", + "und-Aghb": "lez-Aghb-RU", "und-Arab": "ar-Arab-EG", "und-Arab-CC": "ms-Arab-CC", "und-Arab-CN": "ug-Arab-CN", @@ -2930,8 +4026,8 @@ Globalize.load({ "und-Arab-MU": "ur-Arab-MU", "und-Arab-NG": "ha-Arab-NG", "und-Arab-PK": "ur-Arab-PK", + "und-Arab-TH": "mfa-Arab-TH", "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", @@ -2954,11 +4050,12 @@ Globalize.load({ "und-BY": "be-Cyrl-BY", "und-Bali": "ban-Bali-ID", "und-Bamu": "bax-Bamu-CM", + "und-Bass": "bsq-Bass-LR", "und-Batk": "bbc-Batk-ID", "und-Beng": "bn-Beng-BD", "und-Bopo": "zh-Bopo-TW", - "und-Brah": "pra-Brah-IN", - "und-Brai": "und-Brai-FR", + "und-Brah": "pka-Brah-IN", + "und-Brai": "fr-Brai-FR", "und-Bugi": "bug-Bugi-ID", "und-Buhd": "bku-Buhd-PH", "und-CD": "sw-Latn-CD", @@ -3002,8 +4099,10 @@ Globalize.load({ "und-DZ": "ar-Arab-DZ", "und-Deva": "hi-Deva-IN", "und-Deva-BT": "ne-Deva-BT", + "und-Deva-FJ": "hif-Deva-FJ", "und-Deva-MU": "bho-Deva-MU", "und-Deva-PK": "btv-Deva-PK", + "und-Dupl": "fr-Dupl-FR", "und-EA": "es-Latn-EA", "und-EC": "es-Latn-EC", "und-EE": "et-Latn-EE", @@ -3014,9 +4113,9 @@ Globalize.load({ "und-ET": "am-Ethi-ET", "und-EU": "en-Latn-GB", "und-Egyp": "egy-Egyp-EG", + "und-Elba": "sq-Elba-AL", "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", @@ -3034,6 +4133,7 @@ Globalize.load({ "und-Geor": "ka-Geor-GE", "und-Glag": "cu-Glag-BG", "und-Goth": "got-Goth-UA", + "und-Gran": "sa-Gran-IN", "und-Grek": "el-Grek-GR", "und-Grek-TR": "bgx-Grek-TR", "und-Gujr": "gu-Gujr-IN", @@ -3056,6 +4156,7 @@ Globalize.load({ "und-Hebr-UA": "yi-Hebr-UA", "und-Hebr-US": "yi-Hebr-US", "und-Hira": "ja-Hira-JP", + "und-Hmng": "hnj-Hmng-LA", "und-IC": "es-Latn-IC", "und-ID": "id-Latn-ID", "und-IL": "he-Hebr-IL", @@ -3069,6 +4170,7 @@ Globalize.load({ "und-JP": "ja-Jpan-JP", "und-Java": "jv-Java-ID", "und-Jpan": "ja-Jpan-JP", + "und-KE": "sw-Latn-KE", "und-KG": "ky-Cyrl-KG", "und-KH": "km-Khmr-KH", "und-KM": "ar-Arab-KM", @@ -3080,6 +4182,7 @@ Globalize.load({ "und-Kana": "ja-Kana-JP", "und-Khar": "pra-Khar-PK", "und-Khmr": "km-Khmr-KH", + "und-Khoj": "sd-Khoj-IN", "und-Knda": "kn-Knda-IN", "und-Kore": "ko-Kore-KR", "und-Kthi": "bh-Kthi-IN", @@ -3095,21 +4198,17 @@ Globalize.load({ "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-AM": "ku-Latn-AM", "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-MM": "kac-Latn-MM", "und-Latn-MO": "pt-Latn-MO", "und-Latn-MR": "fr-Latn-MR", "und-Latn-RU": "krl-Latn-RU", @@ -3119,6 +4218,7 @@ Globalize.load({ "und-Latn-UA": "pl-Latn-UA", "und-Lepc": "lep-Lepc-IN", "und-Limb": "lif-Limb-IN", + "und-Lina": "lab-Lina-GR", "und-Linb": "grc-Linb-GR", "und-Lisu": "lis-Lisu-CN", "und-Lyci": "xlc-Lyci-TR", @@ -3142,11 +4242,16 @@ Globalize.load({ "und-MX": "es-Latn-MX", "und-MY": "ms-Latn-MY", "und-MZ": "pt-Latn-MZ", + "und-Mahj": "hi-Mahj-IN", "und-Mand": "myz-Mand-IR", + "und-Mani": "xmn-Mani-CN", + "und-Mend": "men-Mend-SL", "und-Merc": "xmr-Merc-SD", "und-Mero": "xmr-Mero-SD", "und-Mlym": "ml-Mlym-IN", + "und-Modi": "mr-Modi-IN", "und-Mong": "mn-Mong-CN", + "und-Mroo": "mru-Mroo-BD", "und-Mtei": "mni-Mtei-IN", "und-Mymr": "my-Mymr-MM", "und-Mymr-IN": "kht-Mymr-IN", @@ -3158,6 +4263,8 @@ Globalize.load({ "und-NL": "nl-Latn-NL", "und-NO": "nb-Latn-NO", "und-NP": "ne-Deva-NP", + "und-Narb": "xna-Narb-SA", + "und-Nbat": "arc-Nbat-JO", "und-Nkoo": "man-Nkoo-GN", "und-OM": "ar-Arab-OM", "und-Ogam": "sga-Ogam-IE", @@ -3178,8 +4285,12 @@ Globalize.load({ "und-PT": "pt-Latn-PT", "und-PW": "pau-Latn-PW", "und-PY": "gn-Latn-PY", + "und-Palm": "arc-Palm-SY", + "und-Pauc": "ctd-Pauc-MM", + "und-Perm": "kv-Perm-RU", "und-Phag": "lzh-Phag-CN", "und-Phli": "pal-Phli-IR", + "und-Phlp": "pal-Phlp-CN", "und-Phnx": "phn-Phnx-LB", "und-Plrd": "hmd-Plrd-CN", "und-Prti": "xpr-Prti-IR", @@ -3211,6 +4322,8 @@ Globalize.load({ "und-Saur": "saz-Saur-IN", "und-Shaw": "en-Shaw-GB", "und-Shrd": "sa-Shrd-IN", + "und-Sidd": "sa-Sidd-IN", + "und-Sind": "sd-Sind-IN", "und-Sinh": "si-Sinh-LK", "und-Sora": "srb-Sora-IN", "und-Sund": "su-Sund-ID", @@ -3245,24 +4358,27 @@ Globalize.load({ "und-Thai-KH": "kdt-Thai-KH", "und-Thai-LA": "kdt-Thai-LA", "und-Tibt": "bo-Tibt-CN", + "und-Tirh": "mai-Tirh-IN", "und-UA": "uk-Cyrl-UA", "und-UG": "sw-Latn-UG", "und-UY": "es-Latn-UY", "und-UZ": "uz-Latn-UZ", "und-Ugar": "uga-Ugar-SY", - "und-VA": "la-Latn-VA", + "und-VA": "it-Latn-VA", "und-VE": "es-Latn-VE", "und-VN": "vi-Latn-VN", "und-VU": "bi-Latn-VU", "und-Vaii": "vai-Vaii-LR", "und-WF": "fr-Latn-WF", "und-WS": "sm-Latn-WS", + "und-Wara": "hoc-Wara-IN", "und-XK": "sq-Latn-XK", "und-Xpeo": "peo-Xpeo-IR", "und-Xsux": "akk-Xsux-IQ", "und-YE": "ar-Arab-YE", "und-YT": "fr-Latn-YT", "und-Yiii": "ii-Yiii-CN", + "und-ZW": "sn-Latn-ZW", "unr": "unr-Beng-IN", "unr-Deva": "unr-Deva-NP", "unr-NP": "unr-Deva-NP", @@ -3274,32 +4390,58 @@ Globalize.load({ "uz-CN": "uz-Cyrl-CN", "vai": "vai-Vaii-LR", "ve": "ve-Latn-ZA", + "vec": "vec-Latn-IT", + "vep": "vep-Latn-RU", "vi": "vi-Latn-VN", "vic": "vic-Latn-SX", + "vls": "vls-Latn-BE", + "vmf": "vmf-Latn-DE", + "vmw": "vmw-Latn-MZ", "vo": "vo-Latn-001", + "vot": "vot-Latn-RU", + "vro": "vro-Latn-EE", "vun": "vun-Latn-TZ", "wa": "wa-Latn-BE", "wae": "wae-Latn-CH", "wal": "wal-Ethi-ET", "war": "war-Latn-PH", + "wbp": "wbp-Latn-AU", + "wbq": "wbq-Telu-IN", + "wbr": "wbr-Deva-IN", + "wls": "wls-Latn-WF", "wo": "wo-Latn-SN", + "wtm": "wtm-Deva-IN", + "wuu": "wuu-Hans-CN", "xav": "xav-Latn-BR", + "xcr": "xcr-Cari-TR", "xh": "xh-Latn-ZA", + "xlc": "xlc-Lyci-TR", + "xld": "xld-Lydi-TR", + "xmf": "xmf-Geor-GE", + "xmn": "xmn-Mani-CN", + "xmr": "xmr-Merc-SD", + "xna": "xna-Narb-SA", + "xnr": "xnr-Deva-IN", "xog": "xog-Latn-UG", + "xpr": "xpr-Prti-IR", + "xsa": "xsa-Sarb-YE", "xsr": "xsr-Deva-NP", "yao": "yao-Latn-MZ", "yap": "yap-Latn-FM", "yav": "yav-Latn-CM", "ybb": "ybb-Latn-CM", - "yi": "yi-Hebr-UA", + "yi": "yi-Hebr-001", "yo": "yo-Latn-NG", + "yrl": "yrl-Latn-BR", "yua": "yua-Latn-MX", "za": "za-Latn-CN", + "zdj": "zdj-Arab-KM", "zea": "zea-Latn-NL", "zgh": "zgh-Tfng-MA", "zh": "zh-Hans-CN", "zh-AU": "zh-Hant-AU", "zh-BN": "zh-Hant-BN", + "zh-Bopo": "zh-Bopo-TW", "zh-GB": "zh-Hant-GB", "zh-GF": "zh-Hant-GF", "zh-HK": "zh-Hant-HK", @@ -3317,7 +4459,7 @@ Globalize.load({ "zh-VN": "zh-Hant-VN", "zmi": "zmi-Latn-MY", "zu": "zu-Latn-ZA", - "zza": "zza-Arab-TR" + "zza": "zza-Latn-TR" } } }); @@ -3325,11 +4467,11 @@ Globalize.load({ Globalize.load({ "supplemental": { "version": { - "_cldrVersion": "25", - "_number": "$Revision: 91 $" + "_unicodeVersion": "7.0.0", + "_number": "$Revision: 11318 $" }, "generation": { - "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + "_date": "$Date: 2015-02-25 23:47:56 -0600 (Wed, 25 Feb 2015) $" }, "timeData": { "001": { @@ -3416,6 +4558,10 @@ Globalize.load({ "_allowed": "H h", "_preferred": "h" }, + "BQ": { + "_allowed": "H", + "_preferred": "H" + }, "BR": { "_allowed": "H", "_preferred": "H" @@ -3440,6 +4586,10 @@ Globalize.load({ "_allowed": "H", "_preferred": "H" }, + "CG": { + "_allowed": "H", + "_preferred": "H" + }, "CI": { "_allowed": "H", "_preferred": "H" @@ -3939,11 +5089,11 @@ Globalize.load({ Globalize.load({ "supplemental": { "version": { - "_cldrVersion": "25", - "_number": "$Revision: 91 $" + "_unicodeVersion": "7.0.0", + "_number": "$Revision: 11318 $" }, "generation": { - "_date": "$Date: 2014-03-13 22:27:12 -0500 (Thu, 13 Mar 2014) $" + "_date": "$Date: 2015-02-25 23:47:56 -0600 (Wed, 25 Feb 2015) $" }, "weekData": { "minDays": { @@ -4157,13 +5307,16 @@ Globalize.load({ "001": "sat", "AE": "fri", "BH": "fri", + "DZ": "fri", "EG": "fri", "IL": "fri", "IQ": "fri", + "IR": "fri", "JO": "fri", "KW": "fri", "LY": "fri", "MA": "fri", + "OM": "fri", "QA": "fri", "SA": "fri", "SD": "fri", @@ -4171,15 +5324,13 @@ Globalize.load({ "TN": "fri", "YE": "fri", "AF": "thu", - "DZ": "thu", - "IR": "thu", - "OM": "thu", "IN": "sun" }, "weekendEnd": { "001": "sun", "AE": "sat", "BH": "sat", + "DZ": "sat", "EG": "sat", "IL": "sat", "IQ": "sat", @@ -4187,6 +5338,7 @@ Globalize.load({ "KW": "sat", "LY": "sat", "MA": "sat", + "OM": "sat", "QA": "sat", "SA": "sat", "SD": "sat", @@ -4194,9 +5346,7 @@ Globalize.load({ "TN": "sat", "YE": "sat", "AF": "fri", - "DZ": "fri", - "IR": "fri", - "OM": "fri" + "IR": "fri" } } } diff --git a/ui/calendar.js b/ui/calendar.js index 966e4c99271..6bf9c82ab63 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -26,7 +26,8 @@ "date", "./button", "./core", - "./button" ], factory ); + "./button" + ], factory ); } else { // Browser globals @@ -178,8 +179,8 @@ return $.widget( "ui.calendar", { _setLocale: function( locale ) { var globalize = new Globalize( locale ), - weekdayShortFormatter = globalize.dateFormatter({ pattern: "EEEEEE" }), - weekdayNarrowFormatter = globalize.dateFormatter({ pattern: "EEEEE" }); + weekdayShortFormatter = globalize.dateFormatter({ raw: "EEEEEE" }), + weekdayNarrowFormatter = globalize.dateFormatter({ raw: "EEEEE" }); this._format = globalize.dateFormatter({ date: "short" }); this._parse = globalize.dateParser({ date: "short" }); @@ -192,9 +193,9 @@ return $.widget( "ui.calendar", { return shortWeekday.length > 3 ? weekdayNarrowFormatter( date ) : shortWeekday; }, - formatWeekdayFull: globalize.dateFormatter({ pattern: "EEEE" }), - formatMonth: globalize.dateFormatter({ pattern: "MMMM" }), - formatWeekOfYear: globalize.dateFormatter({ pattern: "w" }), + formatWeekdayFull: globalize.dateFormatter({ raw: "EEEE" }), + formatMonth: globalize.dateFormatter({ raw: "MMMM" }), + formatWeekOfYear: globalize.dateFormatter({ raw: "w" }), parse: this._parse }; }, From 6db02da67c4150f90e3f5e69a87d885b829d93a9 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 28 Jul 2015 00:42:32 +0200 Subject: [PATCH 088/179] Calendar: Re-introduce formatDate option --- tests/unit/calendar/common.js | 1 + ui/calendar.js | 28 +++++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/tests/unit/calendar/common.js b/tests/unit/calendar/common.js index 3bb3b4e589d..ffbb4c5a314 100644 --- a/tests/unit/calendar/common.js +++ b/tests/unit/calendar/common.js @@ -9,6 +9,7 @@ common.testWidget( "calendar", { buttons: [], classes: {}, disabled: false, + dateFormat: { date: "short" }, eachDay: $.noop, labels: { "datePickerRole": "date picker", diff --git a/ui/calendar.js b/ui/calendar.js index 6bf9c82ab63..02bdc595057 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -39,6 +39,7 @@ return $.widget( "ui.calendar", { version: "@VERSION", options: { buttons: [], + dateFormat: { date: "short" }, eachDay: $.noop, labels: { "datePickerRole": "date picker", @@ -58,7 +59,9 @@ return $.widget( "ui.calendar", { }, refreshRelatedOptions: { + dateFormat: true, eachDay: true, + locale: true, max: true, min: true, showWeek: true, @@ -70,7 +73,7 @@ return $.widget( "ui.calendar", { this.labels = this.options.labels; this.buttonClickContext = this.element[ 0 ]; - this._setLocale( this.options.locale ); + this._setLocale( this.options.locale, this.options.dateFormat ); this.date = new $.ui.calendarDate( this.options.value, this._calendarDateOptions ); this.viewDate = this.date.clone(); @@ -177,13 +180,13 @@ return $.widget( "ui.calendar", { ).addClass( "ui-state-focus" ); }, - _setLocale: function( locale ) { + _setLocale: function( locale, dateFormat ) { var globalize = new Globalize( locale ), weekdayShortFormatter = globalize.dateFormatter({ raw: "EEEEEE" }), weekdayNarrowFormatter = globalize.dateFormatter({ raw: "EEEEE" }); - this._format = globalize.dateFormatter({ date: "short" }); - this._parse = globalize.dateParser({ date: "short" }); + this._format = globalize.dateFormatter( dateFormat ); + this._parse = globalize.dateParser( dateFormat ); this._calendarDateOptions = { firstDay: globalize.cldr.supplemental.weekData.firstDay(), formatWeekdayShort: function( date ) { @@ -590,7 +593,8 @@ return $.widget( "ui.calendar", { _setOptions: function( options ) { var that = this, - refresh = false; + refresh = false, + dateAttributes = false; $.each( options, function( key, value ) { that._setOption( key, value ); @@ -598,8 +602,16 @@ return $.widget( "ui.calendar", { if ( key in that.refreshRelatedOptions ) { refresh = true; } + if ( key === "dateFormat" || key === "locale" ) { + dateAttributes = true; + } } ); + if ( dateAttributes ) { + this._setLocale( this.options.locale, this.options.dateFormat ); + this.date.setAttributes( this._calendarDateOptions ); + this.viewDate.setAttributes( this._calendarDateOptions ); + } if ( refresh ) { this._refresh(); } @@ -636,12 +648,6 @@ return $.widget( "ui.calendar", { if ( key === "eachDay" ) { this.viewDate.eachDay = value; } - - if ( key === "locale" ) { - this._setLocale( value ); - this.date.setAttributes( this._calendarDateOptions ); - this.refresh(); - } } } ); From ce704462b2340a774c142c5aff93200103e92b09 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 28 Jul 2015 22:37:47 +0200 Subject: [PATCH 089/179] Datepicker: Update to Globalize 1.0.0 --- demos/datepicker/animation.html | 1 + demos/datepicker/date-formats.html | 1 + demos/datepicker/default.html | 1 + demos/datepicker/icon-trigger.html | 1 + demos/datepicker/localization.html | 1 + ui/datepicker.js | 6 +++--- 6 files changed, 8 insertions(+), 3 deletions(-) diff --git a/demos/datepicker/animation.html b/demos/datepicker/animation.html index 5f5fc6825aa..f162231ba26 100644 --- a/demos/datepicker/animation.html +++ b/demos/datepicker/animation.html @@ -9,6 +9,7 @@ + diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index a98c99e7eff..6c713a33964 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -9,6 +9,7 @@ + diff --git a/demos/datepicker/default.html b/demos/datepicker/default.html index f57cd41bc61..b4650ad1e44 100644 --- a/demos/datepicker/default.html +++ b/demos/datepicker/default.html @@ -9,6 +9,7 @@ + diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index 933b38b9d66..2478d29d85f 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -9,6 +9,7 @@ + diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index 71070c168cf..7d73a41540c 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -9,6 +9,7 @@ + diff --git a/ui/datepicker.js b/ui/datepicker.js index c1cced4ed7a..ba6fd75279b 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -79,11 +79,11 @@ var widget = $.widget( "ui.datepicker", { options = {}; if ( max !== undefined ) { - options.max = Globalize.parseDate( max, { pattern: "yyyy-MM-dd" } ); + options.max = Globalize.parseDate( max, { raw: "yyyy-MM-dd" } ); } if ( min !== undefined ) { - options.min = Globalize.parseDate( min, { pattern: "yyyy-MM-dd" } ); + options.min = Globalize.parseDate( min, { raw: "yyyy-MM-dd" } ); } return options; @@ -285,7 +285,7 @@ var widget = $.widget( "ui.datepicker", { this._format = globalize.dateFormatter({ date: "short" }); this._parse = globalize.dateParser({ date: "short" }); - this._parseYMD = globalize.dateParser({ pattern: "yyyy-MM-dd" }); + this._parseYMD = globalize.dateParser({ raw: "yyyy-MM-dd" }); }, _buildPosition: function() { From 8bd40304433004dd955fcbf925ed4f24502bfeb5 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 28 Jul 2015 23:10:16 +0200 Subject: [PATCH 090/179] Datepicker: Re-introduce formatDate option, simplify Globalize usage --- tests/unit/datepicker/common.js | 1 + tests/unit/datepicker/options.js | 7 ++++++- ui/datepicker.js | 32 +++++++++++--------------------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/tests/unit/datepicker/common.js b/tests/unit/datepicker/common.js index 84b97fa3a3c..6389adaec08 100644 --- a/tests/unit/datepicker/common.js +++ b/tests/unit/datepicker/common.js @@ -10,6 +10,7 @@ common.testWidget( "datepicker", { buttons: [], classes: {}, disabled: false, + dateFormat: { date: "short" }, eachDay: $.noop, labels: { "datePickerRole": "date picker", diff --git a/tests/unit/datepicker/options.js b/tests/unit/datepicker/options.js index 32979eac8f7..6bad27b6a4f 100644 --- a/tests/unit/datepicker/options.js +++ b/tests/unit/datepicker/options.js @@ -45,13 +45,14 @@ test( "appendTo", function() { }); test( "Pass-through options", function() { - expect( 9 ); + expect( 11 ); var options = { buttons: { "Test": $.noop }, dateFormat: { date: "full" }, disabled: true, eachDay: function( day ) { day; }, + locale: "de", max: new Date( 2000, 0, 1 ), min: new Date( 2000, 0, 2 ), numberOfMonths: 3, @@ -72,6 +73,10 @@ test( "Pass-through options", function() { if ( key === "dateFormat" ) { equal( input.val(), "Wednesday, January 1, 2014", "option " + key + ": updated format" ); } + + if ( key === "locale" ) { + equal( input.val(), "Mittwoch, 1. Januar 2014", "option " + key + ": updated locale" ); + } }); }); diff --git a/ui/datepicker.js b/ui/datepicker.js index ba6fd75279b..2056d9443b5 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -51,19 +51,17 @@ var widget = $.widget( "ui.datepicker", { select: null }, - calendarOptions: [ "buttons", "disabled", "eachDay", "labels", "locale", - "max", "min", "numberOfMonths", "showWeek" ], + calendarOptions: [ "buttons", "disabled", "dateFormat", "eachDay", "labels", + "locale", "max", "min", "numberOfMonths", "showWeek" ], _create: function() { this.suppressExpandOnFocus = false; - this._setLocale( this.options.locale ); - if ( $.type( this.options.max ) === "string" ) { - this.options.max = this._parseYMD( this.options.max ); + this.options.max = Globalize.parseDate( this.options.max, { raw: "yyyy-MM-dd" } ); } if ( $.type( this.options.min ) === "string" ) { - this.options.min = this._parseYMD( this.options.min ); + this.options.min = Globalize.parseDate( this.options.min, { raw: "yyyy-MM-dd" } ); } this._createCalendar(); @@ -90,7 +88,8 @@ var widget = $.widget( "ui.datepicker", { }, _createCalendar: function() { - var that = this; + var that = this, + globalize = new Globalize( this.options.locale ); this.calendar = $( "
      " ) .addClass( "ui-front ui-datepicker" ) @@ -99,7 +98,7 @@ var widget = $.widget( "ui.datepicker", { // Initialize calendar widget this.calendarInstance = this.calendar .calendar( $.extend( {}, this.options, { - value: this._getParsedValue(), + value: globalize.dateParser( this.options.dateFormat )( this.element.val() ), select: function( event ) { that.element.val( that.calendarInstance.value() ); that.close(); @@ -280,21 +279,13 @@ var widget = $.widget( "ui.datepicker", { }); }, - _setLocale: function( locale ) { - var globalize = new Globalize( locale ); - - this._format = globalize.dateFormatter({ date: "short" }); - this._parse = globalize.dateParser({ date: "short" }); - this._parseYMD = globalize.dateParser({ raw: "yyyy-MM-dd" }); - }, - _buildPosition: function() { return $.extend( { of: this.element }, this.options.position ); }, value: function( value ) { if ( arguments.length ) { - this.valueAsDate( this._parse( value ) ); + this.valueAsDate( this.calendarInstance._parse( value ) ); } else { return this._getParsedValue() ? this.element.val() : null; } @@ -304,7 +295,7 @@ var widget = $.widget( "ui.datepicker", { if ( arguments.length ) { if ( this.calendarInstance._isValid( value ) ) { this.calendarInstance.valueAsDate( value ); - this.element.val( this._format( value ) ); + this.element.val( this.calendarInstance._format( value ) ); } } else { return this._getParsedValue(); @@ -326,7 +317,7 @@ var widget = $.widget( "ui.datepicker", { }, _getParsedValue: function() { - return this._parse( this.element.val() ); + return this.calendarInstance._parse( this.element.val() ); }, _setOption: function( key, value ) { @@ -340,8 +331,7 @@ var widget = $.widget( "ui.datepicker", { this.calendar.appendTo( this._appendTo() ); } - if ( key === "locale" ) { - this._setLocale( value ); + if ( key === "locale" || key === "dateFormat" ) { this.element.val( this.calendarInstance.value() ); } From a307992375c1b67a930d6c9c5b497828ed6cad8f Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 25 Aug 2015 17:47:13 +0200 Subject: [PATCH 091/179] Calendar: Fix weekday name jumping when using numberOfMonths option Fixes weekday name jumping when clicking the last day of the last grid. Includes some basic tests for multiple month demo and this specific issue. --- tests/unit/calendar/options.js | 30 +++++++++++++++++++++++++++++- ui/widgets/calendar.js | 2 +- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js index 5af5e479e57..93f19958015 100644 --- a/tests/unit/calendar/options.js +++ b/tests/unit/calendar/options.js @@ -232,7 +232,35 @@ test( "min / max", function() { element .calendar( "option", { min: minDate, max: maxDate } ) .calendar( "value", "1/4/09" ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > max" );}); + testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > max" ); +}); + +test( "numberOfMonths", function() { + expect( 5 ); + var date = new Date( 2015, 8 - 1, 1 ), + input = $( "#calendar" ).calendar({ + numberOfMonths: 3, + value: date + }), + container = input.calendar( "widget" ); + + equal( container.find( ".ui-calendar-group" ).length, 3, "3 calendar grids" ); + equal( + container.find( "tbody:first td[id]:first" ).attr( "id" ), + "calendar-2015-7-1", + "Correct id set for first day of first grid" + ); + equal( + container.find( "tbody:last td[id]:last" ).attr( "id" ), + "calendar-2015-9-31", + "Correct id set for last day of third grid" + ); + + // Test for jumping in weekday rendering after click on last day of last grid + equal( container.find( "thead:last th:last" ).text(), "Sa", "Before click: Last day is saturday" ); + container.find( "tbody:last td[id]:last button" ).trigger( "mousedown" ); + equal( container.find( "thead:last th:last" ).text(), "Sa", "After click: Last day is saturday" ); +}); /* // TODO: Move this to $.date, Globalize or calendar widget diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index 947d79d8d71..a9a18994733 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -329,7 +329,7 @@ return $.widget( "ui.calendar", { var cells = "", i = 0, weekDayLength = this.viewDate.weekdays().length, - weekdays = this.date.weekdays(); + weekdays = this.viewDate.weekdays(); if ( this.options.showWeek ) { cells += "" + this._getTranslation( "weekHeader" ) + ""; From 38101a478b3ee9b91d02fd5c338edf0df9221a4a Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 25 Aug 2015 18:28:18 +0200 Subject: [PATCH 092/179] Datepicker: Fix icon trigger demo Support keyboard control. Fix close on second click. Add removal notice. --- demos/datepicker/icon-trigger.html | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index 2ab3c2e236e..ed79840ab88 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -15,13 +15,18 @@ open: function() { allowOpen = false; } - }); + } ), + widget = datepicker.datepicker( "widget" ); - $( "Open Datepicker") + $( "") + .append( "Open Datepicker" ) .insertAfter( datepicker ) - .on( "click", function() { + .on( "click", function( event ) { allowOpen = true; - datepicker.focus(); + if ( widget.is( ":hidden" ) ) { + datepicker.focus(); + } + event.preventDefault(); }); @@ -30,7 +35,7 @@

      Date:

      -

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

      +

      Click the icon next to the input field to show the datepicker. This demo will be removed soon since its promoting bad practice. Please see our migration guide.

      From 09be7b328ed6092575ee224230c85ea6f7018260 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 25 Aug 2015 22:40:54 +0200 Subject: [PATCH 093/179] Calendar: Fix view when moving between multiple months with keyboard Make sure numberOfMonths is taken into account while navigating with keyboard when rendering multiple calendar grids (numberOfMonths > 1). --- tests/unit/calendar/options.js | 12 ++++++++++-- ui/widgets/calendar.js | 9 ++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js index 93f19958015..01522ebee2b 100644 --- a/tests/unit/calendar/options.js +++ b/tests/unit/calendar/options.js @@ -257,9 +257,17 @@ test( "numberOfMonths", function() { ); // Test for jumping in weekday rendering after click on last day of last grid - equal( container.find( "thead:last th:last" ).text(), "Sa", "Before click: Last day is saturday" ); container.find( "tbody:last td[id]:last button" ).trigger( "mousedown" ); - equal( container.find( "thead:last th:last" ).text(), "Sa", "After click: Last day is saturday" ); + equal( container.find( "thead:last th:last" ).text(), "Sa", + "After mousedown last month: Last day is Saturday" + ); + + // Test if using cursor down to go to the next month advances three month + container.find( "tbody:first td[id]:first button" ).trigger( "mousedown" ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); + equal( container.find( ".ui-calendar-month:first" ).text(), "May", + "After move to previous month: First month is May" + ); }); /* diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index a9a18994733..5952a184f27 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -150,7 +150,14 @@ return $.widget( "ui.calendar", { } if ( this._needsRefresh() ) { - this._refresh(); + if ( this.options.numberOfMonths > 1 && this.date.year() === this.viewDate.year() ) { + this.viewDate.adjust( "M", this.options.numberOfMonths * + ( this.date.month() > this.viewDate.month() ? 1 : -1 ) + ); + this.refresh(); + } else { + this._refresh(); + } this.grid.focus(); } From c5b2d8552c19025bc5c6629898b1ab7521316cc0 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 25 Aug 2015 23:11:21 +0200 Subject: [PATCH 094/179] Calendar: Make use of escapeSelector method --- ui/widgets/calendar.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index 5952a184f27..709622e8a69 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -29,7 +29,8 @@ "../version", "../keycode", "../unique-id", - "../tabbable" + "../tabbable", + "../escape-selector" ], factory ); } else { @@ -170,7 +171,7 @@ return $.widget( "ui.calendar", { // Check if the needed day is already present in our grid due // to eachDay option changes (eg. other-months demo) return !this.grid.find( - this._sanitizeSelector( "#" + this._getDayId( this.date ) ) + "#" + $.ui.escapeSelector( this._getDayId( this.date ) ) ).length; } @@ -186,7 +187,7 @@ return $.widget( "ui.calendar", { .removeClass( "ui-state-focus" ); this.activeDescendant = this.grid.find( - this._sanitizeSelector( "#" + id ) + " > button" + "#" + $.ui.escapeSelector( id ) + " > button" ).addClass( "ui-state-focus" ); }, @@ -545,10 +546,6 @@ return $.widget( "ui.calendar", { return $( "
      " ).text( this.labels[ key ] ).html(); }, - _sanitizeSelector: function( hash ) { - return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; - }, - _setHiddenPicker: function() { this.element.attr( { "aria-hidden": "true", From 483aecb7cdc79b424dec4acdf159aa1a6ab88ce3 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 25 Aug 2015 23:53:03 +0200 Subject: [PATCH 095/179] Calendar tests: Fix and clean-up $.ui.calendarDate unit tests --- tests/unit/date/core.js | 56 +++++++++++++++------------------------ tests/unit/date/date.html | 5 +--- tests/unit/date/helper.js | 30 +++++++++++++++++++++ 3 files changed, 53 insertions(+), 38 deletions(-) create mode 100644 tests/unit/date/helper.js diff --git a/tests/unit/date/core.js b/tests/unit/date/core.js index d5895a91df3..91d368fcb95 100644 --- a/tests/unit/date/core.js +++ b/tests/unit/date/core.js @@ -1,19 +1,21 @@ define( [ "jquery", - "globalize", + "./helper", "date" -], function( $, Globalize ) { +], function( $, testHelper ) { module( "date: core" ); +var attributes = testHelper.getAttributes( "en" ); + test( "Instantiation", function() { expect( 2 ); - ok( new $.date() instanceof $.date, "constructor function" ); - ok( $.date() instanceof $.date, "instantiation without new" ); + ok( new $.ui.calendarDate( null, attributes ) instanceof $.ui.calendarDate, "constructor function" ); + ok( $.ui.calendarDate( null, attributes ) instanceof $.ui.calendarDate, "instantiation without new" ); }); test( "Check Sets and Gets", 6, function() { - var date = $.date(); + var date = $.ui.calendarDate( null, attributes ); 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" ); @@ -23,7 +25,7 @@ test( "Check Sets and Gets", 6, function() { }); test( "Date Adjustments - Normal Use Cases", 10, function() { - var date = $.date(); + var date = $.ui.calendarDate( null, attributes ); // Use October 15, 2012 date.setFullDate( 2012, 9, 15 ); @@ -48,7 +50,7 @@ test( "Date Adjustments - Normal Use Cases", 10, function() { }); test( "Date Adjustments - Month Overflow Edge Cases", 2, function() { - var date = $.date(); + var date = $.ui.calendarDate( null, attributes ); // Use May 31 2012 date.setFullDate( 2012, 4, 31 ); @@ -59,7 +61,7 @@ test( "Date Adjustments - Month Overflow Edge Cases", 2, function() { }); test( "Date Adjustments - Leap Year Edge Cases", 1, function() { - var date = $.date(); + var date = $.ui.calendarDate( null, attributes ); // Use February 29 2012 a Leap year date.setFullDate( 2012, 1, 29 ); @@ -68,7 +70,7 @@ test( "Date Adjustments - Leap Year Edge Cases", 1, function() { }); test( "List days of Week", 2, function() { - var date = $.date(), + var date = $.ui.calendarDate( null, attributes ), offset0 = [ { "fullname": "Sunday", "shortname": "Su" }, { "fullname": "Monday", "shortname": "Mo" }, @@ -89,15 +91,12 @@ test( "List days of Week", 2, function() { ]; deepEqual( date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)" ); - Globalize.locale( "de" ); + date = $.ui.calendarDate( null, testHelper.getAttributes( "de" ) ); 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() { - var date = $.date(); + var date = $.ui.calendarDate( null, attributes ); 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" ); @@ -109,7 +108,7 @@ test( "Leap Year Check", 8, function() { }); test( "Days in Month", 3, function() { - var date = $.date(); + var date = $.ui.calendarDate( null, attributes ); 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" ); @@ -117,23 +116,22 @@ test( "Days in Month", 3, function() { }); test( "Month Name", 2, function() { - var date = $.date(); + var date = $.ui.calendarDate( null, attributes ); equal( date.setMonth( 3 ).monthName(), "April", "Month name return April (English)" ); - Globalize.locale( "de" ); + date = $.ui.calendarDate( null, testHelper.getAttributes( "de" ) ); equal( date.setMonth( 2 ).monthName(), "März", "Month name return March (German)" ); - Globalize.locale( "en" ); }); test( "Clone", 2, function() { - var date = $.date(), + var date = $.ui.calendarDate( null, attributes ), 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(); + // TODO needs work + var date = $.ui.calendarDate( null, attributes ); date.eachDay = function( day ) { if ( day.lead && day.date > 20 ) { day.selectable = false; @@ -158,7 +156,7 @@ test( "Days", 1, function() { }); test( "Months", 5, function(){ - var date = $.date(), + var date = $.ui.calendarDate( null, attributes ), firstMonth = date.months( 1 )[ 0 ], lastMonth = date.months( 1 )[ 1 ]; @@ -171,7 +169,7 @@ test( "Months", 5, function(){ }); test( "Equal", 4, function() { - var date = $.date(); + var date = $.ui.calendarDate( null, attributes ); 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" ); @@ -180,18 +178,8 @@ test( "Equal", 4, function() { }); test( "Date", 1, function() { - var date = $.date(); + var date = $.ui.calendarDate( null, attributes ); ok( date.date() instanceof Date, "Date returned" ); }); -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" ); -}); - } ); diff --git a/tests/unit/date/date.html b/tests/unit/date/date.html index 1d9ee6c1fe1..3c11f519b83 100644 --- a/tests/unit/date/date.html +++ b/tests/unit/date/date.html @@ -11,9 +11,6 @@
      -
      -
      -

      -
      +
      diff --git a/tests/unit/date/helper.js b/tests/unit/date/helper.js new file mode 100644 index 00000000000..01755c53adc --- /dev/null +++ b/tests/unit/date/helper.js @@ -0,0 +1,30 @@ +define( [ + "jquery", + "globalize", + "lib/helper", + "globalize/date" +], function( $, Globalize, helper ) { + +return $.extend( helper, { + getAttributes: function( locale ) { + var globalize = new Globalize( locale ), + weekdayShortFormatter = globalize.dateFormatter({ raw: "EEEEEE" }), + weekdayNarrowFormatter = globalize.dateFormatter({ raw: "EEEEE" } ); + + return { + firstDay: globalize.cldr.supplemental.weekData.firstDay(), + formatWeekdayShort: function( date ) { + + // Return the short weekday if its length is < 3. Otherwise, its narrow form. + var shortWeekday = weekdayShortFormatter( date ); + + return shortWeekday.length > 3 ? weekdayNarrowFormatter( date ) : shortWeekday; + }, + formatWeekdayFull: globalize.dateFormatter({ raw: "EEEE" }), + formatMonth: globalize.dateFormatter({ raw: "MMMM" }), + formatWeekOfYear: globalize.dateFormatter({ raw: "w" }) + }; + } +} ); + +} ); From 462f92f727b81a663e8c2b1999f3b42a554bcfa9 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 25 Aug 2015 23:54:55 +0200 Subject: [PATCH 096/179] Calendar tests: Fix wrong data-widget attribute --- tests/unit/calendar/calendar.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html index 0d28b635151..1cd3e805125 100644 --- a/tests/unit/calendar/calendar.html +++ b/tests/unit/calendar/calendar.html @@ -6,7 +6,7 @@ - + From 9bc5fd23870caac4a722b7e5e9fff889ea6340c1 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 25 Aug 2015 23:59:36 +0200 Subject: [PATCH 097/179] Calendar: Some code style and CGL fixes --- external/date.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/external/date.js b/external/date.js index 4cb29ef27d5..72986e29c3e 100644 --- a/external/date.js +++ b/external/date.js @@ -54,8 +54,8 @@ $.extend( _Date.prototype, { this.firstDay = weekdaysRev[ this.attributes.firstDay ]; }, - //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. + // 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; @@ -92,7 +92,7 @@ $.extend( _Date.prototype, { month = date.getMonth(); // Check if Leap, and February and day is 29th - if ( this.isLeapYear( year ) && month == 1 && day == 29 ) { + if ( this.isLeapYear( year ) && month === 1 && day === 29 ) { // set day to last day of February day = this.daysInMonth( year, month ); @@ -109,12 +109,12 @@ $.extend( _Date.prototype, { 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(); + 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" ) { + if ( period !== "D" ) { day = Math.max( 1, Math.min( day, this.daysInMonth( year, month ) ) ); } this.dateObject = new Date( year, month, day, date.getHours(), @@ -147,7 +147,7 @@ $.extend( _Date.prototype, { isLeapYear: function( year ) { year = year || this.dateObject.getFullYear(); - return new Date( year, 1, 29 ).getMonth() == 1; + return new Date( year, 1, 29 ).getMonth() === 1; }, weekdays: function() { @@ -228,7 +228,7 @@ $.extend( _Date.prototype, { equal: function( other ) { var format = function( date ) { return "" + date.getFullYear() + date.getMonth() + date.getDate(); - } + }; return format( this.dateObject ) === format( other ); }, From 31908a1465d907769dd94a6d0c19d6162568741d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 26 Aug 2015 11:45:15 +0200 Subject: [PATCH 098/179] Calendar: Make header prev / next buttons min / max option aware * Disable / enable header buttons according to min / max * Add tests for header button states * Improve header button rendering and refreshing * Improve header button label escaping on create * Create button pane for multiple pickers (bugfix) --- tests/unit/calendar/options.js | 27 +++++++++++++- ui/widgets/calendar.js | 67 ++++++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js index 01522ebee2b..202b497d69a 100644 --- a/tests/unit/calendar/options.js +++ b/tests/unit/calendar/options.js @@ -191,10 +191,13 @@ test( "showWeek", function() { }); test( "min / max", function() { - expect( 7 ); + expect( 14 ); // With existing date var element = $( "#calendar" ).calendar(), + container = element.calendar( "widget" ), + prevButton = container.find( ".ui-calendar-prev" ), + nextButton = container.find( ".ui-calendar-next" ), minDate = new Date( 2008, 2 - 1, 29 ), maxDate = new Date( 2008, 12 - 1, 7 ); @@ -233,6 +236,28 @@ test( "min / max", function() { .calendar( "option", { min: minDate, max: maxDate } ) .calendar( "value", "1/4/09" ); testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > max" ); + + element + .calendar( "option", { min: minDate, max: maxDate } ) + .calendar( "value", "3/4/08" ); + ok( !prevButton.hasClass( "ui-state-disabled" ), "Prev button enabled" ); + prevButton.simulate( "click" ); + ok( prevButton.hasClass( "ui-state-disabled" ), "Prev button disabled" ); + + element.calendar( "value", "11/4/08" ); + ok( !nextButton.hasClass( "ui-state-disabled" ), "Next button enabled" ); + nextButton.simulate( "click" ); + ok( nextButton.hasClass( "ui-state-disabled" ), "Next button disabled" ); + + element + .calendar( "option", { max: null } ) + .calendar( "value", "1/4/15" ) + .calendar( "option", { max: maxDate } ); + ok( nextButton.hasClass( "ui-state-disabled" ), "Other year: Next button disabled" ); + nextButton.simulate( "click" ); + ok( nextButton.hasClass( "ui-state-disabled" ), "Other year: Next button disabled after click" ); + nextButton.simulate( "click" ); + ok( !nextButton.hasClass( "ui-state-disabled" ), "Other year: Next button enabled after click" ); }); test( "numberOfMonths", function() { diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index 709622e8a69..e274e558cb7 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -233,6 +233,10 @@ return $.widget( "ui.calendar", { } ) .html( pickerHtml ); + this.prevButton = this.element.find( ".ui-calendar-prev" ); + this.nextButton = this.element.find( ".ui-calendar-next" ); + this._refreshHeaderButtons(); + this._createButtonPane(); this.grid = this.element.find( ".ui-calendar-calendar" ); @@ -283,24 +287,14 @@ return $.widget( "ui.calendar", { }, _buildPreviousLink: function() { - var prevText = this._getTranslation( "prevText" ); - - return ""; }, _buildNextLink: function() { - var nextText = this._getTranslation( "nextText" ); - - return ""; }, @@ -517,14 +511,49 @@ return $.widget( "ui.calendar", { this.grid = $( this._buildGrid() ); this.element.find( ".ui-calendar-title" ).html( this._buildTitle() ); this.element.find( ".ui-calendar-calendar" ).replaceWith( this.grid ); - $( ".ui-calendar-prev", this.element ).attr( "title", this.labels.prevText ) - .children().html( this.labels.prevText ); - $( ".ui-calendar-next", this.element ).attr( "title", this.labels.nextText ) - .children().html( this.labels.nextText ); - this._createButtons(); } else { this._refreshMultiplePicker(); } + + this._refreshHeaderButtons(); + this._createButtons(); + }, + + _refreshHeaderButtons: function() { + var prevText = this._getTranslation( "prevText" ), + nextText = this._getTranslation( "nextText" ); + + this.prevButton.attr( "title", prevText ).children().html( prevText ); + this.nextButton.attr( "title", nextText ).children().html( nextText ); + this._headerButtonsState(); + }, + + _headerButtonsState: function() { + var months = this.viewDate.months( this.options.numberOfMonths - 1 ), + i = 0; + + for ( ; i < months.length; i++ ) { + if ( this.options.min !== null && months[ i ].first ) { + this._disableElement( this.prevButton, + ( this.options.min.getMonth() >= months[ i ].month() && + this.options.min.getFullYear() === months[ i ].year() ) || + this.options.min.getFullYear() > months[ i ].year() + ); + } + if ( this.options.max !== null && months[ i ].last ) { + this._disableElement( this.nextButton, + ( this.options.max.getMonth() <= months[ i].month() && + this.options.max.getFullYear() === months[ i ].year() ) || + this.options.max.getFullYear() < months[ i ].year() + ); + } + } + }, + + _disableElement: function( element, state ) { + element + .attr( "aria-disabled", state ) + .toggleClass( "ui-state-disabled", state ); }, _refreshMultiplePicker: function() { From 3135e5bb37841c9d83c2c0eb9315d7fcccfbba93 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 26 Aug 2015 11:49:04 +0200 Subject: [PATCH 099/179] Calendar: Use day of the month instead day of the week for range There is no sense in use the day of the week as a base for min/max range. --- demos/calendar/min-max.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html index 36535b87525..d4b074a5ece 100644 --- a/demos/calendar/min-max.html +++ b/demos/calendar/min-max.html @@ -8,8 +8,8 @@ From 558c31ce4749198875ef97bc8858ee238cdac840 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 2 Sep 2015 22:58:22 +0200 Subject: [PATCH 103/179] Calendar tests: Add header buttons test when using date below min option --- tests/unit/calendar/options.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js index 86eb6492f4b..62390813ad5 100644 --- a/tests/unit/calendar/options.js +++ b/tests/unit/calendar/options.js @@ -191,7 +191,7 @@ test( "showWeek", function() { }); test( "min / max", function() { - expect( 14 ); + expect( 17 ); // With existing date var element = $( "#calendar" ).calendar(), @@ -253,11 +253,21 @@ test( "min / max", function() { .calendar( "option", { max: null } ) .calendar( "value", "1/4/09" ) .calendar( "option", { min: minDate, max: maxDate } ); - ok( nextButton.hasClass( "ui-state-disabled" ), "Other year: Next button disabled" ); + ok( nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button disabled" ); prevButton.simulate( "click" ); - ok( nextButton.hasClass( "ui-state-disabled" ), "Other year: Next button disabled after click" ); + ok( nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button disabled after click" ); prevButton.simulate( "click" ); - ok( !nextButton.hasClass( "ui-state-disabled" ), "Other year: Next button enabled after click" ); + ok( !nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button enabled after click" ); + + element + .calendar( "option", { min: null } ) + .calendar( "value", "1/4/08" ) + .calendar( "option", { min: minDate, max: maxDate } ); + ok( prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button disabled" ); + nextButton.simulate( "click" ); + ok( prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button disabled after click" ); + nextButton.simulate( "click" ); + ok( !prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button enabled after click" ); }); test( "numberOfMonths", function() { From 521604eea5a9ef46a9dfb2eab03b5e30d2877ebf Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 2 Sep 2015 23:06:59 +0200 Subject: [PATCH 104/179] Calendar tests: Test for using right arrow button with numberOfMonth --- tests/unit/calendar/options.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js index 62390813ad5..3172787de47 100644 --- a/tests/unit/calendar/options.js +++ b/tests/unit/calendar/options.js @@ -271,7 +271,7 @@ test( "min / max", function() { }); test( "numberOfMonths", function() { - expect( 5 ); + expect( 6 ); var date = new Date( 2015, 8 - 1, 1 ), input = $( "#calendar" ).calendar({ numberOfMonths: 3, @@ -297,12 +297,18 @@ test( "numberOfMonths", function() { "After mousedown last month: Last day is Saturday" ); - // Test if using cursor down to go to the next month advances three month + // Test if using cursor to go to the next / prev month advances three month container.find( "tbody:first td[id]:first button" ).trigger( "mousedown" ); $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); equal( container.find( ".ui-calendar-month:first" ).text(), "May", "After move to previous month: First month is May" ); + + container.find( "tbody:last td[id]:last button" ).trigger( "mousedown" ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ); + equal( container.find( ".ui-calendar-month:last" ).text(), "October", + "After move to next month: Last month is October" + ); }); /* From af7d2009ce95cf1975bb840ba9d2da9b3fb7a52b Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 10 Sep 2015 23:23:03 +0200 Subject: [PATCH 105/179] Calendar: Remove some obsolete todo comments --- external/date.js | 1 - ui/widgets/calendar.js | 1 - 2 files changed, 2 deletions(-) diff --git a/external/date.js b/external/date.js index bc544559465..b1f10dd4fc4 100644 --- a/external/date.js +++ b/external/date.js @@ -224,7 +224,6 @@ $.extend( _Date.prototype, { return new _Date( new Date( date.getTime() ), this.attributes ); }, - // TODO compare year, month, day each for better performance equal: function( other ) { var format = function( date ) { return "" + date.getFullYear() + date.getMonth() + date.getDate(); diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index e274e558cb7..25c1df001e9 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -17,7 +17,6 @@ if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. - // TODO: Keep button even if its optional? define( [ "jquery", "globalize", From dcef45359418fe103beed0ada435da5080cc16ef Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sun, 27 Sep 2015 18:35:35 +0200 Subject: [PATCH 106/179] Calendar: Move custom date object to ui namespace --- demos/bootstrap.js | 1 - tests/lib/bootstrap.js | 3 +-- tests/unit/date/core.js | 36 ++++++++++++++++++------------------ {external => ui}/date.js | 22 +++++++++------------- ui/widgets/calendar.js | 4 ++-- 5 files changed, 30 insertions(+), 36 deletions(-) rename {external => ui}/date.js (93%) diff --git a/demos/bootstrap.js b/demos/bootstrap.js index 2f2b3209aa2..faffcbdd89b 100644 --- a/demos/bootstrap.js +++ b/demos/bootstrap.js @@ -73,7 +73,6 @@ require.config( { baseUrl: "../../ui", paths: { cldr: "../external/cldrjs/cldr", - date: "../external/date", globalize: "../external/globalize/globalize", "globalize-locales": "../external/localization", jquery: "../external/jquery/jquery", diff --git a/tests/lib/bootstrap.js b/tests/lib/bootstrap.js index 571621fa44e..89c4d489363 100644 --- a/tests/lib/bootstrap.js +++ b/tests/lib/bootstrap.js @@ -2,7 +2,6 @@ requirejs.config({ paths: { - "date": "../../../external/date", "cldr": "../../../external/cldrjs/cldr", "globalize": "../../../external/globalize/globalize", "globalize-locales": "../../../external/localization", @@ -20,7 +19,7 @@ requirejs.config({ "ui": "../../../ui" }, shim: { - "date": [ "globalize-locales" ], + "ui/date": [ "globalize-locales" ], "globalize-old/ja-JP": [ "globalize-old" ], "jquery-simulate": [ "jquery" ], "qunit-assert-close": [ "qunit" ], diff --git a/tests/unit/date/core.js b/tests/unit/date/core.js index 91d368fcb95..349f5d87307 100644 --- a/tests/unit/date/core.js +++ b/tests/unit/date/core.js @@ -1,7 +1,7 @@ define( [ "jquery", "./helper", - "date" + "ui/date" ], function( $, testHelper ) { module( "date: core" ); @@ -10,12 +10,12 @@ var attributes = testHelper.getAttributes( "en" ); test( "Instantiation", function() { expect( 2 ); - ok( new $.ui.calendarDate( null, attributes ) instanceof $.ui.calendarDate, "constructor function" ); - ok( $.ui.calendarDate( null, attributes ) instanceof $.ui.calendarDate, "instantiation without new" ); + ok( new $.ui.date( null, attributes ) instanceof $.ui.date, "constructor function" ); + ok( $.ui.date( null, attributes ) instanceof $.ui.date, "instantiation without new" ); }); test( "Check Sets and Gets", 6, function() { - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); 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" ); @@ -25,7 +25,7 @@ test( "Check Sets and Gets", 6, function() { }); test( "Date Adjustments - Normal Use Cases", 10, function() { - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); // Use October 15, 2012 date.setFullDate( 2012, 9, 15 ); @@ -50,7 +50,7 @@ test( "Date Adjustments - Normal Use Cases", 10, function() { }); test( "Date Adjustments - Month Overflow Edge Cases", 2, function() { - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); // Use May 31 2012 date.setFullDate( 2012, 4, 31 ); @@ -61,7 +61,7 @@ test( "Date Adjustments - Month Overflow Edge Cases", 2, function() { }); test( "Date Adjustments - Leap Year Edge Cases", 1, function() { - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); // Use February 29 2012 a Leap year date.setFullDate( 2012, 1, 29 ); @@ -70,7 +70,7 @@ test( "Date Adjustments - Leap Year Edge Cases", 1, function() { }); test( "List days of Week", 2, function() { - var date = $.ui.calendarDate( null, attributes ), + var date = $.ui.date( null, attributes ), offset0 = [ { "fullname": "Sunday", "shortname": "Su" }, { "fullname": "Monday", "shortname": "Mo" }, @@ -91,12 +91,12 @@ test( "List days of Week", 2, function() { ]; deepEqual( date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)" ); - date = $.ui.calendarDate( null, testHelper.getAttributes( "de" ) ); + date = $.ui.date( null, testHelper.getAttributes( "de" ) ); deepEqual( date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)" ); }); test( "Leap Year Check", 8, function() { - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); 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" ); @@ -108,7 +108,7 @@ test( "Leap Year Check", 8, function() { }); test( "Days in Month", 3, function() { - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); 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" ); @@ -116,14 +116,14 @@ test( "Days in Month", 3, function() { }); test( "Month Name", 2, function() { - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); equal( date.setMonth( 3 ).monthName(), "April", "Month name return April (English)" ); - date = $.ui.calendarDate( null, testHelper.getAttributes( "de" ) ); + date = $.ui.date( null, testHelper.getAttributes( "de" ) ); equal( date.setMonth( 2 ).monthName(), "März", "Month name return March (German)" ); }); test( "Clone", 2, function() { - var date = $.ui.calendarDate( null, attributes ), + var date = $.ui.date( null, attributes ), date2 = date.clone(); ok( date2, "Created cloned object" ); notEqual( date.adjust( "Y", 1 ).year(), date2.year(), "Object manipulated independently" ); @@ -131,7 +131,7 @@ test( "Clone", 2, function() { test( "Days", 1, function() { // TODO needs work - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); date.eachDay = function( day ) { if ( day.lead && day.date > 20 ) { day.selectable = false; @@ -156,7 +156,7 @@ test( "Days", 1, function() { }); test( "Months", 5, function(){ - var date = $.ui.calendarDate( null, attributes ), + var date = $.ui.date( null, attributes ), firstMonth = date.months( 1 )[ 0 ], lastMonth = date.months( 1 )[ 1 ]; @@ -169,7 +169,7 @@ test( "Months", 5, function(){ }); test( "Equal", 4, function() { - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); 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" ); @@ -178,7 +178,7 @@ test( "Equal", 4, function() { }); test( "Date", 1, function() { - var date = $.ui.calendarDate( null, attributes ); + var date = $.ui.date( null, attributes ); ok( date.date() instanceof Date, "Date returned" ); }); diff --git a/external/date.js b/ui/date.js similarity index 93% rename from external/date.js rename to ui/date.js index b1f10dd4fc4..1d207a39f83 100644 --- a/external/date.js +++ b/ui/date.js @@ -9,8 +9,7 @@ // AMD. Register as an anonymous module. define( [ - "jquery" - ], factory ); + "jquery", "./version" ], factory ); } else { // Browser globals @@ -18,10 +17,7 @@ } }( function( $ ) { -$.ui = $.ui || {}; - -var _Date, - weekdaysRev = { +var weekdaysRev = { "sun": 0, "mon": 1, "tue": 2, @@ -31,9 +27,9 @@ var _Date, "sat": 6 }; -_Date = function( date, attributes ) { - if ( !( this instanceof _Date ) ) { - return new _Date( date, attributes ); +$.ui.date = function( date, attributes ) { + if ( !( this instanceof $.ui.date ) ) { + return new $.ui.date( date, attributes ); } this.setAttributes( attributes ); @@ -47,7 +43,7 @@ _Date = function( date, attributes ) { this.dateObject = this.dateObject || new Date(); }; -$.extend( _Date.prototype, { +$.extend( $.ui.date.prototype, { setAttributes: function( attributes ) { this.attributes = attributes; @@ -172,7 +168,7 @@ $.extend( _Date.prototype, { days: function() { var result = [], - today = new _Date( new Date(), this.attributes ), + today = new $.ui.date( new Date(), this.attributes ), date = this.dateObject, firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(), leadDays = ( firstDayOfMonth - this.firstDay + 7 ) % 7, @@ -221,7 +217,7 @@ $.extend( _Date.prototype, { clone: function() { var date = this.dateObject; - return new _Date( new Date( date.getTime() ), this.attributes ); + return new $.ui.date( new Date( date.getTime() ), this.attributes ); }, equal: function( other ) { @@ -236,6 +232,6 @@ $.extend( _Date.prototype, { } }); -return $.ui.calendarDate = _Date; +return $.ui.date; } ) ); diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index 25c1df001e9..63b09ede3e3 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -22,7 +22,7 @@ "globalize", "globalize/date", "globalize-locales", - "date", + "../date", "./button", "../widget", "../version", @@ -78,7 +78,7 @@ return $.widget( "ui.calendar", { this._setLocale( this.options.locale, this.options.dateFormat ); - this.date = new $.ui.calendarDate( this.options.value, this._calendarDateOptions ); + this.date = new $.ui.date( this.options.value, this._calendarDateOptions ); this.viewDate = this.date.clone(); this.viewDate.eachDay = this.options.eachDay; From 8a169db7f45a849ef37193998f39df7011179aa8 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sun, 27 Sep 2015 18:51:39 +0200 Subject: [PATCH 107/179] Calendar: Remove all unused methods from custom date object --- tests/unit/date/core.js | 23 +++++------------------ ui/date.js | 37 ------------------------------------- 2 files changed, 5 insertions(+), 55 deletions(-) diff --git a/tests/unit/date/core.js b/tests/unit/date/core.js index 349f5d87307..c12303516c6 100644 --- a/tests/unit/date/core.js +++ b/tests/unit/date/core.js @@ -14,14 +14,13 @@ test( "Instantiation", function() { ok( $.ui.date( null, attributes ) instanceof $.ui.date, "instantiation without new" ); }); -test( "Check Sets and Gets", 6, function() { +test( "Check Sets and Gets", 4, function() { var date = $.ui.date( null, attributes ); - 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" ); + // TODO Add setTime test }); test( "Date Adjustments - Normal Use Cases", 10, function() { @@ -95,18 +94,6 @@ test( "List days of Week", 2, function() { deepEqual( date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)" ); }); -test( "Leap Year Check", 8, function() { - var date = $.ui.date( null, attributes ); - 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 = $.ui.date( null, attributes ); date.setFullDate( 2012, 1, 1 ); @@ -117,9 +104,9 @@ test( "Days in Month", 3, function() { test( "Month Name", 2, function() { var date = $.ui.date( null, attributes ); - equal( date.setMonth( 3 ).monthName(), "April", "Month name return April (English)" ); + equal( date.setFullDate( 2012, 3, 1 ).monthName(), "April", "Month name return April (English)" ); date = $.ui.date( null, testHelper.getAttributes( "de" ) ); - equal( date.setMonth( 2 ).monthName(), "März", "Month name return March (German)" ); + equal( date.setFullDate( 2012, 2, 1 ).monthName(), "März", "Month name return March (German)" ); }); test( "Clone", 2, function() { @@ -130,7 +117,7 @@ test( "Clone", 2, function() { }); test( "Days", 1, function() { - // TODO needs work + // TODO Needs work var date = $.ui.date( null, attributes ); date.eachDay = function( day ) { if ( day.lead && day.date > 20 ) { diff --git a/ui/date.js b/ui/date.js index 1d207a39f83..b192d6bc2f7 100644 --- a/ui/date.js +++ b/ui/date.js @@ -65,38 +65,6 @@ $.extend( $.ui.date.prototype, { 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.getDate(), year = date.getFullYear(); - if ( days > this.daysInMonth( year, month ) ) { - - // 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 ); @@ -141,11 +109,6 @@ $.extend( $.ui.date.prototype, { return this.dateObject.getFullYear(); }, - isLeapYear: function( year ) { - year = year || this.dateObject.getFullYear(); - return new Date( year, 1, 29 ).getMonth() === 1; - }, - weekdays: function() { var date, firstDay = this.firstDay, From d650fa9a7e127eb6950f93034c92accb65bcb2c3 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sun, 27 Sep 2015 18:57:46 +0200 Subject: [PATCH 108/179] Calendar: Fix some jshint issues --- ui/date.js | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/ui/date.js b/ui/date.js index b192d6bc2f7..ba92038730b 100644 --- a/ui/date.js +++ b/ui/date.js @@ -65,7 +65,6 @@ $.extend( $.ui.date.prototype, { return this; }, - setFullDate: function( year, month, day ) { this.dateObject = new Date( year, month, day ); return this; @@ -110,7 +109,7 @@ $.extend( $.ui.date.prototype, { }, weekdays: function() { - var date, + var date, dow, firstDay = this.firstDay, result = []; @@ -118,32 +117,34 @@ $.extend( $.ui.date.prototype, { date = new Date( this.dateObject.getTime() ); date.setDate( date.getDate() + firstDay - 1 - date.getDay() ); - for ( var dow = 0; dow < 7; dow++ ) { + for ( dow = 0; dow < 7; dow++ ) { date.setTime( date.getTime() + 86400000 ); - result.push({ + result.push( { shortname: this.attributes.formatWeekdayShort( date ), fullname: this.attributes.formatWeekdayFull( date ) - }); + } ); } return result; }, days: function() { - var result = [], + var row, week, dayx, day, + result = [], today = new $.ui.date( new Date(), this.attributes ), date = this.dateObject, firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(), leadDays = ( firstDayOfMonth - this.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 ] = { + + for ( row = 0; row < rows; row++ ) { + week = result[ result.length ] = { number: this.attributes.formatWeekOfYear( printDate ), days: [] }; - for ( var dayx = 0; dayx < 7; dayx++ ) { - var day = week.days[ week.days.length ] = { + for ( dayx = 0; dayx < 7; dayx++ ) { + day = week.days[ week.days.length ] = { lead: printDate.getMonth() !== date.getMonth(), date: printDate.getDate(), month: printDate.getMonth(), @@ -165,10 +166,10 @@ $.extend( $.ui.date.prototype, { // specialized for multi-month template, could be used in general months: function( add ) { - var clone, + var clone, i, result = [ this ]; - for ( var i = 0; i < add; i++ ) { + for ( i = 0; i < add; i++ ) { clone = this.clone(); clone.adjust( "M", i + 1 ); result.push( clone ); @@ -193,7 +194,7 @@ $.extend( $.ui.date.prototype, { date: function() { return this.dateObject; } -}); +} ); return $.ui.date; From 3e14e0fe33a1464dcbca4e60753eeb7dc4b6fd91 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sun, 27 Sep 2015 19:14:52 +0200 Subject: [PATCH 109/179] Calendar tests: Add comment to number of month test --- tests/unit/calendar/options.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js index 3172787de47..bcb86c55f34 100644 --- a/tests/unit/calendar/options.js +++ b/tests/unit/calendar/options.js @@ -298,6 +298,7 @@ test( "numberOfMonths", function() { ); // Test if using cursor to go to the next / prev month advances three month + // Focus doesn't work here so we use an additional mouse down event container.find( "tbody:first td[id]:first button" ).trigger( "mousedown" ); $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); equal( container.find( ".ui-calendar-month:first" ).text(), "May", From 66828b1a83675753c9f6f603236f897f62a215e6 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sun, 27 Sep 2015 19:17:02 +0200 Subject: [PATCH 110/179] Calendar: Remove _refresh method --- ui/widgets/calendar.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index 63b09ede3e3..1cdb07fdb48 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -86,12 +86,14 @@ return $.widget( "ui.calendar", { "click .ui-calendar-prev": function( event ) { event.preventDefault(); this.date.adjust( "M", -this.options.numberOfMonths ); - this._refresh(); + this.viewDate.setTime( this.date.date().getTime() ); + this.refresh(); }, "click .ui-calendar-next": function( event ) { event.preventDefault(); this.date.adjust( "M", this.options.numberOfMonths ); - this._refresh(); + this.viewDate.setTime( this.date.date().getTime() ); + this.refresh(); }, "mousedown .ui-calendar-calendar button": function( event ) { event.preventDefault(); @@ -156,7 +158,8 @@ return $.widget( "ui.calendar", { ); this.refresh(); } else { - this._refresh(); + this.viewDate.setTime( this.date.date().getTime() ); + this.refresh(); } this.grid.focus(); } @@ -491,11 +494,6 @@ return $.widget( "ui.calendar", { this.buttonPane.appendTo( this.element ); }, - _refresh: function() { - this.viewDate.setTime( this.date.date().getTime() ); - this.refresh(); - }, - // 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 @@ -648,7 +646,8 @@ return $.widget( "ui.calendar", { this.viewDate.setAttributes( this._calendarDateOptions ); } if ( refresh ) { - this._refresh(); + this.viewDate.setTime( this.date.date().getTime() ); + this.refresh(); } }, From 2fe43bbbe20ba59dbbbef1effd9f59ac64cb15a7 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Thu, 8 Oct 2015 15:06:55 +0200 Subject: [PATCH 111/179] Calendar: Fix jscs errors after merging master --- tests/unit/calendar/common.js | 2 +- tests/unit/calendar/core.js | 67 ++++++++++++++++---------------- tests/unit/calendar/methods.js | 14 +++---- tests/unit/calendar/options.js | 44 ++++++++++----------- tests/unit/date/core.js | 32 ++++++++------- tests/unit/date/helper.js | 10 ++--- tests/unit/datepicker/common.js | 2 +- tests/unit/datepicker/core.js | 18 ++++----- tests/unit/datepicker/events.js | 24 ++++++------ tests/unit/datepicker/methods.js | 18 ++++----- tests/unit/datepicker/options.js | 36 ++++++++--------- ui/date.js | 1 + ui/widgets/calendar.js | 12 +++--- ui/widgets/datepicker.js | 31 ++++++++------- 14 files changed, 159 insertions(+), 152 deletions(-) diff --git a/tests/unit/calendar/common.js b/tests/unit/calendar/common.js index 5dae54464e0..8b8f40f73f3 100644 --- a/tests/unit/calendar/common.js +++ b/tests/unit/calendar/common.js @@ -28,6 +28,6 @@ common.testWidget( "calendar", { create: null, select: null } -}); +} ); } ); diff --git a/tests/unit/calendar/core.js b/tests/unit/calendar/core.js index 23e5da43a90..b9c5836a17d 100644 --- a/tests/unit/calendar/core.js +++ b/tests/unit/calendar/core.js @@ -51,7 +51,7 @@ test( "base structure", function() { element.calendar( "option", "buttons", { "test": function() {}, "test button": function() {} - }); + } ); equal( dp.children().length, 3, "Structure buttons - child count (header, calendar, buttonpane)" ); @@ -65,6 +65,7 @@ test( "base structure", function() { } function step3() { + // Multi-month 2 element = $( "#calendar" ).calendar( { numberOfMonths: 2 } ); dp = element.calendar( "widget" ); @@ -79,7 +80,7 @@ test( "base structure", function() { } step1(); -}); +} ); test( "Localization", function() { expect( 10 ); @@ -130,7 +131,7 @@ test( "Localization", function() { .calendar( "option", optionsDe ) .calendar( "refresh" ); testLocalization( "After init: " ); -}); +} ); asyncTest( "keyboard handling", function() { expect( 10 ); @@ -138,12 +139,12 @@ asyncTest( "keyboard handling", function() { var element = $( "#calendar" ); function step1() { - element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); testHelper .focusGrid( element ) .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -156,7 +157,7 @@ asyncTest( "keyboard handling", function() { } function step2() { - element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); testHelper.focusGrid( element ) .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) @@ -171,10 +172,10 @@ asyncTest( "keyboard handling", function() { } function step3() { - element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -187,10 +188,10 @@ asyncTest( "keyboard handling", function() { } function step4() { - element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -203,10 +204,10 @@ asyncTest( "keyboard handling", function() { } function step5() { - element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -219,11 +220,11 @@ asyncTest( "keyboard handling", function() { } function step6() { - element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); testHelper.focusGrid( element ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -236,10 +237,10 @@ asyncTest( "keyboard handling", function() { } function step7() { - element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -252,11 +253,11 @@ asyncTest( "keyboard handling", function() { } function step8() { - element.calendar({ value: new Date( 2014, 1 - 1, 1 ) }); + element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); testHelper.focusGrid( element ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -270,10 +271,10 @@ asyncTest( "keyboard handling", function() { // Check for moving to short months function step9() { - element.calendar({ value: new Date( 2014, 3 - 1, 31 ) }); + element.calendar( { value: new Date( 2014, 3 - 1, 31 ) } ); testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -286,10 +287,10 @@ asyncTest( "keyboard handling", function() { } function step10() { - element.calendar({ value: new Date( 2016, 1 - 1, 30 ) }); + element.calendar( { value: new Date( 2016, 1 - 1, 30 ) } ); testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -302,7 +303,7 @@ asyncTest( "keyboard handling", function() { } step1(); -}); +} ); asyncTest( "mouse", function() { expect( 6 ); @@ -319,7 +320,7 @@ asyncTest( "mouse", function() { "Mouse click" ); - element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); + element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) ); $( ".ui-calendar-calendar tbody button:contains(12)", element ).simulate( "mousedown" ); testHelper.equalsDate( element.calendar( "valueAsDate" ), @@ -328,7 +329,7 @@ asyncTest( "mouse", function() { ); // Previous/next - element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); + element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) ); $( ".ui-calendar-prev", element ).simulate( "click" ); $( ".ui-calendar-calendar tbody button:contains(16)", element ).simulate( "mousedown" ); testHelper.equalsDate( @@ -337,7 +338,7 @@ asyncTest( "mouse", function() { "Mouse click - previous" ); - element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); + element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) ); $( ".ui-calendar-next", element ).simulate( "click" ); $( ".ui-calendar-calendar tbody button:contains(18)", element ).simulate( "mousedown" ); testHelper.equalsDate( @@ -352,11 +353,11 @@ asyncTest( "mouse", function() { // Previous/next with minimum/maximum function step2() { element.calendar( "destroy" ); - element.calendar({ - value: new Date( 2008, 3 - 1, 4), + 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 button:contains(16)", element ).simulate( "mousedown" ); @@ -370,11 +371,11 @@ asyncTest( "mouse", function() { function step3() { element.calendar( "destroy" ); - element.calendar({ - value: new Date( 2008, 1 - 1, 4), + 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 button:contains(18)", element ).simulate( "mousedown" ); @@ -387,6 +388,6 @@ asyncTest( "mouse", function() { } step1(); -}); +} ); } ); diff --git a/tests/unit/calendar/methods.js b/tests/unit/calendar/methods.js index 23989860c66..84e26571076 100644 --- a/tests/unit/calendar/methods.js +++ b/tests/unit/calendar/methods.js @@ -11,8 +11,8 @@ test( "destroy", function( assert ) { assert.domEqual( "#calendar", function() { $( "#calendar" ).calendar().calendar( "destroy" ); - }); -}); + } ); +} ); test( "enable / disable", function() { expect( 8 ); @@ -30,7 +30,7 @@ test( "enable / disable", function() { ok( !element.hasClass( "ui-calendar-disabled" ), "no longer has disabled widget class name" ); ok( !element.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" ); equal( element.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" ); -}); +} ); test( "widget", function() { expect( 1 ); @@ -39,7 +39,7 @@ test( "widget", function() { widget = element.calendar( "widget" ); strictEqual( widget[ 0 ], element[ 0 ] ); -}); +} ); test( "value", function() { expect( 3 ); @@ -54,7 +54,7 @@ test( "value", function() { element.calendar( "value", "abc" ); equal( element.calendar( "value" ), "1/1/14", "Setting invalid values should be ignored." ); -}); +} ); test( "valueAsDate", function() { expect( 11 ); @@ -77,7 +77,7 @@ test( "valueAsDate", function() { equal( element.calendar( "valueAsDate" ), null, "Set date - default" ); element.calendar( "valueAsDate", date1 ); - testHelper.equalsDate(element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" ); + testHelper.equalsDate( element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" ); // With minimum/maximum element = $( "#calendar" ).calendar(); @@ -140,6 +140,6 @@ test( "valueAsDate", function() { dateAndTimeClone.getTime(), "Date object passed should not be changed by valueAsDate" ); -}); +} ); } ); diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js index bcb86c55f34..4c9c1f15d02 100644 --- a/tests/unit/calendar/options.js +++ b/tests/unit/calendar/options.js @@ -6,13 +6,13 @@ define( [ module( "calendar: options" ); -test("buttons", function() { +test( "buttons", function() { expect( 21 ); var button, i, newButtons, buttons = { "Ok": function( event ) { - ok(true, "button click fires callback" ); + ok( true, "button click fires callback" ); equal( this, element[ 0 ], "context of callback" ); equal( event.target, button[ 0 ], "event target" ); }, @@ -22,7 +22,7 @@ test("buttons", function() { equal( event.target, button[ 1 ], "event target" ); } }, - element = $( "#calendar" ).calendar({ buttons: buttons }); + element = $( "#calendar" ).calendar( { buttons: buttons } ); button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); equal( button.length, 2, "number of buttons" ); @@ -31,7 +31,7 @@ test("buttons", function() { $.each( buttons, function( key ) { equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) ); i++; - }); + } ); ok( button.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container" ); ok( @@ -69,7 +69,7 @@ test("buttons", function() { $.each( newButtons, function( key ) { equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) ); i += 1; - }); + } ); element.calendar( "option", "buttons", null ); button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); @@ -78,14 +78,14 @@ test("buttons", function() { equal( element.hasClass( "ui-calendar-buttons" ), false, "calendar element removes class about having buttons" ); element.remove(); -}); +} ); test( "buttons - advanced", function() { expect( 7 ); var buttons, - element = $( "#calendar" ).calendar({ - buttons: [{ + element = $( "#calendar" ).calendar( { + buttons: [ { text: "a button", "class": "additional-class", id: "my-button-id", @@ -96,8 +96,8 @@ test( "buttons - advanced", function() { primary: "ui-icon-cancel" }, showText: false - }] - }); + } ] + } ); buttons = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); equal( buttons.length, 1, "correct number of buttons" ); @@ -109,7 +109,7 @@ test( "buttons - advanced", function() { buttons.click(); element.remove(); -}); +} ); test( "dateFormat", function() { expect( 2 ); @@ -122,7 +122,7 @@ test( "dateFormat", function() { element.calendar( "option", "dateFormat", { date: "full" } ); equal( element.calendar( "value" ), "Wednesday, January 1, 2014", "updated formatting" ); -}); +} ); test( "eachDay", function() { expect( 5 ); @@ -140,7 +140,7 @@ test( "eachDay", function() { if ( day.date === 1 ) { day.render = false; } - }); + } ); firstCell = picker.find( "td[id]:first" ); timestamp = parseInt( firstCell.find( "button" ).attr( "data-timestamp" ), 10 ); equal( new Date( timestamp ).getDate(), 2, "first available day is the 2nd" ); @@ -150,7 +150,7 @@ test( "eachDay", function() { if ( day.date === 1 ) { day.selectable = false; } - }); + } ); firstCell = picker.find( "td[id]:first" ); ok( firstCell.find( "button" ).prop( "disabled" ), "the 1st is not selectable" ); @@ -158,11 +158,11 @@ test( "eachDay", function() { if ( day.date === 1 ) { day.extraClasses = "ui-custom"; } - }); + } ); ok( picker.find( "td[id]:first button" ).hasClass( "ui-custom" ), "extraClasses applied" ); input.calendar( "destroy" ); -}); +} ); test( "showWeek", function() { expect( 7 ); @@ -174,7 +174,7 @@ test( "showWeek", function() { "no week column cells present" ); input.calendar( "destroy" ); - input = $( "#calendar" ).calendar({ showWeek: true }); + 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" ), @@ -188,7 +188,7 @@ test( "showWeek", function() { 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( "min / max", function() { expect( 17 ); @@ -268,15 +268,15 @@ test( "min / max", function() { ok( prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button disabled after click" ); nextButton.simulate( "click" ); ok( !prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button enabled after click" ); -}); +} ); test( "numberOfMonths", function() { expect( 6 ); var date = new Date( 2015, 8 - 1, 1 ), - input = $( "#calendar" ).calendar({ + input = $( "#calendar" ).calendar( { numberOfMonths: 3, value: date - }), + } ), container = input.calendar( "widget" ); equal( container.find( ".ui-calendar-group" ).length, 3, "3 calendar grids" ); @@ -310,7 +310,7 @@ test( "numberOfMonths", function() { equal( container.find( ".ui-calendar-month:last" ).text(), "October", "After move to next month: Last month is October" ); -}); +} ); /* // TODO: Move this to $.date, Globalize or calendar widget diff --git a/tests/unit/date/core.js b/tests/unit/date/core.js index c12303516c6..b045315939d 100644 --- a/tests/unit/date/core.js +++ b/tests/unit/date/core.js @@ -12,7 +12,7 @@ test( "Instantiation", function() { expect( 2 ); ok( new $.ui.date( null, attributes ) instanceof $.ui.date, "constructor function" ); ok( $.ui.date( null, attributes ) instanceof $.ui.date, "instantiation without new" ); -}); +} ); test( "Check Sets and Gets", 4, function() { var date = $.ui.date( null, attributes ); @@ -20,8 +20,9 @@ test( "Check Sets and Gets", 4, function() { 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" ); + // TODO Add setTime test -}); +} ); test( "Date Adjustments - Normal Use Cases", 10, function() { var date = $.ui.date( null, attributes ); @@ -46,7 +47,7 @@ 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() { var date = $.ui.date( null, attributes ); @@ -57,7 +58,7 @@ test( "Date Adjustments - Month Overflow Edge Cases", 2, function() { "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 = $.ui.date( null, attributes ); @@ -66,7 +67,7 @@ test( "Date Adjustments - Leap Year Edge Cases", 1, function() { 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 = $.ui.date( null, attributes ), @@ -92,7 +93,7 @@ test( "List days of Week", 2, function() { deepEqual( date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)" ); date = $.ui.date( null, testHelper.getAttributes( "de" ) ); deepEqual( date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)" ); -}); +} ); test( "Days in Month", 3, function() { var date = $.ui.date( null, attributes ); @@ -100,23 +101,24 @@ test( "Days in Month", 3, function() { 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 = $.ui.date( null, attributes ); equal( date.setFullDate( 2012, 3, 1 ).monthName(), "April", "Month name return April (English)" ); date = $.ui.date( null, testHelper.getAttributes( "de" ) ); equal( date.setFullDate( 2012, 2, 1 ).monthName(), "März", "Month name return March (German)" ); -}); +} ); test( "Clone", 2, function() { var date = $.ui.date( null, attributes ), 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 = $.ui.date( null, attributes ); date.eachDay = function( day ) { @@ -139,10 +141,10 @@ 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(){ +test( "Months", 5, function() { var date = $.ui.date( null, attributes ), firstMonth = date.months( 1 )[ 0 ], lastMonth = date.months( 1 )[ 1 ]; @@ -153,7 +155,7 @@ test( "Months", 5, function(){ ok( !lastMonth.first ); ok( firstMonth.month() === lastMonth.month() - 1 ); -}); +} ); test( "Equal", 4, function() { var date = $.ui.date( null, attributes ); @@ -162,11 +164,11 @@ test( "Equal", 4, function() { 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 = $.ui.date( null, attributes ); ok( date.date() instanceof Date, "Date returned" ); -}); +} ); } ); diff --git a/tests/unit/date/helper.js b/tests/unit/date/helper.js index 01755c53adc..fa9c9cf663e 100644 --- a/tests/unit/date/helper.js +++ b/tests/unit/date/helper.js @@ -8,8 +8,8 @@ define( [ return $.extend( helper, { getAttributes: function( locale ) { var globalize = new Globalize( locale ), - weekdayShortFormatter = globalize.dateFormatter({ raw: "EEEEEE" }), - weekdayNarrowFormatter = globalize.dateFormatter({ raw: "EEEEE" } ); + weekdayShortFormatter = globalize.dateFormatter( { raw: "EEEEEE" } ), + weekdayNarrowFormatter = globalize.dateFormatter( { raw: "EEEEE" } ); return { firstDay: globalize.cldr.supplemental.weekData.firstDay(), @@ -20,9 +20,9 @@ return $.extend( helper, { return shortWeekday.length > 3 ? weekdayNarrowFormatter( date ) : shortWeekday; }, - formatWeekdayFull: globalize.dateFormatter({ raw: "EEEE" }), - formatMonth: globalize.dateFormatter({ raw: "MMMM" }), - formatWeekOfYear: globalize.dateFormatter({ raw: "w" }) + formatWeekdayFull: globalize.dateFormatter( { raw: "EEEE" } ), + formatMonth: globalize.dateFormatter( { raw: "MMMM" } ), + formatWeekOfYear: globalize.dateFormatter( { raw: "w" } ) }; } } ); diff --git a/tests/unit/datepicker/common.js b/tests/unit/datepicker/common.js index 61c7ace43e6..bc06a89929a 100644 --- a/tests/unit/datepicker/common.js +++ b/tests/unit/datepicker/common.js @@ -37,6 +37,6 @@ common.testWidget( "datepicker", { open: null, select: null } -}); +} ); } ); diff --git a/tests/unit/datepicker/core.js b/tests/unit/datepicker/core.js index 2a89108755f..83882ef7aee 100644 --- a/tests/unit/datepicker/core.js +++ b/tests/unit/datepicker/core.js @@ -19,7 +19,7 @@ test( "input's value determines starting date", function() { equal( picker.find( ".ui-state-active" ).html(), "1", "correct day highlighted" ); input.val( "" ).datepicker( "destroy" ); -}); +} ); asyncTest( "base structure", function() { expect( 5 ); @@ -29,7 +29,7 @@ asyncTest( "base structure", function() { input.focus(); - setTimeout(function() { + setTimeout( function() { ok( widget.is( ":visible" ), "Datepicker visible" ); equal( widget.children().length, 2, "Child count" ); ok( widget.is( ".ui-calendar" ), "Class ui-calendar" ); @@ -39,7 +39,7 @@ asyncTest( "base structure", function() { input.datepicker( "close" ); start(); }, 50 ); -}); +} ); asyncTest( "Keyboard handling: input", function() { expect( 10 ); @@ -53,7 +53,7 @@ asyncTest( "Keyboard handling: input", function() { ok( !picker.is( ":visible" ), "datepicker closed" ); input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - setTimeout(function() { + setTimeout( function() { ok( picker.is( ":visible" ), "Keystroke down opens datepicker" ); input.datepicker( "destroy" ); step2(); @@ -67,7 +67,7 @@ asyncTest( "Keyboard handling: input", function() { ok( !picker.is( ":visible" ), "datepicker closed" ); input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); - setTimeout(function() { + setTimeout( function() { ok( picker.is( ":visible" ), "Keystroke up opens datepicker" ); input.datepicker( "destroy" ); step3(); @@ -121,12 +121,12 @@ asyncTest( "Keyboard handling: input", function() { } step1(); -}); +} ); // TODO: implement test( "ARIA", function() { expect( 0 ); -}); +} ); asyncTest( "mouse", function() { expect( 4 ); @@ -136,7 +136,7 @@ asyncTest( "mouse", function() { input.datepicker( "open" ); - setTimeout(function() { + setTimeout( function() { input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); $( ".ui-calendar-calendar tbody button:contains(12)", picker ).simulate( "mousedown", {} ); testHelper.equalsDate( @@ -168,6 +168,6 @@ asyncTest( "mouse", function() { start(); }, 100 ); -}); +} ); } ); diff --git a/tests/unit/datepicker/events.js b/tests/unit/datepicker/events.js index 833316ce48a..902896f2a2a 100644 --- a/tests/unit/datepicker/events.js +++ b/tests/unit/datepicker/events.js @@ -17,7 +17,7 @@ test( "beforeOpen", function() { open: function() { ok( input.datepicker( "widget" ).is( ":visible" ), "calendar open on open" ); } - }); + } ); input .datepicker( "open" ) @@ -29,9 +29,9 @@ test( "beforeOpen", function() { open: function() { ok( false, "calendar should not open when openBefore is canceled" ); } - }) + } ) .datepicker( "open" ); -}); +} ); test( "close", function() { expect( 4 ); @@ -41,7 +41,7 @@ test( "close", function() { close: function() { ok( shouldFire, "close event fired" ); } - }); + } ); shouldFire = false; input.datepicker( "open" ); @@ -62,7 +62,7 @@ test( "close", function() { input.datepicker( "open" ); shouldFire = true; input.datepicker( "widget" ).find( "tbody tr:first button:first" ).simulate( "mousedown" ); -}); +} ); test( "open", function() { expect( 2 ); @@ -72,11 +72,11 @@ test( "open", function() { ok( true, "open event fired on open" ); ok( widget.is( ":visible" ), "calendar open on open" ); } - }), + } ), widget = input.datepicker( "widget" ); input.datepicker( "open" ); -}); +} ); asyncTest( "select", function() { expect( 4 ); @@ -90,7 +90,7 @@ asyncTest( "select", function() { "select originalEvent " + message ); } - }), + } ), widget = input.datepicker( "widget" ), message = ""; @@ -99,7 +99,7 @@ asyncTest( "select", function() { input .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - setTimeout(function() { + setTimeout( function() { widget.find( "tbody tr:first button:first" ).simulate( "mousedown" ); input.datepicker( "close" ); step2(); @@ -111,7 +111,7 @@ asyncTest( "select", function() { input .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ) .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); @@ -125,7 +125,7 @@ asyncTest( "select", function() { input .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - setTimeout(function() { + setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); input.datepicker( "close" ); start(); @@ -133,6 +133,6 @@ asyncTest( "select", function() { } step1(); -}); +} ); } ); diff --git a/tests/unit/datepicker/methods.js b/tests/unit/datepicker/methods.js index f05958af0b1..2cf83569819 100644 --- a/tests/unit/datepicker/methods.js +++ b/tests/unit/datepicker/methods.js @@ -15,8 +15,8 @@ test( "destroy", function( assert ) { ok( input.attr( "aria-owns" ), "aria-owns attribute added" ); ok( input.attr( "aria-haspopup" ), "aria-haspopup attribute added" ); input.datepicker( "destroy" ); - }); -}); + } ); +} ); test( "enable / disable", function() { expect( 10 ); @@ -37,7 +37,7 @@ test( "enable / disable", function() { ok( !input.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" ); equal( input.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" ); equal( input.attr( "disabled" ), undefined, "input no longer disabled" ); -}); +} ); test( "widget", function() { expect( 1 ); @@ -45,12 +45,12 @@ test( "widget", function() { var actual = $( "#datepicker" ).datepicker().datepicker( "widget" ); deepEqual( $( "body > .ui-front" )[ 0 ], actual[ 0 ] ); actual.remove(); -}); +} ); test( "open / close", function() { expect( 7 ); - var input = testHelper.initNewInput({ show: false, hide: false }), + var input = testHelper.initNewInput( { show: false, hide: false } ), calendar = input.datepicker( "widget" ); ok( calendar.is( ":hidden" ), "calendar hidden on init" ); @@ -64,7 +64,7 @@ test( "open / close", function() { ok( !calendar.is( ":visible" ), "close: calendar hidden" ); equal( calendar.attr( "aria-hidden" ), "true", "close: calendar aria-hidden" ); equal( calendar.attr( "aria-expanded" ), "false", "close: calendar aria-expanded" ); -}); +} ); test( "value", function() { expect( 4 ); @@ -84,7 +84,7 @@ test( "value", function() { input.val( "abc" ); strictEqual( input.datepicker( "value" ), null, "Invalid values should return null." ); -}); +} ); test( "valueAsDate", function() { expect( 6 ); @@ -110,7 +110,7 @@ test( "valueAsDate", function() { strictEqual( input.datepicker( "valueAsDate" ), null, "Set date - default" ); input.datepicker( "valueAsDate", date1 ); testHelper.equalsDate( input.datepicker( "valueAsDate" ), date1, "Set date - 2008-06-04" ); -}); +} ); test( "isValid", function() { expect( 2 ); @@ -123,6 +123,6 @@ test( "isValid", function() { ok( !input.datepicker( "isValid" ) ); input.datepicker( "destroy" ); -}); +} ); } ); diff --git a/tests/unit/datepicker/options.js b/tests/unit/datepicker/options.js index 75d74546055..6021f1b7e5c 100644 --- a/tests/unit/datepicker/options.js +++ b/tests/unit/datepicker/options.js @@ -17,12 +17,12 @@ test( "appendTo", function() { equal( container, document.body, "defaults to body" ); input.datepicker( "destroy" ); - input.datepicker({ appendTo: "#qunit-fixture" }); + 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" }); + 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" ); @@ -33,16 +33,16 @@ test( "appendTo", function() { equal( container, $( "#qunit-fixture" )[ 0 ], "modified after init" ); input.datepicker( "destroy" ); - input.datepicker({ appendTo: detached }); + 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 ] }); + input.datepicker( { appendTo: detached[ 0 ] } ); container = input.datepicker( "widget" ).parent()[ 0 ]; equal( container, detached[ 0 ], "detached DOM element" ); input.datepicker( "destroy" ); -}); +} ); test( "Pass-through options", function() { expect( 11 ); @@ -77,20 +77,20 @@ test( "Pass-through options", function() { if ( key === "locale" ) { equal( input.val(), "Mittwoch, 1. Januar 2014", "option " + key + ": updated locale" ); } - }); -}); + } ); +} ); -asyncTest( "position", function(assert) { +asyncTest( "position", function( assert ) { expect( 3 ); - var input = $( "" ).datepicker().appendTo( "body" ).css({ + var input = $( "" ).datepicker().appendTo( "body" ).css( { position: "absolute", top: 0, left: 0 - }), + } ), container = input.datepicker( "widget" ); input.datepicker( "open" ); - setTimeout(function() { + setTimeout( function() { assert.close( input.offset().left, container.offset().left, 1, "left sides line up by default" ); assert.close( container.offset().top, input.offset().top + input.outerHeight(), 1, "datepicker directly under input by default" ); @@ -99,21 +99,21 @@ asyncTest( "position", function(assert) { input.datepicker( "option", "position", { my: "left top", at: "right bottom" - }); + } ); assert.close( container.offset().left, input.offset().left + input.outerWidth(), 1, "datepicker on right hand side of input after position change" ); input.remove(); start(); - }); -}); + } ); +} ); test( "Stop datepicker from appearing with beforeOpen event handler", function() { expect( 3 ); var input = testHelper.init( "#datepicker", { beforeOpen: function() {} - }); + } ); input.datepicker( "open" ); ok( input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns nothing" ); @@ -123,7 +123,7 @@ test( "Stop datepicker from appearing with beforeOpen event handler", function() beforeOpen: function() { return true; } - }); + } ); input.datepicker( "open" ); ok( input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns true" ); input.datepicker( "close" ).datepicker( "destroy" ); @@ -132,10 +132,10 @@ test( "Stop datepicker from appearing with beforeOpen event handler", function() beforeOpen: function() { return false; } - }); + } ); input.datepicker( "open" ); ok( !input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns false" ); input.datepicker( "destroy" ); -}); +} ); } ); diff --git a/ui/date.js b/ui/date.js index ba92038730b..2d94f10830e 100644 --- a/ui/date.js +++ b/ui/date.js @@ -59,6 +59,7 @@ $.extend( $.ui.date.prototype, { setDay: function( day ) { var date = this.dateObject; + // FIXME: Why not to use .setDate? this.dateObject = new Date( date.getFullYear(), date.getMonth(), day, date.getHours(), date.getMinutes(), date.getSeconds() ); diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index 1cdb07fdb48..cb777ef01b4 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -195,8 +195,8 @@ return $.widget( "ui.calendar", { _setLocale: function( locale, dateFormat ) { var globalize = new Globalize( locale ), - weekdayShortFormatter = globalize.dateFormatter({ raw: "EEEEEE" }), - weekdayNarrowFormatter = globalize.dateFormatter({ raw: "EEEEE" }); + weekdayShortFormatter = globalize.dateFormatter( { raw: "EEEEEE" } ), + weekdayNarrowFormatter = globalize.dateFormatter( { raw: "EEEEE" } ); this._format = globalize.dateFormatter( dateFormat ); this._parse = globalize.dateParser( dateFormat ); @@ -209,9 +209,9 @@ return $.widget( "ui.calendar", { return shortWeekday.length > 3 ? weekdayNarrowFormatter( date ) : shortWeekday; }, - formatWeekdayFull: globalize.dateFormatter({ raw: "EEEE" }), - formatMonth: globalize.dateFormatter({ raw: "MMMM" }), - formatWeekOfYear: globalize.dateFormatter({ raw: "w" }), + formatWeekdayFull: globalize.dateFormatter( { raw: "EEEE" } ), + formatMonth: globalize.dateFormatter( { raw: "MMMM" } ), + formatWeekOfYear: globalize.dateFormatter( { raw: "w" } ), parse: this._parse }; }, @@ -539,7 +539,7 @@ return $.widget( "ui.calendar", { } if ( this.options.max !== null && months[ i ].last ) { this._disableElement( this.nextButton, - ( this.options.max.getMonth() <= months[ i].month() && + ( this.options.max.getMonth() <= months[ i ].month() && this.options.max.getFullYear() === months[ i ].year() ) || this.options.max.getFullYear() < months[ i ].year() ); diff --git a/ui/widgets/datepicker.js b/ui/widgets/datepicker.js index 5e0e47eb5d2..3534b314480 100644 --- a/ui/widgets/datepicker.js +++ b/ui/widgets/datepicker.js @@ -13,11 +13,11 @@ //>>docs: http://api.jqueryui.com/datepicker/ //>>demos: http://jqueryui.com/datepicker/ -(function( factory ) { +( function( factory ) { if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. - define([ + define( [ "jquery", "globalize", "globalize/date", @@ -32,7 +32,7 @@ // Browser globals factory( jQuery, Globalize ); } -}(function( $, Globalize ) { +}( function( $, Globalize ) { var widget = $.widget( "ui.datepicker", { version: "@VERSION", @@ -106,23 +106,24 @@ var widget = $.widget( "ui.datepicker", { that._focusTrigger(); that._trigger( "select", event ); } - }) ) + } ) ) .calendar( "instance" ); this.calendarInstance.buttonClickContext = that.element[ 0 ]; this._setHiddenPicker(); - this.element.attr({ + this.element.attr( { "aria-haspopup": true, "aria-owns": this.calendar.attr( "id" ) - }); + } ); }, _inputEvents: { 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.calendar.hide(); this.close( event ); @@ -160,7 +161,7 @@ var widget = $.widget( "ui.datepicker", { if ( !this.suppressExpandOnFocus && !this.isOpen ) { this._delay( function() { this.open( event ); - }); + } ); } this._delay( function() { this.suppressExpandOnFocus = false; @@ -173,6 +174,7 @@ var widget = $.widget( "ui.datepicker", { _calendarEvents: { 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 @@ -186,6 +188,7 @@ var widget = $.widget( "ui.datepicker", { 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.calendar.is( ":visible" ) ) { @@ -246,10 +249,10 @@ var widget = $.widget( "ui.datepicker", { this.calendarInstance.refresh(); this.calendar - .attr({ + .attr( { "aria-hidden": false, "aria-expanded": true - }) + } ) .show() .position( this._buildPosition() ) .hide(); @@ -274,10 +277,10 @@ var widget = $.widget( "ui.datepicker", { }, _setHiddenPicker: function() { - this.calendar.attr({ + this.calendar.attr( { "aria-hidden": true, "aria-expanded": false - }); + } ); }, _buildPosition: function() { @@ -351,12 +354,12 @@ var widget = $.widget( "ui.datepicker", { this.calendar.position( this._buildPosition() ); } } -}); +} ); $.each( $.ui.datepicker.prototype.calendarOptions, function( index, option ) { $.ui.datepicker.prototype.options[ option ] = $.ui.calendar.prototype.options[ option ]; -}); +} ); return widget; -})); +} ) ); From 1566cf1b3946070964d18b1b5ad1769b3913f560 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Mon, 16 Nov 2015 22:30:51 +0100 Subject: [PATCH 112/179] Calendar: Remove Globalize.cldr.supplemental.weekData dependency --- tests/unit/date/helper.js | 2 +- ui/date.js | 12 +----------- ui/widgets/calendar.js | 4 +++- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/tests/unit/date/helper.js b/tests/unit/date/helper.js index fa9c9cf663e..3c8056e6afc 100644 --- a/tests/unit/date/helper.js +++ b/tests/unit/date/helper.js @@ -12,7 +12,7 @@ return $.extend( helper, { weekdayNarrowFormatter = globalize.dateFormatter( { raw: "EEEEE" } ); return { - firstDay: globalize.cldr.supplemental.weekData.firstDay(), + firstDay: ( 6 - globalize.dateFormatter( { raw: "c" } )( new Date( 1970, 0, 3 ) ) + 1 ), formatWeekdayShort: function( date ) { // Return the short weekday if its length is < 3. Otherwise, its narrow form. diff --git a/ui/date.js b/ui/date.js index 2d94f10830e..41effff2b9e 100644 --- a/ui/date.js +++ b/ui/date.js @@ -17,16 +17,6 @@ } }( function( $ ) { -var weekdaysRev = { - "sun": 0, - "mon": 1, - "tue": 2, - "wed": 3, - "thu": 4, - "fri": 5, - "sat": 6 - }; - $.ui.date = function( date, attributes ) { if ( !( this instanceof $.ui.date ) ) { return new $.ui.date( date, attributes ); @@ -47,7 +37,7 @@ $.extend( $.ui.date.prototype, { setAttributes: function( attributes ) { this.attributes = attributes; - this.firstDay = weekdaysRev[ this.attributes.firstDay ]; + this.firstDay = this.attributes.firstDay; }, // TODO: Same as the underlying Date object's terminology, but still misleading. diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index cb777ef01b4..25bb79be4a0 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -201,7 +201,9 @@ return $.widget( "ui.calendar", { this._format = globalize.dateFormatter( dateFormat ); this._parse = globalize.dateParser( dateFormat ); this._calendarDateOptions = { - firstDay: globalize.cldr.supplemental.weekData.firstDay(), + + // Calculate localized first day of week (reference is first saturday) + firstDay: ( 6 - globalize.dateFormatter( { raw: "c" } )( new Date( 1970, 0, 3 ) ) + 1 ), formatWeekdayShort: function( date ) { // Return the short weekday if its length is < 3. Otherwise, its narrow form. From c43149d8a4c3b006f1531190232e2d61bf20e806 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Nov 2015 17:04:20 +0100 Subject: [PATCH 113/179] Calendar: Use globalize-runtime with compiled locales --- Gruntfile.js | 39 +- bower.json | 2 +- demos/bootstrap.js | 7 +- external/cldrjs/cldr.js | 13 +- external/cldrjs/cldr/event.js | 6 +- external/cldrjs/cldr/supplemental.js | 6 +- external/globalize/globalize-runtime.js | 236 + .../{globalize => globalize-runtime}/date.js | 706 +-- .../globalize/globalize-runtime/number.js | 682 +++ external/globalize/globalize/number.js | 1266 ---- external/localization.js | 5442 +---------------- package.json | 2 + 12 files changed, 1143 insertions(+), 7264 deletions(-) create mode 100644 external/globalize/globalize-runtime.js rename external/globalize/{globalize => globalize-runtime}/date.js (64%) create mode 100644 external/globalize/globalize-runtime/number.js delete mode 100644 external/globalize/globalize/number.js diff --git a/Gruntfile.js b/Gruntfile.js index 86d921a83a4..10cb371a05f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -234,9 +234,9 @@ grunt.initConfig({ "cldrjs/cldr/supplemental.js": "cldrjs/dist/cldr/supplemental.js", "cldrjs/LICENSE-MIT": "cldrjs/LICENSE-MIT", - "globalize/globalize.js": "globalize/dist/globalize.js", - "globalize/globalize/number.js": "globalize/dist/globalize/number.js", - "globalize/globalize/date.js": "globalize/dist/globalize/date.js", + "globalize/globalize-runtime.js": "globalize/dist/globalize-runtime.js", + "globalize/globalize-runtime/number.js": "globalize/dist/globalize-runtime/number.js", + "globalize/globalize-runtime/date.js": "globalize/dist/globalize-runtime/date.js", "globalize/LICENSE.txt": "globalize/LICENSE.txt", "qunit/qunit.js": "qunit/qunit/qunit.js", @@ -400,6 +400,39 @@ grunt.registerTask( "update-authors", function() { }); }); +grunt.registerTask( "compile-globalize", function() { + var formatters, + Globalize = require( "globalize" ), + globalizeCompiler = require( "globalize-compiler" ), + cldrData = require( "cldr-data" ), + languages = [ "ar", "en", "de", "es", "zh" ]; + + Globalize.load( cldrData.entireMainFor.apply( this, languages ) ); + Globalize.load( cldrData.entireSupplemental() ); + + formatters = languages.reduce( function( ret, language ) { + var globalize = Globalize( language ); + + ret = ret.concat([ + globalize.dateFormatter( { raw: "EEEEEE" } ), + globalize.dateFormatter( { raw: "EEEEE" } ), + globalize.dateFormatter( { raw: "EEEE" } ), + globalize.dateFormatter( { raw: "MMMM" } ), + globalize.dateFormatter( { raw: "w" } ), + globalize.dateFormatter( { raw: "c" } ), + globalize.dateFormatter( { date: "short" } ), + globalize.dateParser( { date: "short" } ), + globalize.dateFormatter( { date: "long" } ), + globalize.dateParser( { date: "long" } ), + globalize.numberParser() + ]); + + return ret; + }, [] ); + + grunt.file.write( "external/localization.js", globalizeCompiler.compile( formatters ) ); +}); + grunt.registerTask( "default", [ "lint", "requirejs", "test" ]); grunt.registerTask( "lint", [ "asciilint", "jshint", "jscs", "csslint", "htmllint" ]); grunt.registerTask( "test", [ "qunit" ]); diff --git a/bower.json b/bower.json index 614e4f78a03..f7b44bb3774 100644 --- a/bower.json +++ b/bower.json @@ -19,7 +19,7 @@ "qunit-assert-close": "JamesMGreene/qunit-assert-close#v1.1.1", "qunit-composite": "JamesMGreene/qunit-composite#v1.1.0", "requirejs": "2.1.14", - "globalize": "1.0.0", + "globalize": "globalize#1.1.0-rc.6", "jquery-1.7.0": "jquery#1.7.0", "jquery-1.7.1": "jquery#1.7.1", diff --git a/demos/bootstrap.js b/demos/bootstrap.js index efac1b838cf..602afa3e798 100644 --- a/demos/bootstrap.js +++ b/demos/bootstrap.js @@ -80,11 +80,16 @@ require.config( { baseUrl: window.location.pathname.indexOf( "demos/" ) !== -1 ? "../../ui" : "../../../ui", paths: { cldr: "../external/cldrjs/cldr", - globalize: "../external/globalize/globalize", + "globalize-runtime": "../external/globalize/globalize-runtime", "globalize-locales": "../external/localization", jquery: "../external/jquery/jquery", external: "../external/" }, + map: { + "*": { + "globalize": "globalize-runtime" + } + }, shim: { "external/globalize-old/globalize.culture.de-DE": [ "external/globalize-old/globalize" ], "external/globalize-old/globalize.culture.ja-JP": [ "external/globalize-old/globalize" ] diff --git a/external/cldrjs/cldr.js b/external/cldrjs/cldr.js index 5b3c637a89d..23b6c96fefe 100644 --- a/external/cldrjs/cldr.js +++ b/external/cldrjs/cldr.js @@ -1,15 +1,15 @@ /** - * CLDR JavaScript Library v0.4.1 + * CLDR JavaScript Library v0.4.3 * http://jquery.com/ * * Copyright 2013 Rafael Xavier de Souza * Released under the MIT license * http://jquery.org/license * - * Date: 2015-02-25T13:51Z + * Date: 2015-08-24T01:00Z */ /*! - * CLDR JavaScript Library v0.4.1 2015-02-25T13:51Z MIT license © Rafael Xavier + * CLDR JavaScript Library v0.4.3 2015-08-24T01:00Z MIT license © Rafael Xavier * http://git.io/h4lmVg */ (function( root, factory ) { @@ -463,12 +463,7 @@ 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" ) { + if ( prop in destination && typeof destination[ prop ] === "object" && !arrayIsArray( destination[ prop ] ) ) { // Merge Objects destination[ prop ] = merge( destination[ prop ], source[ prop ] ); diff --git a/external/cldrjs/cldr/event.js b/external/cldrjs/cldr/event.js index f9eaa368ba2..ee36d3543b5 100644 --- a/external/cldrjs/cldr/event.js +++ b/external/cldrjs/cldr/event.js @@ -1,15 +1,15 @@ /** - * CLDR JavaScript Library v0.4.1 + * CLDR JavaScript Library v0.4.3 * http://jquery.com/ * * Copyright 2013 Rafael Xavier de Souza * Released under the MIT license * http://jquery.org/license * - * Date: 2015-02-25T13:51Z + * Date: 2015-08-24T01:00Z */ /*! - * CLDR JavaScript Library v0.4.1 2015-02-25T13:51Z MIT license © Rafael Xavier + * CLDR JavaScript Library v0.4.3 2015-08-24T01:00Z MIT license © Rafael Xavier * http://git.io/h4lmVg */ (function( factory ) { diff --git a/external/cldrjs/cldr/supplemental.js b/external/cldrjs/cldr/supplemental.js index 87153683c70..821abc4bf34 100644 --- a/external/cldrjs/cldr/supplemental.js +++ b/external/cldrjs/cldr/supplemental.js @@ -1,15 +1,15 @@ /** - * CLDR JavaScript Library v0.4.1 + * CLDR JavaScript Library v0.4.3 * http://jquery.com/ * * Copyright 2013 Rafael Xavier de Souza * Released under the MIT license * http://jquery.org/license * - * Date: 2015-02-25T13:51Z + * Date: 2015-08-24T01:00Z */ /*! - * CLDR JavaScript Library v0.4.1 2015-02-25T13:51Z MIT license © Rafael Xavier + * CLDR JavaScript Library v0.4.3 2015-08-24T01:00Z MIT license © Rafael Xavier * http://git.io/h4lmVg */ (function( factory ) { diff --git a/external/globalize/globalize-runtime.js b/external/globalize/globalize-runtime.js new file mode 100644 index 00000000000..1cee1297ea8 --- /dev/null +++ b/external/globalize/globalize-runtime.js @@ -0,0 +1,236 @@ +/** + * Globalize Runtime v1.1.0-rc.6 + * + * http://github.com/jquery/globalize + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-11-18T10:38Z + */ +/*! + * Globalize Runtime v1.1.0-rc.6 2015-11-18T10:38Z Released under the MIT license + * http://git.io/TrdQbw + */ +(function( root, factory ) { + + // UMD returnExports + if ( typeof define === "function" && define.amd ) { + + // AMD + define( factory ); + } else if ( typeof exports === "object" ) { + + // Node, CommonJS + module.exports = factory(); + } else { + + // Globalize + root.Globalize = factory(); + } +}( this, function() { + + +/** + * A toString method that outputs meaningful values for objects or arrays and + * still performs as fast as a plain string in case variable is string, or as + * fast as `"" + number` in case variable is a number. + * Ref: http://jsperf.com/my-stringify + */ +var toString = function( variable ) { + return typeof variable === "string" ? variable : ( typeof variable === "number" ? "" + + variable : JSON.stringify( variable ) ); +}; + + + + +/** + * formatMessage( message, data ) + * + * @message [String] A message with optional {vars} to be replaced. + * + * @data [Array or JSON] Object with replacing-variables content. + * + * Return the formatted message. For example: + * + * - formatMessage( "{0} second", [ 1 ] ); // 1 second + * + * - formatMessage( "{0}/{1}", ["m", "s"] ); // m/s + * + * - formatMessage( "{name} <{email}>", { + * name: "Foo", + * email: "bar@baz.qux" + * }); // Foo + */ +var formatMessage = function( message, data ) { + + // Replace {attribute}'s + message = message.replace( /{[0-9a-zA-Z-_. ]+}/g, function( name ) { + name = name.replace( /^{([^}]*)}$/, "$1" ); + return toString( data[ name ] ); + }); + + return message; +}; + + + + +var objectExtend = function() { + var destination = arguments[ 0 ], + sources = [].slice.call( arguments, 1 ); + + sources.forEach(function( source ) { + var prop; + for ( prop in source ) { + destination[ prop ] = source[ prop ]; + } + }); + + return destination; +}; + + + + +var createError = function( code, message, attributes ) { + var error; + + message = code + ( message ? ": " + formatMessage( message, attributes ) : "" ); + error = new Error( message ); + error.code = code; + + objectExtend( error, attributes ); + + return error; +}; + + + + +// Based on http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery +var stringHash = function( str ) { + return [].reduce.call( str, function( hash, i ) { + var chr = i.charCodeAt( 0 ); + hash = ( ( hash << 5 ) - hash ) + chr; + return hash | 0; + }, 0 ); +}; + + + + +var runtimeKey = function( fnName, locale, args, argsStr ) { + var hash; + argsStr = argsStr || JSON.stringify( args ); + hash = stringHash( fnName + locale + argsStr ); + return hash > 0 ? "a" + hash : "b" + Math.abs( hash ); +}; + + + + +var validate = function( code, message, check, attributes ) { + if ( !check ) { + throw createError( code, message, attributes ); + } +}; + + + + +var validateParameterPresence = function( value, name ) { + validate( "E_MISSING_PARAMETER", "Missing required parameter `{name}`.", + value !== undefined, { name: name }); +}; + + + + +var validateParameterType = function( value, name, check, expected ) { + validate( + "E_INVALID_PAR_TYPE", + "Invalid `{name}` parameter ({value}). {expected} expected.", + check, + { + expected: expected, + name: name, + value: value + } + ); +}; + + + + +var validateParameterTypeString = function( value, name ) { + validateParameterType( + value, + name, + value === undefined || typeof value === "string", + "a string" + ); +}; + + + + +// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions +var regexpEscape = function( string ) { + return string.replace( /([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1" ); +}; + + + + +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; +}; + + + + +function Globalize( locale ) { + if ( !( this instanceof Globalize ) ) { + return new Globalize( locale ); + } + + validateParameterPresence( locale, "locale" ); + validateParameterTypeString( locale, "locale" ); + + this._locale = locale; +} + +Globalize.locale = function( locale ) { + validateParameterTypeString( locale, "locale" ); + + if ( arguments.length ) { + this._locale = locale; + } + return this._locale; +}; + +Globalize._createError = createError; +Globalize._formatMessage = formatMessage; +Globalize._regexpEscape = regexpEscape; +Globalize._runtimeKey = runtimeKey; +Globalize._stringPad = stringPad; +Globalize._validateParameterPresence = validateParameterPresence; +Globalize._validateParameterTypeString = validateParameterTypeString; +Globalize._validateParameterType = validateParameterType; + +return Globalize; + + + + +})); diff --git a/external/globalize/globalize/date.js b/external/globalize/globalize-runtime/date.js similarity index 64% rename from external/globalize/globalize/date.js rename to external/globalize/globalize-runtime/date.js index 9f26a105de5..118a5da0514 100644 --- a/external/globalize/globalize/date.js +++ b/external/globalize/globalize-runtime/date.js @@ -1,5 +1,5 @@ /** - * Globalize v1.0.0 + * Globalize Runtime v1.1.0-rc.6 * * http://github.com/jquery/globalize * @@ -7,10 +7,10 @@ * Released under the MIT license * http://jquery.org/license * - * Date: 2015-04-23T12:02Z + * Date: 2015-11-18T10:38Z */ /*! - * Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license + * Globalize Runtime v1.1.0-rc.6 2015-11-18T10:38Z Released under the MIT license * http://git.io/TrdQbw */ (function( root, factory ) { @@ -20,34 +20,29 @@ // AMD define([ - "cldr", - "../globalize", - "./number", - "cldr/event", - "cldr/supplemental" + "../globalize-runtime", + "./number" ], factory ); } else if ( typeof exports === "object" ) { // Node, CommonJS - module.exports = factory( require( "cldrjs" ), require( "globalize" ) ); + module.exports = factory( + require( "../globalize-runtime" ), + require( "./number" ) + ); } else { // Extend global - factory( root.Cldr, root.Globalize ); + factory( root.Globalize ); } -}(this, function( Cldr, Globalize ) { +}(this, function( Globalize ) { -var createError = Globalize._createError, - createErrorUnsupportedFeature = Globalize._createErrorUnsupportedFeature, - formatMessage = Globalize._formatMessage, - numberSymbol = Globalize._numberSymbol, +var createErrorUnsupportedFeature = Globalize._createErrorUnsupportedFeature, regexpEscape = Globalize._regexpEscape, + runtimeKey = Globalize._runtimeKey, stringPad = Globalize._stringPad, - validateCldr = Globalize._validateCldr, - validateDefaultLocale = Globalize._validateDefaultLocale, validateParameterPresence = Globalize._validateParameterPresence, validateParameterType = Globalize._validateParameterType, - validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject, validateParameterTypeString = Globalize._validateParameterTypeString; @@ -58,116 +53,6 @@ var validateParameterTypeDate = function( value, name ) { -var createErrorInvalidParameterValue = function( name, value ) { - return createError( "E_INVALID_PAR_VALUE", "Invalid `{name}` value ({value}).", { - name: name, - value: value - }); -}; - - - - -/** - * expandPattern( options, cldr ) - * - * @options [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" ); - * - raw: [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"; - * - { raw: "dd/mm" } returns "dd/mm"; - */ - -var dateExpandPattern = function( options, cldr ) { - var dateSkeleton, result, skeleton, timeSkeleton, type; - - function combineDateTime( type, datePattern, timePattern ) { - return formatMessage( - cldr.main([ - "dates/calendars/gregorian/dateTimeFormats", - type - ]), - [ timePattern, datePattern ] - ); - } - - switch ( true ) { - case "skeleton" in options: - skeleton = options.skeleton; - result = cldr.main([ - "dates/calendars/gregorian/dateTimeFormats/availableFormats", - skeleton - ]); - if ( !result ) { - timeSkeleton = skeleton.split( /[^hHKkmsSAzZOvVXx]/ ).slice( -1 )[ 0 ]; - dateSkeleton = skeleton.split( /[^GyYuUrQqMLlwWdDFgEec]/ )[ 0 ]; - if ( /(MMMM|LLLL).*[Ec]/.test( dateSkeleton ) ) { - type = "full"; - } else if ( /MMMM/g.test( dateSkeleton ) ) { - type = "long"; - } else if ( /MMM/g.test( dateSkeleton ) || /LLL/g.test( dateSkeleton ) ) { - type = "medium"; - } else { - type = "short"; - } - result = combineDateTime( type, - cldr.main([ - "dates/calendars/gregorian/dateTimeFormats/availableFormats", - dateSkeleton - ]), - cldr.main([ - "dates/calendars/gregorian/dateTimeFormats/availableFormats", - timeSkeleton - ]) - ); - } - break; - - case "date" in options: - case "time" in options: - result = cldr.main([ - "dates/calendars/gregorian", - "date" in options ? "dateFormats" : "timeFormats", - ( options.date || options.time ) - ]); - break; - - case "datetime" in options: - result = combineDateTime( options.datetime, - cldr.main([ "dates/calendars/gregorian/dateFormats", options.datetime ]), - cldr.main([ "dates/calendars/gregorian/timeFormats", options.datetime ]) - ); - break; - - case "raw" in options: - result = options.raw; - break; - - default: - throw createErrorInvalidParameterValue({ - name: "options", - value: options - }); - } - - return result; -}; - - - - /** * dayOfWeek( date, firstDay ) * @@ -249,25 +134,11 @@ var dateDayOfYear = function( date ) { -var dateWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ]; - - - - -/** - * firstDayOfWeek - */ -var dateFirstDayOfWeek = function( cldr ) { - return dateWeekDays.indexOf( cldr.supplemental.weekData.firstDay() ); -}; - - - - /** * millisecondsInDay */ var dateMillisecondsInDay = function( date ) { + // TODO Handle daylight savings discontinuities return date - dateStartOf( date, "day" ); }; @@ -275,7 +146,7 @@ var dateMillisecondsInDay = function( date ) { -var datePatternRe = (/([a-z])\1*|'([^']|'')+'|''|./ig); +var datePatternRe = ( /([a-z])\1*|'([^']|'')+'|''|./ig ); @@ -325,6 +196,11 @@ var dateTimezoneHourFormat = function( date, format, timeSeparator, formatNumber +var dateWeekDays = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ]; + + + + /** * format( date, properties ) * @@ -345,12 +221,14 @@ var dateFormat = function( date, numberFormatters, properties ) { length = current.length; if ( chr === "j" ) { + // Locale preferred hHKk. // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data chr = properties.preferredTime; } if ( chr === "Z" ) { + // Z..ZZZ: same as "xxxx". if ( length < 4 ) { chr = "x"; @@ -377,6 +255,7 @@ var dateFormat = function( date, numberFormatters, properties ) { // Year case "y": + // Plain year. // The length specifies the padding, but for two letters it also specifies the // maximum length. @@ -388,6 +267,7 @@ var dateFormat = function( date, numberFormatters, properties ) { break; case "Y": + // Year in "Week of Year" // The length specifies the padding, but for two letters it also specifies the // maximum length. @@ -426,6 +306,7 @@ var dateFormat = function( date, numberFormatters, properties ) { // 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. @@ -435,6 +316,7 @@ var dateFormat = function( date, numberFormatters, properties ) { break; case "W": + // Week of Month. // wom = ceil( ( dom + dow of `1/month` ) / 7 ) - minDaysStuff ? 1 : 0. ret = dateDayOfWeek( dateStartOf( date, "month" ), properties.firstDay ); @@ -452,6 +334,7 @@ var dateFormat = function( date, numberFormatters, properties ) { break; case "F": + // Day of Week in month. eg. 2nd Wed in July. ret = Math.floor( date.getDate() / 7 ) + 1; break; @@ -460,6 +343,7 @@ var dateFormat = function( date, numberFormatters, properties ) { 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 = dateDayOfWeek( date, properties.firstDay ) + 1; @@ -515,6 +399,7 @@ var dateFormat = function( date, numberFormatters, properties ) { // Zone case "z": case "O": + // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT". // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT". if ( date.getTimezoneOffset() === 0 ) { @@ -531,6 +416,7 @@ var dateFormat = function( date, numberFormatters, properties ) { break; case "X": + // Same as x*, except it uses "Z" for zero offset. if ( date.getTimezoneOffset() === 0 ) { ret = "Z"; @@ -539,6 +425,7 @@ var dateFormat = function( date, numberFormatters, properties ) { /* falls through */ case "x": + // x: hourFormat("+HH;-HH") // xx or xxxx: hourFormat("+HHmm;-HHmm") // xxx or xxxxx: hourFormat("+HH:mm;-HH:mm") @@ -575,233 +462,14 @@ var dateFormat = function( date, numberFormatters, properties ) { -/** - * properties( pattern, cldr ) - * - * @pattern [String] raw pattern. - * ref: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns - * - * @cldr [Cldr instance]. - * - * Return the properties given the pattern and cldr. - * - * TODO Support other calendar types. - */ -var dateFormatProperties = function( pattern, cldr ) { - var properties = { - pattern: pattern, - timeSeparator: numberSymbol( "timeSeparator", cldr ) - }, - widths = [ "abbreviated", "wide", "narrow" ]; - - function setNumberFormatterPattern( pad ) { - if ( !properties.numberFormatters ) { - properties.numberFormatters = {}; - } - properties.numberFormatters[ pad ] = stringPad( "", pad ); - } - - pattern.replace( datePatternRe, function( current ) { - var formatNumber, - chr = current.charAt( 0 ), - length = current.length; - - if ( chr === "j" ) { - // Locale preferred hHKk. - // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data - properties.preferredTime = chr = cldr.supplemental.timeData.preferred(); - } - - // ZZZZ: same as "OOOO". - if ( chr === "Z" && length === 4 ) { - chr = "O"; - length = 4; - } - - switch ( chr ) { - - // Era - case "G": - properties.eras = cldr.main([ - "dates/calendars/gregorian/eras", - length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" ) - ]); - break; - - // Year - case "y": - // Plain year. - formatNumber = true; - break; - - case "Y": - // Year in "Week of Year" - properties.firstDay = dateFirstDayOfWeek( cldr ); - properties.minDays = cldr.supplemental.weekData.minDays(); - formatNumber = true; - break; - - case "u": // Extended year. Need to be implemented. - case "U": // Cyclic year name. Need to be implemented. - throw createErrorUnsupportedFeature({ - feature: "year pattern `" + chr + "`" - }); - - // Quarter - case "Q": - case "q": - if ( length > 2 ) { - if ( !properties.quarters ) { - properties.quarters = {}; - } - if ( !properties.quarters[ chr ] ) { - properties.quarters[ chr ] = {}; - } - properties.quarters[ chr ][ length ] = cldr.main([ - "dates/calendars/gregorian/quarters", - chr === "Q" ? "format" : "stand-alone", - widths[ length - 3 ] - ]); - } else { - formatNumber = true; - } - break; - - // Month - case "M": - case "L": - if ( length > 2 ) { - if ( !properties.months ) { - properties.months = {}; - } - if ( !properties.months[ chr ] ) { - properties.months[ chr ] = {}; - } - properties.months[ chr ][ length ] = cldr.main([ - "dates/calendars/gregorian/months", - chr === "M" ? "format" : "stand-alone", - widths[ length - 3 ] - ]); - } else { - formatNumber = true; - } - break; - - // Week - Week of Year (w) or Week of Month (W). - case "w": - case "W": - properties.firstDay = dateFirstDayOfWeek( cldr ); - properties.minDays = cldr.supplemental.weekData.minDays(); - formatNumber = true; - break; - - // Day - case "d": - case "D": - case "F": - formatNumber = true; - break; - - case "g": - // Modified Julian day. Need to be implemented. - throw createErrorUnsupportedFeature({ - feature: "Julian day pattern `g`" - }); - - // Week day - case "e": - case "c": - if ( length <= 2 ) { - properties.firstDay = dateFirstDayOfWeek( cldr ); - formatNumber = true; - break; - } - - /* falls through */ - case "E": - if ( !properties.days ) { - properties.days = {}; - } - if ( !properties.days[ chr ] ) { - properties.days[ chr ] = {}; - } - 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 - properties.days[ chr ][ length ] = cldr.main([ - "dates/calendars/gregorian/days", - chr === "c" ? "stand-alone" : "format", - "short" - ]) || cldr.main([ - "dates/calendars/gregorian/days", - chr === "c" ? "stand-alone" : "format", - "abbreviated" - ]); - } else { - properties.days[ chr ][ length ] = cldr.main([ - "dates/calendars/gregorian/days", - chr === "c" ? "stand-alone" : "format", - widths[ length < 3 ? 0 : length - 3 ] - ]); - } - break; - - // Period (AM or PM) - case "a": - properties.dayPeriods = cldr.main( - "dates/calendars/gregorian/dayPeriods/format/wide" - ); - break; - - // Hour - case "h": // 1-12 - case "H": // 0-23 - case "K": // 0-11 - case "k": // 1-24 - - // Minute - case "m": - - // Second - case "s": - case "S": - case "A": - formatNumber = true; - break; - - // Zone - case "z": - case "O": - // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT". - // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT". - properties.gmtFormat = cldr.main( "dates/timeZoneNames/gmtFormat" ); - properties.gmtZeroFormat = cldr.main( "dates/timeZoneNames/gmtZeroFormat" ); - properties.tzLongHourFormat = cldr.main( "dates/timeZoneNames/hourFormat" ); - - /* falls through */ - case "Z": - case "X": - case "x": - setNumberFormatterPattern( 1 ); - setNumberFormatterPattern( 2 ); - break; - - case "v": - case "V": - throw createErrorUnsupportedFeature({ - feature: "timezone pattern `" + chr + "`" - }); - } +var dateFormatterFn = function( numberFormatters, properties ) { + return function dateFormatter( value ) { + validateParameterPresence( value, "value" ); + validateParameterTypeDate( value, "value" ); - if ( formatNumber ) { - setNumberFormatterPattern( length ); - } - }); + return dateFormat( value, numberFormatters, properties ); + }; - return properties; }; @@ -815,7 +483,7 @@ var dateFormatProperties = function( pattern, cldr ) { * Returns an indication whether the specified year is a leap year. */ var dateIsLeapYear = function( year ) { - return new Date(year, 1, 29).getMonth() === 1; + return new Date( year, 1, 29 ).getMonth() === 1; }; @@ -829,7 +497,7 @@ var dateIsLeapYear = function( year ) { * Return the last day of the given date's month */ var dateLastDayOfMonth = function( date ) { - return new Date( date.getFullYear(), date.getMonth() + 1, 0).getDate(); + return new Date( date.getFullYear(), date.getMonth() + 1, 0 ).getDate(); }; @@ -908,6 +576,7 @@ var dateParse = function( value, tokens, properties ) { var century, chr, value, length; if ( token.type === "literal" ) { + // continue return true; } @@ -916,6 +585,7 @@ var dateParse = function( value, tokens, properties ) { length = token.type.length; if ( chr === "j" ) { + // Locale preferred hHKk. // http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Data chr = properties.preferredTimeData; @@ -936,6 +606,7 @@ var dateParse = function( value, tokens, properties ) { 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; @@ -990,6 +661,7 @@ var dateParse = function( value, tokens, properties ) { break; case "F": + // Day of Week in month. eg. 2nd Wed in July. // Skip break; @@ -998,6 +670,7 @@ var dateParse = function( value, tokens, properties ) { case "e": case "c": case "E": + // Skip. // value = arrayIndexOf( dateWeekDays, token.value ); break; @@ -1104,6 +777,7 @@ var dateParse = function( value, tokens, properties ) { } if ( era === 0 ) { + // 1 BC = year 0 date.setFullYear( date.getFullYear() * -1 + 1 ); } @@ -1117,7 +791,7 @@ var dateParse = function( value, tokens, properties ) { if ( outOfRange( daysOfYear, 1, dateIsLeapYear( date.getFullYear() ) ? 366 : 365 ) ) { return null; } - date.setMonth(0); + date.setMonth( 0 ); date.setDate( daysOfYear ); } @@ -1141,22 +815,6 @@ var dateParse = function( value, tokens, properties ) { -/** - * parseProperties( cldr ) - * - * @cldr [Cldr instance]. - * - * Return parser properties. - */ -var dateParseProperties = function( cldr ) { - return { - preferredTimeData: cldr.supplemental.timeData.preferred() - }; -}; - - - - /** * Generated by: * @@ -1319,6 +977,7 @@ var dateTokenizer = function( value, numberParser, properties ) { length = current.length; if ( chr === "Z" ) { + // Z..ZZZ: same as "xxxx". if ( length < 4 ) { chr = "x"; @@ -1370,6 +1029,7 @@ var dateTokenizer = function( value, numberParser, properties ) { // Quarter case "Q": case "q": + // number l=1:{1}, l=2:{2}. // lookup l=3... oneDigitIfLengthOne() || twoDigitsIfLengthTwo() || lookup([ @@ -1382,6 +1042,7 @@ var dateTokenizer = function( value, numberParser, properties ) { // Month case "M": case "L": + // number l=1:{1,2}, l=2:{2}. // lookup l=3... oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo() || lookup([ @@ -1393,6 +1054,7 @@ var dateTokenizer = function( value, numberParser, properties ) { // Day case "D": + // number {l,3}. if ( length <= 3 ) { @@ -1404,6 +1066,7 @@ var dateTokenizer = function( value, numberParser, properties ) { case "W": case "F": + // number l=1:{1}. oneDigitIfLengthOne(); break; @@ -1411,6 +1074,7 @@ var dateTokenizer = function( value, numberParser, properties ) { // Week day case "e": case "c": + // number l=1:{1}, l=2:{2}. // lookup for length >=3. if ( length <= 2 ) { @@ -1421,6 +1085,7 @@ var dateTokenizer = function( value, numberParser, properties ) { /* 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([ @@ -1458,11 +1123,13 @@ var dateTokenizer = function( value, numberParser, properties ) { case "j": case "m": case "s": + // number l1:{1,2}, l2:{2}. oneOrTwoDigitsIfLengthOne() || twoDigitsIfLengthTwo(); break; case "S": + // number {l}. // Unicode equivalent to /\d{length}/ @@ -1471,6 +1138,7 @@ var dateTokenizer = function( value, numberParser, properties ) { break; case "A": + // number {l+5}. // Unicode equivalent to /\d{length+5}/ @@ -1481,6 +1149,7 @@ var dateTokenizer = function( value, numberParser, properties ) { // Zone case "z": case "O": + // O: "{gmtFormat}+H;{gmtFormat}-H" or "{gmtZeroFormat}", eg. "GMT-8" or "GMT". // OOOO: "{gmtFormat}{hourFormat}" or "{gmtZeroFormat}", eg. "GMT-08:00" or "GMT". if ( value === properties[ "timeZoneNames/gmtZeroFormat" ] ) { @@ -1499,6 +1168,7 @@ var dateTokenizer = function( value, numberParser, properties ) { break; case "X": + // Same as x*, except it uses "Z" for zero offset. if ( value === "Z" ) { token.value = 0; @@ -1508,6 +1178,7 @@ var dateTokenizer = function( value, numberParser, properties ) { /* falls through */ case "x": + // x: hourFormat("+HH;-HH") // xx or xxxx: hourFormat("+HHmm;-HHmm") // xxx or xxxxx: hourFormat("+HH:mm;-HH:mm") @@ -1560,258 +1231,40 @@ var dateTokenizer = function( value, numberParser, properties ) { -/** - * tokenizerProperties( pattern, cldr ) - * - * @pattern [String] raw pattern. - * - * @cldr [Cldr instance]. - * - * Return Object with data that will be used by tokenizer. - */ -var dateTokenizerProperties = function( pattern, cldr ) { - var properties = { - pattern: pattern, - timeSeparator: numberSymbol( "timeSeparator", cldr ) - }, - widths = [ "abbreviated", "wide", "narrow" ]; - - function populateProperties( path, value ) { - - // The `dates` and `calendars` trim's purpose is to reduce properties' key size only. - properties[ path.replace( /^.*\/dates\//, "" ).replace( /calendars\//, "" ) ] = value; - } - - cldr.on( "get", populateProperties ); - - pattern.match( datePatternRe ).forEach(function( current ) { - var chr, length; - - chr = current.charAt( 0 ), - length = current.length; - - if ( chr === "Z" && length < 5 ) { - chr = "O"; - length = 4; - } - - switch ( chr ) { - - // Era - case "G": - cldr.main([ - "dates/calendars/gregorian/eras", - length <= 3 ? "eraAbbr" : ( length === 4 ? "eraNames" : "eraNarrow" ) - ]); - break; - - // Year - case "u": // Extended year. Need to be implemented. - case "U": // Cyclic year name. Need to be implemented. - throw createErrorUnsupportedFeature({ - feature: "year pattern `" + chr + "`" - }); - - // Quarter - case "Q": - case "q": - if ( length > 2 ) { - cldr.main([ - "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... - if ( length > 2 ) { - cldr.main([ - "dates/calendars/gregorian/months", - chr === "M" ? "format" : "stand-alone", - widths[ length - 3 ] - ]); - } - break; - - // Day - case "g": - // Modified Julian day. Need to be implemented. - throw createErrorUnsupportedFeature({ - feature: "Julian day pattern `g`" - }); - - // Week day - case "e": - case "c": - // lookup for length >=3. - if ( length <= 2 ) { - 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 - cldr.main([ - "dates/calendars/gregorian/days", - [ chr === "c" ? "stand-alone" : "format" ], - "short" - ]) || cldr.main([ - "dates/calendars/gregorian/days", - [ chr === "c" ? "stand-alone" : "format" ], - "abbreviated" - ]); - } else { - cldr.main([ - "dates/calendars/gregorian/days", - [ chr === "c" ? "stand-alone" : "format" ], - widths[ length < 3 ? 0 : length - 3 ] - ]); - } - break; - - // Period (AM or PM) - case "a": - cldr.main([ - "dates/calendars/gregorian/dayPeriods/format/wide" - ]); - break; - - // Zone - case "z": - case "O": - cldr.main( "dates/timeZoneNames/gmtFormat" ); - cldr.main( "dates/timeZoneNames/gmtZeroFormat" ); - cldr.main( "dates/timeZoneNames/hourFormat" ); - break; - - case "v": - case "V": - throw createErrorUnsupportedFeature({ - feature: "timezone pattern `" + chr + "`" - }); - } - }); +var dateParserFn = function( numberParser, parseProperties, tokenizerProperties ) { + return function dateParser( value ) { + var tokens; - cldr.off( "get", populateProperties ); + validateParameterPresence( value, "value" ); + validateParameterTypeString( value, "value" ); - return properties; + tokens = dateTokenizer( value, numberParser, tokenizerProperties ); + return dateParse( value, tokens, parseProperties ) || null; + }; }; -function validateRequiredCldr( path, value ) { - validateCldr( path, value, { - skip: [ - /dates\/calendars\/gregorian\/dateTimeFormats\/availableFormats/, - /dates\/calendars\/gregorian\/days\/.*\/short/, - /supplemental\/timeData\/(?!001)/, - /supplemental\/weekData\/(?!001)/ - ] - }); -} +Globalize._dateFormatterFn = dateFormatterFn; +Globalize._dateParserFn = dateParserFn; +Globalize._dateFormat = dateFormat; +Globalize._dateParser = dateParse; +Globalize._dateTokenizer = dateTokenizer; +Globalize._validateParameterTypeDate = validateParameterTypeDate; -/** - * .dateFormatter( options ) - * - * @options [Object] see date/expand_pattern for more info. - * - * Return a date formatter function (of the form below) according to the given options and the - * default/instance locale. - * - * fn( value ) - * - * @value [Date] - * - * Return a function that formats a date according to the given `format` and the default/instance - * locale. - */ Globalize.dateFormatter = Globalize.prototype.dateFormatter = function( options ) { - var cldr, numberFormatters, pad, pattern, properties; - - validateParameterTypePlainObject( options, "options" ); - - cldr = this.cldr; options = options || { skeleton: "yMd" }; - - validateDefaultLocale( cldr ); - - cldr.on( "get", validateRequiredCldr ); - pattern = dateExpandPattern( options, cldr ); - properties = dateFormatProperties( pattern, cldr ); - cldr.off( "get", validateRequiredCldr ); - - // Create needed number formatters. - numberFormatters = properties.numberFormatters; - delete properties.numberFormatters; - for ( pad in numberFormatters ) { - numberFormatters[ pad ] = this.numberFormatter({ - raw: numberFormatters[ pad ] - }); - } - - return function( value ) { - validateParameterPresence( value, "value" ); - validateParameterTypeDate( value, "value" ); - return dateFormat( value, numberFormatters, properties ); - }; + return Globalize[ runtimeKey( "dateFormatter", this._locale, [ options ] ) ]; }; -/** - * .dateParser( options ) - * - * @options [Object] see date/expand_pattern for more info. - * - * Return a function that parses a string date according to the given `formats` and the - * default/instance locale. - */ Globalize.dateParser = Globalize.prototype.dateParser = function( options ) { - var cldr, numberParser, parseProperties, pattern, tokenizerProperties; - - validateParameterTypePlainObject( options, "options" ); - - cldr = this.cldr; options = options || { skeleton: "yMd" }; - - validateDefaultLocale( cldr ); - - cldr.on( "get", validateRequiredCldr ); - pattern = dateExpandPattern( options, cldr ); - tokenizerProperties = dateTokenizerProperties( pattern, cldr ); - parseProperties = dateParseProperties( cldr ); - cldr.off( "get", validateRequiredCldr ); - - numberParser = this.numberParser({ raw: "0" }); - - return function( value ) { - var tokens; - - validateParameterPresence( value, "value" ); - validateParameterTypeString( value, "value" ); - - tokens = dateTokenizer( value, numberParser, tokenizerProperties ); - return dateParse( value, tokens, parseProperties ) || null; - }; + return Globalize[ runtimeKey( "dateParser", this._locale, [ options ] ) ]; }; -/** - * .formatDate( value, options ) - * - * @value [Date] - * - * @options [Object] see date/expand_pattern for more info. - * - * Formats a date or number according to the given options string and the default/instance locale. - */ Globalize.formatDate = Globalize.prototype.formatDate = function( value, options ) { validateParameterPresence( value, "value" ); @@ -1820,15 +1273,6 @@ Globalize.prototype.formatDate = function( value, options ) { return this.dateFormatter( options )( value ); }; -/** - * .parseDate( value, options ) - * - * @value [String] - * - * @options [Object] see date/expand_pattern for more info. - * - * Return a Date instance or null. - */ Globalize.parseDate = Globalize.prototype.parseDate = function( value, options ) { validateParameterPresence( value, "value" ); diff --git a/external/globalize/globalize-runtime/number.js b/external/globalize/globalize-runtime/number.js new file mode 100644 index 00000000000..b3031471a5d --- /dev/null +++ b/external/globalize/globalize-runtime/number.js @@ -0,0 +1,682 @@ +/** + * Globalize Runtime v1.1.0-rc.6 + * + * http://github.com/jquery/globalize + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-11-18T10:38Z + */ +/*! + * Globalize Runtime v1.1.0-rc.6 2015-11-18T10:38Z Released under the MIT license + * http://git.io/TrdQbw + */ +(function( root, factory ) { + + // UMD returnExports + if ( typeof define === "function" && define.amd ) { + + // AMD + define([ + "../globalize-runtime" + ], factory ); + } else if ( typeof exports === "object" ) { + + // Node, CommonJS + module.exports = factory( require( "../globalize-runtime" ) ); + } else { + + // Extend global + factory( root.Globalize ); + } +}(this, function( Globalize ) { + +var createError = Globalize._createError, + regexpEscape = Globalize._regexpEscape, + runtimeKey = Globalize._runtimeKey, + stringPad = Globalize._stringPad, + validateParameterType = Globalize._validateParameterType, + validateParameterPresence = Globalize._validateParameterPresence, + validateParameterTypeString = Globalize._validateParameterTypeString; + + +var createErrorUnsupportedFeature = function( feature ) { + return createError( "E_UNSUPPORTED", "Unsupported {feature}.", { + feature: feature + }); +}; + + + + +var validateParameterTypeNumber = function( value, name ) { + validateParameterType( + value, + name, + value === undefined || typeof value === "number", + "Number" + ); +}; + + + + +/** + * goupingSeparator( number, primaryGroupingSize, secondaryGroupingSize ) + * + * @number [Number]. + * + * @primaryGroupingSize [Number] + * + * @secondaryGroupingSize [Number] + * + * Return the formatted number with group separator. + */ +var numberFormatGroupingSeparator = function( number, primaryGroupingSize, secondaryGroupingSize ) { + var index, + currentGroupingSize = primaryGroupingSize, + ret = "", + sep = ",", + switchToSecondary = secondaryGroupingSize ? true : false; + + number = String( number ).split( "." ); + index = number[ 0 ].length; + + while ( index > currentGroupingSize ) { + ret = number[ 0 ].slice( index - currentGroupingSize, index ) + + ( ret.length ? sep : "" ) + ret; + index -= currentGroupingSize; + if ( switchToSecondary ) { + currentGroupingSize = secondaryGroupingSize; + switchToSecondary = false; + } + } + + number[ 0 ] = number[ 0 ].slice( 0, index ) + ( ret.length ? sep : "" ) + ret; + return number.join( "." ); +}; + + + + +/** + * integerFractionDigits( number, minimumIntegerDigits, minimumFractionDigits, + * maximumFractionDigits, round, roundIncrement ) + * + * @number [Number] + * + * @minimumIntegerDigits [Number] + * + * @minimumFractionDigits [Number] + * + * @maximumFractionDigits [Number] + * + * @round [Function] + * + * @roundIncrement [Function] + * + * Return the formatted integer and fraction digits. + */ +var numberFormatIntegerFractionDigits = function( number, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, round, + roundIncrement ) { + + // Fraction + if ( maximumFractionDigits ) { + + // Rounding + if ( roundIncrement ) { + number = round( number, roundIncrement ); + + // Maximum fraction digits + } else { + number = round( number, { exponent: -maximumFractionDigits } ); + } + + // Minimum fraction digits + if ( minimumFractionDigits ) { + number = String( number ).split( "." ); + number[ 1 ] = stringPad( number[ 1 ] || "", minimumFractionDigits, true ); + number = number.join( "." ); + } + } else { + number = round( number ); + } + + number = String( number ); + + // Minimum integer digits + if ( minimumIntegerDigits ) { + number = number.split( "." ); + number[ 0 ] = stringPad( number[ 0 ], minimumIntegerDigits ); + number = number.join( "." ); + } + + return number; +}; + + + + +/** + * toPrecision( number, precision, round ) + * + * @number (Number) + * + * @precision (Number) significant figures precision (not decimal precision). + * + * @round (Function) + * + * Return number.toPrecision( precision ) using the given round function. + */ +var numberToPrecision = function( number, precision, round ) { + var roundOrder; + + // Get number at two extra significant figure precision. + number = number.toPrecision( precision + 2 ); + + // Then, round it to the required significant figure precision. + roundOrder = Math.ceil( Math.log( Math.abs( number ) ) / Math.log( 10 ) ); + roundOrder -= precision; + + return round( number, { exponent: roundOrder } ); +}; + + + + +/** + * toPrecision( number, minimumSignificantDigits, maximumSignificantDigits, round ) + * + * @number [Number] + * + * @minimumSignificantDigits [Number] + * + * @maximumSignificantDigits [Number] + * + * @round [Function] + * + * Return the formatted significant digits number. + */ +var numberFormatSignificantDigits = function( number, minimumSignificantDigits, maximumSignificantDigits, round ) { + var atMinimum, atMaximum; + + // Sanity check. + if ( minimumSignificantDigits > maximumSignificantDigits ) { + maximumSignificantDigits = minimumSignificantDigits; + } + + atMinimum = numberToPrecision( number, minimumSignificantDigits, round ); + atMaximum = numberToPrecision( number, maximumSignificantDigits, round ); + + // Use atMaximum only if it has more significant digits than atMinimum. + number = +atMinimum === +atMaximum ? atMinimum : atMaximum; + + // Expand integer numbers, eg. 123e5 to 12300. + number = ( +number ).toString( 10 ); + + if ( ( /e/ ).test( number ) ) { + throw createErrorUnsupportedFeature({ + feature: "integers out of (1e21, 1e-7)" + }); + } + + // Add trailing zeros if necessary. + if ( minimumSignificantDigits - number.replace( /^0+|\./g, "" ).length > 0 ) { + number = number.split( "." ); + number[ 1 ] = stringPad( number[ 1 ] || "", minimumSignificantDigits - number[ 0 ].replace( /^0+/, "" ).length, true ); + number = number.join( "." ); + } + + return number; +}; + + + + +/** + * format( number, properties ) + * + * @number [Number]. + * + * @properties [Object] Output of number/format-properties. + * + * Return the formatted number. + * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html + */ +var numberFormat = function( number, properties ) { + var infinitySymbol, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits, + minimumIntegerDigits, minimumSignificantDigits, nanSymbol, nuDigitsMap, padding, prefix, + primaryGroupingSize, pattern, ret, round, roundIncrement, secondaryGroupingSize, suffix, + symbolMap; + + padding = properties[ 1 ]; + minimumIntegerDigits = properties[ 2 ]; + minimumFractionDigits = properties[ 3 ]; + maximumFractionDigits = properties[ 4 ]; + minimumSignificantDigits = properties[ 5 ]; + maximumSignificantDigits = properties[ 6 ]; + roundIncrement = properties[ 7 ]; + primaryGroupingSize = properties[ 8 ]; + secondaryGroupingSize = properties[ 9 ]; + round = properties[ 15 ]; + infinitySymbol = properties[ 16 ]; + nanSymbol = properties[ 17 ]; + symbolMap = properties[ 18 ]; + nuDigitsMap = properties[ 19 ]; + + // NaN + if ( isNaN( number ) ) { + return nanSymbol; + } + + if ( number < 0 ) { + pattern = properties[ 12 ]; + prefix = properties[ 13 ]; + suffix = properties[ 14 ]; + } else { + pattern = properties[ 11 ]; + prefix = properties[ 0 ]; + suffix = properties[ 10 ]; + } + + // Infinity + if ( !isFinite( number ) ) { + return prefix + infinitySymbol + suffix; + } + + ret = prefix; + + // Percent + if ( pattern.indexOf( "%" ) !== -1 ) { + number *= 100; + + // Per mille + } else if ( pattern.indexOf( "\u2030" ) !== -1 ) { + number *= 1000; + } + + // Significant digit format + if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) { + number = numberFormatSignificantDigits( number, minimumSignificantDigits, + maximumSignificantDigits, round ); + + // Integer and fractional format + } else { + number = numberFormatIntegerFractionDigits( number, minimumIntegerDigits, + minimumFractionDigits, maximumFractionDigits, round, roundIncrement ); + } + + // Remove the possible number minus sign + number = number.replace( /^-/, "" ); + + // Grouping separators + if ( primaryGroupingSize ) { + number = numberFormatGroupingSeparator( number, primaryGroupingSize, + secondaryGroupingSize ); + } + + ret += number; + + // Scientific notation + // TODO implement here + + // Padding/'([^']|'')+'|''|[.,\-+E%\u2030]/g + // TODO implement here + + ret += suffix; + + return ret.replace( /('([^']|'')+'|'')|./g, function( character, literal ) { + + // Literals + if ( literal ) { + literal = literal.replace( /''/, "'" ); + if ( literal.length > 2 ) { + literal = literal.slice( 1, -1 ); + } + return literal; + } + + // Symbols + character = character.replace( /[.,\-+E%\u2030]/, function( symbol ) { + return symbolMap[ symbol ]; + }); + + // Numbering system + if ( nuDigitsMap ) { + character = character.replace( /[0-9]/, function( digit ) { + return nuDigitsMap[ +digit ]; + }); + } + + return character; + }); +}; + + + + +var numberFormatterFn = function( properties ) { + return function numberFormatter( value ) { + validateParameterPresence( value, "value" ); + validateParameterTypeNumber( value, "value" ); + + return numberFormat( value, properties ); + }; +}; + + + + +/** + * EBNF representation: + * + * number_pattern_re = prefix_including_padding? + * number + * scientific_notation? + * suffix? + * + * number = integer_including_group_separator fraction_including_decimal_separator + * + * integer_including_group_separator = + * regexp([0-9,]*[0-9]+) + * + * fraction_including_decimal_separator = + * regexp((\.[0-9]+)?) + + * prefix_including_padding = non_number_stuff + * + * scientific_notation = regexp(E[+-]?[0-9]+) + * + * suffix = non_number_stuff + * + * non_number_stuff = regexp([^0-9]*) + * + * + * Regexp groups: + * + * 0: number_pattern_re + * 1: prefix + * 2: integer_including_group_separator fraction_including_decimal_separator + * 3: integer_including_group_separator + * 4: fraction_including_decimal_separator + * 5: scientific_notation + * 6: suffix + */ +var numberNumberRe = ( /^([^0-9]*)(([0-9,]*[0-9]+)(\.[0-9]+)?)(E[+-]?[0-9]+)?([^0-9]*)$/ ); + + + + +/** + * parse( value, properties ) + * + * @value [String]. + * + * @properties [Object] Parser properties is a reduced pre-processed cldr + * data set returned by numberParserProperties(). + * + * Return the parsed Number (including Infinity) or NaN when value is invalid. + * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html + */ +var numberParse = function( value, properties ) { + var aux, infinitySymbol, invertedNuDigitsMap, invertedSymbolMap, localizedDigitRe, + localizedSymbolsRe, negativePrefix, negativeSuffix, number, prefix, suffix; + + infinitySymbol = properties[ 0 ]; + invertedSymbolMap = properties[ 1 ]; + negativePrefix = properties[ 2 ]; + negativeSuffix = properties[ 3 ]; + invertedNuDigitsMap = properties[ 4 ]; + + // Infinite number. + if ( aux = value.match( infinitySymbol ) ) { + + number = Infinity; + prefix = value.slice( 0, aux.length ); + suffix = value.slice( aux.length + 1 ); + + // Finite number. + } else { + + // TODO: Create it during setup, i.e., make it a property. + localizedSymbolsRe = new RegExp( + Object.keys( invertedSymbolMap ).map(function( localizedSymbol ) { + return regexpEscape( localizedSymbol ); + }).join( "|" ), + "g" + ); + + // Reverse localized symbols. + value = value.replace( localizedSymbolsRe, function( localizedSymbol ) { + return invertedSymbolMap[ localizedSymbol ]; + }); + + // Reverse localized numbering system. + if ( invertedNuDigitsMap ) { + + // TODO: Create it during setup, i.e., make it a property. + localizedDigitRe = new RegExp( + Object.keys( invertedNuDigitsMap ).map(function( localizedDigit ) { + return regexpEscape( localizedDigit ); + }).join( "|" ), + "g" + ); + value = value.replace( localizedDigitRe, function( localizedDigit ) { + return invertedNuDigitsMap[ localizedDigit ]; + }); + } + + // Add padding zero to leading decimal. + if ( value.charAt( 0 ) === "." ) { + value = "0" + value; + } + + // Is it a valid number? + value = value.match( numberNumberRe ); + if ( !value ) { + + // Invalid number. + return NaN; + } + + prefix = value[ 1 ]; + suffix = value[ 6 ]; + + // Remove grouping separators. + number = value[ 2 ].replace( /,/g, "" ); + + // Scientific notation + if ( value[ 5 ] ) { + number += value[ 5 ]; + } + + number = +number; + + // Is it a valid number? + if ( isNaN( number ) ) { + + // Invalid number. + return NaN; + } + + // Percent + if ( value[ 0 ].indexOf( "%" ) !== -1 ) { + number /= 100; + suffix = suffix.replace( "%", "" ); + + // Per mille + } else if ( value[ 0 ].indexOf( "\u2030" ) !== -1 ) { + number /= 1000; + suffix = suffix.replace( "\u2030", "" ); + } + } + + // Negative number + // "If there is an explicit negative subpattern, it serves only to specify the negative prefix + // and suffix. If there is no explicit negative subpattern, the negative subpattern is the + // localized minus sign prefixed to the positive subpattern" UTS#35 + if ( prefix === negativePrefix && suffix === negativeSuffix ) { + number *= -1; + } + + return number; +}; + + + + +var numberParserFn = function( properties ) { + return function numberParser( value ) { + validateParameterPresence( value, "value" ); + validateParameterTypeString( value, "value" ); + + return numberParse( value, properties ); + }; + +}; + + + + +var numberTruncate = function( value ) { + if ( isNaN( value ) ) { + return NaN; + } + return Math[ value < 0 ? "ceil" : "floor" ]( value ); +}; + + + + +/** + * round( method ) + * + * @method [String] with either "round", "ceil", "floor", or "truncate". + * + * Return function( value, incrementOrExp ): + * + * @value [Number] eg. 123.45. + * + * @incrementOrExp [Number] optional, eg. 0.1; or + * [Object] Either { increment: } or { exponent: } + * + * Return the rounded number, eg: + * - round( "round" )( 123.45 ): 123; + * - round( "ceil" )( 123.45 ): 124; + * - round( "floor" )( 123.45 ): 123; + * - round( "truncate" )( 123.45 ): 123; + * - round( "round" )( 123.45, 0.1 ): 123.5; + * - round( "round" )( 123.45, 10 ): 120; + * + * Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round + * Ref: #376 + */ +var numberRound = function( method ) { + method = method || "round"; + method = method === "truncate" ? numberTruncate : Math[ method ]; + + return function( value, incrementOrExp ) { + var exp, increment; + + value = +value; + + // If the value is not a number, return NaN. + if ( isNaN( value ) ) { + return NaN; + } + + // Exponent given. + if ( typeof incrementOrExp === "object" && incrementOrExp.exponent ) { + exp = +incrementOrExp.exponent; + increment = 1; + + if ( exp === 0 ) { + return method( value ); + } + + // If the exp is not an integer, return NaN. + if ( !( typeof exp === "number" && exp % 1 === 0 ) ) { + return NaN; + } + + // Increment given. + } else { + increment = +incrementOrExp || 1; + + if ( increment === 1 ) { + return method( value ); + } + + // If the increment is not a number, return NaN. + if ( isNaN( increment ) ) { + return NaN; + } + + increment = increment.toExponential().split( "e" ); + exp = +increment[ 1 ]; + increment = +increment[ 0 ]; + } + + // Shift & Round + value = value.toString().split( "e" ); + value[ 0 ] = +value[ 0 ] / increment; + value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] - exp ) : -exp; + value = method( +( value[ 0 ] + "e" + value[ 1 ] ) ); + + // Shift back + value = value.toString().split( "e" ); + value[ 0 ] = +value[ 0 ] * increment; + value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] + exp ) : exp; + return +( value[ 0 ] + "e" + value[ 1 ] ); + }; +}; + + + + +Globalize._createErrorUnsupportedFeature = createErrorUnsupportedFeature; +Globalize._numberFormat = numberFormat; +Globalize._numberFormatterFn = numberFormatterFn; +Globalize._numberParse = numberParse; +Globalize._numberParserFn = numberParserFn; +Globalize._numberRound = numberRound; +Globalize._validateParameterPresence = validateParameterPresence; +Globalize._validateParameterTypeNumber = validateParameterTypeNumber; +Globalize._validateParameterTypeString = validateParameterTypeString; + +Globalize.numberFormatter = +Globalize.prototype.numberFormatter = function( options ) { + options = options || {}; + return Globalize[ runtimeKey( "numberFormatter", this._locale, [ options ] ) ]; +}; + +Globalize.numberParser = +Globalize.prototype.numberParser = function( options ) { + options = options || {}; + return Globalize[ runtimeKey( "numberParser", this._locale, [ options ] ) ]; +}; + +Globalize.formatNumber = +Globalize.prototype.formatNumber = function( value, options ) { + validateParameterPresence( value, "value" ); + validateParameterTypeNumber( value, "value" ); + + return this.numberFormatter( options )( value ); +}; + +Globalize.parseNumber = +Globalize.prototype.parseNumber = function( value, options ) { + validateParameterPresence( value, "value" ); + validateParameterTypeString( value, "value" ); + + return this.numberParser( options )( value ); +}; + +return Globalize; + + + + +})); diff --git a/external/globalize/globalize/number.js b/external/globalize/globalize/number.js deleted file mode 100644 index 7ab4256d48c..00000000000 --- a/external/globalize/globalize/number.js +++ /dev/null @@ -1,1266 +0,0 @@ -/** - * Globalize v1.0.0 - * - * http://github.com/jquery/globalize - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2015-04-23T12:02Z - */ -/*! - * Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license - * http://git.io/TrdQbw - */ -(function( root, factory ) { - - // UMD returnExports - if ( typeof define === "function" && define.amd ) { - - // AMD - define([ - "cldr", - "../globalize", - "cldr/event", - "cldr/supplemental" - ], factory ); - } else if ( typeof exports === "object" ) { - - // Node, CommonJS - module.exports = factory( require( "cldrjs" ), require( "globalize" ) ); - } else { - - // Global - factory( root.Cldr, root.Globalize ); - } -}(this, function( Cldr, Globalize ) { - -var createError = Globalize._createError, - objectExtend = Globalize._objectExtend, - regexpEscape = Globalize._regexpEscape, - stringPad = Globalize._stringPad, - validateCldr = Globalize._validateCldr, - validateDefaultLocale = Globalize._validateDefaultLocale, - validateParameterPresence = Globalize._validateParameterPresence, - validateParameterRange = Globalize._validateParameterRange, - validateParameterType = Globalize._validateParameterType, - validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject; - - -var createErrorUnsupportedFeature = function( feature ) { - return createError( "E_UNSUPPORTED", "Unsupported {feature}.", { - feature: feature - }); -}; - - - - -var validateParameterTypeNumber = function( value, name ) { - validateParameterType( - value, - name, - value === undefined || typeof value === "number", - "Number" - ); -}; - - - - -var validateParameterTypeString = function( value, name ) { - validateParameterType( - value, - name, - value === undefined || typeof value === "string", - "a string" - ); -}; - - - - -/** - * goupingSeparator( number, primaryGroupingSize, secondaryGroupingSize ) - * - * @number [Number]. - * - * @primaryGroupingSize [Number] - * - * @secondaryGroupingSize [Number] - * - * Return the formatted number with group separator. - */ -var numberFormatGroupingSeparator = function( number, primaryGroupingSize, secondaryGroupingSize ) { - var index, - currentGroupingSize = primaryGroupingSize, - ret = "", - sep = ",", - switchToSecondary = secondaryGroupingSize ? true : false; - - number = String( number ).split( "." ); - index = number[ 0 ].length; - - while ( index > currentGroupingSize ) { - ret = number[ 0 ].slice( index - currentGroupingSize, index ) + - ( ret.length ? sep : "" ) + ret; - index -= currentGroupingSize; - if ( switchToSecondary ) { - currentGroupingSize = secondaryGroupingSize; - switchToSecondary = false; - } - } - - number[ 0 ] = number[ 0 ].slice( 0, index ) + ( ret.length ? sep : "" ) + ret; - return number.join( "." ); -}; - - - - -/** - * integerFractionDigits( number, minimumIntegerDigits, minimumFractionDigits, - * maximumFractionDigits, round, roundIncrement ) - * - * @number [Number] - * - * @minimumIntegerDigits [Number] - * - * @minimumFractionDigits [Number] - * - * @maximumFractionDigits [Number] - * - * @round [Function] - * - * @roundIncrement [Function] - * - * Return the formatted integer and fraction digits. - */ -var numberFormatIntegerFractionDigits = function( number, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, round, - roundIncrement ) { - - // Fraction - if ( maximumFractionDigits ) { - - // Rounding - if ( roundIncrement ) { - number = round( number, roundIncrement ); - - // Maximum fraction digits - } else { - number = round( number, { exponent: -maximumFractionDigits } ); - } - - // Minimum fraction digits - if ( minimumFractionDigits ) { - number = String( number ).split( "." ); - number[ 1 ] = stringPad( number[ 1 ] || "", minimumFractionDigits, true ); - number = number.join( "." ); - } - } else { - number = round( number ); - } - - number = String( number ); - - // Minimum integer digits - if ( minimumIntegerDigits ) { - number = number.split( "." ); - number[ 0 ] = stringPad( number[ 0 ], minimumIntegerDigits ); - number = number.join( "." ); - } - - return number; -}; - - - - -/** - * toPrecision( number, precision, round ) - * - * @number (Number) - * - * @precision (Number) significant figures precision (not decimal precision). - * - * @round (Function) - * - * Return number.toPrecision( precision ) using the given round function. - */ -var numberToPrecision = function( number, precision, round ) { - var roundOrder; - - // Get number at two extra significant figure precision. - number = number.toPrecision( precision + 2 ); - - // Then, round it to the required significant figure precision. - roundOrder = Math.ceil( Math.log( Math.abs( number ) ) / Math.log( 10 ) ); - roundOrder -= precision; - - return round( number, { exponent: roundOrder } ); -}; - - - - -/** - * toPrecision( number, minimumSignificantDigits, maximumSignificantDigits, round ) - * - * @number [Number] - * - * @minimumSignificantDigits [Number] - * - * @maximumSignificantDigits [Number] - * - * @round [Function] - * - * Return the formatted significant digits number. - */ -var numberFormatSignificantDigits = function( number, minimumSignificantDigits, maximumSignificantDigits, round ) { - var atMinimum, atMaximum; - - // Sanity check. - if ( minimumSignificantDigits > maximumSignificantDigits ) { - maximumSignificantDigits = minimumSignificantDigits; - } - - atMinimum = numberToPrecision( number, minimumSignificantDigits, round ); - atMaximum = numberToPrecision( number, maximumSignificantDigits, round ); - - // Use atMaximum only if it has more significant digits than atMinimum. - number = +atMinimum === +atMaximum ? atMinimum : atMaximum; - - // Expand integer numbers, eg. 123e5 to 12300. - number = ( +number ).toString( 10 ); - - if ( (/e/).test( number ) ) { - throw createErrorUnsupportedFeature({ - feature: "integers out of (1e21, 1e-7)" - }); - } - - // Add trailing zeros if necessary. - if ( minimumSignificantDigits - number.replace( /^0+|\./g, "" ).length > 0 ) { - number = number.split( "." ); - number[ 1 ] = stringPad( number[ 1 ] || "", minimumSignificantDigits - number[ 0 ].replace( /^0+/, "" ).length, true ); - number = number.join( "." ); - } - - return number; -}; - - - - -/** - * format( number, properties ) - * - * @number [Number]. - * - * @properties [Object] Output of number/format-properties. - * - * Return the formatted number. - * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html - */ -var numberFormat = function( number, properties ) { - var infinitySymbol, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits, - minimumIntegerDigits, minimumSignificantDigits, nanSymbol, nuDigitsMap, padding, prefix, - primaryGroupingSize, pattern, ret, round, roundIncrement, secondaryGroupingSize, suffix, - symbolMap; - - padding = properties[ 1 ]; - minimumIntegerDigits = properties[ 2 ]; - minimumFractionDigits = properties[ 3 ]; - maximumFractionDigits = properties[ 4 ]; - minimumSignificantDigits = properties[ 5 ]; - maximumSignificantDigits = properties[ 6 ]; - roundIncrement = properties[ 7 ]; - primaryGroupingSize = properties[ 8 ]; - secondaryGroupingSize = properties[ 9 ]; - round = properties[ 15 ]; - infinitySymbol = properties[ 16 ]; - nanSymbol = properties[ 17 ]; - symbolMap = properties[ 18 ]; - nuDigitsMap = properties[ 19 ]; - - // NaN - if ( isNaN( number ) ) { - return nanSymbol; - } - - if ( number < 0 ) { - pattern = properties[ 12 ]; - prefix = properties[ 13 ]; - suffix = properties[ 14 ]; - } else { - pattern = properties[ 11 ]; - prefix = properties[ 0 ]; - suffix = properties[ 10 ]; - } - - // Infinity - if ( !isFinite( number ) ) { - return prefix + infinitySymbol + suffix; - } - - ret = prefix; - - // Percent - if ( pattern.indexOf( "%" ) !== -1 ) { - number *= 100; - - // Per mille - } else if ( pattern.indexOf( "\u2030" ) !== -1 ) { - number *= 1000; - } - - // Significant digit format - if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) { - number = numberFormatSignificantDigits( number, minimumSignificantDigits, - maximumSignificantDigits, round ); - - // Integer and fractional format - } else { - number = numberFormatIntegerFractionDigits( number, minimumIntegerDigits, - minimumFractionDigits, maximumFractionDigits, round, roundIncrement ); - } - - // Remove the possible number minus sign - number = number.replace( /^-/, "" ); - - // Grouping separators - if ( primaryGroupingSize ) { - number = numberFormatGroupingSeparator( number, primaryGroupingSize, - secondaryGroupingSize ); - } - - ret += number; - - // Scientific notation - // TODO implement here - - // Padding/'([^']|'')+'|''|[.,\-+E%\u2030]/g - // TODO implement here - - ret += suffix; - - return ret.replace( /('([^']|'')+'|'')|./g, function( character, literal ) { - - // Literals - if ( literal ) { - literal = literal.replace( /''/, "'" ); - if ( literal.length > 2 ) { - literal = literal.slice( 1, -1 ); - } - return literal; - } - - // Symbols - character = character.replace( /[.,\-+E%\u2030]/, function( symbol ) { - return symbolMap[ symbol ]; - }); - - // Numbering system - if ( nuDigitsMap ) { - character = character.replace( /[0-9]/, function( digit ) { - return nuDigitsMap[ +digit ]; - }); - } - - return character; - }); -}; - - - - -/** - * NumberingSystem( cldr ) - * - * - http://www.unicode.org/reports/tr35/tr35-numbers.html#otherNumberingSystems - * - http://cldr.unicode.org/index/bcp47-extension - * - http://www.unicode.org/reports/tr35/#u_Extension - */ -var numberNumberingSystem = function( cldr ) { - var nu = cldr.attributes[ "u-nu" ]; - - if ( nu ) { - if ( nu === "traditio" ) { - nu = "traditional"; - } - if ( [ "native", "traditional", "finance" ].indexOf( nu ) !== -1 ) { - - // Unicode locale extension `u-nu` is set using either (native, traditional or - // finance). So, lookup the respective locale's numberingSystem and return it. - return cldr.main([ "numbers/otherNumberingSystems", nu ]); - } - - // Unicode locale extension `u-nu` is set with an explicit numberingSystem. Return it. - return nu; - } - - // Return the default numberingSystem. - return cldr.main( "numbers/defaultNumberingSystem" ); -}; - - - - -/** - * nuMap( cldr ) - * - * @cldr [Cldr instance]. - * - * Return digits map if numbering system is different than `latn`. - */ -var numberNumberingSystemDigitsMap = function( cldr ) { - var aux, - nu = numberNumberingSystem( cldr ); - - if ( nu === "latn" ) { - return; - } - - aux = cldr.supplemental([ "numberingSystems", nu ]); - - if ( aux._type !== "numeric" ) { - throw createErrorUnsupportedFeature( "`" + aux._type + "` numbering system" ); - } - - return aux._digits; -}; - - - - -/** - * EBNF representation: - * - * number_pattern_re = prefix? - * padding? - * (integer_fraction_pattern | significant_pattern) - * scientific_notation? - * suffix? - * - * prefix = non_number_stuff - * - * padding = "*" regexp(.) - * - * integer_fraction_pattern = integer_pattern - * fraction_pattern? - * - * integer_pattern = regexp([#,]*[0,]*0+) - * - * fraction_pattern = "." regexp(0*[0-9]*#*) - * - * significant_pattern = regexp([#,]*@+#*) - * - * scientific_notation = regexp(E\+?0+) - * - * suffix = non_number_stuff - * - * non_number_stuff = regexp(('[^']+'|''|[^*#@0,.E])*) - * - * - * Regexp groups: - * - * 0: number_pattern_re - * 1: prefix - * 2: - - * 3: padding - * 4: (integer_fraction_pattern | significant_pattern) - * 5: integer_fraction_pattern - * 6: integer_pattern - * 7: fraction_pattern - * 8: significant_pattern - * 9: scientific_notation - * 10: suffix - * 11: - - */ -var numberPatternRe = (/^(('[^']+'|''|[^*#@0,.E])*)(\*.)?((([#,]*[0,]*0+)(\.0*[0-9]*#*)?)|([#,]*@+#*))(E\+?0+)?(('[^']+'|''|[^*#@0,.E])*)$/); - - - - -/** - * format( number, pattern ) - * - * @number [Number]. - * - * @pattern [String] raw pattern for numbers. - * - * Return the formatted number. - * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html - */ -var numberPatternProperties = function( pattern ) { - var aux1, aux2, fractionPattern, integerFractionOrSignificantPattern, integerPattern, - maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits, - minimumIntegerDigits, minimumSignificantDigits, padding, prefix, primaryGroupingSize, - roundIncrement, scientificNotation, secondaryGroupingSize, significantPattern, suffix; - - pattern = pattern.match( numberPatternRe ); - if ( !pattern ) { - throw new Error( "Invalid pattern: " + pattern ); - } - - prefix = pattern[ 1 ]; - padding = pattern[ 3 ]; - integerFractionOrSignificantPattern = pattern[ 4 ]; - significantPattern = pattern[ 8 ]; - scientificNotation = pattern[ 9 ]; - suffix = pattern[ 10 ]; - - // Significant digit format - if ( significantPattern ) { - significantPattern.replace( /(@+)(#*)/, function( match, minimumSignificantDigitsMatch, maximumSignificantDigitsMatch ) { - minimumSignificantDigits = minimumSignificantDigitsMatch.length; - maximumSignificantDigits = minimumSignificantDigits + - maximumSignificantDigitsMatch.length; - }); - - // Integer and fractional format - } else { - fractionPattern = pattern[ 7 ]; - integerPattern = pattern[ 6 ]; - - if ( fractionPattern ) { - - // Minimum fraction digits, and rounding. - fractionPattern.replace( /[0-9]+/, function( match ) { - minimumFractionDigits = match; - }); - if ( minimumFractionDigits ) { - roundIncrement = +( "0." + minimumFractionDigits ); - minimumFractionDigits = minimumFractionDigits.length; - } else { - minimumFractionDigits = 0; - } - - // Maximum fraction digits - // 1: ignore decimal character - maximumFractionDigits = fractionPattern.length - 1 /* 1 */; - } - - // Minimum integer digits - integerPattern.replace( /0+$/, function( match ) { - minimumIntegerDigits = match.length; - }); - } - - // Scientific notation - if ( scientificNotation ) { - throw createErrorUnsupportedFeature({ - feature: "scientific notation (not implemented)" - }); - } - - // Padding - if ( padding ) { - throw createErrorUnsupportedFeature({ - feature: "padding (not implemented)" - }); - } - - // Grouping - if ( ( aux1 = integerFractionOrSignificantPattern.lastIndexOf( "," ) ) !== -1 ) { - - // Primary grouping size is the interval between the last group separator and the end of - // the integer (or the end of the significant pattern). - aux2 = integerFractionOrSignificantPattern.split( "." )[ 0 ]; - primaryGroupingSize = aux2.length - aux1 - 1; - - // Secondary grouping size is the interval between the last two group separators. - if ( ( aux2 = integerFractionOrSignificantPattern.lastIndexOf( ",", aux1 - 1 ) ) !== -1 ) { - secondaryGroupingSize = aux1 - 1 - aux2; - } - } - - // Return: - // 0: @prefix String - // 1: @padding Array [ , ] TODO - // 2: @minimumIntegerDigits non-negative integer Number value indicating the minimum integer - // digits to be used. Numbers will be padded with leading zeroes if necessary. - // 3: @minimumFractionDigits and - // 4: @maximumFractionDigits are non-negative integer Number values indicating the minimum and - // maximum fraction digits to be used. Numbers will be rounded or padded with trailing - // zeroes if necessary. - // 5: @minimumSignificantDigits and - // 6: @maximumSignificantDigits are positive integer Number values indicating the minimum and - // maximum fraction digits to be shown. Either none or both of these properties are - // present; if they are, they override minimum and maximum integer and fraction digits - // – the formatter uses however many integer and fraction digits are required to display - // the specified number of significant digits. - // 7: @roundIncrement Decimal round increment or null - // 8: @primaryGroupingSize - // 9: @secondaryGroupingSize - // 10: @suffix String - return [ - prefix, - padding, - minimumIntegerDigits, - minimumFractionDigits, - maximumFractionDigits, - minimumSignificantDigits, - maximumSignificantDigits, - roundIncrement, - primaryGroupingSize, - secondaryGroupingSize, - suffix - ]; -}; - - - - -/** - * Symbol( name, cldr ) - * - * @name [String] Symbol name. - * - * @cldr [Cldr instance]. - * - * Return the localized symbol given its name. - */ -var numberSymbol = function( name, cldr ) { - return cldr.main([ - "numbers/symbols-numberSystem-" + numberNumberingSystem( cldr ), - name - ]); -}; - - - - -var numberSymbolName = { - ".": "decimal", - ",": "group", - "%": "percentSign", - "+": "plusSign", - "-": "minusSign", - "E": "exponential", - "\u2030": "perMille" -}; - - - - -/** - * symbolMap( cldr ) - * - * @cldr [Cldr instance]. - * - * Return the (localized symbol, pattern symbol) key value pair, eg. { - * ".": "٫", - * ",": "٬", - * "%": "٪", - * ... - * }; - */ -var numberSymbolMap = function( cldr ) { - var symbol, - symbolMap = {}; - - for ( symbol in numberSymbolName ) { - symbolMap[ symbol ] = numberSymbol( numberSymbolName[ symbol ], cldr ); - } - - return symbolMap; -}; - - - - -var numberTruncate = function( value ) { - if ( isNaN( value ) ) { - return NaN; - } - return Math[ value < 0 ? "ceil" : "floor" ]( value ); -}; - - - - -/** - * round( method ) - * - * @method [String] with either "round", "ceil", "floor", or "truncate". - * - * Return function( value, incrementOrExp ): - * - * @value [Number] eg. 123.45. - * - * @incrementOrExp [Number] optional, eg. 0.1; or - * [Object] Either { increment: } or { exponent: } - * - * Return the rounded number, eg: - * - round( "round" )( 123.45 ): 123; - * - round( "ceil" )( 123.45 ): 124; - * - round( "floor" )( 123.45 ): 123; - * - round( "truncate" )( 123.45 ): 123; - * - round( "round" )( 123.45, 0.1 ): 123.5; - * - round( "round" )( 123.45, 10 ): 120; - * - * Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round - * Ref: #376 - */ -var numberRound = function( method ) { - method = method || "round"; - method = method === "truncate" ? numberTruncate : Math[ method ]; - - return function( value, incrementOrExp ) { - var exp, increment; - - value = +value; - - // If the value is not a number, return NaN. - if ( isNaN( value ) ) { - return NaN; - } - - // Exponent given. - if ( typeof incrementOrExp === "object" && incrementOrExp.exponent ) { - exp = +incrementOrExp.exponent; - increment = 1; - - if ( exp === 0 ) { - return method( value ); - } - - // If the exp is not an integer, return NaN. - if ( !( typeof exp === "number" && exp % 1 === 0 ) ) { - return NaN; - } - - // Increment given. - } else { - increment = +incrementOrExp || 1; - - if ( increment === 1 ) { - return method( value ); - } - - // If the increment is not a number, return NaN. - if ( isNaN( increment ) ) { - return NaN; - } - - increment = increment.toExponential().split( "e" ); - exp = +increment[ 1 ]; - increment = +increment[ 0 ]; - } - - // Shift & Round - value = value.toString().split( "e" ); - value[ 0 ] = +value[ 0 ] / increment; - value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] - exp ) : -exp; - value = method( +(value[ 0 ] + "e" + value[ 1 ] ) ); - - // Shift back - value = value.toString().split( "e" ); - value[ 0 ] = +value[ 0 ] * increment; - value[ 1 ] = value[ 1 ] ? ( +value[ 1 ] + exp ) : exp; - return +( value[ 0 ] + "e" + value[ 1 ] ); - }; -}; - - - - -/** - * formatProperties( pattern, cldr [, options] ) - * - * @pattern [String] raw pattern for numbers. - * - * @cldr [Cldr instance]. - * - * @options [Object]: - * - minimumIntegerDigits [Number] - * - minimumFractionDigits, maximumFractionDigits [Number] - * - minimumSignificantDigits, maximumSignificantDigits [Number] - * - round [String] "ceil", "floor", "round" (default), or "truncate". - * - useGrouping [Boolean] default true. - * - * Return the processed properties that will be used in number/format. - * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html - */ -var numberFormatProperties = function( pattern, cldr, options ) { - var negativePattern, negativePrefix, negativeProperties, negativeSuffix, positivePattern, - properties; - - function getOptions( attribute, propertyIndex ) { - if ( attribute in options ) { - properties[ propertyIndex ] = options[ attribute ]; - } - } - - options = options || {}; - pattern = pattern.split( ";" ); - - positivePattern = pattern[ 0 ]; - - negativePattern = pattern[ 1 ] || "-" + positivePattern; - negativeProperties = numberPatternProperties( negativePattern ); - negativePrefix = negativeProperties[ 0 ]; - negativeSuffix = negativeProperties[ 10 ]; - - properties = numberPatternProperties( positivePattern ).concat([ - positivePattern, - negativePrefix + positivePattern + negativeSuffix, - negativePrefix, - negativeSuffix, - numberRound( options.round ), - numberSymbol( "infinity", cldr ), - numberSymbol( "nan", cldr ), - numberSymbolMap( cldr ), - numberNumberingSystemDigitsMap( cldr ) - ]); - - getOptions( "minimumIntegerDigits", 2 ); - getOptions( "minimumFractionDigits", 3 ); - getOptions( "maximumFractionDigits", 4 ); - getOptions( "minimumSignificantDigits", 5 ); - getOptions( "maximumSignificantDigits", 6 ); - - // Grouping separators - if ( options.useGrouping === false ) { - properties[ 8 ] = null; - } - - // Normalize number of digits if only one of either minimumFractionDigits or - // maximumFractionDigits is passed in as an option - if ( "minimumFractionDigits" in options && !( "maximumFractionDigits" in options ) ) { - // maximumFractionDigits = Math.max( minimumFractionDigits, maximumFractionDigits ); - properties[ 4 ] = Math.max( properties[ 3 ], properties[ 4 ] ); - } else if ( !( "minimumFractionDigits" in options ) && - "maximumFractionDigits" in options ) { - // minimumFractionDigits = Math.min( minimumFractionDigits, maximumFractionDigits ); - properties[ 3 ] = Math.min( properties[ 3 ], properties[ 4 ] ); - } - - // Return: - // 0-10: see number/pattern-properties. - // 11: @positivePattern [String] Positive pattern. - // 12: @negativePattern [String] Negative pattern. - // 13: @negativePrefix [String] Negative prefix. - // 14: @negativeSuffix [String] Negative suffix. - // 15: @round [Function] Round function. - // 16: @infinitySymbol [String] Infinity symbol. - // 17: @nanSymbol [String] NaN symbol. - // 18: @symbolMap [Object] A bunch of other symbols. - // 19: @nuDigitsMap [Array] Digits map if numbering system is different than `latn`. - return properties; -}; - - - - -/** - * EBNF representation: - * - * number_pattern_re = prefix_including_padding? - * number - * scientific_notation? - * suffix? - * - * number = integer_including_group_separator fraction_including_decimal_separator - * - * integer_including_group_separator = - * regexp([0-9,]*[0-9]+) - * - * fraction_including_decimal_separator = - * regexp((\.[0-9]+)?) - - * prefix_including_padding = non_number_stuff - * - * scientific_notation = regexp(E[+-]?[0-9]+) - * - * suffix = non_number_stuff - * - * non_number_stuff = regexp([^0-9]*) - * - * - * Regexp groups: - * - * 0: number_pattern_re - * 1: prefix - * 2: integer_including_group_separator fraction_including_decimal_separator - * 3: integer_including_group_separator - * 4: fraction_including_decimal_separator - * 5: scientific_notation - * 6: suffix - */ -var numberNumberRe = (/^([^0-9]*)(([0-9,]*[0-9]+)(\.[0-9]+)?)(E[+-]?[0-9]+)?([^0-9]*)$/); - - - - -/** - * parse( value, properties ) - * - * @value [String]. - * - * @properties [Object] Parser properties is a reduced pre-processed cldr - * data set returned by numberParserProperties(). - * - * Return the parsed Number (including Infinity) or NaN when value is invalid. - * ref: http://www.unicode.org/reports/tr35/tr35-numbers.html - */ -var numberParse = function( value, properties ) { - var aux, infinitySymbol, invertedNuDigitsMap, invertedSymbolMap, localizedDigitRe, - localizedSymbolsRe, negativePrefix, negativeSuffix, number, prefix, suffix; - - infinitySymbol = properties[ 0 ]; - invertedSymbolMap = properties[ 1 ]; - negativePrefix = properties[ 2 ]; - negativeSuffix = properties[ 3 ]; - invertedNuDigitsMap = properties[ 4 ]; - - // Infinite number. - if ( aux = value.match( infinitySymbol ) ) { - - number = Infinity; - prefix = value.slice( 0, aux.length ); - suffix = value.slice( aux.length + 1 ); - - // Finite number. - } else { - - // TODO: Create it during setup, i.e., make it a property. - localizedSymbolsRe = new RegExp( - Object.keys( invertedSymbolMap ).map(function( localizedSymbol ) { - return regexpEscape( localizedSymbol ); - }).join( "|" ), - "g" - ); - - // Reverse localized symbols. - value = value.replace( localizedSymbolsRe, function( localizedSymbol ) { - return invertedSymbolMap[ localizedSymbol ]; - }); - - // Reverse localized numbering system. - if ( invertedNuDigitsMap ) { - - // TODO: Create it during setup, i.e., make it a property. - localizedDigitRe = new RegExp( - Object.keys( invertedNuDigitsMap ).map(function( localizedDigit ) { - return regexpEscape( localizedDigit ); - }).join( "|" ), - "g" - ); - value = value.replace( localizedDigitRe, function( localizedDigit ) { - return invertedNuDigitsMap[ localizedDigit ]; - }); - } - - // Is it a valid number? - value = value.match( numberNumberRe ); - if ( !value ) { - - // Invalid number. - return NaN; - } - - prefix = value[ 1 ]; - suffix = value[ 6 ]; - - // Remove grouping separators. - number = value[ 2 ].replace( /,/g, "" ); - - // Scientific notation - if ( value[ 5 ] ) { - number += value[ 5 ]; - } - - number = +number; - - // Is it a valid number? - if ( isNaN( number ) ) { - - // Invalid number. - return NaN; - } - - // Percent - if ( value[ 0 ].indexOf( "%" ) !== -1 ) { - number /= 100; - suffix = suffix.replace( "%", "" ); - - // Per mille - } else if ( value[ 0 ].indexOf( "\u2030" ) !== -1 ) { - number /= 1000; - suffix = suffix.replace( "\u2030", "" ); - } - } - - // Negative number - // "If there is an explicit negative subpattern, it serves only to specify the negative prefix - // and suffix. If there is no explicit negative subpattern, the negative subpattern is the - // localized minus sign prefixed to the positive subpattern" UTS#35 - if ( prefix === negativePrefix && suffix === negativeSuffix ) { - number *= -1; - } - - return number; -}; - - - - -/** - * symbolMap( cldr ) - * - * @cldr [Cldr instance]. - * - * Return the (localized symbol, pattern symbol) key value pair, eg. { - * "٫": ".", - * "٬": ",", - * "٪": "%", - * ... - * }; - */ -var numberSymbolInvertedMap = function( cldr ) { - var symbol, - symbolMap = {}; - - for ( symbol in numberSymbolName ) { - symbolMap[ numberSymbol( numberSymbolName[ symbol ], cldr ) ] = symbol; - } - - return symbolMap; -}; - - - - -/** - * parseProperties( pattern, cldr ) - * - * @pattern [String] raw pattern for numbers. - * - * @cldr [Cldr instance]. - * - * Return parser properties, used to feed parser function. - */ -var numberParseProperties = function( pattern, cldr ) { - var invertedNuDigitsMap, invertedNuDigitsMapSanityCheck, negativePattern, negativeProperties, - nuDigitsMap = numberNumberingSystemDigitsMap( cldr ); - - pattern = pattern.split( ";" ); - negativePattern = pattern[ 1 ] || "-" + pattern[ 0 ]; - negativeProperties = numberPatternProperties( negativePattern ); - if ( nuDigitsMap ) { - invertedNuDigitsMap = nuDigitsMap.split( "" ).reduce(function( object, localizedDigit, i ) { - object[ localizedDigit ] = String( i ); - return object; - }, {} ); - invertedNuDigitsMapSanityCheck = "0123456789".split( "" ).reduce(function( object, digit ) { - object[ digit ] = "invalid"; - return object; - }, {} ); - invertedNuDigitsMap = objectExtend( - invertedNuDigitsMapSanityCheck, - invertedNuDigitsMap - ); - } - - // 0: @infinitySymbol [String] Infinity symbol. - // 1: @invertedSymbolMap [Object] Inverted symbol map augmented with sanity check. - // The sanity check prevents permissive parsing, i.e., it prevents symbols that doesn't - // belong to the localized set to pass through. This is obtained with the result of the - // inverted map object overloading symbol name map object (the remaining symbol name - // mappings will invalidate parsing, working as the sanity check). - // 2: @negativePrefix [String] Negative prefix. - // 3: @negativeSuffix [String] Negative suffix with percent or per mille stripped out. - // 4: @invertedNuDigitsMap [Object] Inverted digits map if numbering system is different than - // `latn` augmented with sanity check (similar to invertedSymbolMap). - return [ - numberSymbol( "infinity", cldr ), - objectExtend( {}, numberSymbolName, numberSymbolInvertedMap( cldr ) ), - negativeProperties[ 0 ], - negativeProperties[ 10 ].replace( "%", "" ).replace( "\u2030", "" ), - invertedNuDigitsMap - ]; -}; - - - - -/** - * Pattern( style ) - * - * @style [String] "decimal" (default) or "percent". - * - * @cldr [Cldr instance]. - */ -var numberPattern = function( style, cldr ) { - if ( style !== "decimal" && style !== "percent" ) { - throw new Error( "Invalid style" ); - } - - return cldr.main([ - "numbers", - style + "Formats-numberSystem-" + numberNumberingSystem( cldr ), - "standard" - ]); -}; - - - - -/** - * .numberFormatter( [options] ) - * - * @options [Object]: - * - style: [String] "decimal" (default) or "percent". - * - see also number/format options. - * - * Return a function that formats a number according to the given options and default/instance - * locale. - */ -Globalize.numberFormatter = -Globalize.prototype.numberFormatter = function( options ) { - var cldr, maximumFractionDigits, maximumSignificantDigits, minimumFractionDigits, - minimumIntegerDigits, minimumSignificantDigits, pattern, properties; - - validateParameterTypePlainObject( options, "options" ); - - options = options || {}; - cldr = this.cldr; - - validateDefaultLocale( cldr ); - - cldr.on( "get", validateCldr ); - - if ( options.raw ) { - pattern = options.raw; - } else { - pattern = numberPattern( options.style || "decimal", cldr ); - } - - properties = numberFormatProperties( pattern, cldr, options ); - - cldr.off( "get", validateCldr ); - - minimumIntegerDigits = properties[ 2 ]; - minimumFractionDigits = properties[ 3 ]; - maximumFractionDigits = properties[ 4 ]; - - minimumSignificantDigits = properties[ 5 ]; - maximumSignificantDigits = properties[ 6 ]; - - // Validate significant digit format properties - if ( !isNaN( minimumSignificantDigits * maximumSignificantDigits ) ) { - validateParameterRange( minimumSignificantDigits, "minimumSignificantDigits", 1, 21 ); - validateParameterRange( maximumSignificantDigits, "maximumSignificantDigits", - minimumSignificantDigits, 21 ); - - } else if ( !isNaN( minimumSignificantDigits ) || !isNaN( maximumSignificantDigits ) ) { - throw new Error( "Neither or both the minimum and maximum significant digits must be " + - "present" ); - - // Validate integer and fractional format - } else { - validateParameterRange( minimumIntegerDigits, "minimumIntegerDigits", 1, 21 ); - validateParameterRange( minimumFractionDigits, "minimumFractionDigits", 0, 20 ); - validateParameterRange( maximumFractionDigits, "maximumFractionDigits", - minimumFractionDigits, 20 ); - } - - return function( value ) { - validateParameterPresence( value, "value" ); - validateParameterTypeNumber( value, "value" ); - return numberFormat( value, properties ); - }; -}; - -/** - * .numberParser( [options] ) - * - * @options [Object]: - * - style: [String] "decimal" (default) or "percent". - * - * Return the number parser according to the default/instance locale. - */ -Globalize.numberParser = -Globalize.prototype.numberParser = function( options ) { - var cldr, pattern, properties; - - validateParameterTypePlainObject( options, "options" ); - - options = options || {}; - cldr = this.cldr; - - validateDefaultLocale( cldr ); - - cldr.on( "get", validateCldr ); - - if ( options.raw ) { - pattern = options.raw; - } else { - pattern = numberPattern( options.style || "decimal", cldr ); - } - - properties = numberParseProperties( pattern, cldr ); - - cldr.off( "get", validateCldr ); - - return function( value ) { - validateParameterPresence( value, "value" ); - validateParameterTypeString( value, "value" ); - return numberParse( value, properties ); - }; -}; - -/** - * .formatNumber( value [, options] ) - * - * @value [Number] number to be formatted. - * - * @options [Object]: see number/format-properties. - * - * Format a number according to the given options and default/instance locale. - */ -Globalize.formatNumber = -Globalize.prototype.formatNumber = function( value, options ) { - validateParameterPresence( value, "value" ); - validateParameterTypeNumber( value, "value" ); - - return this.numberFormatter( options )( value ); -}; - -/** - * .parseNumber( value [, options] ) - * - * @value [String] - * - * @options [Object]: See numberParser(). - * - * Return the parsed Number (including Infinity) or NaN when value is invalid. - */ -Globalize.parseNumber = -Globalize.prototype.parseNumber = function( value, options ) { - validateParameterPresence( value, "value" ); - validateParameterTypeString( value, "value" ); - - return this.numberParser( options )( value ); -}; - -/** - * Optimization to avoid duplicating some internal functions across modules. - */ -Globalize._createErrorUnsupportedFeature = createErrorUnsupportedFeature; -Globalize._numberNumberingSystem = numberNumberingSystem; -Globalize._numberPattern = numberPattern; -Globalize._numberSymbol = numberSymbol; -Globalize._stringPad = stringPad; -Globalize._validateParameterTypeNumber = validateParameterTypeNumber; -Globalize._validateParameterTypeString = validateParameterTypeString; - -return Globalize; - - - - -})); diff --git a/external/localization.js b/external/localization.js index 2879601f800..67ecfe83308 100644 --- a/external/localization.js +++ b/external/localization.js @@ -1,5357 +1,105 @@ -/** - * CLDR data - */ -( function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "globalize" - ], factory ); - } else { - - // Browser globals - factory( Globalize ); - } -}( function( Globalize ) { - -Globalize.load({ - "main": { - "ar": { - "identity": { - "version": { - "_cldrVersion": "27.0.1", - "_number": "$Revision: 11294 $" - }, - "generation": { - "_date": "$Date: 2015-02-23 16:50:24 -0600 (Mon, 23 Feb 2015) $" - }, - "language": "ar" - }, - "dates": { - "calendars": { - "gregorian": { - "months": { - "format": { - "abbreviated": { - "1": "يناير", - "2": "فبراير", - "3": "مارس", - "4": "أبريل", - "5": "مايو", - "6": "يونيو", - "7": "يوليو", - "8": "أغسطس", - "9": "سبتمبر", - "10": "أكتوبر", - "11": "نوفمبر", - "12": "ديسمبر" - }, - "narrow": { - "1": "ي", - "2": "ف", - "3": "م", - "4": "أ", - "5": "و", - "6": "ن", - "7": "ل", - "8": "غ", - "9": "س", - "10": "ك", - "11": "ب", - "12": "د" - }, - "wide": { - "1": "يناير", - "2": "فبراير", - "3": "مارس", - "4": "أبريل", - "5": "مايو", - "6": "يونيو", - "7": "يوليو", - "8": "أغسطس", - "9": "سبتمبر", - "10": "أكتوبر", - "11": "نوفمبر", - "12": "ديسمبر" - } - }, - "stand-alone": { - "abbreviated": { - "1": "يناير", - "2": "فبراير", - "3": "مارس", - "4": "أبريل", - "5": "مايو", - "6": "يونيو", - "7": "يوليو", - "8": "أغسطس", - "9": "سبتمبر", - "10": "أكتوبر", - "11": "نوفمبر", - "12": "ديسمبر" - }, - "narrow": { - "1": "ي", - "2": "ف", - "3": "م", - "4": "أ", - "5": "و", - "6": "ن", - "7": "ل", - "8": "غ", - "9": "س", - "10": "ك", - "11": "ب", - "12": "د" - }, - "wide": { - "1": "يناير", - "2": "فبراير", - "3": "مارس", - "4": "أبريل", - "5": "مايو", - "6": "يونيو", - "7": "يوليو", - "8": "أغسطس", - "9": "سبتمبر", - "10": "أكتوبر", - "11": "نوفمبر", - "12": "ديسمبر" - } - } - }, - "days": { - "format": { - "abbreviated": { - "sun": "الأحد", - "mon": "الاثنين", - "tue": "الثلاثاء", - "wed": "الأربعاء", - "thu": "الخميس", - "fri": "الجمعة", - "sat": "السبت" - }, - "narrow": { - "sun": "ح", - "mon": "ن", - "tue": "ث", - "wed": "ر", - "thu": "خ", - "fri": "ج", - "sat": "س" - }, - "short": { - "sun": "الأحد", - "mon": "الاثنين", - "tue": "الثلاثاء", - "wed": "الأربعاء", - "thu": "الخميس", - "fri": "الجمعة", - "sat": "السبت" - }, - "wide": { - "sun": "الأحد", - "mon": "الاثنين", - "tue": "الثلاثاء", - "wed": "الأربعاء", - "thu": "الخميس", - "fri": "الجمعة", - "sat": "السبت" - } - }, - "stand-alone": { - "abbreviated": { - "sun": "الأحد", - "mon": "الاثنين", - "tue": "الثلاثاء", - "wed": "الأربعاء", - "thu": "الخميس", - "fri": "الجمعة", - "sat": "السبت" - }, - "narrow": { - "sun": "ح", - "mon": "ن", - "tue": "ث", - "wed": "ر", - "thu": "خ", - "fri": "ج", - "sat": "س" - }, - "short": { - "sun": "الأحد", - "mon": "الاثنين", - "tue": "الثلاثاء", - "wed": "الأربعاء", - "thu": "الخميس", - "fri": "الجمعة", - "sat": "السبت" - }, - "wide": { - "sun": "الأحد", - "mon": "الاثنين", - "tue": "الثلاثاء", - "wed": "الأربعاء", - "thu": "الخميس", - "fri": "الجمعة", - "sat": "السبت" - } - } - }, - "quarters": { - "format": { - "abbreviated": { - "1": "الربع الأول", - "2": "الربع الثاني", - "3": "الربع الثالث", - "4": "الربع الرابع" - }, - "narrow": { - "1": "١", - "2": "٢", - "3": "٣", - "4": "٤" - }, - "wide": { - "1": "الربع الأول", - "2": "الربع الثاني", - "3": "الربع الثالث", - "4": "الربع الرابع" - } - }, - "stand-alone": { - "abbreviated": { - "1": "الربع الأول", - "2": "الربع الثاني", - "3": "الربع الثالث", - "4": "الربع الرابع" - }, - "narrow": { - "1": "١", - "2": "٢", - "3": "٣", - "4": "٤" - }, - "wide": { - "1": "الربع الأول", - "2": "الربع الثاني", - "3": "الربع الثالث", - "4": "الربع الرابع" - } - } - }, - "dayPeriods": { - "format": { - "abbreviated": { - "am": "ص", - "noon": "ظهرا", - "pm": "م" - }, - "narrow": { - "am": "ص", - "noon": "ظ", - "pm": "م" - }, - "wide": { - "am": "ص", - "noon": "ظهرا", - "pm": "م" - } - }, - "stand-alone": { - "abbreviated": { - "am": "ص", - "noon": "ظهرا", - "pm": "م" - }, - "narrow": { - "am": "ص", - "noon": "ظ", - "pm": "م" - }, - "wide": { - "am": "ص", - "noon": "ظهرا", - "pm": "م" - } - } - }, - "eras": { - "eraNames": { - "0": "قبل الميلاد", - "0-alt-variant": "BCE", - "1": "ميلادي", - "1-alt-variant": "بعد الميلاد" - }, - "eraAbbr": { - "0": "ق.م", - "0-alt-variant": "BCE", - "1": "م", - "1-alt-variant": "ب.م" - }, - "eraNarrow": { - "0": "ق.م", - "0-alt-variant": "BCE", - "1": "م", - "1-alt-variant": "ب.م" - } - }, - "dateFormats": { - "full": "EEEE، d MMMM، y", - "long": "d MMMM، y", - "medium": "dd‏/MM‏/y", - "short": "d‏/M‏/y" - }, - "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} {0}", - "long": "{1} {0}", - "medium": "{1} {0}", - "short": "{1} {0}", - "availableFormats": { - "E": "ccc", - "EHm": "E HH:mm", - "EHms": "E HH:mm:ss", - "Ed": "E، d", - "Ehm": "E h:mm a", - "Ehms": "E h:mm:ss a", - "Gy": "y G", - "GyMMM": "MMM y G", - "GyMMMEd": "E، d MMM، y G", - "GyMMMd": "d MMM، y G", - "H": "HH", - "Hm": "HH:mm", - "Hms": "HH:mm:ss", - "Hmsv": "HH:mm:ss v", - "Hmv": "HH:mm v", - "M": "L", - "MEd": "E، d/M", - "MMM": "LLL", - "MMMEd": "E، d MMM", - "MMMMEd": "E، d MMMM", - "MMMMd": "d MMMM", - "MMMd": "d MMM", - "MMdd": "dd‏/MM", - "Md": "d/‏M", - "d": "d", - "h": "h a", - "hm": "h:mm a", - "hms": "h:mm:ss a", - "hmsv": "h:mm:ss a v", - "hmv": "h:mm a v", - "ms": "mm:ss", - "y": "y", - "yM": "M‏/y", - "yMEd": "E، d/‏M/‏y", - "yMM": "MM‏/y", - "yMMM": "MMM y", - "yMMMEd": "E، d MMM، y", - "yMMMM": "MMMM y", - "yMMMd": "d MMM، y", - "yMd": "d‏/M‏/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}", - "H": { - "H": "HH–HH" - }, - "Hm": { - "H": "HH:mm–HH:mm", - "m": "HH:mm–HH:mm" - }, - "Hmv": { - "H": "HH:mm–HH:mm v", - "m": "HH:mm–HH:mm v" - }, - "Hv": { - "H": "HH–HH v" - }, - "M": { - "M": "M–M" - }, - "MEd": { - "M": "E، d/‏M – E، d/‏M", - "d": "E، d/‏M –‏ E، d/‏M" - }, - "MMM": { - "M": "MMM–MMM" - }, - "MMMEd": { - "M": "E، d MMM – E، d MMM", - "d": "E، d – E، d MMM" - }, - "MMMM": { - "M": "LLLL–LLLL" - }, - "MMMd": { - "M": "d MMM – d MMM", - "d": "d–d MMM" - }, - "Md": { - "M": "M/d – M/d", - "d": "M/d – M/d" - }, - "d": { - "d": "d–d" - }, - "h": { - "a": "h a – h a", - "h": "h–h a" - }, - "hm": { - "a": "h:mm a – h:mm a", - "h": "h:mm–h:mm a", - "m": "h:mm–h:mm a" - }, - "hmv": { - "a": "h:mm a – h:mm a v", - "h": "h:mm–h:mm a v", - "m": "h:mm–h:mm a v" - }, - "hv": { - "a": "h a – h a v", - "h": "h–h a v" - }, - "y": { - "y": "y–y" - }, - "yM": { - "M": "M‏/y – M‏/y", - "y": "M‏/y – M‏/y" - }, - "yMEd": { - "M": "E، d‏/M‏/y – E، d‏/M‏/y", - "d": "E، dd‏/MM‏/y – E، dd‏/MM‏/y", - "y": "E، d‏/M‏/y – E، d‏/M‏/y" - }, - "yMMM": { - "M": "MMM – MMM، y", - "y": "MMM، y – MMM، y" - }, - "yMMMEd": { - "M": "E، d MMM – E، d MMM، y", - "d": "E، d – E، d MMM، y", - "y": "E، d MMM، y – E، d MMM، y" - }, - "yMMMM": { - "M": "MMMM – MMMM، y", - "y": "MMMM، y – MMMM، y" - }, - "yMMMd": { - "M": "d MMM – d MMM، y", - "d": "d–d MMM، y", - "y": "d MMM، y – d MMM، y" - }, - "yMd": { - "M": "d‏/M‏/y – d‏/M‏/y", - "d": "d‏/M‏/y – d‏/M‏/y", - "y": "d‏/M‏/y – d‏/M‏/y" - } - } - } - } - } - }, - "numbers": { - "defaultNumberingSystem": "arab", - "otherNumberingSystems": { - "native": "arab" - }, - "minimumGroupingDigits": "1", - "symbols-numberSystem-arab": { - "decimal": "٫", - "group": "٬", - "list": "؛", - "percentSign": "٪", - "plusSign": "‏+", - "minusSign": "‏-", - "exponential": "اس", - "superscriptingExponent": "×", - "perMille": "؉", - "infinity": "∞", - "nan": "ليس رقم", - "timeSeparator": "،" - }, - "symbols-numberSystem-latn": { - "decimal": ".", - "group": ",", - "list": ";", - "percentSign": "%", - "plusSign": "‎+", - "minusSign": "‎-", - "exponential": "E", - "superscriptingExponent": "×", - "perMille": "‰", - "infinity": "∞", - "nan": "NaN", - "timeSeparator": ":" - }, - "decimalFormats-numberSystem-arab": { - "standard": "#,##0.###", - "long": { - "decimalFormat": { - "1000-count-zero": "0 ألف", - "1000-count-one": "0 ألف", - "1000-count-two": "0 ألف", - "1000-count-few": "0 ألف", - "1000-count-many": "0 ألف", - "1000-count-other": "0 ألف", - "10000-count-zero": "00 ألف", - "10000-count-one": "00 ألف", - "10000-count-two": "00 ألف", - "10000-count-few": "00 ألف", - "10000-count-many": "00 ألف", - "10000-count-other": "00 ألف", - "100000-count-zero": "000 ألف", - "100000-count-one": "000 ألف", - "100000-count-two": "000 ألف", - "100000-count-few": "000 ألف", - "100000-count-many": "000 ألف", - "100000-count-other": "000 ألف", - "1000000-count-zero": "0 مليون", - "1000000-count-one": "0 مليون", - "1000000-count-two": "0 مليون", - "1000000-count-few": "0 مليون", - "1000000-count-many": "0 مليون", - "1000000-count-other": "0 مليون", - "10000000-count-zero": "00 مليون", - "10000000-count-one": "00 مليون", - "10000000-count-two": "00 مليون", - "10000000-count-few": "00 مليون", - "10000000-count-many": "00 مليون", - "10000000-count-other": "00 مليون", - "100000000-count-zero": "000 مليون", - "100000000-count-one": "000 مليون", - "100000000-count-two": "000 مليون", - "100000000-count-few": "000 مليون", - "100000000-count-many": "000 مليون", - "100000000-count-other": "000 مليون", - "1000000000-count-zero": "0 بليون", - "1000000000-count-one": "0 بليون", - "1000000000-count-two": "0 بليون", - "1000000000-count-few": "0 بليون", - "1000000000-count-many": "0 بليون", - "1000000000-count-other": "0 بليون", - "10000000000-count-zero": "00 بليون", - "10000000000-count-one": "00 بليون", - "10000000000-count-two": "00 بليون", - "10000000000-count-few": "00 بليون", - "10000000000-count-many": "00 بليون", - "10000000000-count-other": "00 بليون", - "100000000000-count-zero": "000 بليون", - "100000000000-count-one": "000 بليون", - "100000000000-count-two": "000 بليون", - "100000000000-count-few": "000 بليون", - "100000000000-count-many": "000 بليون", - "100000000000-count-other": "000 بليون", - "1000000000000-count-zero": "0 تريليون", - "1000000000000-count-one": "0 تريليون", - "1000000000000-count-two": "0 تريليون", - "1000000000000-count-few": "0 تريليون", - "1000000000000-count-many": "0 تريليون", - "1000000000000-count-other": "0 تريليون", - "10000000000000-count-zero": "00 تريليون", - "10000000000000-count-one": "00 تريليون", - "10000000000000-count-two": "00 تريليون", - "10000000000000-count-few": "00 تريليون", - "10000000000000-count-many": "00 تريليون", - "10000000000000-count-other": "00 تريليون", - "100000000000000-count-zero": "000 تريليون", - "100000000000000-count-one": "000 تريليون", - "100000000000000-count-two": "000 تريليون", - "100000000000000-count-few": "000 تريليون", - "100000000000000-count-many": "000 تريليون", - "100000000000000-count-other": "000 تريليون" - } - }, - "short": { - "decimalFormat": { - "1000-count-zero": "0 ألف", - "1000-count-one": "0 ألف", - "1000-count-two": "0 ألف", - "1000-count-few": "0 ألف", - "1000-count-many": "0 ألف", - "1000-count-other": "0 ألف", - "10000-count-zero": "00 ألف", - "10000-count-one": "00 ألف", - "10000-count-two": "00 ألف", - "10000-count-few": "00 ألف", - "10000-count-many": "00 ألف", - "10000-count-other": "00 ألف", - "100000-count-zero": "000 ألف", - "100000-count-one": "000 ألف", - "100000-count-two": "000 ألف", - "100000-count-few": "000 ألف", - "100000-count-many": "000 ألف", - "100000-count-other": "000 ألف", - "1000000-count-zero": "0 مليو", - "1000000-count-one": "0 مليو", - "1000000-count-two": "0 مليو", - "1000000-count-few": "0 مليو", - "1000000-count-many": "0 مليو", - "1000000-count-other": "0 مليو", - "10000000-count-zero": "00 مليو", - "10000000-count-one": "00 مليو", - "10000000-count-two": "00 مليو", - "10000000-count-few": "00 مليو", - "10000000-count-many": "00 مليو", - "10000000-count-other": "00 مليو", - "100000000-count-zero": "000 مليو", - "100000000-count-one": "000 مليو", - "100000000-count-two": "000 مليو", - "100000000-count-few": "000 مليو", - "100000000-count-many": "000 مليو", - "100000000-count-other": "000 مليو", - "1000000000-count-zero": "0 بليو", - "1000000000-count-one": "0 بليو", - "1000000000-count-two": "0 بليو", - "1000000000-count-few": "0 بليو", - "1000000000-count-many": "0 بليو", - "1000000000-count-other": "0 بليو", - "10000000000-count-zero": "00 بليو", - "10000000000-count-one": "00 بليو", - "10000000000-count-two": "00 بليو", - "10000000000-count-few": "00 بليو", - "10000000000-count-many": "00 بليو", - "10000000000-count-other": "00 بليو", - "100000000000-count-zero": "000 بليو", - "100000000000-count-one": "000 بليو", - "100000000000-count-two": "000 بليو", - "100000000000-count-few": "000 بليو", - "100000000000-count-many": "000 بليو", - "100000000000-count-other": "000 بليو", - "1000000000000-count-zero": "0 ترليو", - "1000000000000-count-one": "0 ترليو", - "1000000000000-count-two": "0 ترليو", - "1000000000000-count-few": "0 ترليو", - "1000000000000-count-many": "0 ترليو", - "1000000000000-count-other": "0 ترليو", - "10000000000000-count-zero": "00 ترليو", - "10000000000000-count-one": "00 ترليو", - "10000000000000-count-two": "00 ترليو", - "10000000000000-count-few": "00 ترليو", - "10000000000000-count-many": "00 ترليو", - "10000000000000-count-other": "00 ترليو", - "100000000000000-count-zero": "000 ترليو", - "100000000000000-count-one": "000 ترليو", - "100000000000000-count-two": "000 ترليو", - "100000000000000-count-few": "000 ترليو", - "100000000000000-count-many": "000 ترليو", - "100000000000000-count-other": "000 ترليو" - } - } - }, - "decimalFormats-numberSystem-latn": { - "standard": "#,##0.###", - "long": { - "decimalFormat": { - "1000-count-zero": "0 ألف", - "1000-count-one": "0 ألف", - "1000-count-two": "0 ألف", - "1000-count-few": "0 آلاف", - "1000-count-many": "0 ألف", - "1000-count-other": "0 ألف", - "10000-count-zero": "00 ألف", - "10000-count-one": "00 ألف", - "10000-count-two": "00 ألف", - "10000-count-few": "00 ألف", - "10000-count-many": "00 ألف", - "10000-count-other": "00 ألف", - "100000-count-zero": "000 ألف", - "100000-count-one": "000 ألف", - "100000-count-two": "000 ألف", - "100000-count-few": "000 ألف", - "100000-count-many": "000 ألف", - "100000-count-other": "000 ألف", - "1000000-count-zero": "0 مليون", - "1000000-count-one": "0 مليون", - "1000000-count-two": "0 مليون", - "1000000-count-few": "0 ملايين", - "1000000-count-many": "0 مليون", - "1000000-count-other": "0 مليون", - "10000000-count-zero": "00 مليون", - "10000000-count-one": "00 مليون", - "10000000-count-two": "00 مليون", - "10000000-count-few": "00 ملايين", - "10000000-count-many": "00 مليون", - "10000000-count-other": "00 مليون", - "100000000-count-zero": "000 مليون", - "100000000-count-one": "000 مليون", - "100000000-count-two": "000 مليون", - "100000000-count-few": "000 مليون", - "100000000-count-many": "000 مليون", - "100000000-count-other": "000 مليون", - "1000000000-count-zero": "0 بليون", - "1000000000-count-one": "0 بليون", - "1000000000-count-two": "0 بليون", - "1000000000-count-few": "0 بلايين", - "1000000000-count-many": "0 بليون", - "1000000000-count-other": "0 بليون", - "10000000000-count-zero": "00 بليون", - "10000000000-count-one": "00 بليون", - "10000000000-count-two": "00 بليون", - "10000000000-count-few": "00 بليون", - "10000000000-count-many": "00 بليون", - "10000000000-count-other": "00 بليون", - "100000000000-count-zero": "000 بليون", - "100000000000-count-one": "000 بليون", - "100000000000-count-two": "000 بليون", - "100000000000-count-few": "000 بليون", - "100000000000-count-many": "000 بليون", - "100000000000-count-other": "000 بليون", - "1000000000000-count-zero": "0 تريليون", - "1000000000000-count-one": "0 تريليون", - "1000000000000-count-two": "0 تريليون", - "1000000000000-count-few": "0 تريليونات", - "1000000000000-count-many": "0 تريليون", - "1000000000000-count-other": "0 تريليون", - "10000000000000-count-zero": "00 تريليون", - "10000000000000-count-one": "00 تريليون", - "10000000000000-count-two": "00 تريليون", - "10000000000000-count-few": "00 تريليون", - "10000000000000-count-many": "00 تريليون", - "10000000000000-count-other": "00 تريليون", - "100000000000000-count-zero": "000 تريليون", - "100000000000000-count-one": "000 تريليون", - "100000000000000-count-two": "000 تريليون", - "100000000000000-count-few": "000 تريليون", - "100000000000000-count-many": "000 تريليون", - "100000000000000-count-other": "000 تريليون" - } - }, - "short": { - "decimalFormat": { - "1000-count-zero": "0 ألف", - "1000-count-one": "0 ألف", - "1000-count-two": "0 ألف", - "1000-count-few": "0 آلاف", - "1000-count-many": "0 ألف", - "1000-count-other": "0 ألف", - "10000-count-zero": "00 ألف", - "10000-count-one": "00 ألف", - "10000-count-two": "00 ألف", - "10000-count-few": "00 ألف", - "10000-count-many": "00 ألف", - "10000-count-other": "00 ألف", - "100000-count-zero": "000 ألف", - "100000-count-one": "000 ألف", - "100000-count-two": "000 ألف", - "100000-count-few": "000 ألف", - "100000-count-many": "000 ألف", - "100000-count-other": "000 ألف", - "1000000-count-zero": "0 مليو", - "1000000-count-one": "0 مليو", - "1000000-count-two": "0 مليو", - "1000000-count-few": "0 مليو", - "1000000-count-many": "0 مليو", - "1000000-count-other": "0 مليو", - "10000000-count-zero": "00 مليو", - "10000000-count-one": "00 مليو", - "10000000-count-two": "00 مليو", - "10000000-count-few": "00 مليو", - "10000000-count-many": "00 مليو", - "10000000-count-other": "00 مليو", - "100000000-count-zero": "000 مليو", - "100000000-count-one": "000 مليو", - "100000000-count-two": "000 مليو", - "100000000-count-few": "000 مليو", - "100000000-count-many": "000 مليو", - "100000000-count-other": "000 مليو", - "1000000000-count-zero": "0 بليو", - "1000000000-count-one": "0 بليو", - "1000000000-count-two": "0 بليو", - "1000000000-count-few": "0 بليو", - "1000000000-count-many": "0 بليو", - "1000000000-count-other": "0 بليو", - "10000000000-count-zero": "00 بليو", - "10000000000-count-one": "00 بليو", - "10000000000-count-two": "00 بليو", - "10000000000-count-few": "00 بليو", - "10000000000-count-many": "00 بليو", - "10000000000-count-other": "00 بليو", - "100000000000-count-zero": "000 بليو", - "100000000000-count-one": "000 بليو", - "100000000000-count-two": "000 بليو", - "100000000000-count-few": "000 بليو", - "100000000000-count-many": "000 بليو", - "100000000000-count-other": "000 بليو", - "1000000000000-count-zero": "0 ترليو", - "1000000000000-count-one": "0 ترليو", - "1000000000000-count-two": "0 ترليو", - "1000000000000-count-few": "0 ترليو", - "1000000000000-count-many": "0 ترليو", - "1000000000000-count-other": "0 ترليو", - "10000000000000-count-zero": "00 ترليو", - "10000000000000-count-one": "00 ترليو", - "10000000000000-count-two": "00 ترليو", - "10000000000000-count-few": "00 ترليو", - "10000000000000-count-many": "00 ترليو", - "10000000000000-count-other": "00 ترليو", - "100000000000000-count-zero": "000 ترليو", - "100000000000000-count-one": "000 ترليو", - "100000000000000-count-two": "000 ترليو", - "100000000000000-count-few": "000 ترليو", - "100000000000000-count-many": "000 ترليو", - "100000000000000-count-other": "000 ترليو" - } - } - }, - "scientificFormats-numberSystem-arab": { - "standard": "#E0" - }, - "scientificFormats-numberSystem-latn": { - "standard": "#E0" - }, - "percentFormats-numberSystem-arab": { - "standard": "#,##0%" - }, - "percentFormats-numberSystem-latn": { - "standard": "#,##0%" - }, - "currencyFormats-numberSystem-arab": { - "currencySpacing": { - "beforeCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - }, - "afterCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - } - }, - "accounting": "¤#,##0.00;(¤#,##0.00)", - "standard": "¤ #,##0.00", - "unitPattern-count-zero": "{0} {1}", - "unitPattern-count-one": "{0} {1}", - "unitPattern-count-two": "{0} {1}", - "unitPattern-count-few": "{0} {1}", - "unitPattern-count-many": "{0} {1}", - "unitPattern-count-other": "{0} {1}" - }, - "currencyFormats-numberSystem-latn": { - "currencySpacing": { - "beforeCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - }, - "afterCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - } - }, - "accounting": "¤#,##0.00;(¤#,##0.00)", - "standard": "¤ #,##0.00", - "unitPattern-count-zero": "{0} {1}", - "unitPattern-count-one": "{0} {1}", - "unitPattern-count-two": "{0} {1}", - "unitPattern-count-few": "{0} {1}", - "unitPattern-count-many": "{0} {1}", - "unitPattern-count-other": "{0} {1}" - }, - "miscPatterns-numberSystem-arab": { - "atLeast": "+{0}", - "range": "{0}–{1}" - }, - "miscPatterns-numberSystem-latn": { - "atLeast": "+{0}", - "range": "{0}–{1}" - } - } - } - } -}); - -Globalize.load({ - "main": { - "es": { - "identity": { - "version": { - "_cldrVersion": "27.0.1", - "_number": "$Revision: 11321 $" - }, - "generation": { - "_date": "$Date: 2015-02-26 14:20:05 -0600 (Thu, 26 Feb 2015) $" - }, - "language": "es" - }, - "dates": { - "calendars": { - "gregorian": { - "months": { - "format": { - "abbreviated": { - "1": "ene.", - "2": "feb.", - "3": "mar.", - "4": "abr.", - "5": "may.", - "6": "jun.", - "7": "jul.", - "8": "ago.", - "9": "sept.", - "10": "oct.", - "11": "nov.", - "12": "dic." - }, - "narrow": { - "1": "E", - "2": "F", - "3": "M", - "4": "A", - "5": "M", - "6": "J", - "7": "J", - "8": "A", - "9": "S", - "10": "O", - "11": "N", - "12": "D" - }, - "wide": { - "1": "enero", - "2": "febrero", - "3": "marzo", - "4": "abril", - "5": "mayo", - "6": "junio", - "7": "julio", - "8": "agosto", - "9": "septiembre", - "10": "octubre", - "11": "noviembre", - "12": "diciembre" - } - }, - "stand-alone": { - "abbreviated": { - "1": "Ene.", - "2": "Feb.", - "3": "Mar.", - "4": "Abr.", - "5": "May.", - "6": "Jun.", - "7": "Jul.", - "8": "Ago.", - "9": "Sept.", - "10": "Oct.", - "11": "Nov.", - "12": "Dic." - }, - "narrow": { - "1": "E", - "2": "F", - "3": "M", - "4": "A", - "5": "M", - "6": "J", - "7": "J", - "8": "A", - "9": "S", - "10": "O", - "11": "N", - "12": "D" - }, - "wide": { - "1": "Enero", - "2": "Febrero", - "3": "Marzo", - "4": "Abril", - "5": "Mayo", - "6": "Junio", - "7": "Julio", - "8": "Agosto", - "9": "Septiembre", - "10": "Octubre", - "11": "Noviembre", - "12": "Diciembre" - } - } - }, - "days": { - "format": { - "abbreviated": { - "sun": "dom.", - "mon": "lun.", - "tue": "mar.", - "wed": "mié.", - "thu": "jue.", - "fri": "vie.", - "sat": "sáb." - }, - "narrow": { - "sun": "D", - "mon": "L", - "tue": "M", - "wed": "X", - "thu": "J", - "fri": "V", - "sat": "S" - }, - "short": { - "sun": "DO", - "mon": "LU", - "tue": "MA", - "wed": "MI", - "thu": "JU", - "fri": "VI", - "sat": "SA" - }, - "wide": { - "sun": "domingo", - "mon": "lunes", - "tue": "martes", - "wed": "miércoles", - "thu": "jueves", - "fri": "viernes", - "sat": "sábado" - } - }, - "stand-alone": { - "abbreviated": { - "sun": "Dom.", - "mon": "Lun.", - "tue": "Mar.", - "wed": "Mié.", - "thu": "Jue.", - "fri": "Vie.", - "sat": "Sáb." - }, - "narrow": { - "sun": "D", - "mon": "L", - "tue": "M", - "wed": "X", - "thu": "J", - "fri": "V", - "sat": "S" - }, - "short": { - "sun": "DO", - "mon": "LU", - "tue": "MA", - "wed": "MI", - "thu": "JU", - "fri": "VI", - "sat": "SA" - }, - "wide": { - "sun": "Domingo", - "mon": "Lunes", - "tue": "Martes", - "wed": "Miércoles", - "thu": "Jueves", - "fri": "Viernes", - "sat": "Sábado" - } - } - }, - "quarters": { - "format": { - "abbreviated": { - "1": "T1", - "2": "T2", - "3": "T3", - "4": "T4" - }, - "narrow": { - "1": "1", - "2": "2", - "3": "3", - "4": "4" - }, - "wide": { - "1": "1.er trimestre", - "2": "2.º trimestre", - "3": "3.er trimestre", - "4": "4.º trimestre" - } - }, - "stand-alone": { - "abbreviated": { - "1": "T1", - "2": "T2", - "3": "T3", - "4": "T4" - }, - "narrow": { - "1": "1", - "2": "2", - "3": "3", - "4": "4" - }, - "wide": { - "1": "1.er trimestre", - "2": "2.º trimestre", - "3": "3.er trimestre", - "4": "4.º trimestre" - } - } - }, - "dayPeriods": { - "format": { - "abbreviated": { - "am": "a. m.", - "noon": "mediodía", - "pm": "p. m." - }, - "narrow": { - "am": "a.m.", - "noon": "m.", - "pm": "p.m." - }, - "wide": { - "am": "a. m.", - "noon": "mediodía", - "pm": "p. m." - } - }, - "stand-alone": { - "abbreviated": { - "am": "a. m.", - "noon": "mediodía", - "pm": "p. m." - }, - "narrow": { - "am": "a.m.", - "noon": "m.", - "pm": "p.m." - }, - "wide": { - "am": "a. m.", - "noon": "mediodía", - "pm": "p. m." - } - } - }, - "eras": { - "eraNames": { - "0": "antes de Cristo", - "0-alt-variant": "antes de la era común", - "1": "después de Cristo", - "1-alt-variant": "era común" - }, - "eraAbbr": { - "0": "a. C.", - "0-alt-variant": "a. e. c.", - "1": "d. C.", - "1-alt-variant": "e. c." - }, - "eraNarrow": { - "0": "a. C.", - "0-alt-variant": "a. e. c.", - "1": "d. C.", - "1-alt-variant": "e. c." - } - }, - "dateFormats": { - "full": "EEEE, d 'de' MMMM 'de' y", - "long": "d 'de' MMMM 'de' y", - "medium": "d MMM y", - "short": "d/M/yy" - }, - "timeFormats": { - "full": "H:mm:ss (zzzz)", - "long": "H:mm:ss z", - "medium": "H:mm:ss", - "short": "H:mm" - }, - "dateTimeFormats": { - "full": "{1}, {0}", - "long": "{1}, {0}", - "medium": "{1} {0}", - "short": "{1} {0}", - "availableFormats": { - "E": "ccc", - "EHm": "E, H:mm", - "EHms": "E, H:mm:ss", - "Ed": "E d", - "Ehm": "E, h:mm a", - "Ehms": "E, h:mm:ss a", - "Gy": "y G", - "GyMMM": "MMM y G", - "GyMMMEd": "E, d MMM y G", - "GyMMMM": "MMMM 'de' y G", - "GyMMMMEd": "E, d 'de' MMMM 'de' y G", - "GyMMMMd": "d 'de' MMMM 'de' y G", - "GyMMMd": "d MMM y G", - "H": "H", - "Hm": "H:mm", - "Hms": "H:mm:ss", - "Hmsv": "H:mm:ss v", - "Hmsvvvv": "H:mm:ss (vvvv)", - "Hmv": "H:mm v", - "M": "L", - "MEd": "E, d/M", - "MMM": "LLL", - "MMMEd": "E, d MMM", - "MMMMEd": "E, d 'de' MMMM", - "MMMMd": "d 'de' MMMM", - "MMMd": "d MMM", - "MMd": "d/M", - "MMdd": "d/M", - "Md": "d/M", - "d": "d", - "h": "h a", - "hm": "h:mm a", - "hms": "h:mm:ss a", - "hmsv": "h:mm:ss a v", - "hmsvvvv": "h:mm:ss a (vvvv)", - "hmv": "h:mm a v", - "ms": "mm:ss", - "y": "y", - "yM": "M/y", - "yMEd": "EEE, d/M/y", - "yMM": "M/y", - "yMMM": "MMM y", - "yMMMEd": "EEE, d MMM y", - "yMMMM": "MMMM 'de' y", - "yMMMMEd": "EEE, d 'de' MMMM 'de' y", - "yMMMMd": "d 'de' MMMM 'de' y", - "yMMMd": "d MMM y", - "yMd": "d/M/y", - "yQQQ": "QQQ y", - "yQQQQ": "QQQQ 'de' 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}", - "H": { - "H": "H–H" - }, - "Hm": { - "H": "H:mm–H:mm", - "m": "H:mm–H:mm" - }, - "Hmv": { - "H": "H:mm–H:mm v", - "m": "H:mm–H:mm v" - }, - "Hv": { - "H": "H–H v" - }, - "M": { - "M": "M–M" - }, - "MEd": { - "M": "E, d/M–E, d/M", - "d": "E, d/M–E, d/M" - }, - "MMM": { - "M": "MMM–MMM" - }, - "MMMEd": { - "M": "E, d MMM–E, d MMM", - "d": "E, d MMM–E, d MMM" - }, - "MMMMEd": { - "M": "E, d 'de' MMMM–E, d 'de' MMMM", - "d": "E, d 'de' MMMM–E, d 'de' MMMM" - }, - "MMMMd": { - "M": "d 'de' MMMM–d 'de' MMMM", - "d": "d–d 'de' MMMM" - }, - "MMMd": { - "M": "d MMM–d MMM", - "d": "d–d MMM" - }, - "Md": { - "M": "d/M–d/M", - "d": "d/M–d/M" - }, - "d": { - "d": "d–d" - }, - "h": { - "a": "h a–h a", - "h": "h–h a" - }, - "hm": { - "a": "h:mm a – h:mm a", - "h": "h:mm – h:mm a", - "m": "h:mm – h:mm a" - }, - "hmv": { - "a": "h:mm a–h:mm a v", - "h": "h:mm–h:mm a v", - "m": "h:mm–h:mm a v" - }, - "hv": { - "a": "h a–h a v", - "h": "h–h a v" - }, - "y": { - "y": "y–y" - }, - "yM": { - "M": "M/y–M/y", - "y": "M/y–M/y" - }, - "yMEd": { - "M": "E, d/M/y–E, d/M/y", - "d": "E, d/M/y–E, d/M/y", - "y": "E, d/M/y–E, d/M/y" - }, - "yMMM": { - "M": "MMM–MMM y", - "y": "MMM y–MMM y" - }, - "yMMMEd": { - "M": "E, d MMM–E, d MMM y", - "d": "E, d MMM–E, d MMM y", - "y": "E, d MMM y–E, d MMM y" - }, - "yMMMM": { - "M": "MMMM–MMMM 'de' y", - "y": "MMMM 'de' y–MMMM 'de' y" - }, - "yMMMMEd": { - "M": "E, d 'de' MMMM–E, d 'de' MMMM 'de' y", - "d": "E, d 'de' MMMM–E, d 'de' MMMM 'de' y", - "y": "E, d 'de' MMMM 'de' y–E, d 'de' MMMM 'de' y" - }, - "yMMMMd": { - "M": "d 'de' MMMM–d 'de' MMMM 'de' y", - "d": "d–d 'de' MMMM 'de' y", - "y": "d 'de' MMMM 'de' y–d 'de' MMMM 'de' y" - }, - "yMMMd": { - "M": "d MMM–d MMM y", - "d": "d–d MMM y", - "y": "d MMM y–d MMM y" - }, - "yMd": { - "M": "d/M/y–d/M/y", - "d": "d/M/y–d/M/y", - "y": "d/M/y–d/M/y" - } - } - } - } - } - }, - "numbers": { - "defaultNumberingSystem": "latn", - "otherNumberingSystems": { - "native": "latn" - }, - "minimumGroupingDigits": "1", - "symbols-numberSystem-latn": { - "decimal": ",", - "group": ".", - "list": ";", - "percentSign": "%", - "plusSign": "+", - "minusSign": "-", - "exponential": "E", - "superscriptingExponent": "×", - "perMille": "‰", - "infinity": "∞", - "nan": "NaN", - "timeSeparator": ":" - }, - "decimalFormats-numberSystem-latn": { - "standard": "#,##0.###", - "long": { - "decimalFormat": { - "1000-count-one": "0 mil", - "1000-count-other": "0 mil", - "10000-count-one": "00 mil", - "10000-count-other": "00 mil", - "100000-count-one": "000 mil", - "100000-count-other": "000 mil", - "1000000-count-one": "0 millón", - "1000000-count-other": "0 millones", - "10000000-count-one": "00 millones", - "10000000-count-other": "00 millones", - "100000000-count-one": "000 millones", - "100000000-count-other": "000 millones", - "1000000000-count-one": "0 mil millones", - "1000000000-count-other": "0 mil millones", - "10000000000-count-one": "00 mil millones", - "10000000000-count-other": "00 mil millones", - "100000000000-count-one": "000 mil millones", - "100000000000-count-other": "000 mil millones", - "1000000000000-count-one": "0 billón", - "1000000000000-count-other": "0 billones", - "10000000000000-count-one": "00 billones", - "10000000000000-count-other": "00 billones", - "100000000000000-count-one": "000 billones", - "100000000000000-count-other": "000 billones" - } - }, - "short": { - "decimalFormat": { - "1000-count-one": "0 K", - "1000-count-other": "0 K", - "10000-count-one": "00 K", - "10000-count-other": "00 K", - "100000-count-one": "000 K", - "100000-count-other": "000 K", - "1000000-count-one": "0 M", - "1000000-count-other": "0 M", - "10000000-count-one": "00 M", - "10000000-count-other": "00 M", - "100000000-count-one": "000 M", - "100000000-count-other": "000 M", - "1000000000-count-one": "0000 M", - "1000000000-count-other": "0000 M", - "10000000000-count-one": "00 MRD", - "10000000000-count-other": "00 MRD", - "100000000000-count-one": "000 MRD", - "100000000000-count-other": "000 MRD", - "1000000000000-count-one": "0 B", - "1000000000000-count-other": "0 B", - "10000000000000-count-one": "00 B", - "10000000000000-count-other": "00 B", - "100000000000000-count-one": "000 B", - "100000000000000-count-other": "000 B" - } - } - }, - "scientificFormats-numberSystem-latn": { - "standard": "#E0" - }, - "percentFormats-numberSystem-latn": { - "standard": "#,##0 %" - }, - "currencyFormats-numberSystem-latn": { - "currencySpacing": { - "beforeCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - }, - "afterCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - } - }, - "accounting": "#,##0.00 ¤", - "standard": "#,##0.00 ¤", - "unitPattern-count-one": "{0} {1}", - "unitPattern-count-other": "{0} {1}" - }, - "miscPatterns-numberSystem-latn": { - "atLeast": "Más de {0}", - "range": "{0}-{1}" - } - } - } - } -}); +(function( root, factory ) { -Globalize.load({ - "main": { - "en": { - "identity": { - "version": { - "_cldrVersion": "27.0.1", - "_number": "$Revision: 11348 $" - }, - "generation": { - "_date": "$Date: 2015-03-05 01:15:52 -0600 (Thu, 05 Mar 2015) $" - }, - "language": "en" - }, - "numbers": { - "defaultNumberingSystem": "latn", - "otherNumberingSystems": { - "native": "latn" - }, - "minimumGroupingDigits": "1", - "symbols-numberSystem-latn": { - "decimal": ".", - "group": ",", - "list": ";", - "percentSign": "%", - "plusSign": "+", - "minusSign": "-", - "exponential": "E", - "superscriptingExponent": "×", - "perMille": "‰", - "infinity": "∞", - "nan": "NaN", - "timeSeparator": ":" - }, - "decimalFormats-numberSystem-latn": { - "standard": "#,##0.###", - "long": { - "decimalFormat": { - "1000-count-one": "0 thousand", - "1000-count-other": "0 thousand", - "10000-count-one": "00 thousand", - "10000-count-other": "00 thousand", - "100000-count-one": "000 thousand", - "100000-count-other": "000 thousand", - "1000000-count-one": "0 million", - "1000000-count-other": "0 million", - "10000000-count-one": "00 million", - "10000000-count-other": "00 million", - "100000000-count-one": "000 million", - "100000000-count-other": "000 million", - "1000000000-count-one": "0 billion", - "1000000000-count-other": "0 billion", - "10000000000-count-one": "00 billion", - "10000000000-count-other": "00 billion", - "100000000000-count-one": "000 billion", - "100000000000-count-other": "000 billion", - "1000000000000-count-one": "0 trillion", - "1000000000000-count-other": "0 trillion", - "10000000000000-count-one": "00 trillion", - "10000000000000-count-other": "00 trillion", - "100000000000000-count-one": "000 trillion", - "100000000000000-count-other": "000 trillion" - } - }, - "short": { - "decimalFormat": { - "1000-count-one": "0K", - "1000-count-other": "0K", - "10000-count-one": "00K", - "10000-count-other": "00K", - "100000-count-one": "000K", - "100000-count-other": "000K", - "1000000-count-one": "0M", - "1000000-count-other": "0M", - "10000000-count-one": "00M", - "10000000-count-other": "00M", - "100000000-count-one": "000M", - "100000000-count-other": "000M", - "1000000000-count-one": "0B", - "1000000000-count-other": "0B", - "10000000000-count-one": "00B", - "10000000000-count-other": "00B", - "100000000000-count-one": "000B", - "100000000000-count-other": "000B", - "1000000000000-count-one": "0T", - "1000000000000-count-other": "0T", - "10000000000000-count-one": "00T", - "10000000000000-count-other": "00T", - "100000000000000-count-one": "000T", - "100000000000000-count-other": "000T" - } - } - }, - "scientificFormats-numberSystem-latn": { - "standard": "#E0" - }, - "percentFormats-numberSystem-latn": { - "standard": "#,##0%" - }, - "currencyFormats-numberSystem-latn": { - "currencySpacing": { - "beforeCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - }, - "afterCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - } - }, - "accounting": "¤#,##0.00;(¤#,##0.00)", - "standard": "¤#,##0.00", - "unitPattern-count-one": "{0} {1}", - "unitPattern-count-other": "{0} {1}" - }, - "miscPatterns-numberSystem-latn": { - "atLeast": "{0}+", - "range": "{0}–{1}" - } - }, - "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": "am", - "noon": "noon", - "pm": "PM", - "pm-alt-variant": "pm" - }, - "narrow": { - "am": "a", - "noon": "n", - "pm": "p" - }, - "wide": { - "am": "AM", - "am-alt-variant": "am", - "noon": "noon", - "pm": "PM", - "pm-alt-variant": "pm" - } - }, - "stand-alone": { - "abbreviated": { - "am": "AM", - "am-alt-variant": "am", - "noon": "noon", - "pm": "PM", - "pm-alt-variant": "pm" - }, - "narrow": { - "am": "a", - "noon": "n", - "pm": "p" - }, - "wide": { - "am": "AM", - "am-alt-variant": "am", - "noon": "noon", - "pm": "PM", - "pm-alt-variant": "pm" - } - } - }, - "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": { - "E": "ccc", - "EHm": "E HH:mm", - "EHms": "E HH:mm:ss", - "Ed": "d E", - "Ehm": "E h:mm a", - "Ehms": "E h:mm:ss a", - "Gy": "y G", - "GyMMM": "MMM y G", - "GyMMMEd": "E, MMM d, y G", - "GyMMMd": "MMM d, y G", - "H": "HH", - "Hm": "HH:mm", - "Hms": "HH:mm:ss", - "Hmsv": "HH:mm:ss v", - "Hmv": "HH:mm v", - "M": "L", - "MEd": "E, M/d", - "MMM": "LLL", - "MMMEd": "E, MMM d", - "MMMd": "MMM d", - "Md": "M/d", - "d": "d", - "h": "h a", - "hm": "h:mm a", - "hms": "h:mm:ss a", - "hmsv": "h:mm:ss a v", - "hmv": "h:mm a v", - "ms": "mm:ss", - "y": "y", - "yM": "M/y", - "yMEd": "E, M/d/y", - "yMMM": "MMM y", - "yMMMEd": "E, MMM d, y", - "yMMMd": "MMM d, y", - "yMd": "M/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}", - "H": { - "H": "HH – HH" - }, - "Hm": { - "H": "HH:mm – HH:mm", - "m": "HH:mm – HH:mm" - }, - "Hmv": { - "H": "HH:mm – HH:mm v", - "m": "HH:mm – HH:mm v" - }, - "Hv": { - "H": "HH – HH v" - }, - "M": { - "M": "M – M" - }, - "MEd": { - "M": "E, M/d – E, M/d", - "d": "E, M/d – E, M/d" - }, - "MMM": { - "M": "MMM – MMM" - }, - "MMMEd": { - "M": "E, MMM d – E, MMM d", - "d": "E, MMM d – E, MMM d" - }, - "MMMd": { - "M": "MMM d – MMM d", - "d": "MMM d – d" - }, - "Md": { - "M": "M/d – M/d", - "d": "M/d – M/d" - }, - "d": { - "d": "d – d" - }, - "h": { - "a": "h a – h a", - "h": "h – h a" - }, - "hm": { - "a": "h:mm a – h:mm a", - "h": "h:mm – h:mm a", - "m": "h:mm – h:mm a" - }, - "hmv": { - "a": "h:mm a – h:mm a v", - "h": "h:mm – h:mm a v", - "m": "h:mm – h:mm a v" - }, - "hv": { - "a": "h a – h a v", - "h": "h – h a v" - }, - "y": { - "y": "y – y" - }, - "yM": { - "M": "M/y – M/y", - "y": "M/y – M/y" - }, - "yMEd": { - "M": "E, M/d/y – E, M/d/y", - "d": "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" - }, - "yMMMEd": { - "M": "E, MMM d – E, MMM d, y", - "d": "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" - }, - "yMMMd": { - "M": "MMM d – MMM d, y", - "d": "MMM d – d, y", - "y": "MMM d, y – MMM d, y" - }, - "yMd": { - "M": "M/d/y – M/d/y", - "d": "M/d/y – M/d/y", - "y": "M/d/y – M/d/y" - } - } - } - } - } - } - } - } -}); + // UMD returnExports + if ( typeof define === "function" && define.amd ) { -Globalize.load({ - "main": { - "de": { - "identity": { - "version": { - "_cldrVersion": "27.0.1", - "_number": "$Revision: 11304 $" - }, - "generation": { - "_date": "$Date: 2015-02-24 11:35:18 -0600 (Tue, 24 Feb 2015) $" - }, - "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": "mittags", - "pm": "nachm." - }, - "narrow": { - "am": "vm.", - "noon": "m.", - "pm": "nm." - }, - "wide": { - "afternoon": "nachmittags", - "am": "vorm.", - "earlyMorning": "morgens", - "evening": "abends", - "morning": "vormittags", - "night": "nachts", - "noon": "mittags", - "pm": "nachm." - } - }, - "stand-alone": { - "abbreviated": { - "afternoon": "nachmittags", - "am": "vorm.", - "earlyMorning": "morgens", - "evening": "abends", - "morning": "vormittags", - "night": "nachts", - "noon": "mittags", - "pm": "nachm." - }, - "narrow": { - "am": "vm.", - "noon": "m.", - "pm": "nm." - }, - "wide": { - "afternoon": "nachmittags", - "am": "vorm.", - "earlyMorning": "morgens", - "evening": "abends", - "morning": "vormittags", - "night": "nachts", - "noon": "mittags", - "pm": "nachm." - } - } - }, - "eras": { - "eraNames": { - "0": "v. Chr.", - "0-alt-variant": "vor unserer Zeitrechnung", - "1": "n. Chr.", - "1-alt-variant": "unserer 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": "v. u. Z.", - "1": "n. Chr.", - "1-alt-variant": "u. Z." - } - }, - "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} 'um' {0}", - "long": "{1} 'um' {0}", - "medium": "{1}, {0}", - "short": "{1}, {0}", - "availableFormats": { - "E": "ccc", - "EHm": "E, HH:mm", - "EHms": "E, HH:mm:ss", - "Ed": "E, d.", - "Ehm": "E h:mm a", - "Ehms": "E, h:mm:ss a", - "Gy": "y G", - "GyMMM": "MMM y G", - "GyMMMEd": "E, d. MMM y G", - "GyMMMd": "d. MMM y G", - "H": "HH 'Uhr'", - "Hm": "HH:mm", - "Hms": "HH:mm:ss", - "Hmsv": "HH:mm:ss v", - "Hmv": "HH:mm v", - "M": "L", - "MEd": "E, d.M.", - "MMM": "LLL", - "MMMEd": "E, d. MMM", - "MMMMEd": "E, d. MMMM", - "MMMd": "d. MMM", - "MMd": "d.MM.", - "MMdd": "dd.MM.", - "Md": "d.M.", - "d": "d", - "h": "h a", - "hm": "h:mm a", - "hms": "h:mm:ss a", - "hmsv": "h:mm:ss a v", - "hmv": "h:mm a v", - "ms": "mm:ss", - "y": "y", - "yM": "M.y", - "yMEd": "E, d.M.y", - "yMM": "MM.y", - "yMMM": "MMM y", - "yMMMEd": "E, d. MMM y", - "yMMMM": "MMMM y", - "yMMMd": "d. MMM y", - "yMMdd": "dd.MM.y", - "yMd": "d.M.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}", - "H": { - "H": "HH–HH 'Uhr'" - }, - "Hm": { - "H": "HH:mm–HH:mm", - "m": "HH:mm–HH:mm" - }, - "Hmv": { - "H": "HH:mm–HH:mm v", - "m": "HH:mm–HH:mm v" - }, - "Hv": { - "H": "HH–HH 'Uhr' v" - }, - "M": { - "M": "M.–M." - }, - "MEd": { - "M": "E, dd.MM. – E, dd.MM.", - "d": "E, dd.MM. – E, dd.MM." - }, - "MMM": { - "M": "MMM–MMM" - }, - "MMMEd": { - "M": "E, d. MMM – E, d. MMM", - "d": "E, d. – E, d. MMM" - }, - "MMMM": { - "M": "LLLL–LLLL" - }, - "MMMd": { - "M": "d. MMM – d. MMM", - "d": "d.–d. MMM" - }, - "Md": { - "M": "dd.MM. – dd.MM.", - "d": "dd.MM. – dd.MM." - }, - "d": { - "d": "d.–d." - }, - "h": { - "a": "h a – h a", - "h": "h–h a" - }, - "hm": { - "a": "h:mm a – h:mm a", - "h": "h:mm–h:mm a", - "m": "h:mm–h:mm a" - }, - "hmv": { - "a": "h:mm a – h:mm a v", - "h": "h:mm–h:mm a v", - "m": "h:mm–h:mm a v" - }, - "hv": { - "a": "h a – h a v", - "h": "h–h a v" - }, - "y": { - "y": "y–y" - }, - "yM": { - "M": "MM.y – MM.y", - "y": "MM.y – MM.y" - }, - "yMEd": { - "M": "E, dd.MM.y – E, dd.MM.y", - "d": "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" - }, - "yMMMEd": { - "M": "E, d. MMM – E, d. MMM y", - "d": "E, d. – E, d. MMM y", - "y": "E, d. MMM y – E, d. MMM y" - }, - "yMMMM": { - "M": "MMMM–MMMM y", - "y": "MMMM y – MMMM y" - }, - "yMMMd": { - "M": "d. MMM – d. MMM y", - "d": "d.–d. MMM y", - "y": "d. MMM y – d. MMM y" - }, - "yMd": { - "M": "dd.MM.y – dd.MM.y", - "d": "dd.MM.y – dd.MM.y", - "y": "dd.MM.y – dd.MM.y" - } - } - } - } - } - }, - "numbers": { - "defaultNumberingSystem": "latn", - "otherNumberingSystems": { - "native": "latn" - }, - "minimumGroupingDigits": "1", - "symbols-numberSystem-latn": { - "decimal": ",", - "group": ".", - "list": ";", - "percentSign": "%", - "plusSign": "+", - "minusSign": "-", - "exponential": "E", - "superscriptingExponent": "·", - "perMille": "‰", - "infinity": "∞", - "nan": "NaN", - "timeSeparator": ":" - }, - "decimalFormats-numberSystem-latn": { - "standard": "#,##0.###", - "long": { - "decimalFormat": { - "1000-count-one": "0 Tausend", - "1000-count-other": "0 Tausend", - "10000-count-one": "00 Tausend", - "10000-count-other": "00 Tausend", - "100000-count-one": "000 Tausend", - "100000-count-other": "000 Tausend", - "1000000-count-one": "0 Million", - "1000000-count-other": "0 Millionen", - "10000000-count-one": "00 Millionen", - "10000000-count-other": "00 Millionen", - "100000000-count-one": "000 Millionen", - "100000000-count-other": "000 Millionen", - "1000000000-count-one": "0 Milliarde", - "1000000000-count-other": "0 Milliarden", - "10000000000-count-one": "00 Milliarden", - "10000000000-count-other": "00 Milliarden", - "100000000000-count-one": "000 Milliarden", - "100000000000-count-other": "000 Milliarden", - "1000000000000-count-one": "0 Billion", - "1000000000000-count-other": "0 Billionen", - "10000000000000-count-one": "00 Billionen", - "10000000000000-count-other": "00 Billionen", - "100000000000000-count-one": "000 Billionen", - "100000000000000-count-other": "000 Billionen" - } - }, - "short": { - "decimalFormat": { - "1000-count-one": "0 Tsd'.'", - "1000-count-other": "0 Tsd'.'", - "10000-count-one": "00 Tsd'.'", - "10000-count-other": "00 Tsd'.'", - "100000-count-one": "000 Tsd'.'", - "100000-count-other": "000 Tsd'.'", - "1000000-count-one": "0 Mio'.'", - "1000000-count-other": "0 Mio'.'", - "10000000-count-one": "00 Mio'.'", - "10000000-count-other": "00 Mio'.'", - "100000000-count-one": "000 Mio'.'", - "100000000-count-other": "000 Mio'.'", - "1000000000-count-one": "0 Mrd'.'", - "1000000000-count-other": "0 Mrd'.'", - "10000000000-count-one": "00 Mrd'.'", - "10000000000-count-other": "00 Mrd'.'", - "100000000000-count-one": "000 Mrd'.'", - "100000000000-count-other": "000 Mrd'.'", - "1000000000000-count-one": "0 Bio'.'", - "1000000000000-count-other": "0 Bio'.'", - "10000000000000-count-one": "00 Bio'.'", - "10000000000000-count-other": "00 Bio'.'", - "100000000000000-count-one": "000 Bio'.'", - "100000000000000-count-other": "000 Bio'.'" - } - } - }, - "scientificFormats-numberSystem-latn": { - "standard": "#E0" - }, - "percentFormats-numberSystem-latn": { - "standard": "#,##0 %" - }, - "currencyFormats-numberSystem-latn": { - "currencySpacing": { - "beforeCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - }, - "afterCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - } - }, - "accounting": "#,##0.00 ¤", - "standard": "#,##0.00 ¤", - "unitPattern-count-one": "{0} {1}", - "unitPattern-count-other": "{0} {1}" - }, - "miscPatterns-numberSystem-latn": { - "atLeast": "{0}+", - "range": "{0}–{1}" - } - } - } - } -}); + // AMD + define( ["globalize-runtime/number","globalize-runtime/date"], factory ); + } else if ( typeof exports === "object" ) { -Globalize.load({ - "main": { - "zh": { - "identity": { - "version": { - "_cldrVersion": "27.0.1", - "_number": "$Revision: 11294 $" - }, - "generation": { - "_date": "$Date: 2015-02-23 16:50:24 -0600 (Mon, 23 Feb 2015) $" - }, - "language": "zh" - }, - "dates": { - "calendars": { - "gregorian": { - "months": { - "format": { - "abbreviated": { - "1": "1月", - "2": "2月", - "3": "3月", - "4": "4月", - "5": "5月", - "6": "6月", - "7": "7月", - "8": "8月", - "9": "9月", - "10": "10月", - "11": "11月", - "12": "12月" - }, - "narrow": { - "1": "1", - "2": "2", - "3": "3", - "4": "4", - "5": "5", - "6": "6", - "7": "7", - "8": "8", - "9": "9", - "10": "10", - "11": "11", - "12": "12" - }, - "wide": { - "1": "一月", - "2": "二月", - "3": "三月", - "4": "四月", - "5": "五月", - "6": "六月", - "7": "七月", - "8": "八月", - "9": "九月", - "10": "十月", - "11": "十一月", - "12": "十二月" - } - }, - "stand-alone": { - "abbreviated": { - "1": "1月", - "2": "2月", - "3": "3月", - "4": "4月", - "5": "5月", - "6": "6月", - "7": "7月", - "8": "8月", - "9": "9月", - "10": "10月", - "11": "11月", - "12": "12月" - }, - "narrow": { - "1": "1", - "2": "2", - "3": "3", - "4": "4", - "5": "5", - "6": "6", - "7": "7", - "8": "8", - "9": "9", - "10": "10", - "11": "11", - "12": "12" - }, - "wide": { - "1": "一月", - "2": "二月", - "3": "三月", - "4": "四月", - "5": "五月", - "6": "六月", - "7": "七月", - "8": "八月", - "9": "九月", - "10": "十月", - "11": "十一月", - "12": "十二月" - } - } - }, - "days": { - "format": { - "abbreviated": { - "sun": "周日", - "mon": "周一", - "tue": "周二", - "wed": "周三", - "thu": "周四", - "fri": "周五", - "sat": "周六" - }, - "narrow": { - "sun": "日", - "mon": "一", - "tue": "二", - "wed": "三", - "thu": "四", - "fri": "五", - "sat": "六" - }, - "short": { - "sun": "周日", - "mon": "周一", - "tue": "周二", - "wed": "周三", - "thu": "周四", - "fri": "周五", - "sat": "周六" - }, - "wide": { - "sun": "星期日", - "mon": "星期一", - "tue": "星期二", - "wed": "星期三", - "thu": "星期四", - "fri": "星期五", - "sat": "星期六" - } - }, - "stand-alone": { - "abbreviated": { - "sun": "周日", - "mon": "周一", - "tue": "周二", - "wed": "周三", - "thu": "周四", - "fri": "周五", - "sat": "周六" - }, - "narrow": { - "sun": "日", - "mon": "一", - "tue": "二", - "wed": "三", - "thu": "四", - "fri": "五", - "sat": "六" - }, - "short": { - "sun": "周日", - "mon": "周一", - "tue": "周二", - "wed": "周三", - "thu": "周四", - "fri": "周五", - "sat": "周六" - }, - "wide": { - "sun": "星期日", - "mon": "星期一", - "tue": "星期二", - "wed": "星期三", - "thu": "星期四", - "fri": "星期五", - "sat": "星期六" - } - } - }, - "quarters": { - "format": { - "abbreviated": { - "1": "1季度", - "2": "2季度", - "3": "3季度", - "4": "4季度" - }, - "narrow": { - "1": "1", - "2": "2", - "3": "3", - "4": "4" - }, - "wide": { - "1": "第一季度", - "2": "第二季度", - "3": "第三季度", - "4": "第四季度" - } - }, - "stand-alone": { - "abbreviated": { - "1": "1季度", - "2": "2季度", - "3": "3季度", - "4": "4季度" - }, - "narrow": { - "1": "1", - "2": "2", - "3": "3", - "4": "4" - }, - "wide": { - "1": "第一季度", - "2": "第二季度", - "3": "第三季度", - "4": "第四季度" - } - } - }, - "dayPeriods": { - "format": { - "abbreviated": { - "afternoon": "下午", - "am": "上午", - "earlyMorning": "清晨", - "midDay": "中午", - "morning": "上午", - "night": "晚上", - "noon": "中午", - "pm": "下午", - "weeHours": "凌晨" - }, - "narrow": { - "afternoon": "下午", - "am": "上午", - "earlyMorning": "清晨", - "midDay": "中午", - "morning": "上午", - "night": "晚上", - "noon": "中午", - "pm": "下午", - "weeHours": "凌晨" - }, - "wide": { - "afternoon": "下午", - "am": "上午", - "earlyMorning": "清晨", - "midDay": "中午", - "morning": "上午", - "night": "晚上", - "noon": "中午", - "pm": "下午", - "weeHours": "凌晨" - } - }, - "stand-alone": { - "abbreviated": { - "afternoon": "下午", - "am": "上午", - "earlyMorning": "清晨", - "midDay": "中午", - "morning": "上午", - "night": "晚上", - "noon": "中午", - "pm": "下午", - "weeHours": "凌晨" - }, - "narrow": { - "afternoon": "下午", - "am": "上午", - "earlyMorning": "清晨", - "midDay": "中午", - "morning": "上午", - "night": "晚上", - "noon": "中午", - "pm": "下午", - "weeHours": "凌晨" - }, - "wide": { - "afternoon": "下午", - "am": "上午", - "earlyMorning": "清晨", - "midDay": "中午", - "morning": "上午", - "night": "晚上", - "noon": "中午", - "pm": "下午", - "weeHours": "凌晨" - } - } - }, - "eras": { - "eraNames": { - "0": "公元前", - "0-alt-variant": "BCE", - "1": "公元", - "1-alt-variant": "CE" - }, - "eraAbbr": { - "0": "公元前", - "0-alt-variant": "BCE", - "1": "公元", - "1-alt-variant": "CE" - }, - "eraNarrow": { - "0": "公元前", - "0-alt-variant": "BCE", - "1": "公元", - "1-alt-variant": "CE" - } - }, - "dateFormats": { - "full": "y年M月d日EEEE", - "long": "y年M月d日", - "medium": "y年M月d日", - "short": "yy/M/d" - }, - "timeFormats": { - "full": "zzzz ah:mm:ss", - "long": "z ah:mm:ss", - "medium": "ah:mm:ss", - "short": "ah:mm" - }, - "dateTimeFormats": { - "full": "{1} {0}", - "long": "{1} {0}", - "medium": "{1} {0}", - "short": "{1} {0}", - "availableFormats": { - "E": "ccc", - "EHm": "EHH:mm", - "EHms": "EHH:mm:ss", - "Ed": "d日E", - "Ehm": "Eah:mm", - "Ehms": "Eah:mm:ss", - "Gy": "Gy年", - "GyMMM": "Gy年M月", - "GyMMMEd": "Gy年M月d日E", - "GyMMMd": "Gy年M月d日", - "H": "H时", - "Hm": "HH:mm", - "Hms": "HH:mm:ss", - "Hmsv": "v HH:mm:ss", - "Hmv": "v HH:mm", - "M": "M月", - "MEd": "M/dE", - "MMM": "LLL", - "MMMEd": "M月d日E", - "MMMMdd": "M月dd日", - "MMMd": "M月d日", - "MMdd": "MM/dd", - "Md": "M/d", - "d": "d日", - "h": "ah时", - "hm": "ah:mm", - "hms": "ah:mm:ss", - "hmsv": "v ah:mm:ss", - "hmv": "v ah:mm", - "ms": "mm:ss", - "y": "y年", - "yM": "y年M月", - "yMEd": "y/M/dE", - "yMM": "y年M月", - "yMMM": "y年M月", - "yMMMEd": "y年M月d日E", - "yMMMM": "y年M月", - "yMMMd": "y年M月d日", - "yMd": "y/M/d", - "yQQQ": "y年第Q季度", - "yQQQQ": "y年第Q季度" - }, - "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": "{1}{0}", - "Week": "{0} ({2}: {1})", - "Year": "{1} {0}" - }, - "intervalFormats": { - "intervalFormatFallback": "{0} – {1}", - "H": { - "H": "HH–HH" - }, - "Hm": { - "H": "HH:mm–HH:mm", - "m": "HH:mm–HH:mm" - }, - "Hmv": { - "H": "v HH:mm–HH:mm", - "m": "v HH:mm–HH:mm" - }, - "Hv": { - "H": "v HH–HH" - }, - "M": { - "M": "M–M月" - }, - "MEd": { - "M": "M/dE至M/dE", - "d": "M/dE至M/dE" - }, - "MMM": { - "M": "LLL至LLL" - }, - "MMMEd": { - "M": "M月d日E至M月d日E", - "d": "M月d日E至d日E" - }, - "MMMd": { - "M": "M月d日至M月d日", - "d": "M月d日至d日" - }, - "Md": { - "M": "M/d – M/d", - "d": "M/d – M/d" - }, - "d": { - "d": "d–d日" - }, - "h": { - "a": "ah时至ah时", - "h": "ah时至h时" - }, - "hm": { - "a": "ah:mm至ah:mm", - "h": "ah:mm至h:mm", - "m": "ah:mm至h:mm" - }, - "hmv": { - "a": "vah:mm至ah:mm", - "h": "vah:mm至h:mm", - "m": "vah:mm至h:mm" - }, - "hv": { - "a": "vah时至ah时", - "h": "vah时至h时" - }, - "y": { - "y": "y–y年" - }, - "yM": { - "M": "y年M月至M月", - "y": "y年M月至y年M月" - }, - "yMEd": { - "M": "y/M/dE至y/M/dE", - "d": "y/M/dE至y/M/dE", - "y": "y/M/dE至y/M/dE" - }, - "yMMM": { - "M": "y年M月至M月", - "y": "y年M月至y年M月" - }, - "yMMMEd": { - "M": "y年M月d日E至M月d日E", - "d": "y年M月d日E至d日E", - "y": "y年M月d日E至y年M月d日E" - }, - "yMMMM": { - "M": "y年M月至M月", - "y": "y年M月至y年M月" - }, - "yMMMd": { - "M": "y年M月d日至M月d日", - "d": "y年M月d日至d日", - "y": "y年M月d日至y年M月d日" - }, - "yMd": { - "M": "y/M/d – y/M/d", - "d": "y/M/d – y/M/d", - "y": "y/M/d – y/M/d" - } - } - } - } - } - }, - "numbers": { - "defaultNumberingSystem": "latn", - "otherNumberingSystems": { - "native": "hanidec", - "traditional": "hans", - "finance": "hansfin" - }, - "minimumGroupingDigits": "1", - "symbols-numberSystem-hanidec": { - "decimal": ".", - "group": ",", - "list": ";", - "percentSign": "%", - "plusSign": "+", - "minusSign": "-", - "exponential": "E", - "superscriptingExponent": "×", - "perMille": "‰", - "infinity": "∞", - "nan": "NaN", - "timeSeparator": ":" - }, - "symbols-numberSystem-latn": { - "decimal": ".", - "group": ",", - "list": ";", - "percentSign": "%", - "plusSign": "+", - "minusSign": "-", - "exponential": "E", - "superscriptingExponent": "×", - "perMille": "‰", - "infinity": "∞", - "nan": "NaN", - "timeSeparator": ":" - }, - "decimalFormats-numberSystem-hanidec": { - "standard": "#,##0.###", - "long": { - "decimalFormat": { - "1000-count-other": "0千", - "10000-count-other": "0万", - "100000-count-other": "00万", - "1000000-count-other": "000万", - "10000000-count-other": "0000万", - "100000000-count-other": "0亿", - "1000000000-count-other": "00亿", - "10000000000-count-other": "000亿", - "100000000000-count-other": "0000亿", - "1000000000000-count-other": "0兆", - "10000000000000-count-other": "00兆", - "100000000000000-count-other": "000兆" - } - }, - "short": { - "decimalFormat": { - "1000-count-other": "0千", - "10000-count-other": "0万", - "100000-count-other": "00万", - "1000000-count-other": "000万", - "10000000-count-other": "0000万", - "100000000-count-other": "0亿", - "1000000000-count-other": "00亿", - "10000000000-count-other": "000亿", - "100000000000-count-other": "0000亿", - "1000000000000-count-other": "0兆", - "10000000000000-count-other": "00兆", - "100000000000000-count-other": "000兆" - } - } - }, - "decimalFormats-numberSystem-latn": { - "standard": "#,##0.###", - "long": { - "decimalFormat": { - "1000-count-other": "0千", - "10000-count-other": "0万", - "100000-count-other": "00万", - "1000000-count-other": "000万", - "10000000-count-other": "0000万", - "100000000-count-other": "0亿", - "1000000000-count-other": "00亿", - "10000000000-count-other": "000亿", - "100000000000-count-other": "0000亿", - "1000000000000-count-other": "0兆", - "10000000000000-count-other": "00兆", - "100000000000000-count-other": "000兆" - } - }, - "short": { - "decimalFormat": { - "1000-count-other": "0千", - "10000-count-other": "0万", - "100000-count-other": "00万", - "1000000-count-other": "000万", - "10000000-count-other": "0000万", - "100000000-count-other": "0亿", - "1000000000-count-other": "00亿", - "10000000000-count-other": "000亿", - "100000000000-count-other": "0000亿", - "1000000000000-count-other": "0兆", - "10000000000000-count-other": "00兆", - "100000000000000-count-other": "000兆" - } - } - }, - "scientificFormats-numberSystem-hanidec": { - "standard": "#E0" - }, - "scientificFormats-numberSystem-latn": { - "standard": "#E0" - }, - "percentFormats-numberSystem-hanidec": { - "standard": "#,##0%" - }, - "percentFormats-numberSystem-latn": { - "standard": "#,##0%" - }, - "currencyFormats-numberSystem-hanidec": { - "currencySpacing": { - "beforeCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - }, - "afterCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - } - }, - "accounting": "¤#,##0.00;(¤#,##0.00)", - "standard": "¤ #,##0.00", - "unitPattern-count-other": "{0}{1}" - }, - "currencyFormats-numberSystem-latn": { - "currencySpacing": { - "beforeCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - }, - "afterCurrency": { - "currencyMatch": "[:^S:]", - "surroundingMatch": "[:digit:]", - "insertBetween": " " - } - }, - "accounting": "¤#,##0.00;(¤#,##0.00)", - "standard": "¤ #,##0.00", - "unitPattern-count-other": "{0}{1}" - }, - "miscPatterns-numberSystem-hanidec": { - "atLeast": "{0}+", - "range": "{0}-{1}" - }, - "miscPatterns-numberSystem-latn": { - "atLeast": "{0}+", - "range": "{0}-{1}" - } - } - } - } -}); + // Node, CommonJS + module.exports = factory( require("globalize/dist/globalize-runtime/number"), require("globalize/dist/globalize-runtime/date") ); + } else { -Globalize.load({ - "supplemental": { - "version": { - "_unicodeVersion": "7.0.0", - "_number": "$Revision: 11318 $" - }, - "generation": { - "_date": "$Date: 2015-02-25 23:47:56 -0600 (Wed, 25 Feb 2015) $" - }, - "likelySubtags": { - "aa": "aa-Latn-ET", - "ab": "ab-Cyrl-GE", - "abr": "abr-Latn-GH", - "ace": "ace-Latn-ID", - "ach": "ach-Latn-UG", - "ada": "ada-Latn-GH", - "ady": "ady-Cyrl-RU", - "ae": "ae-Avst-IR", - "aeb": "aeb-Arab-TN", - "af": "af-Latn-ZA", - "agq": "agq-Latn-CM", - "ak": "ak-Latn-GH", - "akk": "akk-Xsux-IQ", - "aln": "aln-Latn-XK", - "alt": "alt-Cyrl-RU", - "am": "am-Ethi-ET", - "amo": "amo-Latn-NG", - "aoz": "aoz-Latn-ID", - "ar": "ar-Arab-EG", - "arc": "arc-Armi-IR", - "arc-Nbat": "arc-Nbat-JO", - "arc-Palm": "arc-Palm-SY", - "arn": "arn-Latn-CL", - "aro": "aro-Latn-BO", - "arq": "arq-Arab-DZ", - "ary": "ary-Arab-MA", - "arz": "arz-Arab-EG", - "as": "as-Beng-IN", - "asa": "asa-Latn-TZ", - "ast": "ast-Latn-ES", - "atj": "atj-Latn-CA", - "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", - "azb": "azb-Arab-IR", - "ba": "ba-Cyrl-RU", - "bal": "bal-Arab-PK", - "ban": "ban-Latn-ID", - "bap": "bap-Deva-NP", - "bar": "bar-Latn-AT", - "bas": "bas-Latn-CM", - "bax": "bax-Bamu-CM", - "bbc": "bbc-Latn-ID", - "bbj": "bbj-Latn-CM", - "bci": "bci-Latn-CI", - "be": "be-Cyrl-BY", - "bem": "bem-Latn-ZM", - "bew": "bew-Latn-ID", - "bez": "bez-Latn-TZ", - "bfd": "bfd-Latn-CM", - "bfq": "bfq-Taml-IN", - "bft": "bft-Arab-PK", - "bfy": "bfy-Deva-IN", - "bg": "bg-Cyrl-BG", - "bgc": "bgc-Deva-IN", - "bgx": "bgx-Grek-TR", - "bh": "bh-Kthi-IN", - "bhb": "bhb-Deva-IN", - "bhi": "bhi-Deva-IN", - "bhk": "bhk-Latn-PH", - "bho": "bho-Deva-IN", - "bi": "bi-Latn-VU", - "bik": "bik-Latn-PH", - "bin": "bin-Latn-NG", - "bjj": "bjj-Deva-IN", - "bjn": "bjn-Latn-ID", - "bkm": "bkm-Latn-CM", - "bku": "bku-Latn-PH", - "blt": "blt-Tavt-VN", - "bm": "bm-Latn-ML", - "bmq": "bmq-Latn-ML", - "bn": "bn-Beng-BD", - "bo": "bo-Tibt-CN", - "bpy": "bpy-Beng-IN", - "bqi": "bqi-Arab-IR", - "bqv": "bqv-Latn-CI", - "br": "br-Latn-FR", - "bra": "bra-Deva-IN", - "brh": "brh-Arab-PK", - "brx": "brx-Deva-IN", - "bs": "bs-Latn-BA", - "bsq": "bsq-Bass-LR", - "bss": "bss-Latn-CM", - "bto": "bto-Latn-PH", - "btv": "btv-Deva-PK", - "bua": "bua-Cyrl-RU", - "buc": "buc-Latn-YT", - "bug": "bug-Latn-ID", - "bum": "bum-Latn-CM", - "bvb": "bvb-Latn-GQ", - "byn": "byn-Ethi-ER", - "byv": "byv-Latn-CM", - "bze": "bze-Latn-ML", - "ca": "ca-Latn-ES", - "cch": "cch-Latn-NG", - "ccp": "ccp-Beng-IN", - "ccp-Cakm": "ccp-Cakm-BD", - "ce": "ce-Cyrl-RU", - "ceb": "ceb-Latn-PH", - "cgg": "cgg-Latn-UG", - "ch": "ch-Latn-GU", - "chk": "chk-Latn-FM", - "chm": "chm-Cyrl-RU", - "cho": "cho-Latn-US", - "chp": "chp-Latn-CA", - "chr": "chr-Cher-US", - "cja": "cja-Arab-KH", - "cjm": "cjm-Cham-VN", - "ckb": "ckb-Arab-IQ", - "co": "co-Latn-FR", - "cop": "cop-Copt-EG", - "cps": "cps-Latn-PH", - "cr": "cr-Cans-CA", - "crj": "crj-Cans-CA", - "crk": "crk-Cans-CA", - "crl": "crl-Cans-CA", - "crm": "crm-Cans-CA", - "crs": "crs-Latn-SC", - "cs": "cs-Latn-CZ", - "csb": "csb-Latn-PL", - "csw": "csw-Cans-CA", - "ctd": "ctd-Pauc-MM", - "cu": "cu-Cyrl-RU", - "cu-Glag": "cu-Glag-BG", - "cv": "cv-Cyrl-RU", - "cy": "cy-Latn-GB", - "da": "da-Latn-DK", - "dak": "dak-Latn-US", - "dar": "dar-Cyrl-RU", - "dav": "dav-Latn-KE", - "dcc": "dcc-Arab-IN", - "de": "de-Latn-DE", - "den": "den-Latn-CA", - "dgr": "dgr-Latn-CA", - "dje": "dje-Latn-NE", - "dnj": "dnj-Latn-CI", - "doi": "doi-Arab-IN", - "dsb": "dsb-Latn-DE", - "dtm": "dtm-Latn-ML", - "dtp": "dtp-Latn-MY", - "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", - "egl": "egl-Latn-IT", - "egy": "egy-Egyp-EG", - "eky": "eky-Kali-MM", - "el": "el-Grek-GR", - "en": "en-Latn-US", - "en-Shaw": "en-Shaw-GB", - "eo": "eo-Latn-001", - "es": "es-Latn-ES", - "esu": "esu-Latn-US", - "et": "et-Latn-EE", - "ett": "ett-Ital-IT", - "eu": "eu-Latn-ES", - "ewo": "ewo-Latn-CM", - "ext": "ext-Latn-ES", - "fa": "fa-Arab-IR", - "fan": "fan-Latn-GQ", - "ff": "ff-Latn-SN", - "ffm": "ffm-Latn-ML", - "fi": "fi-Latn-FI", - "fil": "fil-Latn-PH", - "fit": "fit-Latn-SE", - "fj": "fj-Latn-FJ", - "fo": "fo-Latn-FO", - "fon": "fon-Latn-BJ", - "fr": "fr-Latn-FR", - "frc": "frc-Latn-US", - "frp": "frp-Latn-FR", - "frr": "frr-Latn-DE", - "frs": "frs-Latn-DE", - "fud": "fud-Latn-WF", - "fuq": "fuq-Latn-NE", - "fur": "fur-Latn-IT", - "fuv": "fuv-Latn-NG", - "fy": "fy-Latn-NL", - "ga": "ga-Latn-IE", - "gaa": "gaa-Latn-GH", - "gag": "gag-Latn-MD", - "gan": "gan-Hans-CN", - "gay": "gay-Latn-ID", - "gbm": "gbm-Deva-IN", - "gbz": "gbz-Arab-IR", - "gcr": "gcr-Latn-GF", - "gd": "gd-Latn-GB", - "gez": "gez-Ethi-ET", - "ggn": "ggn-Deva-NP", - "gil": "gil-Latn-KI", - "gjk": "gjk-Arab-PK", - "gju": "gju-Arab-PK", - "gl": "gl-Latn-ES", - "glk": "glk-Arab-IR", - "gn": "gn-Latn-PY", - "gom": "gom-Deva-IN", - "gon": "gon-Telu-IN", - "gor": "gor-Latn-ID", - "gos": "gos-Latn-NL", - "got": "got-Goth-UA", - "grc": "grc-Cprt-CY", - "grc-Linb": "grc-Linb-GR", - "grt": "grt-Beng-IN", - "gsw": "gsw-Latn-CH", - "gu": "gu-Gujr-IN", - "gub": "gub-Latn-BR", - "guc": "guc-Latn-CO", - "gur": "gur-Latn-GH", - "guz": "guz-Latn-KE", - "gv": "gv-Latn-IM", - "gvr": "gvr-Deva-NP", - "gwi": "gwi-Latn-CA", - "ha": "ha-Latn-NG", - "ha-CM": "ha-Arab-CM", - "ha-SD": "ha-Arab-SD", - "hak": "hak-Hans-CN", - "haw": "haw-Latn-US", - "haz": "haz-Arab-AF", - "he": "he-Hebr-IL", - "hi": "hi-Deva-IN", - "hif": "hif-Deva-FJ", - "hil": "hil-Latn-PH", - "hmd": "hmd-Plrd-CN", - "hnd": "hnd-Arab-PK", - "hne": "hne-Deva-IN", - "hnj": "hnj-Hmng-LA", - "hnn": "hnn-Latn-PH", - "hno": "hno-Arab-PK", - "ho": "ho-Latn-PG", - "hoc": "hoc-Deva-IN", - "hoj": "hoj-Deva-IN", - "hr": "hr-Latn-HR", - "hsb": "hsb-Latn-DE", - "hsn": "hsn-Hans-CN", - "ht": "ht-Latn-HT", - "hu": "hu-Latn-HU", - "hy": "hy-Armn-AM", - "hz": "hz-Latn-NA", - "ia": "ia-Latn-FR", - "iba": "iba-Latn-MY", - "ibb": "ibb-Latn-NG", - "id": "id-Latn-ID", - "ig": "ig-Latn-NG", - "ii": "ii-Yiii-CN", - "ik": "ik-Latn-US", - "ikt": "ikt-Latn-CA", - "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", - "izh": "izh-Latn-RU", - "ja": "ja-Jpan-JP", - "jam": "jam-Latn-JM", - "jgo": "jgo-Latn-CM", - "ji": "ji-Hebr-UA", - "jmc": "jmc-Latn-TZ", - "jml": "jml-Deva-NP", - "jut": "jut-Latn-DK", - "jv": "jv-Latn-ID", - "jw": "jw-Latn-ID", - "ka": "ka-Geor-GE", - "kaa": "kaa-Cyrl-UZ", - "kab": "kab-Latn-DZ", - "kac": "kac-Latn-MM", - "kaj": "kaj-Latn-NG", - "kam": "kam-Latn-KE", - "kao": "kao-Latn-ML", - "kbd": "kbd-Cyrl-RU", - "kcg": "kcg-Latn-NG", - "kck": "kck-Latn-ZW", - "kde": "kde-Latn-TZ", - "kdt": "kdt-Thai-TH", - "kea": "kea-Latn-CV", - "ken": "ken-Latn-CM", - "kfo": "kfo-Latn-CI", - "kfr": "kfr-Deva-IN", - "kfy": "kfy-Deva-IN", - "kg": "kg-Latn-CD", - "kge": "kge-Latn-ID", - "kgp": "kgp-Latn-BR", - "kha": "kha-Latn-IN", - "khb": "khb-Talu-CN", - "khn": "khn-Deva-IN", - "khq": "khq-Latn-ML", - "kht": "kht-Mymr-IN", - "khw": "khw-Arab-PK", - "ki": "ki-Latn-KE", - "kiu": "kiu-Latn-TR", - "kj": "kj-Latn-NA", - "kjg": "kjg-Laoo-LA", - "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", - "krj": "krj-Latn-PH", - "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", - "kvr": "kvr-Latn-ID", - "kvx": "kvx-Arab-PK", - "kw": "kw-Latn-GB", - "kxm": "kxm-Thai-TH", - "kxp": "kxp-Arab-PK", - "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", - "lab": "lab-Lina-GR", - "lad": "lad-Hebr-IL", - "lag": "lag-Latn-TZ", - "lah": "lah-Arab-PK", - "laj": "laj-Latn-UG", - "lb": "lb-Latn-LU", - "lbe": "lbe-Cyrl-RU", - "lbw": "lbw-Latn-ID", - "lcp": "lcp-Thai-CN", - "lep": "lep-Lepc-IN", - "lez": "lez-Cyrl-RU", - "lg": "lg-Latn-UG", - "li": "li-Latn-NL", - "lif": "lif-Deva-NP", - "lif-Limb": "lif-Limb-IN", - "lij": "lij-Latn-IT", - "lis": "lis-Lisu-CN", - "ljp": "ljp-Latn-ID", - "lki": "lki-Arab-IR", - "lkt": "lkt-Latn-US", - "lmn": "lmn-Telu-IN", - "lmo": "lmo-Latn-IT", - "ln": "ln-Latn-CD", - "lo": "lo-Laoo-LA", - "lol": "lol-Latn-CD", - "loz": "loz-Latn-ZM", - "lrc": "lrc-Arab-IR", - "lt": "lt-Latn-LT", - "ltg": "ltg-Latn-LV", - "lu": "lu-Latn-CD", - "lua": "lua-Latn-CD", - "luo": "luo-Latn-KE", - "luy": "luy-Latn-KE", - "luz": "luz-Arab-IR", - "lv": "lv-Latn-LV", - "lwl": "lwl-Thai-TH", - "lzh": "lzh-Hans-CN", - "lzz": "lzz-Latn-TR", - "mad": "mad-Latn-ID", - "maf": "maf-Latn-CM", - "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", - "maz": "maz-Latn-MX", - "mdf": "mdf-Cyrl-RU", - "mdh": "mdh-Latn-PH", - "mdr": "mdr-Latn-ID", - "men": "men-Latn-SL", - "mer": "mer-Latn-KE", - "mfa": "mfa-Arab-TH", - "mfe": "mfe-Latn-MU", - "mg": "mg-Latn-MG", - "mgh": "mgh-Latn-MZ", - "mgo": "mgo-Latn-CM", - "mgp": "mgp-Deva-NP", - "mgy": "mgy-Latn-TZ", - "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", - "moe": "moe-Latn-CA", - "moh": "moh-Latn-CA", - "mos": "mos-Latn-BF", - "mr": "mr-Deva-IN", - "mrd": "mrd-Deva-NP", - "mrj": "mrj-Cyrl-RU", - "mru": "mru-Mroo-BD", - "ms": "ms-Latn-MY", - "ms-CC": "ms-Arab-CC", - "ms-ID": "ms-Arab-ID", - "mt": "mt-Latn-MT", - "mtr": "mtr-Deva-IN", - "mua": "mua-Latn-CM", - "mus": "mus-Latn-US", - "mvy": "mvy-Arab-PK", - "mwk": "mwk-Latn-ML", - "mwr": "mwr-Deva-IN", - "mwv": "mwv-Latn-ID", - "mxc": "mxc-Latn-ZW", - "my": "my-Mymr-MM", - "myv": "myv-Cyrl-RU", - "myx": "myx-Latn-UG", - "myz": "myz-Mand-IR", - "mzn": "mzn-Arab-IR", - "na": "na-Latn-NR", - "nan": "nan-Hans-CN", - "nap": "nap-Latn-IT", - "naq": "naq-Latn-NA", - "nb": "nb-Latn-NO", - "nch": "nch-Latn-MX", - "nd": "nd-Latn-ZW", - "ndc": "ndc-Latn-MZ", - "nds": "nds-Latn-DE", - "ne": "ne-Deva-NP", - "new": "new-Deva-NP", - "ng": "ng-Latn-NA", - "ngl": "ngl-Latn-MZ", - "nhe": "nhe-Latn-MX", - "nhw": "nhw-Latn-MX", - "nij": "nij-Latn-ID", - "niu": "niu-Latn-NU", - "njo": "njo-Latn-IN", - "nl": "nl-Latn-NL", - "nmg": "nmg-Latn-CM", - "nn": "nn-Latn-NO", - "nnh": "nnh-Latn-CM", - "no": "no-Latn-NO", - "nod": "nod-Lana-TH", - "noe": "noe-Deva-IN", - "non": "non-Runr-SE", - "nqo": "nqo-Nkoo-GN", - "nr": "nr-Latn-ZA", - "nsk": "nsk-Cans-CA", - "nso": "nso-Latn-ZA", - "nus": "nus-Latn-SD", - "nv": "nv-Latn-US", - "nxq": "nxq-Latn-CN", - "ny": "ny-Latn-MW", - "nym": "nym-Latn-TZ", - "nyn": "nyn-Latn-UG", - "nzi": "nzi-Latn-GH", - "oc": "oc-Latn-FR", - "om": "om-Latn-ET", - "or": "or-Orya-IN", - "os": "os-Cyrl-GE", - "otk": "otk-Orkh-MN", - "pa": "pa-Guru-IN", - "pa-Arab": "pa-Arab-PK", - "pa-PK": "pa-Arab-PK", - "pag": "pag-Latn-PH", - "pal": "pal-Phli-IR", - "pal-Phlp": "pal-Phlp-CN", - "pam": "pam-Latn-PH", - "pap": "pap-Latn-AW", - "pau": "pau-Latn-PW", - "pcd": "pcd-Latn-FR", - "pcm": "pcm-Latn-NG", - "pdc": "pdc-Latn-US", - "pdt": "pdt-Latn-CA", - "peo": "peo-Xpeo-IR", - "pfl": "pfl-Latn-DE", - "phn": "phn-Phnx-LB", - "pka": "pka-Brah-IN", - "pko": "pko-Latn-KE", - "pl": "pl-Latn-PL", - "pms": "pms-Latn-IT", - "pnt": "pnt-Grek-GR", - "pon": "pon-Latn-FM", - "pra": "pra-Khar-PK", - "prd": "prd-Arab-IR", - "prg": "prg-Latn-001", - "ps": "ps-Arab-AF", - "pt": "pt-Latn-BR", - "puu": "puu-Latn-GA", - "qu": "qu-Latn-PE", - "quc": "quc-Latn-GT", - "qug": "qug-Latn-EC", - "raj": "raj-Latn-IN", - "rcf": "rcf-Latn-RE", - "rej": "rej-Latn-ID", - "rgn": "rgn-Latn-IT", - "ria": "ria-Latn-IN", - "rif": "rif-Tfng-MA", - "rif-NL": "rif-Latn-NL", - "rjs": "rjs-Deva-NP", - "rkt": "rkt-Beng-BD", - "rm": "rm-Latn-CH", - "rmf": "rmf-Latn-FI", - "rmo": "rmo-Latn-CH", - "rmt": "rmt-Arab-IR", - "rmu": "rmu-Latn-SE", - "rn": "rn-Latn-BI", - "rng": "rng-Latn-MZ", - "ro": "ro-Latn-RO", - "rob": "rob-Latn-ID", - "rof": "rof-Latn-TZ", - "rtm": "rtm-Latn-FJ", - "ru": "ru-Cyrl-RU", - "rue": "rue-Cyrl-UA", - "rug": "rug-Latn-SB", - "rw": "rw-Latn-RW", - "rwk": "rwk-Latn-TZ", - "ryu": "ryu-Kana-JP", - "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", - "sc": "sc-Latn-IT", - "sck": "sck-Deva-IN", - "scn": "scn-Latn-IT", - "sco": "sco-Latn-GB", - "scs": "scs-Latn-CA", - "sd": "sd-Arab-PK", - "sd-Deva": "sd-Deva-IN", - "sd-Khoj": "sd-Khoj-IN", - "sd-Sind": "sd-Sind-IN", - "sdc": "sdc-Latn-IT", - "se": "se-Latn-NO", - "sef": "sef-Latn-CI", - "seh": "seh-Latn-MZ", - "sei": "sei-Latn-MX", - "ses": "ses-Latn-ML", - "sg": "sg-Latn-CF", - "sga": "sga-Ogam-IE", - "sgs": "sgs-Latn-LT", - "shi": "shi-Tfng-MA", - "shn": "shn-Mymr-MM", - "si": "si-Sinh-LK", - "sid": "sid-Latn-ET", - "sk": "sk-Latn-SK", - "skr": "skr-Arab-PK", - "sl": "sl-Latn-SI", - "sli": "sli-Latn-PL", - "sly": "sly-Latn-ID", - "sm": "sm-Latn-WS", - "sma": "sma-Latn-SE", - "smj": "smj-Latn-SE", - "smn": "smn-Latn-FI", - "smp": "smp-Samr-IL", - "sms": "sms-Latn-FI", - "sn": "sn-Latn-ZW", - "snk": "snk-Latn-ML", - "so": "so-Latn-SO", - "sou": "sou-Thai-TH", - "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", - "srb": "srb-Sora-IN", - "srn": "srn-Latn-SR", - "srr": "srr-Latn-SN", - "srx": "srx-Deva-IN", - "ss": "ss-Latn-ZA", - "ssy": "ssy-Latn-ER", - "st": "st-Latn-ZA", - "stq": "stq-Latn-DE", - "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", - "swv": "swv-Deva-IN", - "sxn": "sxn-Latn-ID", - "syl": "syl-Beng-BD", - "syr": "syr-Syrc-IQ", - "szl": "szl-Latn-PL", - "ta": "ta-Taml-IN", - "taj": "taj-Deva-NP", - "tbw": "tbw-Latn-PH", - "tcy": "tcy-Knda-IN", - "tdd": "tdd-Tale-CN", - "tdg": "tdg-Deva-NP", - "tdh": "tdh-Deva-NP", - "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", - "thl": "thl-Deva-NP", - "thq": "thq-Deva-NP", - "thr": "thr-Deva-NP", - "ti": "ti-Ethi-ET", - "tig": "tig-Ethi-ER", - "tiv": "tiv-Latn-NG", - "tk": "tk-Latn-TM", - "tkl": "tkl-Latn-TK", - "tkr": "tkr-Latn-AZ", - "tkt": "tkt-Deva-NP", - "tl": "tl-Latn-PH", - "tly": "tly-Latn-AZ", - "tmh": "tmh-Latn-NE", - "tn": "tn-Latn-ZA", - "to": "to-Latn-TO", - "tog": "tog-Latn-MW", - "tpi": "tpi-Latn-PG", - "tr": "tr-Latn-TR", - "tru": "tru-Latn-TR", - "trv": "trv-Latn-TW", - "ts": "ts-Latn-ZA", - "tsd": "tsd-Grek-GR", - "tsf": "tsf-Deva-NP", - "tsg": "tsg-Latn-PH", - "tsj": "tsj-Tibt-BT", - "tt": "tt-Cyrl-RU", - "ttj": "ttj-Latn-UG", - "tts": "tts-Thai-TH", - "ttt": "ttt-Latn-AZ", - "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", - "uga": "uga-Ugar-SY", - "uk": "uk-Cyrl-UA", - "uli": "uli-Latn-FM", - "umb": "umb-Latn-AO", - "und": "en-Latn-US", - "und-002": "en-Latn-NG", - "und-003": "en-Latn-US", - "und-005": "pt-Latn-BR", - "und-009": "en-Latn-AU", - "und-011": "en-Latn-NG", - "und-013": "es-Latn-MX", - "und-014": "sw-Latn-TZ", - "und-015": "ar-Arab-EG", - "und-017": "sw-Latn-CD", - "und-018": "en-Latn-ZA", - "und-019": "en-Latn-US", - "und-021": "en-Latn-US", - "und-029": "es-Latn-CU", - "und-030": "zh-Hans-CN", - "und-034": "hi-Deva-IN", - "und-035": "id-Latn-ID", - "und-039": "it-Latn-IT", - "und-053": "en-Latn-AU", - "und-054": "en-Latn-PG", - "und-057": "en-Latn-GU", - "und-061": "sm-Latn-WS", - "und-142": "zh-Hans-CN", - "und-143": "uz-Latn-UZ", - "und-145": "ar-Arab-SA", - "und-150": "ru-Cyrl-RU", - "und-151": "ru-Cyrl-RU", - "und-154": "en-Latn-GB", - "und-155": "de-Latn-DE", - "und-419": "es-Latn-419", - "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-AS": "sm-Latn-AS", - "und-AT": "de-Latn-AT", - "und-AW": "nl-Latn-AW", - "und-AX": "sv-Latn-AX", - "und-AZ": "az-Latn-AZ", - "und-Aghb": "lez-Aghb-RU", - "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-TH": "mfa-Arab-TH", - "und-Arab-TJ": "fa-Arab-TJ", - "und-Arab-YT": "swb-Arab-YT", - "und-Armi": "arc-Armi-IR", - "und-Armn": "hy-Armn-AM", - "und-Avst": "ae-Avst-IR", - "und-BA": "bs-Latn-BA", - "und-BD": "bn-Beng-BD", - "und-BE": "nl-Latn-BE", - "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-BQ": "pap-Latn-BQ", - "und-BR": "pt-Latn-BR", - "und-BT": "dz-Tibt-BT", - "und-BV": "und-Latn-BV", - "und-BY": "be-Cyrl-BY", - "und-Bali": "ban-Bali-ID", - "und-Bamu": "bax-Bamu-CM", - "und-Bass": "bsq-Bass-LR", - "und-Batk": "bbc-Batk-ID", - "und-Beng": "bn-Beng-BD", - "und-Bopo": "zh-Bopo-TW", - "und-Brah": "pka-Brah-IN", - "und-Brai": "fr-Brai-FR", - "und-Bugi": "bug-Bugi-ID", - "und-Buhd": "bku-Buhd-PH", - "und-CD": "sw-Latn-CD", - "und-CF": "fr-Latn-CF", - "und-CG": "fr-Latn-CG", - "und-CH": "de-Latn-CH", - "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-CP": "und-Latn-CP", - "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-CZ": "cs-Latn-CZ", - "und-Cakm": "ccp-Cakm-BD", - "und-Cans": "cr-Cans-CA", - "und-Cari": "xcr-Cari-TR", - "und-Cham": "cjm-Cham-VN", - "und-Cher": "chr-Cher-US", - "und-Copt": "cop-Copt-EG", - "und-Cprt": "grc-Cprt-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-DE": "de-Latn-DE", - "und-DJ": "aa-Latn-DJ", - "und-DK": "da-Latn-DK", - "und-DO": "es-Latn-DO", - "und-DZ": "ar-Arab-DZ", - "und-Deva": "hi-Deva-IN", - "und-Deva-BT": "ne-Deva-BT", - "und-Deva-FJ": "hif-Deva-FJ", - "und-Deva-MU": "bho-Deva-MU", - "und-Deva-PK": "btv-Deva-PK", - "und-Dupl": "fr-Dupl-FR", - "und-EA": "es-Latn-EA", - "und-EC": "es-Latn-EC", - "und-EE": "et-Latn-EE", - "und-EG": "ar-Arab-EG", - "und-EH": "ar-Arab-EH", - "und-ER": "ti-Ethi-ER", - "und-ES": "es-Latn-ES", - "und-ET": "am-Ethi-ET", - "und-EU": "en-Latn-GB", - "und-Egyp": "egy-Egyp-EG", - "und-Elba": "sq-Elba-AL", - "und-Ethi": "am-Ethi-ET", - "und-FI": "fi-Latn-FI", - "und-FO": "fo-Latn-FO", - "und-FR": "fr-Latn-FR", - "und-GA": "fr-Latn-GA", - "und-GE": "ka-Geor-GE", - "und-GF": "fr-Latn-GF", - "und-GH": "ak-Latn-GH", - "und-GL": "kl-Latn-GL", - "und-GN": "fr-Latn-GN", - "und-GP": "fr-Latn-GP", - "und-GQ": "es-Latn-GQ", - "und-GR": "el-Grek-GR", - "und-GS": "und-Latn-GS", - "und-GT": "es-Latn-GT", - "und-GW": "pt-Latn-GW", - "und-Geor": "ka-Geor-GE", - "und-Glag": "cu-Glag-BG", - "und-Goth": "got-Goth-UA", - "und-Gran": "sa-Gran-IN", - "und-Grek": "el-Grek-GR", - "und-Grek-TR": "bgx-Grek-TR", - "und-Gujr": "gu-Gujr-IN", - "und-Guru": "pa-Guru-IN", - "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-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-Hmng": "hnj-Hmng-LA", - "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-JO": "ar-Arab-JO", - "und-JP": "ja-Jpan-JP", - "und-Java": "jv-Java-ID", - "und-Jpan": "ja-Jpan-JP", - "und-KE": "sw-Latn-KE", - "und-KG": "ky-Cyrl-KG", - "und-KH": "km-Khmr-KH", - "und-KM": "ar-Arab-KM", - "und-KP": "ko-Kore-KP", - "und-KR": "ko-Kore-KR", - "und-KW": "ar-Arab-KW", - "und-KZ": "ru-Cyrl-KZ", - "und-Kali": "eky-Kali-MM", - "und-Kana": "ja-Kana-JP", - "und-Khar": "pra-Khar-PK", - "und-Khmr": "km-Khmr-KH", - "und-Khoj": "sd-Khoj-IN", - "und-Knda": "kn-Knda-IN", - "und-Kore": "ko-Kore-KR", - "und-Kthi": "bh-Kthi-IN", - "und-LA": "lo-Laoo-LA", - "und-LB": "ar-Arab-LB", - "und-LI": "de-Latn-LI", - "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-Lana": "nod-Lana-TH", - "und-Laoo": "lo-Laoo-LA", - "und-Latn-AF": "tk-Latn-AF", - "und-Latn-AM": "ku-Latn-AM", - "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-IR": "tk-Latn-IR", - "und-Latn-KM": "fr-Latn-KM", - "und-Latn-MA": "fr-Latn-MA", - "und-Latn-MK": "sq-Latn-MK", - "und-Latn-MM": "kac-Latn-MM", - "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-Lepc": "lep-Lepc-IN", - "und-Limb": "lif-Limb-IN", - "und-Lina": "lab-Lina-GR", - "und-Linb": "grc-Linb-GR", - "und-Lisu": "lis-Lisu-CN", - "und-Lyci": "xlc-Lyci-TR", - "und-Lydi": "xld-Lydi-TR", - "und-MA": "ar-Arab-MA", - "und-MC": "fr-Latn-MC", - "und-MD": "ro-Latn-MD", - "und-ME": "sr-Latn-ME", - "und-MF": "fr-Latn-MF", - "und-MG": "mg-Latn-MG", - "und-MK": "mk-Cyrl-MK", - "und-ML": "bm-Latn-ML", - "und-MM": "my-Mymr-MM", - "und-MN": "mn-Cyrl-MN", - "und-MO": "zh-Hant-MO", - "und-MQ": "fr-Latn-MQ", - "und-MR": "ar-Arab-MR", - "und-MT": "mt-Latn-MT", - "und-MU": "mfe-Latn-MU", - "und-MV": "dv-Thaa-MV", - "und-MX": "es-Latn-MX", - "und-MY": "ms-Latn-MY", - "und-MZ": "pt-Latn-MZ", - "und-Mahj": "hi-Mahj-IN", - "und-Mand": "myz-Mand-IR", - "und-Mani": "xmn-Mani-CN", - "und-Mend": "men-Mend-SL", - "und-Merc": "xmr-Merc-SD", - "und-Mero": "xmr-Mero-SD", - "und-Mlym": "ml-Mlym-IN", - "und-Modi": "mr-Modi-IN", - "und-Mong": "mn-Mong-CN", - "und-Mroo": "mru-Mroo-BD", - "und-Mtei": "mni-Mtei-IN", - "und-Mymr": "my-Mymr-MM", - "und-Mymr-IN": "kht-Mymr-IN", - "und-Mymr-TH": "mnw-Mymr-TH", - "und-NA": "af-Latn-NA", - "und-NC": "fr-Latn-NC", - "und-NE": "ha-Latn-NE", - "und-NI": "es-Latn-NI", - "und-NL": "nl-Latn-NL", - "und-NO": "nb-Latn-NO", - "und-NP": "ne-Deva-NP", - "und-Narb": "xna-Narb-SA", - "und-Nbat": "arc-Nbat-JO", - "und-Nkoo": "man-Nkoo-GN", - "und-OM": "ar-Arab-OM", - "und-Ogam": "sga-Ogam-IE", - "und-Olck": "sat-Olck-IN", - "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-PK": "ur-Arab-PK", - "und-PL": "pl-Latn-PL", - "und-PM": "fr-Latn-PM", - "und-PR": "es-Latn-PR", - "und-PS": "ar-Arab-PS", - "und-PT": "pt-Latn-PT", - "und-PW": "pau-Latn-PW", - "und-PY": "gn-Latn-PY", - "und-Palm": "arc-Palm-SY", - "und-Pauc": "ctd-Pauc-MM", - "und-Perm": "kv-Perm-RU", - "und-Phag": "lzh-Phag-CN", - "und-Phli": "pal-Phli-IR", - "und-Phlp": "pal-Phlp-CN", - "und-Phnx": "phn-Phnx-LB", - "und-Plrd": "hmd-Plrd-CN", - "und-Prti": "xpr-Prti-IR", - "und-QA": "ar-Arab-QA", - "und-QO": "en-Latn-IO", - "und-RE": "fr-Latn-RE", - "und-RO": "ro-Latn-RO", - "und-RS": "sr-Cyrl-RS", - "und-RU": "ru-Cyrl-RU", - "und-RW": "rw-Latn-RW", - "und-Rjng": "rej-Rjng-ID", - "und-Runr": "non-Runr-SE", - "und-SA": "ar-Arab-SA", - "und-SC": "fr-Latn-SC", - "und-SD": "ar-Arab-SD", - "und-SE": "sv-Latn-SE", - "und-SI": "sl-Latn-SI", - "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-SR": "nl-Latn-SR", - "und-ST": "pt-Latn-ST", - "und-SV": "es-Latn-SV", - "und-SY": "ar-Arab-SY", - "und-Samr": "smp-Samr-IL", - "und-Sarb": "xsa-Sarb-YE", - "und-Saur": "saz-Saur-IN", - "und-Shaw": "en-Shaw-GB", - "und-Shrd": "sa-Shrd-IN", - "und-Sidd": "sa-Sidd-IN", - "und-Sind": "sd-Sind-IN", - "und-Sinh": "si-Sinh-LK", - "und-Sora": "srb-Sora-IN", - "und-Sund": "su-Sund-ID", - "und-Sylo": "syl-Sylo-BD", - "und-Syrc": "syr-Syrc-IQ", - "und-TD": "fr-Latn-TD", - "und-TF": "fr-Latn-TF", - "und-TG": "fr-Latn-TG", - "und-TH": "th-Thai-TH", - "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-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-Telu": "te-Telu-IN", - "und-Tfng": "zgh-Tfng-MA", - "und-Tglg": "fil-Tglg-PH", - "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-Tirh": "mai-Tirh-IN", - "und-UA": "uk-Cyrl-UA", - "und-UG": "sw-Latn-UG", - "und-UY": "es-Latn-UY", - "und-UZ": "uz-Latn-UZ", - "und-Ugar": "uga-Ugar-SY", - "und-VA": "it-Latn-VA", - "und-VE": "es-Latn-VE", - "und-VN": "vi-Latn-VN", - "und-VU": "bi-Latn-VU", - "und-Vaii": "vai-Vaii-LR", - "und-WF": "fr-Latn-WF", - "und-WS": "sm-Latn-WS", - "und-Wara": "hoc-Wara-IN", - "und-XK": "sq-Latn-XK", - "und-Xpeo": "peo-Xpeo-IR", - "und-Xsux": "akk-Xsux-IQ", - "und-YE": "ar-Arab-YE", - "und-YT": "fr-Latn-YT", - "und-Yiii": "ii-Yiii-CN", - "und-ZW": "sn-Latn-ZW", - "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", - "vec": "vec-Latn-IT", - "vep": "vep-Latn-RU", - "vi": "vi-Latn-VN", - "vic": "vic-Latn-SX", - "vls": "vls-Latn-BE", - "vmf": "vmf-Latn-DE", - "vmw": "vmw-Latn-MZ", - "vo": "vo-Latn-001", - "vot": "vot-Latn-RU", - "vro": "vro-Latn-EE", - "vun": "vun-Latn-TZ", - "wa": "wa-Latn-BE", - "wae": "wae-Latn-CH", - "wal": "wal-Ethi-ET", - "war": "war-Latn-PH", - "wbp": "wbp-Latn-AU", - "wbq": "wbq-Telu-IN", - "wbr": "wbr-Deva-IN", - "wls": "wls-Latn-WF", - "wo": "wo-Latn-SN", - "wtm": "wtm-Deva-IN", - "wuu": "wuu-Hans-CN", - "xav": "xav-Latn-BR", - "xcr": "xcr-Cari-TR", - "xh": "xh-Latn-ZA", - "xlc": "xlc-Lyci-TR", - "xld": "xld-Lydi-TR", - "xmf": "xmf-Geor-GE", - "xmn": "xmn-Mani-CN", - "xmr": "xmr-Merc-SD", - "xna": "xna-Narb-SA", - "xnr": "xnr-Deva-IN", - "xog": "xog-Latn-UG", - "xpr": "xpr-Prti-IR", - "xsa": "xsa-Sarb-YE", - "xsr": "xsr-Deva-NP", - "yao": "yao-Latn-MZ", - "yap": "yap-Latn-FM", - "yav": "yav-Latn-CM", - "ybb": "ybb-Latn-CM", - "yi": "yi-Hebr-001", - "yo": "yo-Latn-NG", - "yrl": "yrl-Latn-BR", - "yua": "yua-Latn-MX", - "za": "za-Latn-CN", - "zdj": "zdj-Arab-KM", - "zea": "zea-Latn-NL", - "zgh": "zgh-Tfng-MA", - "zh": "zh-Hans-CN", - "zh-AU": "zh-Hant-AU", - "zh-BN": "zh-Hant-BN", - "zh-Bopo": "zh-Bopo-TW", - "zh-GB": "zh-Hant-GB", - "zh-GF": "zh-Hant-GF", - "zh-HK": "zh-Hant-HK", - "zh-Hant": "zh-Hant-TW", - "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", - "zmi": "zmi-Latn-MY", - "zu": "zu-Latn-ZA", - "zza": "zza-Latn-TR" - } + // Global + factory( root.Globalize ); } -}); +}( this, function( Globalize ) { -Globalize.load({ - "supplemental": { - "version": { - "_unicodeVersion": "7.0.0", - "_number": "$Revision: 11318 $" - }, - "generation": { - "_date": "$Date: 2015-02-25 23:47:56 -0600 (Wed, 25 Feb 2015) $" - }, - "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" - }, - "BQ": { - "_allowed": "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" - }, - "CG": { - "_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" - }, - "ID": { - "_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" - } - } - } -}); +var validateParameterTypeNumber = Globalize._validateParameterTypeNumber; +var validateParameterPresence = Globalize._validateParameterPresence; +var numberRound = Globalize._numberRound; +var numberFormat = Globalize._numberFormat; +var numberFormatterFn = Globalize._numberFormatterFn; +var validateParameterTypeString = Globalize._validateParameterTypeString; +var numberParse = Globalize._numberParse; +var numberParserFn = Globalize._numberParserFn; +var validateParameterTypeDate = Globalize._validateParameterTypeDate; +var dateFormat = Globalize._dateFormat; +var dateFormatterFn = Globalize._dateFormatterFn; +var dateTokenizer = Globalize._dateTokenizer; +var dateParse = Globalize._dateParse; +var dateParserFn = Globalize._dateParserFn; -Globalize.load({ - "supplemental": { - "version": { - "_unicodeVersion": "7.0.0", - "_number": "$Revision: 11318 $" - }, - "generation": { - "_date": "$Date: 2015-02-25 23:47:56 -0600 (Wed, 25 Feb 2015) $" - }, - "weekData": { - "minDays": { - "001": "1", - "GU": "1", - "UM": "1", - "US": "1", - "VI": "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", - "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", - "VA": "4" - }, - "firstDay": { - "001": "mon", - "AD": "mon", - "AI": "mon", - "AL": "mon", - "AM": "mon", - "AN": "mon", - "AT": "mon", - "AX": "mon", - "AZ": "mon", - "BA": "mon", - "BE": "mon", - "BG": "mon", - "BM": "mon", - "BN": "mon", - "BY": "mon", - "CH": "mon", - "CL": "mon", - "CM": "mon", - "CR": "mon", - "CY": "mon", - "CZ": "mon", - "DE": "mon", - "DK": "mon", - "EC": "mon", - "EE": "mon", - "ES": "mon", - "FI": "mon", - "FJ": "mon", - "FO": "mon", - "FR": "mon", - "GB": "mon", - "GE": "mon", - "GF": "mon", - "GP": "mon", - "GR": "mon", - "HR": "mon", - "HU": "mon", - "IS": "mon", - "IT": "mon", - "KG": "mon", - "KZ": "mon", - "LB": "mon", - "LI": "mon", - "LK": "mon", - "LT": "mon", - "LU": "mon", - "LV": "mon", - "MC": "mon", - "MD": "mon", - "ME": "mon", - "MK": "mon", - "MN": "mon", - "MQ": "mon", - "MY": "mon", - "NL": "mon", - "NO": "mon", - "PL": "mon", - "PT": "mon", - "RE": "mon", - "RO": "mon", - "RS": "mon", - "RU": "mon", - "SE": "mon", - "SI": "mon", - "SK": "mon", - "SM": "mon", - "TJ": "mon", - "TM": "mon", - "TR": "mon", - "UA": "mon", - "UY": "mon", - "UZ": "mon", - "VA": "mon", - "VN": "mon", - "XK": "mon", - "AE": "sat", - "AF": "sat", - "BH": "sat", - "DJ": "sat", - "DZ": "sat", - "EG": "sat", - "IQ": "sat", - "IR": "sat", - "JO": "sat", - "KW": "sat", - "LY": "sat", - "MA": "sat", - "OM": "sat", - "QA": "sat", - "SD": "sat", - "SY": "sat", - "AG": "sun", - "AR": "sun", - "AS": "sun", - "AU": "sun", - "BR": "sun", - "BS": "sun", - "BT": "sun", - "BW": "sun", - "BZ": "sun", - "CA": "sun", - "CN": "sun", - "CO": "sun", - "DM": "sun", - "DO": "sun", - "ET": "sun", - "GT": "sun", - "GU": "sun", - "HK": "sun", - "HN": "sun", - "ID": "sun", - "IE": "sun", - "IL": "sun", - "IN": "sun", - "JM": "sun", - "JP": "sun", - "KE": "sun", - "KH": "sun", - "KR": "sun", - "LA": "sun", - "MH": "sun", - "MM": "sun", - "MO": "sun", - "MT": "sun", - "MX": "sun", - "MZ": "sun", - "NI": "sun", - "NP": "sun", - "NZ": "sun", - "PA": "sun", - "PE": "sun", - "PH": "sun", - "PK": "sun", - "PR": "sun", - "PY": "sun", - "SA": "sun", - "SG": "sun", - "SV": "sun", - "TH": "sun", - "TN": "sun", - "TT": "sun", - "TW": "sun", - "UM": "sun", - "US": "sun", - "VE": "sun", - "VI": "sun", - "WS": "sun", - "YE": "sun", - "ZA": "sun", - "ZW": "sun", - "BD": "fri", - "MV": "fri" - }, - "firstDay-alt-variant": { - "GB": "sun" - }, - "weekendStart": { - "001": "sat", - "AE": "fri", - "BH": "fri", - "DZ": "fri", - "EG": "fri", - "IL": "fri", - "IQ": "fri", - "IR": "fri", - "JO": "fri", - "KW": "fri", - "LY": "fri", - "MA": "fri", - "OM": "fri", - "QA": "fri", - "SA": "fri", - "SD": "fri", - "SY": "fri", - "TN": "fri", - "YE": "fri", - "AF": "thu", - "IN": "sun" - }, - "weekendEnd": { - "001": "sun", - "AE": "sat", - "BH": "sat", - "DZ": "sat", - "EG": "sat", - "IL": "sat", - "IQ": "sat", - "JO": "sat", - "KW": "sat", - "LY": "sat", - "MA": "sat", - "OM": "sat", - "QA": "sat", - "SA": "sat", - "SD": "sat", - "SY": "sat", - "TN": "sat", - "YE": "sat", - "AF": "fri", - "IR": "fri" - } - } - } -}); +Globalize.a126395188 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","NaN",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]); +Globalize.a1378886668 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","NaN",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]); +Globalize.b203855544 = numberFormatterFn(["",,2,,,,,,,,"","00","-00","-","",numberRound(),"∞","NaN",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]); +Globalize.a1916379524 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","ليس رقم",{".":"٫",",":"٬","%":"٪","+":"‏+","-":"‏-","E":"اس","‰":"؉"},"٠١٢٣٤٥٦٧٨٩"]); +Globalize.b376385760 = numberFormatterFn(["",,2,,,,,,,,"","00","-00","-","",numberRound(),"∞","NaN",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]); +Globalize.a1711088039 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","NaN",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]); +Globalize.b1148906457 = numberFormatterFn(["",,1,,,,,,,,"","0","-0","-","",numberRound(),"∞","NaN",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]); +Globalize.b1256031091 = numberFormatterFn(["",,2,,,,,,,,"","00","-00","-","",numberRound(),"∞","NaN",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},]); +Globalize.b1965900303 = numberParserFn(["∞",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]); +Globalize.b960923264 = numberParserFn(["∞",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]); +Globalize.b2076722823 = numberParserFn(["∞",{".":"decimal",",":"group","%":"percentSign","+":"plusSign","-":"minusSign","E":"exponential","‰":"perMille","٫":".","٬":",","٪":"%","‏+":"+","‏-":"-","اس":"E","؉":"‰"},"-","",{"0":"invalid","1":"invalid","2":"invalid","3":"invalid","4":"invalid","5":"invalid","6":"invalid","7":"invalid","8":"invalid","9":"invalid","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9"}]); +Globalize.b1370229258 = numberParserFn(["∞",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]); +Globalize.a1749351181 = numberParserFn(["∞",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]); +Globalize.b2002841143 = numberParserFn(["∞",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]); +Globalize.b755631779 = numberParserFn(["∞",{".":"decimal",",":"group","%":"percentSign","+":"plusSign","-":"minusSign","E":"exponential","‰":"perMille","٫":".","٬":",","٪":"%","‏+":"+","‏-":"-","اس":"E","؉":"‰"},"-","",{"0":"invalid","1":"invalid","2":"invalid","3":"invalid","4":"invalid","5":"invalid","6":"invalid","7":"invalid","8":"invalid","9":"invalid","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9"}]); +Globalize.b1293124635 = numberParserFn(["∞",{".":".",",":",","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]); +Globalize.a474049536 = numberParserFn(["∞",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]); +Globalize.b1961282698 = numberParserFn(["∞",{".":",",",":".","%":"%","+":"+","-":"-","E":"E","‰":"‰"},"-","",]); +Globalize.a1750470059 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"الأحد","mon":"الاثنين","tue":"الثلاثاء","wed":"الأربعاء","thu":"الخميس","fri":"الجمعة","sat":"السبت"}}}}); +Globalize.b617625506 = dateFormatterFn({"1":Globalize("en").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":0}); +Globalize.b93641787 = dateFormatterFn({"1":Globalize("en").numberFormatter({"raw":"0"}),"2":Globalize("en").numberFormatter({"raw":"00"})}, {"pattern":"M/d/yy","timeSeparator":":"}); +Globalize.b80132650 = dateFormatterFn({"1":Globalize("ar").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":6}); +Globalize.a682848010 = dateFormatterFn({"1":Globalize("zh").numberFormatter({"raw":"0"})}, {"pattern":"y/M/d","timeSeparator":":"}); +Globalize.b1836232371 = dateFormatterFn({"1":Globalize("ar").numberFormatter({"raw":"0"})}, {"pattern":"d‏/M‏/y","timeSeparator":":"}); +Globalize.a218160295 = dateFormatterFn({"1":Globalize("en").numberFormatter({"raw":"0"})}, {"pattern":"MMMM d, y","timeSeparator":":","months":{"M":{"4":{"1":"January","2":"February","3":"March","4":"April","5":"May","6":"June","7":"July","8":"August","9":"September","10":"October","11":"November","12":"December"}}}}); +Globalize.b285424135 = dateFormatterFn({"1":Globalize("zh").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":0}); +Globalize.a1351587010 = dateFormatterFn({"1":Globalize("zh").numberFormatter({"raw":"0"})}, {"pattern":"y年M月d日","timeSeparator":":"}); +Globalize.b1382770181 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"So.","mon":"Mo.","tue":"Di.","wed":"Mi.","thu":"Do.","fri":"Fr.","sat":"Sa."}}}}); +Globalize.b1430109660 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"S","mon":"M","tue":"D","wed":"M","thu":"D","fri":"F","sat":"S"}}}}); +Globalize.a1754951899 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"Sonntag","mon":"Montag","tue":"Dienstag","wed":"Mittwoch","thu":"Donnerstag","fri":"Freitag","sat":"Samstag"}}}}); +Globalize.a501706459 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"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"}}}}); +Globalize.b1869521166 = dateFormatterFn({"1":Globalize("de").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":1,"minDays":4}); +Globalize.a864358539 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"الأحد","mon":"الاثنين","tue":"الثلاثاء","wed":"الأربعاء","thu":"الخميس","fri":"الجمعة","sat":"السبت"}}}}); +Globalize.b1870116986 = dateFormatterFn({"1":Globalize("de").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":1}); +Globalize.a1026267252 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"ح","mon":"ن","tue":"ث","wed":"ر","thu":"خ","fri":"ج","sat":"س"}}}}); +Globalize.b392241633 = dateFormatterFn({"1":Globalize("ar").numberFormatter({"raw":"0"})}, {"pattern":"d MMMM، y","timeSeparator":":","months":{"M":{"4":{"1":"يناير","2":"فبراير","3":"مارس","4":"أبريل","5":"مايو","6":"يونيو","7":"يوليو","8":"أغسطس","9":"سبتمبر","10":"أكتوبر","11":"نوفمبر","12":"ديسمبر"}}}}); +Globalize.b388886901 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"1":"يناير","2":"فبراير","3":"مارس","4":"أبريل","5":"مايو","6":"يونيو","7":"يوليو","8":"أغسطس","9":"سبتمبر","10":"أكتوبر","11":"نوفمبر","12":"ديسمبر"}}}}); +Globalize.b79536830 = dateFormatterFn({"1":Globalize("ar").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":6,"minDays":1}); +Globalize.a1446348751 = dateFormatterFn({"1":Globalize("de").numberFormatter({"raw":"0"})}, {"pattern":"d. MMMM y","timeSeparator":":","months":{"M":{"4":{"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"}}}}); +Globalize.b284828315 = dateFormatterFn({"1":Globalize("zh").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":0,"minDays":1}); +Globalize.b801906653 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"Su","mon":"Mo","tue":"Tu","wed":"We","thu":"Th","fri":"Fr","sat":"Sa"}}}}); +Globalize.b729298712 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"DO","mon":"LU","tue":"MA","wed":"MI","thu":"JU","fri":"VI","sat":"SA"}}}}); +Globalize.a946274711 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"D","mon":"L","tue":"M","wed":"X","thu":"J","fri":"V","sat":"S"}}}}); +Globalize.b1770621176 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"domingo","mon":"lunes","tue":"martes","wed":"miércoles","thu":"jueves","fri":"viernes","sat":"sábado"}}}}); +Globalize.a1271100680 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"1":"enero","2":"febrero","3":"marzo","4":"abril","5":"mayo","6":"junio","7":"julio","8":"agosto","9":"septiembre","10":"octubre","11":"noviembre","12":"diciembre"}}}}); +Globalize.a1150144485 = dateFormatterFn({"1":Globalize("es").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":1,"minDays":4}); +Globalize.a1636669180 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"S","mon":"M","tue":"T","wed":"W","thu":"T","fri":"F","sat":"S"}}}}); +Globalize.a1149548665 = dateFormatterFn({"1":Globalize("es").numberFormatter({"raw":"0"})}, {"pattern":"c","timeSeparator":":","firstDay":1}); +Globalize.b21033846 = dateFormatterFn({"1":Globalize("es").numberFormatter({"raw":"0"}),"2":Globalize("es").numberFormatter({"raw":"00"})}, {"pattern":"d/M/yy","timeSeparator":":"}); +Globalize.a52764931 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"Sunday","mon":"Monday","tue":"Tuesday","wed":"Wednesday","thu":"Thursday","fri":"Friday","sat":"Saturday"}}}}); +Globalize.b194087032 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"1":"一月","2":"二月","3":"三月","4":"四月","5":"五月","6":"六月","7":"七月","8":"八月","9":"九月","10":"十月","11":"十一月","12":"十二月"}}}}); +Globalize.b1200480509 = dateFormatterFn({}, {"pattern":"MMMM","timeSeparator":":","months":{"M":{"4":{"1":"January","2":"February","3":"March","4":"April","5":"May","6":"June","7":"July","8":"August","9":"September","10":"October","11":"November","12":"December"}}}}); +Globalize.b472234174 = dateFormatterFn({"1":Globalize("es").numberFormatter({"raw":"0"})}, {"pattern":"d 'de' MMMM 'de' y","timeSeparator":":","months":{"M":{"4":{"1":"enero","2":"febrero","3":"marzo","4":"abril","5":"mayo","6":"junio","7":"julio","8":"agosto","9":"septiembre","10":"octubre","11":"noviembre","12":"diciembre"}}}}); +Globalize.a1059158408 = dateFormatterFn({}, {"pattern":"EEEE","timeSeparator":":","days":{"E":{"4":{"sun":"星期日","mon":"星期一","tue":"星期二","wed":"星期三","thu":"星期四","fri":"星期五","sat":"星期六"}}}}); +Globalize.b617029686 = dateFormatterFn({"1":Globalize("en").numberFormatter({"raw":"0"})}, {"pattern":"w","timeSeparator":":","firstDay":0,"minDays":1}); +Globalize.b25416856 = dateFormatterFn({}, {"pattern":"EEEEEE","timeSeparator":":","days":{"E":{"6":{"sun":"周日","mon":"周一","tue":"周二","wed":"周三","thu":"周四","fri":"周五","sat":"周六"}}}}); +Globalize.b1524871401 = dateFormatterFn({}, {"pattern":"EEEEE","timeSeparator":":","days":{"E":{"5":{"sun":"日","mon":"一","tue":"二","wed":"三","thu":"四","fri":"五","sat":"六"}}}}); +Globalize.b674505315 = dateFormatterFn({"2":Globalize("de").numberFormatter({"raw":"00"})}, {"pattern":"dd.MM.yy","timeSeparator":":"}); +Globalize.b1518991631 = dateParserFn(Globalize("es").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"d 'de' MMMM 'de' y","timeSeparator":":","gregorian/months/format/wide":{"1":"enero","2":"febrero","3":"marzo","4":"abril","5":"mayo","6":"junio","7":"julio","8":"agosto","9":"septiembre","10":"octubre","11":"noviembre","12":"diciembre"}}); +Globalize.a399591294 = dateParserFn(Globalize("de").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"d. MMMM y","timeSeparator":":","gregorian/months/format/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"}}); +Globalize.a1235751886 = dateParserFn(Globalize("de").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"dd.MM.yy","timeSeparator":":"}); +Globalize.b828597162 = dateParserFn(Globalize("en").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"MMMM d, y","timeSeparator":":","gregorian/months/format/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"}}); +Globalize.a1889223355 = dateParserFn(Globalize("es").numberParser({"raw":"0"}), {"preferredTimeData":"H"}, {"pattern":"d/M/yy","timeSeparator":":"}); +Globalize.b1701862085 = dateParserFn(Globalize("zh").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"y/M/d","timeSeparator":":"}); +Globalize.b1438999090 = dateParserFn(Globalize("ar").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"d MMMM، y","timeSeparator":":","gregorian/months/format/wide":{"1":"يناير","2":"فبراير","3":"مارس","4":"أبريل","5":"مايو","6":"يونيو","7":"يوليو","8":"أغسطس","9":"سبتمبر","10":"أكتوبر","11":"نوفمبر","12":"ديسمبر"}}); +Globalize.a74024830 = dateParserFn(Globalize("ar").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"d‏/M‏/y","timeSeparator":":"}); +Globalize.a304829553 = dateParserFn(Globalize("zh").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"y年M月d日","timeSeparator":":"}); +Globalize.a1816615414 = dateParserFn(Globalize("en").numberParser({"raw":"0"}), {"preferredTimeData":"h"}, {"pattern":"M/d/yy","timeSeparator":":"}); return Globalize; -} ) ); +})); diff --git a/package.json b/package.json index 599efbb5a6f..1ea3d972b3d 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,9 @@ }, "dependencies": {}, "devDependencies": { + "cldr-data": ">=26", "commitplease": "2.0.0", + "globalize-compiler": "0.1.1", "grunt": "0.4.2", "grunt-bowercopy": "1.1.0", "grunt-compare-size": "0.4.0", From 9a879d0fdc725f2a7ae6c35949a72cc03946bf58 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Nov 2015 17:04:55 +0100 Subject: [PATCH 114/179] Calendar: Fix first day of week calculation for non latin locales --- ui/widgets/calendar.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index 25bb79be4a0..c056a9ac277 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -196,14 +196,13 @@ return $.widget( "ui.calendar", { _setLocale: function( locale, dateFormat ) { var globalize = new Globalize( locale ), weekdayShortFormatter = globalize.dateFormatter( { raw: "EEEEEE" } ), - weekdayNarrowFormatter = globalize.dateFormatter( { raw: "EEEEE" } ); + weekdayNarrowFormatter = globalize.dateFormatter( { raw: "EEEEE" } ), + firstDayRaw = globalize.dateFormatter( { raw: "c" } )( new Date( 1970, 0, 3 ) ); this._format = globalize.dateFormatter( dateFormat ); this._parse = globalize.dateParser( dateFormat ); this._calendarDateOptions = { - - // Calculate localized first day of week (reference is first saturday) - firstDay: ( 6 - globalize.dateFormatter( { raw: "c" } )( new Date( 1970, 0, 3 ) ) + 1 ), + firstDay: ( 7 - globalize.parseNumber( firstDayRaw ) ), formatWeekdayShort: function( date ) { // Return the short weekday if its length is < 3. Otherwise, its narrow form. From d53f549c37353b5be634d78f5d06a7facef0ff28 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Nov 2015 17:05:33 +0100 Subject: [PATCH 115/179] Datepicker: Fix outdated Globalize format option in date-format demo --- demos/datepicker/date-formats.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index 500c4a7f6ec..a234e223b36 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -15,7 +15,7 @@ value = $( this ).val(); if ( value === "iso" ) { - datepicker.datepicker( "option", "dateFormat", { pattern: "yyyy-MM-dd" } ); + datepicker.datepicker( "option", "dateFormat", { raw: "yyyy-MM-dd" } ); } else { datepicker.datepicker( "option", "dateFormat", { date: value } ); } From 9fdefeecb99f43da95ec39f61b9538bb23cbd4b8 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 18 Nov 2015 17:06:20 +0100 Subject: [PATCH 116/179] Calendar: Remove unused data-modules attribute from localization demo --- demos/calendar/localization.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/calendar/localization.html b/demos/calendar/localization.html index dfd8b1f1e68..2c2cc2310d1 100644 --- a/demos/calendar/localization.html +++ b/demos/calendar/localization.html @@ -7,7 +7,7 @@ - @@ -19,7 +82,7 @@
      -

      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.

      +

      Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes.

      From 5ee64dd0e0743643f3e314d898b45669b4db0a49 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 12 Apr 2017 22:47:27 +0200 Subject: [PATCH 176/179] Calendar: Introduce build methods for year and month title --- demos/calendar/dropdown-month-year.html | 18 ++---------------- ui/widgets/calendar.js | 12 ++++++++++-- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/demos/calendar/dropdown-month-year.html b/demos/calendar/dropdown-month-year.html index e9571343f01..e1c03630ddb 100644 --- a/demos/calendar/dropdown-month-year.html +++ b/demos/calendar/dropdown-month-year.html @@ -9,21 +9,7 @@