From a06d107c1041f5f3044d3b719073f9519e89fb59 Mon Sep 17 00:00:00 2001 From: Bill Gianopoulos Date: Sat, 15 Jul 2017 14:32:56 -0400 Subject: [PATCH] Bug 1376167 - Avoid use of nsIScriptableDateFomat in Seamonkey JavaScript files. r=IanN,frg --- suite/browser/pageinfo/pageInfo.js | 12 ++-- suite/common/bookmarks/bookmarksManager.js | 14 ++-- suite/common/dataman/dataman.js | 23 +++---- suite/common/downloads/treeView.js | 68 +++++++++++-------- suite/common/history/treeView.js | 68 +++++++++++-------- suite/common/permissions/cookieViewer.js | 18 ++--- .../tests/chrome/test_treeview_date.xul | 21 ++---- suite/common/places/treeView.js | 47 ++++++++----- suite/feeds/src/FeedWriter.js | 23 ++++--- 9 files changed, 153 insertions(+), 141 deletions(-) diff --git a/suite/browser/pageinfo/pageInfo.js b/suite/browser/pageinfo/pageInfo.js index 47c67843df..4e21bd0ec0 100644 --- a/suite/browser/pageinfo/pageInfo.js +++ b/suite/browser/pageinfo/pageInfo.js @@ -1307,18 +1307,14 @@ function formatNumber(number) function formatDate(datestr, unknown) { - // scriptable date formatter, for pretty printing dates - var dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"] - .getService(Components.interfaces.nsIScriptableDateFormat); - var date = new Date(datestr); if (!date.valueOf()) return unknown; - return dateService.FormatDateTime("", dateService.dateFormatLong, - dateService.timeFormatSeconds, - date.getFullYear(), date.getMonth()+1, date.getDate(), - date.getHours(), date.getMinutes(), date.getSeconds()); + const dtOptions = { year: "numeric", month: "long", day: "numeric", + hour: "numeric", minute: "numeric", second: "numeric", + timeZoneName: "short", weekday: "short" }; + return date.toLocaleString(undefined, dtOptions); } function getSelectedItems(linksMode) diff --git a/suite/common/bookmarks/bookmarksManager.js b/suite/common/bookmarks/bookmarksManager.js index 39e139c804..7e52075844 100644 --- a/suite/common/bookmarks/bookmarksManager.js +++ b/suite/common/bookmarks/bookmarksManager.js @@ -362,8 +362,11 @@ var PlacesOrganizer = { populateRestoreMenu: function PO_populateRestoreMenu() { let restorePopup = document.getElementById("fileRestorePopup"); - let dateSvc = Components.classes["@mozilla.org/intl/scriptabledateformat;1"] - .getService(Components.interfaces.nsIScriptableDateFormat); + const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"] + .getService(Components.interfaces.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) @@ -378,12 +381,7 @@ var PlacesOrganizer = { let backupDate = PlacesBackups.getDateForFile(backupFiles[i]); let m = restorePopup.insertBefore(document.createElement("menuitem"), document.getElementById("restoreFromFile")); - m.setAttribute("label", - dateSvc.FormatDate("", - Components.interfaces.nsIScriptableDateFormat.dateFormatLong, - backupDate.getFullYear(), - backupDate.getMonth() + 1, - backupDate.getDate())); + m.setAttribute("label", dateFormatter.format(backupDate)); m.setAttribute("value", backupFiles[i].leafName); m.setAttribute("oncommand", "PlacesOrganizer.onRestoreMenuItemClick(this);"); diff --git a/suite/common/dataman/dataman.js b/suite/common/dataman/dataman.js index d215790465..cabb9d95d6 100644 --- a/suite/common/dataman/dataman.js +++ b/suite/common/dataman/dataman.js @@ -10,9 +10,6 @@ Components.utils.import("resource://gre/modules/DownloadUtils.jsm"); // locally loaded services var gLocSvc = {}; -XPCOMUtils.defineLazyServiceGetter(gLocSvc, "date", - "@mozilla.org/intl/scriptabledateformat;1", - "nsIScriptableDateFormat"); XPCOMUtils.defineLazyModuleGetter(gLocSvc, "FormHistory", "resource://gre/modules/FormHistory.jsm", "FormHistory"); @@ -982,11 +979,11 @@ var gCookies = { // See bug 238045 for details. let expiry = ""; try { - expiry = gLocSvc.date.FormatDateTime("", gLocSvc.date.dateFormatLong, - gLocSvc.date.timeFormatSeconds, - date.getFullYear(), date.getMonth()+1, - date.getDate(), date.getHours(), - date.getMinutes(), date.getSeconds()); + const dtOptions = { year: "numeric", month: "long", day: "numeric", + hour: "numeric", minute: "numeric", + second: "numeric", timeZoneName: "short", + weekday: "short" }; + expiry = date.toLocaleString(undefined, dtOptions); } catch (e) {} return expiry; @@ -2854,11 +2851,11 @@ var gFormdata = { // See bug 238045 for details. let dtString = ""; try { - dtString = gLocSvc.date.FormatDateTime("", gLocSvc.date.dateFormatLong, - gLocSvc.date.timeFormatSeconds, - date.getFullYear(), date.getMonth()+1, - date.getDate(), date.getHours(), - date.getMinutes(), date.getSeconds()); + const dtOptions = { year: "numeric", month: "long", day: "numeric", + hour: "numeric", minute: "numeric", + second: "numeric", timeZoneName: "short", + weekday: "short" }; + dtString = date.toLocaleString(undefined, dtOptions); } catch (e) {} return dtString; diff --git a/suite/common/downloads/treeView.js b/suite/common/downloads/treeView.js index 42f9a6aeea..da6bfe2cad 100644 --- a/suite/common/downloads/treeView.js +++ b/suite/common/downloads/treeView.js @@ -466,18 +466,9 @@ DownloadTreeView.prototype = { _dlBundle: null, _lastListIndex: 0, _selectionCache: null, - __dateService: null, // ***** local helper functions ***** - get _dateService() { - if (!this.__dateService) { - this.__dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"] - .getService(Components.interfaces.nsIScriptableDateFormat); - } - return this.__dateService; - }, - // Cache IDs of selected downloads for later restoration _cacheSelection: function() { // Abort if there's already something cached @@ -518,30 +509,49 @@ DownloadTreeView.prototype = { }, _convertTimeToString: function(aTime) { - var timeObj = new Date(aTime); + const MS_PER_MINUTE = 60000; + const MS_PER_DAY = 86400000; + let timeMs = aTime / 1000; // PRTime is in microseconds - // Check if it is today and only display the time. Only bother - // checking for today if it's within the last 24 hours, since - // computing midnight is not really cheap. Sometimes we may get dates - // in the future, so always show those. - var ago = Date.now() - aTime; - var dateFormat = Components.interfaces.nsIScriptableDateFormat.dateFormatShort; - if (ago > -10000 && ago < (1000 * 24 * 60 * 60)) { - var midnight = new Date(); - midnight.setHours(0); - midnight.setMinutes(0); - midnight.setSeconds(0); - midnight.setMilliseconds(0); + // Date is calculated starting from midnight, so the modulo with a day are + // 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; - if (aTime > midnight.getTime()) - dateFormat = Components.interfaces.nsIScriptableDateFormat.dateFormatNone; + let timeObj = new Date(timeMs); + return timeMs >= midnight ? this._todayFormatter.format(timeObj) + : this._dateFormatter.format(timeObj); + }, + + // 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 = Components.classes["@mozilla.org/chrome/chrome-registry;1"] + .getService(Components.interfaces.nsIXULChromeRegistry) + .getSelectedLocale("global", true); + const dtOptions = { hour: 'numeric', minute: 'numeric' }; + this.__todayFormatter = new Intl.DateTimeFormat(locale, dtOptions); } + return this.__todayFormatter; + }, - return (this._dateService.FormatDateTime("", dateFormat, - Components.interfaces.nsIScriptableDateFormat.timeFormatNoSeconds, - timeObj.getFullYear(), timeObj.getMonth() + 1, - timeObj.getDate(), timeObj.getHours(), - timeObj.getMinutes(), timeObj.getSeconds())); + __dateFormatter: null, + get _dateFormatter() { + if (!this.__dateFormatter) { + const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"] + .getService(Components.interfaces.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; }, }; diff --git a/suite/common/history/treeView.js b/suite/common/history/treeView.js index 3946f89a87..ce81669bae 100644 --- a/suite/common/history/treeView.js +++ b/suite/common/history/treeView.js @@ -12,14 +12,6 @@ function PlacesTreeView() { } PlacesTreeView.prototype = { - __dateService: null, - get _dateService() { - if (!this.__dateService) { - this.__dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"] - .getService(Components.interfaces.nsIScriptableDateFormat); - } - return this.__dateService; - }, QueryInterface: function PTV_QueryInterface(aIID) { if (aIID.equals(Components.interfaces.nsITreeView) || @@ -424,31 +416,49 @@ PlacesTreeView.prototype = { }, _convertPRTimeToString: function PTV__convertPRTimeToString(aTime) { - var timeInMilliseconds = aTime / 1000; // PRTime is in microseconds - var timeObj = new Date(timeInMilliseconds); + const MS_PER_MINUTE = 60000; + const MS_PER_DAY = 86400000; + let timeMs = aTime / 1000; // PRTime is in microseconds - // Check if it is today and only display the time. Only bother - // checking for today if it's within the last 24 hours, since - // computing midnight is not really cheap. Sometimes we may get dates - // in the future, so always show those. - var ago = Date.now() - timeInMilliseconds; - var dateFormat = Components.interfaces.nsIScriptableDateFormat.dateFormatShort; - if (ago > -10000 && ago < (1000 * 24 * 60 * 60)) { - var midnight = new Date(); - midnight.setHours(0); - midnight.setMinutes(0); - midnight.setSeconds(0); - midnight.setMilliseconds(0); + // Date is calculated starting from midnight, so the modulo with a day are + // 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; - if (timeInMilliseconds > midnight.getTime()) - dateFormat = Components.interfaces.nsIScriptableDateFormat.dateFormatNone; + let timeObj = new Date(timeMs); + return timeMs >= midnight ? this._todayFormatter.format(timeObj) + : this._dateFormatter.format(timeObj); + }, + + // 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 = Components.classes["@mozilla.org/chrome/chrome-registry;1"] + .getService(Components.interfaces.nsIXULChromeRegistry) + .getSelectedLocale("global", true); + const dtOptions = { hour: 'numeric', minute: 'numeric' }; + this.__todayFormatter = new Intl.DateTimeFormat(locale, dtOptions); } + return this.__todayFormatter; + }, - return (this._dateService.FormatDateTime("", dateFormat, - Components.interfaces.nsIScriptableDateFormat.timeFormatNoSeconds, - timeObj.getFullYear(), timeObj.getMonth() + 1, - timeObj.getDate(), timeObj.getHours(), - timeObj.getMinutes(), timeObj.getSeconds())); + __dateFormatter: null, + get _dateFormatter() { + if (!this.__dateFormatter) { + const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"] + .getService(Components.interfaces.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; }, // nsINavHistoryResultObserver diff --git a/suite/common/permissions/cookieViewer.js b/suite/common/permissions/cookieViewer.js index 5419f17eae..f1c2e51f15 100644 --- a/suite/common/permissions/cookieViewer.js +++ b/suite/common/permissions/cookieViewer.js @@ -38,14 +38,6 @@ function Startup() { promptservice = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] .getService(Components.interfaces.nsIPromptService); - // intialize gDateService - if (!gDateService) { - const nsScriptableDateFormat_CONTRACTID = "@mozilla.org/intl/scriptabledateformat;1"; - const nsIScriptableDateFormat = Components.interfaces.nsIScriptableDateFormat; - gDateService = Components.classes[nsScriptableDateFormat_CONTRACTID] - .getService(nsIScriptableDateFormat); - } - // intialize string bundle cookieBundle = document.getElementById("cookieBundle"); @@ -175,11 +167,11 @@ function GetExpiresString(expires) { // see bug 238045 for details var expiry = ""; try { - expiry = gDateService.FormatDateTime("", gDateService.dateFormatLong, - gDateService.timeFormatSeconds, - date.getFullYear(), date.getMonth()+1, - date.getDate(), date.getHours(), - date.getMinutes(), date.getSeconds()); + const dtOptions = { year: "numeric", month: "long", day: "numeric", + hour: "numeric", minute: "numeric", + second: "numeric", timeZoneName: "short", + weekday: "short" }; + expiry = date.toLocaleString(undefined, dtOptions); } catch(ex) { // do nothing } diff --git a/suite/common/places/tests/chrome/test_treeview_date.xul b/suite/common/places/tests/chrome/test_treeview_date.xul index 98967e4a97..286a8dde34 100644 --- a/suite/common/places/tests/chrome/test_treeview_date.xul +++ b/suite/common/places/tests/chrome/test_treeview_date.xul @@ -69,8 +69,6 @@ var bh = hs.QueryInterface(Ci.nsIBrowserHistory); var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. getService(Ci.nsINavBookmarksService); - var ds = Cc["@mozilla.org/intl/scriptabledateformat;1"]. - getService(Ci.nsIScriptableDateFormat); var iosvc = Cc["@mozilla.org/network/io-service;1"]. getService(Ci.nsIIOService); @@ -125,24 +123,19 @@ case "date": var timeObj = new Date(node.time / 1000); // Default is short date format. - var 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; } - var timeStr = ds.FormatDateTime("", dateFormat, - Ci.nsIScriptableDateFormat.timeFormatNoSeconds, - timeObj.getFullYear(), timeObj.getMonth() + 1, - timeObj.getDate(), timeObj.getHours(), - timeObj.getMinutes(), timeObj.getSeconds()) - + var timeStr = timeObj.toLocaleString(locale, dtOptions); is(text, timeStr, "Date format is correct"); break; case "visitCount": diff --git a/suite/common/places/treeView.js b/suite/common/places/treeView.js index a1e4289e47..514bd8c1bb 100644 --- a/suite/common/places/treeView.js +++ b/suite/common/places/treeView.js @@ -15,14 +15,6 @@ function PlacesTreeView(aFlatList, aOnOpenFlatContainer, aController) { } PlacesTreeView.prototype = { - __dateService: null, - get _dateService() { - if (!this.__dateService) { - this.__dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"] - .getService(Components.interfaces.nsIScriptableDateFormat); - } - return this.__dateService; - }, QueryInterface: function PTV_QueryInterface(aIID) { if (aIID.equals(Components.interfaces.nsITreeView) || @@ -469,17 +461,36 @@ PlacesTreeView.prototype = { let midnight = now - (now % MS_PER_DAY); midnight += new Date(midnight).getTimezoneOffset() * MS_PER_MINUTE; - const nsIScriptableDateFormat = Components.interfaces.nsIScriptableDateFormat; - let dateFormat = timeMs >= midnight ? - nsIScriptableDateFormat.dateFormatNone : - nsIScriptableDateFormat.dateFormatShort; - let timeObj = new Date(timeMs); - return (this._dateService.FormatDateTime("", dateFormat, - nsIScriptableDateFormat.timeFormatNoSeconds, - timeObj.getFullYear(), timeObj.getMonth() + 1, - timeObj.getDate(), timeObj.getHours(), - timeObj.getMinutes(), timeObj.getSeconds())); + return timeMs >= midnight ? this._todayFormatter.format(timeObj) + : this._dateFormatter.format(timeObj); + }, + + // 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 = Components.classes["@mozilla.org/chrome/chrome-registry;1"] + .getService(Components.interfaces.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 = Components.classes["@mozilla.org/chrome/chrome-registry;1"] + .getService(Components.interfaces.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, diff --git a/suite/feeds/src/FeedWriter.js b/suite/feeds/src/FeedWriter.js index 1c03558bfc..d661bbdddb 100644 --- a/suite/feeds/src/FeedWriter.js +++ b/suite/feeds/src/FeedWriter.js @@ -268,17 +268,22 @@ FeedWriter.prototype = { * A date as extracted from a feed entry. (entry.updated) */ _parseDate: function parseDate(dateString) { - // Make sure the date we're given is valid. - if (isNaN(Date.parse(dateString))) - return null; - // Convert the date into the user's local time zone. var dateObj = new Date(dateString); - var dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"] - .getService(Components.interfaces.nsIScriptableDateFormat); - return dateService.FormatDateTime("", dateService.dateFormatLong, dateService.timeFormatNoSeconds, - dateObj.getFullYear(), dateObj.getMonth()+1, dateObj.getDate(), - dateObj.getHours(), dateObj.getMinutes(), dateObj.getSeconds()); + // Make sure the date we're given is valid. + if (!dateObj.getTime()) + return false; + + return this._dateFormatter.format(dateObj); + }, + + __dateFormatter: null, + get _dateFormatter() { + if (!this.__dateFormatter) { + const dtOptions = { timeStyle: "short", dateStyle: "long" }; + this.__dateFormatter = Services.intl.createDateTimeFormat(undefined, dtOptions); + } + return this.__dateFormatter; }, /**