diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-07-05 12:28:21 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-07-06 16:56:42 +0200 |
commit | 4d32f38a76f81f77d6a19d39df3303c813c31f96 (patch) | |
tree | 6873bd91b6d9b8b0bca913a52178264d35acb776 /Userland/Libraries/LibJS | |
parent | e9bc35d805f931746aedfb183a2d155feedd1375 (diff) | |
download | serenity-4d32f38a76f81f77d6a19d39df3303c813c31f96.zip |
LibJS: Partially implement Intl.Locale.prototype.collations property
We do not yet parse collation data from the CLDR. This stubs out the
collations property, analogous to Intl.supportedValuesOf.
Diffstat (limited to 'Userland/Libraries/LibJS')
7 files changed, 57 insertions, 2 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index d35634c8c9..f3ef49871c 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -98,6 +98,7 @@ namespace JS { P(clz32) \ P(codePointAt) \ P(collation) \ + P(collations) \ P(compactDisplay) \ P(compareExchange) \ P(compile) \ diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp b/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp index 4b58004a14..ce1cf5c402 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp @@ -120,7 +120,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of) // 3. Else if key is "collation", then else if (key == "collation"sv) { // a. Let list be ! AvailableCollations( ). - // NOTE: We don't yet parse any collation data, but "default" is allowed. + // FIXME: We don't yet parse any collation data, but "default" is allowed. This matches Intl.Locale.prototype.collations. static constexpr auto collations = AK::Array { "default"sv }; list = collations.span(); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Locale.cpp b/Userland/Libraries/LibJS/Runtime/Intl/Locale.cpp index f014be677f..27dd2fafb5 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/Locale.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/Locale.cpp @@ -87,4 +87,24 @@ Array* calendars_of_locale(GlobalObject& global_object, Locale const& locale_obj return create_array_from_list_or_restricted(global_object, move(list), move(restricted)); } +// 1.1.3 CollationsOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-collations-of-locale +Array* collations_of_locale(GlobalObject& global_object, Locale const& locale_object) +{ + // 1. Let restricted be loc.[[Collation]]. + Optional<String> restricted = locale_object.has_collation() ? locale_object.collation() : Optional<String> {}; + + // 2. Let locale be loc.[[Locale]]. + auto const& locale = locale_object.locale(); + + // 3. Assert: locale matches the unicode_locale_id production. + VERIFY(Unicode::parse_unicode_locale_id(locale).has_value()); + + // 4. Let list be a List of 1 or more unique canonical collation identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for string comparison in locale. The values "standard" and "search" must be excluded from list. + // FIXME: Retrieve this data from the CLDR when we fully support collation. This matches Intl.supportedValuesOf. + Vector<StringView> list { "default"sv }; + + // 5. Return ! CreateArrayFromListOrRestricted( list, restricted ). + return create_array_from_list_or_restricted(global_object, move(list), move(restricted)); +} + } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Locale.h b/Userland/Libraries/LibJS/Runtime/Intl/Locale.h index f9157c09a9..1e8430e33e 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/Locale.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/Locale.h @@ -75,5 +75,6 @@ private: }; Array* calendars_of_locale(GlobalObject& global_object, Locale const& locale); +Array* collations_of_locale(GlobalObject& global_object, Locale const& locale); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/LocalePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/LocalePrototype.cpp index 52bc2ca6e6..099598de8a 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/LocalePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/LocalePrototype.cpp @@ -38,6 +38,7 @@ void LocalePrototype::initialize(GlobalObject& global_object) define_native_accessor(vm.names.calendars, calendars, {}, Attribute::Configurable); define_native_accessor(vm.names.caseFirst, case_first, {}, Attribute::Configurable); define_native_accessor(vm.names.collation, collation, {}, Attribute::Configurable); + define_native_accessor(vm.names.collations, collations, {}, Attribute::Configurable); define_native_accessor(vm.names.hourCycle, hour_cycle, {}, Attribute::Configurable); define_native_accessor(vm.names.numberingSystem, numbering_system, {}, Attribute::Configurable); define_native_accessor(vm.names.numeric, numeric, {}, Attribute::Configurable); @@ -202,9 +203,11 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::region) } #define JS_ENUMERATE_LOCALE_INFO_PROPERTIES \ - __JS_ENUMERATE(calendars) + __JS_ENUMERATE(calendars) \ + __JS_ENUMERATE(collations) // 1.4.16 get Intl.Locale.prototype.calendars, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.calendars +// 1.4.17 get Intl.Locale.prototype.collations, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.collations #define __JS_ENUMERATE(keyword) \ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::keyword) \ { \ diff --git a/Userland/Libraries/LibJS/Runtime/Intl/LocalePrototype.h b/Userland/Libraries/LibJS/Runtime/Intl/LocalePrototype.h index e59442f4d3..6c304d3a83 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/LocalePrototype.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/LocalePrototype.h @@ -29,6 +29,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(calendars); JS_DECLARE_NATIVE_FUNCTION(case_first); JS_DECLARE_NATIVE_FUNCTION(collation); + JS_DECLARE_NATIVE_FUNCTION(collations); JS_DECLARE_NATIVE_FUNCTION(hour_cycle); JS_DECLARE_NATIVE_FUNCTION(numbering_system); JS_DECLARE_NATIVE_FUNCTION(numeric); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Intl/Locale/Locale.prototype.collations.js b/Userland/Libraries/LibJS/Tests/builtins/Intl/Locale/Locale.prototype.collations.js new file mode 100644 index 0000000000..e7732c2a58 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Intl/Locale/Locale.prototype.collations.js @@ -0,0 +1,29 @@ +describe("errors", () => { + test("called on non-Locale object", () => { + expect(() => { + Intl.Locale.prototype.collations; + }).toThrowWithMessage(TypeError, "Not an object of type Intl.Locale"); + }); +}); + +describe("normal behavior", () => { + test("basic functionality", () => { + expect(Array.isArray(new Intl.Locale("en").collations)).toBeTrue(); + expect(new Intl.Locale("en").collations).toEqual(["default"]); + + expect(Array.isArray(new Intl.Locale("ar").collations)).toBeTrue(); + expect(new Intl.Locale("ar").collations).toEqual(["default"]); + }); + + test("extension keyword overrides default data", () => { + expect(new Intl.Locale("en-u-co-compat").collations).toEqual(["compat"]); + expect(new Intl.Locale("en", { collation: "compat" }).collations).toEqual(["compat"]); + + expect(new Intl.Locale("ar-u-co-reformed").collations).toEqual(["reformed"]); + expect(new Intl.Locale("ar", { collation: "reformed" }).collations).toEqual(["reformed"]); + + // Invalid collations also take precedence. + expect(new Intl.Locale("en-u-co-ladybird").collations).toEqual(["ladybird"]); + expect(new Intl.Locale("en", { collation: "ladybird" }).collations).toEqual(["ladybird"]); + }); +}); |