mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:37:35 +00:00
LibJS: Port Intl locale resolution to String
This commit is contained in:
parent
2f1184ccdb
commit
bb4b6d8ce3
20 changed files with 208 additions and 205 deletions
|
@ -80,7 +80,7 @@ ThrowCompletionOr<Optional<::Locale::LocaleID>> is_structurally_valid_language_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6.2.3 CanonicalizeUnicodeLocaleId ( locale ), https://tc39.es/ecma402/#sec-canonicalizeunicodelocaleid
|
// 6.2.3 CanonicalizeUnicodeLocaleId ( locale ), https://tc39.es/ecma402/#sec-canonicalizeunicodelocaleid
|
||||||
ThrowCompletionOr<DeprecatedString> canonicalize_unicode_locale_id(VM& vm, ::Locale::LocaleID& locale)
|
ThrowCompletionOr<String> canonicalize_unicode_locale_id(VM& vm, ::Locale::LocaleID& locale)
|
||||||
{
|
{
|
||||||
// Note: This implementation differs from the spec in how Step 3 is implemented. The spec assumes
|
// Note: This implementation differs from the spec in how Step 3 is implemented. The spec assumes
|
||||||
// the input to this method is a string, and is written such that operations are performed on parts
|
// the input to this method is a string, and is written such that operations are performed on parts
|
||||||
|
@ -118,7 +118,7 @@ ThrowCompletionOr<DeprecatedString> canonicalize_unicode_locale_id(VM& vm, ::Loc
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
|
|
||||||
// 4. Return localeId.
|
// 4. Return localeId.
|
||||||
return locale_id->to_deprecated_string();
|
return locale_id.release_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6.3.1 IsWellFormedCurrencyCode ( currency ), https://tc39.es/ecma402/#sec-iswellformedcurrencycode
|
// 6.3.1 IsWellFormedCurrencyCode ( currency ), https://tc39.es/ecma402/#sec-iswellformedcurrencycode
|
||||||
|
@ -183,18 +183,18 @@ bool is_well_formed_unit_identifier(StringView unit_identifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.1 CanonicalizeLocaleList ( locales ), https://tc39.es/ecma402/#sec-canonicalizelocalelist
|
// 9.2.1 CanonicalizeLocaleList ( locales ), https://tc39.es/ecma402/#sec-canonicalizelocalelist
|
||||||
ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM& vm, Value locales)
|
ThrowCompletionOr<Vector<String>> canonicalize_locale_list(VM& vm, Value locales)
|
||||||
{
|
{
|
||||||
auto& realm = *vm.current_realm();
|
auto& realm = *vm.current_realm();
|
||||||
|
|
||||||
// 1. If locales is undefined, then
|
// 1. If locales is undefined, then
|
||||||
if (locales.is_undefined()) {
|
if (locales.is_undefined()) {
|
||||||
// a. Return a new empty List.
|
// a. Return a new empty List.
|
||||||
return Vector<DeprecatedString> {};
|
return Vector<String> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Let seen be a new empty List.
|
// 2. Let seen be a new empty List.
|
||||||
Vector<DeprecatedString> seen;
|
Vector<String> seen;
|
||||||
|
|
||||||
Object* object = nullptr;
|
Object* object = nullptr;
|
||||||
// 3. If Type(locales) is String or Type(locales) is Object and locales has an [[InitializedLocale]] internal slot, then
|
// 3. If Type(locales) is String or Type(locales) is Object and locales has an [[InitializedLocale]] internal slot, then
|
||||||
|
@ -228,9 +228,9 @@ ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM& vm, Val
|
||||||
|
|
||||||
// ii. If Type(kValue) is not String or Object, throw a TypeError exception.
|
// ii. If Type(kValue) is not String or Object, throw a TypeError exception.
|
||||||
if (!key_value.is_string() && !key_value.is_object())
|
if (!key_value.is_string() && !key_value.is_object())
|
||||||
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOrString, key_value.to_string_without_side_effects());
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOrString, key_value);
|
||||||
|
|
||||||
DeprecatedString tag;
|
String tag;
|
||||||
|
|
||||||
// iii. If Type(kValue) is Object and kValue has an [[InitializedLocale]] internal slot, then
|
// iii. If Type(kValue) is Object and kValue has an [[InitializedLocale]] internal slot, then
|
||||||
if (key_value.is_object() && is<Locale>(key_value.as_object())) {
|
if (key_value.is_object() && is<Locale>(key_value.as_object())) {
|
||||||
|
@ -240,7 +240,7 @@ ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM& vm, Val
|
||||||
// iv. Else,
|
// iv. Else,
|
||||||
else {
|
else {
|
||||||
// 1. Let tag be ? ToString(kValue).
|
// 1. Let tag be ? ToString(kValue).
|
||||||
tag = TRY(key_value.to_deprecated_string(vm));
|
tag = TRY(key_value.to_string(vm));
|
||||||
}
|
}
|
||||||
|
|
||||||
// v. If ! IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
|
// v. If ! IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
|
||||||
|
@ -264,7 +264,7 @@ ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM& vm, Val
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.2 BestAvailableLocale ( availableLocales, locale ), https://tc39.es/ecma402/#sec-bestavailablelocale
|
// 9.2.2 BestAvailableLocale ( availableLocales, locale ), https://tc39.es/ecma402/#sec-bestavailablelocale
|
||||||
Optional<DeprecatedString> best_available_locale(StringView locale)
|
Optional<StringView> best_available_locale(StringView locale)
|
||||||
{
|
{
|
||||||
// 1. Let candidate be locale.
|
// 1. Let candidate be locale.
|
||||||
StringView candidate = locale;
|
StringView candidate = locale;
|
||||||
|
@ -290,12 +290,12 @@ Optional<DeprecatedString> best_available_locale(StringView locale)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MatcherResult {
|
struct MatcherResult {
|
||||||
DeprecatedString locale;
|
String locale;
|
||||||
Vector<::Locale::Extension> extensions {};
|
Vector<::Locale::Extension> extensions {};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 9.2.3 LookupMatcher ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-lookupmatcher
|
// 9.2.3 LookupMatcher ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-lookupmatcher
|
||||||
static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<DeprecatedString> const& requested_locales)
|
static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<String> const& requested_locales)
|
||||||
{
|
{
|
||||||
// 1. Let result be a new Record.
|
// 1. Let result be a new Record.
|
||||||
MatcherResult result {};
|
MatcherResult result {};
|
||||||
|
@ -307,7 +307,7 @@ static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<Deprecated
|
||||||
|
|
||||||
// a. Let noExtensionsLocale be the String value that is locale with any Unicode locale extension sequences removed.
|
// a. Let noExtensionsLocale be the String value that is locale with any Unicode locale extension sequences removed.
|
||||||
auto extensions = locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
auto extensions = locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
||||||
auto no_extensions_locale = locale_id->to_deprecated_string();
|
auto no_extensions_locale = TRY_OR_THROW_OOM(vm, locale_id->to_string());
|
||||||
|
|
||||||
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
||||||
auto available_locale = best_available_locale(no_extensions_locale);
|
auto available_locale = best_available_locale(no_extensions_locale);
|
||||||
|
@ -315,7 +315,7 @@ static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<Deprecated
|
||||||
// c. If availableLocale is not undefined, then
|
// c. If availableLocale is not undefined, then
|
||||||
if (available_locale.has_value()) {
|
if (available_locale.has_value()) {
|
||||||
// i. Set result.[[locale]] to availableLocale.
|
// i. Set result.[[locale]] to availableLocale.
|
||||||
result.locale = available_locale.release_value();
|
result.locale = TRY_OR_THROW_OOM(vm, String::from_utf8(*available_locale));
|
||||||
|
|
||||||
// ii. If locale and noExtensionsLocale are not the same String value, then
|
// ii. If locale and noExtensionsLocale are not the same String value, then
|
||||||
if (locale != no_extensions_locale) {
|
if (locale != no_extensions_locale) {
|
||||||
|
@ -331,14 +331,14 @@ static ThrowCompletionOr<MatcherResult> lookup_matcher(VM& vm, Vector<Deprecated
|
||||||
|
|
||||||
// 3. Let defLocale be ! DefaultLocale().
|
// 3. Let defLocale be ! DefaultLocale().
|
||||||
// 4. Set result.[[locale]] to defLocale.
|
// 4. Set result.[[locale]] to defLocale.
|
||||||
result.locale = ::Locale::default_locale();
|
result.locale = TRY_OR_THROW_OOM(vm, String::from_utf8(::Locale::default_locale()));
|
||||||
|
|
||||||
// 5. Return result.
|
// 5. Return result.
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.4 BestFitMatcher ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-bestfitmatcher
|
// 9.2.4 BestFitMatcher ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-bestfitmatcher
|
||||||
static ThrowCompletionOr<MatcherResult> best_fit_matcher(VM& vm, Vector<DeprecatedString> const& requested_locales)
|
static ThrowCompletionOr<MatcherResult> best_fit_matcher(VM& vm, Vector<String> const& requested_locales)
|
||||||
{
|
{
|
||||||
// The algorithm is implementation dependent, but should produce results that a typical user of the requested locales would
|
// The algorithm is implementation dependent, but should produce results that a typical user of the requested locales would
|
||||||
// perceive as at least as good as those produced by the LookupMatcher abstract operation.
|
// perceive as at least as good as those produced by the LookupMatcher abstract operation.
|
||||||
|
@ -346,14 +346,14 @@ static ThrowCompletionOr<MatcherResult> best_fit_matcher(VM& vm, Vector<Deprecat
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.6 InsertUnicodeExtensionAndCanonicalize ( locale, extension ), https://tc39.es/ecma402/#sec-insert-unicode-extension-and-canonicalize
|
// 9.2.6 InsertUnicodeExtensionAndCanonicalize ( locale, extension ), https://tc39.es/ecma402/#sec-insert-unicode-extension-and-canonicalize
|
||||||
ThrowCompletionOr<DeprecatedString> insert_unicode_extension_and_canonicalize(VM& vm, ::Locale::LocaleID locale, ::Locale::LocaleExtension extension)
|
ThrowCompletionOr<String> insert_unicode_extension_and_canonicalize(VM& vm, ::Locale::LocaleID locale, ::Locale::LocaleExtension extension)
|
||||||
{
|
{
|
||||||
// Note: This implementation differs from the spec in how the extension is inserted. The spec assumes
|
// Note: This implementation differs from the spec in how the extension is inserted. The spec assumes
|
||||||
// the input to this method is a string, and is written such that operations are performed on parts
|
// the input to this method is a string, and is written such that operations are performed on parts
|
||||||
// of that string. LibUnicode gives us the parsed locale in a structure, so we can mutate that
|
// of that string. LibUnicode gives us the parsed locale in a structure, so we can mutate that
|
||||||
// structure directly.
|
// structure directly.
|
||||||
TRY_OR_THROW_OOM(vm, locale.extensions.try_append(move(extension)));
|
TRY_OR_THROW_OOM(vm, locale.extensions.try_append(move(extension)));
|
||||||
return TRY(canonicalize_unicode_locale_id(vm, locale));
|
return canonicalize_unicode_locale_id(vm, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -377,7 +377,7 @@ static auto& find_key_in_value(T& value, StringView key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.7 ResolveLocale ( availableLocales, requestedLocales, options, relevantExtensionKeys, localeData ), https://tc39.es/ecma402/#sec-resolvelocale
|
// 9.2.7 ResolveLocale ( availableLocales, requestedLocales, options, relevantExtensionKeys, localeData ), https://tc39.es/ecma402/#sec-resolvelocale
|
||||||
ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys)
|
ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<String> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys)
|
||||||
{
|
{
|
||||||
// 1. Let matcher be options.[[localeMatcher]].
|
// 1. Let matcher be options.[[localeMatcher]].
|
||||||
auto const& matcher = options.locale_matcher;
|
auto const& matcher = options.locale_matcher;
|
||||||
|
@ -434,9 +434,9 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
||||||
// f. Assert: Type(value) is either String or Null.
|
// f. Assert: Type(value) is either String or Null.
|
||||||
// NOTE: ECMA-402 assumes keyLocaleData is sorted by locale preference. Our list is sorted
|
// NOTE: ECMA-402 assumes keyLocaleData is sorted by locale preference. Our list is sorted
|
||||||
// alphabetically, so we get the locale's preferred value from LibUnicode.
|
// alphabetically, so we get the locale's preferred value from LibUnicode.
|
||||||
Optional<DeprecatedString> value;
|
Optional<String> value;
|
||||||
if (auto preference = ::Locale::get_preferred_keyword_value_for_locale(found_locale, key); preference.has_value())
|
if (auto preference = ::Locale::get_preferred_keyword_value_for_locale(found_locale, key); preference.has_value())
|
||||||
value = *preference;
|
value = TRY_OR_THROW_OOM(vm, String::from_utf8(*preference));
|
||||||
|
|
||||||
// g. Let supportedExtensionAddition be "".
|
// g. Let supportedExtensionAddition be "".
|
||||||
Optional<::Locale::Keyword> supported_extension_addition {};
|
Optional<::Locale::Keyword> supported_extension_addition {};
|
||||||
|
@ -456,7 +456,7 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
||||||
// a. If keyLocaleData contains requestedValue, then
|
// a. If keyLocaleData contains requestedValue, then
|
||||||
if (key_locale_data.contains_slow(requested_value)) {
|
if (key_locale_data.contains_slow(requested_value)) {
|
||||||
// i. Let value be requestedValue.
|
// i. Let value be requestedValue.
|
||||||
value = requested_value.to_deprecated_string();
|
value = move(requested_value);
|
||||||
|
|
||||||
// ii. Let supportedExtensionAddition be the string-concatenation of "-", key, "-", and value.
|
// ii. Let supportedExtensionAddition be the string-concatenation of "-", key, "-", and value.
|
||||||
supported_extension_addition = ::Locale::Keyword { TRY_OR_THROW_OOM(vm, String::from_utf8(key)), move(entry.value) };
|
supported_extension_addition = ::Locale::Keyword { TRY_OR_THROW_OOM(vm, String::from_utf8(key)), move(entry.value) };
|
||||||
|
@ -465,7 +465,7 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
||||||
// 4. Else if keyLocaleData contains "true", then
|
// 4. Else if keyLocaleData contains "true", then
|
||||||
else if (key_locale_data.contains_slow("true"sv)) {
|
else if (key_locale_data.contains_slow("true"sv)) {
|
||||||
// a. Let value be "true".
|
// a. Let value be "true".
|
||||||
value = "true"sv;
|
value = TRY_OR_THROW_OOM(vm, String::from_utf8("true"sv));
|
||||||
|
|
||||||
// b. Let supportedExtensionAddition be the string-concatenation of "-" and key.
|
// b. Let supportedExtensionAddition be the string-concatenation of "-" and key.
|
||||||
supported_extension_addition = ::Locale::Keyword { TRY_OR_THROW_OOM(vm, String::from_utf8(key)), {} };
|
supported_extension_addition = ::Locale::Keyword { TRY_OR_THROW_OOM(vm, String::from_utf8(key)), {} };
|
||||||
|
@ -483,14 +483,12 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
||||||
if (options_value.has_value()) {
|
if (options_value.has_value()) {
|
||||||
// 1. Let optionsValue be the string optionsValue after performing the algorithm steps to transform Unicode extension values to canonical syntax per Unicode Technical Standard #35 LDML § 3.2.1 Canonical Unicode Locale Identifiers, treating key as ukey and optionsValue as uvalue productions.
|
// 1. Let optionsValue be the string optionsValue after performing the algorithm steps to transform Unicode extension values to canonical syntax per Unicode Technical Standard #35 LDML § 3.2.1 Canonical Unicode Locale Identifiers, treating key as ukey and optionsValue as uvalue productions.
|
||||||
// 2. Let optionsValue be the string optionsValue after performing the algorithm steps to replace Unicode extension values with their canonical form per Unicode Technical Standard #35 LDML § 3.2.1 Canonical Unicode Locale Identifiers, treating key as ukey and optionsValue as uvalue productions.
|
// 2. Let optionsValue be the string optionsValue after performing the algorithm steps to replace Unicode extension values with their canonical form per Unicode Technical Standard #35 LDML § 3.2.1 Canonical Unicode Locale Identifiers, treating key as ukey and optionsValue as uvalue productions.
|
||||||
auto options_value_string = TRY_OR_THROW_OOM(vm, String::from_deprecated_string(*options_value));
|
TRY_OR_THROW_OOM(vm, ::Locale::canonicalize_unicode_extension_values(key, *options_value, true));
|
||||||
TRY_OR_THROW_OOM(vm, ::Locale::canonicalize_unicode_extension_values(key, options_value_string, true));
|
|
||||||
options_value = options_value_string.to_deprecated_string();
|
|
||||||
|
|
||||||
// 3. If optionsValue is the empty String, then
|
// 3. If optionsValue is the empty String, then
|
||||||
if (options_value->is_empty()) {
|
if (options_value->is_empty()) {
|
||||||
// a. Let optionsValue be "true".
|
// a. Let optionsValue be "true".
|
||||||
options_value = "true"sv;
|
options_value = TRY_OR_THROW_OOM(vm, String::from_utf8("true"sv));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,10 +526,10 @@ ThrowCompletionOr<LocaleResult> resolve_locale(VM& vm, Vector<DeprecatedString>
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.8 LookupSupportedLocales ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-lookupsupportedlocales
|
// 9.2.8 LookupSupportedLocales ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-lookupsupportedlocales
|
||||||
static ThrowCompletionOr<Vector<DeprecatedString>> lookup_supported_locales(VM& vm, Vector<DeprecatedString> const& requested_locales)
|
static ThrowCompletionOr<Vector<String>> lookup_supported_locales(VM& vm, Vector<String> const& requested_locales)
|
||||||
{
|
{
|
||||||
// 1. Let subset be a new empty List.
|
// 1. Let subset be a new empty List.
|
||||||
Vector<DeprecatedString> subset;
|
Vector<String> subset;
|
||||||
|
|
||||||
// 2. For each element locale of requestedLocales, do
|
// 2. For each element locale of requestedLocales, do
|
||||||
for (auto const& locale : requested_locales) {
|
for (auto const& locale : requested_locales) {
|
||||||
|
@ -540,7 +538,7 @@ static ThrowCompletionOr<Vector<DeprecatedString>> lookup_supported_locales(VM&
|
||||||
|
|
||||||
// a. Let noExtensionsLocale be the String value that is locale with any Unicode locale extension sequences removed.
|
// a. Let noExtensionsLocale be the String value that is locale with any Unicode locale extension sequences removed.
|
||||||
locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
||||||
auto no_extensions_locale = locale_id->to_deprecated_string();
|
auto no_extensions_locale = TRY_OR_THROW_OOM(vm, locale_id->to_string());
|
||||||
|
|
||||||
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
||||||
auto available_locale = best_available_locale(no_extensions_locale);
|
auto available_locale = best_available_locale(no_extensions_locale);
|
||||||
|
@ -555,7 +553,7 @@ static ThrowCompletionOr<Vector<DeprecatedString>> lookup_supported_locales(VM&
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.9 BestFitSupportedLocales ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-bestfitsupportedlocales
|
// 9.2.9 BestFitSupportedLocales ( availableLocales, requestedLocales ), https://tc39.es/ecma402/#sec-bestfitsupportedlocales
|
||||||
static ThrowCompletionOr<Vector<DeprecatedString>> best_fit_supported_locales(VM& vm, Vector<DeprecatedString> const& requested_locales)
|
static ThrowCompletionOr<Vector<String>> best_fit_supported_locales(VM& vm, Vector<String> const& requested_locales)
|
||||||
{
|
{
|
||||||
// The BestFitSupportedLocales abstract operation returns the subset of the provided BCP 47
|
// The BestFitSupportedLocales abstract operation returns the subset of the provided BCP 47
|
||||||
// language priority list requestedLocales for which availableLocales has a matching locale
|
// language priority list requestedLocales for which availableLocales has a matching locale
|
||||||
|
@ -567,7 +565,7 @@ static ThrowCompletionOr<Vector<DeprecatedString>> best_fit_supported_locales(VM
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.10 SupportedLocales ( availableLocales, requestedLocales, options ), https://tc39.es/ecma402/#sec-supportedlocales
|
// 9.2.10 SupportedLocales ( availableLocales, requestedLocales, options ), https://tc39.es/ecma402/#sec-supportedlocales
|
||||||
ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<DeprecatedString> const& requested_locales, Value options)
|
ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<String> const& requested_locales, Value options)
|
||||||
{
|
{
|
||||||
auto& realm = *vm.current_realm();
|
auto& realm = *vm.current_realm();
|
||||||
|
|
||||||
|
@ -577,7 +575,7 @@ ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<DeprecatedString> con
|
||||||
// 2. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
|
// 2. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
|
||||||
auto matcher = TRY(get_option(vm, *options_object, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
|
auto matcher = TRY(get_option(vm, *options_object, vm.names.localeMatcher, OptionType::String, { "lookup"sv, "best fit"sv }, "best fit"sv));
|
||||||
|
|
||||||
Vector<DeprecatedString> supported_locales;
|
Vector<String> supported_locales;
|
||||||
|
|
||||||
// 3. If matcher is "best fit", then
|
// 3. If matcher is "best fit", then
|
||||||
if (TRY(matcher.as_string().utf8_string_view()) == "best fit"sv) {
|
if (TRY(matcher.as_string().utf8_string_view()) == "best fit"sv) {
|
||||||
|
@ -591,7 +589,7 @@ ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<DeprecatedString> con
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Return CreateArrayFromList(supportedLocales).
|
// 5. Return CreateArrayFromList(supportedLocales).
|
||||||
return Array::create_from<DeprecatedString>(realm, supported_locales, [&vm](auto& locale) { return PrimitiveString::create(vm, locale); }).ptr();
|
return Array::create_from<String>(realm, supported_locales, [&vm](auto& locale) { return PrimitiveString::create(vm, move(locale)); }).ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9.2.12 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject
|
// 9.2.12 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/DeprecatedString.h>
|
||||||
#include <AK/Span.h>
|
#include <AK/Span.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Variant.h>
|
#include <AK/Variant.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibJS/Forward.h>
|
#include <LibJS/Forward.h>
|
||||||
|
@ -21,23 +22,23 @@ namespace JS::Intl {
|
||||||
|
|
||||||
struct LocaleOptions {
|
struct LocaleOptions {
|
||||||
Value locale_matcher;
|
Value locale_matcher;
|
||||||
Optional<DeprecatedString> ca; // [[Calendar]]
|
Optional<String> ca; // [[Calendar]]
|
||||||
Optional<DeprecatedString> co; // [[Collation]]
|
Optional<String> co; // [[Collation]]
|
||||||
Optional<DeprecatedString> hc; // [[HourCycle]]
|
Optional<String> hc; // [[HourCycle]]
|
||||||
Optional<DeprecatedString> kf; // [[CaseFirst]]
|
Optional<String> kf; // [[CaseFirst]]
|
||||||
Optional<DeprecatedString> kn; // [[Numeric]]
|
Optional<String> kn; // [[Numeric]]
|
||||||
Optional<DeprecatedString> nu; // [[NumberingSystem]]
|
Optional<String> nu; // [[NumberingSystem]]
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LocaleResult {
|
struct LocaleResult {
|
||||||
DeprecatedString locale;
|
String locale;
|
||||||
DeprecatedString data_locale;
|
String data_locale;
|
||||||
Optional<DeprecatedString> ca; // [[Calendar]]
|
Optional<String> ca; // [[Calendar]]
|
||||||
Optional<DeprecatedString> co; // [[Collation]]
|
Optional<String> co; // [[Collation]]
|
||||||
Optional<DeprecatedString> hc; // [[HourCycle]]
|
Optional<String> hc; // [[HourCycle]]
|
||||||
Optional<DeprecatedString> kf; // [[CaseFirst]]
|
Optional<String> kf; // [[CaseFirst]]
|
||||||
Optional<DeprecatedString> kn; // [[Numeric]]
|
Optional<String> kn; // [[Numeric]]
|
||||||
Optional<DeprecatedString> nu; // [[NumberingSystem]]
|
Optional<String> nu; // [[NumberingSystem]]
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PatternPartition {
|
struct PatternPartition {
|
||||||
|
@ -80,14 +81,14 @@ struct PatternPartitionWithSource : public PatternPartition {
|
||||||
using StringOrBoolean = Variant<StringView, bool>;
|
using StringOrBoolean = Variant<StringView, bool>;
|
||||||
|
|
||||||
ThrowCompletionOr<Optional<::Locale::LocaleID>> is_structurally_valid_language_tag(VM&, StringView locale);
|
ThrowCompletionOr<Optional<::Locale::LocaleID>> is_structurally_valid_language_tag(VM&, StringView locale);
|
||||||
ThrowCompletionOr<DeprecatedString> canonicalize_unicode_locale_id(VM&, ::Locale::LocaleID& locale);
|
ThrowCompletionOr<String> canonicalize_unicode_locale_id(VM&, ::Locale::LocaleID& locale);
|
||||||
bool is_well_formed_currency_code(StringView currency);
|
bool is_well_formed_currency_code(StringView currency);
|
||||||
bool is_well_formed_unit_identifier(StringView unit_identifier);
|
bool is_well_formed_unit_identifier(StringView unit_identifier);
|
||||||
ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM&, Value locales);
|
ThrowCompletionOr<Vector<String>> canonicalize_locale_list(VM&, Value locales);
|
||||||
Optional<DeprecatedString> best_available_locale(StringView locale);
|
Optional<StringView> best_available_locale(StringView locale);
|
||||||
ThrowCompletionOr<DeprecatedString> insert_unicode_extension_and_canonicalize(VM&, ::Locale::LocaleID locale_id, ::Locale::LocaleExtension extension);
|
ThrowCompletionOr<String> insert_unicode_extension_and_canonicalize(VM&, ::Locale::LocaleID locale_id, ::Locale::LocaleExtension extension);
|
||||||
ThrowCompletionOr<LocaleResult> resolve_locale(VM&, Vector<DeprecatedString> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys);
|
ThrowCompletionOr<LocaleResult> resolve_locale(VM&, Vector<String> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys);
|
||||||
ThrowCompletionOr<Array*> supported_locales(VM&, Vector<DeprecatedString> const& requested_locales, Value options);
|
ThrowCompletionOr<Array*> supported_locales(VM&, Vector<String> const& requested_locales, Value options);
|
||||||
ThrowCompletionOr<Object*> coerce_options_to_object(VM&, Value options);
|
ThrowCompletionOr<Object*> coerce_options_to_object(VM&, Value options);
|
||||||
ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(VM&, Object const& options, PropertyKey const& property, Span<StringView const> values, StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback);
|
ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(VM&, Object const& options, PropertyKey const& property, Span<StringView const> values, StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback);
|
||||||
ThrowCompletionOr<Optional<int>> default_number_option(VM&, Value value, int minimum, int maximum, Optional<int> fallback);
|
ThrowCompletionOr<Optional<int>> default_number_option(VM&, Value value, int minimum, int maximum, Optional<int> fallback);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Array.h>
|
#include <AK/Array.h>
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/String.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <LibJS/Runtime/Intl/CollatorCompareFunction.h>
|
#include <LibJS/Runtime/Intl/CollatorCompareFunction.h>
|
||||||
#include <LibJS/Runtime/Object.h>
|
#include <LibJS/Runtime/Object.h>
|
||||||
|
@ -45,8 +45,8 @@ public:
|
||||||
|
|
||||||
virtual ~Collator() override = default;
|
virtual ~Collator() override = default;
|
||||||
|
|
||||||
DeprecatedString const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
|
|
||||||
Usage usage() const { return m_usage; }
|
Usage usage() const { return m_usage; }
|
||||||
void set_usage(StringView usage);
|
void set_usage(StringView usage);
|
||||||
|
@ -60,8 +60,8 @@ public:
|
||||||
void set_case_first(StringView case_first);
|
void set_case_first(StringView case_first);
|
||||||
StringView case_first_string() const;
|
StringView case_first_string() const;
|
||||||
|
|
||||||
DeprecatedString const& collation() const { return m_collation; }
|
String const& collation() const { return m_collation; }
|
||||||
void set_collation(DeprecatedString collation) { m_collation = move(collation); }
|
void set_collation(String collation) { m_collation = move(collation); }
|
||||||
|
|
||||||
bool ignore_punctuation() const { return m_ignore_punctuation; }
|
bool ignore_punctuation() const { return m_ignore_punctuation; }
|
||||||
void set_ignore_punctuation(bool ignore_punctuation) { m_ignore_punctuation = ignore_punctuation; }
|
void set_ignore_punctuation(bool ignore_punctuation) { m_ignore_punctuation = ignore_punctuation; }
|
||||||
|
@ -77,11 +77,11 @@ private:
|
||||||
|
|
||||||
virtual void visit_edges(Visitor&) override;
|
virtual void visit_edges(Visitor&) override;
|
||||||
|
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
Usage m_usage { Usage::Sort }; // [[Usage]]
|
Usage m_usage { Usage::Sort }; // [[Usage]]
|
||||||
Sensitivity m_sensitivity { Sensitivity::Variant }; // [[Sensitivity]]
|
Sensitivity m_sensitivity { Sensitivity::Variant }; // [[Sensitivity]]
|
||||||
CaseFirst m_case_first { CaseFirst::False }; // [[CaseFirst]]
|
CaseFirst m_case_first { CaseFirst::False }; // [[CaseFirst]]
|
||||||
DeprecatedString m_collation; // [[Collation]]
|
String m_collation; // [[Collation]]
|
||||||
bool m_ignore_punctuation { false }; // [[IgnorePunctuation]]
|
bool m_ignore_punctuation { false }; // [[IgnorePunctuation]]
|
||||||
bool m_numeric { false }; // [[Numeric]]
|
bool m_numeric { false }; // [[Numeric]]
|
||||||
CollatorCompareFunction* m_bound_compare { nullptr }; // [[BoundCompare]]
|
CollatorCompareFunction* m_bound_compare { nullptr }; // [[BoundCompare]]
|
||||||
|
|
|
@ -53,7 +53,7 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, collation, "collation"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, collation, "collation"sv);
|
||||||
|
|
||||||
// 12. Set opt.[[co]] to collation.
|
// 12. Set opt.[[co]] to collation.
|
||||||
opt.co = TRY(collation.as_string().deprecated_string());
|
opt.co = TRY(collation.as_string().utf8_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13. Let numeric be ? GetOption(options, "numeric", boolean, empty, undefined).
|
// 13. Let numeric be ? GetOption(options, "numeric", boolean, empty, undefined).
|
||||||
|
@ -62,14 +62,16 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
||||||
// 14. If numeric is not undefined, then
|
// 14. If numeric is not undefined, then
|
||||||
// a. Let numeric be ! ToString(numeric).
|
// a. Let numeric be ! ToString(numeric).
|
||||||
// 15. Set opt.[[kn]] to numeric.
|
// 15. Set opt.[[kn]] to numeric.
|
||||||
if (!numeric.is_undefined())
|
if (!numeric.is_undefined()) {
|
||||||
opt.kn = MUST(numeric.to_deprecated_string(vm));
|
// NOTE: We TRY this operation only to propagate OOM errors.
|
||||||
|
opt.kn = TRY(numeric.to_string(vm));
|
||||||
|
}
|
||||||
|
|
||||||
// 16. Let caseFirst be ? GetOption(options, "caseFirst", string, « "upper", "lower", "false" », undefined).
|
// 16. Let caseFirst be ? GetOption(options, "caseFirst", string, « "upper", "lower", "false" », undefined).
|
||||||
// 17. Set opt.[[kf]] to caseFirst.
|
// 17. Set opt.[[kf]] to caseFirst.
|
||||||
auto case_first = TRY(get_option(vm, *options, vm.names.caseFirst, OptionType::String, { "upper"sv, "lower"sv, "false"sv }, Empty {}));
|
auto case_first = TRY(get_option(vm, *options, vm.names.caseFirst, OptionType::String, { "upper"sv, "lower"sv, "false"sv }, Empty {}));
|
||||||
if (!case_first.is_undefined())
|
if (!case_first.is_undefined())
|
||||||
opt.kf = TRY(case_first.as_string().deprecated_string());
|
opt.kf = TRY(case_first.as_string().utf8_string());
|
||||||
|
|
||||||
// 18. Let relevantExtensionKeys be %Collator%.[[RelevantExtensionKeys]].
|
// 18. Let relevantExtensionKeys be %Collator%.[[RelevantExtensionKeys]].
|
||||||
auto relevant_extension_keys = Collator::relevant_extension_keys();
|
auto relevant_extension_keys = Collator::relevant_extension_keys();
|
||||||
|
@ -83,7 +85,7 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
||||||
// 21. Let collation be r.[[co]].
|
// 21. Let collation be r.[[co]].
|
||||||
// 22. If collation is null, let collation be "default".
|
// 22. If collation is null, let collation be "default".
|
||||||
// 23. Set collator.[[Collation]] to collation.
|
// 23. Set collator.[[Collation]] to collation.
|
||||||
collator.set_collation(result.co.has_value() ? result.co.release_value() : "default");
|
collator.set_collation(result.co.has_value() ? result.co.release_value() : TRY_OR_THROW_OOM(vm, String::from_utf8("default"sv)));
|
||||||
|
|
||||||
// 24. If relevantExtensionKeys contains "kn", then
|
// 24. If relevantExtensionKeys contains "kn", then
|
||||||
if (relevant_extension_keys.span().contains_slow("kn"sv) && result.kn.has_value()) {
|
if (relevant_extension_keys.span().contains_slow("kn"sv) && result.kn.has_value()) {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <AK/Array.h>
|
#include <AK/Array.h>
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/DeprecatedString.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <AK/Time.h>
|
#include <AK/Time.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
@ -43,17 +44,17 @@ public:
|
||||||
|
|
||||||
virtual ~DateTimeFormat() override = default;
|
virtual ~DateTimeFormat() override = default;
|
||||||
|
|
||||||
DeprecatedString const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
|
|
||||||
DeprecatedString const& data_locale() const { return m_data_locale; }
|
String const& data_locale() const { return m_data_locale; }
|
||||||
void set_data_locale(DeprecatedString data_locale) { m_data_locale = move(data_locale); }
|
void set_data_locale(String data_locale) { m_data_locale = move(data_locale); }
|
||||||
|
|
||||||
DeprecatedString const& calendar() const { return m_calendar; }
|
String const& calendar() const { return m_calendar; }
|
||||||
void set_calendar(DeprecatedString calendar) { m_calendar = move(calendar); }
|
void set_calendar(String calendar) { m_calendar = move(calendar); }
|
||||||
|
|
||||||
DeprecatedString const& numbering_system() const { return m_numbering_system; }
|
String const& numbering_system() const { return m_numbering_system; }
|
||||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||||
|
|
||||||
bool has_hour_cycle() const { return m_hour_cycle.has_value(); }
|
bool has_hour_cycle() const { return m_hour_cycle.has_value(); }
|
||||||
::Locale::HourCycle hour_cycle() const { return *m_hour_cycle; }
|
::Locale::HourCycle hour_cycle() const { return *m_hour_cycle; }
|
||||||
|
@ -134,9 +135,9 @@ private:
|
||||||
|
|
||||||
virtual void visit_edges(Visitor&) override;
|
virtual void visit_edges(Visitor&) override;
|
||||||
|
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
DeprecatedString m_calendar; // [[Calendar]]
|
String m_calendar; // [[Calendar]]
|
||||||
DeprecatedString m_numbering_system; // [[NumberingSystem]]
|
String m_numbering_system; // [[NumberingSystem]]
|
||||||
Optional<::Locale::HourCycle> m_hour_cycle; // [[HourCycle]]
|
Optional<::Locale::HourCycle> m_hour_cycle; // [[HourCycle]]
|
||||||
DeprecatedString m_time_zone; // [[TimeZone]]
|
DeprecatedString m_time_zone; // [[TimeZone]]
|
||||||
Optional<Style> m_date_style; // [[DateStyle]]
|
Optional<Style> m_date_style; // [[DateStyle]]
|
||||||
|
@ -144,7 +145,7 @@ private:
|
||||||
Vector<::Locale::CalendarRangePattern> m_range_patterns; // [[RangePatterns]]
|
Vector<::Locale::CalendarRangePattern> m_range_patterns; // [[RangePatterns]]
|
||||||
NativeFunction* m_bound_format { nullptr }; // [[BoundFormat]]
|
NativeFunction* m_bound_format { nullptr }; // [[BoundFormat]]
|
||||||
|
|
||||||
DeprecatedString m_data_locale;
|
String m_data_locale;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OptionRequired {
|
enum class OptionRequired {
|
||||||
|
|
|
@ -110,7 +110,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, calendar, "calendar"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, calendar, "calendar"sv);
|
||||||
|
|
||||||
// 8. Set opt.[[ca]] to calendar.
|
// 8. Set opt.[[ca]] to calendar.
|
||||||
opt.ca = TRY(calendar.as_string().deprecated_string());
|
opt.ca = TRY(calendar.as_string().utf8_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Let numberingSystem be ? GetOption(options, "numberingSystem", string, empty, undefined).
|
// 9. Let numberingSystem be ? GetOption(options, "numberingSystem", string, empty, undefined).
|
||||||
|
@ -123,7 +123,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||||
|
|
||||||
// 11. Set opt.[[nu]] to numberingSystem.
|
// 11. Set opt.[[nu]] to numberingSystem.
|
||||||
opt.nu = TRY(numbering_system.as_string().deprecated_string());
|
opt.nu = TRY(numbering_system.as_string().utf8_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12. Let hour12 be ? GetOption(options, "hour12", boolean, empty, undefined).
|
// 12. Let hour12 be ? GetOption(options, "hour12", boolean, empty, undefined).
|
||||||
|
@ -140,7 +140,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
|
|
||||||
// 15. Set opt.[[hc]] to hourCycle.
|
// 15. Set opt.[[hc]] to hourCycle.
|
||||||
if (!hour_cycle.is_nullish())
|
if (!hour_cycle.is_nullish())
|
||||||
opt.hc = TRY(hour_cycle.as_string().deprecated_string());
|
opt.hc = TRY(hour_cycle.as_string().utf8_string());
|
||||||
|
|
||||||
// 16. Let localeData be %DateTimeFormat%.[[LocaleData]].
|
// 16. Let localeData be %DateTimeFormat%.[[LocaleData]].
|
||||||
// 17. Let r be ResolveLocale(%DateTimeFormat%.[[AvailableLocales]], requestedLocales, opt, %DateTimeFormat%.[[RelevantExtensionKeys]], localeData).
|
// 17. Let r be ResolveLocale(%DateTimeFormat%.[[AvailableLocales]], requestedLocales, opt, %DateTimeFormat%.[[RelevantExtensionKeys]], localeData).
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/DeprecatedString.h>
|
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <LibJS/Runtime/Object.h>
|
#include <LibJS/Runtime/Object.h>
|
||||||
#include <LibLocale/Locale.h>
|
#include <LibLocale/Locale.h>
|
||||||
|
@ -41,8 +41,8 @@ class DisplayNames final : public Object {
|
||||||
public:
|
public:
|
||||||
virtual ~DisplayNames() override = default;
|
virtual ~DisplayNames() override = default;
|
||||||
|
|
||||||
DeprecatedString const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
|
|
||||||
::Locale::Style style() const { return m_style; }
|
::Locale::Style style() const { return m_style; }
|
||||||
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
|
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
|
||||||
|
@ -64,7 +64,7 @@ public:
|
||||||
private:
|
private:
|
||||||
DisplayNames(Object& prototype);
|
DisplayNames(Object& prototype);
|
||||||
|
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
||||||
Type m_type { Type::Invalid }; // [[Type]]
|
Type m_type { Type::Invalid }; // [[Type]]
|
||||||
Fallback m_fallback { Fallback::Invalid }; // [[Fallback]]
|
Fallback m_fallback { Fallback::Invalid }; // [[Fallback]]
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <AK/Array.h>
|
#include <AK/Array.h>
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/DeprecatedString.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Object.h>
|
#include <LibJS/Runtime/Object.h>
|
||||||
#include <LibJS/Runtime/Temporal/Duration.h>
|
#include <LibJS/Runtime/Temporal/Duration.h>
|
||||||
|
@ -51,18 +52,18 @@ public:
|
||||||
|
|
||||||
virtual ~DurationFormat() override = default;
|
virtual ~DurationFormat() override = default;
|
||||||
|
|
||||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
DeprecatedString const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
|
|
||||||
void set_data_locale(DeprecatedString data_locale) { m_data_locale = move(data_locale); }
|
void set_data_locale(String data_locale) { m_data_locale = move(data_locale); }
|
||||||
DeprecatedString const& data_locale() const { return m_data_locale; }
|
String const& data_locale() const { return m_data_locale; }
|
||||||
|
|
||||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||||
DeprecatedString const& numbering_system() const { return m_numbering_system; }
|
String const& numbering_system() const { return m_numbering_system; }
|
||||||
|
|
||||||
void set_style(StringView style) { m_style = style_from_string(style); }
|
void set_style(StringView style) { m_style = style_from_string(style); }
|
||||||
Style style() const { return m_style; }
|
Style style() const { return m_style; }
|
||||||
DeprecatedString style_string() const { return style_to_string(m_style); }
|
StringView style_string() const { return style_to_string(m_style); }
|
||||||
|
|
||||||
void set_years_style(StringView years_style) { m_years_style = date_style_from_string(years_style); }
|
void set_years_style(StringView years_style) { m_years_style = date_style_from_string(years_style); }
|
||||||
ValueStyle years_style() const { return m_years_style; }
|
ValueStyle years_style() const { return m_years_style; }
|
||||||
|
@ -160,9 +161,9 @@ private:
|
||||||
static Display display_from_string(StringView display);
|
static Display display_from_string(StringView display);
|
||||||
static StringView display_to_string(Display);
|
static StringView display_to_string(Display);
|
||||||
|
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
DeprecatedString m_data_locale; // [[DataLocale]]
|
String m_data_locale; // [[DataLocale]]
|
||||||
DeprecatedString m_numbering_system; // [[NumberingSystem]]
|
String m_numbering_system; // [[NumberingSystem]]
|
||||||
Style m_style { Style::Long }; // [[Style]]
|
Style m_style { Style::Long }; // [[Style]]
|
||||||
ValueStyle m_years_style { ValueStyle::Long }; // [[YearsStyle]]
|
ValueStyle m_years_style { ValueStyle::Long }; // [[YearsStyle]]
|
||||||
Display m_years_display { Display::Auto }; // [[YearsDisplay]]
|
Display m_years_display { Display::Auto }; // [[YearsDisplay]]
|
||||||
|
|
|
@ -74,7 +74,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DurationFormatConstructor::construct(Fun
|
||||||
// 8. Let opt be the Record { [[localeMatcher]]: matcher, [[nu]]: numberingSystem }.
|
// 8. Let opt be the Record { [[localeMatcher]]: matcher, [[nu]]: numberingSystem }.
|
||||||
LocaleOptions opt {};
|
LocaleOptions opt {};
|
||||||
opt.locale_matcher = matcher;
|
opt.locale_matcher = matcher;
|
||||||
opt.nu = numbering_system.is_undefined() ? Optional<DeprecatedString>() : TRY(numbering_system.as_string().deprecated_string());
|
opt.nu = numbering_system.is_undefined() ? Optional<String>() : TRY(numbering_system.as_string().utf8_string());
|
||||||
|
|
||||||
// 9. Let r be ResolveLocale(%DurationFormat%.[[AvailableLocales]], requestedLocales, opt, %DurationFormat%.[[RelevantExtensionKeys]], %DurationFormat%.[[LocaleData]]).
|
// 9. Let r be ResolveLocale(%DurationFormat%.[[AvailableLocales]], requestedLocales, opt, %DurationFormat%.[[RelevantExtensionKeys]], %DurationFormat%.[[LocaleData]]).
|
||||||
auto result = TRY(resolve_locale(vm, requested_locales, opt, DurationFormat::relevant_extension_keys()));
|
auto result = TRY(resolve_locale(vm, requested_locales, opt, DurationFormat::relevant_extension_keys()));
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/DeprecatedString.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <AK/Variant.h>
|
#include <AK/Variant.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
@ -30,8 +31,8 @@ public:
|
||||||
|
|
||||||
virtual ~ListFormat() override = default;
|
virtual ~ListFormat() override = default;
|
||||||
|
|
||||||
DeprecatedString const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
|
|
||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
void set_type(StringView type);
|
void set_type(StringView type);
|
||||||
|
@ -44,7 +45,7 @@ public:
|
||||||
private:
|
private:
|
||||||
explicit ListFormat(Object& prototype);
|
explicit ListFormat(Object& prototype);
|
||||||
|
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
Type m_type { Type::Invalid }; // [[Type]]
|
Type m_type { Type::Invalid }; // [[Type]]
|
||||||
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,9 +14,34 @@
|
||||||
|
|
||||||
namespace JS::Intl {
|
namespace JS::Intl {
|
||||||
|
|
||||||
NonnullGCPtr<Locale> Locale::create(Realm& realm, ::Locale::LocaleID const& locale_id)
|
ThrowCompletionOr<NonnullGCPtr<Locale>> Locale::create(Realm& realm, ::Locale::LocaleID locale_id)
|
||||||
{
|
{
|
||||||
return realm.heap().allocate<Locale>(realm, locale_id, *realm.intrinsics().intl_locale_prototype());
|
auto locale = realm.heap().allocate<Locale>(realm, *realm.intrinsics().intl_locale_prototype());
|
||||||
|
locale->set_locale(TRY_OR_THROW_OOM(realm.vm(), locale_id.to_string()));
|
||||||
|
|
||||||
|
for (auto& extension : locale_id.extensions) {
|
||||||
|
if (!extension.has<::Locale::LocaleExtension>())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto& keyword : extension.get<::Locale::LocaleExtension>().keywords) {
|
||||||
|
if (keyword.key == "ca"sv)
|
||||||
|
locale->set_calendar(move(keyword.value));
|
||||||
|
else if (keyword.key == "co"sv)
|
||||||
|
locale->set_collation(move(keyword.value));
|
||||||
|
else if (keyword.key == "hc"sv)
|
||||||
|
locale->set_hour_cycle(move(keyword.value));
|
||||||
|
else if (keyword.key == "kf"sv)
|
||||||
|
locale->set_case_first(move(keyword.value));
|
||||||
|
else if (keyword.key == "kn"sv)
|
||||||
|
locale->set_numeric(keyword.value.is_empty());
|
||||||
|
else if (keyword.key == "nu"sv)
|
||||||
|
locale->set_numbering_system(move(keyword.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14 Locale Objects, https://tc39.es/ecma402/#locale-objects
|
// 14 Locale Objects, https://tc39.es/ecma402/#locale-objects
|
||||||
|
@ -25,37 +50,8 @@ Locale::Locale(Object& prototype)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Locale::Locale(::Locale::LocaleID const& locale_id, Object& prototype)
|
|
||||||
: Object(ConstructWithPrototypeTag::Tag, prototype)
|
|
||||||
{
|
|
||||||
set_locale(locale_id.to_deprecated_string());
|
|
||||||
|
|
||||||
for (auto const& extension : locale_id.extensions) {
|
|
||||||
if (!extension.has<::Locale::LocaleExtension>())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (auto const& keyword : extension.get<::Locale::LocaleExtension>().keywords) {
|
|
||||||
if (keyword.key == "ca"sv) {
|
|
||||||
set_calendar(keyword.value.to_deprecated_string());
|
|
||||||
} else if (keyword.key == "co"sv) {
|
|
||||||
set_collation(keyword.value.to_deprecated_string());
|
|
||||||
} else if (keyword.key == "hc"sv) {
|
|
||||||
set_hour_cycle(keyword.value.to_deprecated_string());
|
|
||||||
} else if (keyword.key == "kf"sv) {
|
|
||||||
set_case_first(keyword.value.to_deprecated_string());
|
|
||||||
} else if (keyword.key == "kn"sv) {
|
|
||||||
set_numeric(keyword.value.is_empty());
|
|
||||||
} else if (keyword.key == "nu"sv) {
|
|
||||||
set_numbering_system(keyword.value.to_deprecated_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1.1.1 CreateArrayFromListOrRestricted ( list , restricted )
|
// 1.1.1 CreateArrayFromListOrRestricted ( list , restricted )
|
||||||
static Array* create_array_from_list_or_restricted(VM& vm, Vector<StringView> list, Optional<DeprecatedString> restricted)
|
static Array* create_array_from_list_or_restricted(VM& vm, Vector<StringView> list, Optional<String> restricted)
|
||||||
{
|
{
|
||||||
auto& realm = *vm.current_realm();
|
auto& realm = *vm.current_realm();
|
||||||
|
|
||||||
|
@ -75,7 +71,7 @@ static Array* create_array_from_list_or_restricted(VM& vm, Vector<StringView> li
|
||||||
Array* calendars_of_locale(VM& vm, Locale const& locale_object)
|
Array* calendars_of_locale(VM& vm, Locale const& locale_object)
|
||||||
{
|
{
|
||||||
// 1. Let restricted be loc.[[Calendar]].
|
// 1. Let restricted be loc.[[Calendar]].
|
||||||
Optional<DeprecatedString> restricted = locale_object.has_calendar() ? locale_object.calendar() : Optional<DeprecatedString> {};
|
Optional<String> restricted = locale_object.has_calendar() ? locale_object.calendar() : Optional<String> {};
|
||||||
|
|
||||||
// 2. Let locale be loc.[[Locale]].
|
// 2. Let locale be loc.[[Locale]].
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
@ -94,7 +90,7 @@ Array* calendars_of_locale(VM& vm, Locale const& locale_object)
|
||||||
Array* collations_of_locale(VM& vm, Locale const& locale_object)
|
Array* collations_of_locale(VM& vm, Locale const& locale_object)
|
||||||
{
|
{
|
||||||
// 1. Let restricted be loc.[[Collation]].
|
// 1. Let restricted be loc.[[Collation]].
|
||||||
Optional<DeprecatedString> restricted = locale_object.has_collation() ? locale_object.collation() : Optional<DeprecatedString> {};
|
Optional<String> restricted = locale_object.has_collation() ? locale_object.collation() : Optional<String> {};
|
||||||
|
|
||||||
// 2. Let locale be loc.[[Locale]].
|
// 2. Let locale be loc.[[Locale]].
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
@ -113,7 +109,7 @@ Array* collations_of_locale(VM& vm, Locale const& locale_object)
|
||||||
Array* hour_cycles_of_locale(VM& vm, Locale const& locale_object)
|
Array* hour_cycles_of_locale(VM& vm, Locale const& locale_object)
|
||||||
{
|
{
|
||||||
// 1. Let restricted be loc.[[HourCycle]].
|
// 1. Let restricted be loc.[[HourCycle]].
|
||||||
Optional<DeprecatedString> restricted = locale_object.has_hour_cycle() ? locale_object.hour_cycle() : Optional<DeprecatedString> {};
|
Optional<String> restricted = locale_object.has_hour_cycle() ? locale_object.hour_cycle() : Optional<String> {};
|
||||||
|
|
||||||
// 2. Let locale be loc.[[Locale]].
|
// 2. Let locale be loc.[[Locale]].
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
@ -132,7 +128,7 @@ Array* hour_cycles_of_locale(VM& vm, Locale const& locale_object)
|
||||||
Array* numbering_systems_of_locale(VM& vm, Locale const& locale_object)
|
Array* numbering_systems_of_locale(VM& vm, Locale const& locale_object)
|
||||||
{
|
{
|
||||||
// 1. Let restricted be loc.[[NumberingSystem]].
|
// 1. Let restricted be loc.[[NumberingSystem]].
|
||||||
Optional<DeprecatedString> restricted = locale_object.has_numbering_system() ? locale_object.numbering_system() : Optional<DeprecatedString> {};
|
Optional<String> restricted = locale_object.has_numbering_system() ? locale_object.numbering_system() : Optional<String> {};
|
||||||
|
|
||||||
// 2. Let locale be loc.[[Locale]].
|
// 2. Let locale be loc.[[Locale]].
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Array.h>
|
#include <AK/Array.h>
|
||||||
#include <AK/DeprecatedString.h>
|
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibJS/Runtime/Completion.h>
|
#include <LibJS/Runtime/Completion.h>
|
||||||
#include <LibJS/Runtime/Object.h>
|
#include <LibJS/Runtime/Object.h>
|
||||||
|
@ -21,7 +21,7 @@ class Locale final : public Object {
|
||||||
JS_OBJECT(Locale, Object);
|
JS_OBJECT(Locale, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static NonnullGCPtr<Locale> create(Realm&, ::Locale::LocaleID const&);
|
static ThrowCompletionOr<NonnullGCPtr<Locale>> create(Realm&, ::Locale::LocaleID);
|
||||||
|
|
||||||
static constexpr auto relevant_extension_keys()
|
static constexpr auto relevant_extension_keys()
|
||||||
{
|
{
|
||||||
|
@ -36,43 +36,42 @@ public:
|
||||||
|
|
||||||
virtual ~Locale() override = default;
|
virtual ~Locale() override = default;
|
||||||
|
|
||||||
DeprecatedString const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
|
|
||||||
bool has_calendar() const { return m_calendar.has_value(); }
|
bool has_calendar() const { return m_calendar.has_value(); }
|
||||||
DeprecatedString const& calendar() const { return m_calendar.value(); }
|
String const& calendar() const { return m_calendar.value(); }
|
||||||
void set_calendar(DeprecatedString calendar) { m_calendar = move(calendar); }
|
void set_calendar(String calendar) { m_calendar = move(calendar); }
|
||||||
|
|
||||||
bool has_case_first() const { return m_case_first.has_value(); }
|
bool has_case_first() const { return m_case_first.has_value(); }
|
||||||
DeprecatedString const& case_first() const { return m_case_first.value(); }
|
String const& case_first() const { return m_case_first.value(); }
|
||||||
void set_case_first(DeprecatedString case_first) { m_case_first = move(case_first); }
|
void set_case_first(String case_first) { m_case_first = move(case_first); }
|
||||||
|
|
||||||
bool has_collation() const { return m_collation.has_value(); }
|
bool has_collation() const { return m_collation.has_value(); }
|
||||||
DeprecatedString const& collation() const { return m_collation.value(); }
|
String const& collation() const { return m_collation.value(); }
|
||||||
void set_collation(DeprecatedString collation) { m_collation = move(collation); }
|
void set_collation(String collation) { m_collation = move(collation); }
|
||||||
|
|
||||||
bool has_hour_cycle() const { return m_hour_cycle.has_value(); }
|
bool has_hour_cycle() const { return m_hour_cycle.has_value(); }
|
||||||
DeprecatedString const& hour_cycle() const { return m_hour_cycle.value(); }
|
String const& hour_cycle() const { return m_hour_cycle.value(); }
|
||||||
void set_hour_cycle(DeprecatedString hour_cycle) { m_hour_cycle = move(hour_cycle); }
|
void set_hour_cycle(String hour_cycle) { m_hour_cycle = move(hour_cycle); }
|
||||||
|
|
||||||
bool has_numbering_system() const { return m_numbering_system.has_value(); }
|
bool has_numbering_system() const { return m_numbering_system.has_value(); }
|
||||||
DeprecatedString const& numbering_system() const { return m_numbering_system.value(); }
|
String const& numbering_system() const { return m_numbering_system.value(); }
|
||||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||||
|
|
||||||
bool numeric() const { return m_numeric; }
|
bool numeric() const { return m_numeric; }
|
||||||
void set_numeric(bool numeric) { m_numeric = numeric; }
|
void set_numeric(bool numeric) { m_numeric = numeric; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Locale(Object& prototype);
|
explicit Locale(Object& prototype);
|
||||||
Locale(::Locale::LocaleID const&, Object& prototype);
|
|
||||||
|
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
Optional<DeprecatedString> m_calendar; // [[Calendar]]
|
Optional<String> m_calendar; // [[Calendar]]
|
||||||
Optional<DeprecatedString> m_case_first; // [[CaseFirst]]
|
Optional<String> m_case_first; // [[CaseFirst]]
|
||||||
Optional<DeprecatedString> m_collation; // [[Collation]]
|
Optional<String> m_collation; // [[Collation]]
|
||||||
Optional<DeprecatedString> m_hour_cycle; // [[HourCycle]]
|
Optional<String> m_hour_cycle; // [[HourCycle]]
|
||||||
Optional<DeprecatedString> m_numbering_system; // [[NumberingSystem]]
|
Optional<String> m_numbering_system; // [[NumberingSystem]]
|
||||||
bool m_numeric { false }; // [[Numeric]]
|
bool m_numeric { false }; // [[Numeric]]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Table 1: WeekInfo Record Fields, https://tc39.es/proposal-intl-locale-info/#table-locale-weekinfo-record
|
// Table 1: WeekInfo Record Fields, https://tc39.es/proposal-intl-locale-info/#table-locale-weekinfo-record
|
||||||
|
|
|
@ -41,7 +41,7 @@ static ThrowCompletionOr<Optional<String>> get_string_option(VM& vm, Object cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14.1.2 ApplyOptionsToTag ( tag, options ), https://tc39.es/ecma402/#sec-apply-options-to-tag
|
// 14.1.2 ApplyOptionsToTag ( tag, options ), https://tc39.es/ecma402/#sec-apply-options-to-tag
|
||||||
static ThrowCompletionOr<DeprecatedString> apply_options_to_tag(VM& vm, StringView tag, Object const& options)
|
static ThrowCompletionOr<String> apply_options_to_tag(VM& vm, StringView tag, Object const& options)
|
||||||
{
|
{
|
||||||
// 1. Assert: Type(tag) is String.
|
// 1. Assert: Type(tag) is String.
|
||||||
// 2. Assert: Type(options) is Object.
|
// 2. Assert: Type(options) is Object.
|
||||||
|
@ -200,7 +200,7 @@ static ThrowCompletionOr<LocaleAndKeys> apply_unicode_extension_to_tag(VM& vm, S
|
||||||
|
|
||||||
// 7. Let locale be the String value that is tag with any Unicode locale extension sequences removed.
|
// 7. Let locale be the String value that is tag with any Unicode locale extension sequences removed.
|
||||||
locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
||||||
auto locale = locale_id->to_string().release_value_but_fixme_should_propagate_errors();
|
auto locale = TRY_OR_THROW_OOM(vm, locale_id->to_string());
|
||||||
|
|
||||||
// 8. Let newExtension be a Unicode BCP 47 U Extension based on attributes and keywords.
|
// 8. Let newExtension be a Unicode BCP 47 U Extension based on attributes and keywords.
|
||||||
::Locale::LocaleExtension new_extension { move(attributes), move(keywords) };
|
::Locale::LocaleExtension new_extension { move(attributes), move(keywords) };
|
||||||
|
@ -208,7 +208,7 @@ static ThrowCompletionOr<LocaleAndKeys> apply_unicode_extension_to_tag(VM& vm, S
|
||||||
// 9. If newExtension is not the empty String, then
|
// 9. If newExtension is not the empty String, then
|
||||||
if (!new_extension.attributes.is_empty() || !new_extension.keywords.is_empty()) {
|
if (!new_extension.attributes.is_empty() || !new_extension.keywords.is_empty()) {
|
||||||
// a. Let locale be ! InsertUnicodeExtensionAndCanonicalize(locale, newExtension).
|
// a. Let locale be ! InsertUnicodeExtensionAndCanonicalize(locale, newExtension).
|
||||||
locale = TRY_OR_THROW_OOM(vm, String::from_deprecated_string(TRY(insert_unicode_extension_and_canonicalize(vm, locale_id.release_value(), move(new_extension)))));
|
locale = TRY(insert_unicode_extension_and_canonicalize(vm, locale_id.release_value(), move(new_extension)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. Set result.[[locale]] to locale.
|
// 10. Set result.[[locale]] to locale.
|
||||||
|
@ -262,7 +262,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> LocaleConstructor::construct(FunctionObj
|
||||||
// 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, "%Locale.prototype%", internalSlotsList).
|
// 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, "%Locale.prototype%", internalSlotsList).
|
||||||
auto locale = TRY(ordinary_create_from_constructor<Locale>(vm, new_target, &Intrinsics::intl_locale_prototype));
|
auto locale = TRY(ordinary_create_from_constructor<Locale>(vm, new_target, &Intrinsics::intl_locale_prototype));
|
||||||
|
|
||||||
DeprecatedString tag;
|
String tag;
|
||||||
|
|
||||||
// 7. If Type(tag) is not String or Object, throw a TypeError exception.
|
// 7. If Type(tag) is not String or Object, throw a TypeError exception.
|
||||||
if (!tag_value.is_string() && !tag_value.is_object())
|
if (!tag_value.is_string() && !tag_value.is_object())
|
||||||
|
@ -277,7 +277,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> LocaleConstructor::construct(FunctionObj
|
||||||
// 9. Else,
|
// 9. Else,
|
||||||
else {
|
else {
|
||||||
// a. Let tag be ? ToString(tag).
|
// a. Let tag be ? ToString(tag).
|
||||||
tag = TRY(tag_value.to_deprecated_string(vm));
|
tag = TRY(tag_value.to_string(vm));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. Set options to ? CoerceOptionsToObject(options).
|
// 10. Set options to ? CoerceOptionsToObject(options).
|
||||||
|
@ -328,28 +328,28 @@ ThrowCompletionOr<NonnullGCPtr<Object>> LocaleConstructor::construct(FunctionObj
|
||||||
auto result = TRY(apply_unicode_extension_to_tag(vm, tag, move(opt), relevant_extension_keys));
|
auto result = TRY(apply_unicode_extension_to_tag(vm, tag, move(opt), relevant_extension_keys));
|
||||||
|
|
||||||
// 30. Set locale.[[Locale]] to r.[[locale]].
|
// 30. Set locale.[[Locale]] to r.[[locale]].
|
||||||
locale->set_locale(result.locale.to_deprecated_string());
|
locale->set_locale(move(result.locale));
|
||||||
// 31. Set locale.[[Calendar]] to r.[[ca]].
|
// 31. Set locale.[[Calendar]] to r.[[ca]].
|
||||||
if (result.ca.has_value())
|
if (result.ca.has_value())
|
||||||
locale->set_calendar(result.ca->to_deprecated_string());
|
locale->set_calendar(result.ca.release_value());
|
||||||
// 32. Set locale.[[Collation]] to r.[[co]].
|
// 32. Set locale.[[Collation]] to r.[[co]].
|
||||||
if (result.co.has_value())
|
if (result.co.has_value())
|
||||||
locale->set_collation(result.co->to_deprecated_string());
|
locale->set_collation(result.co.release_value());
|
||||||
// 33. Set locale.[[HourCycle]] to r.[[hc]].
|
// 33. Set locale.[[HourCycle]] to r.[[hc]].
|
||||||
if (result.hc.has_value())
|
if (result.hc.has_value())
|
||||||
locale->set_hour_cycle(result.hc->to_deprecated_string());
|
locale->set_hour_cycle(result.hc.release_value());
|
||||||
|
|
||||||
// 34. If relevantExtensionKeys contains "kf", then
|
// 34. If relevantExtensionKeys contains "kf", then
|
||||||
if (relevant_extension_keys.span().contains_slow("kf"sv)) {
|
if (relevant_extension_keys.span().contains_slow("kf"sv)) {
|
||||||
// a. Set locale.[[CaseFirst]] to r.[[kf]].
|
// a. Set locale.[[CaseFirst]] to r.[[kf]].
|
||||||
if (result.kf.has_value())
|
if (result.kf.has_value())
|
||||||
locale->set_case_first(result.kf->to_deprecated_string());
|
locale->set_case_first(result.kf.release_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 35. If relevantExtensionKeys contains "kn", then
|
// 35. If relevantExtensionKeys contains "kn", then
|
||||||
if (relevant_extension_keys.span().contains_slow("kn"sv)) {
|
if (relevant_extension_keys.span().contains_slow("kn"sv)) {
|
||||||
// a. If SameValue(r.[[kn]], "true") is true or r.[[kn]] is the empty String, then
|
// a. If SameValue(r.[[kn]], "true") is true or r.[[kn]] is the empty String, then
|
||||||
if (result.kn.has_value() && (same_value(PrimitiveString::create(vm, *result.kn), PrimitiveString::create(vm, "true")) || result.kn->is_empty())) {
|
if (result.kn.has_value() && (result.kn == "true"sv || result.kn->is_empty())) {
|
||||||
// i. Set locale.[[Numeric]] to true.
|
// i. Set locale.[[Numeric]] to true.
|
||||||
locale->set_numeric(true);
|
locale->set_numeric(true);
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> LocaleConstructor::construct(FunctionObj
|
||||||
|
|
||||||
// 36. Set locale.[[NumberingSystem]] to r.[[nu]].
|
// 36. Set locale.[[NumberingSystem]] to r.[[nu]].
|
||||||
if (result.nu.has_value())
|
if (result.nu.has_value())
|
||||||
locale->set_numbering_system(result.nu->to_deprecated_string());
|
locale->set_numbering_system(result.nu.release_value());
|
||||||
|
|
||||||
// 37. Return locale.
|
// 37. Return locale.
|
||||||
return locale;
|
return locale;
|
||||||
|
|
|
@ -69,7 +69,8 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
|
||||||
locale->language_id = maximal.release_value();
|
locale->language_id = maximal.release_value();
|
||||||
|
|
||||||
// 4. Return ! Construct(%Locale%, maximal).
|
// 4. Return ! Construct(%Locale%, maximal).
|
||||||
return Locale::create(realm, *locale);
|
// NOTE: We TRY this operation only to propagate OOM errors.
|
||||||
|
return TRY(Locale::create(realm, locale.release_value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14.3.4 Intl.Locale.prototype.minimize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
|
// 14.3.4 Intl.Locale.prototype.minimize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
|
||||||
|
@ -89,7 +90,8 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
|
||||||
locale->language_id = minimal.release_value();
|
locale->language_id = minimal.release_value();
|
||||||
|
|
||||||
// 4. Return ! Construct(%Locale%, minimal).
|
// 4. Return ! Construct(%Locale%, minimal).
|
||||||
return Locale::create(realm, *locale);
|
// NOTE: We TRY this operation only to propagate OOM errors.
|
||||||
|
return TRY(Locale::create(realm, locale.release_value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14.3.5 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
|
// 14.3.5 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/Array.h>
|
#include <AK/Array.h>
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/DeprecatedString.h>
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Intl/MathematicalValue.h>
|
#include <LibJS/Runtime/Intl/MathematicalValue.h>
|
||||||
#include <LibJS/Runtime/Object.h>
|
#include <LibJS/Runtime/Object.h>
|
||||||
|
@ -58,11 +59,11 @@ public:
|
||||||
|
|
||||||
virtual ~NumberFormatBase() override = default;
|
virtual ~NumberFormatBase() override = default;
|
||||||
|
|
||||||
DeprecatedString const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
|
|
||||||
DeprecatedString const& data_locale() const { return m_data_locale; }
|
String const& data_locale() const { return m_data_locale; }
|
||||||
void set_data_locale(DeprecatedString data_locale) { m_data_locale = move(data_locale); }
|
void set_data_locale(String data_locale) { m_data_locale = move(data_locale); }
|
||||||
|
|
||||||
int min_integer_digits() const { return m_min_integer_digits; }
|
int min_integer_digits() const { return m_min_integer_digits; }
|
||||||
void set_min_integer_digits(int min_integer_digits) { m_min_integer_digits = min_integer_digits; }
|
void set_min_integer_digits(int min_integer_digits) { m_min_integer_digits = min_integer_digits; }
|
||||||
|
@ -102,8 +103,8 @@ protected:
|
||||||
explicit NumberFormatBase(Object& prototype);
|
explicit NumberFormatBase(Object& prototype);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
DeprecatedString m_data_locale; // [[DataLocale]]
|
String m_data_locale; // [[DataLocale]]
|
||||||
int m_min_integer_digits { 0 }; // [[MinimumIntegerDigits]]
|
int m_min_integer_digits { 0 }; // [[MinimumIntegerDigits]]
|
||||||
Optional<int> m_min_fraction_digits {}; // [[MinimumFractionDigits]]
|
Optional<int> m_min_fraction_digits {}; // [[MinimumFractionDigits]]
|
||||||
Optional<int> m_max_fraction_digits {}; // [[MaximumFractionDigits]]
|
Optional<int> m_max_fraction_digits {}; // [[MaximumFractionDigits]]
|
||||||
|
@ -178,16 +179,16 @@ public:
|
||||||
|
|
||||||
virtual ~NumberFormat() override = default;
|
virtual ~NumberFormat() override = default;
|
||||||
|
|
||||||
DeprecatedString const& numbering_system() const { return m_numbering_system; }
|
String const& numbering_system() const { return m_numbering_system; }
|
||||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||||
|
|
||||||
Style style() const { return m_style; }
|
Style style() const { return m_style; }
|
||||||
StringView style_string() const;
|
StringView style_string() const;
|
||||||
void set_style(StringView style);
|
void set_style(StringView style);
|
||||||
|
|
||||||
bool has_currency() const { return m_currency.has_value(); }
|
bool has_currency() const { return m_currency.has_value(); }
|
||||||
DeprecatedString const& currency() const { return m_currency.value(); }
|
String const& currency() const { return m_currency.value(); }
|
||||||
void set_currency(DeprecatedString currency) { m_currency = move(currency); }
|
void set_currency(String currency) { m_currency = move(currency); }
|
||||||
|
|
||||||
bool has_currency_display() const { return m_currency_display.has_value(); }
|
bool has_currency_display() const { return m_currency_display.has_value(); }
|
||||||
CurrencyDisplay currency_display() const { return *m_currency_display; }
|
CurrencyDisplay currency_display() const { return *m_currency_display; }
|
||||||
|
@ -201,8 +202,8 @@ public:
|
||||||
void set_currency_sign(StringView set_currency_sign);
|
void set_currency_sign(StringView set_currency_sign);
|
||||||
|
|
||||||
bool has_unit() const { return m_unit.has_value(); }
|
bool has_unit() const { return m_unit.has_value(); }
|
||||||
DeprecatedString const& unit() const { return m_unit.value(); }
|
String const& unit() const { return m_unit.value(); }
|
||||||
void set_unit(DeprecatedString unit) { m_unit = move(unit); }
|
void set_unit(String unit) { m_unit = move(unit); }
|
||||||
|
|
||||||
bool has_unit_display() const { return m_unit_display.has_value(); }
|
bool has_unit_display() const { return m_unit_display.has_value(); }
|
||||||
::Locale::Style unit_display() const { return *m_unit_display; }
|
::Locale::Style unit_display() const { return *m_unit_display; }
|
||||||
|
@ -238,14 +239,14 @@ private:
|
||||||
|
|
||||||
virtual void visit_edges(Visitor&) override;
|
virtual void visit_edges(Visitor&) override;
|
||||||
|
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
DeprecatedString m_data_locale; // [[DataLocale]]
|
String m_data_locale; // [[DataLocale]]
|
||||||
DeprecatedString m_numbering_system; // [[NumberingSystem]]
|
String m_numbering_system; // [[NumberingSystem]]
|
||||||
Style m_style { Style::Invalid }; // [[Style]]
|
Style m_style { Style::Invalid }; // [[Style]]
|
||||||
Optional<DeprecatedString> m_currency {}; // [[Currency]]
|
Optional<String> m_currency {}; // [[Currency]]
|
||||||
Optional<CurrencyDisplay> m_currency_display {}; // [[CurrencyDisplay]]
|
Optional<CurrencyDisplay> m_currency_display {}; // [[CurrencyDisplay]]
|
||||||
Optional<CurrencySign> m_currency_sign {}; // [[CurrencySign]]
|
Optional<CurrencySign> m_currency_sign {}; // [[CurrencySign]]
|
||||||
Optional<DeprecatedString> m_unit {}; // [[Unit]]
|
Optional<String> m_unit {}; // [[Unit]]
|
||||||
Optional<::Locale::Style> m_unit_display {}; // [[UnitDisplay]]
|
Optional<::Locale::Style> m_unit_display {}; // [[UnitDisplay]]
|
||||||
UseGrouping m_use_grouping { false }; // [[UseGrouping]]
|
UseGrouping m_use_grouping { false }; // [[UseGrouping]]
|
||||||
Notation m_notation { Notation::Invalid }; // [[Notation]]
|
Notation m_notation { Notation::Invalid }; // [[Notation]]
|
||||||
|
|
|
@ -107,7 +107,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat&
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||||
|
|
||||||
// 8. Set opt.[[nu]] to numberingSystem.
|
// 8. Set opt.[[nu]] to numberingSystem.
|
||||||
opt.nu = TRY(numbering_system.as_string().deprecated_string());
|
opt.nu = TRY(numbering_system.as_string().utf8_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Let localeData be %NumberFormat%.[[LocaleData]].
|
// 9. Let localeData be %NumberFormat%.[[LocaleData]].
|
||||||
|
@ -454,7 +454,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& int
|
||||||
// 14. If style is "currency", then
|
// 14. If style is "currency", then
|
||||||
if (intl_object.style() == NumberFormat::Style::Currency) {
|
if (intl_object.style() == NumberFormat::Style::Currency) {
|
||||||
// a. Set intlObj.[[Currency]] to the ASCII-uppercase of currency.
|
// a. Set intlObj.[[Currency]] to the ASCII-uppercase of currency.
|
||||||
intl_object.set_currency(TRY(currency.as_string().deprecated_string()).to_uppercase());
|
intl_object.set_currency(TRY_OR_THROW_OOM(vm, TRY(currency.as_string().utf8_string()).to_uppercase()));
|
||||||
|
|
||||||
// c. Set intlObj.[[CurrencyDisplay]] to currencyDisplay.
|
// c. Set intlObj.[[CurrencyDisplay]] to currencyDisplay.
|
||||||
intl_object.set_currency_display(TRY(currency_display.as_string().utf8_string_view()));
|
intl_object.set_currency_display(TRY(currency_display.as_string().utf8_string_view()));
|
||||||
|
@ -466,7 +466,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& int
|
||||||
// 15. If style is "unit", then
|
// 15. If style is "unit", then
|
||||||
if (intl_object.style() == NumberFormat::Style::Unit) {
|
if (intl_object.style() == NumberFormat::Style::Unit) {
|
||||||
// a. Set intlObj.[[Unit]] to unit.
|
// a. Set intlObj.[[Unit]] to unit.
|
||||||
intl_object.set_unit(TRY(unit.as_string().utf8_string_view()));
|
intl_object.set_unit(TRY(unit.as_string().utf8_string()));
|
||||||
|
|
||||||
// b. Set intlObj.[[UnitDisplay]] to unitDisplay.
|
// b. Set intlObj.[[UnitDisplay]] to unitDisplay.
|
||||||
intl_object.set_unit_display(TRY(unit_display.as_string().utf8_string_view()));
|
intl_object.set_unit_display(TRY(unit_display.as_string().utf8_string_view()));
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <AK/Array.h>
|
#include <AK/Array.h>
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/DeprecatedString.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <LibJS/Runtime/Completion.h>
|
#include <LibJS/Runtime/Completion.h>
|
||||||
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
||||||
|
@ -35,14 +36,14 @@ public:
|
||||||
|
|
||||||
virtual ~RelativeTimeFormat() override = default;
|
virtual ~RelativeTimeFormat() override = default;
|
||||||
|
|
||||||
DeprecatedString const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
|
|
||||||
DeprecatedString const& data_locale() const { return m_data_locale; }
|
String const& data_locale() const { return m_data_locale; }
|
||||||
void set_data_locale(DeprecatedString data_locale) { m_data_locale = move(data_locale); }
|
void set_data_locale(String data_locale) { m_data_locale = move(data_locale); }
|
||||||
|
|
||||||
DeprecatedString const& numbering_system() const { return m_numbering_system; }
|
String const& numbering_system() const { return m_numbering_system; }
|
||||||
void set_numbering_system(DeprecatedString numbering_system) { m_numbering_system = move(numbering_system); }
|
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||||
|
|
||||||
::Locale::Style style() const { return m_style; }
|
::Locale::Style style() const { return m_style; }
|
||||||
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
|
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
|
||||||
|
@ -63,9 +64,9 @@ private:
|
||||||
|
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
DeprecatedString m_data_locale; // [[DataLocale]]
|
String m_data_locale; // [[DataLocale]]
|
||||||
DeprecatedString m_numbering_system; // [[NumberingSystem]]
|
String m_numbering_system; // [[NumberingSystem]]
|
||||||
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
||||||
Numeric m_numeric { Numeric::Always }; // [[Numeric]]
|
Numeric m_numeric { Numeric::Always }; // [[Numeric]]
|
||||||
NumberFormat* m_number_format { nullptr }; // [[NumberFormat]]
|
NumberFormat* m_number_format { nullptr }; // [[NumberFormat]]
|
||||||
|
|
|
@ -105,7 +105,7 @@ ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(VM& vm, R
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||||
|
|
||||||
// 8. Set opt.[[nu]] to numberingSystem.
|
// 8. Set opt.[[nu]] to numberingSystem.
|
||||||
opt.nu = TRY(numbering_system.as_string().deprecated_string());
|
opt.nu = TRY(numbering_system.as_string().utf8_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Let localeData be %RelativeTimeFormat%.[[LocaleData]].
|
// 9. Let localeData be %RelativeTimeFormat%.[[LocaleData]].
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/String.h>
|
||||||
#include <LibJS/Runtime/Object.h>
|
#include <LibJS/Runtime/Object.h>
|
||||||
|
|
||||||
namespace JS::Intl {
|
namespace JS::Intl {
|
||||||
|
@ -23,8 +23,8 @@ public:
|
||||||
|
|
||||||
virtual ~Segmenter() override = default;
|
virtual ~Segmenter() override = default;
|
||||||
|
|
||||||
DeprecatedString const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
void set_locale(DeprecatedString locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
|
|
||||||
SegmenterGranularity segmenter_granularity() const { return m_segmenter_granularity; }
|
SegmenterGranularity segmenter_granularity() const { return m_segmenter_granularity; }
|
||||||
void set_segmenter_granularity(StringView);
|
void set_segmenter_granularity(StringView);
|
||||||
|
@ -33,7 +33,7 @@ public:
|
||||||
private:
|
private:
|
||||||
explicit Segmenter(Object& prototype);
|
explicit Segmenter(Object& prototype);
|
||||||
|
|
||||||
DeprecatedString m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
SegmenterGranularity m_segmenter_granularity { SegmenterGranularity::Grapheme }; // [[SegmenterGranularity]]
|
SegmenterGranularity m_segmenter_granularity { SegmenterGranularity::Grapheme }; // [[SegmenterGranularity]]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -901,7 +901,7 @@ static ThrowCompletionOr<String> transform_case(VM& vm, String const& string, Va
|
||||||
|
|
||||||
// 4. Let noExtensionsLocale be the String value that is requestedLocale with any Unicode locale extension sequences (6.2.1) removed.
|
// 4. Let noExtensionsLocale be the String value that is requestedLocale with any Unicode locale extension sequences (6.2.1) removed.
|
||||||
requested_locale->remove_extension_type<Locale::LocaleExtension>();
|
requested_locale->remove_extension_type<Locale::LocaleExtension>();
|
||||||
auto no_extensions_locale = requested_locale->to_deprecated_string();
|
auto no_extensions_locale = TRY_OR_THROW_OOM(vm, requested_locale->to_string());
|
||||||
|
|
||||||
// 5. Let availableLocales be a List with language tags that includes the languages for which the Unicode Character Database contains language sensitive case mappings. Implementations may add additional language tags if they support case mapping for additional locales.
|
// 5. Let availableLocales be a List with language tags that includes the languages for which the Unicode Character Database contains language sensitive case mappings. Implementations may add additional language tags if they support case mapping for additional locales.
|
||||||
// 6. Let locale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
// 6. Let locale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue