mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
LibJS: Migrate remaining Intl objects to use ResolveOptions
This is an editorial change in the ECMA-402 spec. See:
75e67db
This commit is contained in:
parent
3f55240a8e
commit
2729c88154
Notes:
github-actions[bot]
2025-04-08 10:52:47 +00:00
Author: https://github.com/trflynn89
Commit: 2729c88154
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4275
8 changed files with 92 additions and 215 deletions
|
@ -23,17 +23,6 @@
|
|||
|
||||
namespace JS::Intl {
|
||||
|
||||
Optional<LocaleKey> locale_key_from_value(Value value)
|
||||
{
|
||||
if (value.is_undefined())
|
||||
return OptionalNone {};
|
||||
if (value.is_null())
|
||||
return Empty {};
|
||||
if (value.is_string())
|
||||
return value.as_string().utf8_string();
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
// 6.2.1 IsStructurallyValidLanguageTag ( locale ), https://tc39.es/ecma402/#sec-isstructurallyvalidlanguagetag
|
||||
bool is_structurally_valid_language_tag(StringView locale)
|
||||
{
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
namespace JS::Intl {
|
||||
|
||||
using LocaleKey = Variant<Empty, String>;
|
||||
Optional<LocaleKey> locale_key_from_value(Value);
|
||||
|
||||
struct LocaleOptions {
|
||||
Value locale_matcher;
|
||||
|
|
|
@ -50,67 +50,45 @@ ThrowCompletionOr<GC::Ref<Object>> DurationFormatConstructor::construct(Function
|
|||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
auto locales = vm.argument(0);
|
||||
auto locales_value = vm.argument(0);
|
||||
auto options_value = vm.argument(1);
|
||||
|
||||
// 2. Let durationFormat be ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.DurationFormatPrototype%", « [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[YearsOptions]], [[MonthsOptions]], [[WeeksOptions]], [[DaysOptions]], [[HoursOptions]], [[MinutesOptions]], [[SecondsOptions]], [[MillisecondsOptions]], [[MicrosecondsOptions]], [[NanosecondsOptions]], [[HourMinuteSeparator]], [[MinuteSecondSeparator]], [[FractionalDigits]] »).
|
||||
auto duration_format = TRY(ordinary_create_from_constructor<DurationFormat>(vm, new_target, &Intrinsics::intl_duration_format_prototype));
|
||||
|
||||
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||
auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
|
||||
// 3. Let optionsResolution be ? ResolveOptions(%Intl.DurationFormat%, %Intl.DurationFormat%.[[LocaleData]], locales, options).
|
||||
// 4. Set options to optionsResolution.[[Options]].
|
||||
// 5. Let r be optionsResolution.[[ResolvedLocale]].
|
||||
auto [options, result, _] = TRY(resolve_options(vm, duration_format, locales_value, options_value));
|
||||
|
||||
// 4. Let options be ? GetOptionsObject(options).
|
||||
auto options = TRY(get_options_object(vm, options_value));
|
||||
|
||||
// 5. Let matcher be ? GetOption(options, "localeMatcher", STRING, « "lookup", "best fit" », "best fit").
|
||||
auto matcher = TRY(get_option(vm, *options, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
|
||||
|
||||
// 6. Let numberingSystem be ? GetOption(options, "numberingSystem", STRING, EMPTY, undefined).
|
||||
auto numbering_system = TRY(get_option(vm, *options, vm.names.numberingSystem, OptionType::String, {}, Empty {}));
|
||||
|
||||
// 7. If numberingSystem is not undefined, then
|
||||
if (!numbering_system.is_undefined()) {
|
||||
// a. If numberingSystem cannot be matched by the type Unicode locale nonterminal, throw a RangeError exception.
|
||||
if (!Unicode::is_type_identifier(numbering_system.as_string().utf8_string_view()))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
}
|
||||
|
||||
// 8. Let opt be the Record { [[localeMatcher]]: matcher, [[nu]]: numberingSystem }.
|
||||
LocaleOptions opt {};
|
||||
opt.locale_matcher = matcher;
|
||||
opt.nu = locale_key_from_value(numbering_system);
|
||||
|
||||
// 9. Let r be ResolveLocale(%Intl.DurationFormat%.[[AvailableLocales]], requestedLocales, opt, %Intl.DurationFormat%.[[RelevantExtensionKeys]], %Intl.DurationFormat%.[[LocaleData]]).
|
||||
auto result = resolve_locale(requested_locales, opt, duration_format->relevant_extension_keys());
|
||||
|
||||
// 10. Set durationFormat.[[Locale]] to r.[[Locale]].
|
||||
// 6. Set durationFormat.[[Locale]] to r.[[Locale]].
|
||||
duration_format->set_locale(move(result.locale));
|
||||
|
||||
// 11. Let resolvedLocaleData be r.[[LocaleData]].
|
||||
// 7. Let resolvedLocaleData be r.[[LocaleData]].
|
||||
|
||||
// 12. Let digitalFormat be resolvedLocaleData.[[DigitalFormat]].
|
||||
// 8. Let digitalFormat be resolvedLocaleData.[[DigitalFormat]].
|
||||
auto digital_format = Unicode::digital_format(result.icu_locale);
|
||||
|
||||
// 13. Set durationFormat.[[HourMinuteSeparator]] to digitalFormat.[[HourMinuteSeparator]].
|
||||
// 9. Set durationFormat.[[HourMinuteSeparator]] to digitalFormat.[[HourMinuteSeparator]].
|
||||
duration_format->set_hour_minute_separator(move(digital_format.hours_minutes_separator));
|
||||
|
||||
// 14. Set durationFormat.[[MinuteSecondSeparator]] to digitalFormat.[[MinuteSecondSeparator]].
|
||||
// 10. Set durationFormat.[[MinuteSecondSeparator]] to digitalFormat.[[MinuteSecondSeparator]].
|
||||
duration_format->set_minute_second_separator(move(digital_format.minutes_seconds_separator));
|
||||
|
||||
// 15. Set durationFormat.[[NumberingSystem]] to r.[[nu]].
|
||||
// 11. Set durationFormat.[[NumberingSystem]] to r.[[nu]].
|
||||
if (auto* resolved_numbering_system = result.nu.get_pointer<String>())
|
||||
duration_format->set_numbering_system(move(*resolved_numbering_system));
|
||||
|
||||
// 16. Let style be ? GetOption(options, "style", STRING, « "long", "short", "narrow", "digital" », "short").
|
||||
// 12. Let style be ? GetOption(options, "style", STRING, « "long", "short", "narrow", "digital" », "short").
|
||||
auto style = TRY(get_option(vm, *options, vm.names.style, OptionType::String, { "long"sv, "short"sv, "narrow"sv, "digital"sv }, "short"sv));
|
||||
|
||||
// 17. Set durationFormat.[[Style]] to style.
|
||||
// 13. Set durationFormat.[[Style]] to style.
|
||||
duration_format->set_style(style.as_string().utf8_string_view());
|
||||
|
||||
// 18. Let prevStyle be the empty String.
|
||||
// 14. Let prevStyle be the empty String.
|
||||
Optional<DurationFormat::ValueStyle> previous_style;
|
||||
|
||||
// 19. For each row of Table 20, except the header row, in table order, do
|
||||
// 15. For each row of Table 20, except the header row, in table order, do
|
||||
for (auto const& duration_instances_component : duration_instances_components) {
|
||||
// a. Let slot be the Internal Slot value of the current row.
|
||||
auto slot = duration_instances_component.set_internal_slot;
|
||||
|
@ -137,10 +115,10 @@ ThrowCompletionOr<GC::Ref<Object>> DurationFormatConstructor::construct(Function
|
|||
}
|
||||
}
|
||||
|
||||
// 20. Set durationFormat.[[FractionalDigits]] to ? GetNumberOption(options, "fractionalDigits", 0, 9, undefined).
|
||||
// 16. Set durationFormat.[[FractionalDigits]] to ? GetNumberOption(options, "fractionalDigits", 0, 9, undefined).
|
||||
duration_format->set_fractional_digits(Optional<u8>(TRY(get_number_option(vm, *options, vm.names.fractionalDigits, 0, 9, {}))));
|
||||
|
||||
// 21. Return durationFormat.
|
||||
// 17. Return durationFormat.
|
||||
return duration_format;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,55 +48,42 @@ ThrowCompletionOr<GC::Ref<Object>> ListFormatConstructor::construct(FunctionObje
|
|||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
auto locale_value = vm.argument(0);
|
||||
auto locales_value = vm.argument(0);
|
||||
auto options_value = vm.argument(1);
|
||||
|
||||
// 2. Let listFormat be ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.ListFormat.prototype%", « [[InitializedListFormat]], [[Locale]], [[Type]], [[Style]], [[Templates]] »).
|
||||
auto list_format = TRY(ordinary_create_from_constructor<ListFormat>(vm, new_target, &Intrinsics::intl_list_format_prototype));
|
||||
|
||||
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||
auto requested_locales = TRY(canonicalize_locale_list(vm, locale_value));
|
||||
// 3. Let optionsResolution be ? ResolveOptions(%Intl.ListFormat%, %Intl.ListFormat%.[[LocaleData]], locales, options).
|
||||
// 4. Set options to optionsResolution.[[Options]].
|
||||
// 5. Let r be optionsResolution.[[ResolvedLocale]].
|
||||
auto [options, result, _] = TRY(resolve_options(vm, list_format, locales_value, options_value));
|
||||
|
||||
// 4. Set options to ? GetOptionsObject(options).
|
||||
auto options = TRY(get_options_object(vm, options_value));
|
||||
|
||||
// 5. Let opt be a new Record.
|
||||
LocaleOptions opt {};
|
||||
|
||||
// 6. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
|
||||
auto matcher = TRY(get_option(vm, *options, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
|
||||
|
||||
// 7. Set opt.[[localeMatcher]] to matcher.
|
||||
opt.locale_matcher = matcher;
|
||||
|
||||
// 8. Let r be ResolveLocale(%Intl.ListFormat%.[[AvailableLocales]], requestedLocales, opt, %Intl.ListFormat%.[[RelevantExtensionKeys]], %Intl.ListFormat%.[[LocaleData]]).
|
||||
auto result = resolve_locale(requested_locales, opt, list_format->relevant_extension_keys());
|
||||
|
||||
// 9. Set listFormat.[[Locale]] to r.[[Locale]].
|
||||
// 6. Set listFormat.[[Locale]] to r.[[Locale]].
|
||||
list_format->set_locale(move(result.locale));
|
||||
|
||||
// 10. Let type be ? GetOption(options, "type", string, « "conjunction", "disjunction", "unit" », "conjunction").
|
||||
// 7. Let type be ? GetOption(options, "type", string, « "conjunction", "disjunction", "unit" », "conjunction").
|
||||
auto type = TRY(get_option(vm, *options, vm.names.type, OptionType::String, { "conjunction"sv, "disjunction"sv, "unit"sv }, "conjunction"sv));
|
||||
|
||||
// 11. Set listFormat.[[Type]] to type.
|
||||
// 8. Set listFormat.[[Type]] to type.
|
||||
list_format->set_type(type.as_string().utf8_string_view());
|
||||
|
||||
// 12. Let style be ? GetOption(options, "style", string, « "long", "short", "narrow" », "long").
|
||||
// 9. Let style be ? GetOption(options, "style", string, « "long", "short", "narrow" », "long").
|
||||
auto style = TRY(get_option(vm, *options, vm.names.style, OptionType::String, { "long"sv, "short"sv, "narrow"sv }, "long"sv));
|
||||
|
||||
// 14. Set listFormat.[[Style]] to style.
|
||||
// 10. Set listFormat.[[Style]] to style.
|
||||
list_format->set_style(style.as_string().utf8_string_view());
|
||||
|
||||
// 14. Let resolvedLocaleData be r.[[LocaleData]].
|
||||
// 15. Let dataLocaleTypes be resolvedLocaleData.[[<type>]].
|
||||
// 16. Set listFormat.[[Templates]] to dataLocaleTypes.[[<style>]].
|
||||
// 11. Let resolvedLocaleData be r.[[LocaleData]].
|
||||
// 12. Let dataLocaleTypes be resolvedLocaleData.[[<type>]].
|
||||
// 13. Set listFormat.[[Templates]] to dataLocaleTypes.[[<style>]].
|
||||
auto formatter = Unicode::ListFormat::create(
|
||||
list_format->locale(),
|
||||
list_format->type(),
|
||||
list_format->style());
|
||||
list_format->set_formatter(move(formatter));
|
||||
|
||||
// 17. Return listFormat.
|
||||
// 14. Return listFormat.
|
||||
return list_format;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,62 +54,36 @@ ThrowCompletionOr<GC::Ref<Object>> NumberFormatConstructor::construct(FunctionOb
|
|||
// 2. Let numberFormat be ? OrdinaryCreateFromConstructor(newTarget, "%Intl.NumberFormat.prototype%", « [[InitializedNumberFormat]], [[Locale]], [[LocaleData]], [[NumberingSystem]], [[Style]], [[Unit]], [[UnitDisplay]], [[Currency]], [[CurrencyDisplay]], [[CurrencySign]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]], [[Notation]], [[CompactDisplay]], [[UseGrouping]], [[SignDisplay]], [[RoundingIncrement]], [[RoundingMode]], [[ComputedRoundingPriority]], [[TrailingZeroDisplay]], [[BoundFormat]] »).
|
||||
auto number_format = TRY(ordinary_create_from_constructor<NumberFormat>(vm, new_target, &Intrinsics::intl_number_format_prototype));
|
||||
|
||||
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||
auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value));
|
||||
// 3. Let optionsResolution be ? ResolveOptions(%Intl.NumberFormat%, %Intl.NumberFormat%.[[LocaleData]], locales, options, « COERCE-OPTIONS »).
|
||||
// 4. Set options to optionsResolution.[[Options]].
|
||||
// 5. Let r be optionsResolution.[[ResolvedLocale]].
|
||||
auto [options, result, _] = TRY(resolve_options(vm, number_format, locales_value, options_value, SpecialBehaviors::CoerceOptions));
|
||||
|
||||
// 4. Set options to ? CoerceOptionsToObject(options).
|
||||
auto* options = TRY(coerce_options_to_object(vm, options_value));
|
||||
|
||||
// 5. Let opt be a new Record.
|
||||
LocaleOptions opt {};
|
||||
|
||||
// 6. Let matcher be ? GetOption(options, "localeMatcher", STRING, « "lookup", "best fit" », "best fit").
|
||||
auto matcher = TRY(get_option(vm, *options, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
|
||||
|
||||
// 7. Set opt.[[localeMatcher]] to matcher.
|
||||
opt.locale_matcher = matcher;
|
||||
|
||||
// 8. Let numberingSystem be ? GetOption(options, "numberingSystem", STRING, EMPTY, undefined).
|
||||
auto numbering_system = TRY(get_option(vm, *options, vm.names.numberingSystem, OptionType::String, {}, Empty {}));
|
||||
|
||||
// 9. If numberingSystem is not undefined, then
|
||||
if (!numbering_system.is_undefined()) {
|
||||
// a. If numberingSystem cannot be matched by the type Unicode locale nonterminal, throw a RangeError exception.
|
||||
if (!Unicode::is_type_identifier(numbering_system.as_string().utf8_string_view()))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
}
|
||||
|
||||
// 10. Set opt.[[nu]] to numberingSystem.
|
||||
opt.nu = locale_key_from_value(numbering_system);
|
||||
|
||||
// 11. Let r be ResolveLocale(%Intl.NumberFormat%.[[AvailableLocales]], requestedLocales, opt, %Intl.NumberFormat%.[[RelevantExtensionKeys]], %Intl.NumberFormat%.[[LocaleData]]).
|
||||
auto result = resolve_locale(requested_locales, opt, number_format->relevant_extension_keys());
|
||||
|
||||
// 12. Set numberFormat.[[Locale]] to r.[[Locale]].
|
||||
// 6. Set numberFormat.[[Locale]] to r.[[Locale]].
|
||||
number_format->set_locale(move(result.locale));
|
||||
|
||||
// 13. Set numberFormat.[[LocaleData]] to r.[[LocaleData]].
|
||||
// 7. Set numberFormat.[[LocaleData]] to r.[[LocaleData]].
|
||||
|
||||
// 14. Set numberFormat.[[NumberingSystem]] to r.[[nu]].
|
||||
// 8. Set numberFormat.[[NumberingSystem]] to r.[[nu]].
|
||||
if (auto* resolved_numbering_system = result.nu.get_pointer<String>())
|
||||
number_format->set_numbering_system(move(*resolved_numbering_system));
|
||||
|
||||
// 15. Perform ? SetNumberFormatUnitOptions(numberFormat, options).
|
||||
// 9. Perform ? SetNumberFormatUnitOptions(numberFormat, options).
|
||||
TRY(set_number_format_unit_options(vm, number_format, *options));
|
||||
|
||||
// 16. Let style be numberFormat.[[Style]].
|
||||
// 10. Let style be numberFormat.[[Style]].
|
||||
auto style = number_format->style();
|
||||
|
||||
// 17. Let notation be ? GetOption(options, "notation", STRING, « "standard", "scientific", "engineering", "compact" », "standard").
|
||||
// 11. Let notation be ? GetOption(options, "notation", STRING, « "standard", "scientific", "engineering", "compact" », "standard").
|
||||
auto notation = TRY(get_option(vm, *options, vm.names.notation, OptionType::String, { "standard"sv, "scientific"sv, "engineering"sv, "compact"sv }, "standard"sv));
|
||||
|
||||
// 18. Set numberFormat.[[Notation]] to notation.
|
||||
// 12. Set numberFormat.[[Notation]] to notation.
|
||||
number_format->set_notation(notation.as_string().utf8_string_view());
|
||||
|
||||
int default_min_fraction_digits = 0;
|
||||
int default_max_fraction_digits = 0;
|
||||
|
||||
// 19. If style is "currency" and notation is "standard", then
|
||||
// 13. If style is "currency" and notation is "standard", then
|
||||
if (style == Unicode::NumberFormatStyle::Currency && number_format->notation() == Unicode::Notation::Standard) {
|
||||
// a. Let currency be numberFormat.[[Currency]].
|
||||
auto const& currency = number_format->currency();
|
||||
|
@ -123,7 +97,7 @@ ThrowCompletionOr<GC::Ref<Object>> NumberFormatConstructor::construct(FunctionOb
|
|||
// d. Let mxfdDefault be cDigits.
|
||||
default_max_fraction_digits = digits;
|
||||
}
|
||||
// 20. Else,
|
||||
// 14. Else,
|
||||
else {
|
||||
// a. Let mnfdDefault be 0.
|
||||
default_min_fraction_digits = 0;
|
||||
|
@ -135,16 +109,16 @@ ThrowCompletionOr<GC::Ref<Object>> NumberFormatConstructor::construct(FunctionOb
|
|||
default_max_fraction_digits = style == Unicode::NumberFormatStyle::Percent ? 0 : 3;
|
||||
}
|
||||
|
||||
// 21. Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation).
|
||||
// 15. Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation).
|
||||
TRY(set_number_format_digit_options(vm, number_format, *options, default_min_fraction_digits, default_max_fraction_digits, number_format->notation()));
|
||||
|
||||
// 22. Let compactDisplay be ? GetOption(options, "compactDisplay", STRING, « "short", "long" », "short").
|
||||
// 16. Let compactDisplay be ? GetOption(options, "compactDisplay", STRING, « "short", "long" », "short").
|
||||
auto compact_display = TRY(get_option(vm, *options, vm.names.compactDisplay, OptionType::String, { "short"sv, "long"sv }, "short"sv));
|
||||
|
||||
// 23. Let defaultUseGrouping be "auto".
|
||||
// 17. Let defaultUseGrouping be "auto".
|
||||
auto default_use_grouping = "auto"sv;
|
||||
|
||||
// 24. If notation is "compact", then
|
||||
// 18. If notation is "compact", then
|
||||
if (number_format->notation() == Unicode::Notation::Compact) {
|
||||
// a. Set numberFormat.[[CompactDisplay]] to compactDisplay.
|
||||
number_format->set_compact_display(compact_display.as_string().utf8_string_view());
|
||||
|
@ -153,32 +127,32 @@ ThrowCompletionOr<GC::Ref<Object>> NumberFormatConstructor::construct(FunctionOb
|
|||
default_use_grouping = "min2"sv;
|
||||
}
|
||||
|
||||
// 25. NOTE: For historical reasons, the strings "true" and "false" are accepted and replaced with the default value.
|
||||
// 26. Let useGrouping be ? GetBooleanOrStringNumberFormatOption(options, "useGrouping", « "min2", "auto", "always", "true", "false" », defaultUseGrouping).
|
||||
// 19. NOTE: For historical reasons, the strings "true" and "false" are accepted and replaced with the default value.
|
||||
// 20. Let useGrouping be ? GetBooleanOrStringNumberFormatOption(options, "useGrouping", « "min2", "auto", "always", "true", "false" », defaultUseGrouping).
|
||||
auto use_grouping = TRY(get_boolean_or_string_number_format_option(vm, *options, vm.names.useGrouping, { "min2"sv, "auto"sv, "always"sv, "true"sv, "false"sv }, default_use_grouping));
|
||||
|
||||
// 27. If useGrouping is "true" or useGrouping is "false", set useGrouping to defaultUseGrouping.
|
||||
// 21. If useGrouping is "true" or useGrouping is "false", set useGrouping to defaultUseGrouping.
|
||||
if (auto const* use_grouping_string = use_grouping.get_pointer<StringView>()) {
|
||||
if (use_grouping_string->is_one_of("true"sv, "false"sv))
|
||||
use_grouping = default_use_grouping;
|
||||
}
|
||||
|
||||
// 28. If useGrouping is true, set useGrouping to "always".
|
||||
// 22. If useGrouping is true, set useGrouping to "always".
|
||||
if (auto const* use_grouping_boolean = use_grouping.get_pointer<bool>()) {
|
||||
if (*use_grouping_boolean)
|
||||
use_grouping = "always"sv;
|
||||
}
|
||||
|
||||
// 29. Set numberFormat.[[UseGrouping]] to useGrouping.
|
||||
// 23. Set numberFormat.[[UseGrouping]] to useGrouping.
|
||||
number_format->set_use_grouping(use_grouping);
|
||||
|
||||
// 30. Let signDisplay be ? GetOption(options, "signDisplay", STRING, « "auto", "never", "always", "exceptZero", "negative" », "auto").
|
||||
// 24. Let signDisplay be ? GetOption(options, "signDisplay", STRING, « "auto", "never", "always", "exceptZero", "negative" », "auto").
|
||||
auto sign_display = TRY(get_option(vm, *options, vm.names.signDisplay, OptionType::String, { "auto"sv, "never"sv, "always"sv, "exceptZero"sv, "negative"sv }, "auto"sv));
|
||||
|
||||
// 31. Set numberFormat.[[SignDisplay]] to signDisplay.
|
||||
// 25. Set numberFormat.[[SignDisplay]] to signDisplay.
|
||||
number_format->set_sign_display(sign_display.as_string().utf8_string_view());
|
||||
|
||||
// 32. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||
// 26. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||
// a. Let this be the this value.
|
||||
// b. Return ? ChainNumberFormat(numberFormat, NewTarget, this).
|
||||
|
||||
|
@ -189,7 +163,7 @@ ThrowCompletionOr<GC::Ref<Object>> NumberFormatConstructor::construct(FunctionOb
|
|||
number_format->rounding_options());
|
||||
number_format->set_formatter(move(formatter));
|
||||
|
||||
// 33. Return numberFormat.
|
||||
// 27. Return numberFormat.
|
||||
return number_format;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,34 +55,21 @@ ThrowCompletionOr<GC::Ref<Object>> PluralRulesConstructor::construct(FunctionObj
|
|||
// 2. Let pluralRules be ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.PluralRules.prototype%", « [[InitializedPluralRules]], [[Locale]], [[Type]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]], [[RoundingIncrement]], [[RoundingMode]], [[ComputedRoundingPriority]], [[TrailingZeroDisplay]] »).
|
||||
auto plural_rules = TRY(ordinary_create_from_constructor<PluralRules>(vm, new_target, &Intrinsics::intl_plural_rules_prototype));
|
||||
|
||||
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||
auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value));
|
||||
// 3. Let optionsResolution be ? ResolveOptions(%Intl.PluralRules%, %Intl.PluralRules%.[[LocaleData]], locales, options, « COERCE-OPTIONS »).
|
||||
// 4. Set options to optionsResolution.[[Options]].
|
||||
// 5. Let r be optionsResolution.[[ResolvedLocale]].
|
||||
auto [options, result, _] = TRY(resolve_options(vm, plural_rules, locales_value, options_value, SpecialBehaviors::CoerceOptions));
|
||||
|
||||
// 4. Set options to ? CoerceOptionsToObject(options).
|
||||
auto* options = TRY(coerce_options_to_object(vm, options_value));
|
||||
|
||||
// 5. Let opt be a new Record.
|
||||
LocaleOptions opt {};
|
||||
|
||||
// 6. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
|
||||
auto matcher = TRY(get_option(vm, *options, vm.names.localeMatcher, OptionType::String, AK::Array { "lookup"sv, "best fit"sv }, "best fit"sv));
|
||||
|
||||
// 7. Set opt.[[localeMatcher]] to matcher.
|
||||
opt.locale_matcher = matcher;
|
||||
|
||||
// 8. Let r be ResolveLocale(%Intl.PluralRules%.[[AvailableLocales]], requestedLocales, opt, %Intl.PluralRules%.[[RelevantExtensionKeys]], %Intl.PluralRules%.[[LocaleData]]).
|
||||
auto result = resolve_locale(requested_locales, opt, plural_rules->relevant_extension_keys());
|
||||
|
||||
// 9. Set pluralRules.[[Locale]] to r.[[locale]].
|
||||
// 6. Set pluralRules.[[Locale]] to r.[[locale]].
|
||||
plural_rules->set_locale(move(result.locale));
|
||||
|
||||
// 10. Let t be ? GetOption(options, "type", string, « "cardinal", "ordinal" », "cardinal").
|
||||
// 7. Let t be ? GetOption(options, "type", string, « "cardinal", "ordinal" », "cardinal").
|
||||
auto type = TRY(get_option(vm, *options, vm.names.type, OptionType::String, AK::Array { "cardinal"sv, "ordinal"sv }, "cardinal"sv));
|
||||
|
||||
// 11. Set pluralRules.[[Type]] to t.
|
||||
// 8. Set pluralRules.[[Type]] to t.
|
||||
plural_rules->set_type(type.as_string().utf8_string_view());
|
||||
|
||||
// 12. Perform ? SetNumberFormatDigitOptions(pluralRules, options, 0, 3, "standard").
|
||||
// 9. Perform ? SetNumberFormatDigitOptions(pluralRules, options, 0, 3, "standard").
|
||||
TRY(set_number_format_digit_options(vm, plural_rules, *options, 0, 3, Unicode::Notation::Standard));
|
||||
|
||||
// Non-standard, create an ICU number formatter for this Intl object.
|
||||
|
@ -94,7 +81,7 @@ ThrowCompletionOr<GC::Ref<Object>> PluralRulesConstructor::construct(FunctionObj
|
|||
formatter->create_plural_rules(plural_rules->type());
|
||||
plural_rules->set_formatter(move(formatter));
|
||||
|
||||
// 13. Return pluralRules.
|
||||
// 10. Return pluralRules.
|
||||
return plural_rules;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,69 +54,45 @@ ThrowCompletionOr<GC::Ref<Object>> RelativeTimeFormatConstructor::construct(Func
|
|||
// 2. Let relativeTimeFormat be ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.RelativeTimeFormat.prototype%", « [[InitializedRelativeTimeFormat]], [[Locale]], [[LocaleData]], [[Style]], [[Numeric]], [[NumberFormat]], [[NumberingSystem]], [[PluralRules]] »).
|
||||
auto relative_time_format = TRY(ordinary_create_from_constructor<RelativeTimeFormat>(vm, new_target, &Intrinsics::intl_relative_time_format_prototype));
|
||||
|
||||
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||
auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value));
|
||||
// 3. Let optionsResolution be ? ResolveOptions(%Intl.RelativeTimeFormat%, %Intl.RelativeTimeFormat%.[[LocaleData]], locales, options, « COERCE-OPTIONS »).
|
||||
// 4. Set options to optionsResolution.[[Options]].
|
||||
// 5. Let r be optionsResolution.[[ResolvedLocale]].
|
||||
auto [options, result, _] = TRY(resolve_options(vm, relative_time_format, locales_value, options_value, SpecialBehaviors::CoerceOptions));
|
||||
|
||||
// 4. Set options to ? CoerceOptionsToObject(options).
|
||||
auto* options = TRY(coerce_options_to_object(vm, options_value));
|
||||
|
||||
// 5. Let opt be a new Record.
|
||||
LocaleOptions opt {};
|
||||
|
||||
// 6. Let matcher be ? GetOption(options, "localeMatcher", STRING, « "lookup", "best fit" », "best fit").
|
||||
auto matcher = TRY(get_option(vm, *options, vm.names.localeMatcher, OptionType::String, AK::Array { "lookup"sv, "best fit"sv }, "best fit"sv));
|
||||
|
||||
// 7. Set opt.[[LocaleMatcher]] to matcher.
|
||||
opt.locale_matcher = matcher;
|
||||
|
||||
// 8. Let numberingSystem be ? GetOption(options, "numberingSystem", STRING, EMPTY, undefined).
|
||||
auto numbering_system = TRY(get_option(vm, *options, vm.names.numberingSystem, OptionType::String, {}, Empty {}));
|
||||
|
||||
// 9. If numberingSystem is not undefined, then
|
||||
if (!numbering_system.is_undefined()) {
|
||||
// a. If numberingSystem cannot be matched by the type Unicode locale nonterminal, throw a RangeError exception.
|
||||
if (!Unicode::is_type_identifier(numbering_system.as_string().utf8_string_view()))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
}
|
||||
|
||||
// 10. Set opt.[[nu]] to numberingSystem.
|
||||
opt.nu = locale_key_from_value(numbering_system);
|
||||
|
||||
// 11. Let r be ResolveLocale(%Intl.RelativeTimeFormat%.[[AvailableLocales]], requestedLocales, opt, %Intl.RelativeTimeFormat%.[[RelevantExtensionKeys]], %Intl.RelativeTimeFormat%.[[LocaleData]]).
|
||||
auto result = resolve_locale(requested_locales, opt, relative_time_format->relevant_extension_keys());
|
||||
|
||||
// 12. Let locale be r.[[Locale]].
|
||||
// 6. Let locale be r.[[Locale]].
|
||||
auto locale = move(result.locale);
|
||||
|
||||
// 13. Set relativeTimeFormat.[[Locale]] to locale.
|
||||
// 7. Set relativeTimeFormat.[[Locale]] to locale.
|
||||
relative_time_format->set_locale(locale);
|
||||
|
||||
// 14. Set relativeTimeFormat.[[LocaleData]] to r.[[LocaleData]].
|
||||
// 8. Set relativeTimeFormat.[[LocaleData]] to r.[[LocaleData]].
|
||||
|
||||
// 15. Set relativeTimeFormat.[[NumberingSystem]] to r.[[nu]].
|
||||
// 9. Set relativeTimeFormat.[[NumberingSystem]] to r.[[nu]].
|
||||
if (auto* resolved_numbering_system = result.nu.get_pointer<String>())
|
||||
relative_time_format->set_numbering_system(move(*resolved_numbering_system));
|
||||
|
||||
// 16. Let style be ? GetOption(options, "style", STRING, « "long", "short", "narrow" », "long").
|
||||
// 10. Let style be ? GetOption(options, "style", STRING, « "long", "short", "narrow" », "long").
|
||||
auto style = TRY(get_option(vm, *options, vm.names.style, OptionType::String, { "long"sv, "short"sv, "narrow"sv }, "long"sv));
|
||||
|
||||
// 17. Set relativeTimeFormat.[[Style]] to style.
|
||||
// 11. Set relativeTimeFormat.[[Style]] to style.
|
||||
relative_time_format->set_style(style.as_string().utf8_string_view());
|
||||
|
||||
// 18. Let numeric be ? GetOption(options, "numeric", STRING, « "always", "auto" », "always").
|
||||
// 12. Let numeric be ? GetOption(options, "numeric", STRING, « "always", "auto" », "always").
|
||||
auto numeric = TRY(get_option(vm, *options, vm.names.numeric, OptionType::String, { "always"sv, "auto"sv }, "always"sv));
|
||||
|
||||
// 19. Set relativeTimeFormat.[[Numeric]] to numeric.
|
||||
// 13. Set relativeTimeFormat.[[Numeric]] to numeric.
|
||||
relative_time_format->set_numeric(numeric.as_string().utf8_string_view());
|
||||
|
||||
// 20. Let relativeTimeFormat.[[NumberFormat]] be ! Construct(%Intl.NumberFormat%, « locale »).
|
||||
// 21. Let relativeTimeFormat.[[PluralRules]] be ! Construct(%Intl.PluralRules%, « locale »).
|
||||
// 14. Let nfOptions be OrdinaryObjectCreate(null).
|
||||
// 15. Perform ! CreateDataPropertyOrThrow(nfOptions, "numberingSystem", relativeTimeFormat.[[NumberingSystem]]).
|
||||
// 16. Let relativeTimeFormat.[[NumberFormat]] be ! Construct(%Intl.NumberFormat%, « locale, nfOptions »).
|
||||
// 17. Let relativeTimeFormat.[[PluralRules]] be ! Construct(%Intl.PluralRules%, « locale »).
|
||||
auto formatter = Unicode::RelativeTimeFormat::create(
|
||||
result.icu_locale,
|
||||
relative_time_format->style());
|
||||
relative_time_format->set_formatter(move(formatter));
|
||||
|
||||
// 22. Return relativeTimeFormat.
|
||||
// 18. Return relativeTimeFormat.
|
||||
return relative_time_format;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,44 +48,31 @@ ThrowCompletionOr<GC::Ref<Object>> SegmenterConstructor::construct(FunctionObjec
|
|||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
auto locales = vm.argument(0);
|
||||
auto locales_value = vm.argument(0);
|
||||
auto options_value = vm.argument(1);
|
||||
|
||||
// 2. Let internalSlotsList be « [[InitializedSegmenter]], [[Locale]], [[SegmenterGranularity]] ».
|
||||
// 3. Let segmenter be ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.Segmenter.prototype%", internalSlotsList).
|
||||
auto segmenter = TRY(ordinary_create_from_constructor<Segmenter>(vm, new_target, &Intrinsics::intl_segmenter_prototype));
|
||||
|
||||
// 4. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||
auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
|
||||
// 4. Let optionsResolution be ? ResolveOptions(%Intl.Segmenter%, %Intl.Segmenter%.[[LocaleData]], locales, options).
|
||||
// 5. Set options to optionsResolution.[[Options]].
|
||||
// 6. Let r be optionsResolution.[[ResolvedLocale]].
|
||||
auto [options, result, _] = TRY(resolve_options(vm, segmenter, locales_value, options_value));
|
||||
|
||||
// 5. Set options to ? GetOptionsObject(options).
|
||||
auto options = TRY(get_options_object(vm, options_value));
|
||||
|
||||
// 6. Let opt be a new Record.
|
||||
LocaleOptions opt {};
|
||||
|
||||
// 7. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
|
||||
auto matcher = TRY(get_option(vm, *options, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
|
||||
|
||||
// 8. Set opt.[[localeMatcher]] to matcher.
|
||||
opt.locale_matcher = matcher;
|
||||
|
||||
// 9. Let r be ResolveLocale(%Intl.Segmenter%.[[AvailableLocales]], requestedLocales, opt, %Intl.Segmenter%.[[RelevantExtensionKeys]], %Intl.Segmenter%.[[LocaleData]]).
|
||||
auto result = resolve_locale(requested_locales, opt, segmenter->relevant_extension_keys());
|
||||
|
||||
// 10. Set segmenter.[[Locale]] to r.[[locale]].
|
||||
// 7. Set segmenter.[[Locale]] to r.[[locale]].
|
||||
segmenter->set_locale(move(result.locale));
|
||||
|
||||
// 11. Let granularity be ? GetOption(options, "granularity", string, « "grapheme", "word", "sentence" », "grapheme").
|
||||
// 8. Let granularity be ? GetOption(options, "granularity", string, « "grapheme", "word", "sentence" », "grapheme").
|
||||
auto granularity = TRY(get_option(vm, *options, vm.names.granularity, OptionType::String, { "grapheme"sv, "word"sv, "sentence"sv }, "grapheme"sv));
|
||||
|
||||
// 12. Set segmenter.[[SegmenterGranularity]] to granularity.
|
||||
// 9. Set segmenter.[[SegmenterGranularity]] to granularity.
|
||||
segmenter->set_segmenter_granularity(granularity.as_string().utf8_string_view());
|
||||
|
||||
auto locale_segmenter = Unicode::Segmenter::create(segmenter->locale(), segmenter->segmenter_granularity());
|
||||
segmenter->set_segmenter(move(locale_segmenter));
|
||||
|
||||
// 13. Return segmenter.
|
||||
// 10. Return segmenter.
|
||||
return segmenter;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue