--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -309,17 +309,17 @@ var AboutNetAndCertErrorListener = {
let now = Date.now();
let certRange = this._getCertValidityRange();
let approximateDate = now - difference * 1000;
// If the difference is more than a day, we last fetched the date in the last 5 days,
// and adjusting the date per the interval would make the cert valid, warn the user:
if (Math.abs(difference) > 60 * 60 * 24 && (now - lastFetched) <= 60 * 60 * 24 * 5 &&
certRange.notBefore < approximateDate && certRange.notAfter > approximateDate) {
- let formatter = Services.intl.createDateTimeFormat(undefined, {
+ let formatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short"
});
let systemDate = formatter.format(new Date());
// negative difference means local time is behind server time
approximateDate = formatter.format(new Date(approximateDate));
content.document.getElementById("wrongSystemTime_URL")
.textContent = content.document.location.hostname;
@@ -345,17 +345,17 @@ var AboutNetAndCertErrorListener = {
let buildDate = new Date(year, month, day);
let systemDate = new Date();
// We don't check the notBefore of the cert with the build date,
// as it is of course almost certain that it is now later than the build date,
// so we shouldn't exclude the possibility that the cert has become valid
// since the build date.
if (buildDate > systemDate && new Date(certRange.notAfter) > buildDate) {
- let formatter = Services.intl.createDateTimeFormat(undefined, {
+ let formatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short"
});
content.document.getElementById("wrongSystemTimeWithoutReference_URL")
.textContent = content.document.location.hostname;
content.document.getElementById("wrongSystemTimeWithoutReference_systemDate")
.textContent = formatter.format(systemDate);
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -1011,17 +1011,17 @@ function formatNumber(number) {
return (+number).toLocaleString(); // coerce number to a numeric value before calling toLocaleString()
}
function formatDate(datestr, unknown) {
var date = new Date(datestr);
if (!date.valueOf())
return unknown;
- const dateTimeFormatter = Services.intl.createDateTimeFormat(undefined, {
+ const dateTimeFormatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "long", timeStyle: "long"
});
return dateTimeFormatter.format(date);
}
function doCopy() {
if (!gClipboardHelper)
return;
--- a/browser/base/content/test/about/browser_aboutCertError.js
+++ b/browser/base/content/test/about/browser_aboutCertError.js
@@ -146,17 +146,17 @@ add_task(async function checkWrongSystem
text: div.textContent,
systemDate: systemDateDiv.textContent,
actualDate: actualDateDiv.textContent,
learnMoreLink: learnMoreLink.href
};
});
}
- let formatter = Services.intl.createDateTimeFormat(undefined, {
+ let formatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short"
});
// pretend we have a positively skewed (ahead) system time
let serverDate = new Date("2015/10/27");
let serverDateFmt = formatter.format(serverDate);
let localDateFmt = formatter.format(new Date());
--- a/browser/components/feeds/FeedWriter.js
+++ b/browser/components/feeds/FeedWriter.js
@@ -187,17 +187,17 @@ FeedWriter.prototype = {
__dateFormatter: null,
get _dateFormatter() {
if (!this.__dateFormatter) {
const dtOptions = {
timeStyle: "short",
dateStyle: "long"
};
- this.__dateFormatter = Services.intl.createDateTimeFormat(undefined, dtOptions);
+ this.__dateFormatter = new Services.intl.DateTimeFormat(undefined, dtOptions);
}
return this.__dateFormatter;
},
/**
* Returns the feed type.
*/
__feedType: null,
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -408,17 +408,17 @@ var PlacesOrganizer = {
* Populates the restore menu with the dates of the backups available.
*/
populateRestoreMenu: function PO_populateRestoreMenu() {
let restorePopup = document.getElementById("fileRestorePopup");
const dtOptions = {
dateStyle: "long"
};
- let dateFormatter = Services.intl.createDateTimeFormat(undefined, dtOptions);
+ let dateFormatter = new Services.intl.DateTimeFormat(undefined, dtOptions);
// Remove existing menu items. Last item is the restoreFromFile item.
while (restorePopup.childNodes.length > 1)
restorePopup.firstChild.remove();
(async function() {
let backupFiles = await PlacesBackups.getBackupFiles();
if (backupFiles.length == 0)
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -551,29 +551,29 @@ PlacesTreeView.prototype = {
},
// 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 dtOptions = { timeStyle: "short" };
- this.__todayFormatter = Services.intl.createDateTimeFormat(undefined, dtOptions);
+ this.__todayFormatter = new Services.intl.DateTimeFormat(undefined, dtOptions);
}
return this.__todayFormatter;
},
__dateFormatter: null,
get _dateFormatter() {
if (!this.__dateFormatter) {
const dtOptions = {
dateStyle: "short",
timeStyle: "short"
};
- this.__dateFormatter = Services.intl.createDateTimeFormat(undefined, dtOptions);
+ this.__dateFormatter = new Services.intl.DateTimeFormat(undefined, dtOptions);
}
return this.__dateFormatter;
},
COLUMN_TYPE_UNKNOWN: 0,
COLUMN_TYPE_TITLE: 1,
COLUMN_TYPE_URI: 2,
COLUMN_TYPE_DATE: 3,
--- a/browser/components/places/tests/chrome/test_treeview_date.xul
+++ b/browser/components/places/tests/chrome/test_treeview_date.xul
@@ -133,17 +133,17 @@
if (node.uri == "http://at.midnight.com/" ||
node.uri == "http://after.midnight.com/") {
dtOptions.dateStyle = undefined;
} 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 = Services.intl.createDateTimeFormat(undefined, dtOptions).format(timeObj);
+ let timeStr = new Services.intl.DateTimeFormat(undefined, dtOptions).format(timeObj);
is(text, timeStr, "Date format is correct");
break;
case "visitCount":
is(text, 1, "Visit count is correct");
break;
}
}
--- a/browser/components/preferences/cookies.js
+++ b/browser/components/preferences/cookies.js
@@ -486,17 +486,17 @@ var gCookiesWindow = {
break;
}
this._view._rowCount = hostCount.value;
},
formatExpiresString(aExpires) {
if (aExpires) {
var date = new Date(1000 * aExpires);
- const dateTimeFormatter = Services.intl.createDateTimeFormat(undefined, {
+ const dateTimeFormatter = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "long", timeStyle: "long"
});
return dateTimeFormatter.format(date);
}
return this._bundle.getString("expireAtEndOfSession");
},
_getUserContextString(aUserContextId) {
--- a/toolkit/components/mozintl/mozIMozIntl.idl
+++ b/toolkit/components/mozintl/mozIMozIntl.idl
@@ -36,10 +36,10 @@
*/
[scriptable, uuid(7f63279a-1a29-4ae6-9e7a-dc9684a23530)]
interface mozIMozIntl : nsISupports
{
jsval getCalendarInfo([optional] in jsval locales);
jsval getDisplayNames([optional] in jsval locales, [optional] in jsval options);
jsval getLocaleInfo([optional] in jsval locales);
- jsval createDateTimeFormat([optional] in jsval locales, [optional] in jsval options);
+ readonly attribute jsval DateTimeFormat;
};
--- a/toolkit/components/mozintl/mozIntl.js
+++ b/toolkit/components/mozintl/mozIntl.js
@@ -64,37 +64,41 @@ class MozIntl {
getLocaleInfo(locales, ...args) {
if (!this._cache.hasOwnProperty("getLocaleInfo")) {
mozIntlHelper.addGetLocaleInfo(this._cache);
}
return this._cache.getLocaleInfo(getLocales(locales), ...args);
}
- createDateTimeFormat(locales, options, ...args) {
+ get DateTimeFormat() {
if (!this._cache.hasOwnProperty("DateTimeFormat")) {
mozIntlHelper.addDateTimeFormatConstructor(this._cache);
}
- let resolvedLocales =
- this._cache.DateTimeFormat.supportedLocalesOf(getLocales(locales));
+ let DateTimeFormat = this._cache.DateTimeFormat;
- if (options) {
- if (options.dateStyle || options.timeStyle) {
- options.pattern = osPrefs.getDateTimePattern(
- getDateTimePatternStyle(options.dateStyle),
- getDateTimePatternStyle(options.timeStyle),
- resolvedLocales[0]);
- } else {
- // make sure that user doesn't pass a pattern explicitly
- options.pattern = undefined;
+ class MozDateTimeFormat extends this._cache.DateTimeFormat {
+ constructor(locales, options, ...args) {
+ let resolvedLocales = DateTimeFormat.supportedLocalesOf(getLocales(locales));
+ if (options) {
+ if (options.dateStyle || options.timeStyle) {
+ options.pattern = osPrefs.getDateTimePattern(
+ getDateTimePatternStyle(options.dateStyle),
+ getDateTimePatternStyle(options.timeStyle),
+ resolvedLocales[0]);
+ } else {
+ // make sure that user doesn't pass a pattern explicitly
+ options.pattern = undefined;
+ }
+ }
+ super(resolvedLocales, options, ...args);
}
}
-
- return new this._cache.DateTimeFormat(resolvedLocales, options, ...args);
+ return MozDateTimeFormat;
}
}
MozIntl.prototype.classID = Components.ID("{35ec195a-e8d0-4300-83af-c8a2cc84b4a3}");
MozIntl.prototype.QueryInterface = XPCOMUtils.generateQI([Ci.mozIMozIntl, Ci.nsISupports]);
var components = [MozIntl];
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/toolkit/components/mozintl/test/test_mozintl.js
+++ b/toolkit/components/mozintl/test/test_mozintl.js
@@ -1,26 +1,48 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Components.utils.import("resource://gre/modules/Services.jsm");
function run_test() {
test_methods_presence();
test_methods_calling();
+ test_constructors();
ok(true);
}
function test_methods_presence() {
equal(Services.intl.getCalendarInfo instanceof Function, true);
equal(Services.intl.getDisplayNames instanceof Function, true);
equal(Services.intl.getLocaleInfo instanceof Function, true);
- equal(Services.intl.createDateTimeFormat instanceof Function, true);
+ equal(Services.intl.getLocaleInfo instanceof Object, true);
}
function test_methods_calling() {
Services.intl.getCalendarInfo("pl");
Services.intl.getDisplayNames("ar");
Services.intl.getLocaleInfo("de");
- Services.intl.createDateTimeFormat("fr");
+ new Services.intl.DateTimeFormat("fr");
ok(true);
}
+
+function test_constructors() {
+ let dtf = new Intl.DateTimeFormat();
+ let dtf2 = new Services.intl.DateTimeFormat();
+
+ equal(typeof dtf, typeof dtf2);
+
+ Assert.throws(() => {
+ // This is an observable difference between Intl and mozIntl.
+ //
+ // Old ECMA402 APIs (edition 1 and 2) allowed for constructors to be called
+ // as functions.
+ // Starting from ed.3 all new constructors are throwing when called without |new|.
+ //
+ // All MozIntl APIs do not implement the legacy behavior and throw
+ // when called without |new|.
+ //
+ // For more information see https://github.com/tc39/ecma402/pull/84 .
+ Services.intl.DateTimeFormat();
+ }, /class constructors must be invoked with |new|/);
+}
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -1435,17 +1435,17 @@ function UserAutoCompleteResult(aSearchS
}
this._showInsecureFieldWarning = (!isSecure && LoginHelper.showInsecureFieldWarning) ? 1 : 0;
this.searchString = aSearchString;
this.logins = matchingLogins.sort(loginSort);
this.matchCount = matchingLogins.length + this._showInsecureFieldWarning;
this._messageManager = messageManager;
this._stringBundle = Services.strings.createBundle("chrome://passwordmgr/locale/passwordmgr.properties");
- this._dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined, { dateStyle: "medium" });
+ this._dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined, { dateStyle: "medium" });
this._isPasswordField = isPasswordField;
this._duplicateUsernames = findDuplicates(matchingLogins);
if (this.matchCount > 0) {
this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
this.defaultIndex = 0;
--- a/toolkit/components/passwordmgr/LoginManagerContextMenu.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContextMenu.jsm
@@ -186,12 +186,12 @@ var LoginManagerContextMenu = {
};
XPCOMUtils.defineLazyGetter(LoginManagerContextMenu, "_stringBundle", function() {
return Services.strings.
createBundle("chrome://passwordmgr/locale/passwordmgr.properties");
});
XPCOMUtils.defineLazyGetter(LoginManagerContextMenu, "dateAndTimeFormatter", function() {
- return Services.intl.createDateTimeFormat(undefined, {
+ return new Services.intl.DateTimeFormat(undefined, {
dateStyle: "medium"
});
});
--- a/toolkit/components/passwordmgr/content/passwordManager.js
+++ b/toolkit/components/passwordmgr/content/passwordManager.js
@@ -55,19 +55,19 @@ let signonReloadDisplay = {
break;
}
Services.obs.notifyObservers(null, "passwordmgr-dialog-updated");
}
}
};
// Formatter for localization.
-let dateFormatter = Services.intl.createDateTimeFormat(undefined,
+let dateFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium" });
-let dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined,
+let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium",
timeStyle: "short" });
function Startup() {
// be prepared to reload the display if anything changes
Services.obs.addObserver(signonReloadDisplay, "passwordmgr-storage-changed");
signonsTree = document.getElementById("signonsTree");
--- a/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html
@@ -129,17 +129,17 @@ async function reinitializeForm(index) {
uname = $_(index, "uname");
pword = $_(index, "pword");
uname.value = "";
pword.value = "";
pword.focus();
}
function generateDateString(date) {
- let dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined,
+ let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium" });
return dateAndTimeFormatter.format(date);
}
const DATE_NOW_STRING = generateDateString(new Date());
// Check for expected username/password in form.
function checkACFormPasswordField(expectedPassword) {
--- a/toolkit/components/passwordmgr/test/unit/test_context_menu.js
+++ b/toolkit/components/passwordmgr/test/unit/test_context_menu.js
@@ -97,17 +97,17 @@ function checkLoginItems(logins, items)
duplicates.add(login.username);
}
seen.add(login.username);
}
return duplicates;
}
let duplicates = findDuplicates(logins);
- let dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined,
+ let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium" });
for (let login of logins) {
if (login.username && !duplicates.has(login.username)) {
// If login is not duplicate and we can't find an item for it, fail.
if (!items.find(item => item.label == login.username)) {
return false;
}
continue;
--- a/toolkit/components/passwordmgr/test/unit/test_user_autocomplete_result.js
+++ b/toolkit/components/passwordmgr/test/unit/test_user_autocomplete_result.js
@@ -19,17 +19,17 @@ matchingLogins.push(new nsLoginInfo("htt
matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
"testuser3", "testpass3", "uname", "pword"));
matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
"zzzuser4", "zzzpass4", "uname", "pword"));
let meta = matchingLogins[0].QueryInterface(Ci.nsILoginMetaInfo);
-let dateAndTimeFormatter = Services.intl.createDateTimeFormat(undefined,
+let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
{ dateStyle: "medium" });
let time = dateAndTimeFormatter.format(new Date(meta.timePasswordChanged));
const LABEL_NO_USERNAME = "No username (" + time + ")";
let expectedResults = [
{
insecureFieldWarningEnabled: true,
insecureAutoFillFormsEnabled: true,
--- a/toolkit/content/aboutTelemetry.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -419,17 +419,17 @@ var PingPicker = {
const today = new Date();
today.setHours(0, 0, 0, 0);
const yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
for (let p of this._archivedPings) {
pingTypes.add(p.type);
const pingDate = new Date(p.timestampCreated);
- const datetimeText = Services.intl.createDateTimeFormat(undefined, {
+ const datetimeText = new Services.intl.DateTimeFormat(undefined, {
dateStyle: "short",
timeStyle: "medium"
}).format(pingDate);
const pingName = `${datetimeText}, ${p.type}`;
let option = document.createElement("option");
let content = document.createTextNode(pingName);
option.appendChild(content);
--- a/toolkit/crashreporter/content/crashes.js
+++ b/toolkit/crashreporter/content/crashes.js
@@ -68,18 +68,18 @@ function populateReportList() {
document.getElementById("reportList").style.display = "none";
document.getElementById("noReports").style.display = "block";
return;
}
var dateFormatter;
var timeFormatter;
try {
- dateFormatter = Services.intl.createDateTimeFormat(undefined, { dateStyle: "short" });
- timeFormatter = Services.intl.createDateTimeFormat(undefined, { timeStyle: "short" });
+ dateFormatter = new Services.intl.DateTimeFormat(undefined, { dateStyle: "short" });
+ timeFormatter = new Services.intl.DateTimeFormat(undefined, { timeStyle: "short" });
} catch (e) {
// XXX Fallback to be removed once bug 1215247 is complete
// and the Intl API is available on all platforms.
dateFormatter = {
format(date) {
return date.toLocaleDateString();
}
};
--- a/toolkit/mozapps/downloads/DownloadUtils.jsm
+++ b/toolkit/mozapps/downloads/DownloadUtils.jsm
@@ -344,17 +344,17 @@ this.DownloadUtils = {
// Figure out when today begins
let today = new Date(aNow.getFullYear(), aNow.getMonth(), aNow.getDate());
let dateTimeCompact;
let dateTimeFull;
// Figure out if the time is from today, yesterday, this week, etc.
if (aDate >= today) {
- let dts = Services.intl.createDateTimeFormat(undefined, {
+ let dts = new Services.intl.DateTimeFormat(undefined, {
timeStyle: "short"
});
dateTimeCompact = dts.format(aDate);
} else if (today - aDate < (MS_PER_DAY)) {
// After yesterday started, show yesterday
dateTimeCompact = gBundle.GetStringFromName(gStr.yesterday);
} else if (today - aDate < (6 * MS_PER_DAY)) {
// After last week started, show day of week
@@ -364,17 +364,17 @@ this.DownloadUtils = {
dateTimeCompact = aDate.toLocaleString(undefined, {
month: "long",
day: "numeric"
});
}
const dtOptions = { dateStyle: "long", timeStyle: "short" };
dateTimeFull =
- Services.intl.createDateTimeFormat(undefined, dtOptions).format(aDate);
+ new Services.intl.DateTimeFormat(undefined, dtOptions).format(aDate);
return [dateTimeCompact, dateTimeFull];
},
/**
* Get the appropriate display host string for a URI string depending on if
* the URI has an eTLD + 1, is an IP address, a local file, or other protocol
*
--- a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
+++ b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
@@ -73,37 +73,37 @@ function testAllGetReadableDates() {
const today_11_30 = new Date(2000, 11, 31, 11, 30, 15);
const today_12_30 = new Date(2000, 11, 31, 12, 30, 15);
const yesterday_11_30 = new Date(2000, 11, 30, 11, 30, 15);
const yesterday_12_30 = new Date(2000, 11, 30, 12, 30, 15);
const twodaysago = new Date(2000, 11, 29, 11, 30, 15);
const sixdaysago = new Date(2000, 11, 25, 11, 30, 15);
const sevendaysago = new Date(2000, 11, 24, 11, 30, 15);
- let cDtf = Services.intl.createDateTimeFormat;
+ let cDtf = Services.intl.DateTimeFormat;
testGetReadableDates(today_11_30,
- cDtf(undefined, {timeStyle: "short"}).format(today_11_30));
+ (new cDtf(undefined, {timeStyle: "short"})).format(today_11_30));
testGetReadableDates(today_12_30,
- cDtf(undefined, {timeStyle: "short"}).format(today_12_30));
+ (new cDtf(undefined, {timeStyle: "short"})).format(today_12_30));
testGetReadableDates(yesterday_11_30, "Yesterday");
testGetReadableDates(yesterday_12_30, "Yesterday");
testGetReadableDates(twodaysago,
twodaysago.toLocaleDateString(undefined, { weekday: "long" }));
testGetReadableDates(sixdaysago,
sixdaysago.toLocaleDateString(undefined, { weekday: "long" }));
testGetReadableDates(sevendaysago,
sevendaysago.toLocaleDateString(undefined, { month: "long" }) + " " +
sevendaysago.getDate().toString().padStart(2, "0"));
let [, dateTimeFull] = DownloadUtils.getReadableDates(today_11_30);
const dtOptions = { dateStyle: "long", timeStyle: "short" };
- Assert.equal(dateTimeFull, cDtf(undefined, dtOptions).format(today_11_30));
+ Assert.equal(dateTimeFull, (new cDtf(undefined, dtOptions)).format(today_11_30));
}
function run_test() {
testConvertByteUnits(-1, "-1", "bytes");
testConvertByteUnits(1, _("1"), "bytes");
testConvertByteUnits(42, _("42"), "bytes");
testConvertByteUnits(123, _("123"), "bytes");
testConvertByteUnits(1024, _("1.0"), "KB");