mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-20 06:07:30 +09:00
Revert "Add pluralrules to JS Intl"
This reverts commit 7686bceecff17f91758c8c6547a78e71ff3a8c38.
This commit is contained in:
parent
85692a1198
commit
7e93e7170f
3 changed files with 134 additions and 542 deletions
|
|
@ -9,8 +9,7 @@
|
||||||
JSMSG_INVALID_OPTION_VALUE: false, JSMSG_INVALID_DIGITS_VALUE: false,
|
JSMSG_INVALID_OPTION_VALUE: false, JSMSG_INVALID_DIGITS_VALUE: false,
|
||||||
JSMSG_INTL_OBJECT_REINITED: false, JSMSG_INVALID_CURRENCY_CODE: false,
|
JSMSG_INTL_OBJECT_REINITED: false, JSMSG_INVALID_CURRENCY_CODE: false,
|
||||||
JSMSG_UNDEFINED_CURRENCY: false, JSMSG_INVALID_TIME_ZONE: false,
|
JSMSG_UNDEFINED_CURRENCY: false, JSMSG_INVALID_TIME_ZONE: false,
|
||||||
JSMSG_DATE_NOT_FINITE: false, JSMSG_INVALID_KEYS_TYPE: false,
|
JSMSG_DATE_NOT_FINITE: false,
|
||||||
JSMSG_INVALID_KEY: false,
|
|
||||||
intl_Collator_availableLocales: false,
|
intl_Collator_availableLocales: false,
|
||||||
intl_availableCollations: false,
|
intl_availableCollations: false,
|
||||||
intl_CompareStrings: false,
|
intl_CompareStrings: false,
|
||||||
|
|
@ -21,9 +20,6 @@
|
||||||
intl_availableCalendars: false,
|
intl_availableCalendars: false,
|
||||||
intl_patternForSkeleton: false,
|
intl_patternForSkeleton: false,
|
||||||
intl_FormatDateTime: false,
|
intl_FormatDateTime: false,
|
||||||
intl_SelectPluralRule: false,
|
|
||||||
intl_GetPluralCategories: false,
|
|
||||||
intl_GetCalendarInfo: false,
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -436,7 +432,7 @@ function CanonicalizeLanguageTag(locale) {
|
||||||
subtags[i] = subtag;
|
subtags[i] = subtag;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
var normal = ArrayJoinRange(subtags, "-", 0, i);
|
var normal = callFunction(std_Array_join, callFunction(std_Array_slice, subtags, 0, i), "-");
|
||||||
|
|
||||||
// Extension sequences are sorted by their singleton characters.
|
// Extension sequences are sorted by their singleton characters.
|
||||||
// "u-ca-chinese-t-zh-latn" -> "t-zh-latn-u-ca-chinese"
|
// "u-ca-chinese-t-zh-latn" -> "t-zh-latn-u-ca-chinese"
|
||||||
|
|
@ -446,7 +442,7 @@ function CanonicalizeLanguageTag(locale) {
|
||||||
i++;
|
i++;
|
||||||
while (i < subtags.length && subtags[i].length > 1)
|
while (i < subtags.length && subtags[i].length > 1)
|
||||||
i++;
|
i++;
|
||||||
var extension = ArrayJoinRange(subtags, "-", extensionStart, i);
|
var extension = callFunction(std_Array_join, callFunction(std_Array_slice, subtags, extensionStart, i), "-");
|
||||||
callFunction(std_Array_push, extensions, extension);
|
callFunction(std_Array_push, extensions, extension);
|
||||||
}
|
}
|
||||||
callFunction(std_Array_sort, extensions);
|
callFunction(std_Array_sort, extensions);
|
||||||
|
|
@ -454,7 +450,7 @@ function CanonicalizeLanguageTag(locale) {
|
||||||
// Private use sequences are left as is. "x-private"
|
// Private use sequences are left as is. "x-private"
|
||||||
var privateUse = "";
|
var privateUse = "";
|
||||||
if (i < subtags.length)
|
if (i < subtags.length)
|
||||||
privateUse = ArrayJoinRange(subtags, "-", i);
|
privateUse = callFunction(std_Array_join, callFunction(std_Array_slice, subtags, i), "-");
|
||||||
|
|
||||||
// Put everything back together.
|
// Put everything back together.
|
||||||
var canonical = normal;
|
var canonical = normal;
|
||||||
|
|
@ -471,24 +467,6 @@ function CanonicalizeLanguageTag(locale) {
|
||||||
return canonical;
|
return canonical;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Joins the array elements in the given range with the supplied separator.
|
|
||||||
*/
|
|
||||||
function ArrayJoinRange(array, separator, from, to = array.length) {
|
|
||||||
assert(typeof separator === "string", "|separator| is a string value");
|
|
||||||
assert(typeof from === "number", "|from| is a number value");
|
|
||||||
assert(typeof to === "number", "|to| is a number value");
|
|
||||||
assert(0 <= from && from <= to && to <= array.length, "|from| and |to| form a valid range");
|
|
||||||
|
|
||||||
if (from === to)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
var result = array[from];
|
|
||||||
for (var i = from + 1; i < to; i++) {
|
|
||||||
result += separator + array[i];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function localeContainsNoUnicodeExtensions(locale) {
|
function localeContainsNoUnicodeExtensions(locale) {
|
||||||
// No "-u-", no possible Unicode extension.
|
// No "-u-", no possible Unicode extension.
|
||||||
|
|
@ -860,7 +838,6 @@ function BestAvailableLocaleIgnoringDefault(availableLocales, locale) {
|
||||||
return BestAvailableLocaleHelper(availableLocales, locale, false);
|
return BestAvailableLocaleHelper(availableLocales, locale, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var noRelevantExtensionKeys = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares a BCP 47 language priority list against the set of locales in
|
* Compares a BCP 47 language priority list against the set of locales in
|
||||||
|
|
@ -1188,10 +1165,9 @@ function GetOption(options, property, type, values, fallback) {
|
||||||
* Spec: ECMAScript Internationalization API Specification, 9.2.10.
|
* Spec: ECMAScript Internationalization API Specification, 9.2.10.
|
||||||
*/
|
*/
|
||||||
function GetNumberOption(options, property, minimum, maximum, fallback) {
|
function GetNumberOption(options, property, minimum, maximum, fallback) {
|
||||||
assert(typeof minimum === "number" && (minimum | 0) === minimum, "GetNumberOption");
|
assert(typeof minimum === "number", "GetNumberOption");
|
||||||
assert(typeof maximum === "number" && (maximum | 0) === maximum, "GetNumberOption");
|
assert(typeof maximum === "number", "GetNumberOption");
|
||||||
assert(typeof fallback === "number" && (fallback | 0) === fallback, "GetNumberOption");
|
assert(fallback === undefined || (fallback >= minimum && fallback <= maximum), "GetNumberOption");
|
||||||
assert(minimum <= fallback && fallback <= maximum, "GetNumberOption");
|
|
||||||
|
|
||||||
// Step 1.
|
// Step 1.
|
||||||
var value = options[property];
|
var value = options[property];
|
||||||
|
|
@ -1201,10 +1177,7 @@ function GetNumberOption(options, property, minimum, maximum, fallback) {
|
||||||
value = ToNumber(value);
|
value = ToNumber(value);
|
||||||
if (Number_isNaN(value) || value < minimum || value > maximum)
|
if (Number_isNaN(value) || value < minimum || value > maximum)
|
||||||
ThrowRangeError(JSMSG_INVALID_DIGITS_VALUE, value);
|
ThrowRangeError(JSMSG_INVALID_DIGITS_VALUE, value);
|
||||||
|
return std_Math_floor(value);
|
||||||
// Apply bitwise-or to convert -0 to +0 per ES2017, 5.2 and to ensure
|
|
||||||
// the result is an int32 value.
|
|
||||||
return std_Math_floor(value) | 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3.
|
// Step 3.
|
||||||
|
|
@ -1278,9 +1251,7 @@ function initializeIntlObject(obj) {
|
||||||
function setLazyData(internals, type, lazyData)
|
function setLazyData(internals, type, lazyData)
|
||||||
{
|
{
|
||||||
assert(internals.type === "partial", "can't set lazy data for anything but a newborn");
|
assert(internals.type === "partial", "can't set lazy data for anything but a newborn");
|
||||||
assert(type === "Collator" || type === "DateTimeFormat" ||
|
assert(type === "Collator" || type === "DateTimeFormat" || type == "NumberFormat", "bad type");
|
||||||
type == "NumberFormat" || type === "PluralRules",
|
|
||||||
"bad type");
|
|
||||||
assert(IsObject(lazyData), "non-object lazy data");
|
assert(IsObject(lazyData), "non-object lazy data");
|
||||||
|
|
||||||
// Set in reverse order so that the .type change is a barrier.
|
// Set in reverse order so that the .type change is a barrier.
|
||||||
|
|
@ -1330,9 +1301,7 @@ function isInitializedIntlObject(obj) {
|
||||||
if (IsObject(internals)) {
|
if (IsObject(internals)) {
|
||||||
assert(callFunction(std_Object_hasOwnProperty, internals, "type"), "missing type");
|
assert(callFunction(std_Object_hasOwnProperty, internals, "type"), "missing type");
|
||||||
var type = internals.type;
|
var type = internals.type;
|
||||||
assert(type === "partial" || type === "Collator" ||
|
assert(type === "partial" || type === "Collator" || type === "DateTimeFormat" || type === "NumberFormat", "unexpected type");
|
||||||
type === "DateTimeFormat" || type === "NumberFormat" || type === "PluralRules",
|
|
||||||
"unexpected type");
|
|
||||||
assert(callFunction(std_Object_hasOwnProperty, internals, "lazyData"), "missing lazyData");
|
assert(callFunction(std_Object_hasOwnProperty, internals, "lazyData"), "missing lazyData");
|
||||||
assert(callFunction(std_Object_hasOwnProperty, internals, "internalProps"), "missing internalProps");
|
assert(callFunction(std_Object_hasOwnProperty, internals, "internalProps"), "missing internalProps");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1389,8 +1358,6 @@ function getInternals(obj)
|
||||||
internalProps = resolveCollatorInternals(lazyData)
|
internalProps = resolveCollatorInternals(lazyData)
|
||||||
else if (type === "DateTimeFormat")
|
else if (type === "DateTimeFormat")
|
||||||
internalProps = resolveDateTimeFormatInternals(lazyData)
|
internalProps = resolveDateTimeFormatInternals(lazyData)
|
||||||
else if (type === "PluralRules")
|
|
||||||
internalProps = resolvePluralRulesInternals(lazyData)
|
|
||||||
else
|
else
|
||||||
internalProps = resolveNumberFormatInternals(lazyData);
|
internalProps = resolveNumberFormatInternals(lazyData);
|
||||||
setInternalProperties(internals, internalProps);
|
setInternalProperties(internals, internalProps);
|
||||||
|
|
@ -1722,7 +1689,6 @@ function Intl_Collator_compare_get() {
|
||||||
// Step 2.
|
// Step 2.
|
||||||
return internals.boundCompare;
|
return internals.boundCompare;
|
||||||
}
|
}
|
||||||
_SetCanonicalName(Intl_Collator_compare_get, "get compare");
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1791,37 +1757,45 @@ function resolveNumberFormatInternals(lazyNumberFormatData) {
|
||||||
// Step 6.
|
// Step 6.
|
||||||
var opt = lazyNumberFormatData.opt;
|
var opt = lazyNumberFormatData.opt;
|
||||||
|
|
||||||
|
// Compute effective locale.
|
||||||
|
// Step 9.
|
||||||
var NumberFormat = numberFormatInternalProperties;
|
var NumberFormat = numberFormatInternalProperties;
|
||||||
|
|
||||||
// Step 9.
|
// Step 10.
|
||||||
var localeData = NumberFormat.localeData;
|
var localeData = NumberFormat.localeData;
|
||||||
|
|
||||||
// Step 10.
|
// Step 11.
|
||||||
var r = ResolveLocale(callFunction(NumberFormat.availableLocales, NumberFormat),
|
var r = ResolveLocale(callFunction(NumberFormat.availableLocales, NumberFormat),
|
||||||
lazyNumberFormatData.requestedLocales,
|
lazyNumberFormatData.requestedLocales,
|
||||||
lazyNumberFormatData.opt,
|
lazyNumberFormatData.opt,
|
||||||
NumberFormat.relevantExtensionKeys,
|
NumberFormat.relevantExtensionKeys,
|
||||||
localeData);
|
localeData);
|
||||||
|
|
||||||
// Steps 11-12. (Step 13 is not relevant to our implementation.)
|
// Steps 12-13. (Step 14 is not relevant to our implementation.)
|
||||||
internalProps.locale = r.locale;
|
internalProps.locale = r.locale;
|
||||||
internalProps.numberingSystem = r.nu;
|
internalProps.numberingSystem = r.nu;
|
||||||
|
|
||||||
// Compute formatting options.
|
// Compute formatting options.
|
||||||
// Step 15.
|
// Step 16.
|
||||||
var style = lazyNumberFormatData.style;
|
var s = lazyNumberFormatData.style;
|
||||||
internalProps.style = style;
|
internalProps.style = s;
|
||||||
|
|
||||||
// Steps 19, 21.
|
// Steps 20, 22.
|
||||||
if (style === "currency") {
|
if (s === "currency") {
|
||||||
internalProps.currency = lazyNumberFormatData.currency;
|
internalProps.currency = lazyNumberFormatData.currency;
|
||||||
internalProps.currencyDisplay = lazyNumberFormatData.currencyDisplay;
|
internalProps.currencyDisplay = lazyNumberFormatData.currencyDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 24.
|
||||||
internalProps.minimumIntegerDigits = lazyNumberFormatData.minimumIntegerDigits;
|
internalProps.minimumIntegerDigits = lazyNumberFormatData.minimumIntegerDigits;
|
||||||
|
|
||||||
|
// Steps 27.
|
||||||
internalProps.minimumFractionDigits = lazyNumberFormatData.minimumFractionDigits;
|
internalProps.minimumFractionDigits = lazyNumberFormatData.minimumFractionDigits;
|
||||||
|
|
||||||
|
// Step 30.
|
||||||
internalProps.maximumFractionDigits = lazyNumberFormatData.maximumFractionDigits;
|
internalProps.maximumFractionDigits = lazyNumberFormatData.maximumFractionDigits;
|
||||||
|
|
||||||
|
// Step 33.
|
||||||
if ("minimumSignificantDigits" in lazyNumberFormatData) {
|
if ("minimumSignificantDigits" in lazyNumberFormatData) {
|
||||||
// Note: Intl.NumberFormat.prototype.resolvedOptions() exposes the
|
// Note: Intl.NumberFormat.prototype.resolvedOptions() exposes the
|
||||||
// actual presence (versus undefined-ness) of these properties.
|
// actual presence (versus undefined-ness) of these properties.
|
||||||
|
|
@ -1830,10 +1804,10 @@ function resolveNumberFormatInternals(lazyNumberFormatData) {
|
||||||
internalProps.maximumSignificantDigits = lazyNumberFormatData.maximumSignificantDigits;
|
internalProps.maximumSignificantDigits = lazyNumberFormatData.maximumSignificantDigits;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 27.
|
// Step 35.
|
||||||
internalProps.useGrouping = lazyNumberFormatData.useGrouping;
|
internalProps.useGrouping = lazyNumberFormatData.useGrouping;
|
||||||
|
|
||||||
// Step 34.
|
// Step 42.
|
||||||
internalProps.boundFormat = undefined;
|
internalProps.boundFormat = undefined;
|
||||||
|
|
||||||
// The caller is responsible for associating |internalProps| with the right
|
// The caller is responsible for associating |internalProps| with the right
|
||||||
|
|
@ -1861,44 +1835,6 @@ function getNumberFormatInternals(obj, methodName) {
|
||||||
return internalProps;
|
return internalProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies digit options used for number formatting onto the intl object.
|
|
||||||
*
|
|
||||||
* Spec: ECMAScript Internationalization API Specification, 11.1.1.
|
|
||||||
*/
|
|
||||||
function SetNumberFormatDigitOptions(lazyData, options, mnfdDefault, mxfdDefault) {
|
|
||||||
// We skip Step 1 because we set the properties on a lazyData object.
|
|
||||||
|
|
||||||
// Step 2-3.
|
|
||||||
assert(IsObject(options), "SetNumberFormatDigitOptions");
|
|
||||||
assert(typeof mnfdDefault === "number", "SetNumberFormatDigitOptions");
|
|
||||||
assert(typeof mxfdDefault === "number", "SetNumberFormatDigitOptions");
|
|
||||||
assert(mnfdDefault <= mxfdDefault, "SetNumberFormatDigitOptions");
|
|
||||||
|
|
||||||
// Steps 4-6.
|
|
||||||
const mnid = GetNumberOption(options, "minimumIntegerDigits", 1, 21, 1);
|
|
||||||
const mnfd = GetNumberOption(options, "minimumFractionDigits", 0, 20, mnfdDefault);
|
|
||||||
const mxfdActualDefault = std_Math_max(mnfd, mxfdDefault);
|
|
||||||
const mxfd = GetNumberOption(options, "maximumFractionDigits", mnfd, 20, mxfdActualDefault);
|
|
||||||
|
|
||||||
// Steps 7-8.
|
|
||||||
let mnsd = options.minimumSignificantDigits;
|
|
||||||
let mxsd = options.maximumSignificantDigits;
|
|
||||||
|
|
||||||
// Steps 9-11.
|
|
||||||
lazyData.minimumIntegerDigits = mnid;
|
|
||||||
lazyData.minimumFractionDigits = mnfd;
|
|
||||||
lazyData.maximumFractionDigits = mxfd;
|
|
||||||
|
|
||||||
// Step 12.
|
|
||||||
if (mnsd !== undefined || mxsd !== undefined) {
|
|
||||||
mnsd = GetNumberOption(options, "minimumSignificantDigits", 1, 21, 1);
|
|
||||||
mxsd = GetNumberOption(options, "maximumSignificantDigits", mnsd, 21, 21);
|
|
||||||
lazyData.minimumSignificantDigits = mnsd;
|
|
||||||
lazyData.maximumSignificantDigits = mxsd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an object as a NumberFormat.
|
* Initializes an object as a NumberFormat.
|
||||||
|
|
@ -1948,7 +1884,7 @@ function InitializeNumberFormat(numberFormat, locales, options) {
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Note that lazy data is only installed as a final step of initialization,
|
// Note that lazy data is only installed as a final step of initialization,
|
||||||
// so every NumberFormat lazy data object has *all* these properties, never a
|
// so every Collator lazy data object has *all* these properties, never a
|
||||||
// subset of them.
|
// subset of them.
|
||||||
var lazyNumberFormatData = std_Object_create(null);
|
var lazyNumberFormatData = std_Object_create(null);
|
||||||
|
|
||||||
|
|
@ -1978,46 +1914,67 @@ function InitializeNumberFormat(numberFormat, locales, options) {
|
||||||
opt.localeMatcher = matcher;
|
opt.localeMatcher = matcher;
|
||||||
|
|
||||||
// Compute formatting options.
|
// Compute formatting options.
|
||||||
// Step 14.
|
// Step 15.
|
||||||
var style = GetOption(options, "style", "string", ["decimal", "percent", "currency"], "decimal");
|
var s = GetOption(options, "style", "string", ["decimal", "percent", "currency"], "decimal");
|
||||||
lazyNumberFormatData.style = style;
|
lazyNumberFormatData.style = s;
|
||||||
|
|
||||||
// Steps 16-19.
|
// Steps 17-20.
|
||||||
var c = GetOption(options, "currency", "string", undefined, undefined);
|
var c = GetOption(options, "currency", "string", undefined, undefined);
|
||||||
if (c !== undefined && !IsWellFormedCurrencyCode(c))
|
if (c !== undefined && !IsWellFormedCurrencyCode(c))
|
||||||
ThrowRangeError(JSMSG_INVALID_CURRENCY_CODE, c);
|
ThrowRangeError(JSMSG_INVALID_CURRENCY_CODE, c);
|
||||||
var cDigits;
|
var cDigits;
|
||||||
if (style === "currency") {
|
if (s === "currency") {
|
||||||
if (c === undefined)
|
if (c === undefined)
|
||||||
ThrowTypeError(JSMSG_UNDEFINED_CURRENCY);
|
ThrowTypeError(JSMSG_UNDEFINED_CURRENCY);
|
||||||
|
|
||||||
// Steps 19.a-c.
|
// Steps 20.a-c.
|
||||||
c = toASCIIUpperCase(c);
|
c = toASCIIUpperCase(c);
|
||||||
lazyNumberFormatData.currency = c;
|
lazyNumberFormatData.currency = c;
|
||||||
cDigits = CurrencyDigits(c);
|
cDigits = CurrencyDigits(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 20.
|
// Step 21.
|
||||||
var cd = GetOption(options, "currencyDisplay", "string", ["code", "symbol", "name"], "symbol");
|
var cd = GetOption(options, "currencyDisplay", "string", ["code", "symbol", "name"], "symbol");
|
||||||
if (style === "currency")
|
if (s === "currency")
|
||||||
lazyNumberFormatData.currencyDisplay = cd;
|
lazyNumberFormatData.currencyDisplay = cd;
|
||||||
|
|
||||||
// Steps 22-25.
|
// Step 23.
|
||||||
var mnfdDefault, mxfdDefault;
|
var mnid = GetNumberOption(options, "minimumIntegerDigits", 1, 21, 1);
|
||||||
if (style === "currency") {
|
lazyNumberFormatData.minimumIntegerDigits = mnid;
|
||||||
mnfdDefault = cDigits;
|
|
||||||
mxfdDefault = cDigits;
|
|
||||||
} else {
|
|
||||||
mnfdDefault = 0;
|
|
||||||
mxfdDefault = style === "percent" ? 0 : 3;
|
|
||||||
}
|
|
||||||
SetNumberFormatDigitOptions(lazyNumberFormatData, options, mnfdDefault, mxfdDefault);
|
|
||||||
|
|
||||||
// Steps 26.
|
// Steps 25-26.
|
||||||
|
var mnfdDefault = (s === "currency") ? cDigits : 0;
|
||||||
|
var mnfd = GetNumberOption(options, "minimumFractionDigits", 0, 20, mnfdDefault);
|
||||||
|
lazyNumberFormatData.minimumFractionDigits = mnfd;
|
||||||
|
|
||||||
|
// Steps 28-29.
|
||||||
|
var mxfdDefault;
|
||||||
|
if (s === "currency")
|
||||||
|
mxfdDefault = std_Math_max(mnfd, cDigits);
|
||||||
|
else if (s === "percent")
|
||||||
|
mxfdDefault = std_Math_max(mnfd, 0);
|
||||||
|
else
|
||||||
|
mxfdDefault = std_Math_max(mnfd, 3);
|
||||||
|
var mxfd = GetNumberOption(options, "maximumFractionDigits", mnfd, 20, mxfdDefault);
|
||||||
|
lazyNumberFormatData.maximumFractionDigits = mxfd;
|
||||||
|
|
||||||
|
// Steps 31-32.
|
||||||
|
var mnsd = options.minimumSignificantDigits;
|
||||||
|
var mxsd = options.maximumSignificantDigits;
|
||||||
|
|
||||||
|
// Step 33.
|
||||||
|
if (mnsd !== undefined || mxsd !== undefined) {
|
||||||
|
mnsd = GetNumberOption(options, "minimumSignificantDigits", 1, 21, 1);
|
||||||
|
mxsd = GetNumberOption(options, "maximumSignificantDigits", mnsd, 21, 21);
|
||||||
|
lazyNumberFormatData.minimumSignificantDigits = mnsd;
|
||||||
|
lazyNumberFormatData.maximumSignificantDigits = mxsd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 34.
|
||||||
var g = GetOption(options, "useGrouping", "boolean", undefined, true);
|
var g = GetOption(options, "useGrouping", "boolean", undefined, true);
|
||||||
lazyNumberFormatData.useGrouping = g;
|
lazyNumberFormatData.useGrouping = g;
|
||||||
|
|
||||||
// Steps 35-36.
|
// Step 43.
|
||||||
//
|
//
|
||||||
// We've done everything that must be done now: mark the lazy data as fully
|
// We've done everything that must be done now: mark the lazy data as fully
|
||||||
// computed and install it.
|
// computed and install it.
|
||||||
|
|
@ -2025,6 +1982,43 @@ function InitializeNumberFormat(numberFormat, locales, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping from currency codes to the number of decimal digits used for them.
|
||||||
|
* Default is 2 digits.
|
||||||
|
*
|
||||||
|
* Spec: ISO 4217 Currency and Funds Code List.
|
||||||
|
* http://www.currency-iso.org/en/home/tables/table-a1.html
|
||||||
|
*/
|
||||||
|
var currencyDigits = {
|
||||||
|
BHD: 3,
|
||||||
|
BIF: 0,
|
||||||
|
BYR: 0,
|
||||||
|
CLF: 4,
|
||||||
|
CLP: 0,
|
||||||
|
DJF: 0,
|
||||||
|
GNF: 0,
|
||||||
|
IQD: 3,
|
||||||
|
ISK: 0,
|
||||||
|
JOD: 3,
|
||||||
|
JPY: 0,
|
||||||
|
KMF: 0,
|
||||||
|
KRW: 0,
|
||||||
|
KWD: 3,
|
||||||
|
LYD: 3,
|
||||||
|
OMR: 3,
|
||||||
|
PYG: 0,
|
||||||
|
RWF: 0,
|
||||||
|
TND: 3,
|
||||||
|
UGX: 0,
|
||||||
|
UYI: 0,
|
||||||
|
VND: 0,
|
||||||
|
VUV: 0,
|
||||||
|
XAF: 0,
|
||||||
|
XOF: 0,
|
||||||
|
XPF: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of decimal digits to be used for the given currency.
|
* Returns the number of decimal digits to be used for the given currency.
|
||||||
*
|
*
|
||||||
|
|
@ -2106,7 +2100,7 @@ function numberFormatFormatToBind(value) {
|
||||||
|
|
||||||
// Step 1.a.ii-iii.
|
// Step 1.a.ii-iii.
|
||||||
var x = ToNumber(value);
|
var x = ToNumber(value);
|
||||||
return intl_FormatNumber(this, x, /* formatToParts = */ false);
|
return intl_FormatNumber(this, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2133,22 +2127,6 @@ function Intl_NumberFormat_format_get() {
|
||||||
// Step 2.
|
// Step 2.
|
||||||
return internals.boundFormat;
|
return internals.boundFormat;
|
||||||
}
|
}
|
||||||
_SetCanonicalName(Intl_NumberFormat_format_get, "get format");
|
|
||||||
|
|
||||||
|
|
||||||
function Intl_NumberFormat_formatToParts(value) {
|
|
||||||
// Step 1.
|
|
||||||
var nf = this;
|
|
||||||
|
|
||||||
// Steps 2-3.
|
|
||||||
getNumberFormatInternals(nf, "formatToParts");
|
|
||||||
|
|
||||||
// Step 4.
|
|
||||||
var x = ToNumber(value);
|
|
||||||
|
|
||||||
// Step 5.
|
|
||||||
return intl_FormatNumber(nf, x, /* formatToParts = */ true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2290,6 +2268,26 @@ function getDateTimeFormatInternals(obj, methodName) {
|
||||||
return internalProps;
|
return internalProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Components of date and time formats and their values.
|
||||||
|
*
|
||||||
|
* Spec: ECMAScript Internationalization API Specification, 12.1.1.
|
||||||
|
*/
|
||||||
|
var dateTimeComponentValues = {
|
||||||
|
weekday: ["narrow", "short", "long"],
|
||||||
|
era: ["narrow", "short", "long"],
|
||||||
|
year: ["2-digit", "numeric"],
|
||||||
|
month: ["2-digit", "numeric", "narrow", "short", "long"],
|
||||||
|
day: ["2-digit", "numeric"],
|
||||||
|
hour: ["2-digit", "numeric"],
|
||||||
|
minute: ["2-digit", "numeric"],
|
||||||
|
second: ["2-digit", "numeric"],
|
||||||
|
timeZoneName: ["short", "long"]
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var dateTimeComponents = std_Object_getOwnPropertyNames(dateTimeComponentValues);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an object as a DateTimeFormat.
|
* Initializes an object as a DateTimeFormat.
|
||||||
|
|
@ -2379,19 +2377,12 @@ function InitializeDateTimeFormat(dateTimeFormat, locales, options) {
|
||||||
lazyDateTimeFormatData.formatOpt = formatOpt;
|
lazyDateTimeFormatData.formatOpt = formatOpt;
|
||||||
|
|
||||||
// Step 19.
|
// Step 19.
|
||||||
// 12.1, Table 4: Components of date and time formats.
|
var i, prop;
|
||||||
formatOpt.weekday = GetOption(options, "weekday", "string", ["narrow", "short", "long"],
|
for (i = 0; i < dateTimeComponents.length; i++) {
|
||||||
undefined);
|
prop = dateTimeComponents[i];
|
||||||
formatOpt.era = GetOption(options, "era", "string", ["narrow", "short", "long"], undefined);
|
var value = GetOption(options, prop, "string", dateTimeComponentValues[prop], undefined);
|
||||||
formatOpt.year = GetOption(options, "year", "string", ["2-digit", "numeric"], undefined);
|
formatOpt[prop] = value;
|
||||||
formatOpt.month = GetOption(options, "month", "string",
|
}
|
||||||
["2-digit", "numeric", "narrow", "short", "long"], undefined);
|
|
||||||
formatOpt.day = GetOption(options, "day", "string", ["2-digit", "numeric"], undefined);
|
|
||||||
formatOpt.hour = GetOption(options, "hour", "string", ["2-digit", "numeric"], undefined);
|
|
||||||
formatOpt.minute = GetOption(options, "minute", "string", ["2-digit", "numeric"], undefined);
|
|
||||||
formatOpt.second = GetOption(options, "second", "string", ["2-digit", "numeric"], undefined);
|
|
||||||
formatOpt.timeZoneName = GetOption(options, "timeZoneName", "string", ["short", "long"],
|
|
||||||
undefined);
|
|
||||||
|
|
||||||
// Steps 20-21 provided by ICU - see comment after this function.
|
// Steps 20-21 provided by ICU - see comment after this function.
|
||||||
|
|
||||||
|
|
@ -2659,6 +2650,7 @@ function ToDateTimeOptions(options, required, defaults) {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares the date and time components requested by options with the available
|
* Compares the date and time components requested by options with the available
|
||||||
* date and time formats in formats, and selects the best match according
|
* date and time formats in formats, and selects the best match according
|
||||||
|
|
@ -2844,7 +2836,6 @@ function Intl_DateTimeFormat_format_get() {
|
||||||
// Step 2.
|
// Step 2.
|
||||||
return internals.boundFormat;
|
return internals.boundFormat;
|
||||||
}
|
}
|
||||||
_SetCanonicalName(Intl_DateTimeFormat_format_get, "get format");
|
|
||||||
|
|
||||||
|
|
||||||
function Intl_DateTimeFormat_formatToParts() {
|
function Intl_DateTimeFormat_formatToParts() {
|
||||||
|
|
@ -2980,232 +2971,6 @@ function resolveICUPattern(pattern, result) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********** Intl.PluralRules **********/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PluralRules internal properties.
|
|
||||||
*
|
|
||||||
* Spec: ECMAScript 402 API, PluralRules, 1.3.3.
|
|
||||||
*/
|
|
||||||
var pluralRulesInternalProperties = {
|
|
||||||
_availableLocales: null,
|
|
||||||
availableLocales: function()
|
|
||||||
{
|
|
||||||
var locales = this._availableLocales;
|
|
||||||
if (locales)
|
|
||||||
return locales;
|
|
||||||
|
|
||||||
locales = intl_PluralRules_availableLocales();
|
|
||||||
addSpecialMissingLanguageTags(locales);
|
|
||||||
return (this._availableLocales = locales);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute an internal properties object from |lazyPluralRulesData|.
|
|
||||||
*/
|
|
||||||
function resolvePluralRulesInternals(lazyPluralRulesData) {
|
|
||||||
assert(IsObject(lazyPluralRulesData), "lazy data not an object?");
|
|
||||||
|
|
||||||
var internalProps = std_Object_create(null);
|
|
||||||
|
|
||||||
var requestedLocales = lazyPluralRulesData.requestedLocales;
|
|
||||||
|
|
||||||
var PluralRules = pluralRulesInternalProperties;
|
|
||||||
|
|
||||||
// Step 13.
|
|
||||||
const r = ResolveLocale(callFunction(PluralRules.availableLocales, PluralRules),
|
|
||||||
lazyPluralRulesData.requestedLocales,
|
|
||||||
lazyPluralRulesData.opt,
|
|
||||||
noRelevantExtensionKeys, undefined);
|
|
||||||
|
|
||||||
// Step 14.
|
|
||||||
internalProps.locale = r.locale;
|
|
||||||
internalProps.type = lazyPluralRulesData.type;
|
|
||||||
|
|
||||||
internalProps.pluralCategories = intl_GetPluralCategories(
|
|
||||||
internalProps.locale,
|
|
||||||
internalProps.type);
|
|
||||||
|
|
||||||
internalProps.minimumIntegerDigits = lazyPluralRulesData.minimumIntegerDigits;
|
|
||||||
internalProps.minimumFractionDigits = lazyPluralRulesData.minimumFractionDigits;
|
|
||||||
internalProps.maximumFractionDigits = lazyPluralRulesData.maximumFractionDigits;
|
|
||||||
|
|
||||||
if ("minimumSignificantDigits" in lazyPluralRulesData) {
|
|
||||||
assert("maximumSignificantDigits" in lazyPluralRulesData, "min/max sig digits mismatch");
|
|
||||||
internalProps.minimumSignificantDigits = lazyPluralRulesData.minimumSignificantDigits;
|
|
||||||
internalProps.maximumSignificantDigits = lazyPluralRulesData.maximumSignificantDigits;
|
|
||||||
}
|
|
||||||
|
|
||||||
return internalProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an object containing the PluralRules internal properties of |obj|,
|
|
||||||
* or throws a TypeError if |obj| isn't PluralRules-initialized.
|
|
||||||
*/
|
|
||||||
function getPluralRulesInternals(obj, methodName) {
|
|
||||||
var internals = getIntlObjectInternals(obj, "PluralRules", methodName);
|
|
||||||
assert(internals.type === "PluralRules", "bad type escaped getIntlObjectInternals");
|
|
||||||
|
|
||||||
var internalProps = maybeInternalProperties(internals);
|
|
||||||
if (internalProps)
|
|
||||||
return internalProps;
|
|
||||||
|
|
||||||
internalProps = resolvePluralRulesInternals(internals.lazyData);
|
|
||||||
setInternalProperties(internals, internalProps);
|
|
||||||
return internalProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes an object as a PluralRules.
|
|
||||||
*
|
|
||||||
* This method is complicated a moderate bit by its implementing initialization
|
|
||||||
* as a *lazy* concept. Everything that must happen now, does -- but we defer
|
|
||||||
* all the work we can until the object is actually used as a PluralRules.
|
|
||||||
* This later work occurs in |resolvePluralRulesInternals|; steps not noted
|
|
||||||
* here occur there.
|
|
||||||
*
|
|
||||||
* Spec: ECMAScript 402 API, PluralRules, 1.1.1.
|
|
||||||
*/
|
|
||||||
function InitializePluralRules(pluralRules, locales, options) {
|
|
||||||
assert(IsObject(pluralRules), "InitializePluralRules");
|
|
||||||
|
|
||||||
// Step 1.
|
|
||||||
if (isInitializedIntlObject(pluralRules))
|
|
||||||
ThrowTypeError(JSMSG_INTL_OBJECT_REINITED);
|
|
||||||
|
|
||||||
let internals = initializeIntlObject(pluralRules);
|
|
||||||
|
|
||||||
// Lazy PluralRules data has the following structure:
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// requestedLocales: List of locales,
|
|
||||||
// type: "cardinal" / "ordinal",
|
|
||||||
//
|
|
||||||
// opt: // opt object computer in InitializePluralRules
|
|
||||||
// {
|
|
||||||
// localeMatcher: "lookup" / "best fit",
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// minimumIntegerDigits: integer ∈ [1, 21],
|
|
||||||
// minimumFractionDigits: integer ∈ [0, 20],
|
|
||||||
// maximumFractionDigits: integer ∈ [0, 20],
|
|
||||||
//
|
|
||||||
// // optional
|
|
||||||
// minimumSignificantDigits: integer ∈ [1, 21],
|
|
||||||
// maximumSignificantDigits: integer ∈ [1, 21],
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Note that lazy data is only installed as a final step of initialization,
|
|
||||||
// so every PluralRules lazy data object has *all* these properties, never a
|
|
||||||
// subset of them.
|
|
||||||
const lazyPluralRulesData = std_Object_create(null);
|
|
||||||
|
|
||||||
// Step 3.
|
|
||||||
let requestedLocales = CanonicalizeLocaleList(locales);
|
|
||||||
lazyPluralRulesData.requestedLocales = requestedLocales;
|
|
||||||
|
|
||||||
// Steps 4-5.
|
|
||||||
if (options === undefined)
|
|
||||||
options = {};
|
|
||||||
else
|
|
||||||
options = ToObject(options);
|
|
||||||
|
|
||||||
// Step 6.
|
|
||||||
const type = GetOption(options, "type", "string", ["cardinal", "ordinal"], "cardinal");
|
|
||||||
lazyPluralRulesData.type = type;
|
|
||||||
|
|
||||||
// Step 8.
|
|
||||||
let opt = new Record();
|
|
||||||
lazyPluralRulesData.opt = opt;
|
|
||||||
|
|
||||||
// Steps 9-10.
|
|
||||||
let matcher = GetOption(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit");
|
|
||||||
opt.localeMatcher = matcher;
|
|
||||||
|
|
||||||
// Steps 11-12.
|
|
||||||
SetNumberFormatDigitOptions(lazyPluralRulesData, options, 0, 3);
|
|
||||||
|
|
||||||
setLazyData(internals, "PluralRules", lazyPluralRulesData)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the subset of the given locale list for which this locale list has a
|
|
||||||
* matching (possibly fallback) locale. Locales appear in the same order in the
|
|
||||||
* returned list as in the input list.
|
|
||||||
*
|
|
||||||
* Spec: ECMAScript 402 API, PluralRules, 1.3.2.
|
|
||||||
*/
|
|
||||||
function Intl_PluralRules_supportedLocalesOf(locales /*, options*/) {
|
|
||||||
var options = arguments.length > 1 ? arguments[1] : undefined;
|
|
||||||
|
|
||||||
// Step 1.
|
|
||||||
var availableLocales = callFunction(pluralRulesInternalProperties.availableLocales,
|
|
||||||
pluralRulesInternalProperties);
|
|
||||||
// Step 2.
|
|
||||||
let requestedLocales = CanonicalizeLocaleList(locales);
|
|
||||||
|
|
||||||
// Step 3.
|
|
||||||
return SupportedLocales(availableLocales, requestedLocales, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a String value representing the plural category matching
|
|
||||||
* the number passed as value according to the
|
|
||||||
* effective locale and the formatting options of this PluralRules.
|
|
||||||
*
|
|
||||||
* Spec: ECMAScript 402 API, PluralRules, 1.4.3.
|
|
||||||
*/
|
|
||||||
function Intl_PluralRules_select(value) {
|
|
||||||
// Step 1.
|
|
||||||
let pluralRules = this;
|
|
||||||
// Step 2.
|
|
||||||
let internals = getPluralRulesInternals(pluralRules, "select");
|
|
||||||
|
|
||||||
// Steps 3-4.
|
|
||||||
let n = ToNumber(value);
|
|
||||||
|
|
||||||
// Step 5.
|
|
||||||
return intl_SelectPluralRule(pluralRules, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the resolved options for a PluralRules object.
|
|
||||||
*
|
|
||||||
* Spec: ECMAScript 402 API, PluralRules, 1.4.4.
|
|
||||||
*/
|
|
||||||
function Intl_PluralRules_resolvedOptions() {
|
|
||||||
var internals = getPluralRulesInternals(this, "resolvedOptions");
|
|
||||||
|
|
||||||
var internalsPluralCategories = internals.pluralCategories;
|
|
||||||
var pluralCategories = [];
|
|
||||||
for (var i = 0; i < internalsPluralCategories.length; i++)
|
|
||||||
_DefineDataProperty(pluralCategories, i, internalsPluralCategories[i]);
|
|
||||||
|
|
||||||
var result = {
|
|
||||||
locale: internals.locale,
|
|
||||||
type: internals.type,
|
|
||||||
pluralCategories,
|
|
||||||
minimumIntegerDigits: internals.minimumIntegerDigits,
|
|
||||||
minimumFractionDigits: internals.minimumFractionDigits,
|
|
||||||
maximumFractionDigits: internals.maximumFractionDigits,
|
|
||||||
};
|
|
||||||
|
|
||||||
var optionalProperties = [
|
|
||||||
"minimumSignificantDigits",
|
|
||||||
"maximumSignificantDigits"
|
|
||||||
];
|
|
||||||
|
|
||||||
for (var i = 0; i < optionalProperties.length; i++) {
|
|
||||||
var p = optionalProperties[i];
|
|
||||||
if (callFunction(std_Object_hasOwnProperty, internals, p))
|
|
||||||
_DefineDataProperty(result, p, internals[p]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function Intl_getCanonicalLocales(locales) {
|
function Intl_getCanonicalLocales(locales) {
|
||||||
let codes = CanonicalizeLocaleList(locales);
|
let codes = CanonicalizeLocaleList(locales);
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
@ -3241,126 +3006,3 @@ function Intl_getCalendarInfo(locales) {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is a custom method designed after Intl API, but currently
|
|
||||||
* not part of the spec or spec proposal.
|
|
||||||
* We want to use it internally to retrieve translated values from CLDR in
|
|
||||||
* order to ensure they're aligned with what Intl API returns.
|
|
||||||
*
|
|
||||||
* This API may one day be a foundation for an ECMA402 API spec proposal.
|
|
||||||
*
|
|
||||||
* The function takes two arguments - locales which is a list of locale strings
|
|
||||||
* and options which is an object with two optional properties:
|
|
||||||
*
|
|
||||||
* keys:
|
|
||||||
* an Array of string values that are paths to individual terms
|
|
||||||
*
|
|
||||||
* style:
|
|
||||||
* a String with a value "long", "short" or "narrow"
|
|
||||||
*
|
|
||||||
* It returns an object with properties:
|
|
||||||
*
|
|
||||||
* locale:
|
|
||||||
* a negotiated locale string
|
|
||||||
*
|
|
||||||
* style:
|
|
||||||
* negotiated style
|
|
||||||
*
|
|
||||||
* values:
|
|
||||||
* A key-value pair list of requested keys and corresponding
|
|
||||||
* translated values
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function Intl_getDisplayNames(locales, options) {
|
|
||||||
// 1. Let requestLocales be ? CanonicalizeLocaleList(locales).
|
|
||||||
const requestedLocales = CanonicalizeLocaleList(locales);
|
|
||||||
|
|
||||||
// 2. If options is undefined, then
|
|
||||||
if (options === undefined)
|
|
||||||
// a. Let options be ObjectCreate(%ObjectPrototype%).
|
|
||||||
options = {};
|
|
||||||
// 3. Else,
|
|
||||||
else
|
|
||||||
// a. Let options be ? ToObject(options).
|
|
||||||
options = ToObject(options);
|
|
||||||
|
|
||||||
const DateTimeFormat = dateTimeFormatInternalProperties;
|
|
||||||
|
|
||||||
// 4. Let localeData be %DateTimeFormat%.[[localeData]].
|
|
||||||
const localeData = DateTimeFormat.localeData;
|
|
||||||
|
|
||||||
// 5. Let opt be a new Record.
|
|
||||||
const localeOpt = new Record();
|
|
||||||
// 6. Set localeOpt.[[localeMatcher]] to "best fit".
|
|
||||||
localeOpt.localeMatcher = "best fit";
|
|
||||||
|
|
||||||
// 7. Let r be ResolveLocale(%DateTimeFormat%.[[availableLocales]], requestedLocales, localeOpt,
|
|
||||||
// %DateTimeFormat%.[[relevantExtensionKeys]], localeData).
|
|
||||||
const r = ResolveLocale(callFunction(DateTimeFormat.availableLocales, DateTimeFormat),
|
|
||||||
requestedLocales,
|
|
||||||
localeOpt,
|
|
||||||
DateTimeFormat.relevantExtensionKeys,
|
|
||||||
localeData);
|
|
||||||
|
|
||||||
// 8. Let style be ? GetOption(options, "style", "string", « "long", "short", "narrow" », "long").
|
|
||||||
const style = GetOption(options, "style", "string", ["long", "short", "narrow"], "long");
|
|
||||||
// 9. Let keys be ? Get(options, "keys").
|
|
||||||
let keys = options.keys;
|
|
||||||
|
|
||||||
// 10. If keys is undefined,
|
|
||||||
if (keys === undefined) {
|
|
||||||
// a. Let keys be ArrayCreate(0).
|
|
||||||
keys = [];
|
|
||||||
} else if (!IsObject(keys)) {
|
|
||||||
// 11. Else,
|
|
||||||
// a. If Type(keys) is not Object, throw a TypeError exception.
|
|
||||||
ThrowTypeError(JSMSG_INVALID_KEYS_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 12. Let processedKeys be ArrayCreate(0).
|
|
||||||
// (This really should be a List, but we use an Array here in order that
|
|
||||||
// |intl_ComputeDisplayNames| may infallibly access the list's length via
|
|
||||||
// |ArrayObject::length|.)
|
|
||||||
let processedKeys = [];
|
|
||||||
// 13. Let len be ? ToLength(? Get(keys, "length")).
|
|
||||||
let len = ToLength(keys.length);
|
|
||||||
// 14. Let i be 0.
|
|
||||||
// 15. Repeat, while i < len
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
// a. Let processedKey be ? ToString(? Get(keys, i)).
|
|
||||||
// b. Perform ? CreateDataPropertyOrThrow(processedKeys, i, processedKey).
|
|
||||||
callFunction(std_Array_push, processedKeys, ToString(keys[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 16. Let names be ? ComputeDisplayNames(r.[[locale]], style, processedKeys).
|
|
||||||
const names = intl_ComputeDisplayNames(r.locale, style, processedKeys);
|
|
||||||
|
|
||||||
// 17. Let values be ObjectCreate(%ObjectPrototype%).
|
|
||||||
const values = {};
|
|
||||||
|
|
||||||
// 18. Set i to 0.
|
|
||||||
// 19. Repeat, while i < len
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
// a. Let key be ? Get(processedKeys, i).
|
|
||||||
const key = processedKeys[i];
|
|
||||||
// b. Let name be ? Get(names, i).
|
|
||||||
const name = names[i];
|
|
||||||
// c. Assert: Type(name) is string.
|
|
||||||
assert(typeof name === "string", "unexpected non-string value");
|
|
||||||
// d. Assert: the length of name is greater than zero.
|
|
||||||
assert(name.length > 0, "empty string value");
|
|
||||||
// e. Perform ? DefinePropertyOrThrow(values, key, name).
|
|
||||||
_DefineDataProperty(values, key, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 20. Let options be ObjectCreate(%ObjectPrototype%).
|
|
||||||
// 21. Perform ! DefinePropertyOrThrow(result, "locale", r.[[locale]]).
|
|
||||||
// 22. Perform ! DefinePropertyOrThrow(result, "style", style).
|
|
||||||
// 23. Perform ! DefinePropertyOrThrow(result, "values", values).
|
|
||||||
const result = { locale: r.locale, style, values };
|
|
||||||
|
|
||||||
// 24. Return result.
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty("addIntlExtras"))
|
|
||||||
|
|
||||||
// Tests the PluralRules.resolvedOptions function for overriden Array[Symbol.species].
|
|
||||||
|
|
||||||
addIntlExtras(Intl);
|
|
||||||
|
|
||||||
var pl = new Intl.PluralRules("de");
|
|
||||||
|
|
||||||
Object.defineProperty(Array, Symbol.species, {
|
|
||||||
value: function() {
|
|
||||||
return new Proxy(["?"], {
|
|
||||||
get(t, pk, r) {
|
|
||||||
return Reflect.get(t, pk, r);
|
|
||||||
},
|
|
||||||
defineProperty(t, pk) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var pluralCategories = pl.resolvedOptions().pluralCategories;
|
|
||||||
|
|
||||||
assertEqArray(pluralCategories, ["one", "other"]);
|
|
||||||
|
|
||||||
if (typeof reportCompare === "function")
|
|
||||||
reportCompare(0, 0);
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
|
|
||||||
|
|
||||||
// Tests the getCanonicalLocales function for overriden Array[Symbol.species].
|
|
||||||
|
|
||||||
Object.defineProperty(Array, Symbol.species, {
|
|
||||||
value: function() {
|
|
||||||
return new Proxy(["?"], {
|
|
||||||
get(t, pk, r) {
|
|
||||||
return Reflect.get(t, pk, r);
|
|
||||||
},
|
|
||||||
defineProperty(t, pk) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var arr = Intl.getCanonicalLocales("de-x-private");
|
|
||||||
|
|
||||||
assertEqArray(arr, ["de-x-private"]);
|
|
||||||
|
|
||||||
if (typeof reportCompare === "function")
|
|
||||||
reportCompare(0, 0);
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue