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

LibJS: Implement the Intl.DisplayNames constructor

There is notably FIXME notations in this commit regarding Unicode locale
extensions. We are not parsing extensions (or private use extensions) at
all yet.
This commit is contained in:
Timothy Flynn 2021-08-24 22:58:45 -04:00 committed by Linus Groh
parent 1c2ac69e3c
commit e8dd2eea74
7 changed files with 538 additions and 0 deletions

View file

@ -6,8 +6,11 @@
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Intl/AbstractOperations.h>
#include <LibJS/Runtime/Intl/DisplayNames.h>
#include <LibJS/Runtime/Intl/DisplayNamesConstructor.h>
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
#include <LibUnicode/Locale.h>
namespace JS::Intl {
@ -42,11 +45,82 @@ Value DisplayNamesConstructor::construct(FunctionObject& new_target)
auto& vm = this->vm();
auto& global_object = this->global_object();
auto locales = vm.argument(0);
auto options = vm.argument(1);
// 2. Let displayNames be ? OrdinaryCreateFromConstructor(NewTarget, "%DisplayNames.prototype%", « [[InitializedDisplayNames]], [[Locale]], [[Style]], [[Type]], [[Fallback]], [[Fields]] »).
auto* display_names = ordinary_create_from_constructor<DisplayNames>(global_object, new_target, &GlobalObject::intl_display_names_prototype);
if (vm.exception())
return {};
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
auto requested_locales = canonicalize_locale_list(global_object, locales);
if (vm.exception())
return {};
// 4. If options is undefined, throw a TypeError exception.
if (options.is_undefined()) {
vm.throw_exception<TypeError>(global_object, ErrorType::IsUndefined, "options"sv);
return {};
}
// 5. Set options to ? GetOptionsObject(options).
options = Temporal::get_options_object(global_object, options);
if (vm.exception())
return {};
// 6. Let opt be a new Record.
LocaleOptions opt {};
// 7. Let localeData be %DisplayNames%.[[LocaleData]].
// 8. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
auto matcher = get_option(global_object, options, vm.names.localeMatcher, Value::Type::String, { "lookup"sv, "best fit"sv }, "best fit"sv);
if (vm.exception())
return {};
// 9. Set opt.[[localeMatcher]] to matcher.
opt.locale_matcher = matcher;
// 10. Let r be ResolveLocale(%DisplayNames%.[[AvailableLocales]], requestedLocales, opt, %DisplayNames%.[[RelevantExtensionKeys]]).
auto result = resolve_locale(requested_locales, opt, {});
// 11. Let style be ? GetOption(options, "style", "string", « "narrow", "short", "long" », "long").
auto style = get_option(global_object, options, vm.names.style, Value::Type::String, { "narrow"sv, "short"sv, "long"sv }, "long"sv);
if (vm.exception())
return {};
// 12. Set displayNames.[[Style]] to style.
display_names->set_style(style.as_string().string());
// 13. Let type be ? GetOption(options, "type", "string", « "language", "region", "script", "currency" », undefined).
auto type = get_option(global_object, options, vm.names.type, Value::Type::String, { "language"sv, "region"sv, "script"sv, "currency"sv }, Empty {});
if (vm.exception())
return {};
// 14. If type is undefined, throw a TypeError exception.
if (type.is_undefined()) {
vm.throw_exception<TypeError>(global_object, ErrorType::IsUndefined, "options.type"sv);
return {};
}
// 15. Set displayNames.[[Type]] to type.
display_names->set_type(type.as_string().string());
// 16. Let fallback be ? GetOption(options, "fallback", "string", « "code", "none" », "code").
auto fallback = get_option(global_object, options, vm.names.fallback, Value::Type::String, { "code"sv, "none"sv }, "code"sv);
if (vm.exception())
return {};
// 17. Set displayNames.[[Fallback]] to fallback.
display_names->set_fallback(fallback.as_string().string());
// 18. Set displayNames.[[Locale]] to r.[[locale]].
display_names->set_locale(move(result.locale));
// Note: The remaining steps are skipped in favor of deferring to LibUnicode. We could copy
// the data from LibUnicode to the DisplayNames object, but for now we do not do that.
// 28. Return displayNames.
return display_names;
}