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:
parent
1c2ac69e3c
commit
e8dd2eea74
7 changed files with 538 additions and 0 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue