moment-duration-format
Advanced tools
Comparing version 2.2.2 to 2.3.0
{ | ||
"name": "moment-duration-format", | ||
"version": "2.2.2", | ||
"version": "2.3.0", | ||
"description": "A moment.js plugin for formatting durations.", | ||
@@ -5,0 +5,0 @@ "main": "lib/moment-duration-format.js", |
@@ -47,2 +47,18 @@ /*! Moment Duration Format v2.2.2 | ||
// `Intl.NumberFormat#format` is tested on plugin initialization. | ||
// If the feature test passes, `intlNumberFormatRoundingWorks` will be set to | ||
// `true` and the native function will be used to generate formatted output. | ||
// If the feature test fails, either `Number#tolocaleString` (if | ||
// `toLocaleStringWorks` is `true`), or the fallback format function internal | ||
// to this plugin will be used. | ||
var intlNumberFormatWorks = false; | ||
// `Intl.NumberFormat#format` rounds incorrectly for select numbers in Microsoft | ||
// environments (Edge, IE11, Windows Phone) and possibly other environments. | ||
// If the rounding test fails and `Intl.NumberFormat#format` will be used for | ||
// formatting, the plugin will "pre-round" number values using the fallback number | ||
// format function before passing them to `Intl.NumberFormat#format` for final | ||
// formatting. | ||
var intlNumberFormatRoundingWorks = false; | ||
// Token type names in order of descending magnitude. | ||
@@ -152,2 +168,29 @@ var types = "escape years months weeks days hours minutes seconds milliseconds general".split(" "); | ||
// cachedNumberFormat | ||
// Returns an `Intl.NumberFormat` instance for the given locale and configuration. | ||
// On first use of a particular configuration, the instance is cached for fast | ||
// repeat access. | ||
function cachedNumberFormat(locale, options) { | ||
// Create a sorted, stringified version of `options` | ||
// for use as part of the cache key | ||
var optionsString = map( | ||
keys(options).sort(), | ||
function(key) { | ||
return key + ':' + options[key]; | ||
} | ||
).join(','); | ||
// Set our cache key | ||
var cacheKey = locale + '+' + optionsString; | ||
// If we don't have this configuration cached, configure and cache it | ||
if (!cachedNumberFormat.cache[cacheKey]) { | ||
cachedNumberFormat.cache[cacheKey] = Intl.NumberFormat(locale, options); | ||
} | ||
// Return the cached version of this configuration | ||
return cachedNumberFormat.cache[cacheKey]; | ||
} | ||
cachedNumberFormat.cache = {}; | ||
// formatNumber | ||
@@ -165,4 +208,4 @@ // Formats any number greater than or equal to zero using these options: | ||
// | ||
// `useToLocaleString` will use `toLocaleString` for formatting. | ||
// `userLocale` option is passed through to `toLocaleString`. | ||
// `useToLocaleString` will use `Intl.NumberFormat` or `toLocaleString` for formatting. | ||
// `userLocale` option is passed through to the formatting function. | ||
// `fractionDigits` is passed through to `maximumFractionDigits` and `minimumFractionDigits` | ||
@@ -197,10 +240,21 @@ // Using `maximumSignificantDigits` will override `minimumIntegerDigits` and `fractionDigits`. | ||
if (!toLocaleStringRoundingWorks) { | ||
var roundingOptions = extend({}, options); | ||
roundingOptions.useGrouping = false; | ||
roundingOptions.decimalSeparator = "."; | ||
number = parseFloat(formatNumber(number, roundingOptions), 10); | ||
if (intlNumberFormatWorks) { | ||
if (!intlNumberFormatRoundingWorks) { | ||
var roundingOptions = extend({}, options); | ||
roundingOptions.useGrouping = false; | ||
roundingOptions.decimalSeparator = "."; | ||
number = parseFloat(formatNumber(number, roundingOptions), 10); | ||
} | ||
return cachedNumberFormat(userLocale, localeStringOptions).format(number); | ||
} else { | ||
if (!toLocaleStringRoundingWorks) { | ||
var roundingOptions = extend({}, options); | ||
roundingOptions.useGrouping = false; | ||
roundingOptions.decimalSeparator = "."; | ||
number = parseFloat(formatNumber(number, roundingOptions), 10); | ||
} | ||
return number.toLocaleString(userLocale, localeStringOptions); | ||
} | ||
return number.toLocaleString(userLocale, localeStringOptions); | ||
} | ||
@@ -621,4 +675,4 @@ | ||
function featureTestToLocaleStringRounding() { | ||
return (3.55).toLocaleString("en", { | ||
function featureTestFormatterRounding(formatter) { | ||
return formatter(3.55, "en", { | ||
useGrouping: false, | ||
@@ -631,33 +685,29 @@ minimumIntegerDigits: 1, | ||
function featureTestToLocaleString() { | ||
function featureTestFormatter(formatter) { | ||
var passed = true; | ||
// Test locale. | ||
passed = passed && toLocaleStringSupportsLocales(); | ||
if (!passed) { return false; } | ||
// Test minimumIntegerDigits. | ||
passed = passed && (1).toLocaleString("en", { minimumIntegerDigits: 1 }) === "1"; | ||
passed = passed && (1).toLocaleString("en", { minimumIntegerDigits: 2 }) === "01"; | ||
passed = passed && (1).toLocaleString("en", { minimumIntegerDigits: 3 }) === "001"; | ||
passed = passed && formatter(1, "en", { minimumIntegerDigits: 1 }) === "1"; | ||
passed = passed && formatter(1, "en", { minimumIntegerDigits: 2 }) === "01"; | ||
passed = passed && formatter(1, "en", { minimumIntegerDigits: 3 }) === "001"; | ||
if (!passed) { return false; } | ||
// Test maximumFractionDigits and minimumFractionDigits. | ||
passed = passed && (99.99).toLocaleString("en", { maximumFractionDigits: 0, minimumFractionDigits: 0 }) === "100"; | ||
passed = passed && (99.99).toLocaleString("en", { maximumFractionDigits: 1, minimumFractionDigits: 1 }) === "100.0"; | ||
passed = passed && (99.99).toLocaleString("en", { maximumFractionDigits: 2, minimumFractionDigits: 2 }) === "99.99"; | ||
passed = passed && (99.99).toLocaleString("en", { maximumFractionDigits: 3, minimumFractionDigits: 3 }) === "99.990"; | ||
passed = passed && formatter(99.99, "en", { maximumFractionDigits: 0, minimumFractionDigits: 0 }) === "100"; | ||
passed = passed && formatter(99.99, "en", { maximumFractionDigits: 1, minimumFractionDigits: 1 }) === "100.0"; | ||
passed = passed && formatter(99.99, "en", { maximumFractionDigits: 2, minimumFractionDigits: 2 }) === "99.99"; | ||
passed = passed && formatter(99.99, "en", { maximumFractionDigits: 3, minimumFractionDigits: 3 }) === "99.990"; | ||
if (!passed) { return false; } | ||
// Test maximumSignificantDigits. | ||
passed = passed && (99.99).toLocaleString("en", { maximumSignificantDigits: 1 }) === "100"; | ||
passed = passed && (99.99).toLocaleString("en", { maximumSignificantDigits: 2 }) === "100"; | ||
passed = passed && (99.99).toLocaleString("en", { maximumSignificantDigits: 3 }) === "100"; | ||
passed = passed && (99.99).toLocaleString("en", { maximumSignificantDigits: 4 }) === "99.99"; | ||
passed = passed && (99.99).toLocaleString("en", { maximumSignificantDigits: 5 }) === "99.99"; | ||
passed = passed && formatter(99.99, "en", { maximumSignificantDigits: 1 }) === "100"; | ||
passed = passed && formatter(99.99, "en", { maximumSignificantDigits: 2 }) === "100"; | ||
passed = passed && formatter(99.99, "en", { maximumSignificantDigits: 3 }) === "100"; | ||
passed = passed && formatter(99.99, "en", { maximumSignificantDigits: 4 }) === "99.99"; | ||
passed = passed && formatter(99.99, "en", { maximumSignificantDigits: 5 }) === "99.99"; | ||
if (!passed) { return false; } | ||
// Test grouping. | ||
passed = passed && (1000).toLocaleString("en", { useGrouping: true }) === "1,000"; | ||
passed = passed && (1000).toLocaleString("en", { useGrouping: false }) === "1000"; | ||
passed = passed && formatter(1000, "en", { useGrouping: true }) === "1,000"; | ||
passed = passed && formatter(1000, "en", { useGrouping: false }) === "1000"; | ||
if (!passed) { return false; } | ||
@@ -901,3 +951,3 @@ | ||
useToLocaleString = useToLocaleString && toLocaleStringWorks; | ||
useToLocaleString = useToLocaleString && (toLocaleStringWorks || intlNumberFormatWorks); | ||
@@ -1671,5 +1721,19 @@ // Trim options. | ||
// Run feature tests for `Number#toLocaleString`. | ||
toLocaleStringWorks = featureTestToLocaleString(); | ||
toLocaleStringRoundingWorks = toLocaleStringWorks && featureTestToLocaleStringRounding(); | ||
var toLocaleStringFormatter = function(number, locale, options) { | ||
return number.toLocaleString(locale, options); | ||
}; | ||
toLocaleStringWorks = toLocaleStringSupportsLocales() && featureTestFormatter(toLocaleStringFormatter); | ||
toLocaleStringRoundingWorks = toLocaleStringWorks && featureTestFormatterRounding(toLocaleStringFormatter); | ||
// Run feature tests for `Intl.NumberFormat#format`. | ||
var intlNumberFormatFormatter = function(number, locale, options) { | ||
if (window.Intl && window.Intl.NumberFormat) { | ||
return window.Intl.NumberFormat(locale, options).format(number); | ||
} | ||
}; | ||
intlNumberFormatWorks = featureTestFormatter(intlNumberFormatFormatter); | ||
intlNumberFormatRoundingWorks = intlNumberFormatWorks && featureTestFormatterRounding(intlNumberFormatFormatter); | ||
// Initialize duration format on the global moment instance. | ||
@@ -1676,0 +1740,0 @@ init(moment); |
{ | ||
"name": "moment-duration-format", | ||
"version": "2.2.2", | ||
"version": "2.3.0", | ||
"description": "A moment.js plugin for formatting durations.", | ||
@@ -5,0 +5,0 @@ "main": "lib/moment-duration-format.js", |
@@ -15,5 +15,5 @@ # Moment Duration Format | ||
Where it is available and functional, this plugin uses `Number#toLocaleString` to render formatted numerical output. Unfortunately, many environments do not fully implement the full suite of options in the `toLocaleString` spec, and some provide a buggy implementation. | ||
Where it is available and functional, this plugin uses either `Intl.NumberFormat#format` or `Number#toLocaleString` to render formatted numerical output. Unfortunately, many environments do not fully implement the full suite of options in their respective specs, and some provide a buggy implementation. | ||
This plugin runs a feature test for `toLocaleString`, and will revert to a fallback function to render formatted numerical output if the feature test fails. To force this plugin to always use the fallback number format function, set `useToLocaleString` to `false`. The fallback number format function output can be localized using options detailed at the bottom of this page. You should, in general, specify the fallback number formatting options if the default `"en"` locale formatting would be unacceptable on some devices or in some environments. | ||
This plugin runs a feature test for each formatter, and will revert to a fallback function to render formatted numerical output if the feature test fails. To force this plugin to always use the fallback number format function, set `useToLocaleString` to `false`. The fallback number format function output can be localized using options detailed at the bottom of this page. You should, in general, specify the fallback number formatting options if the default `"en"` locale formatting would be unacceptable on some devices or in some environments. | ||
@@ -46,5 +46,5 @@ This plugin is tested using BrowserStack on a range of Android devices with OS versions from 2.2 to 7, and on a range of iOS devices with OS versions from 4.3 to 11. Also tested on Chrome, Firefox, IE 8-11, and Edge browsers. | ||
- moment-duration-format and its fallback number formatting function do not follow the same API as `Number#toLocaleString` for significant digits and faction digits. The fallback function should be updated to use the `toLocaleString` API, and the plugin should expose the `toLocaleString` API options directly rather than hiding some of the options and masking them behind `precision` and `useSignificantDigits` options. | ||
- moment-duration-format and its fallback number formatting function do not follow the same API as `Number#toLocaleString` for significant digits and faction digits. The fallback function should be updated to use the `toLocaleString` API, and the plugin should expose the API options directly rather than hiding some of the options and masking them behind `precision` and `useSignificantDigits` options. | ||
- Exposing the fallback number formatting function as well as the `toLocaleString` feature test function would facilitate testing and allow them to be used outside of the context of formatting durations. | ||
- Exposing the fallback number formatting function as well as the formatter feature test function would facilitate testing and allow them to be used outside of the context of formatting durations. | ||
@@ -848,3 +848,3 @@ --- | ||
Formatted numerical output is rendered using [`toLocaleString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString) if that built-in function is available and passes a feature test on plugin initialization. If the feature test fails, a fallback format function is used. See below for details on localizing output from the fallback format function. | ||
Formatted numerical output is rendered using [`Intl.NumberFormat#format`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat/format) or [`toLocaleString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString) where available, as long as they pass a feature test on plugin initialization. If the feature tests fail, a fallback format function is used. See below for details on localizing output from the fallback format function. | ||
@@ -1141,5 +1141,5 @@ Unit labels are automatically localized and pluralized. Unit labels are detected using the [locale set in moment.js](https://momentjs.com/docs/#/i18n/), which can be different from the locale of user's environment. This plugin uses custom extensions to the moment.js locale object, which can be easily added for any locale (see below). | ||
Set this option to `false` to ignore the `toLocaleString` feature test and force the use of the `formatNumber` fallback function included in this plugin. | ||
Set this option to `false` to ignore the `Intl.NumberFormat` and `toLocaleString` feature tests and force the use of the `formatNumber` fallback function included in this plugin. | ||
The fallback number format options will have no effect when `toLocaleString` is used. The grouping separator, decimal separator, and integer digit grouping will be determined by the user locale. | ||
The fallback number format options will have no effect when `Intl.NumberFormat` or `toLocaleString` are used. The grouping separator, decimal separator, and integer digit grouping will be determined by the user locale. | ||
@@ -1169,3 +1169,3 @@ ```javascript | ||
```javascript | ||
// Force the use of the fallback number format function. Do not use toLocaleString. | ||
// Force the use of the fallback number format function. Do not use toLocaleString or Intl.NumberFormat. | ||
// We're in some sort of strange hybrid french-indian locale... | ||
@@ -1172,0 +1172,0 @@ moment.duration(100000000000, "seconds").format("m", { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 3 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
700239
14
18469
3