ladybird/Userland/Libraries/LibJS/Runtime/Intl/DisplayNames.h
Timothy Flynn 9724a25daf LibJS+LibLocale: Replace canonical locales and display names with ICU
Note: We keep locale parsing and syntactic validation as-is. ECMA-402
places additional restrictions on locales above what is required by the
Unicode spec. ICU doesn't provide methods that let us easily check those
restrictions, whereas LibLocale does. Other browsers also implement
their own validators here.

This introduces a locale cache to re-use parsed locale data and various
related structures (not doing so has a non-negligible performance impact
on Intl tests).

The existing APIs for canonicalization and display names are pretty
intertwined, so they must both be adapted at once here. The results of
canonicalization are slightly different on some edge cases. But the
changed results are actually now aligned with Chrome and Safari.
2024-06-09 10:47:28 +02:00

74 lines
2.3 KiB
C++

/*
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Optional.h>
#include <AK/String.h>
#include <AK/StringView.h>
#include <LibJS/Runtime/Object.h>
#include <LibLocale/DisplayNames.h>
#include <LibLocale/Locale.h>
namespace JS::Intl {
class DisplayNames final : public Object {
JS_OBJECT(DisplayNames, Object);
JS_DECLARE_ALLOCATOR(DisplayNames);
enum class Type {
Invalid,
Language,
Region,
Script,
Currency,
Calendar,
DateTimeField,
};
enum class Fallback {
Invalid,
None,
Code,
};
public:
virtual ~DisplayNames() override = default;
String const& locale() const { return m_locale; }
void set_locale(String locale) { m_locale = move(locale); }
::Locale::Style style() const { return m_style; }
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
StringView style_string() const { return ::Locale::style_to_string(m_style); }
Type type() const { return m_type; }
void set_type(StringView type);
StringView type_string() const;
Fallback fallback() const { return m_fallback; }
void set_fallback(StringView fallback);
StringView fallback_string() const;
bool has_language_display() const { return m_language_display.has_value(); }
::Locale::LanguageDisplay language_display() const { return *m_language_display; }
void set_language_display(StringView language_display) { m_language_display = ::Locale::language_display_from_string(language_display); }
StringView language_display_string() const { return ::Locale::language_display_to_string(*m_language_display); }
private:
DisplayNames(Object& prototype);
String m_locale; // [[Locale]]
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
Type m_type { Type::Invalid }; // [[Type]]
Fallback m_fallback { Fallback::Invalid }; // [[Fallback]]
Optional<::Locale::LanguageDisplay> m_language_display; // [[LanguageDisplay]]
};
ThrowCompletionOr<Value> canonical_code_for_display_names(VM&, DisplayNames::Type, StringView code);
bool is_valid_date_time_field_code(StringView field);
}