1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:47:36 +00:00

LibJS: Implement Intl.DisplayNames.prototype.of

Note that only option type=region is really implemented. Other types
will resort to the fallback option. This prototype method will be able
to implement other type options once LibUnicode supports more.
This commit is contained in:
Timothy Flynn 2021-08-24 23:10:50 -04:00 committed by Linus Groh
parent 38d29a40dc
commit 17bb652775
6 changed files with 189 additions and 0 deletions

View file

@ -377,4 +377,70 @@ Value get_option(GlobalObject& global_object, Value options, PropertyName const&
return value;
}
// 12.1.1 CanonicalCodeForDisplayNames ( type, code ), https://tc39.es/ecma402/#sec-canonicalcodefordisplaynames
Value canonical_code_for_display_names(GlobalObject& global_object, DisplayNames::Type type, StringView code)
{
auto& vm = global_object.vm();
// 1. If type is "language", then
if (type == DisplayNames::Type::Language) {
// a. If code does not match the unicode_language_id production, throw a RangeError exception.
if (!Unicode::parse_unicode_language_id(code).has_value()) {
vm.throw_exception<RangeError>(global_object, ErrorType::IntlInvalidCode, code, "language"sv);
return {};
}
// b. If IsStructurallyValidLanguageTag(code) is false, throw a RangeError exception.
auto locale_id = is_structurally_valid_language_tag(code);
if (!locale_id.has_value()) {
vm.throw_exception<RangeError>(global_object, ErrorType::IntlInvalidLanguageTag, code);
return {};
}
// c. Set code to CanonicalizeUnicodeLocaleId(code).
// d. Return code.
auto canonicalized_tag = JS::Intl::canonicalize_unicode_locale_id(*locale_id);
return js_string(vm, move(canonicalized_tag));
}
// 2. If type is "region", then
if (type == DisplayNames::Type::Region) {
// a. If code does not match the unicode_region_subtag production, throw a RangeError exception.
if (!Unicode::is_unicode_region_subtag(code)) {
vm.throw_exception<RangeError>(global_object, ErrorType::IntlInvalidCode, code, "region"sv);
return {};
}
// b. Let code be the result of mapping code to upper case as described in 6.1.
// c. Return code.
return js_string(vm, code.to_uppercase_string());
}
// 3. If type is "script", then
if (type == DisplayNames::Type::Script) {
// a. If code does not match the unicode_script_subtag production, throw a RangeError exception.
if (!Unicode::is_unicode_script_subtag(code)) {
vm.throw_exception<RangeError>(global_object, ErrorType::IntlInvalidCode, code, "script"sv);
return {};
}
// b. Let code be the result of mapping the first character in code to upper case, and mapping the second, third, and fourth character in code to lower case, as described in 6.1.
// c. Return code.
return js_string(vm, code.to_titlecase_string());
}
// 4. Assert: type is "currency".
VERIFY(type == DisplayNames::Type::Currency);
// 5. If ! IsWellFormedCurrencyCode(code) is false, throw a RangeError exception.
if (!is_well_formed_currency_code(code)) {
vm.throw_exception<RangeError>(global_object, ErrorType::IntlInvalidCode, code, "currency"sv);
return {};
}
// 6. Let code be the result of mapping code to upper case as described in 6.1.
// 7. Return code.
return js_string(vm, code.to_uppercase_string());
}
}