Bug 1329927 - Use mozIntl.getDisplayNames for date picker UI r=mconley
authorScott Wu <scottcwwu@gmail.com>
Tue, 14 Feb 2017 13:07:22 +0800
changeset 343260 dce3a8ef420554b81f5541c9248ee4f50de42bcc
parent 343259 df87366fda49daa8aaa4d4c9102d02fdfbefbb0a
child 343261 b25738421d6e3390548b27c224cdcd2dfa613133
push id31374
push userkwierso@gmail.com
push dateThu, 16 Feb 2017 17:26:30 +0000
treeherdermozilla-central@4158b1d8bb2a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs1329927
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1329927 - Use mozIntl.getDisplayNames for date picker UI r=mconley MozReview-Commit-ID: LqKzK9jx1i6
toolkit/content/widgets/datepicker.js
toolkit/content/widgets/datetimepopup.xml
--- a/toolkit/content/widgets/datepicker.js
+++ b/toolkit/content/widgets/datepicker.js
@@ -15,16 +15,20 @@ function DatePicker(context) {
   DatePicker.prototype = {
     /**
      * Initializes the date picker. Set the default states and properties.
      * @param  {Object} props
      *         {
      *           {Number} year [optional]
      *           {Number} month [optional]
      *           {Number} date [optional]
+     *           {Number} firstDayOfWeek
+     *           {Array<Number>} weekends
+     *           {Array<String>} monthStrings
+     *           {Array<String>} weekdayStrings
      *           {String} locale [optional]: User preferred locale
      *         }
      */
     init(props = {}) {
       this.props = props;
       this._setDefaultState();
       this._createComponents();
       this._update();
@@ -35,16 +39,18 @@ function DatePicker(context) {
      */
     _setDefaultState() {
       const now = new Date();
       const { year = now.getFullYear(),
               month = now.getMonth(),
               day = now.getDate(),
               firstDayOfWeek,
               weekends,
+              monthStrings,
+              weekdayStrings,
               locale } = this.props;
       const dateKeeper = new DateKeeper({
         year, month, day
       }, {
         firstDayOfWeek,
         weekends,
         calViewSize: CAL_VIEW_SIZE
       });
@@ -52,18 +58,18 @@ function DatePicker(context) {
       this.state = {
         dateKeeper,
         locale,
         isMonthPickerVisible: false,
         isYearSet: false,
         isMonthSet: false,
         isDateSet: false,
         getDayString: new Intl.NumberFormat(locale).format,
-        // TODO: use calendar terms when available (Bug 1287677)
-        getWeekHeaderString: weekday => ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][weekday],
+        getWeekHeaderString: weekday => weekdayStrings[weekday],
+        getMonthString: month => monthStrings[month],
         setValue: ({ dateValue, selectionValue }) => {
           dateKeeper.setValue(dateValue);
           this.state.selectionValue = selectionValue;
           this.state.isYearSet = true;
           this.state.isMonthSet = true;
           this.state.isDateSet = true;
           this._update();
           this._dispatchState();
@@ -98,16 +104,17 @@ function DatePicker(context) {
           locale: this.state.locale
         }, {
           weekHeader: this.context.weekHeader,
           daysView: this.context.daysView
         }),
         monthYear: new MonthYear({
           setYear: this.state.setYear,
           setMonth: this.state.setMonth,
+          getMonthString: this.state.getMonthString,
           locale: this.state.locale
         }, {
           monthYear: this.context.monthYear,
           monthYearView: this.context.monthYearView
         })
       };
     },
 
@@ -274,35 +281,35 @@ function DatePicker(context) {
   /**
    * MonthYear is a component that handles the month & year spinners
    *
    * @param {Object} options
    *        {
    *          {String} locale
    *          {Function} setYear
    *          {Function} setMonth
+   *          {Function} getMonthString
    *        }
    * @param {DOMElement} context
    */
   function MonthYear(options, context) {
     const spinnerSize = 5;
-    const monthFormat = new Intl.DateTimeFormat(options.locale, { month: "short", timeZone: "UTC" }).format;
     const yearFormat = new Intl.DateTimeFormat(options.locale, { year: "numeric" }).format;
     const dateFormat = new Intl.DateTimeFormat(options.locale, { year: "numeric", month: "long" }).format;
 
     this.context = context;
     this.state = { dateFormat };
     this.props = {};
     this.components = {
       month: new Spinner({
         setValue: month => {
           this.state.isMonthSet = true;
           options.setMonth(month);
         },
-        getDisplayString: month => monthFormat(new Date(Date.UTC(0, month))),
+        getDisplayString: options.getMonthString,
         viewportSize: spinnerSize
       }, context.monthYearView),
       year: new Spinner({
         setValue: year => {
           this.state.isYearSet = true;
           options.setYear(year);
         },
         getDisplayString: year => yearFormat(new Date(new Date(0).setFullYear(year))),
--- a/toolkit/content/widgets/datetimepopup.xml
+++ b/toolkit/content/widgets/datetimepopup.xml
@@ -17,16 +17,23 @@
     <implementation>
       <field name="dateTimePopupFrame">
         this.querySelector("#dateTimePopupFrame");
       </field>
       <field name="TIME_PICKER_WIDTH" readonly="true">"12em"</field>
       <field name="TIME_PICKER_HEIGHT" readonly="true">"21em"</field>
       <field name="DATE_PICKER_WIDTH" readonly="true">"23.1em"</field>
       <field name="DATE_PICKER_HEIGHT" readonly="true">"20.7em"</field>
+      <constructor><![CDATA[
+        this.l10n = {};
+        const mozIntl = Components.classes["@mozilla.org/mozintl;1"]
+                          .getService(Components.interfaces.mozIMozIntl);
+        mozIntl.addGetCalendarInfo(l10n);
+        mozIntl.addGetDisplayNames(l10n);
+      ]]></constructor>
       <method name="loadPicker">
         <parameter name="type"/>
         <parameter name="detail"/>
         <body><![CDATA[
           this.hidden = false;
           this.type = type;
           this.pickerState = {};
           // TODO: Resize picker according to content zoom level
@@ -112,26 +119,53 @@
                 }
               });
               break;
             }
             case "date": {
               const { year, month, day } = detail.value;
               const { firstDayOfWeek, weekends } =
                 this.getCalendarInfo(locale);
+              const monthStrings = this.getDisplayNames(
+                locale, [
+                  "dates/gregorian/months/january",
+                  "dates/gregorian/months/february",
+                  "dates/gregorian/months/march",
+                  "dates/gregorian/months/april",
+                  "dates/gregorian/months/may",
+                  "dates/gregorian/months/june",
+                  "dates/gregorian/months/july",
+                  "dates/gregorian/months/august",
+                  "dates/gregorian/months/september",
+                  "dates/gregorian/months/october",
+                  "dates/gregorian/months/november",
+                  "dates/gregorian/months/december",
+                ], "short");
+              const weekdayStrings = this.getDisplayNames(
+                locale, [
+                  "dates/gregorian/weekdays/sunday",
+                  "dates/gregorian/weekdays/monday",
+                  "dates/gregorian/weekdays/tuesday",
+                  "dates/gregorian/weekdays/wednesday",
+                  "dates/gregorian/weekdays/thursday",
+                  "dates/gregorian/weekdays/friday",
+                  "dates/gregorian/weekdays/saturday",
+                ], "short");
 
               this.postMessageToPicker({
                 name: "PickerInit",
                 detail: {
                   year,
                   // Month value from input box starts from 1 instead of 0
                   month: month == undefined ? undefined : month - 1,
                   day,
                   firstDayOfWeek,
                   weekends,
+                  monthStrings,
+                  weekdayStrings,
                   locale
                 }
               });
               break;
             }
           }
         ]]></body>
       </method>
@@ -187,21 +221,17 @@
               break;
             }
           }
         ]]></body>
       </method>
       <method name="getCalendarInfo">
         <parameter name="locale"/>
         <body><![CDATA[
-          const l10n = {};
-          const mozIntl = Components.classes["@mozilla.org/mozintl;1"]
-                            .getService(Components.interfaces.mozIMozIntl);
-          mozIntl.addGetCalendarInfo(l10n);
-          const calendarInfo = l10n.getCalendarInfo(locale);
+          const calendarInfo = this.l10n.getCalendarInfo(locale);
 
           // Day of week from calendarInfo starts from 1 as Sunday to 7 as Saturday,
           // so they need to be mapped to JavaScript convention with 0 as Sunday
           // and 6 as Saturday
           let firstDayOfWeek = calendarInfo.firstDayOfWeek - 1,
               weekendStart = calendarInfo.weekendStart - 1,
               weekendEnd = calendarInfo.weekendEnd - 1;
 
@@ -219,16 +249,25 @@
           }
 
           return {
             firstDayOfWeek,
             weekends
           }
         ]]></body>
       </method>
+      <method name="getDisplayNames">
+        <parameter name="locale"/>
+        <parameter name="keys"/>
+        <parameter name="style"/>
+        <body><![CDATA[
+          const displayNames = this.l10n.getDisplayNames(locale, {keys, style});
+          return keys.map(key => displayNames.values[key]);
+        ]]></body>
+      </method>
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           switch (aEvent.type) {
             case "load": {
               this.initPicker(this.detail);
               this.dateTimePopupFrame.contentWindow.addEventListener("message", this);
               break;