Bug 1406311 - memoize number formatters in devtools l10n.js;r=ochameau
MozReview-Commit-ID: 7YIeimLREGg
--- a/devtools/shared/l10n.js
+++ b/devtools/shared/l10n.js
@@ -30,16 +30,32 @@ const reqShared = require.context("raw!d
true, /^.*\.properties$/);
const reqClient = require.context("raw!devtools/client/locales/",
true, /^.*\.properties$/);
const reqShim = require.context("raw!devtools/shim/locales/",
true, /^.*\.properties$/);
const reqGlobal = require.context("raw!toolkit/locales/",
true, /^.*\.properties$/);
+// Map used to memoize Number formatters.
+const numberFormatters = new Map();
+const getNumberFormatter = function (decimals) {
+ let formatter = numberFormatters.get(decimals);
+ if (!formatter) {
+ // Create and memoize a formatter for the provided decimals
+ formatter = Intl.NumberFormat(undefined, {
+ maximumFractionDigits: decimals,
+ minimumFractionDigits: decimals
+ });
+ numberFormatters.set(decimals, formatter);
+ }
+
+ return formatter;
+};
+
/**
* Memoized getter for properties files that ensures a given url is only required and
* parsed once.
*
* @param {String} url
* The URL of the properties file to parse.
* @return {Object} parsed properties mapped in an object.
*/
@@ -139,28 +155,28 @@ LocalizationHelper.prototype = {
if (number === (number|0)) {
return number;
}
// If this isn't a number (and yes, `isNaN(null)` is false), return zero.
if (isNaN(number) || number === null) {
return "0";
}
- let localized = number.toLocaleString();
+ // Localize the number using a memoized Intl.NumberFormat formatter.
+ let localized = getNumberFormatter(decimals).format(number);
- // If no grouping or decimal separators are available, bail out, because
- // padding with zeros at the end of the string won't make sense anymore.
- if (!localized.match(/[^\d]/)) {
- return localized;
+ // Convert the localized number to a number again.
+ let localizedNumber = localized * 1;
+ // Check if this number is now equal to an integer.
+ if (localizedNumber === (localizedNumber|0)) {
+ // If it is, remove the fraction part.
+ return getNumberFormatter(0).format(localizedNumber);
}
- return number.toLocaleString(undefined, {
- maximumFractionDigits: decimals,
- minimumFractionDigits: decimals
- });
+ return localized;
}
};
function getPropertiesForNode(node) {
let bundleEl = node.closest("[data-localization-bundle]");
if (!bundleEl) {
return null;
}