Bug 1301655 - pt 3 - Replace use of nsIScriptableDateFormat with Intl API methods in browser/components/places code. r=gandalf
authorJonathan Kew <jkew@mozilla.com>
Fri, 28 Oct 2016 12:04:07 +0100
changeset 319931 68543a46ef49fb7309c345179c87912b8d75e41b
parent 319930 625ba7fc4b96abe8474f5f478b39692e72dd1233
child 319932 59f24ab7fc079e573cbdb2fb8d828a951639e62a
push id83271
push userjkew@mozilla.com
push dateFri, 28 Oct 2016 11:07:26 +0000
treeherdermozilla-inbound@686282bd2f19 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgandalf
bugs1301655
milestone52.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 1301655 - pt 3 - Replace use of nsIScriptableDateFormat with Intl API methods in browser/components/places code. r=gandalf
browser/components/places/content/places.js
browser/components/places/content/treeView.js
browser/components/places/tests/chrome/test_treeview_date.xul
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -406,18 +406,21 @@ var PlacesOrganizer = {
   },
 
   /**
    * Populates the restore menu with the dates of the backups available.
    */
   populateRestoreMenu: function PO_populateRestoreMenu() {
     let restorePopup = document.getElementById("fileRestorePopup");
 
-    let dateSvc = Cc["@mozilla.org/intl/scriptabledateformat;1"].
-                  getService(Ci.nsIScriptableDateFormat);
+    const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                   .getService(Ci.nsIXULChromeRegistry)
+                   .getSelectedLocale("global", true);
+    const dtOptions = { year: 'numeric', month: 'long', day: 'numeric' };
+    let dateFormatter = new Intl.DateTimeFormat(locale, dtOptions);
 
     // Remove existing menu items.  Last item is the restoreFromFile item.
     while (restorePopup.childNodes.length > 1)
       restorePopup.removeChild(restorePopup.firstChild);
 
     Task.spawn(function* () {
       let backupFiles = yield PlacesBackups.getBackupFiles();
       if (backupFiles.length == 0)
@@ -439,23 +442,17 @@ var PlacesOrganizer = {
                      ")";
         } else {
           sizeInfo = " (" + sizeString + ")";
         }
 
         let backupDate = PlacesBackups.getDateForFile(backupFiles[i]);
         let m = restorePopup.insertBefore(document.createElement("menuitem"),
                                           document.getElementById("restoreFromFile"));
-        m.setAttribute("label",
-                       dateSvc.FormatDate("",
-                                          Ci.nsIScriptableDateFormat.dateFormatLong,
-                                          backupDate.getFullYear(),
-                                          backupDate.getMonth() + 1,
-                                          backupDate.getDate()) +
-                                          sizeInfo);
+        m.setAttribute("label", dateFormatter.format(backupDate) + sizeInfo);
         m.setAttribute("value", OS.Path.basename(backupFiles[i]));
         m.setAttribute("oncommand",
                        "PlacesOrganizer.onRestoreMenuItemClick(this);");
       }
 
       // Add the restoreFromFile item.
       restorePopup.insertBefore(document.createElement("menuseparator"),
                                 document.getElementById("restoreFromFile"));
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -28,25 +28,16 @@ PlacesTreeView.prototype = {
   __xulStore: null,
   get _xulStore() {
     if (!this.__xulStore) {
       this.__xulStore = Cc["@mozilla.org/xul/xulstore;1"].getService(Ci.nsIXULStore);
     }
     return this.__xulStore;
   },
 
-  __dateService: null,
-  get _dateService() {
-    if (!this.__dateService) {
-      this.__dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
-                           getService(Ci.nsIScriptableDateFormat);
-    }
-    return this.__dateService;
-  },
-
   QueryInterface: XPCOMUtils.generateQI(PTV_interfaces),
 
   // Bug 761494:
   // ----------
   // Some addons use methods from nsINavHistoryResultObserver and
   // nsINavHistoryResultTreeViewer, without QIing to these interfaces first.
   // That's not a problem when the view is retrieved through the
   // <tree>.view getter (which returns the wrappedJSObject of this object),
@@ -499,26 +490,46 @@ PlacesTreeView.prototype = {
     // milliseconds from today's midnight.
     // getTimezoneOffset corrects that based on local time, notice midnight
     // can have a different offset during DST-change days.
     let dateObj = new Date();
     let now = dateObj.getTime() - dateObj.getTimezoneOffset() * MS_PER_MINUTE;
     let midnight = now - (now % MS_PER_DAY);
     midnight += new Date(midnight).getTimezoneOffset() * MS_PER_MINUTE;
 
-    let dateFormat = timeMs >= midnight ?
-                      Ci.nsIScriptableDateFormat.dateFormatNone :
-                      Ci.nsIScriptableDateFormat.dateFormatShort;
+    let timeObj = new Date(timeMs);
+    return timeMs >= midnight ? this._todayFormatter.format(timeObj)
+                              : this._dateFormatter.format(timeObj);
+  },
 
-    let timeObj = new Date(timeMs);
-    return (this._dateService.FormatDateTime("", dateFormat,
-      Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
-      timeObj.getFullYear(), timeObj.getMonth() + 1,
-      timeObj.getDate(), timeObj.getHours(),
-      timeObj.getMinutes(), timeObj.getSeconds()));
+  // We use a different formatter for times within the current day,
+  // so we cache both a "today" formatter and a general date formatter.
+  __todayFormatter: null,
+  get _todayFormatter() {
+    if (!this.__todayFormatter) {
+      const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                     .getService(Ci.nsIXULChromeRegistry)
+                     .getSelectedLocale("global", true);
+      const dtOptions = { hour: 'numeric', minute: 'numeric' };
+      this.__todayFormatter = new Intl.DateTimeFormat(locale, dtOptions);
+    }
+    return this.__todayFormatter;
+  },
+
+  __dateFormatter: null,
+  get _dateFormatter() {
+    if (!this.__dateFormatter) {
+      const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                     .getService(Ci.nsIXULChromeRegistry)
+                     .getSelectedLocale("global", true);
+      const dtOptions = { year: '2-digit', month: 'numeric', day: 'numeric',
+                          hour: 'numeric', minute: 'numeric' };
+      this.__dateFormatter = new Intl.DateTimeFormat(locale, dtOptions);
+    }
+    return this.__dateFormatter;
   },
 
   COLUMN_TYPE_UNKNOWN: 0,
   COLUMN_TYPE_TITLE: 1,
   COLUMN_TYPE_URI: 2,
   COLUMN_TYPE_DATE: 3,
   COLUMN_TYPE_VISITCOUNT: 4,
   COLUMN_TYPE_DESCRIPTION: 5,
--- a/browser/components/places/tests/chrome/test_treeview_date.xul
+++ b/browser/components/places/tests/chrome/test_treeview_date.xul
@@ -48,19 +48,16 @@
      * https://bugzilla.mozilla.org/show_bug.cgi?id=435322
      *
      * Ensures that date in places treeviews is correctly formatted.
      */
 
     function runTest() {
       SimpleTest.waitForExplicitFinish();
 
-      let ds = Cc["@mozilla.org/intl/scriptabledateformat;1"].
-               getService(Ci.nsIScriptableDateFormat);
-
       function uri(spec) {
         return Services.io.newURI(spec, null, null);
       }
 
       Task.spawn(function* () {
         yield PlacesTestUtils.clearHistory();
 
         let midnight = new Date();
@@ -102,16 +99,19 @@
         tree.place = queryURI;
 
         // loop through the rows and check formatting
         let treeView = tree.view;
         let rc = treeView.rowCount;
         ok(rc >= 3, "Rows found");
         let columns = tree.columns;
         ok(columns.count > 0, "Columns found");
+        const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                       .getService(Ci.nsIXULChromeRegistry)
+                       .getSelectedLocale("global", true);
         for (let r = 0; r < rc; r++) {
           let node = treeView.nodeForTreeIndex(r);
           ok(node, "Places node found");
           for (let ci = 0; ci < columns.count; ci++) {
             let c = columns.getColumnAt(ci);
             let text = treeView.getCellText(r, c);
             switch (c.element.getAttribute("anonid")) {
               case "title":
@@ -122,33 +122,28 @@
                   is(text, node.title, "Title is correct");
                 break;
               case "url":
                 is(text, node.uri, "Uri is correct");
                 break;
               case "date":
                 let timeObj = new Date(node.time / 1000);
                 // Default is short date format.
-                let dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
+                let dtOptions = { year: '2-digit', month: 'numeric', day: 'numeric',
+                                  hour: 'numeric', minute: 'numeric' };
                 // For today's visits we don't show date portion.
                 if (node.uri == "http://at.midnight.com/" ||
-                    node.uri == "http://after.midnight.com/")
-                  dateFormat = Ci.nsIScriptableDateFormat.dateFormatNone;
-                else if (node.uri == "http://before.midnight.com/")
-                  dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
-                else {
+                    node.uri == "http://after.midnight.com/") {
+                  dtOptions = { hour: 'numeric', minute: 'numeric' };
+                } else if (node.uri != "http://before.midnight.com/") {
                   // Avoid to test spurious uris, due to how the test works
                   // a redirecting uri could be put in the tree while we test.
                   break;
                 }
-                let timeStr = ds.FormatDateTime("", dateFormat,
-                      Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
-                      timeObj.getFullYear(), timeObj.getMonth() + 1,
-                      timeObj.getDate(), timeObj.getHours(),
-                      timeObj.getMinutes(), timeObj.getSeconds())
+                let timeStr = timeObj.toLocaleString(locale, dtOptions);
 
                 is(text, timeStr, "Date format is correct");
                 break;
               case "visitCount":
                 is(text, 1, "Visit count is correct");
                 break;
             }
           }