mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-07 21:17:07 +09:00
LibJS: Update the Intl.Locale prototype to the latest editorial spec
This has been refactored a bit recently.
This commit is contained in:
parent
208a5e6763
commit
324bd0f163
Notes:
github-actions[bot]
2025-06-04 21:12:39 +00:00
Author: https://github.com/trflynn89
Commit: 324bd0f163
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4996
3 changed files with 95 additions and 130 deletions
|
@ -6,10 +6,8 @@
|
|||
|
||||
#include <AK/QuickSort.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Intl/Locale.h>
|
||||
#include <LibUnicode/DateTimeFormat.h>
|
||||
#include <LibUnicode/Locale.h>
|
||||
#include <LibUnicode/TimeZone.h>
|
||||
#include <LibUnicode/UnicodeKeywords.h>
|
||||
|
||||
|
@ -38,6 +36,13 @@ Locale::Locale(Object& prototype)
|
|||
{
|
||||
}
|
||||
|
||||
Unicode::LocaleID const& Locale::locale_id() const
|
||||
{
|
||||
if (!m_cached_locale_id.has_value())
|
||||
m_cached_locale_id = Unicode::parse_unicode_locale_id(locale());
|
||||
return *m_cached_locale_id;
|
||||
}
|
||||
|
||||
// 1.1.1 CreateArrayFromListOrRestricted ( list , restricted )
|
||||
static GC::Ref<Array> create_array_from_list_or_restricted(VM& vm, Vector<String> list, Optional<String> restricted)
|
||||
{
|
||||
|
@ -49,7 +54,7 @@ static GC::Ref<Array> create_array_from_list_or_restricted(VM& vm, Vector<String
|
|||
list = { restricted.release_value() };
|
||||
}
|
||||
|
||||
// 2. Return ! CreateArrayFromList( list ).
|
||||
// 2. Return CreateArrayFromList( list ).
|
||||
return Array::create_from<String>(realm, list, [&vm](auto value) {
|
||||
return PrimitiveString::create(vm, move(value));
|
||||
});
|
||||
|
@ -64,13 +69,11 @@ GC::Ref<Array> calendars_of_locale(VM& vm, Locale const& locale_object)
|
|||
// 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 calendar 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 date and time formatting in locale.
|
||||
// 3. Let list be a List of one or more unique calendar types in canonical form (10), sorted in descending preference
|
||||
// of those in common use for date and time formatting in locale.
|
||||
auto list = Unicode::available_calendars(locale);
|
||||
|
||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||
// 4. Return CreateArrayFromListOrRestricted( list, restricted ).
|
||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||
}
|
||||
|
||||
|
@ -83,13 +86,12 @@ GC::Ref<Array> collations_of_locale(VM& vm, Locale const& locale_object)
|
|||
// 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, ordered as if an Array of the same values had been sorted, using %Array.prototype.sort% using undefined as comparefn, of those in common use for string comparison in locale. The values "standard" and "search" must be excluded from list.
|
||||
// 3. Let list be a List of one or more unique collation types in canonical form (9), of those in common use for
|
||||
// string comparison in locale. The values "standard" and "search" must be excluded from list. The list is sorted
|
||||
// according to lexicographic code unit order.
|
||||
auto list = Unicode::available_collations(locale);
|
||||
|
||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||
// 4. Return CreateArrayFromListOrRestricted( list, restricted ).
|
||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||
}
|
||||
|
||||
|
@ -102,13 +104,12 @@ GC::Ref<Array> hour_cycles_of_locale(VM& vm, Locale const& locale_object)
|
|||
// 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 hour cycle identifiers, which must be lower case String values indicating either the 12-hour format ("h11", "h12") or the 24-hour format ("h23", "h24"), sorted in descending preference of those in common use for date and time formatting in locale.
|
||||
// 3. Let list be a List of one or more unique hour cycle identifiers, which must be lower case String values
|
||||
// indicating either the 12-hour format ("h11", "h12") or the 24-hour format ("h23", "h24"), sorted in descending
|
||||
// preference of those in common use for date and time formatting in locale.
|
||||
auto list = Unicode::available_hour_cycles(locale);
|
||||
|
||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||
// 4. Return CreateArrayFromListOrRestricted( list, restricted ).
|
||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||
}
|
||||
|
||||
|
@ -121,52 +122,36 @@ GC::Ref<Array> numbering_systems_of_locale(VM& vm, Locale const& locale_object)
|
|||
// 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 numbering system 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 formatting numeric values in locale.
|
||||
// 3. Let list be a List of one or more unique numbering system identifiers in canonical form (8), sorted in
|
||||
// descending preference of those in common use for formatting numeric values in locale.
|
||||
auto list = Unicode::available_number_systems(locale);
|
||||
|
||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||
// 4. Return CreateArrayFromListOrRestricted( list, restricted ).
|
||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||
}
|
||||
|
||||
// 1.1.6 TimeZonesOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-time-zones-of-locale
|
||||
// NOTE: Our implementation takes a region rather than a Locale object to avoid needlessly parsing the locale twice.
|
||||
GC::Ref<Array> time_zones_of_locale(VM& vm, StringView region)
|
||||
GC::Ref<Array> time_zones_of_locale(VM& vm, Locale const& locale_object)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let locale be loc.[[Locale]].
|
||||
// 2. Assert: locale matches the unicode_locale_id production.
|
||||
// 3. Let region be the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id.
|
||||
// 1. Let region be GetLocaleRegion(loc.[[Locale]]).
|
||||
auto const& region = locale_object.locale_id().language_id.region;
|
||||
|
||||
// 4. Let list be a List of unique canonical time zone identifiers, which must be String values indicating a canonical Zone name of the IANA Time Zone Database, ordered as if an Array of the same values had been sorted using %Array.prototype.sort% using undefined as comparefn, of those in common use in region. If no time zones are commonly used in region, let list be a new empty List.
|
||||
auto list = Unicode::available_time_zones_in_region(region);
|
||||
// 2. Assert: region is not undefined.
|
||||
VERIFY(region.has_value());
|
||||
|
||||
// 5. Return ! CreateArrayFromList( list ).
|
||||
// 3. Let list be a List of unique canonical time zone identifiers, which must be String values indicating a
|
||||
// canonical Zone name of the IANA Time Zone Database, of those in common use in region. The list is empty if no
|
||||
// time zones are commonly used in region. The list is sorted according to lexicographic code unit order.
|
||||
auto list = Unicode::available_time_zones_in_region(*region);
|
||||
|
||||
// 4. Return CreateArrayFromList( list ).
|
||||
return Array::create_from<String>(realm, list, [&vm](auto value) {
|
||||
return PrimitiveString::create(vm, value);
|
||||
return PrimitiveString::create(vm, move(value));
|
||||
});
|
||||
}
|
||||
|
||||
// 1.1.7 CharacterDirectionOfLocale ( loc ), https://tc39.es/proposal-intl-locale-info/#sec-character-direction-of-locale
|
||||
StringView character_direction_of_locale(Locale const& locale_object)
|
||||
{
|
||||
// 1. Let locale be loc.[[Locale]].
|
||||
auto const& locale = locale_object.locale();
|
||||
|
||||
// 2. Assert: locale matches the unicode_locale_id production.
|
||||
VERIFY(Unicode::parse_unicode_locale_id(locale).has_value());
|
||||
|
||||
// 3. If the default general ordering of characters (characterOrder) within a line in locale is right-to-left, return "rtl".
|
||||
if (Unicode::is_locale_character_ordering_right_to_left(locale))
|
||||
return "rtl"sv;
|
||||
|
||||
// 4. Return "ltr".
|
||||
return "ltr"sv;
|
||||
}
|
||||
|
||||
struct FirstDayStringAndValue {
|
||||
StringView weekday;
|
||||
StringView string;
|
||||
|
@ -190,8 +175,8 @@ StringView weekday_to_string(StringView weekday)
|
|||
{
|
||||
// 1. For each row of Table 1, except the header row, in table order, do
|
||||
for (auto const& row : first_day_string_and_value_table) {
|
||||
// a. Let w be the name given in the Weekday column of the row.
|
||||
// b. Let s be the name given in the String column of the row.
|
||||
// a. Let w be the name given in the Weekday column of the current row.
|
||||
// b. Let s be the name given in the String column of the current row.
|
||||
// c. If fw is equal to w, return s.
|
||||
if (weekday == row.weekday)
|
||||
return row.string;
|
||||
|
@ -206,8 +191,8 @@ Optional<u8> string_to_weekday_value(StringView weekday)
|
|||
{
|
||||
// 1. For each row of Table 1, except the header row, in table order, do
|
||||
for (auto const& row : first_day_string_and_value_table) {
|
||||
// a. Let s be the name given in the String column of the row.
|
||||
// b. Let v be the name given in the Value column of the row.
|
||||
// a. Let s be the name given in the String column of the current row.
|
||||
// b. Let v be the name given in the Value column of the current row.
|
||||
// c. If fw is equal to s, return v.
|
||||
if (weekday == row.string)
|
||||
return row.value;
|
||||
|
@ -258,10 +243,7 @@ WeekInfo week_info_of_locale(Locale const& locale_object)
|
|||
// 1. Let locale be loc.[[Locale]].
|
||||
auto const& locale = locale_object.locale();
|
||||
|
||||
// 2. Assert: locale matches the unicode_locale_id production.
|
||||
VERIFY(Unicode::parse_unicode_locale_id(locale).has_value());
|
||||
|
||||
// 3. Let r be a record whose fields are defined by Table 2, with values based on locale.
|
||||
// 2. Let r be a record whose fields are defined by Table 2, with values based on locale.
|
||||
auto locale_week_info = Unicode::week_info_of_locale(locale);
|
||||
|
||||
WeekInfo week_info {};
|
||||
|
@ -272,20 +254,20 @@ WeekInfo week_info_of_locale(Locale const& locale_object)
|
|||
Optional<u8> first_day_of_week;
|
||||
|
||||
if (locale_object.has_first_day_of_week()) {
|
||||
// 4. Let fws be loc.[[FirstDayOfWeek]].
|
||||
// 3. Let fws be loc.[[FirstDayOfWeek]].
|
||||
auto const& first_day_of_week_string = locale_object.first_day_of_week();
|
||||
|
||||
// 5. Let fw be !StringToWeekdayValue(fws).
|
||||
// 4. Let fw be StringToWeekdayValue(fws).
|
||||
first_day_of_week = string_to_weekday_value(first_day_of_week_string);
|
||||
}
|
||||
|
||||
// 6. If fw is not undefined, then
|
||||
// 5. If fw is not undefined, then
|
||||
if (first_day_of_week.has_value()) {
|
||||
// a. Set r.[[FirstDay]] to fw.
|
||||
week_info.first_day = *first_day_of_week;
|
||||
}
|
||||
|
||||
// 7. Return r.
|
||||
// 6. Return r.
|
||||
return week_info;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <LibUnicode/Forward.h>
|
||||
#include <LibUnicode/Locale.h>
|
||||
|
||||
namespace JS::Intl {
|
||||
|
||||
|
@ -37,6 +37,8 @@ public:
|
|||
|
||||
virtual ~Locale() override = default;
|
||||
|
||||
Unicode::LocaleID const& locale_id() const;
|
||||
|
||||
String const& locale() const { return m_locale; }
|
||||
void set_locale(String locale) { m_locale = move(locale); }
|
||||
|
||||
|
@ -78,6 +80,8 @@ private:
|
|||
Optional<String> m_hour_cycle; // [[HourCycle]]
|
||||
Optional<String> m_numbering_system; // [[NumberingSystem]]
|
||||
bool m_numeric { false }; // [[Numeric]]
|
||||
|
||||
mutable Optional<Unicode::LocaleID> m_cached_locale_id;
|
||||
};
|
||||
|
||||
// Table 1: WeekInfo Record Fields, https://tc39.es/proposal-intl-locale-info/#table-locale-weekinfo-record
|
||||
|
@ -91,8 +95,7 @@ GC::Ref<Array> calendars_of_locale(VM&, Locale const&);
|
|||
GC::Ref<Array> collations_of_locale(VM&, Locale const& locale);
|
||||
GC::Ref<Array> hour_cycles_of_locale(VM&, Locale const& locale);
|
||||
GC::Ref<Array> numbering_systems_of_locale(VM&, Locale const&);
|
||||
GC::Ref<Array> time_zones_of_locale(VM&, StringView region);
|
||||
StringView character_direction_of_locale(Locale const&);
|
||||
GC::Ref<Array> time_zones_of_locale(VM&, Locale const&);
|
||||
StringView weekday_to_string(StringView weekday);
|
||||
Optional<u8> string_to_weekday_value(StringView weekday);
|
||||
WeekInfo week_info_of_locale(Locale const&);
|
||||
|
|
|
@ -62,12 +62,8 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::base_name)
|
|||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let locale be loc.[[Locale]].
|
||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
||||
VERIFY(locale.has_value());
|
||||
|
||||
// 4. Return the substring of locale corresponding to the unicode_language_id production.
|
||||
return PrimitiveString::create(vm, locale->language_id.to_string());
|
||||
// 3. Return GetLocaleBaseName(loc.[[Locale]]).
|
||||
return PrimitiveString::create(vm, locale_object->locale_id().language_id.to_string());
|
||||
}
|
||||
|
||||
#define JS_ENUMERATE_LOCALE_KEYWORD_PROPERTIES \
|
||||
|
@ -81,7 +77,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::base_name)
|
|||
// 15.3.3 get Intl.Locale.prototype.calendar, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar
|
||||
// 15.3.4 get Intl.Locale.prototype.caseFirst, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst
|
||||
// 15.3.5 get Intl.Locale.prototype.collation, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation
|
||||
// 1.4.10 get Intl.Locale.prototype.firstDayOfWeek, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.firstDayOfWeek
|
||||
// 1.4.1 get Intl.Locale.prototype.firstDayOfWeek, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.firstDayOfWeek
|
||||
// 15.3.6 get Intl.Locale.prototype.hourCycle, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle
|
||||
// 15.3.10 get Intl.Locale.prototype.numberingSystem, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numberingSystem
|
||||
#define __JS_ENUMERATE(keyword) \
|
||||
|
@ -102,14 +98,8 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::language)
|
|||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let locale be loc.[[Locale]].
|
||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
||||
|
||||
// 4. Assert: locale matches the unicode_locale_id production.
|
||||
VERIFY(locale.has_value());
|
||||
|
||||
// 5. Return the substring of locale corresponding to the unicode_language_subtag production of the unicode_language_id.
|
||||
return PrimitiveString::create(vm, locale->language_id.language.release_value());
|
||||
// 3. Return GetLocaleLanguage(loc.[[Locale]]).
|
||||
return PrimitiveString::create(vm, *locale_object->locale_id().language_id.language);
|
||||
}
|
||||
|
||||
// 15.3.8 Intl.Locale.prototype.maximize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize
|
||||
|
@ -124,7 +114,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
|
|||
// 3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set maximal to loc.[[Locale]].
|
||||
auto maximal = Unicode::add_likely_subtags(locale_object->locale()).value_or(locale_object->locale());
|
||||
|
||||
// 4. Return ! Construct(%Locale%, maximal).
|
||||
// 4. Return ! Construct(%Intl.Locale%, maximal).
|
||||
return Locale::create(realm, locale_object, move(maximal));
|
||||
}
|
||||
|
||||
|
@ -140,7 +130,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
|
|||
// 3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set minimal to loc.[[Locale]].
|
||||
auto minimal = Unicode::remove_likely_subtags(locale_object->locale()).value_or(locale_object->locale());
|
||||
|
||||
// 4. Return ! Construct(%Locale%, minimal).
|
||||
// 4. Return ! Construct(%Intl.Locale%, minimal).
|
||||
return Locale::create(realm, locale_object, move(minimal));
|
||||
}
|
||||
|
||||
|
@ -152,7 +142,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::numeric)
|
|||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Return loc.[[Numeric]].
|
||||
return Value(locale_object->numeric());
|
||||
return Value { locale_object->numeric() };
|
||||
}
|
||||
|
||||
// 15.3.12 get Intl.Locale.prototype.region, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.region
|
||||
|
@ -162,18 +152,10 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::region)
|
|||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let locale be loc.[[Locale]].
|
||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
||||
|
||||
// 4. Assert: locale matches the unicode_locale_id production.
|
||||
VERIFY(locale.has_value());
|
||||
|
||||
// 5. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined.
|
||||
if (!locale->language_id.region.has_value())
|
||||
return js_undefined();
|
||||
|
||||
// 6. Return the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id.
|
||||
return PrimitiveString::create(vm, locale->language_id.region.release_value());
|
||||
// 3. Return GetLocaleRegion(loc.[[Locale]]).
|
||||
if (auto const& region = locale_object->locale_id().language_id.region; region.has_value())
|
||||
return PrimitiveString::create(vm, *region);
|
||||
return js_undefined();
|
||||
}
|
||||
|
||||
// 15.3.13 get Intl.Locale.prototype.script, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.script
|
||||
|
@ -183,18 +165,10 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::script)
|
|||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let locale be loc.[[Locale]].
|
||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
||||
|
||||
// 4. Assert: locale matches the unicode_locale_id production.
|
||||
VERIFY(locale.has_value());
|
||||
|
||||
// 5. If the unicode_language_id production of locale does not contain the ["-" unicode_script_subtag] sequence, return undefined.
|
||||
if (!locale->language_id.script.has_value())
|
||||
return js_undefined();
|
||||
|
||||
// 6. Return the substring of locale corresponding to the unicode_script_subtag production of the unicode_language_id.
|
||||
return PrimitiveString::create(vm, locale->language_id.script.release_value());
|
||||
// 3. Return GetLocaleScript(loc.[[Locale]]).
|
||||
if (auto const& script = locale_object->locale_id().language_id.script; script.has_value())
|
||||
return PrimitiveString::create(vm, *script);
|
||||
return js_undefined();
|
||||
}
|
||||
|
||||
// 15.3.14 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
|
||||
|
@ -214,10 +188,10 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::to_string)
|
|||
__JS_ENUMERATE(hour_cycles) \
|
||||
__JS_ENUMERATE(numbering_systems)
|
||||
|
||||
// 1.4.17 Intl.Locale.prototype.getCalendars, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getCalendars
|
||||
// 1.4.18 Intl.Locale.prototype.getCollations, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getCollations
|
||||
// 1.4.19 Intl.Locale.prototype.getHourCycles, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getHourCycles
|
||||
// 1.4.20 Intl.Locale.prototype.getNumberingSystems, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getNumberingSystems
|
||||
// 1.4.2 Intl.Locale.prototype.getCalendars, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getCalendars
|
||||
// 1.4.3 Intl.Locale.prototype.getCollations, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getCollations
|
||||
// 1.4.4 Intl.Locale.prototype.getHourCycles, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getHourCycles
|
||||
// 1.4.5 Intl.Locale.prototype.getNumberingSystems, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getNumberingSystems
|
||||
#define __JS_ENUMERATE(keyword) \
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::get_##keyword) \
|
||||
{ \
|
||||
|
@ -227,25 +201,25 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::to_string)
|
|||
JS_ENUMERATE_LOCALE_INFO_PROPERTIES
|
||||
#undef __JS_ENUMERATE
|
||||
|
||||
// 1.4.21 Intl.Locale.prototype.getTimeZones, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getTimeZones
|
||||
// 1.4.6 Intl.Locale.prototype.getTimeZones, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getTimeZones
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::get_time_zones)
|
||||
{
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let locale be loc.[[Locale]].
|
||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
||||
// 3. Let region be GetLocaleRegion(loc.[[Locale]]).
|
||||
auto const& region = locale_object->locale_id().language_id.region;
|
||||
|
||||
// 4. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined.
|
||||
if (!locale.has_value() || !locale->language_id.region.has_value())
|
||||
// 4. If region is undefined, return undefined.
|
||||
if (!region.has_value())
|
||||
return js_undefined();
|
||||
|
||||
// 5. Return ! TimeZonesOfLocale(loc).
|
||||
return time_zones_of_locale(vm, locale->language_id.region.value());
|
||||
// 5. Return TimeZonesOfLocale(loc).
|
||||
return time_zones_of_locale(vm, locale_object);
|
||||
}
|
||||
|
||||
// 1.4.22 Intl.Locale.prototype.getTextInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getTextInfo
|
||||
// 1.4.7 Intl.Locale.prototype.getTextInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getTextInfo
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::get_text_info)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
@ -254,20 +228,26 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::get_text_info)
|
|||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let info be ! ObjectCreate(%Object.prototype%).
|
||||
// 3. Let info be OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto info = Object::create(realm, realm.intrinsics().object_prototype());
|
||||
|
||||
// 4. Let dir be ! CharacterDirectionOfLocale(loc).
|
||||
auto direction = character_direction_of_locale(locale_object);
|
||||
// 4. Let dir be "ltr".
|
||||
auto direction = "ltr"sv;
|
||||
|
||||
// 5. Perform ! CreateDataPropertyOrThrow(info, "direction", dir).
|
||||
// 5. If LocaleIsRightToLeft(loc) is true, then
|
||||
if (Unicode::is_locale_character_ordering_right_to_left(locale_object->locale())) {
|
||||
// a. Set dir to "rtl".
|
||||
direction = "rtl"sv;
|
||||
}
|
||||
|
||||
// 6. Perform ! CreateDataPropertyOrThrow(info, "direction", dir).
|
||||
MUST(info->create_data_property_or_throw(vm.names.direction, PrimitiveString::create(vm, direction)));
|
||||
|
||||
// 6. Return info.
|
||||
// 7. Return info.
|
||||
return info;
|
||||
}
|
||||
|
||||
// 1.4.23 Intl.Locale.prototype.getWeekInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getWeekInfo
|
||||
// 1.4.8 Intl.Locale.prototype.getWeekInfo, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.getWeekInfo
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::get_week_info)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
@ -276,23 +256,23 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::get_week_info)
|
|||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let info be ! ObjectCreate(%Object.prototype%).
|
||||
// 3. Let info be OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto info = Object::create(realm, realm.intrinsics().object_prototype());
|
||||
|
||||
// 4. Let wi be ! WeekInfoOfLocale(loc).
|
||||
// 4. Let wi be WeekInfoOfLocale(loc).
|
||||
auto week_info = week_info_of_locale(locale_object);
|
||||
|
||||
// 5. Let we be ! CreateArrayFromList( wi.[[Weekend]] ).
|
||||
auto weekend = Array::create_from<u8>(realm, week_info.weekend, [](auto day) { return Value(day); });
|
||||
// 5. Let we be CreateArrayFromList(wi.[[Weekend]]).
|
||||
auto weekend = Array::create_from<u8>(realm, week_info.weekend, [](auto day) { return Value { day }; });
|
||||
|
||||
// 6. Perform ! CreateDataPropertyOrThrow(info, "firstDay", wi.[[FirstDay]]).
|
||||
MUST(info->create_data_property_or_throw(vm.names.firstDay, Value(week_info.first_day)));
|
||||
MUST(info->create_data_property_or_throw(vm.names.firstDay, Value { week_info.first_day }));
|
||||
|
||||
// 7. Perform ! CreateDataPropertyOrThrow(info, "weekend", we).
|
||||
MUST(info->create_data_property_or_throw(vm.names.weekend, weekend));
|
||||
|
||||
// 8. Perform ! CreateDataPropertyOrThrow(info, "minimalDays", wi.[[MinimalDays]]).
|
||||
MUST(info->create_data_property_or_throw(vm.names.minimalDays, Value(week_info.minimal_days)));
|
||||
MUST(info->create_data_property_or_throw(vm.names.minimalDays, Value { week_info.minimal_days }));
|
||||
|
||||
// 9. Return info.
|
||||
return info;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue