diff --git a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp index d578ebf2374..4cd76c77bb9 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp @@ -22,24 +22,24 @@ ListFormat::ListFormat(Object& prototype) } // 13.5.2 CreatePartsFromList ( listFormat, list ), https://tc39.es/ecma402/#sec-createpartsfromlist -Vector<::Locale::ListFormatPart> create_parts_from_list(ListFormat const& list_format, Vector const& list) +Vector<::Locale::ListFormat::Partition> create_parts_from_list(ListFormat const& list_format, ReadonlySpan list) { - return ::Locale::format_list_to_parts(list_format.locale(), list_format.type(), list_format.style(), list); + return list_format.formatter().format_to_parts(list); } // 13.5.3 FormatList ( listFormat, list ), https://tc39.es/ecma402/#sec-formatlist -String format_list(ListFormat const& list_format, Vector const& list) +String format_list(ListFormat const& list_format, ReadonlySpan list) { // 1. Let parts be ! CreatePartsFromList(listFormat, list). // 2. Let result be an empty String. // 3. For each Record { [[Type]], [[Value]] } part in parts, do // a. Set result to the string-concatenation of result and part.[[Value]]. // 4. Return result. - return ::Locale::format_list(list_format.locale(), list_format.type(), list_format.style(), list); + return list_format.formatter().format(list); } // 13.5.4 FormatListToParts ( listFormat, list ), https://tc39.es/ecma402/#sec-formatlisttoparts -NonnullGCPtr format_list_to_parts(VM& vm, ListFormat const& list_format, Vector const& list) +NonnullGCPtr format_list_to_parts(VM& vm, ListFormat const& list_format, ReadonlySpan list) { auto& realm = *vm.current_realm(); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.h b/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.h index 75ff3c9a3ee..6e1f0eb8165 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.h @@ -41,17 +41,23 @@ public: void set_style(StringView style) { m_style = ::Locale::style_from_string(style); } StringView style_string() const { return ::Locale::style_to_string(m_style); } + ::Locale::ListFormat const& formatter() const { return *m_formatter; } + void set_formatter(NonnullOwnPtr<::Locale::ListFormat> formatter) { m_formatter = move(formatter); } + private: explicit ListFormat(Object& prototype); String m_locale; // [[Locale]] ::Locale::ListFormatType m_type { ::Locale::ListFormatType::Conjunction }; // [[Type]] ::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]] + + // Non-standard. Stores the ICU list formatter for the Intl object's formatting options. + OwnPtr<::Locale::ListFormat> m_formatter; }; -Vector<::Locale::ListFormatPart> create_parts_from_list(ListFormat const&, Vector const& list); -String format_list(ListFormat const&, Vector const& list); -NonnullGCPtr format_list_to_parts(VM&, ListFormat const&, Vector const& list); +Vector<::Locale::ListFormat::Partition> create_parts_from_list(ListFormat const&, ReadonlySpan list); +String format_list(ListFormat const&, ReadonlySpan list); +NonnullGCPtr format_list_to_parts(VM&, ListFormat const&, ReadonlySpan list); ThrowCompletionOr> string_list_from_iterable(VM&, Value iterable); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/ListFormatConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Intl/ListFormatConstructor.cpp index 1b8adf1ec49..69d2e581a95 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/ListFormatConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/ListFormatConstructor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023, Tim Flynn + * Copyright (c) 2021-2024, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -52,7 +52,7 @@ ThrowCompletionOr> ListFormatConstructor::construct(Functio auto locale_value = vm.argument(0); auto options_value = vm.argument(1); - // 2. Let listFormat be ? OrdinaryCreateFromConstructor(NewTarget, "%ListFormat.prototype%", « [[InitializedListFormat]], [[Locale]], [[Type]], [[Style]], [[Templates]] »). + // 2. Let listFormat be ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.ListFormat.prototype%", « [[InitializedListFormat]], [[Locale]], [[Type]], [[Style]], [[Templates]] »). auto list_format = TRY(ordinary_create_from_constructor(vm, new_target, &Intrinsics::intl_list_format_prototype)); // 3. Let requestedLocales be ? CanonicalizeLocaleList(locales). @@ -70,29 +70,34 @@ ThrowCompletionOr> ListFormatConstructor::construct(Functio // 7. Set opt.[[localeMatcher]] to matcher. opt.locale_matcher = matcher; - // 8. Let localeData be %ListFormat%.[[LocaleData]]. - - // 9. Let r be ResolveLocale(%ListFormat%.[[AvailableLocales]], requestedLocales, opt, %ListFormat%.[[RelevantExtensionKeys]], localeData). + // 8. Let r be ResolveLocale(%Intl.ListFormat%.[[AvailableLocales]], requestedLocales, opt, %Intl.ListFormat%.[[RelevantExtensionKeys]], %Intl.ListFormat%.[[LocaleData]]). auto result = resolve_locale(requested_locales, opt, {}); - // 10. Set listFormat.[[Locale]] to r.[[locale]]. + // 9. Set listFormat.[[Locale]] to r.[[Locale]]. list_format->set_locale(move(result.locale)); - // 11. Let type be ? GetOption(options, "type", string, « "conjunction", "disjunction", "unit" », "conjunction"). + // 10. 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)); - // 12. Set listFormat.[[Type]] to type. + // 11. Set listFormat.[[Type]] to type. list_format->set_type(type.as_string().utf8_string_view()); - // 13. Let style be ? GetOption(options, "style", string, « "long", "short", "narrow" », "long"). + // 12. 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. + // 13. Set listFormat.[[Style]] to style. list_format->set_style(style.as_string().utf8_string_view()); - // Note: The remaining steps are skipped in favor of deferring to LibUnicode. + // 14. Let resolvedLocaleData be r.[[LocaleData]]. + // 15. Let dataLocaleTypes be resolvedLocaleData.[[]]. + // 16. Set listFormat.[[Templates]] to dataLocaleTypes.[[