mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1610514 - Part 3: Pass through a boolean flag to detect style=unit number formatters. r=jwalden
Differential Revision: https://phabricator.services.mozilla.com/D60969 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
16f000f4f4
commit
ffe63d4342
@ -31,6 +31,6 @@ function BigInt_toLocaleString() {
|
||||
}
|
||||
|
||||
// Step 3.
|
||||
return intl_FormatNumber(numberFormat, x, /* formatToParts = */ false);
|
||||
return intl_FormatNumber(numberFormat, x, /* formatToParts = */ false, /* unitStyle = */ false);
|
||||
}
|
||||
#endif // JS_HAS_INTL_API
|
||||
|
@ -35,7 +35,7 @@ function Number_toLocaleString() {
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
return intl_FormatNumber(numberFormat, x, /* formatToParts = */ false);
|
||||
return intl_FormatNumber(numberFormat, x, /* formatToParts = */ false, /* unitStyle = */ false);
|
||||
}
|
||||
#endif // JS_HAS_INTL_API
|
||||
|
||||
|
@ -1005,8 +1005,11 @@ static bool FormatNumeric(JSContext* cx, const UNumberFormatter* nf,
|
||||
return true;
|
||||
}
|
||||
|
||||
enum class FormattingType { ForUnit, NotForUnit };
|
||||
|
||||
static FieldType GetFieldTypeForNumberField(UNumberFormatFields fieldName,
|
||||
HandleValue x) {
|
||||
HandleValue x,
|
||||
FormattingType formattingType) {
|
||||
// See intl/icu/source/i18n/unicode/unum.h for a detailed field list. This
|
||||
// list is deliberately exhaustive: cases might have to be added/removed if
|
||||
// this code is compiled with a different ICU with more UNumberFormatFields
|
||||
@ -1044,6 +1047,11 @@ static FieldType GetFieldTypeForNumberField(UNumberFormatFields fieldName,
|
||||
}
|
||||
|
||||
case UNUM_PERCENT_FIELD:
|
||||
// Percent fields are returned as "unit" elements when the number
|
||||
// formatter's style is "unit".
|
||||
if (formattingType == FormattingType::ForUnit) {
|
||||
return &JSAtomState::unit;
|
||||
}
|
||||
return &JSAtomState::percentSign;
|
||||
|
||||
case UNUM_CURRENCY_FIELD:
|
||||
@ -1418,6 +1426,7 @@ static bool FormattedNumberToParts(JSContext* cx,
|
||||
const UFormattedValue* formattedValue,
|
||||
HandleValue number,
|
||||
FieldType relativeTimeUnit,
|
||||
FormattingType formattingType,
|
||||
MutableHandleValue result) {
|
||||
MOZ_ASSERT(number.isNumeric());
|
||||
|
||||
@ -1468,8 +1477,8 @@ static bool FormattedNumberToParts(JSContext* cx,
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldType type =
|
||||
GetFieldTypeForNumberField(UNumberFormatFields(field), number);
|
||||
FieldType type = GetFieldTypeForNumberField(UNumberFormatFields(field),
|
||||
number, formattingType);
|
||||
|
||||
if (!fields.append(type, beginIndex, endIndex)) {
|
||||
return false;
|
||||
@ -1489,9 +1498,9 @@ bool js::intl::FormattedRelativeTimeToParts(
|
||||
JSContext* cx, const UFormattedValue* formattedValue, double timeValue,
|
||||
FieldType relativeTimeUnit, MutableHandleValue result) {
|
||||
Value tval = DoubleValue(timeValue);
|
||||
return FormattedNumberToParts(cx, formattedValue,
|
||||
HandleValue::fromMarkedLocation(&tval),
|
||||
relativeTimeUnit, result);
|
||||
return FormattedNumberToParts(
|
||||
cx, formattedValue, HandleValue::fromMarkedLocation(&tval),
|
||||
relativeTimeUnit, FormattingType::NotForUnit, result);
|
||||
}
|
||||
#else
|
||||
static ArrayObject* LegacyFormattedNumberToParts(
|
||||
@ -1542,6 +1551,7 @@ static ArrayObject* LegacyFormattedNumberToParts(
|
||||
|
||||
static bool FormatNumericToParts(JSContext* cx, const UNumberFormatter* nf,
|
||||
UFormattedNumber* formatted, HandleValue x,
|
||||
FormattingType formattingType,
|
||||
MutableHandleValue result) {
|
||||
PartitionNumberPatternResult formattedValue =
|
||||
PartitionNumberPattern(cx, nf, formatted, x);
|
||||
@ -1550,7 +1560,8 @@ static bool FormatNumericToParts(JSContext* cx, const UNumberFormatter* nf,
|
||||
}
|
||||
|
||||
#ifndef U_HIDE_DRAFT_API
|
||||
return FormattedNumberToParts(cx, formattedValue, x, nullptr, result);
|
||||
return FormattedNumberToParts(cx, formattedValue, x, nullptr, formattingType,
|
||||
result);
|
||||
#else
|
||||
return LegacyFormattedNumberToParts(cx, formattedValue, x, result);
|
||||
#endif
|
||||
@ -1558,10 +1569,11 @@ static bool FormatNumericToParts(JSContext* cx, const UNumberFormatter* nf,
|
||||
|
||||
bool js::intl_FormatNumber(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 3);
|
||||
MOZ_ASSERT(args.length() == 4);
|
||||
MOZ_ASSERT(args[0].isObject());
|
||||
MOZ_ASSERT(args[1].isNumeric());
|
||||
MOZ_ASSERT(args[2].isBoolean());
|
||||
MOZ_ASSERT(args[3].isBoolean());
|
||||
|
||||
Rooted<NumberFormatObject*> numberFormat(
|
||||
cx, &args[0].toObject().as<NumberFormatObject>());
|
||||
@ -1593,7 +1605,11 @@ bool js::intl_FormatNumber(JSContext* cx, unsigned argc, Value* vp) {
|
||||
|
||||
// Use the UNumberFormatter to actually format the number.
|
||||
if (args[2].toBoolean()) {
|
||||
return FormatNumericToParts(cx, nf, formatted, args[1], args.rval());
|
||||
FormattingType formattingType = args[3].toBoolean()
|
||||
? FormattingType::ForUnit
|
||||
: FormattingType::NotForUnit;
|
||||
return FormatNumericToParts(cx, nf, formatted, args[1], formattingType,
|
||||
args.rval());
|
||||
}
|
||||
|
||||
return FormatNumeric(cx, nf, formatted, args[1], args.rval());
|
||||
|
@ -94,7 +94,8 @@ extern MOZ_MUST_USE bool intl_numberingSystem(JSContext* cx, unsigned argc,
|
||||
*
|
||||
* Spec: ECMAScript Internationalization API Specification, 11.3.2.
|
||||
*
|
||||
* Usage: formatted = intl_FormatNumber(numberFormat, x, formatToParts)
|
||||
* Usage: formatted = intl_FormatNumber(numberFormat, x, formatToParts,
|
||||
* unitStyle)
|
||||
*/
|
||||
extern MOZ_MUST_USE bool intl_FormatNumber(JSContext* cx, unsigned argc,
|
||||
Value* vp);
|
||||
|
@ -698,7 +698,7 @@ function createNumberFormatFormat(nf) {
|
||||
var x = ToNumeric(value);
|
||||
|
||||
// Step 5.
|
||||
return intl_FormatNumber(nf, x, /* formatToParts = */ false);
|
||||
return intl_FormatNumber(nf, x, /* formatToParts = */ false, /* unitStyle = */ false);
|
||||
};
|
||||
}
|
||||
|
||||
@ -746,14 +746,14 @@ function Intl_NumberFormat_formatToParts(value) {
|
||||
"Intl_NumberFormat_formatToParts");
|
||||
}
|
||||
|
||||
// Ensure the NumberFormat internals are resolved.
|
||||
getNumberFormatInternals(nf);
|
||||
var internals = getNumberFormatInternals(nf);
|
||||
var unitStyle = internals.style === "unit";
|
||||
|
||||
// Step 4.
|
||||
var x = ToNumeric(value);
|
||||
|
||||
// Step 5.
|
||||
return intl_FormatNumber(nf, x, /* formatToParts = */ true);
|
||||
return intl_FormatNumber(nf, x, /* formatToParts = */ true, unitStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -464,9 +464,6 @@ skip script test262/intl402/NumberFormat/prototype/format/signDisplay-ko-KR.js
|
||||
skip script test262/intl402/NumberFormat/prototype/format/signDisplay-de-DE.js
|
||||
skip script test262/intl402/NumberFormat/prototype/format/signDisplay-rounding.js
|
||||
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1610514
|
||||
skip script test262/intl402/NumberFormat/prototype/formatToParts/percent-en-US.js
|
||||
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1608809
|
||||
skip script test262/language/expressions/class/super-evaluation-order.js
|
||||
|
||||
|
@ -0,0 +1,86 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("Intl")||release_or_beta)
|
||||
|
||||
const sanctionedSimpleUnitIdentifiers = [
|
||||
"acre",
|
||||
"bit",
|
||||
"byte",
|
||||
"celsius",
|
||||
"centimeter",
|
||||
"day",
|
||||
"degree",
|
||||
"fahrenheit",
|
||||
"fluid-ounce",
|
||||
"foot",
|
||||
"gallon",
|
||||
"gigabit",
|
||||
"gigabyte",
|
||||
"gram",
|
||||
"hectare",
|
||||
"hour",
|
||||
"inch",
|
||||
"kilobit",
|
||||
"kilobyte",
|
||||
"kilogram",
|
||||
"kilometer",
|
||||
"liter",
|
||||
"megabit",
|
||||
"megabyte",
|
||||
"meter",
|
||||
"mile",
|
||||
"mile-scandinavian",
|
||||
"milliliter",
|
||||
"millimeter",
|
||||
"millisecond",
|
||||
"minute",
|
||||
"month",
|
||||
"ounce",
|
||||
"percent",
|
||||
"petabyte",
|
||||
"pound",
|
||||
"second",
|
||||
"stone",
|
||||
"terabit",
|
||||
"terabyte",
|
||||
"week",
|
||||
"yard",
|
||||
"year",
|
||||
];
|
||||
|
||||
// Test only English and Chinese to keep the overall runtime reasonable.
|
||||
//
|
||||
// Chinese is included because it contains more than one "unit" element for
|
||||
// certain unit combinations.
|
||||
const locales = ["en", "zh"];
|
||||
|
||||
// Plural rules for English only differentiate between "one" and "other". Plural
|
||||
// rules for Chinese only use "other". That means we only need to test two values
|
||||
// per unit.
|
||||
const values = [0, 1];
|
||||
|
||||
// Ensure unit formatters contain at least one "unit" element.
|
||||
|
||||
for (const locale of locales) {
|
||||
for (const unit of sanctionedSimpleUnitIdentifiers) {
|
||||
const nf = new Intl.NumberFormat(locale, {style: "unit", unit});
|
||||
|
||||
for (const value of values) {
|
||||
assertEq(nf.formatToParts(value).filter(e => e.type === "unit").length > 0, true,
|
||||
`locale=${locale}, unit=${unit}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const numerator of sanctionedSimpleUnitIdentifiers) {
|
||||
for (const denominator of sanctionedSimpleUnitIdentifiers) {
|
||||
const unit = `${numerator}-per-${denominator}`;
|
||||
const nf = new Intl.NumberFormat(locale, {style: "unit", unit});
|
||||
|
||||
for (const value of values) {
|
||||
assertEq(nf.formatToParts(value).filter(e => e.type === "unit").length > 0, true,
|
||||
`locale=${locale}, unit=${unit}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
Loading…
Reference in New Issue
Block a user