mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:28:11 +00:00
Userland: Move files destined for LibLocale to the Locale namespace
This commit is contained in:
parent
88504b89e1
commit
ff48220dca
55 changed files with 720 additions and 716 deletions
|
@ -75,7 +75,7 @@ constexpr auto s_day_period_list_index_type = "u8"sv;
|
||||||
using HourCycleListIndexType = u8;
|
using HourCycleListIndexType = u8;
|
||||||
constexpr auto s_hour_cycle_list_index_type = "u8"sv;
|
constexpr auto s_hour_cycle_list_index_type = "u8"sv;
|
||||||
|
|
||||||
struct CalendarPattern : public Unicode::CalendarPattern {
|
struct CalendarPattern : public Locale::CalendarPattern {
|
||||||
bool contains_only_date_fields() const
|
bool contains_only_date_fields() const
|
||||||
{
|
{
|
||||||
return !day_period.has_value() && !hour.has_value() && !minute.has_value() && !second.has_value() && !fractional_second_digits.has_value() && !time_zone_name.has_value();
|
return !day_period.has_value() && !hour.has_value() && !minute.has_value() && !second.has_value() && !fractional_second_digits.has_value() && !time_zone_name.has_value();
|
||||||
|
@ -195,7 +195,7 @@ struct CalendarRangePattern : public CalendarPattern {
|
||||||
&& (end_range == other.end_range);
|
&& (end_range == other.end_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Unicode::CalendarRangePattern::Field> field {};
|
Optional<Locale::CalendarRangePattern::Field> field {};
|
||||||
StringIndexType start_range { 0 };
|
StringIndexType start_range { 0 };
|
||||||
StringIndexType separator { 0 };
|
StringIndexType separator { 0 };
|
||||||
StringIndexType end_range { 0 };
|
StringIndexType end_range { 0 };
|
||||||
|
@ -500,7 +500,7 @@ struct DayPeriod {
|
||||||
&& (end == other.end);
|
&& (end == other.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
Unicode::DayPeriod day_period {};
|
Locale::DayPeriod day_period {};
|
||||||
u8 begin { 0 };
|
u8 begin { 0 };
|
||||||
u8 end { 0 };
|
u8 end { 0 };
|
||||||
};
|
};
|
||||||
|
@ -524,11 +524,11 @@ struct AK::Traits<DayPeriod> : public GenericTraits<DayPeriod> {
|
||||||
|
|
||||||
using TimeZoneNamesList = Vector<TimeZoneNamesIndexType>;
|
using TimeZoneNamesList = Vector<TimeZoneNamesIndexType>;
|
||||||
using DayPeriodList = Vector<DayPeriodIndexType>;
|
using DayPeriodList = Vector<DayPeriodIndexType>;
|
||||||
using HourCycleList = Vector<Unicode::HourCycle>;
|
using HourCycleList = Vector<Locale::HourCycle>;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct AK::Formatter<Unicode::HourCycle> : Formatter<FormatString> {
|
struct AK::Formatter<Locale::HourCycle> : Formatter<FormatString> {
|
||||||
ErrorOr<void> format(FormatBuilder& builder, Unicode::HourCycle hour_cycle)
|
ErrorOr<void> format(FormatBuilder& builder, Locale::HourCycle hour_cycle)
|
||||||
{
|
{
|
||||||
return builder.put_u64(to_underlying(hour_cycle));
|
return builder.put_u64(to_underlying(hour_cycle));
|
||||||
}
|
}
|
||||||
|
@ -569,13 +569,13 @@ struct CLDR {
|
||||||
HashMap<String, u8> minimum_days;
|
HashMap<String, u8> minimum_days;
|
||||||
Vector<String> minimum_days_regions;
|
Vector<String> minimum_days_regions;
|
||||||
|
|
||||||
HashMap<String, Unicode::Weekday> first_day;
|
HashMap<String, Locale::Weekday> first_day;
|
||||||
Vector<String> first_day_regions;
|
Vector<String> first_day_regions;
|
||||||
|
|
||||||
HashMap<String, Unicode::Weekday> weekend_start;
|
HashMap<String, Locale::Weekday> weekend_start;
|
||||||
Vector<String> weekend_start_regions;
|
Vector<String> weekend_start_regions;
|
||||||
|
|
||||||
HashMap<String, Unicode::Weekday> weekend_end;
|
HashMap<String, Locale::Weekday> weekend_end;
|
||||||
Vector<String> weekend_end_regions;
|
Vector<String> weekend_end_regions;
|
||||||
|
|
||||||
HashMap<String, Vector<TimeZone::TimeZone>> meta_zones;
|
HashMap<String, Vector<TimeZone::TimeZone>> meta_zones;
|
||||||
|
@ -584,30 +584,30 @@ struct CLDR {
|
||||||
Vector<String> calendars;
|
Vector<String> calendars;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Optional<Unicode::DayPeriod> day_period_from_string(StringView day_period)
|
static Optional<Locale::DayPeriod> day_period_from_string(StringView day_period)
|
||||||
{
|
{
|
||||||
if (day_period == "am"sv)
|
if (day_period == "am"sv)
|
||||||
return Unicode::DayPeriod::AM;
|
return Locale::DayPeriod::AM;
|
||||||
if (day_period == "pm"sv)
|
if (day_period == "pm"sv)
|
||||||
return Unicode::DayPeriod::PM;
|
return Locale::DayPeriod::PM;
|
||||||
if (day_period == "noon"sv)
|
if (day_period == "noon"sv)
|
||||||
return Unicode::DayPeriod::Noon;
|
return Locale::DayPeriod::Noon;
|
||||||
if (day_period == "morning1"sv)
|
if (day_period == "morning1"sv)
|
||||||
return Unicode::DayPeriod::Morning1;
|
return Locale::DayPeriod::Morning1;
|
||||||
if (day_period == "morning2"sv)
|
if (day_period == "morning2"sv)
|
||||||
return Unicode::DayPeriod::Morning2;
|
return Locale::DayPeriod::Morning2;
|
||||||
if (day_period == "afternoon1"sv)
|
if (day_period == "afternoon1"sv)
|
||||||
return Unicode::DayPeriod::Afternoon1;
|
return Locale::DayPeriod::Afternoon1;
|
||||||
if (day_period == "afternoon2"sv)
|
if (day_period == "afternoon2"sv)
|
||||||
return Unicode::DayPeriod::Afternoon2;
|
return Locale::DayPeriod::Afternoon2;
|
||||||
if (day_period == "evening1"sv)
|
if (day_period == "evening1"sv)
|
||||||
return Unicode::DayPeriod::Evening1;
|
return Locale::DayPeriod::Evening1;
|
||||||
if (day_period == "evening2"sv)
|
if (day_period == "evening2"sv)
|
||||||
return Unicode::DayPeriod::Evening2;
|
return Locale::DayPeriod::Evening2;
|
||||||
if (day_period == "night1"sv)
|
if (day_period == "night1"sv)
|
||||||
return Unicode::DayPeriod::Night1;
|
return Locale::DayPeriod::Night1;
|
||||||
if (day_period == "night2"sv)
|
if (day_period == "night2"sv)
|
||||||
return Unicode::DayPeriod::Night2;
|
return Locale::DayPeriod::Night2;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,15 +622,15 @@ static ErrorOr<void> parse_hour_cycles(String core_path, CLDR& cldr)
|
||||||
auto const& supplemental_object = time_data.as_object().get("supplemental"sv);
|
auto const& supplemental_object = time_data.as_object().get("supplemental"sv);
|
||||||
auto const& time_data_object = supplemental_object.as_object().get("timeData"sv);
|
auto const& time_data_object = supplemental_object.as_object().get("timeData"sv);
|
||||||
|
|
||||||
auto parse_hour_cycle = [](StringView hour_cycle) -> Optional<Unicode::HourCycle> {
|
auto parse_hour_cycle = [](StringView hour_cycle) -> Optional<Locale::HourCycle> {
|
||||||
if (hour_cycle == "h"sv)
|
if (hour_cycle == "h"sv)
|
||||||
return Unicode::HourCycle::H12;
|
return Locale::HourCycle::H12;
|
||||||
if (hour_cycle == "H"sv)
|
if (hour_cycle == "H"sv)
|
||||||
return Unicode::HourCycle::H23;
|
return Locale::HourCycle::H23;
|
||||||
if (hour_cycle == "K"sv)
|
if (hour_cycle == "K"sv)
|
||||||
return Unicode::HourCycle::H11;
|
return Locale::HourCycle::H11;
|
||||||
if (hour_cycle == "k"sv)
|
if (hour_cycle == "k"sv)
|
||||||
return Unicode::HourCycle::H24;
|
return Locale::HourCycle::H24;
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -638,7 +638,7 @@ static ErrorOr<void> parse_hour_cycles(String core_path, CLDR& cldr)
|
||||||
auto allowed_hour_cycles_string = value.as_object().get("_allowed"sv).as_string();
|
auto allowed_hour_cycles_string = value.as_object().get("_allowed"sv).as_string();
|
||||||
auto allowed_hour_cycles = allowed_hour_cycles_string.split_view(' ');
|
auto allowed_hour_cycles = allowed_hour_cycles_string.split_view(' ');
|
||||||
|
|
||||||
Vector<Unicode::HourCycle> hour_cycles;
|
Vector<Locale::HourCycle> hour_cycles;
|
||||||
|
|
||||||
for (auto allowed_hour_cycle : allowed_hour_cycles) {
|
for (auto allowed_hour_cycle : allowed_hour_cycles) {
|
||||||
if (auto hour_cycle = parse_hour_cycle(allowed_hour_cycle); hour_cycle.has_value())
|
if (auto hour_cycle = parse_hour_cycle(allowed_hour_cycle); hour_cycle.has_value())
|
||||||
|
@ -666,21 +666,21 @@ static ErrorOr<void> parse_week_data(String core_path, CLDR& cldr)
|
||||||
auto const& supplemental_object = week_data.as_object().get("supplemental"sv);
|
auto const& supplemental_object = week_data.as_object().get("supplemental"sv);
|
||||||
auto const& week_data_object = supplemental_object.as_object().get("weekData"sv);
|
auto const& week_data_object = supplemental_object.as_object().get("weekData"sv);
|
||||||
|
|
||||||
auto parse_weekday = [](StringView day) -> Unicode::Weekday {
|
auto parse_weekday = [](StringView day) -> Locale::Weekday {
|
||||||
if (day == "sun"sv)
|
if (day == "sun"sv)
|
||||||
return Unicode::Weekday::Sunday;
|
return Locale::Weekday::Sunday;
|
||||||
if (day == "mon"sv)
|
if (day == "mon"sv)
|
||||||
return Unicode::Weekday::Monday;
|
return Locale::Weekday::Monday;
|
||||||
if (day == "tue"sv)
|
if (day == "tue"sv)
|
||||||
return Unicode::Weekday::Tuesday;
|
return Locale::Weekday::Tuesday;
|
||||||
if (day == "wed"sv)
|
if (day == "wed"sv)
|
||||||
return Unicode::Weekday::Wednesday;
|
return Locale::Weekday::Wednesday;
|
||||||
if (day == "thu"sv)
|
if (day == "thu"sv)
|
||||||
return Unicode::Weekday::Thursday;
|
return Locale::Weekday::Thursday;
|
||||||
if (day == "fri"sv)
|
if (day == "fri"sv)
|
||||||
return Unicode::Weekday::Friday;
|
return Locale::Weekday::Friday;
|
||||||
if (day == "sat"sv)
|
if (day == "sat"sv)
|
||||||
return Unicode::Weekday::Saturday;
|
return Locale::Weekday::Saturday;
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -803,7 +803,7 @@ static String remove_period_from_pattern(String pattern)
|
||||||
static Optional<CalendarPattern> parse_date_time_pattern_raw(String pattern, String skeleton, CLDR& cldr)
|
static Optional<CalendarPattern> parse_date_time_pattern_raw(String pattern, String skeleton, CLDR& cldr)
|
||||||
{
|
{
|
||||||
// https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
|
// https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
|
||||||
using Unicode::CalendarPatternStyle;
|
using Locale::CalendarPatternStyle;
|
||||||
|
|
||||||
CalendarPattern format {};
|
CalendarPattern format {};
|
||||||
|
|
||||||
|
@ -1047,25 +1047,25 @@ static void parse_interval_patterns(Calendar& calendar, JsonObject const& interv
|
||||||
|
|
||||||
auto name_of_field = [&](char field) {
|
auto name_of_field = [&](char field) {
|
||||||
if (char_is_one_of(field, 'G'))
|
if (char_is_one_of(field, 'G'))
|
||||||
return Unicode::CalendarRangePattern::Field::Era;
|
return Locale::CalendarRangePattern::Field::Era;
|
||||||
if (char_is_one_of(field, 'y', 'Y', 'u', 'U', 'r'))
|
if (char_is_one_of(field, 'y', 'Y', 'u', 'U', 'r'))
|
||||||
return Unicode::CalendarRangePattern::Field::Year;
|
return Locale::CalendarRangePattern::Field::Year;
|
||||||
if (char_is_one_of(field, 'M', 'L'))
|
if (char_is_one_of(field, 'M', 'L'))
|
||||||
return Unicode::CalendarRangePattern::Field::Month;
|
return Locale::CalendarRangePattern::Field::Month;
|
||||||
if (char_is_one_of(field, 'd', 'D', 'F', 'g'))
|
if (char_is_one_of(field, 'd', 'D', 'F', 'g'))
|
||||||
return Unicode::CalendarRangePattern::Field::Day;
|
return Locale::CalendarRangePattern::Field::Day;
|
||||||
if (char_is_one_of(field, 'a', 'b'))
|
if (char_is_one_of(field, 'a', 'b'))
|
||||||
return Unicode::CalendarRangePattern::Field::AmPm;
|
return Locale::CalendarRangePattern::Field::AmPm;
|
||||||
if (char_is_one_of(field, 'B'))
|
if (char_is_one_of(field, 'B'))
|
||||||
return Unicode::CalendarRangePattern::Field::DayPeriod;
|
return Locale::CalendarRangePattern::Field::DayPeriod;
|
||||||
if (char_is_one_of(field, 'h', 'H', 'K', 'k'))
|
if (char_is_one_of(field, 'h', 'H', 'K', 'k'))
|
||||||
return Unicode::CalendarRangePattern::Field::Hour;
|
return Locale::CalendarRangePattern::Field::Hour;
|
||||||
if (char_is_one_of(field, 'm'))
|
if (char_is_one_of(field, 'm'))
|
||||||
return Unicode::CalendarRangePattern::Field::Minute;
|
return Locale::CalendarRangePattern::Field::Minute;
|
||||||
if (char_is_one_of(field, 's'))
|
if (char_is_one_of(field, 's'))
|
||||||
return Unicode::CalendarRangePattern::Field::Second;
|
return Locale::CalendarRangePattern::Field::Second;
|
||||||
if (char_is_one_of(field, 'S'))
|
if (char_is_one_of(field, 'S'))
|
||||||
return Unicode::CalendarRangePattern::Field::FractionalSecondDigits;
|
return Locale::CalendarRangePattern::Field::FractionalSecondDigits;
|
||||||
|
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
};
|
};
|
||||||
|
@ -1227,12 +1227,12 @@ static void generate_missing_patterns(Calendar& calendar, CalendarPatternList& f
|
||||||
auto const& date_time_formats = cldr.unique_formats.get(calendar.date_time_formats);
|
auto const& date_time_formats = cldr.unique_formats.get(calendar.date_time_formats);
|
||||||
CalendarPatternIndexType date_time_format_index = 0;
|
CalendarPatternIndexType date_time_format_index = 0;
|
||||||
|
|
||||||
if (date_format.month == Unicode::CalendarPatternStyle::Long) {
|
if (date_format.month == Locale::CalendarPatternStyle::Long) {
|
||||||
if (date_format.weekday.has_value())
|
if (date_format.weekday.has_value())
|
||||||
date_time_format_index = date_time_formats.full_format;
|
date_time_format_index = date_time_formats.full_format;
|
||||||
else
|
else
|
||||||
date_time_format_index = date_time_formats.long_format;
|
date_time_format_index = date_time_formats.long_format;
|
||||||
} else if (date_format.month == Unicode::CalendarPatternStyle::Short) {
|
} else if (date_format.month == Locale::CalendarPatternStyle::Short) {
|
||||||
date_time_format_index = date_time_formats.medium_format;
|
date_time_format_index = date_time_formats.medium_format;
|
||||||
} else {
|
} else {
|
||||||
date_time_format_index = date_time_formats.short_format;
|
date_time_format_index = date_time_formats.short_format;
|
||||||
|
@ -1314,7 +1314,7 @@ static void parse_calendar_symbols(Calendar& calendar, JsonObject const& calenda
|
||||||
append_symbol(symbol_lists[2], key, value.as_string());
|
append_symbol(symbol_lists[2], key, value.as_string());
|
||||||
});
|
});
|
||||||
|
|
||||||
store_symbol_lists(Unicode::CalendarSymbol::Era, move(symbol_lists));
|
store_symbol_lists(Locale::CalendarSymbol::Era, move(symbol_lists));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto parse_month_symbols = [&](auto const& symbols_object) {
|
auto parse_month_symbols = [&](auto const& symbols_object) {
|
||||||
|
@ -1338,7 +1338,7 @@ static void parse_calendar_symbols(Calendar& calendar, JsonObject const& calenda
|
||||||
append_symbol(symbol_lists[2], key, value.as_string());
|
append_symbol(symbol_lists[2], key, value.as_string());
|
||||||
});
|
});
|
||||||
|
|
||||||
store_symbol_lists(Unicode::CalendarSymbol::Month, move(symbol_lists));
|
store_symbol_lists(Locale::CalendarSymbol::Month, move(symbol_lists));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto parse_weekday_symbols = [&](auto const& symbols_object) {
|
auto parse_weekday_symbols = [&](auto const& symbols_object) {
|
||||||
|
@ -1349,19 +1349,19 @@ static void parse_calendar_symbols(Calendar& calendar, JsonObject const& calenda
|
||||||
|
|
||||||
auto append_symbol = [&](auto& symbols, auto const& key, auto symbol) {
|
auto append_symbol = [&](auto& symbols, auto const& key, auto symbol) {
|
||||||
if (key == "sun"sv)
|
if (key == "sun"sv)
|
||||||
symbols[to_underlying(Unicode::Weekday::Sunday)] = cldr.unique_strings.ensure(move(symbol));
|
symbols[to_underlying(Locale::Weekday::Sunday)] = cldr.unique_strings.ensure(move(symbol));
|
||||||
else if (key == "mon"sv)
|
else if (key == "mon"sv)
|
||||||
symbols[to_underlying(Unicode::Weekday::Monday)] = cldr.unique_strings.ensure(move(symbol));
|
symbols[to_underlying(Locale::Weekday::Monday)] = cldr.unique_strings.ensure(move(symbol));
|
||||||
else if (key == "tue"sv)
|
else if (key == "tue"sv)
|
||||||
symbols[to_underlying(Unicode::Weekday::Tuesday)] = cldr.unique_strings.ensure(move(symbol));
|
symbols[to_underlying(Locale::Weekday::Tuesday)] = cldr.unique_strings.ensure(move(symbol));
|
||||||
else if (key == "wed"sv)
|
else if (key == "wed"sv)
|
||||||
symbols[to_underlying(Unicode::Weekday::Wednesday)] = cldr.unique_strings.ensure(move(symbol));
|
symbols[to_underlying(Locale::Weekday::Wednesday)] = cldr.unique_strings.ensure(move(symbol));
|
||||||
else if (key == "thu"sv)
|
else if (key == "thu"sv)
|
||||||
symbols[to_underlying(Unicode::Weekday::Thursday)] = cldr.unique_strings.ensure(move(symbol));
|
symbols[to_underlying(Locale::Weekday::Thursday)] = cldr.unique_strings.ensure(move(symbol));
|
||||||
else if (key == "fri"sv)
|
else if (key == "fri"sv)
|
||||||
symbols[to_underlying(Unicode::Weekday::Friday)] = cldr.unique_strings.ensure(move(symbol));
|
symbols[to_underlying(Locale::Weekday::Friday)] = cldr.unique_strings.ensure(move(symbol));
|
||||||
else if (key == "sat"sv)
|
else if (key == "sat"sv)
|
||||||
symbols[to_underlying(Unicode::Weekday::Saturday)] = cldr.unique_strings.ensure(move(symbol));
|
symbols[to_underlying(Locale::Weekday::Saturday)] = cldr.unique_strings.ensure(move(symbol));
|
||||||
};
|
};
|
||||||
|
|
||||||
narrow_symbols.for_each_member([&](auto const& key, JsonValue const& value) {
|
narrow_symbols.for_each_member([&](auto const& key, JsonValue const& value) {
|
||||||
|
@ -1374,7 +1374,7 @@ static void parse_calendar_symbols(Calendar& calendar, JsonObject const& calenda
|
||||||
append_symbol(symbol_lists[2], key, value.as_string());
|
append_symbol(symbol_lists[2], key, value.as_string());
|
||||||
});
|
});
|
||||||
|
|
||||||
store_symbol_lists(Unicode::CalendarSymbol::Weekday, move(symbol_lists));
|
store_symbol_lists(Locale::CalendarSymbol::Weekday, move(symbol_lists));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto parse_day_period_symbols = [&](auto const& symbols_object) {
|
auto parse_day_period_symbols = [&](auto const& symbols_object) {
|
||||||
|
@ -1398,7 +1398,7 @@ static void parse_calendar_symbols(Calendar& calendar, JsonObject const& calenda
|
||||||
append_symbol(symbol_lists[2], key, value.as_string());
|
append_symbol(symbol_lists[2], key, value.as_string());
|
||||||
});
|
});
|
||||||
|
|
||||||
store_symbol_lists(Unicode::CalendarSymbol::DayPeriod, move(symbol_lists));
|
store_symbol_lists(Locale::CalendarSymbol::DayPeriod, move(symbol_lists));
|
||||||
};
|
};
|
||||||
|
|
||||||
parse_era_symbols(calendar_object.get("eras"sv).as_object());
|
parse_era_symbols(calendar_object.get("eras"sv).as_object());
|
||||||
|
@ -1726,7 +1726,7 @@ static ErrorOr<void> generate_unicode_locale_header(Core::Stream::BufferedFile&
|
||||||
|
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
generate_enum(generator, format_identifier, "Calendar"sv, {}, cldr.calendars);
|
generate_enum(generator, format_identifier, "Calendar"sv, {}, cldr.calendars);
|
||||||
|
@ -1774,7 +1774,7 @@ static ErrorOr<void> generate_unicode_locale_implementation(Core::Stream::Buffer
|
||||||
#include <LibUnicode/DateTimeFormat.h>
|
#include <LibUnicode/DateTimeFormat.h>
|
||||||
#include <LibUnicode/Locale.h>
|
#include <LibUnicode/Locale.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
cldr.unique_strings.generate(generator);
|
cldr.unique_strings.generate(generator);
|
||||||
|
@ -2099,9 +2099,9 @@ Optional<@return_type@> get_regional_@lookup_type@(StringView region)
|
||||||
};
|
};
|
||||||
|
|
||||||
append_regional_lookup("u8"sv, "minimum_days"sv);
|
append_regional_lookup("u8"sv, "minimum_days"sv);
|
||||||
append_regional_lookup("Unicode::Weekday"sv, "first_day"sv);
|
append_regional_lookup("Weekday"sv, "first_day"sv);
|
||||||
append_regional_lookup("Unicode::Weekday"sv, "weekend_start"sv);
|
append_regional_lookup("Weekday"sv, "weekend_start"sv);
|
||||||
append_regional_lookup("Unicode::Weekday"sv, "weekend_end"sv);
|
append_regional_lookup("Weekday"sv, "weekend_end"sv);
|
||||||
|
|
||||||
generator.append(R"~~~(
|
generator.append(R"~~~(
|
||||||
static CalendarData const* find_calendar_data(StringView locale, StringView calendar)
|
static CalendarData const* find_calendar_data(StringView locale, StringView calendar)
|
||||||
|
|
|
@ -1051,7 +1051,7 @@ static ErrorOr<void> generate_unicode_locale_header(Core::Stream::BufferedFile&
|
||||||
|
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
auto locales = cldr.locales.keys();
|
auto locales = cldr.locales.keys();
|
||||||
|
@ -1107,7 +1107,7 @@ static ErrorOr<void> generate_unicode_locale_implementation(Core::Stream::Buffer
|
||||||
#include <LibUnicode/DateTimeFormat.h>
|
#include <LibUnicode/DateTimeFormat.h>
|
||||||
#include <LibUnicode/Locale.h>
|
#include <LibUnicode/Locale.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
cldr.unique_strings.generate(generator);
|
cldr.unique_strings.generate(generator);
|
||||||
|
|
|
@ -55,8 +55,8 @@ enum class NumberFormatType {
|
||||||
Compact,
|
Compact,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumberFormat : public Unicode::NumberFormat {
|
struct NumberFormat : public Locale::NumberFormat {
|
||||||
using Base = Unicode::NumberFormat;
|
using Base = Locale::NumberFormat;
|
||||||
|
|
||||||
unsigned hash() const
|
unsigned hash() const
|
||||||
{
|
{
|
||||||
|
@ -478,7 +478,7 @@ static ErrorOr<void> parse_number_systems(String locale_numbers_path, CLDR& cldr
|
||||||
VERIFY(split_key[0] == "unitPattern"sv);
|
VERIFY(split_key[0] == "unitPattern"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
format.plurality = Unicode::plural_category_from_string(split_key[2]);
|
format.plurality = Locale::plural_category_from_string(split_key[2]);
|
||||||
parse_number_pattern(move(patterns), cldr, NumberFormatType::Compact, format);
|
parse_number_pattern(move(patterns), cldr, NumberFormatType::Compact, format);
|
||||||
|
|
||||||
auto format_index = cldr.unique_formats.ensure(move(format));
|
auto format_index = cldr.unique_formats.ensure(move(format));
|
||||||
|
@ -488,27 +488,27 @@ static ErrorOr<void> parse_number_systems(String locale_numbers_path, CLDR& cldr
|
||||||
return cldr.unique_format_lists.ensure(move(result));
|
return cldr.unique_format_lists.ensure(move(result));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto numeric_symbol_from_string = [&](StringView numeric_symbol) -> Optional<Unicode::NumericSymbol> {
|
auto numeric_symbol_from_string = [&](StringView numeric_symbol) -> Optional<Locale::NumericSymbol> {
|
||||||
if (numeric_symbol == "approximatelySign"sv)
|
if (numeric_symbol == "approximatelySign"sv)
|
||||||
return Unicode::NumericSymbol::ApproximatelySign;
|
return Locale::NumericSymbol::ApproximatelySign;
|
||||||
if (numeric_symbol == "decimal"sv)
|
if (numeric_symbol == "decimal"sv)
|
||||||
return Unicode::NumericSymbol::Decimal;
|
return Locale::NumericSymbol::Decimal;
|
||||||
if (numeric_symbol == "exponential"sv)
|
if (numeric_symbol == "exponential"sv)
|
||||||
return Unicode::NumericSymbol::Exponential;
|
return Locale::NumericSymbol::Exponential;
|
||||||
if (numeric_symbol == "group"sv)
|
if (numeric_symbol == "group"sv)
|
||||||
return Unicode::NumericSymbol::Group;
|
return Locale::NumericSymbol::Group;
|
||||||
if (numeric_symbol == "infinity"sv)
|
if (numeric_symbol == "infinity"sv)
|
||||||
return Unicode::NumericSymbol::Infinity;
|
return Locale::NumericSymbol::Infinity;
|
||||||
if (numeric_symbol == "minusSign"sv)
|
if (numeric_symbol == "minusSign"sv)
|
||||||
return Unicode::NumericSymbol::MinusSign;
|
return Locale::NumericSymbol::MinusSign;
|
||||||
if (numeric_symbol == "nan"sv)
|
if (numeric_symbol == "nan"sv)
|
||||||
return Unicode::NumericSymbol::NaN;
|
return Locale::NumericSymbol::NaN;
|
||||||
if (numeric_symbol == "percentSign"sv)
|
if (numeric_symbol == "percentSign"sv)
|
||||||
return Unicode::NumericSymbol::PercentSign;
|
return Locale::NumericSymbol::PercentSign;
|
||||||
if (numeric_symbol == "plusSign"sv)
|
if (numeric_symbol == "plusSign"sv)
|
||||||
return Unicode::NumericSymbol::PlusSign;
|
return Locale::NumericSymbol::PlusSign;
|
||||||
if (numeric_symbol == "timeSeparator"sv)
|
if (numeric_symbol == "timeSeparator"sv)
|
||||||
return Unicode::NumericSymbol::TimeSeparator;
|
return Locale::NumericSymbol::TimeSeparator;
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -548,11 +548,11 @@ static ErrorOr<void> parse_number_systems(String locale_numbers_path, CLDR& cldr
|
||||||
auto end_index = range_separator.find("{1}"sv).value();
|
auto end_index = range_separator.find("{1}"sv).value();
|
||||||
range_separator = range_separator.substring(begin_index, end_index - begin_index);
|
range_separator = range_separator.substring(begin_index, end_index - begin_index);
|
||||||
|
|
||||||
if (to_underlying(Unicode::NumericSymbol::RangeSeparator) >= symbols.size())
|
if (to_underlying(Locale::NumericSymbol::RangeSeparator) >= symbols.size())
|
||||||
symbols.resize(to_underlying(Unicode::NumericSymbol::RangeSeparator) + 1);
|
symbols.resize(to_underlying(Locale::NumericSymbol::RangeSeparator) + 1);
|
||||||
|
|
||||||
auto symbol_index = cldr.unique_strings.ensure(move(range_separator));
|
auto symbol_index = cldr.unique_strings.ensure(move(range_separator));
|
||||||
symbols[to_underlying(Unicode::NumericSymbol::RangeSeparator)] = symbol_index;
|
symbols[to_underlying(Locale::NumericSymbol::RangeSeparator)] = symbol_index;
|
||||||
|
|
||||||
number_system.symbols = cldr.unique_symbols.ensure(move(symbols));
|
number_system.symbols = cldr.unique_symbols.ensure(move(symbols));
|
||||||
} else if (key.starts_with(decimal_formats_prefix)) {
|
} else if (key.starts_with(decimal_formats_prefix)) {
|
||||||
|
@ -644,7 +644,7 @@ static ErrorOr<void> parse_units(String locale_units_path, CLDR& cldr, LocaleDat
|
||||||
return find(extra_sanctioned_units.begin(), extra_sanctioned_units.end(), unit_name) != extra_sanctioned_units.end();
|
return find(extra_sanctioned_units.begin(), extra_sanctioned_units.end(), unit_name) != extra_sanctioned_units.end();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto parse_units_object = [&](auto const& units_object, Unicode::Style style) {
|
auto parse_units_object = [&](auto const& units_object, Locale::Style style) {
|
||||||
constexpr auto unit_pattern_prefix = "unitPattern-count-"sv;
|
constexpr auto unit_pattern_prefix = "unitPattern-count-"sv;
|
||||||
constexpr auto combined_unit_separator = "-per-"sv;
|
constexpr auto combined_unit_separator = "-per-"sv;
|
||||||
|
|
||||||
|
@ -676,7 +676,7 @@ static ErrorOr<void> parse_units(String locale_units_path, CLDR& cldr, LocaleDat
|
||||||
NumberFormat format {};
|
NumberFormat format {};
|
||||||
|
|
||||||
auto plurality = unit_key.substring_view(unit_pattern_prefix.length());
|
auto plurality = unit_key.substring_view(unit_pattern_prefix.length());
|
||||||
format.plurality = Unicode::plural_category_from_string(plurality);
|
format.plurality = Locale::plural_category_from_string(plurality);
|
||||||
|
|
||||||
auto zero_format = pattern_value.as_string().replace("{0}"sv, "{number}"sv, ReplaceMode::FirstOnly);
|
auto zero_format = pattern_value.as_string().replace("{0}"sv, "{number}"sv, ReplaceMode::FirstOnly);
|
||||||
zero_format = parse_identifiers(zero_format, "unitIdentifier"sv, cldr, format);
|
zero_format = parse_identifiers(zero_format, "unitIdentifier"sv, cldr, format);
|
||||||
|
@ -691,13 +691,13 @@ static ErrorOr<void> parse_units(String locale_units_path, CLDR& cldr, LocaleDat
|
||||||
auto number_format_list_index = cldr.unique_format_lists.ensure(move(formats));
|
auto number_format_list_index = cldr.unique_format_lists.ensure(move(formats));
|
||||||
|
|
||||||
switch (style) {
|
switch (style) {
|
||||||
case Unicode::Style::Long:
|
case Locale::Style::Long:
|
||||||
unit.long_formats = number_format_list_index;
|
unit.long_formats = number_format_list_index;
|
||||||
break;
|
break;
|
||||||
case Unicode::Style::Short:
|
case Locale::Style::Short:
|
||||||
unit.short_formats = number_format_list_index;
|
unit.short_formats = number_format_list_index;
|
||||||
break;
|
break;
|
||||||
case Unicode::Style::Narrow:
|
case Locale::Style::Narrow:
|
||||||
unit.narrow_formats = number_format_list_index;
|
unit.narrow_formats = number_format_list_index;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -706,9 +706,9 @@ static ErrorOr<void> parse_units(String locale_units_path, CLDR& cldr, LocaleDat
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
parse_units_object(long_object.as_object(), Unicode::Style::Long);
|
parse_units_object(long_object.as_object(), Locale::Style::Long);
|
||||||
parse_units_object(short_object.as_object(), Unicode::Style::Short);
|
parse_units_object(short_object.as_object(), Locale::Style::Short);
|
||||||
parse_units_object(narrow_object.as_object(), Unicode::Style::Narrow);
|
parse_units_object(narrow_object.as_object(), Locale::Style::Narrow);
|
||||||
|
|
||||||
for (auto& unit : units) {
|
for (auto& unit : units) {
|
||||||
auto unit_index = cldr.unique_units.ensure(move(unit.value));
|
auto unit_index = cldr.unique_units.ensure(move(unit.value));
|
||||||
|
@ -776,7 +776,7 @@ static ErrorOr<void> generate_unicode_locale_header(Core::Stream::BufferedFile&
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
generate_enum(generator, format_identifier, "NumberSystem"sv, {}, cldr.number_systems);
|
generate_enum(generator, format_identifier, "NumberSystem"sv, {}, cldr.number_systems);
|
||||||
|
@ -812,7 +812,7 @@ static ErrorOr<void> generate_unicode_locale_implementation(Core::Stream::Buffer
|
||||||
#include <LibUnicode/NumberFormat.h>
|
#include <LibUnicode/NumberFormat.h>
|
||||||
#include <LibUnicode/PluralRules.h>
|
#include <LibUnicode/PluralRules.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
cldr.unique_strings.generate(generator);
|
cldr.unique_strings.generate(generator);
|
||||||
|
|
|
@ -67,7 +67,7 @@ struct Relation {
|
||||||
else if (symbol == 'e' || symbol == 'c')
|
else if (symbol == 'e' || symbol == 'c')
|
||||||
generator.append(exponential_variable_name());
|
generator.append(exponential_variable_name());
|
||||||
else
|
else
|
||||||
generator.append(String::formatted("ops.{}", Unicode::PluralOperands::symbol_to_variable_name(symbol)));
|
generator.append(String::formatted("ops.{}", Locale::PluralOperands::symbol_to_variable_name(symbol)));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto append_value = [&](u32 value) {
|
auto append_value = [&](u32 value) {
|
||||||
|
@ -78,7 +78,7 @@ struct Relation {
|
||||||
|
|
||||||
auto append_range = [&](auto const& range) {
|
auto append_range = [&](auto const& range) {
|
||||||
// This check avoids generating "0 <= unsigned_value", which is always true.
|
// This check avoids generating "0 <= unsigned_value", which is always true.
|
||||||
if (range[0] != 0 || Unicode::PluralOperands::symbol_requires_floating_point_modulus(symbol)) {
|
if (range[0] != 0 || Locale::PluralOperands::symbol_requires_floating_point_modulus(symbol)) {
|
||||||
generator.append(String::formatted("{} <= ", range[0]));
|
generator.append(String::formatted("{} <= ", range[0]));
|
||||||
append_variable_name();
|
append_variable_name();
|
||||||
generator.append(" && "sv);
|
generator.append(" && "sv);
|
||||||
|
@ -129,10 +129,10 @@ struct Relation {
|
||||||
|
|
||||||
generated_variables.set(variable);
|
generated_variables.set(variable);
|
||||||
generator.set("variable"sv, move(variable));
|
generator.set("variable"sv, move(variable));
|
||||||
generator.set("operand"sv, Unicode::PluralOperands::symbol_to_variable_name(symbol));
|
generator.set("operand"sv, Locale::PluralOperands::symbol_to_variable_name(symbol));
|
||||||
generator.set("modulus"sv, String::number(*modulus));
|
generator.set("modulus"sv, String::number(*modulus));
|
||||||
|
|
||||||
if (Unicode::PluralOperands::symbol_requires_floating_point_modulus(symbol)) {
|
if (Locale::PluralOperands::symbol_requires_floating_point_modulus(symbol)) {
|
||||||
generator.append(R"~~~(
|
generator.append(R"~~~(
|
||||||
auto @variable@ = fmod(ops.@operand@, @modulus@);)~~~");
|
auto @variable@ = fmod(ops.@operand@, @modulus@);)~~~");
|
||||||
} else {
|
} else {
|
||||||
|
@ -439,7 +439,7 @@ static ErrorOr<void> generate_unicode_locale_header(Core::Stream::BufferedFile&
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
generator.append(R"~~~(
|
generator.append(R"~~~(
|
||||||
|
@ -466,7 +466,7 @@ static ErrorOr<void> generate_unicode_locale_implementation(Core::Stream::Buffer
|
||||||
#include <LibUnicode/PluralRules.h>
|
#include <LibUnicode/PluralRules.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
using PluralCategoryFunction = PluralCategory(*)(PluralOperands);
|
using PluralCategoryFunction = PluralCategory(*)(PluralOperands);
|
||||||
using PluralRangeFunction = PluralCategory(*)(PluralCategory, PluralCategory);
|
using PluralRangeFunction = PluralCategory(*)(PluralCategory, PluralCategory);
|
||||||
|
|
|
@ -180,7 +180,7 @@ static ErrorOr<void> generate_unicode_locale_header(Core::Stream::BufferedFile&
|
||||||
|
|
||||||
#include <LibUnicode/Forward.h>
|
#include <LibUnicode/Forward.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
generator.append(R"~~~(
|
generator.append(R"~~~(
|
||||||
|
@ -207,7 +207,7 @@ static ErrorOr<void> generate_unicode_locale_implementation(Core::Stream::Buffer
|
||||||
#include <LibUnicode/PluralRules.h>
|
#include <LibUnicode/PluralRules.h>
|
||||||
#include <LibUnicode/RelativeTimeFormat.h>
|
#include <LibUnicode/RelativeTimeFormat.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
cldr.unique_strings.generate(generator);
|
cldr.unique_strings.generate(generator);
|
||||||
|
|
|
@ -714,7 +714,7 @@ struct SpecialCasing {
|
||||||
u32 titlecase_mapping[@casing_transform_size@];
|
u32 titlecase_mapping[@casing_transform_size@];
|
||||||
u32 titlecase_mapping_size { 0 };
|
u32 titlecase_mapping_size { 0 };
|
||||||
|
|
||||||
Locale locale { Locale::None };
|
Locale::Locale locale { Locale::Locale::None };
|
||||||
Condition condition { Condition::None };
|
Condition condition { Condition::None };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -780,7 +780,7 @@ static constexpr Array<SpecialCasing, @special_casing_size@> s_special_casing {
|
||||||
append_list_and_size(casing.titlecase_mapping, format);
|
append_list_and_size(casing.titlecase_mapping, format);
|
||||||
|
|
||||||
generator.set("locale", casing.locale.is_empty() ? "None" : casing.locale);
|
generator.set("locale", casing.locale.is_empty() ? "None" : casing.locale);
|
||||||
generator.append(", Locale::@locale@");
|
generator.append(", Locale::Locale::@locale@");
|
||||||
|
|
||||||
generator.set("condition", casing.condition.is_empty() ? "None" : casing.condition);
|
generator.set("condition", casing.condition.is_empty() ? "None" : casing.condition);
|
||||||
generator.append(", Condition::@condition@");
|
generator.append(", Condition::@condition@");
|
||||||
|
|
|
@ -285,7 +285,7 @@ struct CanonicalLanguageID {
|
||||||
VERIFY(!segments.is_empty());
|
VERIFY(!segments.is_empty());
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
|
||||||
if (Unicode::is_unicode_language_subtag(segments[index])) {
|
if (Locale::is_unicode_language_subtag(segments[index])) {
|
||||||
language_id.language = unique_strings.ensure(segments[index]);
|
language_id.language = unique_strings.ensure(segments[index]);
|
||||||
if (segments.size() == ++index)
|
if (segments.size() == ++index)
|
||||||
return language_id;
|
return language_id;
|
||||||
|
@ -293,20 +293,20 @@ struct CanonicalLanguageID {
|
||||||
return Error::from_string_literal("Expected language subtag");
|
return Error::from_string_literal("Expected language subtag");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Unicode::is_unicode_script_subtag(segments[index])) {
|
if (Locale::is_unicode_script_subtag(segments[index])) {
|
||||||
language_id.script = unique_strings.ensure(segments[index]);
|
language_id.script = unique_strings.ensure(segments[index]);
|
||||||
if (segments.size() == ++index)
|
if (segments.size() == ++index)
|
||||||
return language_id;
|
return language_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Unicode::is_unicode_region_subtag(segments[index])) {
|
if (Locale::is_unicode_region_subtag(segments[index])) {
|
||||||
language_id.region = unique_strings.ensure(segments[index]);
|
language_id.region = unique_strings.ensure(segments[index]);
|
||||||
if (segments.size() == ++index)
|
if (segments.size() == ++index)
|
||||||
return language_id;
|
return language_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (index < segments.size()) {
|
while (index < segments.size()) {
|
||||||
if (!Unicode::is_unicode_variant_subtag(segments[index]))
|
if (!Locale::is_unicode_variant_subtag(segments[index]))
|
||||||
return Error::from_string_literal("Expected variant subtag");
|
return Error::from_string_literal("Expected variant subtag");
|
||||||
language_id.variants.append(unique_strings.ensure(segments[index++]));
|
language_id.variants.append(unique_strings.ensure(segments[index++]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,67 +15,67 @@ TEST_CASE(time_zone_name)
|
||||||
{
|
{
|
||||||
struct TestData {
|
struct TestData {
|
||||||
StringView locale;
|
StringView locale;
|
||||||
Unicode::CalendarPatternStyle style;
|
Locale::CalendarPatternStyle style;
|
||||||
StringView time_zone;
|
StringView time_zone;
|
||||||
StringView expected_result;
|
StringView expected_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto test_data = Array {
|
constexpr auto test_data = Array {
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "UTC"sv, "Coordinated Universal Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "UTC"sv, "Coordinated Universal Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "UTC"sv, "UTC"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "UTC"sv, "UTC"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongGeneric, "UTC"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongGeneric, "UTC"sv, "GMT"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortGeneric, "UTC"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortGeneric, "UTC"sv, "GMT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "UTC"sv, "التوقيت العالمي المنسق"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "UTC"sv, "التوقيت العالمي المنسق"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "UTC"sv, "UTC"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "UTC"sv, "UTC"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongGeneric, "UTC"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongGeneric, "UTC"sv, "غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortGeneric, "UTC"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortGeneric, "UTC"sv, "غرينتش"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "America/Los_Angeles"sv, "Pacific Standard Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "America/Los_Angeles"sv, "Pacific Standard Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "America/Los_Angeles"sv, "PST"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "America/Los_Angeles"sv, "PST"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongGeneric, "America/Los_Angeles"sv, "Pacific Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongGeneric, "America/Los_Angeles"sv, "Pacific Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortGeneric, "America/Los_Angeles"sv, "PT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortGeneric, "America/Los_Angeles"sv, "PT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "America/Los_Angeles"sv, "توقيت المحيط الهادي الرسمي"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "America/Los_Angeles"sv, "توقيت المحيط الهادي الرسمي"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "America/Los_Angeles"sv, "غرينتش-٨"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "America/Los_Angeles"sv, "غرينتش-٨"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongGeneric, "America/Los_Angeles"sv, "توقيت المحيط الهادي"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongGeneric, "America/Los_Angeles"sv, "توقيت المحيط الهادي"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortGeneric, "America/Los_Angeles"sv, "غرينتش-٨"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortGeneric, "America/Los_Angeles"sv, "غرينتش-٨"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "America/Vancouver"sv, "Pacific Standard Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "America/Vancouver"sv, "Pacific Standard Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "America/Vancouver"sv, "PST"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "America/Vancouver"sv, "PST"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongGeneric, "America/Vancouver"sv, "Pacific Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongGeneric, "America/Vancouver"sv, "Pacific Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortGeneric, "America/Vancouver"sv, "PT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortGeneric, "America/Vancouver"sv, "PT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "America/Vancouver"sv, "توقيت المحيط الهادي الرسمي"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "America/Vancouver"sv, "توقيت المحيط الهادي الرسمي"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "America/Vancouver"sv, "غرينتش-٨"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "America/Vancouver"sv, "غرينتش-٨"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongGeneric, "America/Vancouver"sv, "توقيت المحيط الهادي"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongGeneric, "America/Vancouver"sv, "توقيت المحيط الهادي"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortGeneric, "America/Vancouver"sv, "غرينتش-٨"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortGeneric, "America/Vancouver"sv, "غرينتش-٨"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "Europe/London"sv, "Greenwich Mean Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "Europe/London"sv, "Greenwich Mean Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "Europe/London"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "Europe/London"sv, "GMT"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongGeneric, "Europe/London"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongGeneric, "Europe/London"sv, "GMT"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortGeneric, "Europe/London"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortGeneric, "Europe/London"sv, "GMT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "Europe/London"sv, "توقيت غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "Europe/London"sv, "توقيت غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "Europe/London"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "Europe/London"sv, "غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongGeneric, "Europe/London"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongGeneric, "Europe/London"sv, "غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortGeneric, "Europe/London"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortGeneric, "Europe/London"sv, "غرينتش"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "Africa/Accra"sv, "Greenwich Mean Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "Africa/Accra"sv, "Greenwich Mean Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "Africa/Accra"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "Africa/Accra"sv, "GMT"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongGeneric, "Africa/Accra"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongGeneric, "Africa/Accra"sv, "GMT"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortGeneric, "Africa/Accra"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortGeneric, "Africa/Accra"sv, "GMT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "Africa/Accra"sv, "توقيت غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "Africa/Accra"sv, "توقيت غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "Africa/Accra"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "Africa/Accra"sv, "غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongGeneric, "Africa/Accra"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongGeneric, "Africa/Accra"sv, "غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortGeneric, "Africa/Accra"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortGeneric, "Africa/Accra"sv, "غرينتش"sv },
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto jan_1_2022 = AK::Time::from_seconds(1640995200); // Saturday, January 1, 2022 12:00:00 AM
|
constexpr auto jan_1_2022 = AK::Time::from_seconds(1640995200); // Saturday, January 1, 2022 12:00:00 AM
|
||||||
|
|
||||||
for (auto const& test : test_data) {
|
for (auto const& test : test_data) {
|
||||||
auto time_zone = Unicode::format_time_zone(test.locale, test.time_zone, test.style, jan_1_2022);
|
auto time_zone = Locale::format_time_zone(test.locale, test.time_zone, test.style, jan_1_2022);
|
||||||
EXPECT_EQ(time_zone, test.expected_result);
|
EXPECT_EQ(time_zone, test.expected_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,48 +84,48 @@ TEST_CASE(time_zone_name_dst)
|
||||||
{
|
{
|
||||||
struct TestData {
|
struct TestData {
|
||||||
StringView locale;
|
StringView locale;
|
||||||
Unicode::CalendarPatternStyle style;
|
Locale::CalendarPatternStyle style;
|
||||||
StringView time_zone;
|
StringView time_zone;
|
||||||
StringView expected_result;
|
StringView expected_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto test_data = Array {
|
constexpr auto test_data = Array {
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "UTC"sv, "Coordinated Universal Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "UTC"sv, "Coordinated Universal Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "UTC"sv, "UTC"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "UTC"sv, "UTC"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "UTC"sv, "التوقيت العالمي المنسق"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "UTC"sv, "التوقيت العالمي المنسق"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "UTC"sv, "UTC"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "UTC"sv, "UTC"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "America/Los_Angeles"sv, "Pacific Daylight Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "America/Los_Angeles"sv, "Pacific Daylight Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "America/Los_Angeles"sv, "PDT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "America/Los_Angeles"sv, "PDT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "America/Los_Angeles"sv, "توقيت المحيط الهادي الصيفي"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "America/Los_Angeles"sv, "توقيت المحيط الهادي الصيفي"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "America/Los_Angeles"sv, "غرينتش-٧"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "America/Los_Angeles"sv, "غرينتش-٧"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "America/Vancouver"sv, "Pacific Daylight Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "America/Vancouver"sv, "Pacific Daylight Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "America/Vancouver"sv, "PDT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "America/Vancouver"sv, "PDT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "America/Vancouver"sv, "توقيت المحيط الهادي الصيفي"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "America/Vancouver"sv, "توقيت المحيط الهادي الصيفي"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "America/Vancouver"sv, "غرينتش-٧"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "America/Vancouver"sv, "غرينتش-٧"sv },
|
||||||
|
|
||||||
// FIXME: This should be "British Summer Time", but the CLDR puts that one name in a section we aren't parsing.
|
// FIXME: This should be "British Summer Time", but the CLDR puts that one name in a section we aren't parsing.
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "Europe/London"sv, "GMT+01:00"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "Europe/London"sv, "GMT+01:00"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "Europe/London"sv, "GMT+1"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "Europe/London"sv, "GMT+1"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "Europe/London"sv, "غرينتش+٠١:٠٠"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "Europe/London"sv, "غرينتش+٠١:٠٠"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "Europe/London"sv, "غرينتش+١"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "Europe/London"sv, "غرينتش+١"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Long, "Africa/Accra"sv, "Greenwich Mean Time"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Long, "Africa/Accra"sv, "Greenwich Mean Time"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::Short, "Africa/Accra"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::Short, "Africa/Accra"sv, "GMT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Long, "Africa/Accra"sv, "توقيت غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Long, "Africa/Accra"sv, "توقيت غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::Short, "Africa/Accra"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::Short, "Africa/Accra"sv, "غرينتش"sv },
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto sep_19_2022 = AK::Time::from_seconds(1663553728); // Monday, September 19, 2022 2:15:28 AM
|
constexpr auto sep_19_2022 = AK::Time::from_seconds(1663553728); // Monday, September 19, 2022 2:15:28 AM
|
||||||
|
|
||||||
for (auto const& test : test_data) {
|
for (auto const& test : test_data) {
|
||||||
auto time_zone = Unicode::format_time_zone(test.locale, test.time_zone, test.style, sep_19_2022);
|
auto time_zone = Locale::format_time_zone(test.locale, test.time_zone, test.style, sep_19_2022);
|
||||||
EXPECT_EQ(time_zone, test.expected_result);
|
EXPECT_EQ(time_zone, test.expected_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,52 +137,52 @@ TEST_CASE(format_time_zone_offset)
|
||||||
|
|
||||||
struct TestData {
|
struct TestData {
|
||||||
StringView locale;
|
StringView locale;
|
||||||
Unicode::CalendarPatternStyle style;
|
Locale::CalendarPatternStyle style;
|
||||||
AK::Time time;
|
AK::Time time;
|
||||||
StringView time_zone;
|
StringView time_zone;
|
||||||
StringView expected_result;
|
StringView expected_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto test_data = Array {
|
constexpr auto test_data = Array {
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortOffset, {}, "UTC"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortOffset, {}, "UTC"sv, "GMT"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongOffset, {}, "UTC"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongOffset, {}, "UTC"sv, "GMT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortOffset, {}, "UTC"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortOffset, {}, "UTC"sv, "غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongOffset, {}, "UTC"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongOffset, {}, "UTC"sv, "غرينتش"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_1833, "America/Los_Angeles"sv, "GMT-7:52:58"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_1833, "America/Los_Angeles"sv, "GMT-7:52:58"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_2022, "America/Los_Angeles"sv, "GMT-8"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_2022, "America/Los_Angeles"sv, "GMT-8"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_1833, "America/Los_Angeles"sv, "GMT-07:52:58"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_1833, "America/Los_Angeles"sv, "GMT-07:52:58"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_2022, "America/Los_Angeles"sv, "GMT-08:00"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_2022, "America/Los_Angeles"sv, "GMT-08:00"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_1833, "America/Los_Angeles"sv, "غرينتش-٧:٥٢:٥٨"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_1833, "America/Los_Angeles"sv, "غرينتش-٧:٥٢:٥٨"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_2022, "America/Los_Angeles"sv, "غرينتش-٨"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_2022, "America/Los_Angeles"sv, "غرينتش-٨"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_1833, "America/Los_Angeles"sv, "غرينتش-٠٧:٥٢:٥٨"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_1833, "America/Los_Angeles"sv, "غرينتش-٠٧:٥٢:٥٨"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_2022, "America/Los_Angeles"sv, "غرينتش-٠٨:٠٠"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_2022, "America/Los_Angeles"sv, "غرينتش-٠٨:٠٠"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_1833, "Europe/London"sv, "GMT-0:01:15"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_1833, "Europe/London"sv, "GMT-0:01:15"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_2022, "Europe/London"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_2022, "Europe/London"sv, "GMT"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_1833, "Europe/London"sv, "GMT-00:01:15"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_1833, "Europe/London"sv, "GMT-00:01:15"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_2022, "Europe/London"sv, "GMT"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_2022, "Europe/London"sv, "GMT"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_1833, "Europe/London"sv, "غرينتش-٠:٠١:١٥"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_1833, "Europe/London"sv, "غرينتش-٠:٠١:١٥"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_2022, "Europe/London"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_2022, "Europe/London"sv, "غرينتش"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_1833, "Europe/London"sv, "غرينتش-٠٠:٠١:١٥"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_1833, "Europe/London"sv, "غرينتش-٠٠:٠١:١٥"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_2022, "Europe/London"sv, "غرينتش"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_2022, "Europe/London"sv, "غرينتش"sv },
|
||||||
|
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_1833, "Asia/Kathmandu"sv, "GMT+5:41:16"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_1833, "Asia/Kathmandu"sv, "GMT+5:41:16"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_2022, "Asia/Kathmandu"sv, "GMT+5:45"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_2022, "Asia/Kathmandu"sv, "GMT+5:45"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_1833, "Asia/Kathmandu"sv, "GMT+05:41:16"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_1833, "Asia/Kathmandu"sv, "GMT+05:41:16"sv },
|
||||||
TestData { "en"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_2022, "Asia/Kathmandu"sv, "GMT+05:45"sv },
|
TestData { "en"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_2022, "Asia/Kathmandu"sv, "GMT+05:45"sv },
|
||||||
|
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_1833, "Asia/Kathmandu"sv, "غرينتش+٥:٤١:١٦"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_1833, "Asia/Kathmandu"sv, "غرينتش+٥:٤١:١٦"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::ShortOffset, jan_1_2022, "Asia/Kathmandu"sv, "غرينتش+٥:٤٥"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::ShortOffset, jan_1_2022, "Asia/Kathmandu"sv, "غرينتش+٥:٤٥"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_1833, "Asia/Kathmandu"sv, "غرينتش+٠٥:٤١:١٦"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_1833, "Asia/Kathmandu"sv, "غرينتش+٠٥:٤١:١٦"sv },
|
||||||
TestData { "ar"sv, Unicode::CalendarPatternStyle::LongOffset, jan_1_2022, "Asia/Kathmandu"sv, "غرينتش+٠٥:٤٥"sv },
|
TestData { "ar"sv, Locale::CalendarPatternStyle::LongOffset, jan_1_2022, "Asia/Kathmandu"sv, "غرينتش+٠٥:٤٥"sv },
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto const& test : test_data) {
|
for (auto const& test : test_data) {
|
||||||
auto time_zone = Unicode::format_time_zone(test.locale, test.time_zone, test.style, test.time);
|
auto time_zone = Locale::format_time_zone(test.locale, test.time_zone, test.style, test.time);
|
||||||
EXPECT_EQ(time_zone, test.expected_result);
|
EXPECT_EQ(time_zone, test.expected_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,91 +10,91 @@
|
||||||
|
|
||||||
TEST_CASE(is_unicode_language_subtag)
|
TEST_CASE(is_unicode_language_subtag)
|
||||||
{
|
{
|
||||||
EXPECT(Unicode::is_unicode_language_subtag("aa"sv));
|
EXPECT(Locale::is_unicode_language_subtag("aa"sv));
|
||||||
EXPECT(Unicode::is_unicode_language_subtag("aaa"sv));
|
EXPECT(Locale::is_unicode_language_subtag("aaa"sv));
|
||||||
EXPECT(Unicode::is_unicode_language_subtag("aaaaa"sv));
|
EXPECT(Locale::is_unicode_language_subtag("aaaaa"sv));
|
||||||
EXPECT(Unicode::is_unicode_language_subtag("aaaaaa"sv));
|
EXPECT(Locale::is_unicode_language_subtag("aaaaaa"sv));
|
||||||
EXPECT(Unicode::is_unicode_language_subtag("aaaaaaa"sv));
|
EXPECT(Locale::is_unicode_language_subtag("aaaaaaa"sv));
|
||||||
EXPECT(Unicode::is_unicode_language_subtag("aaaaaaaa"sv));
|
EXPECT(Locale::is_unicode_language_subtag("aaaaaaaa"sv));
|
||||||
|
|
||||||
EXPECT(!Unicode::is_unicode_language_subtag(""sv));
|
EXPECT(!Locale::is_unicode_language_subtag(""sv));
|
||||||
EXPECT(!Unicode::is_unicode_language_subtag("a"sv));
|
EXPECT(!Locale::is_unicode_language_subtag("a"sv));
|
||||||
EXPECT(!Unicode::is_unicode_language_subtag("aaaa"sv));
|
EXPECT(!Locale::is_unicode_language_subtag("aaaa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_language_subtag("aaaaaaaaa"sv));
|
EXPECT(!Locale::is_unicode_language_subtag("aaaaaaaaa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_language_subtag("123"sv));
|
EXPECT(!Locale::is_unicode_language_subtag("123"sv));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE(is_unicode_script_subtag)
|
TEST_CASE(is_unicode_script_subtag)
|
||||||
{
|
{
|
||||||
EXPECT(Unicode::is_unicode_script_subtag("aaaa"sv));
|
EXPECT(Locale::is_unicode_script_subtag("aaaa"sv));
|
||||||
|
|
||||||
EXPECT(!Unicode::is_unicode_script_subtag(""sv));
|
EXPECT(!Locale::is_unicode_script_subtag(""sv));
|
||||||
EXPECT(!Unicode::is_unicode_script_subtag("a"sv));
|
EXPECT(!Locale::is_unicode_script_subtag("a"sv));
|
||||||
EXPECT(!Unicode::is_unicode_script_subtag("aa"sv));
|
EXPECT(!Locale::is_unicode_script_subtag("aa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_script_subtag("aaa"sv));
|
EXPECT(!Locale::is_unicode_script_subtag("aaa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_script_subtag("aaaaa"sv));
|
EXPECT(!Locale::is_unicode_script_subtag("aaaaa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_script_subtag("1234"sv));
|
EXPECT(!Locale::is_unicode_script_subtag("1234"sv));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE(is_unicode_region_subtag)
|
TEST_CASE(is_unicode_region_subtag)
|
||||||
{
|
{
|
||||||
EXPECT(Unicode::is_unicode_region_subtag("aa"sv));
|
EXPECT(Locale::is_unicode_region_subtag("aa"sv));
|
||||||
EXPECT(Unicode::is_unicode_region_subtag("123"sv));
|
EXPECT(Locale::is_unicode_region_subtag("123"sv));
|
||||||
|
|
||||||
EXPECT(!Unicode::is_unicode_region_subtag(""sv));
|
EXPECT(!Locale::is_unicode_region_subtag(""sv));
|
||||||
EXPECT(!Unicode::is_unicode_region_subtag("a"sv));
|
EXPECT(!Locale::is_unicode_region_subtag("a"sv));
|
||||||
EXPECT(!Unicode::is_unicode_region_subtag("aaa"sv));
|
EXPECT(!Locale::is_unicode_region_subtag("aaa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_region_subtag("12"sv));
|
EXPECT(!Locale::is_unicode_region_subtag("12"sv));
|
||||||
EXPECT(!Unicode::is_unicode_region_subtag("12a"sv));
|
EXPECT(!Locale::is_unicode_region_subtag("12a"sv));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE(is_unicode_variant_subtag)
|
TEST_CASE(is_unicode_variant_subtag)
|
||||||
{
|
{
|
||||||
EXPECT(Unicode::is_unicode_variant_subtag("aaaaa"sv));
|
EXPECT(Locale::is_unicode_variant_subtag("aaaaa"sv));
|
||||||
EXPECT(Unicode::is_unicode_variant_subtag("aaaaaa"sv));
|
EXPECT(Locale::is_unicode_variant_subtag("aaaaaa"sv));
|
||||||
EXPECT(Unicode::is_unicode_variant_subtag("aaaaaaa"sv));
|
EXPECT(Locale::is_unicode_variant_subtag("aaaaaaa"sv));
|
||||||
EXPECT(Unicode::is_unicode_variant_subtag("aaaaaaaa"sv));
|
EXPECT(Locale::is_unicode_variant_subtag("aaaaaaaa"sv));
|
||||||
|
|
||||||
EXPECT(Unicode::is_unicode_variant_subtag("1aaa"sv));
|
EXPECT(Locale::is_unicode_variant_subtag("1aaa"sv));
|
||||||
EXPECT(Unicode::is_unicode_variant_subtag("12aa"sv));
|
EXPECT(Locale::is_unicode_variant_subtag("12aa"sv));
|
||||||
EXPECT(Unicode::is_unicode_variant_subtag("123a"sv));
|
EXPECT(Locale::is_unicode_variant_subtag("123a"sv));
|
||||||
EXPECT(Unicode::is_unicode_variant_subtag("1234"sv));
|
EXPECT(Locale::is_unicode_variant_subtag("1234"sv));
|
||||||
|
|
||||||
EXPECT(!Unicode::is_unicode_variant_subtag(""sv));
|
EXPECT(!Locale::is_unicode_variant_subtag(""sv));
|
||||||
EXPECT(!Unicode::is_unicode_variant_subtag("a"sv));
|
EXPECT(!Locale::is_unicode_variant_subtag("a"sv));
|
||||||
EXPECT(!Unicode::is_unicode_variant_subtag("aa"sv));
|
EXPECT(!Locale::is_unicode_variant_subtag("aa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_variant_subtag("aaa"sv));
|
EXPECT(!Locale::is_unicode_variant_subtag("aaa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_variant_subtag("aaaa"sv));
|
EXPECT(!Locale::is_unicode_variant_subtag("aaaa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_variant_subtag("aaaaaaaaa"sv));
|
EXPECT(!Locale::is_unicode_variant_subtag("aaaaaaaaa"sv));
|
||||||
EXPECT(!Unicode::is_unicode_variant_subtag("a234"sv));
|
EXPECT(!Locale::is_unicode_variant_subtag("a234"sv));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE(is_type_identifier)
|
TEST_CASE(is_type_identifier)
|
||||||
{
|
{
|
||||||
EXPECT(Unicode::is_type_identifier("aaaa"sv));
|
EXPECT(Locale::is_type_identifier("aaaa"sv));
|
||||||
EXPECT(Unicode::is_type_identifier("aaaa-bbbb"sv));
|
EXPECT(Locale::is_type_identifier("aaaa-bbbb"sv));
|
||||||
EXPECT(Unicode::is_type_identifier("aaaa-bbbb-cccc"sv));
|
EXPECT(Locale::is_type_identifier("aaaa-bbbb-cccc"sv));
|
||||||
|
|
||||||
EXPECT(Unicode::is_type_identifier("1aaa"sv));
|
EXPECT(Locale::is_type_identifier("1aaa"sv));
|
||||||
EXPECT(Unicode::is_type_identifier("12aa"sv));
|
EXPECT(Locale::is_type_identifier("12aa"sv));
|
||||||
EXPECT(Unicode::is_type_identifier("123a"sv));
|
EXPECT(Locale::is_type_identifier("123a"sv));
|
||||||
EXPECT(Unicode::is_type_identifier("1234"sv));
|
EXPECT(Locale::is_type_identifier("1234"sv));
|
||||||
|
|
||||||
EXPECT(!Unicode::is_type_identifier(""sv));
|
EXPECT(!Locale::is_type_identifier(""sv));
|
||||||
EXPECT(!Unicode::is_type_identifier("a"sv));
|
EXPECT(!Locale::is_type_identifier("a"sv));
|
||||||
EXPECT(!Unicode::is_type_identifier("aa"sv));
|
EXPECT(!Locale::is_type_identifier("aa"sv));
|
||||||
EXPECT(!Unicode::is_type_identifier("aaaaaaaaa"sv));
|
EXPECT(!Locale::is_type_identifier("aaaaaaaaa"sv));
|
||||||
EXPECT(!Unicode::is_type_identifier("aaaa-"sv));
|
EXPECT(!Locale::is_type_identifier("aaaa-"sv));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE(parse_unicode_locale_id)
|
TEST_CASE(parse_unicode_locale_id)
|
||||||
{
|
{
|
||||||
auto fail = [](StringView locale) {
|
auto fail = [](StringView locale) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
EXPECT(!locale_id.has_value());
|
EXPECT(!locale_id.has_value());
|
||||||
};
|
};
|
||||||
auto pass = [](StringView locale, Optional<StringView> expected_language, Optional<StringView> expected_script, Optional<StringView> expected_region, Vector<String> expected_variants) {
|
auto pass = [](StringView locale, Optional<StringView> expected_language, Optional<StringView> expected_script, Optional<StringView> expected_region, Vector<String> expected_variants) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
|
|
||||||
EXPECT_EQ(locale_id->language_id.language, expected_language);
|
EXPECT_EQ(locale_id->language_id.language, expected_language);
|
||||||
|
@ -121,15 +121,15 @@ TEST_CASE(parse_unicode_locale_id)
|
||||||
TEST_CASE(parse_unicode_locale_id_with_unicode_locale_extension)
|
TEST_CASE(parse_unicode_locale_id_with_unicode_locale_extension)
|
||||||
{
|
{
|
||||||
auto fail = [](StringView locale) {
|
auto fail = [](StringView locale) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
EXPECT(!locale_id.has_value());
|
EXPECT(!locale_id.has_value());
|
||||||
};
|
};
|
||||||
auto pass = [](StringView locale, Unicode::LocaleExtension const& expected_extension) {
|
auto pass = [](StringView locale, Locale::LocaleExtension const& expected_extension) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
EXPECT_EQ(locale_id->extensions.size(), 1u);
|
EXPECT_EQ(locale_id->extensions.size(), 1u);
|
||||||
|
|
||||||
auto const& actual_extension = locale_id->extensions[0].get<Unicode::LocaleExtension>();
|
auto const& actual_extension = locale_id->extensions[0].get<Locale::LocaleExtension>();
|
||||||
VERIFY(actual_extension.attributes == expected_extension.attributes);
|
VERIFY(actual_extension.attributes == expected_extension.attributes);
|
||||||
EXPECT_EQ(actual_extension.keywords.size(), expected_extension.keywords.size());
|
EXPECT_EQ(actual_extension.keywords.size(), expected_extension.keywords.size());
|
||||||
|
|
||||||
|
@ -167,15 +167,15 @@ TEST_CASE(parse_unicode_locale_id_with_unicode_locale_extension)
|
||||||
TEST_CASE(parse_unicode_locale_id_with_transformed_extension)
|
TEST_CASE(parse_unicode_locale_id_with_transformed_extension)
|
||||||
{
|
{
|
||||||
auto fail = [](StringView locale) {
|
auto fail = [](StringView locale) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
EXPECT(!locale_id.has_value());
|
EXPECT(!locale_id.has_value());
|
||||||
};
|
};
|
||||||
auto pass = [](StringView locale, Unicode::TransformedExtension const& expected_extension) {
|
auto pass = [](StringView locale, Locale::TransformedExtension const& expected_extension) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
EXPECT_EQ(locale_id->extensions.size(), 1u);
|
EXPECT_EQ(locale_id->extensions.size(), 1u);
|
||||||
|
|
||||||
auto const& actual_extension = locale_id->extensions[0].get<Unicode::TransformedExtension>();
|
auto const& actual_extension = locale_id->extensions[0].get<Locale::TransformedExtension>();
|
||||||
|
|
||||||
VERIFY(actual_extension.language.has_value() == expected_extension.language.has_value());
|
VERIFY(actual_extension.language.has_value() == expected_extension.language.has_value());
|
||||||
if (actual_extension.language.has_value()) {
|
if (actual_extension.language.has_value()) {
|
||||||
|
@ -216,32 +216,32 @@ TEST_CASE(parse_unicode_locale_id_with_transformed_extension)
|
||||||
fail("en-t-k0-aa"sv);
|
fail("en-t-k0-aa"sv);
|
||||||
fail("en-t-k0-aaaaaaaaa"sv);
|
fail("en-t-k0-aaaaaaaaa"sv);
|
||||||
|
|
||||||
pass("en-t-en"sv, { Unicode::LanguageID { false, "en"sv }, {} });
|
pass("en-t-en"sv, { Locale::LanguageID { false, "en"sv }, {} });
|
||||||
pass("en-t-en-latn"sv, { Unicode::LanguageID { false, "en"sv, "latn"sv }, {} });
|
pass("en-t-en-latn"sv, { Locale::LanguageID { false, "en"sv, "latn"sv }, {} });
|
||||||
pass("en-t-en-us"sv, { Unicode::LanguageID { false, "en"sv, {}, "us"sv }, {} });
|
pass("en-t-en-us"sv, { Locale::LanguageID { false, "en"sv, {}, "us"sv }, {} });
|
||||||
pass("en-t-en-latn-us"sv, { Unicode::LanguageID { false, "en"sv, "latn"sv, "us"sv }, {} });
|
pass("en-t-en-latn-us"sv, { Locale::LanguageID { false, "en"sv, "latn"sv, "us"sv }, {} });
|
||||||
pass("en-t-en-posix"sv, { Unicode::LanguageID { false, "en"sv, {}, {}, { "posix"sv } }, {} });
|
pass("en-t-en-posix"sv, { Locale::LanguageID { false, "en"sv, {}, {}, { "posix"sv } }, {} });
|
||||||
pass("en-t-en-latn-posix"sv, { Unicode::LanguageID { false, "en"sv, "latn"sv, {}, { "posix"sv } }, {} });
|
pass("en-t-en-latn-posix"sv, { Locale::LanguageID { false, "en"sv, "latn"sv, {}, { "posix"sv } }, {} });
|
||||||
pass("en-t-en-us-posix"sv, { Unicode::LanguageID { false, "en"sv, {}, "us"sv, { "posix"sv } }, {} });
|
pass("en-t-en-us-posix"sv, { Locale::LanguageID { false, "en"sv, {}, "us"sv, { "posix"sv } }, {} });
|
||||||
pass("en-t-en-latn-us-posix"sv, { Unicode::LanguageID { false, "en"sv, "latn"sv, "us"sv, { "posix"sv } }, {} });
|
pass("en-t-en-latn-us-posix"sv, { Locale::LanguageID { false, "en"sv, "latn"sv, "us"sv, { "posix"sv } }, {} });
|
||||||
pass("en-t-k0-aaa"sv, { {}, { { "k0"sv, { "aaa"sv } } } });
|
pass("en-t-k0-aaa"sv, { {}, { { "k0"sv, { "aaa"sv } } } });
|
||||||
pass("en-t-k0-aaa-bbbb"sv, { {}, { { "k0"sv, "aaa-bbbb"sv } } });
|
pass("en-t-k0-aaa-bbbb"sv, { {}, { { "k0"sv, "aaa-bbbb"sv } } });
|
||||||
pass("en-t-k0-aaa-k1-bbbb"sv, { {}, { { "k0"sv, { "aaa"sv } }, { "k1"sv, "bbbb"sv } } });
|
pass("en-t-k0-aaa-k1-bbbb"sv, { {}, { { "k0"sv, { "aaa"sv } }, { "k1"sv, "bbbb"sv } } });
|
||||||
pass("en-t-en-k0-aaa"sv, { Unicode::LanguageID { false, "en"sv }, { { "k0"sv, "aaa"sv } } });
|
pass("en-t-en-k0-aaa"sv, { Locale::LanguageID { false, "en"sv }, { { "k0"sv, "aaa"sv } } });
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE(parse_unicode_locale_id_with_other_extension)
|
TEST_CASE(parse_unicode_locale_id_with_other_extension)
|
||||||
{
|
{
|
||||||
auto fail = [](StringView locale) {
|
auto fail = [](StringView locale) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
EXPECT(!locale_id.has_value());
|
EXPECT(!locale_id.has_value());
|
||||||
};
|
};
|
||||||
auto pass = [](StringView locale, Unicode::OtherExtension const& expected_extension) {
|
auto pass = [](StringView locale, Locale::OtherExtension const& expected_extension) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
EXPECT_EQ(locale_id->extensions.size(), 1u);
|
EXPECT_EQ(locale_id->extensions.size(), 1u);
|
||||||
|
|
||||||
auto const& actual_extension = locale_id->extensions[0].get<Unicode::OtherExtension>();
|
auto const& actual_extension = locale_id->extensions[0].get<Locale::OtherExtension>();
|
||||||
EXPECT_EQ(actual_extension.key, expected_extension.key);
|
EXPECT_EQ(actual_extension.key, expected_extension.key);
|
||||||
EXPECT_EQ(actual_extension.value, expected_extension.value);
|
EXPECT_EQ(actual_extension.value, expected_extension.value);
|
||||||
};
|
};
|
||||||
|
@ -267,11 +267,11 @@ TEST_CASE(parse_unicode_locale_id_with_other_extension)
|
||||||
TEST_CASE(parse_unicode_locale_id_with_private_use_extension)
|
TEST_CASE(parse_unicode_locale_id_with_private_use_extension)
|
||||||
{
|
{
|
||||||
auto fail = [](StringView locale) {
|
auto fail = [](StringView locale) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
EXPECT(!locale_id.has_value());
|
EXPECT(!locale_id.has_value());
|
||||||
};
|
};
|
||||||
auto pass = [](StringView locale, Vector<String> const& expected_extension) {
|
auto pass = [](StringView locale, Vector<String> const& expected_extension) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
EXPECT_EQ(locale_id->private_use_extensions, expected_extension);
|
EXPECT_EQ(locale_id->private_use_extensions, expected_extension);
|
||||||
};
|
};
|
||||||
|
@ -291,10 +291,10 @@ TEST_CASE(parse_unicode_locale_id_with_private_use_extension)
|
||||||
TEST_CASE(canonicalize_unicode_locale_id)
|
TEST_CASE(canonicalize_unicode_locale_id)
|
||||||
{
|
{
|
||||||
auto test = [](StringView locale, StringView expected_canonical_locale) {
|
auto test = [](StringView locale, StringView expected_canonical_locale) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = Locale::parse_unicode_locale_id(locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
|
|
||||||
auto canonical_locale = Unicode::canonicalize_unicode_locale_id(*locale_id);
|
auto canonical_locale = Locale::canonicalize_unicode_locale_id(*locale_id);
|
||||||
EXPECT_EQ(*canonical_locale, expected_canonical_locale);
|
EXPECT_EQ(*canonical_locale, expected_canonical_locale);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -466,8 +466,8 @@ TEST_CASE(canonicalize_unicode_locale_id)
|
||||||
|
|
||||||
TEST_CASE(supports_locale_aliases)
|
TEST_CASE(supports_locale_aliases)
|
||||||
{
|
{
|
||||||
EXPECT(Unicode::is_locale_available("zh"sv));
|
EXPECT(Locale::is_locale_available("zh"sv));
|
||||||
EXPECT(Unicode::is_locale_available("zh-Hant"sv));
|
EXPECT(Locale::is_locale_available("zh-Hant"sv));
|
||||||
EXPECT(Unicode::is_locale_available("zh-TW"sv));
|
EXPECT(Locale::is_locale_available("zh-TW"sv));
|
||||||
EXPECT(Unicode::is_locale_available("zh-Hant-TW"sv));
|
EXPECT(Locale::is_locale_available("zh-Hant-TW"sv));
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,11 +125,11 @@ void TimeZoneSettingsWidget::set_time_zone_location()
|
||||||
{
|
{
|
||||||
m_time_zone_location = compute_time_zone_location();
|
m_time_zone_location = compute_time_zone_location();
|
||||||
|
|
||||||
auto locale = Unicode::default_locale();
|
auto locale = Locale::default_locale();
|
||||||
auto now = AK::Time::now_realtime();
|
auto now = AK::Time::now_realtime();
|
||||||
|
|
||||||
auto name = Unicode::format_time_zone(locale, m_time_zone, Unicode::CalendarPatternStyle::Long, now);
|
auto name = Locale::format_time_zone(locale, m_time_zone, Locale::CalendarPatternStyle::Long, now);
|
||||||
auto offset = Unicode::format_time_zone(locale, m_time_zone, Unicode::CalendarPatternStyle::LongOffset, now);
|
auto offset = Locale::format_time_zone(locale, m_time_zone, Locale::CalendarPatternStyle::LongOffset, now);
|
||||||
|
|
||||||
m_time_zone_text = String::formatted("{}\n({})", name, offset);
|
m_time_zone_text = String::formatted("{}\n({})", name, offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1147,7 +1147,7 @@ String time_zone_string(double time)
|
||||||
|
|
||||||
// Most implementations seem to prefer the long-form display name of the time zone. Not super important, but we may as well match that behavior.
|
// Most implementations seem to prefer the long-form display name of the time zone. Not super important, but we may as well match that behavior.
|
||||||
if (auto maybe_offset = TimeZone::get_time_zone_offset(tz_name, AK::Time::from_milliseconds(time)); maybe_offset.has_value()) {
|
if (auto maybe_offset = TimeZone::get_time_zone_offset(tz_name, AK::Time::from_milliseconds(time)); maybe_offset.has_value()) {
|
||||||
if (auto long_name = Unicode::get_time_zone_name(Unicode::default_locale(), tz_name, Unicode::CalendarPatternStyle::Long, maybe_offset->in_dst); long_name.has_value())
|
if (auto long_name = Locale::get_time_zone_name(Locale::default_locale(), tz_name, Locale::CalendarPatternStyle::Long, maybe_offset->in_dst); long_name.has_value())
|
||||||
tz_name = long_name.release_value();
|
tz_name = long_name.release_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
namespace JS::Intl {
|
namespace JS::Intl {
|
||||||
|
|
||||||
// 6.2.2 IsStructurallyValidLanguageTag ( locale ), https://tc39.es/ecma402/#sec-isstructurallyvalidlanguagetag
|
// 6.2.2 IsStructurallyValidLanguageTag ( locale ), https://tc39.es/ecma402/#sec-isstructurallyvalidlanguagetag
|
||||||
Optional<Unicode::LocaleID> is_structurally_valid_language_tag(StringView locale)
|
Optional<::Locale::LocaleID> is_structurally_valid_language_tag(StringView locale)
|
||||||
{
|
{
|
||||||
auto contains_duplicate_variant = [](auto& variants) {
|
auto contains_duplicate_variant = [](auto& variants) {
|
||||||
if (variants.is_empty())
|
if (variants.is_empty())
|
||||||
|
@ -39,7 +39,7 @@ Optional<Unicode::LocaleID> is_structurally_valid_language_tag(StringView locale
|
||||||
// IsStructurallyValidLanguageTag returns true if all of the following conditions hold, false otherwise:
|
// IsStructurallyValidLanguageTag returns true if all of the following conditions hold, false otherwise:
|
||||||
|
|
||||||
// locale can be generated from the EBNF grammar for unicode_locale_id in Unicode Technical Standard #35 LDML § 3.2 Unicode Locale Identifier;
|
// locale can be generated from the EBNF grammar for unicode_locale_id in Unicode Technical Standard #35 LDML § 3.2 Unicode Locale Identifier;
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = ::Locale::parse_unicode_locale_id(locale);
|
||||||
if (!locale_id.has_value())
|
if (!locale_id.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ Optional<Unicode::LocaleID> is_structurally_valid_language_tag(StringView locale
|
||||||
// contains at most one unicode_locale_extensions component,
|
// contains at most one unicode_locale_extensions component,
|
||||||
// contains at most one transformed_extensions component, and
|
// contains at most one transformed_extensions component, and
|
||||||
char key = extension.visit(
|
char key = extension.visit(
|
||||||
[](Unicode::LocaleExtension const&) { return 'u'; },
|
[](::Locale::LocaleExtension const&) { return 'u'; },
|
||||||
[](Unicode::TransformedExtension const&) { return 't'; },
|
[](::Locale::TransformedExtension const&) { return 't'; },
|
||||||
[](Unicode::OtherExtension const& ext) { return static_cast<char>(to_ascii_lowercase(ext.key)); });
|
[](::Locale::OtherExtension const& ext) { return static_cast<char>(to_ascii_lowercase(ext.key)); });
|
||||||
|
|
||||||
if (unique_keys.contains_slow(key))
|
if (unique_keys.contains_slow(key))
|
||||||
return {};
|
return {};
|
||||||
|
@ -69,7 +69,7 @@ Optional<Unicode::LocaleID> is_structurally_valid_language_tag(StringView locale
|
||||||
|
|
||||||
// if a transformed_extensions component that contains a tlang component is present, then
|
// if a transformed_extensions component that contains a tlang component is present, then
|
||||||
// the tlang component contains no duplicate unicode_variant_subtag subtags.
|
// the tlang component contains no duplicate unicode_variant_subtag subtags.
|
||||||
if (auto* transformed = extension.get_pointer<Unicode::TransformedExtension>()) {
|
if (auto* transformed = extension.get_pointer<::Locale::TransformedExtension>()) {
|
||||||
auto& language = transformed->language;
|
auto& language = transformed->language;
|
||||||
if (language.has_value() && contains_duplicate_variant(language->variants))
|
if (language.has_value() && contains_duplicate_variant(language->variants))
|
||||||
return {};
|
return {};
|
||||||
|
@ -80,7 +80,7 @@ Optional<Unicode::LocaleID> is_structurally_valid_language_tag(StringView locale
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6.2.3 CanonicalizeUnicodeLocaleId ( locale ), https://tc39.es/ecma402/#sec-canonicalizeunicodelocaleid
|
// 6.2.3 CanonicalizeUnicodeLocaleId ( locale ), https://tc39.es/ecma402/#sec-canonicalizeunicodelocaleid
|
||||||
String canonicalize_unicode_locale_id(Unicode::LocaleID& locale)
|
String canonicalize_unicode_locale_id(::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
|
||||||
|
@ -92,10 +92,10 @@ String canonicalize_unicode_locale_id(Unicode::LocaleID& locale)
|
||||||
// * only the first instance of any attribute duplicated in the input, and
|
// * only the first instance of any attribute duplicated in the input, and
|
||||||
// * only the first keyword for a given key in the input.
|
// * only the first keyword for a given key in the input.
|
||||||
for (auto& extension : locale.extensions) {
|
for (auto& extension : locale.extensions) {
|
||||||
if (!extension.has<Unicode::LocaleExtension>())
|
if (!extension.has<::Locale::LocaleExtension>())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto& locale_extension = extension.get<Unicode::LocaleExtension>();
|
auto& locale_extension = extension.get<::Locale::LocaleExtension>();
|
||||||
|
|
||||||
auto attributes = move(locale_extension.attributes);
|
auto attributes = move(locale_extension.attributes);
|
||||||
for (auto& attribute : attributes) {
|
for (auto& attribute : attributes) {
|
||||||
|
@ -114,7 +114,7 @@ String canonicalize_unicode_locale_id(Unicode::LocaleID& locale)
|
||||||
|
|
||||||
// 1. Let localeId be the string locale after performing the algorithm to transform it to canonical syntax per Unicode Technical Standard #35 LDML § 3.2.1 Canonical Unicode Locale Identifiers.
|
// 1. Let localeId be the string locale after performing the algorithm to transform it to canonical syntax per Unicode Technical Standard #35 LDML § 3.2.1 Canonical Unicode Locale Identifiers.
|
||||||
// 2. Let localeId be the string localeId after performing the algorithm to transform it to canonical form.
|
// 2. Let localeId be the string localeId after performing the algorithm to transform it to canonical form.
|
||||||
auto locale_id = Unicode::canonicalize_unicode_locale_id(locale);
|
auto locale_id = ::Locale::canonicalize_unicode_locale_id(locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
|
|
||||||
// 4. Return localeId.
|
// 4. Return localeId.
|
||||||
|
@ -271,7 +271,7 @@ Optional<String> best_available_locale(StringView locale)
|
||||||
// 2. Repeat,
|
// 2. Repeat,
|
||||||
while (true) {
|
while (true) {
|
||||||
// a. If availableLocales contains an element equal to candidate, return candidate.
|
// a. If availableLocales contains an element equal to candidate, return candidate.
|
||||||
if (Unicode::is_locale_available(candidate))
|
if (::Locale::is_locale_available(candidate))
|
||||||
return candidate;
|
return candidate;
|
||||||
|
|
||||||
// b. Let pos be the character index of the last occurrence of "-" (U+002D) within candidate. If that character does not occur, return undefined.
|
// b. Let pos be the character index of the last occurrence of "-" (U+002D) within candidate. If that character does not occur, return undefined.
|
||||||
|
@ -290,7 +290,7 @@ Optional<String> best_available_locale(StringView locale)
|
||||||
|
|
||||||
struct MatcherResult {
|
struct MatcherResult {
|
||||||
String locale;
|
String locale;
|
||||||
Vector<Unicode::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
|
||||||
|
@ -301,11 +301,11 @@ static MatcherResult lookup_matcher(Vector<String> const& requested_locales)
|
||||||
|
|
||||||
// 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) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = ::Locale::parse_unicode_locale_id(locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
|
|
||||||
// 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<Unicode::LocaleExtension>();
|
auto extensions = locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
||||||
auto no_extensions_locale = locale_id->to_string();
|
auto no_extensions_locale = locale_id->to_string();
|
||||||
|
|
||||||
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
||||||
|
@ -330,7 +330,7 @@ static MatcherResult lookup_matcher(Vector<String> const& requested_locales)
|
||||||
|
|
||||||
// 3. Let defLocale be ! DefaultLocale().
|
// 3. Let defLocale be ! DefaultLocale().
|
||||||
// 4. Set result.[[locale]] to defLocale.
|
// 4. Set result.[[locale]] to defLocale.
|
||||||
result.locale = Unicode::default_locale();
|
result.locale = ::Locale::default_locale();
|
||||||
|
|
||||||
// 5. Return result.
|
// 5. Return result.
|
||||||
return result;
|
return result;
|
||||||
|
@ -345,7 +345,7 @@ static MatcherResult best_fit_matcher(Vector<String> const& requested_locales)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
String insert_unicode_extension_and_canonicalize(Unicode::LocaleID locale, Unicode::LocaleExtension extension)
|
String insert_unicode_extension_and_canonicalize(::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
|
||||||
|
@ -403,13 +403,13 @@ LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptio
|
||||||
result.data_locale = found_locale;
|
result.data_locale = found_locale;
|
||||||
|
|
||||||
// 7. If r has an [[extension]] field, then
|
// 7. If r has an [[extension]] field, then
|
||||||
Vector<Unicode::Keyword> keywords;
|
Vector<::Locale::Keyword> keywords;
|
||||||
for (auto& extension : matcher_result.extensions) {
|
for (auto& extension : matcher_result.extensions) {
|
||||||
if (!extension.has<Unicode::LocaleExtension>())
|
if (!extension.has<::Locale::LocaleExtension>())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// a. Let components be ! UnicodeExtensionComponents(r.[[extension]]).
|
// a. Let components be ! UnicodeExtensionComponents(r.[[extension]]).
|
||||||
auto& components = extension.get<Unicode::LocaleExtension>();
|
auto& components = extension.get<::Locale::LocaleExtension>();
|
||||||
// b. Let keywords be components.[[Keywords]].
|
// b. Let keywords be components.[[Keywords]].
|
||||||
keywords = move(components.keywords);
|
keywords = move(components.keywords);
|
||||||
|
|
||||||
|
@ -417,7 +417,7 @@ LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptio
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Let supportedExtension be "-u".
|
// 8. Let supportedExtension be "-u".
|
||||||
Unicode::LocaleExtension supported_extension {};
|
::Locale::LocaleExtension supported_extension {};
|
||||||
|
|
||||||
// 9. For each element key of relevantExtensionKeys, do
|
// 9. For each element key of relevantExtensionKeys, do
|
||||||
for (auto const& key : relevant_extension_keys) {
|
for (auto const& key : relevant_extension_keys) {
|
||||||
|
@ -425,18 +425,18 @@ LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptio
|
||||||
// b. Assert: Type(foundLocaleData) is Record.
|
// b. Assert: Type(foundLocaleData) is Record.
|
||||||
// c. Let keyLocaleData be foundLocaleData.[[<key>]].
|
// c. Let keyLocaleData be foundLocaleData.[[<key>]].
|
||||||
// d. Assert: Type(keyLocaleData) is List.
|
// d. Assert: Type(keyLocaleData) is List.
|
||||||
auto key_locale_data = Unicode::get_available_keyword_values(key);
|
auto key_locale_data = ::Locale::get_available_keyword_values(key);
|
||||||
|
|
||||||
// e. Let value be keyLocaleData[0].
|
// e. Let value be keyLocaleData[0].
|
||||||
// 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<String> value;
|
Optional<String> value;
|
||||||
if (auto preference = Unicode::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 = *preference;
|
||||||
|
|
||||||
// g. Let supportedExtensionAddition be "".
|
// g. Let supportedExtensionAddition be "".
|
||||||
Optional<Unicode::Keyword> supported_extension_addition {};
|
Optional<::Locale::Keyword> supported_extension_addition {};
|
||||||
|
|
||||||
// h. If r has an [[extension]] field, then
|
// h. If r has an [[extension]] field, then
|
||||||
for (auto& entry : keywords) {
|
for (auto& entry : keywords) {
|
||||||
|
@ -456,7 +456,7 @@ LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptio
|
||||||
value = move(requested_value);
|
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 = Unicode::Keyword { key, move(entry.value) };
|
supported_extension_addition = ::Locale::Keyword { key, move(entry.value) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 4. Else if keyLocaleData contains "true", then
|
// 4. Else if keyLocaleData contains "true", then
|
||||||
|
@ -465,7 +465,7 @@ LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptio
|
||||||
value = "true"sv;
|
value = "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 = Unicode::Keyword { key, {} };
|
supported_extension_addition = ::Locale::Keyword { key, {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -480,7 +480,7 @@ LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptio
|
||||||
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.
|
||||||
Unicode::canonicalize_unicode_extension_values(key, *options_value, true);
|
::Locale::canonicalize_unicode_extension_values(key, *options_value, true);
|
||||||
|
|
||||||
// 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()) {
|
||||||
|
@ -511,7 +511,7 @@ LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptio
|
||||||
|
|
||||||
// 10. If the number of elements in supportedExtension is greater than 2, then
|
// 10. If the number of elements in supportedExtension is greater than 2, then
|
||||||
if (!supported_extension.keywords.is_empty()) {
|
if (!supported_extension.keywords.is_empty()) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(found_locale);
|
auto locale_id = ::Locale::parse_unicode_locale_id(found_locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
|
|
||||||
// a. Let foundLocale be InsertUnicodeExtensionAndCanonicalize(foundLocale, supportedExtension).
|
// a. Let foundLocale be InsertUnicodeExtensionAndCanonicalize(foundLocale, supportedExtension).
|
||||||
|
@ -533,11 +533,11 @@ Vector<String> lookup_supported_locales(Vector<String> const& requested_locales)
|
||||||
|
|
||||||
// 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) {
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(locale);
|
auto locale_id = ::Locale::parse_unicode_locale_id(locale);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
|
|
||||||
// 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<Unicode::LocaleExtension>();
|
locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
||||||
auto no_extensions_locale = locale_id->to_string();
|
auto no_extensions_locale = locale_id->to_string();
|
||||||
|
|
||||||
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
// b. Let availableLocale be ! BestAvailableLocale(availableLocales, noExtensionsLocale).
|
||||||
|
|
|
@ -79,13 +79,13 @@ struct PatternPartitionWithSource : public PatternPartition {
|
||||||
|
|
||||||
using StringOrBoolean = Variant<StringView, bool>;
|
using StringOrBoolean = Variant<StringView, bool>;
|
||||||
|
|
||||||
Optional<Unicode::LocaleID> is_structurally_valid_language_tag(StringView locale);
|
Optional<::Locale::LocaleID> is_structurally_valid_language_tag(StringView locale);
|
||||||
String canonicalize_unicode_locale_id(Unicode::LocaleID& locale);
|
String canonicalize_unicode_locale_id(::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<String>> canonicalize_locale_list(VM&, Value locales);
|
ThrowCompletionOr<Vector<String>> canonicalize_locale_list(VM&, Value locales);
|
||||||
Optional<String> best_available_locale(StringView locale);
|
Optional<String> best_available_locale(StringView locale);
|
||||||
String insert_unicode_extension_and_canonicalize(Unicode::LocaleID locale_id, Unicode::LocaleExtension extension);
|
String insert_unicode_extension_and_canonicalize(::Locale::LocaleID locale_id, ::Locale::LocaleExtension extension);
|
||||||
LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys);
|
LocaleResult resolve_locale(Vector<String> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys);
|
||||||
Vector<String> lookup_supported_locales(Vector<String> const& requested_locales);
|
Vector<String> lookup_supported_locales(Vector<String> const& requested_locales);
|
||||||
Vector<String> best_fit_supported_locales(Vector<String> const& requested_locales);
|
Vector<String> best_fit_supported_locales(Vector<String> const& requested_locales);
|
||||||
|
|
|
@ -49,7 +49,7 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
||||||
// 11. If collation is not undefined, then
|
// 11. If collation is not undefined, then
|
||||||
if (!collation.is_undefined()) {
|
if (!collation.is_undefined()) {
|
||||||
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(collation.as_string().string()))
|
if (!::Locale::is_type_identifier(collation.as_string().string()))
|
||||||
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.
|
||||||
|
|
|
@ -150,13 +150,13 @@ ThrowCompletionOr<Object*> to_date_time_options(VM& vm, Value options_value, Opt
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11.5.2 DateTimeStyleFormat ( dateStyle, timeStyle, styles ), https://tc39.es/ecma402/#sec-date-time-style-format
|
// 11.5.2 DateTimeStyleFormat ( dateStyle, timeStyle, styles ), https://tc39.es/ecma402/#sec-date-time-style-format
|
||||||
Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale, DateTimeFormat& date_time_format)
|
Optional<::Locale::CalendarPattern> date_time_style_format(StringView data_locale, DateTimeFormat& date_time_format)
|
||||||
{
|
{
|
||||||
Unicode::CalendarPattern time_format {};
|
::Locale::CalendarPattern time_format {};
|
||||||
Unicode::CalendarPattern date_format {};
|
::Locale::CalendarPattern date_format {};
|
||||||
|
|
||||||
auto get_pattern = [&](auto type, auto style) -> Optional<Unicode::CalendarPattern> {
|
auto get_pattern = [&](auto type, auto style) -> Optional<::Locale::CalendarPattern> {
|
||||||
auto formats = Unicode::get_calendar_format(data_locale, date_time_format.calendar(), type);
|
auto formats = ::Locale::get_calendar_format(data_locale, date_time_format.calendar(), type);
|
||||||
|
|
||||||
if (formats.has_value()) {
|
if (formats.has_value()) {
|
||||||
switch (style) {
|
switch (style) {
|
||||||
|
@ -178,7 +178,7 @@ Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale
|
||||||
if (date_time_format.has_time_style()) {
|
if (date_time_format.has_time_style()) {
|
||||||
// a. Assert: timeStyle is one of "full", "long", "medium", or "short".
|
// a. Assert: timeStyle is one of "full", "long", "medium", or "short".
|
||||||
// b. Let timeFormat be styles.[[TimeFormat]].[[<timeStyle>]].
|
// b. Let timeFormat be styles.[[TimeFormat]].[[<timeStyle>]].
|
||||||
auto pattern = get_pattern(Unicode::CalendarFormatType::Time, date_time_format.time_style());
|
auto pattern = get_pattern(::Locale::CalendarFormatType::Time, date_time_format.time_style());
|
||||||
if (!pattern.has_value())
|
if (!pattern.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale
|
||||||
if (date_time_format.has_date_style()) {
|
if (date_time_format.has_date_style()) {
|
||||||
// a. Assert: dateStyle is one of "full", "long", "medium", or "short".
|
// a. Assert: dateStyle is one of "full", "long", "medium", or "short".
|
||||||
// b. Let dateFormat be styles.[[DateFormat]].[[<dateStyle>]].
|
// b. Let dateFormat be styles.[[DateFormat]].[[<dateStyle>]].
|
||||||
auto pattern = get_pattern(Unicode::CalendarFormatType::Date, date_time_format.date_style());
|
auto pattern = get_pattern(::Locale::CalendarFormatType::Date, date_time_format.date_style());
|
||||||
if (!pattern.has_value())
|
if (!pattern.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale
|
||||||
// 3. If dateStyle is not undefined and timeStyle is not undefined, then
|
// 3. If dateStyle is not undefined and timeStyle is not undefined, then
|
||||||
if (date_time_format.has_date_style() && date_time_format.has_time_style()) {
|
if (date_time_format.has_date_style() && date_time_format.has_time_style()) {
|
||||||
// a. Let format be a new Record.
|
// a. Let format be a new Record.
|
||||||
Unicode::CalendarPattern format {};
|
::Locale::CalendarPattern format {};
|
||||||
|
|
||||||
// b. Add to format all fields from dateFormat except [[pattern]] and [[rangePatterns]].
|
// b. Add to format all fields from dateFormat except [[pattern]] and [[rangePatterns]].
|
||||||
format.for_each_calendar_field_zipped_with(date_format, [](auto& format_field, auto const& date_format_field, auto) {
|
format.for_each_calendar_field_zipped_with(date_format, [](auto& format_field, auto const& date_format_field, auto) {
|
||||||
|
@ -213,7 +213,7 @@ Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale
|
||||||
});
|
});
|
||||||
|
|
||||||
// d. Let connector be styles.[[DateTimeFormat]].[[<dateStyle>]].
|
// d. Let connector be styles.[[DateTimeFormat]].[[<dateStyle>]].
|
||||||
auto connector = get_pattern(Unicode::CalendarFormatType::DateTime, date_time_format.date_style());
|
auto connector = get_pattern(::Locale::CalendarFormatType::DateTime, date_time_format.date_style());
|
||||||
if (!connector.has_value())
|
if (!connector.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale
|
||||||
// NOTE: Our implementation of steps h-j differ from the spec. LibUnicode does not attach range patterns to the
|
// NOTE: Our implementation of steps h-j differ from the spec. LibUnicode does not attach range patterns to the
|
||||||
// format pattern; rather, lookups for range patterns are performed separately based on the format pattern's
|
// format pattern; rather, lookups for range patterns are performed separately based on the format pattern's
|
||||||
// skeleton. So we form a new skeleton here and defer the range pattern lookups.
|
// skeleton. So we form a new skeleton here and defer the range pattern lookups.
|
||||||
format.skeleton = Unicode::combine_skeletons(date_format.skeleton, time_format.skeleton);
|
format.skeleton = ::Locale::combine_skeletons(date_format.skeleton, time_format.skeleton);
|
||||||
|
|
||||||
// k. Return format.
|
// k. Return format.
|
||||||
return format;
|
return format;
|
||||||
|
@ -255,7 +255,7 @@ Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11.5.3 BasicFormatMatcher ( options, formats ), https://tc39.es/ecma402/#sec-basicformatmatcher
|
// 11.5.3 BasicFormatMatcher ( options, formats ), https://tc39.es/ecma402/#sec-basicformatmatcher
|
||||||
Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats)
|
Optional<::Locale::CalendarPattern> basic_format_matcher(::Locale::CalendarPattern const& options, Vector<::Locale::CalendarPattern> formats)
|
||||||
{
|
{
|
||||||
// 1. Let removalPenalty be 120.
|
// 1. Let removalPenalty be 120.
|
||||||
constexpr int removal_penalty = 120;
|
constexpr int removal_penalty = 120;
|
||||||
|
@ -282,7 +282,7 @@ Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern
|
||||||
int best_score = NumericLimits<int>::min();
|
int best_score = NumericLimits<int>::min();
|
||||||
|
|
||||||
// 9. Let bestFormat be undefined.
|
// 9. Let bestFormat be undefined.
|
||||||
Optional<Unicode::CalendarPattern> best_format;
|
Optional<::Locale::CalendarPattern> best_format;
|
||||||
|
|
||||||
// 10. Assert: Type(formats) is List.
|
// 10. Assert: Type(formats) is List.
|
||||||
// 11. For each element format of formats, do
|
// 11. For each element format of formats, do
|
||||||
|
@ -306,53 +306,53 @@ Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern
|
||||||
score -= removal_penalty;
|
score -= removal_penalty;
|
||||||
}
|
}
|
||||||
// v. Else if property is "timeZoneName", then
|
// v. Else if property is "timeZoneName", then
|
||||||
else if (type == Unicode::CalendarPattern::Field::TimeZoneName) {
|
else if (type == ::Locale::CalendarPattern::Field::TimeZoneName) {
|
||||||
// This is needed to avoid a compile error. Although we only enter this branch for TimeZoneName,
|
// This is needed to avoid a compile error. Although we only enter this branch for TimeZoneName,
|
||||||
// the lambda we are in will be generated with property types other than CalendarPatternStyle.
|
// the lambda we are in will be generated with property types other than CalendarPatternStyle.
|
||||||
auto compare_prop = [](auto prop, auto test) { return prop == static_cast<ValueType>(test); };
|
auto compare_prop = [](auto prop, auto test) { return prop == static_cast<ValueType>(test); };
|
||||||
|
|
||||||
// 1. If optionsProp is "short" or "shortGeneric", then
|
// 1. If optionsProp is "short" or "shortGeneric", then
|
||||||
if (compare_prop(options_prop, Unicode::CalendarPatternStyle::Short) || compare_prop(options_prop, Unicode::CalendarPatternStyle::ShortGeneric)) {
|
if (compare_prop(options_prop, ::Locale::CalendarPatternStyle::Short) || compare_prop(options_prop, ::Locale::CalendarPatternStyle::ShortGeneric)) {
|
||||||
// a. If formatProp is "shortOffset", decrease score by offsetPenalty.
|
// a. If formatProp is "shortOffset", decrease score by offsetPenalty.
|
||||||
if (compare_prop(format_prop, Unicode::CalendarPatternStyle::ShortOffset))
|
if (compare_prop(format_prop, ::Locale::CalendarPatternStyle::ShortOffset))
|
||||||
score -= offset_penalty;
|
score -= offset_penalty;
|
||||||
// b. Else if formatProp is "longOffset", decrease score by (offsetPenalty + shortMorePenalty).
|
// b. Else if formatProp is "longOffset", decrease score by (offsetPenalty + shortMorePenalty).
|
||||||
else if (compare_prop(format_prop, Unicode::CalendarPatternStyle::LongOffset))
|
else if (compare_prop(format_prop, ::Locale::CalendarPatternStyle::LongOffset))
|
||||||
score -= offset_penalty + short_more_penalty;
|
score -= offset_penalty + short_more_penalty;
|
||||||
// c. Else if optionsProp is "short" and formatProp is "long", decrease score by shortMorePenalty.
|
// c. Else if optionsProp is "short" and formatProp is "long", decrease score by shortMorePenalty.
|
||||||
else if (compare_prop(options_prop, Unicode::CalendarPatternStyle::Short) || compare_prop(format_prop, Unicode::CalendarPatternStyle::Long))
|
else if (compare_prop(options_prop, ::Locale::CalendarPatternStyle::Short) || compare_prop(format_prop, ::Locale::CalendarPatternStyle::Long))
|
||||||
score -= short_more_penalty;
|
score -= short_more_penalty;
|
||||||
// d. Else if optionsProp is "shortGeneric" and formatProp is "longGeneric", decrease score by shortMorePenalty.
|
// d. Else if optionsProp is "shortGeneric" and formatProp is "longGeneric", decrease score by shortMorePenalty.
|
||||||
else if (compare_prop(options_prop, Unicode::CalendarPatternStyle::ShortGeneric) || compare_prop(format_prop, Unicode::CalendarPatternStyle::LongGeneric))
|
else if (compare_prop(options_prop, ::Locale::CalendarPatternStyle::ShortGeneric) || compare_prop(format_prop, ::Locale::CalendarPatternStyle::LongGeneric))
|
||||||
score -= short_more_penalty;
|
score -= short_more_penalty;
|
||||||
// e. Else if optionsProp ≠ formatProp, decrease score by removalPenalty.
|
// e. Else if optionsProp ≠ formatProp, decrease score by removalPenalty.
|
||||||
else if (options_prop != format_prop)
|
else if (options_prop != format_prop)
|
||||||
score -= removal_penalty;
|
score -= removal_penalty;
|
||||||
}
|
}
|
||||||
// 2. Else if optionsProp is "shortOffset" and formatProp is "longOffset", decrease score by shortMorePenalty.
|
// 2. Else if optionsProp is "shortOffset" and formatProp is "longOffset", decrease score by shortMorePenalty.
|
||||||
else if (compare_prop(options_prop, Unicode::CalendarPatternStyle::ShortOffset) || compare_prop(format_prop, Unicode::CalendarPatternStyle::LongOffset)) {
|
else if (compare_prop(options_prop, ::Locale::CalendarPatternStyle::ShortOffset) || compare_prop(format_prop, ::Locale::CalendarPatternStyle::LongOffset)) {
|
||||||
score -= short_more_penalty;
|
score -= short_more_penalty;
|
||||||
}
|
}
|
||||||
// 3. Else if optionsProp is "long" or "longGeneric", then
|
// 3. Else if optionsProp is "long" or "longGeneric", then
|
||||||
else if (compare_prop(options_prop, Unicode::CalendarPatternStyle::Long) || compare_prop(options_prop, Unicode::CalendarPatternStyle::LongGeneric)) {
|
else if (compare_prop(options_prop, ::Locale::CalendarPatternStyle::Long) || compare_prop(options_prop, ::Locale::CalendarPatternStyle::LongGeneric)) {
|
||||||
// a. If formatProp is "longOffset", decrease score by offsetPenalty.
|
// a. If formatProp is "longOffset", decrease score by offsetPenalty.
|
||||||
if (compare_prop(format_prop, Unicode::CalendarPatternStyle::LongOffset))
|
if (compare_prop(format_prop, ::Locale::CalendarPatternStyle::LongOffset))
|
||||||
score -= offset_penalty;
|
score -= offset_penalty;
|
||||||
// b. Else if formatProp is "shortOffset", decrease score by (offsetPenalty + longLessPenalty).
|
// b. Else if formatProp is "shortOffset", decrease score by (offsetPenalty + longLessPenalty).
|
||||||
else if (compare_prop(format_prop, Unicode::CalendarPatternStyle::ShortOffset))
|
else if (compare_prop(format_prop, ::Locale::CalendarPatternStyle::ShortOffset))
|
||||||
score -= offset_penalty + long_less_penalty;
|
score -= offset_penalty + long_less_penalty;
|
||||||
// c. Else if optionsProp is "long" and formatProp is "short", decrease score by longLessPenalty.
|
// c. Else if optionsProp is "long" and formatProp is "short", decrease score by longLessPenalty.
|
||||||
else if (compare_prop(options_prop, Unicode::CalendarPatternStyle::Long) || compare_prop(format_prop, Unicode::CalendarPatternStyle::Short))
|
else if (compare_prop(options_prop, ::Locale::CalendarPatternStyle::Long) || compare_prop(format_prop, ::Locale::CalendarPatternStyle::Short))
|
||||||
score -= long_less_penalty;
|
score -= long_less_penalty;
|
||||||
// d. Else if optionsProp is "longGeneric" and formatProp is "shortGeneric", decrease score by longLessPenalty.
|
// d. Else if optionsProp is "longGeneric" and formatProp is "shortGeneric", decrease score by longLessPenalty.
|
||||||
else if (compare_prop(options_prop, Unicode::CalendarPatternStyle::LongGeneric) || compare_prop(format_prop, Unicode::CalendarPatternStyle::ShortGeneric))
|
else if (compare_prop(options_prop, ::Locale::CalendarPatternStyle::LongGeneric) || compare_prop(format_prop, ::Locale::CalendarPatternStyle::ShortGeneric))
|
||||||
score -= long_less_penalty;
|
score -= long_less_penalty;
|
||||||
// e. Else if optionsProp ≠ formatProp, decrease score by removalPenalty.
|
// e. Else if optionsProp ≠ formatProp, decrease score by removalPenalty.
|
||||||
else if (options_prop != format_prop)
|
else if (options_prop != format_prop)
|
||||||
score -= removal_penalty;
|
score -= removal_penalty;
|
||||||
}
|
}
|
||||||
// 4. Else if optionsProp is "longOffset" and formatProp is "shortOffset", decrease score by longLessPenalty.
|
// 4. Else if optionsProp is "longOffset" and formatProp is "shortOffset", decrease score by longLessPenalty.
|
||||||
else if (compare_prop(options_prop, Unicode::CalendarPatternStyle::LongOffset) || compare_prop(format_prop, Unicode::CalendarPatternStyle::ShortOffset)) {
|
else if (compare_prop(options_prop, ::Locale::CalendarPatternStyle::LongOffset) || compare_prop(format_prop, ::Locale::CalendarPatternStyle::ShortOffset)) {
|
||||||
score -= long_less_penalty;
|
score -= long_less_penalty;
|
||||||
}
|
}
|
||||||
// 5. Else if optionsProp ≠ formatProp, decrease score by removalPenalty.
|
// 5. Else if optionsProp ≠ formatProp, decrease score by removalPenalty.
|
||||||
|
@ -362,7 +362,7 @@ Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern
|
||||||
}
|
}
|
||||||
// vi. Else if optionsProp ≠ formatProp, then
|
// vi. Else if optionsProp ≠ formatProp, then
|
||||||
else if (options_prop != format_prop) {
|
else if (options_prop != format_prop) {
|
||||||
using ValuesType = Conditional<IsIntegral<ValueType>, AK::Array<u8, 3>, AK::Array<Unicode::CalendarPatternStyle, 5>>;
|
using ValuesType = Conditional<IsIntegral<ValueType>, AK::Array<u8, 3>, AK::Array<::Locale::CalendarPatternStyle, 5>>;
|
||||||
ValuesType values {};
|
ValuesType values {};
|
||||||
|
|
||||||
// 1. If property is "fractionalSecondDigits", then
|
// 1. If property is "fractionalSecondDigits", then
|
||||||
|
@ -374,11 +374,11 @@ Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern
|
||||||
else {
|
else {
|
||||||
// a. Let values be « "2-digit", "numeric", "narrow", "short", "long" ».
|
// a. Let values be « "2-digit", "numeric", "narrow", "short", "long" ».
|
||||||
values = {
|
values = {
|
||||||
Unicode::CalendarPatternStyle::TwoDigit,
|
::Locale::CalendarPatternStyle::TwoDigit,
|
||||||
Unicode::CalendarPatternStyle::Numeric,
|
::Locale::CalendarPatternStyle::Numeric,
|
||||||
Unicode::CalendarPatternStyle::Narrow,
|
::Locale::CalendarPatternStyle::Narrow,
|
||||||
Unicode::CalendarPatternStyle::Short,
|
::Locale::CalendarPatternStyle::Short,
|
||||||
Unicode::CalendarPatternStyle::Long,
|
::Locale::CalendarPatternStyle::Long,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,14 +430,14 @@ Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern
|
||||||
// differ by field length, we expand the field lengths here.
|
// differ by field length, we expand the field lengths here.
|
||||||
best_format->for_each_calendar_field_zipped_with(options, [&](auto& best_format_field, auto const& option_field, auto field_type) {
|
best_format->for_each_calendar_field_zipped_with(options, [&](auto& best_format_field, auto const& option_field, auto field_type) {
|
||||||
switch (field_type) {
|
switch (field_type) {
|
||||||
case Unicode::CalendarPattern::Field::FractionalSecondDigits:
|
case ::Locale::CalendarPattern::Field::FractionalSecondDigits:
|
||||||
if ((best_format_field.has_value() || best_format->second.has_value()) && option_field.has_value())
|
if ((best_format_field.has_value() || best_format->second.has_value()) && option_field.has_value())
|
||||||
best_format_field = option_field;
|
best_format_field = option_field;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Unicode::CalendarPattern::Field::Hour:
|
case ::Locale::CalendarPattern::Field::Hour:
|
||||||
case Unicode::CalendarPattern::Field::Minute:
|
case ::Locale::CalendarPattern::Field::Minute:
|
||||||
case Unicode::CalendarPattern::Field::Second:
|
case ::Locale::CalendarPattern::Field::Second:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -452,7 +452,7 @@ Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11.5.4 BestFitFormatMatcher ( options, formats ), https://tc39.es/ecma402/#sec-bestfitformatmatcher
|
// 11.5.4 BestFitFormatMatcher ( options, formats ), https://tc39.es/ecma402/#sec-bestfitformatmatcher
|
||||||
Optional<Unicode::CalendarPattern> best_fit_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats)
|
Optional<::Locale::CalendarPattern> best_fit_format_matcher(::Locale::CalendarPattern const& options, Vector<::Locale::CalendarPattern> formats)
|
||||||
{
|
{
|
||||||
// When the BestFitFormatMatcher abstract operation is called with two arguments options and formats, it performs
|
// When the BestFitFormatMatcher abstract operation is called with two arguments options and formats, it performs
|
||||||
// implementation dependent steps, which should return a set of component representations that a typical user of
|
// implementation dependent steps, which should return a set of component representations that a typical user of
|
||||||
|
@ -462,11 +462,11 @@ Optional<Unicode::CalendarPattern> best_fit_format_matcher(Unicode::CalendarPatt
|
||||||
|
|
||||||
struct StyleAndValue {
|
struct StyleAndValue {
|
||||||
StringView name {};
|
StringView name {};
|
||||||
Unicode::CalendarPatternStyle style {};
|
::Locale::CalendarPatternStyle style {};
|
||||||
i32 value { 0 };
|
i32 value { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
static Optional<StyleAndValue> find_calendar_field(StringView name, Unicode::CalendarPattern const& options, Unicode::CalendarPattern const* range_options, LocalTime const& local_time)
|
static Optional<StyleAndValue> find_calendar_field(StringView name, ::Locale::CalendarPattern const& options, ::Locale::CalendarPattern const* range_options, LocalTime const& local_time)
|
||||||
{
|
{
|
||||||
auto make_style_and_value = [](auto name, auto style, auto fallback_style, auto value) {
|
auto make_style_and_value = [](auto name, auto style, auto fallback_style, auto value) {
|
||||||
if (style.has_value())
|
if (style.has_value())
|
||||||
|
@ -483,7 +483,7 @@ static Optional<StyleAndValue> find_calendar_field(StringView name, Unicode::Cal
|
||||||
constexpr auto minute = "minute"sv;
|
constexpr auto minute = "minute"sv;
|
||||||
constexpr auto second = "second"sv;
|
constexpr auto second = "second"sv;
|
||||||
|
|
||||||
Optional<Unicode::CalendarPatternStyle> empty;
|
Optional<::Locale::CalendarPatternStyle> empty;
|
||||||
|
|
||||||
if (name == weekday)
|
if (name == weekday)
|
||||||
return make_style_and_value(weekday, range_options ? range_options->weekday : empty, *options.weekday, local_time.weekday);
|
return make_style_and_value(weekday, range_options ? range_options->weekday : empty, *options.weekday, local_time.weekday);
|
||||||
|
@ -504,7 +504,7 @@ static Optional<StyleAndValue> find_calendar_field(StringView name, Unicode::Cal
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Optional<StringView> resolve_day_period(StringView locale, StringView calendar, Unicode::CalendarPatternStyle style, Span<PatternPartition const> pattern_parts, LocalTime local_time)
|
static Optional<StringView> resolve_day_period(StringView locale, StringView calendar, ::Locale::CalendarPatternStyle style, Span<PatternPartition const> pattern_parts, LocalTime local_time)
|
||||||
{
|
{
|
||||||
// Use the "noon" day period if the locale has it, but only if the time is either exactly 12:00.00 or would be displayed as such.
|
// Use the "noon" day period if the locale has it, but only if the time is either exactly 12:00.00 or would be displayed as such.
|
||||||
if (local_time.hour == 12) {
|
if (local_time.hour == 12) {
|
||||||
|
@ -519,17 +519,17 @@ static Optional<StringView> resolve_day_period(StringView locale, StringView cal
|
||||||
});
|
});
|
||||||
|
|
||||||
if (it == pattern_parts.end()) {
|
if (it == pattern_parts.end()) {
|
||||||
auto noon_symbol = Unicode::get_calendar_day_period_symbol(locale, calendar, style, Unicode::DayPeriod::Noon);
|
auto noon_symbol = ::Locale::get_calendar_day_period_symbol(locale, calendar, style, ::Locale::DayPeriod::Noon);
|
||||||
if (noon_symbol.has_value())
|
if (noon_symbol.has_value())
|
||||||
return *noon_symbol;
|
return *noon_symbol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Unicode::get_calendar_day_period_symbol_for_hour(locale, calendar, style, local_time.hour);
|
return ::Locale::get_calendar_day_period_symbol_for_hour(locale, calendar, style, local_time.hour);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11.5.6 FormatDateTimePattern ( dateTimeFormat, patternParts, x, rangeFormatOptions ), https://tc39.es/ecma402/#sec-formatdatetimepattern
|
// 11.5.6 FormatDateTimePattern ( dateTimeFormat, patternParts, x, rangeFormatOptions ), https://tc39.es/ecma402/#sec-formatdatetimepattern
|
||||||
ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options)
|
ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, double time, ::Locale::CalendarPattern const* range_format_options)
|
||||||
{
|
{
|
||||||
auto& realm = *vm.current_realm();
|
auto& realm = *vm.current_realm();
|
||||||
|
|
||||||
|
@ -650,7 +650,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
||||||
// iii. Let fv be a String value representing v in the form given by f; the String value depends upon the implementation and the effective locale of dateTimeFormat.
|
// iii. Let fv be a String value representing v in the form given by f; the String value depends upon the implementation and the effective locale of dateTimeFormat.
|
||||||
// The String value may also depend on the value of the [[InDST]] field of tm if f is "short", "long", "shortOffset", or "longOffset".
|
// The String value may also depend on the value of the [[InDST]] field of tm if f is "short", "long", "shortOffset", or "longOffset".
|
||||||
// If the implementation does not have a localized representation of f, then use the String value of v itself.
|
// If the implementation does not have a localized representation of f, then use the String value of v itself.
|
||||||
auto formatted_value = Unicode::format_time_zone(data_locale, value, style, local_time.time_since_epoch());
|
auto formatted_value = ::Locale::format_time_zone(data_locale, value, style, local_time.time_since_epoch());
|
||||||
|
|
||||||
// iv. Append a new Record { [[Type]]: p, [[Value]]: fv } as the last element of the list result.
|
// iv. Append a new Record { [[Type]]: p, [[Value]]: fv } as the last element of the list result.
|
||||||
result.append({ "timeZoneName"sv, move(formatted_value) });
|
result.append({ "timeZoneName"sv, move(formatted_value) });
|
||||||
|
@ -680,17 +680,17 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
||||||
auto hour_cycle = date_time_format.hour_cycle();
|
auto hour_cycle = date_time_format.hour_cycle();
|
||||||
|
|
||||||
// vi. If p is "hour" and dateTimeFormat.[[HourCycle]] is "h11" or "h12", then
|
// vi. If p is "hour" and dateTimeFormat.[[HourCycle]] is "h11" or "h12", then
|
||||||
if ((hour_cycle == Unicode::HourCycle::H11) || (hour_cycle == Unicode::HourCycle::H12)) {
|
if ((hour_cycle == ::Locale::HourCycle::H11) || (hour_cycle == ::Locale::HourCycle::H12)) {
|
||||||
// 1. Let v be v modulo 12.
|
// 1. Let v be v modulo 12.
|
||||||
value = value % 12;
|
value = value % 12;
|
||||||
|
|
||||||
// 2. If v is 0 and dateTimeFormat.[[HourCycle]] is "h12", let v be 12.
|
// 2. If v is 0 and dateTimeFormat.[[HourCycle]] is "h12", let v be 12.
|
||||||
if ((value == 0) && (hour_cycle == Unicode::HourCycle::H12))
|
if ((value == 0) && (hour_cycle == ::Locale::HourCycle::H12))
|
||||||
value = 12;
|
value = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// vii. If p is "hour" and dateTimeFormat.[[HourCycle]] is "h24", then
|
// vii. If p is "hour" and dateTimeFormat.[[HourCycle]] is "h24", then
|
||||||
if (hour_cycle == Unicode::HourCycle::H24) {
|
if (hour_cycle == ::Locale::HourCycle::H24) {
|
||||||
// 1. If v is 0, let v be 24.
|
// 1. If v is 0, let v be 24.
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
value = 24;
|
value = 24;
|
||||||
|
@ -699,13 +699,13 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
||||||
|
|
||||||
switch (style) {
|
switch (style) {
|
||||||
// viii. If f is "numeric", then
|
// viii. If f is "numeric", then
|
||||||
case Unicode::CalendarPatternStyle::Numeric:
|
case ::Locale::CalendarPatternStyle::Numeric:
|
||||||
// 1. Let fv be FormatNumeric(nf, v).
|
// 1. Let fv be FormatNumeric(nf, v).
|
||||||
formatted_value = format_numeric(vm, *number_format, Value(value));
|
formatted_value = format_numeric(vm, *number_format, Value(value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ix. Else if f is "2-digit", then
|
// ix. Else if f is "2-digit", then
|
||||||
case Unicode::CalendarPatternStyle::TwoDigit:
|
case ::Locale::CalendarPatternStyle::TwoDigit:
|
||||||
// 1. Let fv be FormatNumeric(nf2, v).
|
// 1. Let fv be FormatNumeric(nf2, v).
|
||||||
formatted_value = format_numeric(vm, *number_format2, Value(value));
|
formatted_value = format_numeric(vm, *number_format2, Value(value));
|
||||||
|
|
||||||
|
@ -725,17 +725,17 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
||||||
// If p is "era" and rangeFormatOptions is undefined, then the String value may also depend on whether dateTimeFormat.[[Era]] is undefined.
|
// If p is "era" and rangeFormatOptions is undefined, then the String value may also depend on whether dateTimeFormat.[[Era]] is undefined.
|
||||||
// If p is "era" and rangeFormatOptions is not undefined, then the String value may also depend on whether rangeFormatOptions.[[era]] is undefined.
|
// If p is "era" and rangeFormatOptions is not undefined, then the String value may also depend on whether rangeFormatOptions.[[era]] is undefined.
|
||||||
// If the implementation does not have a localized representation of f, then use the String value of v itself.
|
// If the implementation does not have a localized representation of f, then use the String value of v itself.
|
||||||
case Unicode::CalendarPatternStyle::Narrow:
|
case ::Locale::CalendarPatternStyle::Narrow:
|
||||||
case Unicode::CalendarPatternStyle::Short:
|
case ::Locale::CalendarPatternStyle::Short:
|
||||||
case Unicode::CalendarPatternStyle::Long: {
|
case ::Locale::CalendarPatternStyle::Long: {
|
||||||
Optional<StringView> symbol;
|
Optional<StringView> symbol;
|
||||||
|
|
||||||
if (part == "era"sv)
|
if (part == "era"sv)
|
||||||
symbol = Unicode::get_calendar_era_symbol(data_locale, date_time_format.calendar(), style, static_cast<Unicode::Era>(value));
|
symbol = ::Locale::get_calendar_era_symbol(data_locale, date_time_format.calendar(), style, static_cast<::Locale::Era>(value));
|
||||||
else if (part == "month"sv)
|
else if (part == "month"sv)
|
||||||
symbol = Unicode::get_calendar_month_symbol(data_locale, date_time_format.calendar(), style, static_cast<Unicode::Month>(value - 1));
|
symbol = ::Locale::get_calendar_month_symbol(data_locale, date_time_format.calendar(), style, static_cast<::Locale::Month>(value - 1));
|
||||||
else if (part == "weekday"sv)
|
else if (part == "weekday"sv)
|
||||||
symbol = Unicode::get_calendar_weekday_symbol(data_locale, date_time_format.calendar(), style, static_cast<Unicode::Weekday>(value));
|
symbol = ::Locale::get_calendar_weekday_symbol(data_locale, date_time_format.calendar(), style, static_cast<::Locale::Weekday>(value));
|
||||||
|
|
||||||
formatted_value = symbol.value_or(String::number(value));
|
formatted_value = symbol.value_or(String::number(value));
|
||||||
break;
|
break;
|
||||||
|
@ -759,13 +759,13 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
||||||
// ii. If v is greater than 11, then
|
// ii. If v is greater than 11, then
|
||||||
if (value > 11) {
|
if (value > 11) {
|
||||||
// 1. Let fv be an implementation and locale dependent String value representing "post meridiem".
|
// 1. Let fv be an implementation and locale dependent String value representing "post meridiem".
|
||||||
auto symbol = Unicode::get_calendar_day_period_symbol(data_locale, date_time_format.calendar(), Unicode::CalendarPatternStyle::Short, Unicode::DayPeriod::PM);
|
auto symbol = ::Locale::get_calendar_day_period_symbol(data_locale, date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, ::Locale::DayPeriod::PM);
|
||||||
formatted_value = symbol.value_or("PM"sv);
|
formatted_value = symbol.value_or("PM"sv);
|
||||||
}
|
}
|
||||||
// iii. Else,
|
// iii. Else,
|
||||||
else {
|
else {
|
||||||
// 1. Let fv be an implementation and locale dependent String value representing "ante meridiem".
|
// 1. Let fv be an implementation and locale dependent String value representing "ante meridiem".
|
||||||
auto symbol = Unicode::get_calendar_day_period_symbol(data_locale, date_time_format.calendar(), Unicode::CalendarPatternStyle::Short, Unicode::DayPeriod::AM);
|
auto symbol = ::Locale::get_calendar_day_period_symbol(data_locale, date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, ::Locale::DayPeriod::AM);
|
||||||
formatted_value = symbol.value_or("AM"sv);
|
formatted_value = symbol.value_or("AM"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,7 +794,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
||||||
// Non-standard, TR-35 requires the decimal separator before injected {fractionalSecondDigits} partitions
|
// Non-standard, TR-35 requires the decimal separator before injected {fractionalSecondDigits} partitions
|
||||||
// to adhere to the selected locale. This depends on other generated data, so it is deferred to here.
|
// to adhere to the selected locale. This depends on other generated data, so it is deferred to here.
|
||||||
else if (part == "decimal"sv) {
|
else if (part == "decimal"sv) {
|
||||||
auto decimal_symbol = Unicode::get_number_system_symbol(data_locale, date_time_format.numbering_system(), Unicode::NumericSymbol::Decimal).value_or("."sv);
|
auto decimal_symbol = ::Locale::get_number_system_symbol(data_locale, date_time_format.numbering_system(), ::Locale::NumericSymbol::Decimal).value_or("."sv);
|
||||||
result.append({ "literal"sv, decimal_symbol });
|
result.append({ "literal"sv, decimal_symbol });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,30 +884,30 @@ template<typename Callback>
|
||||||
void for_each_range_pattern_field(LocalTime const& time1, LocalTime const& time2, Callback&& callback)
|
void for_each_range_pattern_field(LocalTime const& time1, LocalTime const& time2, Callback&& callback)
|
||||||
{
|
{
|
||||||
// Table 4: Range pattern fields, https://tc39.es/ecma402/#table-datetimeformat-rangepatternfields
|
// Table 4: Range pattern fields, https://tc39.es/ecma402/#table-datetimeformat-rangepatternfields
|
||||||
if (callback(static_cast<u8>(time1.era), static_cast<u8>(time2.era), Unicode::CalendarRangePattern::Field::Era) == IterationDecision::Break)
|
if (callback(static_cast<u8>(time1.era), static_cast<u8>(time2.era), ::Locale::CalendarRangePattern::Field::Era) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
if (callback(time1.year, time2.year, Unicode::CalendarRangePattern::Field::Year) == IterationDecision::Break)
|
if (callback(time1.year, time2.year, ::Locale::CalendarRangePattern::Field::Year) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
if (callback(time1.month, time2.month, Unicode::CalendarRangePattern::Field::Month) == IterationDecision::Break)
|
if (callback(time1.month, time2.month, ::Locale::CalendarRangePattern::Field::Month) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
if (callback(time1.day, time2.day, Unicode::CalendarRangePattern::Field::Day) == IterationDecision::Break)
|
if (callback(time1.day, time2.day, ::Locale::CalendarRangePattern::Field::Day) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
if (callback(time1.hour, time2.hour, Unicode::CalendarRangePattern::Field::AmPm) == IterationDecision::Break)
|
if (callback(time1.hour, time2.hour, ::Locale::CalendarRangePattern::Field::AmPm) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
if (callback(time1.hour, time2.hour, Unicode::CalendarRangePattern::Field::DayPeriod) == IterationDecision::Break)
|
if (callback(time1.hour, time2.hour, ::Locale::CalendarRangePattern::Field::DayPeriod) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
if (callback(time1.hour, time2.hour, Unicode::CalendarRangePattern::Field::Hour) == IterationDecision::Break)
|
if (callback(time1.hour, time2.hour, ::Locale::CalendarRangePattern::Field::Hour) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
if (callback(time1.minute, time2.minute, Unicode::CalendarRangePattern::Field::Minute) == IterationDecision::Break)
|
if (callback(time1.minute, time2.minute, ::Locale::CalendarRangePattern::Field::Minute) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
if (callback(time1.second, time2.second, Unicode::CalendarRangePattern::Field::Second) == IterationDecision::Break)
|
if (callback(time1.second, time2.second, ::Locale::CalendarRangePattern::Field::Second) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
if (callback(time1.millisecond, time2.millisecond, Unicode::CalendarRangePattern::Field::FractionalSecondDigits) == IterationDecision::Break)
|
if (callback(time1.millisecond, time2.millisecond, ::Locale::CalendarRangePattern::Field::FractionalSecondDigits) == IterationDecision::Break)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
ThrowCompletionOr<void> for_each_range_pattern_with_source(Unicode::CalendarRangePattern& pattern, Callback&& callback)
|
ThrowCompletionOr<void> for_each_range_pattern_with_source(::Locale::CalendarRangePattern& pattern, Callback&& callback)
|
||||||
{
|
{
|
||||||
TRY(callback(pattern.start_range, "startRange"sv));
|
TRY(callback(pattern.start_range, "startRange"sv));
|
||||||
TRY(callback(pattern.separator, "shared"sv));
|
TRY(callback(pattern.separator, "shared"sv));
|
||||||
|
@ -942,7 +942,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
||||||
auto range_patterns = date_time_format.range_patterns();
|
auto range_patterns = date_time_format.range_patterns();
|
||||||
|
|
||||||
// 8. Let rangePattern be undefined.
|
// 8. Let rangePattern be undefined.
|
||||||
Optional<Unicode::CalendarRangePattern> range_pattern;
|
Optional<::Locale::CalendarRangePattern> range_pattern;
|
||||||
|
|
||||||
// 9. Let dateFieldsPracticallyEqual be true.
|
// 9. Let dateFieldsPracticallyEqual be true.
|
||||||
bool date_fields_practically_equal = true;
|
bool date_fields_practically_equal = true;
|
||||||
|
@ -955,7 +955,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
||||||
// a. Let fieldName be the name given in the Range Pattern Field column of the row.
|
// a. Let fieldName be the name given in the Range Pattern Field column of the row.
|
||||||
|
|
||||||
// b. If rangePatterns has a field [[<fieldName>]], let rp be rangePatterns.[[<fieldName>]]; else let rp be undefined.
|
// b. If rangePatterns has a field [[<fieldName>]], let rp be rangePatterns.[[<fieldName>]]; else let rp be undefined.
|
||||||
Optional<Unicode::CalendarRangePattern> pattern;
|
Optional<::Locale::CalendarRangePattern> pattern;
|
||||||
for (auto const& range : range_patterns) {
|
for (auto const& range : range_patterns) {
|
||||||
if (range.field == field_name) {
|
if (range.field == field_name) {
|
||||||
pattern = range;
|
pattern = range;
|
||||||
|
@ -975,7 +975,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
||||||
|
|
||||||
switch (field_name) {
|
switch (field_name) {
|
||||||
// ii. If fieldName is equal to [[AmPm]], then
|
// ii. If fieldName is equal to [[AmPm]], then
|
||||||
case Unicode::CalendarRangePattern::Field::AmPm: {
|
case ::Locale::CalendarRangePattern::Field::AmPm: {
|
||||||
// 1. Let v1 be tm1.[[Hour]].
|
// 1. Let v1 be tm1.[[Hour]].
|
||||||
// 2. Let v2 be tm2.[[Hour]].
|
// 2. Let v2 be tm2.[[Hour]].
|
||||||
|
|
||||||
|
@ -988,12 +988,12 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// iii. Else if fieldName is equal to [[DayPeriod]], then
|
// iii. Else if fieldName is equal to [[DayPeriod]], then
|
||||||
case Unicode::CalendarRangePattern::Field::DayPeriod: {
|
case ::Locale::CalendarRangePattern::Field::DayPeriod: {
|
||||||
// 1. Let v1 be a String value representing the day period of tm1; the String value depends upon the implementation and the effective locale of dateTimeFormat.
|
// 1. Let v1 be a String value representing the day period of tm1; the String value depends upon the implementation and the effective locale of dateTimeFormat.
|
||||||
auto start_period = Unicode::get_calendar_day_period_symbol_for_hour(date_time_format.data_locale(), date_time_format.calendar(), Unicode::CalendarPatternStyle::Short, start_value);
|
auto start_period = ::Locale::get_calendar_day_period_symbol_for_hour(date_time_format.data_locale(), date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, start_value);
|
||||||
|
|
||||||
// 2. Let v2 be a String value representing the day period of tm2; the String value depends upon the implementation and the effective locale of dateTimeFormat.
|
// 2. Let v2 be a String value representing the day period of tm2; the String value depends upon the implementation and the effective locale of dateTimeFormat.
|
||||||
auto end_period = Unicode::get_calendar_day_period_symbol_for_hour(date_time_format.data_locale(), date_time_format.calendar(), Unicode::CalendarPatternStyle::Short, end_value);
|
auto end_period = ::Locale::get_calendar_day_period_symbol_for_hour(date_time_format.data_locale(), date_time_format.calendar(), ::Locale::CalendarPatternStyle::Short, end_value);
|
||||||
|
|
||||||
// 3. If v1 is not equal to v2, then
|
// 3. If v1 is not equal to v2, then
|
||||||
if (start_period != end_period) {
|
if (start_period != end_period) {
|
||||||
|
@ -1004,7 +1004,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// iv. Else if fieldName is equal to [[FractionalSecondDigits]], then
|
// iv. Else if fieldName is equal to [[FractionalSecondDigits]], then
|
||||||
case Unicode::CalendarRangePattern::Field::FractionalSecondDigits: {
|
case ::Locale::CalendarRangePattern::Field::FractionalSecondDigits: {
|
||||||
// 1. Let fractionalSecondDigits be dateTimeFormat.[[FractionalSecondDigits]].
|
// 1. Let fractionalSecondDigits be dateTimeFormat.[[FractionalSecondDigits]].
|
||||||
Optional<u8> fractional_second_digits;
|
Optional<u8> fractional_second_digits;
|
||||||
if (date_time_format.has_fractional_second_digits())
|
if (date_time_format.has_fractional_second_digits())
|
||||||
|
@ -1083,7 +1083,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
|
||||||
// 14. If rangePattern is undefined, then
|
// 14. If rangePattern is undefined, then
|
||||||
if (!range_pattern.has_value()) {
|
if (!range_pattern.has_value()) {
|
||||||
// a. Let rangePattern be rangePatterns.[[Default]].
|
// a. Let rangePattern be rangePatterns.[[Default]].
|
||||||
range_pattern = Unicode::get_calendar_default_range_format(date_time_format.data_locale(), date_time_format.calendar());
|
range_pattern = ::Locale::get_calendar_default_range_format(date_time_format.data_locale(), date_time_format.calendar());
|
||||||
|
|
||||||
// Non-standard, range_pattern will be empty if Unicode data generation is disabled.
|
// Non-standard, range_pattern will be empty if Unicode data generation is disabled.
|
||||||
if (!range_pattern.has_value())
|
if (!range_pattern.has_value())
|
||||||
|
@ -1217,7 +1217,7 @@ ThrowCompletionOr<LocalTime> to_local_time(VM& vm, double time, StringView calen
|
||||||
// WeekDay(tz) specified in es2022's Week Day.
|
// WeekDay(tz) specified in es2022's Week Day.
|
||||||
.weekday = week_day(zoned_time),
|
.weekday = week_day(zoned_time),
|
||||||
// Let year be YearFromTime(tz) specified in es2022's Year Number. If year is less than 0, return 'BC', else, return 'AD'.
|
// Let year be YearFromTime(tz) specified in es2022's Year Number. If year is less than 0, return 'BC', else, return 'AD'.
|
||||||
.era = year < 0 ? Unicode::Era::BC : Unicode::Era::AD,
|
.era = year < 0 ? ::Locale::Era::BC : ::Locale::Era::AD,
|
||||||
// YearFromTime(tz) specified in es2022's Year Number.
|
// YearFromTime(tz) specified in es2022's Year Number.
|
||||||
.year = year,
|
.year = year,
|
||||||
// undefined.
|
// undefined.
|
||||||
|
|
|
@ -21,10 +21,10 @@ namespace JS::Intl {
|
||||||
|
|
||||||
class DateTimeFormat final
|
class DateTimeFormat final
|
||||||
: public Object
|
: public Object
|
||||||
, public Unicode::CalendarPattern {
|
, public ::Locale::CalendarPattern {
|
||||||
JS_OBJECT(DateTimeFormat, Object);
|
JS_OBJECT(DateTimeFormat, Object);
|
||||||
|
|
||||||
using Patterns = Unicode::CalendarPattern;
|
using Patterns = ::Locale::CalendarPattern;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Style {
|
enum class Style {
|
||||||
|
@ -56,9 +56,9 @@ public:
|
||||||
void set_numbering_system(String 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(); }
|
||||||
Unicode::HourCycle hour_cycle() const { return *m_hour_cycle; }
|
::Locale::HourCycle hour_cycle() const { return *m_hour_cycle; }
|
||||||
StringView hour_cycle_string() const { return Unicode::hour_cycle_to_string(*m_hour_cycle); }
|
StringView hour_cycle_string() const { return ::Locale::hour_cycle_to_string(*m_hour_cycle); }
|
||||||
void set_hour_cycle(Unicode::HourCycle hour_cycle) { m_hour_cycle = hour_cycle; }
|
void set_hour_cycle(::Locale::HourCycle hour_cycle) { m_hour_cycle = hour_cycle; }
|
||||||
void clear_hour_cycle() { m_hour_cycle.clear(); }
|
void clear_hour_cycle() { m_hour_cycle.clear(); }
|
||||||
|
|
||||||
String const& time_zone() const { return m_time_zone; }
|
String const& time_zone() const { return m_time_zone; }
|
||||||
|
@ -77,51 +77,51 @@ public:
|
||||||
String const& pattern() const { return Patterns::pattern; };
|
String const& pattern() const { return Patterns::pattern; };
|
||||||
void set_pattern(String pattern) { Patterns::pattern = move(pattern); }
|
void set_pattern(String pattern) { Patterns::pattern = move(pattern); }
|
||||||
|
|
||||||
Span<Unicode::CalendarRangePattern const> range_patterns() const { return m_range_patterns.span(); };
|
Span<::Locale::CalendarRangePattern const> range_patterns() const { return m_range_patterns.span(); };
|
||||||
void set_range_patterns(Vector<Unicode::CalendarRangePattern> range_patterns) { m_range_patterns = move(range_patterns); }
|
void set_range_patterns(Vector<::Locale::CalendarRangePattern> range_patterns) { m_range_patterns = move(range_patterns); }
|
||||||
|
|
||||||
bool has_era() const { return Patterns::era.has_value(); }
|
bool has_era() const { return Patterns::era.has_value(); }
|
||||||
Unicode::CalendarPatternStyle era() const { return *Patterns::era; };
|
::Locale::CalendarPatternStyle era() const { return *Patterns::era; };
|
||||||
StringView era_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::era); }
|
StringView era_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::era); }
|
||||||
|
|
||||||
bool has_year() const { return Patterns::year.has_value(); }
|
bool has_year() const { return Patterns::year.has_value(); }
|
||||||
Unicode::CalendarPatternStyle year() const { return *Patterns::year; };
|
::Locale::CalendarPatternStyle year() const { return *Patterns::year; };
|
||||||
StringView year_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::year); }
|
StringView year_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::year); }
|
||||||
|
|
||||||
bool has_month() const { return Patterns::month.has_value(); }
|
bool has_month() const { return Patterns::month.has_value(); }
|
||||||
Unicode::CalendarPatternStyle month() const { return *Patterns::month; };
|
::Locale::CalendarPatternStyle month() const { return *Patterns::month; };
|
||||||
StringView month_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::month); }
|
StringView month_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::month); }
|
||||||
|
|
||||||
bool has_weekday() const { return Patterns::weekday.has_value(); }
|
bool has_weekday() const { return Patterns::weekday.has_value(); }
|
||||||
Unicode::CalendarPatternStyle weekday() const { return *Patterns::weekday; };
|
::Locale::CalendarPatternStyle weekday() const { return *Patterns::weekday; };
|
||||||
StringView weekday_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::weekday); }
|
StringView weekday_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::weekday); }
|
||||||
|
|
||||||
bool has_day() const { return Patterns::day.has_value(); }
|
bool has_day() const { return Patterns::day.has_value(); }
|
||||||
Unicode::CalendarPatternStyle day() const { return *Patterns::day; };
|
::Locale::CalendarPatternStyle day() const { return *Patterns::day; };
|
||||||
StringView day_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::day); }
|
StringView day_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::day); }
|
||||||
|
|
||||||
bool has_day_period() const { return Patterns::day_period.has_value(); }
|
bool has_day_period() const { return Patterns::day_period.has_value(); }
|
||||||
Unicode::CalendarPatternStyle day_period() const { return *Patterns::day_period; };
|
::Locale::CalendarPatternStyle day_period() const { return *Patterns::day_period; };
|
||||||
StringView day_period_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::day_period); }
|
StringView day_period_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::day_period); }
|
||||||
|
|
||||||
bool has_hour() const { return Patterns::hour.has_value(); }
|
bool has_hour() const { return Patterns::hour.has_value(); }
|
||||||
Unicode::CalendarPatternStyle hour() const { return *Patterns::hour; };
|
::Locale::CalendarPatternStyle hour() const { return *Patterns::hour; };
|
||||||
StringView hour_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::hour); }
|
StringView hour_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::hour); }
|
||||||
|
|
||||||
bool has_minute() const { return Patterns::minute.has_value(); }
|
bool has_minute() const { return Patterns::minute.has_value(); }
|
||||||
Unicode::CalendarPatternStyle minute() const { return *Patterns::minute; };
|
::Locale::CalendarPatternStyle minute() const { return *Patterns::minute; };
|
||||||
StringView minute_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::minute); }
|
StringView minute_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::minute); }
|
||||||
|
|
||||||
bool has_second() const { return Patterns::second.has_value(); }
|
bool has_second() const { return Patterns::second.has_value(); }
|
||||||
Unicode::CalendarPatternStyle second() const { return *Patterns::second; };
|
::Locale::CalendarPatternStyle second() const { return *Patterns::second; };
|
||||||
StringView second_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::second); }
|
StringView second_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::second); }
|
||||||
|
|
||||||
bool has_fractional_second_digits() const { return Patterns::fractional_second_digits.has_value(); }
|
bool has_fractional_second_digits() const { return Patterns::fractional_second_digits.has_value(); }
|
||||||
u8 fractional_second_digits() const { return *Patterns::fractional_second_digits; };
|
u8 fractional_second_digits() const { return *Patterns::fractional_second_digits; };
|
||||||
|
|
||||||
bool has_time_zone_name() const { return Patterns::time_zone_name.has_value(); }
|
bool has_time_zone_name() const { return Patterns::time_zone_name.has_value(); }
|
||||||
Unicode::CalendarPatternStyle time_zone_name() const { return *Patterns::time_zone_name; };
|
::Locale::CalendarPatternStyle time_zone_name() const { return *Patterns::time_zone_name; };
|
||||||
StringView time_zone_name_string() const { return Unicode::calendar_pattern_style_to_string(*Patterns::time_zone_name); }
|
StringView time_zone_name_string() const { return ::Locale::calendar_pattern_style_to_string(*Patterns::time_zone_name); }
|
||||||
|
|
||||||
NativeFunction* bound_format() const { return m_bound_format; }
|
NativeFunction* bound_format() const { return m_bound_format; }
|
||||||
void set_bound_format(NativeFunction* bound_format) { m_bound_format = bound_format; }
|
void set_bound_format(NativeFunction* bound_format) { m_bound_format = bound_format; }
|
||||||
|
@ -134,15 +134,15 @@ private:
|
||||||
|
|
||||||
virtual void visit_edges(Visitor&) override;
|
virtual void visit_edges(Visitor&) override;
|
||||||
|
|
||||||
String m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
String m_calendar; // [[Calendar]]
|
String m_calendar; // [[Calendar]]
|
||||||
String m_numbering_system; // [[NumberingSystem]]
|
String m_numbering_system; // [[NumberingSystem]]
|
||||||
Optional<Unicode::HourCycle> m_hour_cycle; // [[HourCycle]]
|
Optional<::Locale::HourCycle> m_hour_cycle; // [[HourCycle]]
|
||||||
String m_time_zone; // [[TimeZone]]
|
String m_time_zone; // [[TimeZone]]
|
||||||
Optional<Style> m_date_style; // [[DateStyle]]
|
Optional<Style> m_date_style; // [[DateStyle]]
|
||||||
Optional<Style> m_time_style; // [[TimeStyle]]
|
Optional<Style> m_time_style; // [[TimeStyle]]
|
||||||
Vector<Unicode::CalendarRangePattern> m_range_patterns; // [[RangePatterns]]
|
Vector<::Locale::CalendarRangePattern> m_range_patterns; // [[RangePatterns]]
|
||||||
NativeFunction* m_bound_format { nullptr }; // [[BoundFormat]]
|
NativeFunction* m_bound_format { nullptr }; // [[BoundFormat]]
|
||||||
|
|
||||||
String m_data_locale;
|
String m_data_locale;
|
||||||
};
|
};
|
||||||
|
@ -168,7 +168,7 @@ struct LocalTime {
|
||||||
}
|
}
|
||||||
|
|
||||||
int weekday { 0 }; // [[Weekday]]
|
int weekday { 0 }; // [[Weekday]]
|
||||||
Unicode::Era era {}; // [[Era]]
|
::Locale::Era era {}; // [[Era]]
|
||||||
i32 year { 0 }; // [[Year]]
|
i32 year { 0 }; // [[Year]]
|
||||||
Value related_year {}; // [[RelatedYear]]
|
Value related_year {}; // [[RelatedYear]]
|
||||||
Value year_name {}; // [[YearName]]
|
Value year_name {}; // [[YearName]]
|
||||||
|
@ -181,10 +181,10 @@ struct LocalTime {
|
||||||
};
|
};
|
||||||
|
|
||||||
ThrowCompletionOr<Object*> to_date_time_options(VM&, Value options_value, OptionRequired, OptionDefaults);
|
ThrowCompletionOr<Object*> to_date_time_options(VM&, Value options_value, OptionRequired, OptionDefaults);
|
||||||
Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale, DateTimeFormat& date_time_format);
|
Optional<::Locale::CalendarPattern> date_time_style_format(StringView data_locale, DateTimeFormat& date_time_format);
|
||||||
Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats);
|
Optional<::Locale::CalendarPattern> basic_format_matcher(::Locale::CalendarPattern const& options, Vector<::Locale::CalendarPattern> formats);
|
||||||
Optional<Unicode::CalendarPattern> best_fit_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats);
|
Optional<::Locale::CalendarPattern> best_fit_format_matcher(::Locale::CalendarPattern const& options, Vector<::Locale::CalendarPattern> formats);
|
||||||
ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM&, DateTimeFormat&, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options);
|
ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM&, DateTimeFormat&, Vector<PatternPartition> pattern_parts, double time, ::Locale::CalendarPattern const* range_format_options);
|
||||||
ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(VM&, DateTimeFormat&, double time);
|
ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(VM&, DateTimeFormat&, double time);
|
||||||
ThrowCompletionOr<String> format_date_time(VM&, DateTimeFormat&, double time);
|
ThrowCompletionOr<String> format_date_time(VM&, DateTimeFormat&, double time);
|
||||||
ThrowCompletionOr<Array*> format_date_time_to_parts(VM&, DateTimeFormat&, double time);
|
ThrowCompletionOr<Array*> format_date_time_to_parts(VM&, DateTimeFormat&, double time);
|
||||||
|
@ -194,7 +194,7 @@ ThrowCompletionOr<Array*> format_date_time_range_to_parts(VM&, DateTimeFormat&,
|
||||||
ThrowCompletionOr<LocalTime> to_local_time(VM&, double time, StringView calendar, StringView time_zone);
|
ThrowCompletionOr<LocalTime> to_local_time(VM&, double time, StringView calendar, StringView time_zone);
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
ThrowCompletionOr<void> for_each_calendar_field(VM& vm, Unicode::CalendarPattern& pattern, Callback&& callback)
|
ThrowCompletionOr<void> for_each_calendar_field(VM& vm, ::Locale::CalendarPattern& pattern, Callback&& callback)
|
||||||
{
|
{
|
||||||
constexpr auto narrow_short_long = AK::Array { "narrow"sv, "short"sv, "long"sv };
|
constexpr auto narrow_short_long = AK::Array { "narrow"sv, "short"sv, "long"sv };
|
||||||
constexpr auto two_digit_numeric = AK::Array { "2-digit"sv, "numeric"sv };
|
constexpr auto two_digit_numeric = AK::Array { "2-digit"sv, "numeric"sv };
|
||||||
|
|
|
@ -105,7 +105,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
// 7. If calendar is not undefined, then
|
// 7. If calendar is not undefined, then
|
||||||
if (!calendar.is_undefined()) {
|
if (!calendar.is_undefined()) {
|
||||||
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(calendar.as_string().string()))
|
if (!::Locale::is_type_identifier(calendar.as_string().string()))
|
||||||
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.
|
||||||
|
@ -118,7 +118,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
// 10. If numberingSystem is not undefined, then
|
// 10. If numberingSystem is not undefined, then
|
||||||
if (!numbering_system.is_undefined()) {
|
if (!numbering_system.is_undefined()) {
|
||||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
if (!::Locale::is_type_identifier(numbering_system.as_string().string()))
|
||||||
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.
|
||||||
|
@ -165,30 +165,30 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
|
|
||||||
// 23. Let dataLocaleData be localeData.[[<dataLocale>]].
|
// 23. Let dataLocaleData be localeData.[[<dataLocale>]].
|
||||||
// 24. Let hcDefault be dataLocaleData.[[hourCycle]].
|
// 24. Let hcDefault be dataLocaleData.[[hourCycle]].
|
||||||
auto default_hour_cycle = Unicode::get_default_regional_hour_cycle(data_locale);
|
auto default_hour_cycle = ::Locale::get_default_regional_hour_cycle(data_locale);
|
||||||
|
|
||||||
// Non-standard, default_hour_cycle will be empty if Unicode data generation is disabled.
|
// Non-standard, default_hour_cycle will be empty if Unicode data generation is disabled.
|
||||||
if (!default_hour_cycle.has_value())
|
if (!default_hour_cycle.has_value())
|
||||||
return &date_time_format;
|
return &date_time_format;
|
||||||
|
|
||||||
Optional<Unicode::HourCycle> hour_cycle_value;
|
Optional<::Locale::HourCycle> hour_cycle_value;
|
||||||
|
|
||||||
// 25. If hour12 is true, then
|
// 25. If hour12 is true, then
|
||||||
if (hour12.is_boolean() && hour12.as_bool()) {
|
if (hour12.is_boolean() && hour12.as_bool()) {
|
||||||
// a. If hcDefault is "h11" or "h23", let hc be "h11". Otherwise, let hc be "h12".
|
// a. If hcDefault is "h11" or "h23", let hc be "h11". Otherwise, let hc be "h12".
|
||||||
if ((default_hour_cycle == Unicode::HourCycle::H11) || (default_hour_cycle == Unicode::HourCycle::H23))
|
if ((default_hour_cycle == ::Locale::HourCycle::H11) || (default_hour_cycle == ::Locale::HourCycle::H23))
|
||||||
hour_cycle_value = Unicode::HourCycle::H11;
|
hour_cycle_value = ::Locale::HourCycle::H11;
|
||||||
else
|
else
|
||||||
hour_cycle_value = Unicode::HourCycle::H12;
|
hour_cycle_value = ::Locale::HourCycle::H12;
|
||||||
|
|
||||||
}
|
}
|
||||||
// 26. Else if hour12 is false, then
|
// 26. Else if hour12 is false, then
|
||||||
else if (hour12.is_boolean() && !hour12.as_bool()) {
|
else if (hour12.is_boolean() && !hour12.as_bool()) {
|
||||||
// a. If hcDefault is "h11" or "h23", let hc be "h23". Otherwise, let hc be "h24".
|
// a. If hcDefault is "h11" or "h23", let hc be "h23". Otherwise, let hc be "h24".
|
||||||
if ((default_hour_cycle == Unicode::HourCycle::H11) || (default_hour_cycle == Unicode::HourCycle::H23))
|
if ((default_hour_cycle == ::Locale::HourCycle::H11) || (default_hour_cycle == ::Locale::HourCycle::H23))
|
||||||
hour_cycle_value = Unicode::HourCycle::H23;
|
hour_cycle_value = ::Locale::HourCycle::H23;
|
||||||
else
|
else
|
||||||
hour_cycle_value = Unicode::HourCycle::H24;
|
hour_cycle_value = ::Locale::HourCycle::H24;
|
||||||
|
|
||||||
}
|
}
|
||||||
// 27. Else,
|
// 27. Else,
|
||||||
|
@ -198,7 +198,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
|
|
||||||
// b. Let hc be r.[[hc]].
|
// b. Let hc be r.[[hc]].
|
||||||
if (result.hc.has_value())
|
if (result.hc.has_value())
|
||||||
hour_cycle_value = Unicode::hour_cycle_from_string(*result.hc);
|
hour_cycle_value = ::Locale::hour_cycle_from_string(*result.hc);
|
||||||
|
|
||||||
// c. If hc is null, set hc to hcDefault.
|
// c. If hc is null, set hc to hcDefault.
|
||||||
if (!hour_cycle_value.has_value())
|
if (!hour_cycle_value.has_value())
|
||||||
|
@ -237,7 +237,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
date_time_format.set_time_zone(move(time_zone));
|
date_time_format.set_time_zone(move(time_zone));
|
||||||
|
|
||||||
// 33. Let formatOptions be a new Record.
|
// 33. Let formatOptions be a new Record.
|
||||||
Unicode::CalendarPattern format_options {};
|
::Locale::CalendarPattern format_options {};
|
||||||
|
|
||||||
// 34. Set formatOptions.[[hourCycle]] to hc.
|
// 34. Set formatOptions.[[hourCycle]] to hc.
|
||||||
format_options.hour_cycle = hour_cycle_value;
|
format_options.hour_cycle = hour_cycle_value;
|
||||||
|
@ -274,7 +274,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
|
|
||||||
// d. Set formatOptions.[[<prop>]] to value.
|
// d. Set formatOptions.[[<prop>]] to value.
|
||||||
if (!value.is_undefined()) {
|
if (!value.is_undefined()) {
|
||||||
option = Unicode::calendar_pattern_style_from_string(value.as_string().string());
|
option = ::Locale::calendar_pattern_style_from_string(value.as_string().string());
|
||||||
|
|
||||||
// e. If value is not undefined, then
|
// e. If value is not undefined, then
|
||||||
// i. Set hasExplicitFormatComponents to true.
|
// i. Set hasExplicitFormatComponents to true.
|
||||||
|
@ -302,7 +302,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
if (!time_style.is_undefined())
|
if (!time_style.is_undefined())
|
||||||
date_time_format.set_time_style(time_style.as_string().string());
|
date_time_format.set_time_style(time_style.as_string().string());
|
||||||
|
|
||||||
Optional<Unicode::CalendarPattern> best_format {};
|
Optional<::Locale::CalendarPattern> best_format {};
|
||||||
|
|
||||||
// 42. If dateStyle is not undefined or timeStyle is not undefined, then
|
// 42. If dateStyle is not undefined or timeStyle is not undefined, then
|
||||||
if (date_time_format.has_date_style() || date_time_format.has_time_style()) {
|
if (date_time_format.has_date_style() || date_time_format.has_time_style()) {
|
||||||
|
@ -319,7 +319,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
// 43. Else,
|
// 43. Else,
|
||||||
else {
|
else {
|
||||||
// a. Let formats be dataLocaleData.[[formats]].[[<resolvedCalendar>]].
|
// a. Let formats be dataLocaleData.[[formats]].[[<resolvedCalendar>]].
|
||||||
auto formats = Unicode::get_calendar_available_formats(data_locale, date_time_format.calendar());
|
auto formats = ::Locale::get_calendar_available_formats(data_locale, date_time_format.calendar());
|
||||||
|
|
||||||
// b. If matcher is "basic", then
|
// b. If matcher is "basic", then
|
||||||
if (matcher.as_string().string() == "basic"sv) {
|
if (matcher.as_string().string() == "basic"sv) {
|
||||||
|
@ -345,7 +345,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
});
|
});
|
||||||
|
|
||||||
String pattern;
|
String pattern;
|
||||||
Vector<Unicode::CalendarRangePattern> range_patterns;
|
Vector<::Locale::CalendarRangePattern> range_patterns;
|
||||||
|
|
||||||
// 45. If dateTimeFormat.[[Hour]] is undefined, then
|
// 45. If dateTimeFormat.[[Hour]] is undefined, then
|
||||||
if (!date_time_format.has_hour()) {
|
if (!date_time_format.has_hour()) {
|
||||||
|
@ -354,7 +354,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
}
|
}
|
||||||
|
|
||||||
// 46. If dateTimeformat.[[HourCycle]] is "h11" or "h12", then
|
// 46. If dateTimeformat.[[HourCycle]] is "h11" or "h12", then
|
||||||
if ((hour_cycle_value == Unicode::HourCycle::H11) || (hour_cycle_value == Unicode::HourCycle::H12)) {
|
if ((hour_cycle_value == ::Locale::HourCycle::H11) || (hour_cycle_value == ::Locale::HourCycle::H12)) {
|
||||||
// a. Let pattern be bestFormat.[[pattern12]].
|
// a. Let pattern be bestFormat.[[pattern12]].
|
||||||
if (best_format->pattern12.has_value()) {
|
if (best_format->pattern12.has_value()) {
|
||||||
pattern = best_format->pattern12.release_value();
|
pattern = best_format->pattern12.release_value();
|
||||||
|
@ -365,7 +365,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
}
|
}
|
||||||
|
|
||||||
// b. Let rangePatterns be bestFormat.[[rangePatterns12]].
|
// b. Let rangePatterns be bestFormat.[[rangePatterns12]].
|
||||||
range_patterns = Unicode::get_calendar_range12_formats(data_locale, date_time_format.calendar(), best_format->skeleton);
|
range_patterns = ::Locale::get_calendar_range12_formats(data_locale, date_time_format.calendar(), best_format->skeleton);
|
||||||
}
|
}
|
||||||
// 47. Else,
|
// 47. Else,
|
||||||
else {
|
else {
|
||||||
|
@ -373,7 +373,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
||||||
pattern = move(best_format->pattern);
|
pattern = move(best_format->pattern);
|
||||||
|
|
||||||
// b. Let rangePatterns be bestFormat.[[rangePatterns]].
|
// b. Let rangePatterns be bestFormat.[[rangePatterns]].
|
||||||
range_patterns = Unicode::get_calendar_range_formats(data_locale, date_time_format.calendar(), best_format->skeleton);
|
range_patterns = ::Locale::get_calendar_range_formats(data_locale, date_time_format.calendar(), best_format->skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 48. Set dateTimeFormat.[[Pattern]] to pattern.
|
// 48. Set dateTimeFormat.[[Pattern]] to pattern.
|
||||||
|
|
|
@ -180,12 +180,12 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
|
||||||
MUST(options->create_data_property_or_throw(vm.names.hourCycle, js_string(vm, date_time_format->hour_cycle_string())));
|
MUST(options->create_data_property_or_throw(vm.names.hourCycle, js_string(vm, date_time_format->hour_cycle_string())));
|
||||||
|
|
||||||
switch (date_time_format->hour_cycle()) {
|
switch (date_time_format->hour_cycle()) {
|
||||||
case Unicode::HourCycle::H11:
|
case ::Locale::HourCycle::H11:
|
||||||
case Unicode::HourCycle::H12:
|
case ::Locale::HourCycle::H12:
|
||||||
MUST(options->create_data_property_or_throw(vm.names.hour12, Value(true)));
|
MUST(options->create_data_property_or_throw(vm.names.hour12, Value(true)));
|
||||||
break;
|
break;
|
||||||
case Unicode::HourCycle::H23:
|
case ::Locale::HourCycle::H23:
|
||||||
case Unicode::HourCycle::H24:
|
case ::Locale::HourCycle::H24:
|
||||||
MUST(options->create_data_property_or_throw(vm.names.hour12, Value(false)));
|
MUST(options->create_data_property_or_throw(vm.names.hour12, Value(false)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
|
||||||
if constexpr (IsIntegral<ValueType>) {
|
if constexpr (IsIntegral<ValueType>) {
|
||||||
TRY(options->create_data_property_or_throw(property, Value(*option)));
|
TRY(options->create_data_property_or_throw(property, Value(*option)));
|
||||||
} else {
|
} else {
|
||||||
auto name = Unicode::calendar_pattern_style_to_string(*option);
|
auto name = ::Locale::calendar_pattern_style_to_string(*option);
|
||||||
TRY(options->create_data_property_or_throw(property, js_string(vm, name)));
|
TRY(options->create_data_property_or_throw(property, js_string(vm, name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(VM& vm, DisplayNames::
|
||||||
// 1. If type is "language", then
|
// 1. If type is "language", then
|
||||||
if (type == DisplayNames::Type::Language) {
|
if (type == DisplayNames::Type::Language) {
|
||||||
// a. If code does not match the unicode_language_id production, throw a RangeError exception.
|
// a. If code does not match the unicode_language_id production, throw a RangeError exception.
|
||||||
if (!Unicode::parse_unicode_language_id(code).has_value())
|
if (!::Locale::parse_unicode_language_id(code).has_value())
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "language"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "language"sv);
|
||||||
|
|
||||||
// b. If IsStructurallyValidLanguageTag(code) is false, throw a RangeError exception.
|
// b. If IsStructurallyValidLanguageTag(code) is false, throw a RangeError exception.
|
||||||
|
@ -122,7 +122,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(VM& vm, DisplayNames::
|
||||||
// 2. If type is "region", then
|
// 2. If type is "region", then
|
||||||
if (type == DisplayNames::Type::Region) {
|
if (type == DisplayNames::Type::Region) {
|
||||||
// a. If code does not match the unicode_region_subtag production, throw a RangeError exception.
|
// a. If code does not match the unicode_region_subtag production, throw a RangeError exception.
|
||||||
if (!Unicode::is_unicode_region_subtag(code))
|
if (!::Locale::is_unicode_region_subtag(code))
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "region"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "region"sv);
|
||||||
|
|
||||||
// b. Return the ASCII-uppercase of code.
|
// b. Return the ASCII-uppercase of code.
|
||||||
|
@ -132,7 +132,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(VM& vm, DisplayNames::
|
||||||
// 3. If type is "script", then
|
// 3. If type is "script", then
|
||||||
if (type == DisplayNames::Type::Script) {
|
if (type == DisplayNames::Type::Script) {
|
||||||
// a. If code does not match the unicode_script_subtag production, throw a RangeError exception.
|
// a. If code does not match the unicode_script_subtag production, throw a RangeError exception.
|
||||||
if (!Unicode::is_unicode_script_subtag(code))
|
if (!::Locale::is_unicode_script_subtag(code))
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "script"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "script"sv);
|
||||||
|
|
||||||
// Assert: The length of code is 4, and every code unit of code represents an ASCII letter (0x0041 through 0x005A and 0x0061 through 0x007A, both inclusive).
|
// Assert: The length of code is 4, and every code unit of code represents an ASCII letter (0x0041 through 0x005A and 0x0061 through 0x007A, both inclusive).
|
||||||
|
@ -148,7 +148,7 @@ ThrowCompletionOr<Value> canonical_code_for_display_names(VM& vm, DisplayNames::
|
||||||
// 4. If type is "calendar", then
|
// 4. If type is "calendar", then
|
||||||
if (type == DisplayNames::Type::Calendar) {
|
if (type == DisplayNames::Type::Calendar) {
|
||||||
// a. If code does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If code does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(code))
|
if (!::Locale::is_type_identifier(code))
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "calendar"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, code, "calendar"sv);
|
||||||
|
|
||||||
// b. If code uses any of the backwards compatibility syntax described in Unicode Technical Standard #35 LDML § 3.3 BCP 47 Conformance, throw a RangeError exception.
|
// b. If code uses any of the backwards compatibility syntax described in Unicode Technical Standard #35 LDML § 3.3 BCP 47 Conformance, throw a RangeError exception.
|
||||||
|
|
|
@ -44,9 +44,9 @@ public:
|
||||||
String const& locale() const { return m_locale; }
|
String const& locale() const { return m_locale; }
|
||||||
void set_locale(String locale) { m_locale = move(locale); }
|
void set_locale(String locale) { m_locale = move(locale); }
|
||||||
|
|
||||||
Unicode::Style style() const { return m_style; }
|
::Locale::Style style() const { return m_style; }
|
||||||
void set_style(StringView style) { m_style = Unicode::style_from_string(style); }
|
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
|
||||||
StringView style_string() const { return Unicode::style_to_string(m_style); }
|
StringView style_string() const { return ::Locale::style_to_string(m_style); }
|
||||||
|
|
||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
void set_type(StringView type);
|
void set_type(StringView type);
|
||||||
|
@ -64,11 +64,11 @@ public:
|
||||||
private:
|
private:
|
||||||
DisplayNames(Object& prototype);
|
DisplayNames(Object& prototype);
|
||||||
|
|
||||||
String m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
Unicode::Style m_style { Unicode::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]]
|
||||||
Optional<LanguageDisplay> m_language_display {}; // [[LanguageDisplay]]
|
Optional<LanguageDisplay> m_language_display {}; // [[LanguageDisplay]]
|
||||||
};
|
};
|
||||||
|
|
||||||
ThrowCompletionOr<Value> canonical_code_for_display_names(VM&, DisplayNames::Type, StringView code);
|
ThrowCompletionOr<Value> canonical_code_for_display_names(VM&, DisplayNames::Type, StringView code);
|
||||||
|
|
|
@ -140,7 +140,7 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesConstructor::supported_locales_of)
|
||||||
auto options = vm.argument(1);
|
auto options = vm.argument(1);
|
||||||
|
|
||||||
// 1. Let availableLocales be %DisplayNames%.[[AvailableLocales]].
|
// 1. Let availableLocales be %DisplayNames%.[[AvailableLocales]].
|
||||||
// No-op, availability of each requested locale is checked via Unicode::is_locale_available()
|
// No-op, availability of each requested locale is checked via ::Locale::is_locale_available()
|
||||||
|
|
||||||
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||||
auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
|
auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
|
||||||
|
|
|
@ -57,48 +57,48 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::of)
|
||||||
switch (display_names->type()) {
|
switch (display_names->type()) {
|
||||||
case DisplayNames::Type::Language:
|
case DisplayNames::Type::Language:
|
||||||
if (display_names->language_display() == DisplayNames::LanguageDisplay::Dialect) {
|
if (display_names->language_display() == DisplayNames::LanguageDisplay::Dialect) {
|
||||||
result = Unicode::get_locale_language_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_language_mapping(display_names->locale(), code.as_string().string());
|
||||||
if (result.has_value())
|
if (result.has_value())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto locale = is_structurally_valid_language_tag(code.as_string().string()); locale.has_value())
|
if (auto locale = is_structurally_valid_language_tag(code.as_string().string()); locale.has_value())
|
||||||
formatted_result = Unicode::format_locale_for_display(display_names->locale(), locale.release_value());
|
formatted_result = ::Locale::format_locale_for_display(display_names->locale(), locale.release_value());
|
||||||
break;
|
break;
|
||||||
case DisplayNames::Type::Region:
|
case DisplayNames::Type::Region:
|
||||||
result = Unicode::get_locale_territory_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_territory_mapping(display_names->locale(), code.as_string().string());
|
||||||
break;
|
break;
|
||||||
case DisplayNames::Type::Script:
|
case DisplayNames::Type::Script:
|
||||||
result = Unicode::get_locale_script_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_script_mapping(display_names->locale(), code.as_string().string());
|
||||||
break;
|
break;
|
||||||
case DisplayNames::Type::Currency:
|
case DisplayNames::Type::Currency:
|
||||||
switch (display_names->style()) {
|
switch (display_names->style()) {
|
||||||
case Unicode::Style::Long:
|
case ::Locale::Style::Long:
|
||||||
result = Unicode::get_locale_long_currency_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_long_currency_mapping(display_names->locale(), code.as_string().string());
|
||||||
break;
|
break;
|
||||||
case Unicode::Style::Short:
|
case ::Locale::Style::Short:
|
||||||
result = Unicode::get_locale_short_currency_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_short_currency_mapping(display_names->locale(), code.as_string().string());
|
||||||
break;
|
break;
|
||||||
case Unicode::Style::Narrow:
|
case ::Locale::Style::Narrow:
|
||||||
result = Unicode::get_locale_narrow_currency_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_narrow_currency_mapping(display_names->locale(), code.as_string().string());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DisplayNames::Type::Calendar:
|
case DisplayNames::Type::Calendar:
|
||||||
result = Unicode::get_locale_calendar_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_calendar_mapping(display_names->locale(), code.as_string().string());
|
||||||
break;
|
break;
|
||||||
case DisplayNames::Type::DateTimeField:
|
case DisplayNames::Type::DateTimeField:
|
||||||
switch (display_names->style()) {
|
switch (display_names->style()) {
|
||||||
case Unicode::Style::Long:
|
case ::Locale::Style::Long:
|
||||||
result = Unicode::get_locale_long_date_field_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_long_date_field_mapping(display_names->locale(), code.as_string().string());
|
||||||
break;
|
break;
|
||||||
case Unicode::Style::Short:
|
case ::Locale::Style::Short:
|
||||||
result = Unicode::get_locale_short_date_field_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_short_date_field_mapping(display_names->locale(), code.as_string().string());
|
||||||
break;
|
break;
|
||||||
case Unicode::Style::Narrow:
|
case ::Locale::Style::Narrow:
|
||||||
result = Unicode::get_locale_narrow_date_field_mapping(display_names->locale(), code.as_string().string());
|
result = ::Locale::get_locale_narrow_date_field_mapping(display_names->locale(), code.as_string().string());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
|
|
|
@ -293,7 +293,7 @@ ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM& vm, String
|
||||||
// FIXME: LibUnicode currently only exposes unit patterns converted to an ECMA402 NumberFormat-specific format,
|
// FIXME: LibUnicode currently only exposes unit patterns converted to an ECMA402 NumberFormat-specific format,
|
||||||
// since DurationFormat only needs a tiny subset of it, it's much easier to just convert it to the expected format
|
// since DurationFormat only needs a tiny subset of it, it's much easier to just convert it to the expected format
|
||||||
// here, but at some point we should split the the NumberFormat exporter to export both formats of the data.
|
// here, but at some point we should split the the NumberFormat exporter to export both formats of the data.
|
||||||
static String convert_number_format_pattern_to_duration_format_template(Unicode::NumberFormat const& number_format)
|
static String convert_number_format_pattern_to_duration_format_template(::Locale::NumberFormat const& number_format)
|
||||||
{
|
{
|
||||||
auto result = number_format.zero_format.replace("{number}"sv, "{0}"sv, ReplaceMode::FirstOnly);
|
auto result = number_format.zero_format.replace("{number}"sv, "{0}"sv, ReplaceMode::FirstOnly);
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationForma
|
||||||
// c. If nextValue is not 0 or nextDisplay is not "auto", then
|
// c. If nextValue is not 0 or nextDisplay is not "auto", then
|
||||||
if (next_value != 0.0 || next_display != DurationFormat::Display::Auto) {
|
if (next_value != 0.0 || next_display != DurationFormat::Display::Auto) {
|
||||||
// i. Let separator be dataLocaleData.[[formats]].[[digital]].[[separator]].
|
// i. Let separator be dataLocaleData.[[formats]].[[digital]].[[separator]].
|
||||||
auto separator = Unicode::get_number_system_symbol(data_locale, duration_format.numbering_system(), Unicode::NumericSymbol::TimeSeparator).value_or(":"sv);
|
auto separator = ::Locale::get_number_system_symbol(data_locale, duration_format.numbering_system(), ::Locale::NumericSymbol::TimeSeparator).value_or(":"sv);
|
||||||
|
|
||||||
// ii. Append the new Record { [[Type]]: "literal", [[Value]]: separator} to the end of result.
|
// ii. Append the new Record { [[Type]]: "literal", [[Value]]: separator} to the end of result.
|
||||||
result.append({ "literal"sv, separator });
|
result.append({ "literal"sv, separator });
|
||||||
|
@ -464,7 +464,7 @@ Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationForma
|
||||||
// 3. Let prv be ! ResolvePlural(pr, 𝔽(value)).
|
// 3. Let prv be ! ResolvePlural(pr, 𝔽(value)).
|
||||||
auto plurality = resolve_plural(*plural_rules, Value(value));
|
auto plurality = resolve_plural(*plural_rules, Value(value));
|
||||||
|
|
||||||
auto formats = Unicode::get_unit_formats(data_locale, duration_instances_component.unit_singular, static_cast<Unicode::Style>(style));
|
auto formats = ::Locale::get_unit_formats(data_locale, duration_instances_component.unit_singular, static_cast<::Locale::Style>(style));
|
||||||
auto pattern = formats.find_if([&](auto& p) { return p.plurality == plurality; });
|
auto pattern = formats.find_if([&](auto& p) { return p.plurality == plurality; });
|
||||||
if (pattern == formats.end())
|
if (pattern == formats.end())
|
||||||
continue;
|
continue;
|
||||||
|
@ -505,7 +505,7 @@ Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationForma
|
||||||
list_style = DurationFormat::Style::Narrow;
|
list_style = DurationFormat::Style::Narrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto unicode_list_style = Unicode::style_to_string(static_cast<Unicode::Style>(list_style));
|
auto unicode_list_style = ::Locale::style_to_string(static_cast<::Locale::Style>(list_style));
|
||||||
|
|
||||||
// 8. Perform ! CreateDataPropertyOrThrow(lfOpts, "style", listStyle).
|
// 8. Perform ! CreateDataPropertyOrThrow(lfOpts, "style", listStyle).
|
||||||
MUST(list_format_options->create_data_property_or_throw(vm.names.style, js_string(vm, unicode_list_style)));
|
MUST(list_format_options->create_data_property_or_throw(vm.names.style, js_string(vm, unicode_list_style)));
|
||||||
|
|
|
@ -33,9 +33,9 @@ public:
|
||||||
Numeric,
|
Numeric,
|
||||||
TwoDigit
|
TwoDigit
|
||||||
};
|
};
|
||||||
static_assert(to_underlying(ValueStyle::Long) == to_underlying(Unicode::Style::Long));
|
static_assert(to_underlying(ValueStyle::Long) == to_underlying(::Locale::Style::Long));
|
||||||
static_assert(to_underlying(ValueStyle::Short) == to_underlying(Unicode::Style::Short));
|
static_assert(to_underlying(ValueStyle::Short) == to_underlying(::Locale::Style::Short));
|
||||||
static_assert(to_underlying(ValueStyle::Narrow) == to_underlying(Unicode::Style::Narrow));
|
static_assert(to_underlying(ValueStyle::Narrow) == to_underlying(::Locale::Style::Narrow));
|
||||||
|
|
||||||
enum class Display {
|
enum class Display {
|
||||||
Auto,
|
Auto,
|
||||||
|
|
|
@ -67,7 +67,7 @@ ThrowCompletionOr<Object*> DurationFormatConstructor::construct(FunctionObject&
|
||||||
// 7. If numberingSystem is not undefined, then
|
// 7. If numberingSystem is not undefined, then
|
||||||
if (!numbering_system.is_undefined()) {
|
if (!numbering_system.is_undefined()) {
|
||||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
if (!::Locale::is_type_identifier(numbering_system.as_string().string()))
|
||||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,22 +118,22 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of)
|
||||||
// 2. If key is "calendar", then
|
// 2. If key is "calendar", then
|
||||||
if (key == "calendar"sv) {
|
if (key == "calendar"sv) {
|
||||||
// a. Let list be ! AvailableCalendars( ).
|
// a. Let list be ! AvailableCalendars( ).
|
||||||
list = Unicode::get_available_calendars();
|
list = ::Locale::get_available_calendars();
|
||||||
}
|
}
|
||||||
// 3. Else if key is "collation", then
|
// 3. Else if key is "collation", then
|
||||||
else if (key == "collation"sv) {
|
else if (key == "collation"sv) {
|
||||||
// a. Let list be ! AvailableCollations( ).
|
// a. Let list be ! AvailableCollations( ).
|
||||||
list = Unicode::get_available_collation_types();
|
list = ::Locale::get_available_collation_types();
|
||||||
}
|
}
|
||||||
// 4. Else if key is "currency", then
|
// 4. Else if key is "currency", then
|
||||||
else if (key == "currency"sv) {
|
else if (key == "currency"sv) {
|
||||||
// a. Let list be ! AvailableCurrencies( ).
|
// a. Let list be ! AvailableCurrencies( ).
|
||||||
list = Unicode::get_available_currencies();
|
list = ::Locale::get_available_currencies();
|
||||||
}
|
}
|
||||||
// 5. Else if key is "numberingSystem", then
|
// 5. Else if key is "numberingSystem", then
|
||||||
else if (key == "numberingSystem"sv) {
|
else if (key == "numberingSystem"sv) {
|
||||||
// a. Let list be ! AvailableNumberingSystems( ).
|
// a. Let list be ! AvailableNumberingSystems( ).
|
||||||
list = Unicode::get_available_number_systems();
|
list = ::Locale::get_available_number_systems();
|
||||||
}
|
}
|
||||||
// 6. Else if key is "timeZone", then
|
// 6. Else if key is "timeZone", then
|
||||||
else if (key == "timeZone"sv) {
|
else if (key == "timeZone"sv) {
|
||||||
|
|
|
@ -95,7 +95,7 @@ Vector<PatternPartition> deconstruct_pattern(StringView pattern, Placeables plac
|
||||||
// 13.5.2 CreatePartsFromList ( listFormat, list ), https://tc39.es/ecma402/#sec-createpartsfromlist
|
// 13.5.2 CreatePartsFromList ( listFormat, list ), https://tc39.es/ecma402/#sec-createpartsfromlist
|
||||||
Vector<PatternPartition> create_parts_from_list(ListFormat const& list_format, Vector<String> const& list)
|
Vector<PatternPartition> create_parts_from_list(ListFormat const& list_format, Vector<String> const& list)
|
||||||
{
|
{
|
||||||
auto list_patterns = Unicode::get_locale_list_patterns(list_format.locale(), list_format.type_string(), list_format.style());
|
auto list_patterns = ::Locale::get_locale_list_patterns(list_format.locale(), list_format.type_string(), list_format.style());
|
||||||
if (!list_patterns.has_value())
|
if (!list_patterns.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
|
|
@ -37,16 +37,16 @@ public:
|
||||||
void set_type(StringView type);
|
void set_type(StringView type);
|
||||||
StringView type_string() const;
|
StringView type_string() const;
|
||||||
|
|
||||||
Unicode::Style style() const { return m_style; }
|
::Locale::Style style() const { return m_style; }
|
||||||
void set_style(StringView style) { m_style = Unicode::style_from_string(style); }
|
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
|
||||||
StringView style_string() const { return Unicode::style_to_string(m_style); }
|
StringView style_string() const { return ::Locale::style_to_string(m_style); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ListFormat(Object& prototype);
|
explicit ListFormat(Object& prototype);
|
||||||
|
|
||||||
String m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
Type m_type { Type::Invalid }; // [[Type]]
|
Type m_type { Type::Invalid }; // [[Type]]
|
||||||
Unicode::Style m_style { Unicode::Style::Long }; // [[Style]]
|
::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
|
||||||
};
|
};
|
||||||
|
|
||||||
using Placeables = HashMap<StringView, Variant<PatternPartition, Vector<PatternPartition>>>;
|
using Placeables = HashMap<StringView, Variant<PatternPartition, Vector<PatternPartition>>>;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
namespace JS::Intl {
|
namespace JS::Intl {
|
||||||
|
|
||||||
Locale* Locale::create(Realm& realm, Unicode::LocaleID const& locale_id)
|
Locale* Locale::create(Realm& realm, ::Locale::LocaleID const& locale_id)
|
||||||
{
|
{
|
||||||
return realm.heap().allocate<Locale>(realm, locale_id, *realm.intrinsics().intl_locale_prototype());
|
return realm.heap().allocate<Locale>(realm, locale_id, *realm.intrinsics().intl_locale_prototype());
|
||||||
}
|
}
|
||||||
|
@ -25,16 +25,16 @@ Locale::Locale(Object& prototype)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Locale::Locale(Unicode::LocaleID const& locale_id, Object& prototype)
|
Locale::Locale(::Locale::LocaleID const& locale_id, Object& prototype)
|
||||||
: Object(prototype)
|
: Object(prototype)
|
||||||
{
|
{
|
||||||
set_locale(locale_id.to_string());
|
set_locale(locale_id.to_string());
|
||||||
|
|
||||||
for (auto const& extension : locale_id.extensions) {
|
for (auto const& extension : locale_id.extensions) {
|
||||||
if (!extension.has<Unicode::LocaleExtension>())
|
if (!extension.has<::Locale::LocaleExtension>())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (auto const& keyword : extension.get<Unicode::LocaleExtension>().keywords) {
|
for (auto const& keyword : extension.get<::Locale::LocaleExtension>().keywords) {
|
||||||
if (keyword.key == "ca"sv) {
|
if (keyword.key == "ca"sv) {
|
||||||
set_calendar(keyword.value);
|
set_calendar(keyword.value);
|
||||||
} else if (keyword.key == "co"sv) {
|
} else if (keyword.key == "co"sv) {
|
||||||
|
@ -81,10 +81,10 @@ Array* calendars_of_locale(VM& vm, Locale const& locale_object)
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
|
||||||
// 3. Assert: locale matches the unicode_locale_id production.
|
// 3. Assert: locale matches the unicode_locale_id production.
|
||||||
VERIFY(Unicode::parse_unicode_locale_id(locale).has_value());
|
VERIFY(::Locale::parse_unicode_locale_id(locale).has_value());
|
||||||
|
|
||||||
// 4. Let list be a List of 1 or more unique canonical calendar identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for date and time formatting in locale.
|
// 4. Let list be a List of 1 or more unique canonical calendar identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for date and time formatting in locale.
|
||||||
auto list = Unicode::get_keywords_for_locale(locale, "ca"sv);
|
auto list = ::Locale::get_keywords_for_locale(locale, "ca"sv);
|
||||||
|
|
||||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||||
|
@ -100,10 +100,10 @@ Array* collations_of_locale(VM& vm, Locale const& locale_object)
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
|
||||||
// 3. Assert: locale matches the unicode_locale_id production.
|
// 3. Assert: locale matches the unicode_locale_id production.
|
||||||
VERIFY(Unicode::parse_unicode_locale_id(locale).has_value());
|
VERIFY(::Locale::parse_unicode_locale_id(locale).has_value());
|
||||||
|
|
||||||
// 4. Let list be a List of 1 or more unique canonical collation identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for string comparison in locale. The values "standard" and "search" must be excluded from list.
|
// 4. Let list be a List of 1 or more unique canonical collation identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for string comparison in locale. The values "standard" and "search" must be excluded from list.
|
||||||
auto list = Unicode::get_keywords_for_locale(locale, "co"sv);
|
auto list = ::Locale::get_keywords_for_locale(locale, "co"sv);
|
||||||
|
|
||||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||||
|
@ -119,10 +119,10 @@ Array* hour_cycles_of_locale(VM& vm, Locale const& locale_object)
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
|
||||||
// 3. Assert: locale matches the unicode_locale_id production.
|
// 3. Assert: locale matches the unicode_locale_id production.
|
||||||
VERIFY(Unicode::parse_unicode_locale_id(locale).has_value());
|
VERIFY(::Locale::parse_unicode_locale_id(locale).has_value());
|
||||||
|
|
||||||
// 4. Let list be a List of 1 or more unique hour cycle identifiers, which must be lower case String values indicating either the 12-hour format ("h11", "h12") or the 24-hour format ("h23", "h24"), sorted in descending preference of those in common use for date and time formatting in locale.
|
// 4. Let list be a List of 1 or more unique hour cycle identifiers, which must be lower case String values indicating either the 12-hour format ("h11", "h12") or the 24-hour format ("h23", "h24"), sorted in descending preference of those in common use for date and time formatting in locale.
|
||||||
auto list = Unicode::get_keywords_for_locale(locale, "hc"sv);
|
auto list = ::Locale::get_keywords_for_locale(locale, "hc"sv);
|
||||||
|
|
||||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||||
|
@ -138,10 +138,10 @@ Array* numbering_systems_of_locale(VM& vm, Locale const& locale_object)
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
|
||||||
// 3. Assert: locale matches the unicode_locale_id production.
|
// 3. Assert: locale matches the unicode_locale_id production.
|
||||||
VERIFY(Unicode::parse_unicode_locale_id(locale).has_value());
|
VERIFY(::Locale::parse_unicode_locale_id(locale).has_value());
|
||||||
|
|
||||||
// 4. Let list be a List of 1 or more unique canonical numbering system identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for formatting numeric values in locale.
|
// 4. Let list be a List of 1 or more unique canonical numbering system identifiers, which must be lower case String values conforming to the type sequence from UTS 35 Unicode Locale Identifier, section 3.2, sorted in descending preference of those in common use for formatting numeric values in locale.
|
||||||
auto list = Unicode::get_keywords_for_locale(locale, "nu"sv);
|
auto list = ::Locale::get_keywords_for_locale(locale, "nu"sv);
|
||||||
|
|
||||||
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
// 5. Return ! CreateArrayFromListOrRestricted( list, restricted ).
|
||||||
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
return create_array_from_list_or_restricted(vm, move(list), move(restricted));
|
||||||
|
@ -174,36 +174,36 @@ StringView character_direction_of_locale(Locale const& locale_object)
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
|
||||||
// 2. Assert: locale matches the unicode_locale_id production.
|
// 2. Assert: locale matches the unicode_locale_id production.
|
||||||
VERIFY(Unicode::parse_unicode_locale_id(locale).has_value());
|
VERIFY(::Locale::parse_unicode_locale_id(locale).has_value());
|
||||||
|
|
||||||
// 3. If the default general ordering of characters (characterOrder) within a line in locale is right-to-left, return "rtl".
|
// 3. If the default general ordering of characters (characterOrder) within a line in locale is right-to-left, return "rtl".
|
||||||
// NOTE: LibUnicode handles both LTR and RTL character orders in this call, not just RTL. We then fallback to LTR
|
// NOTE: LibUnicode handles both LTR and RTL character orders in this call, not just RTL. We then fallback to LTR
|
||||||
// below if LibUnicode doesn't conclusively know the character order for this locale.
|
// below if LibUnicode doesn't conclusively know the character order for this locale.
|
||||||
if (auto character_order = Unicode::character_order_for_locale(locale); character_order.has_value())
|
if (auto character_order = ::Locale::character_order_for_locale(locale); character_order.has_value())
|
||||||
return Unicode::character_order_to_string(*character_order);
|
return ::Locale::character_order_to_string(*character_order);
|
||||||
|
|
||||||
// 4. Return "ltr".
|
// 4. Return "ltr".
|
||||||
return "ltr"sv;
|
return "ltr"sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 weekday_to_integer(Optional<Unicode::Weekday> weekday, Unicode::Weekday falllback)
|
static u8 weekday_to_integer(Optional<::Locale::Weekday> weekday, ::Locale::Weekday falllback)
|
||||||
{
|
{
|
||||||
// NOTE: This fallback will be used if LibUnicode data generation is disabled. Its value should
|
// NOTE: This fallback will be used if LibUnicode data generation is disabled. Its value should
|
||||||
// be that of the default region ("001") in the CLDR.
|
// be that of the default region ("001") in the CLDR.
|
||||||
switch (weekday.value_or(falllback)) {
|
switch (weekday.value_or(falllback)) {
|
||||||
case Unicode::Weekday::Monday:
|
case ::Locale::Weekday::Monday:
|
||||||
return 1;
|
return 1;
|
||||||
case Unicode::Weekday::Tuesday:
|
case ::Locale::Weekday::Tuesday:
|
||||||
return 2;
|
return 2;
|
||||||
case Unicode::Weekday::Wednesday:
|
case ::Locale::Weekday::Wednesday:
|
||||||
return 3;
|
return 3;
|
||||||
case Unicode::Weekday::Thursday:
|
case ::Locale::Weekday::Thursday:
|
||||||
return 4;
|
return 4;
|
||||||
case Unicode::Weekday::Friday:
|
case ::Locale::Weekday::Friday:
|
||||||
return 5;
|
return 5;
|
||||||
case Unicode::Weekday::Saturday:
|
case ::Locale::Weekday::Saturday:
|
||||||
return 6;
|
return 6;
|
||||||
case Unicode::Weekday::Sunday:
|
case ::Locale::Weekday::Sunday:
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,8 +212,8 @@ static u8 weekday_to_integer(Optional<Unicode::Weekday> weekday, Unicode::Weekda
|
||||||
|
|
||||||
static Vector<u8> weekend_of_locale(StringView locale)
|
static Vector<u8> weekend_of_locale(StringView locale)
|
||||||
{
|
{
|
||||||
auto weekend_start = weekday_to_integer(Unicode::get_locale_weekend_start(locale), Unicode::Weekday::Saturday);
|
auto weekend_start = weekday_to_integer(::Locale::get_locale_weekend_start(locale), ::Locale::Weekday::Saturday);
|
||||||
auto weekend_end = weekday_to_integer(Unicode::get_locale_weekend_end(locale), Unicode::Weekday::Sunday);
|
auto weekend_end = weekday_to_integer(::Locale::get_locale_weekend_end(locale), ::Locale::Weekday::Sunday);
|
||||||
|
|
||||||
// There currently aren't any regions in the CLDR which wrap around from Sunday (7) to Monday (1).
|
// There currently aren't any regions in the CLDR which wrap around from Sunday (7) to Monday (1).
|
||||||
// If this changes, this logic will need to be updated to handle that.
|
// If this changes, this logic will need to be updated to handle that.
|
||||||
|
@ -235,12 +235,12 @@ WeekInfo week_info_of_locale(Locale const& locale_object)
|
||||||
auto const& locale = locale_object.locale();
|
auto const& locale = locale_object.locale();
|
||||||
|
|
||||||
// 2. Assert: locale matches the unicode_locale_id production.
|
// 2. Assert: locale matches the unicode_locale_id production.
|
||||||
VERIFY(Unicode::parse_unicode_locale_id(locale).has_value());
|
VERIFY(::Locale::parse_unicode_locale_id(locale).has_value());
|
||||||
|
|
||||||
// 3. Return a record whose fields are defined by Table 1, with values based on locale.
|
// 3. Return a record whose fields are defined by Table 1, with values based on locale.
|
||||||
WeekInfo week_info {};
|
WeekInfo week_info {};
|
||||||
week_info.minimal_days = Unicode::get_locale_minimum_days(locale).value_or(1);
|
week_info.minimal_days = ::Locale::get_locale_minimum_days(locale).value_or(1);
|
||||||
week_info.first_day = weekday_to_integer(Unicode::get_locale_first_day(locale), Unicode::Weekday::Monday);
|
week_info.first_day = weekday_to_integer(::Locale::get_locale_first_day(locale), ::Locale::Weekday::Monday);
|
||||||
week_info.weekend = weekend_of_locale(locale);
|
week_info.weekend = weekend_of_locale(locale);
|
||||||
|
|
||||||
return week_info;
|
return week_info;
|
||||||
|
|
|
@ -21,7 +21,7 @@ class Locale final : public Object {
|
||||||
JS_OBJECT(Locale, Object);
|
JS_OBJECT(Locale, Object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Locale* create(Realm&, Unicode::LocaleID const&);
|
static Locale* create(Realm&, ::Locale::LocaleID const&);
|
||||||
|
|
||||||
static constexpr auto relevant_extension_keys()
|
static constexpr auto relevant_extension_keys()
|
||||||
{
|
{
|
||||||
|
@ -64,7 +64,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Locale(Object& prototype);
|
explicit Locale(Object& prototype);
|
||||||
Locale(Unicode::LocaleID const&, Object& prototype);
|
Locale(::Locale::LocaleID const&, Object& prototype);
|
||||||
|
|
||||||
String m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
Optional<String> m_calendar; // [[Calendar]]
|
Optional<String> m_calendar; // [[Calendar]]
|
||||||
|
|
|
@ -52,23 +52,23 @@ static ThrowCompletionOr<String> apply_options_to_tag(VM& vm, StringView tag, Ob
|
||||||
// 4. Let language be ? GetOption(options, "language", "string", undefined, undefined).
|
// 4. Let language be ? GetOption(options, "language", "string", undefined, undefined).
|
||||||
// 5. If language is not undefined, then
|
// 5. If language is not undefined, then
|
||||||
// a. If language does not match the unicode_language_subtag production, throw a RangeError exception.
|
// a. If language does not match the unicode_language_subtag production, throw a RangeError exception.
|
||||||
auto language = TRY(get_string_option(vm, options, vm.names.language, Unicode::is_unicode_language_subtag));
|
auto language = TRY(get_string_option(vm, options, vm.names.language, ::Locale::is_unicode_language_subtag));
|
||||||
|
|
||||||
// 6. Let script be ? GetOption(options, "script", "string", undefined, undefined).
|
// 6. Let script be ? GetOption(options, "script", "string", undefined, undefined).
|
||||||
// 7. If script is not undefined, then
|
// 7. If script is not undefined, then
|
||||||
// a. If script does not match the unicode_script_subtag production, throw a RangeError exception.
|
// a. If script does not match the unicode_script_subtag production, throw a RangeError exception.
|
||||||
auto script = TRY(get_string_option(vm, options, vm.names.script, Unicode::is_unicode_script_subtag));
|
auto script = TRY(get_string_option(vm, options, vm.names.script, ::Locale::is_unicode_script_subtag));
|
||||||
|
|
||||||
// 8. Let region be ? GetOption(options, "region", "string", undefined, undefined).
|
// 8. Let region be ? GetOption(options, "region", "string", undefined, undefined).
|
||||||
// 9. If region is not undefined, then
|
// 9. If region is not undefined, then
|
||||||
// a. If region does not match the unicode_region_subtag production, throw a RangeError exception.
|
// a. If region does not match the unicode_region_subtag production, throw a RangeError exception.
|
||||||
auto region = TRY(get_string_option(vm, options, vm.names.region, Unicode::is_unicode_region_subtag));
|
auto region = TRY(get_string_option(vm, options, vm.names.region, ::Locale::is_unicode_region_subtag));
|
||||||
|
|
||||||
// 10. Set tag to ! CanonicalizeUnicodeLocaleId(tag).
|
// 10. Set tag to ! CanonicalizeUnicodeLocaleId(tag).
|
||||||
auto canonicalized_tag = JS::Intl::canonicalize_unicode_locale_id(*locale_id);
|
auto canonicalized_tag = JS::Intl::canonicalize_unicode_locale_id(*locale_id);
|
||||||
|
|
||||||
// 11. Assert: tag matches the unicode_locale_id production.
|
// 11. Assert: tag matches the unicode_locale_id production.
|
||||||
locale_id = Unicode::parse_unicode_locale_id(canonicalized_tag);
|
locale_id = ::Locale::parse_unicode_locale_id(canonicalized_tag);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
|
|
||||||
// 12. Let languageId be the substring of tag corresponding to the unicode_language_id production.
|
// 12. Let languageId be the substring of tag corresponding to the unicode_language_id production.
|
||||||
|
@ -108,20 +108,20 @@ static LocaleAndKeys apply_unicode_extension_to_tag(StringView tag, LocaleAndKey
|
||||||
{
|
{
|
||||||
// 1. Assert: Type(tag) is String.
|
// 1. Assert: Type(tag) is String.
|
||||||
// 2. Assert: tag matches the unicode_locale_id production.
|
// 2. Assert: tag matches the unicode_locale_id production.
|
||||||
auto locale_id = Unicode::parse_unicode_locale_id(tag);
|
auto locale_id = ::Locale::parse_unicode_locale_id(tag);
|
||||||
VERIFY(locale_id.has_value());
|
VERIFY(locale_id.has_value());
|
||||||
|
|
||||||
Vector<String> attributes;
|
Vector<String> attributes;
|
||||||
Vector<Unicode::Keyword> keywords;
|
Vector<::Locale::Keyword> keywords;
|
||||||
|
|
||||||
// 3. If tag contains a substring that is a Unicode locale extension sequence, then
|
// 3. If tag contains a substring that is a Unicode locale extension sequence, then
|
||||||
for (auto& extension : locale_id->extensions) {
|
for (auto& extension : locale_id->extensions) {
|
||||||
if (!extension.has<Unicode::LocaleExtension>())
|
if (!extension.has<::Locale::LocaleExtension>())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// a. Let extension be the String value consisting of the substring of the Unicode locale extension sequence within tag.
|
// a. Let extension be the String value consisting of the substring of the Unicode locale extension sequence within tag.
|
||||||
// b. Let components be ! UnicodeExtensionComponents(extension).
|
// b. Let components be ! UnicodeExtensionComponents(extension).
|
||||||
auto& components = extension.get<Unicode::LocaleExtension>();
|
auto& components = extension.get<::Locale::LocaleExtension>();
|
||||||
// c. Let attributes be components.[[Attributes]].
|
// c. Let attributes be components.[[Attributes]].
|
||||||
attributes = move(components.attributes);
|
attributes = move(components.attributes);
|
||||||
// d. Let keywords be components.[[Keywords]].
|
// d. Let keywords be components.[[Keywords]].
|
||||||
|
@ -157,7 +157,7 @@ static LocaleAndKeys apply_unicode_extension_to_tag(StringView tag, LocaleAndKey
|
||||||
// a. Let value be undefined.
|
// a. Let value be undefined.
|
||||||
Optional<String> value {};
|
Optional<String> value {};
|
||||||
|
|
||||||
Unicode::Keyword* entry = nullptr;
|
::Locale::Keyword* entry = nullptr;
|
||||||
// b. If keywords contains an element whose [[Key]] is the same as key, then
|
// b. If keywords contains an element whose [[Key]] is the same as key, then
|
||||||
if (auto it = keywords.find_if([&](auto const& k) { return key == k.key; }); it != keywords.end()) {
|
if (auto it = keywords.find_if([&](auto const& k) { return key == k.key; }); it != keywords.end()) {
|
||||||
// i. Let entry be the element of keywords whose [[Key]] is the same as key.
|
// i. Let entry be the element of keywords whose [[Key]] is the same as key.
|
||||||
|
@ -196,11 +196,11 @@ static LocaleAndKeys apply_unicode_extension_to_tag(StringView tag, LocaleAndKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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<Unicode::LocaleExtension>();
|
locale_id->remove_extension_type<::Locale::LocaleExtension>();
|
||||||
auto locale = locale_id->to_string();
|
auto locale = 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.
|
||||||
Unicode::LocaleExtension new_extension { move(attributes), move(keywords) };
|
::Locale::LocaleExtension new_extension { move(attributes), move(keywords) };
|
||||||
|
|
||||||
// 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()) {
|
||||||
|
@ -290,13 +290,13 @@ ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_targ
|
||||||
// 14. If calendar is not undefined, then
|
// 14. If calendar is not undefined, then
|
||||||
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
// 15. Set opt.[[ca]] to calendar.
|
// 15. Set opt.[[ca]] to calendar.
|
||||||
opt.ca = TRY(get_string_option(vm, *options, vm.names.calendar, Unicode::is_type_identifier));
|
opt.ca = TRY(get_string_option(vm, *options, vm.names.calendar, ::Locale::is_type_identifier));
|
||||||
|
|
||||||
// 16. Let collation be ? GetOption(options, "collation", "string", undefined, undefined).
|
// 16. Let collation be ? GetOption(options, "collation", "string", undefined, undefined).
|
||||||
// 17. If collation is not undefined, then
|
// 17. If collation is not undefined, then
|
||||||
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
// 18. Set opt.[[co]] to collation.
|
// 18. Set opt.[[co]] to collation.
|
||||||
opt.co = TRY(get_string_option(vm, *options, vm.names.collation, Unicode::is_type_identifier));
|
opt.co = TRY(get_string_option(vm, *options, vm.names.collation, ::Locale::is_type_identifier));
|
||||||
|
|
||||||
// 19. Let hc be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined).
|
// 19. Let hc be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined).
|
||||||
// 20. Set opt.[[hc]] to hc.
|
// 20. Set opt.[[hc]] to hc.
|
||||||
|
@ -318,7 +318,7 @@ ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_targ
|
||||||
// 27. If numberingSystem is not undefined, then
|
// 27. If numberingSystem is not undefined, then
|
||||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
// 28. Set opt.[[nu]] to numberingSystem.
|
// 28. Set opt.[[nu]] to numberingSystem.
|
||||||
opt.nu = TRY(get_string_option(vm, *options, vm.names.numberingSystem, Unicode::is_type_identifier));
|
opt.nu = TRY(get_string_option(vm, *options, vm.names.numberingSystem, ::Locale::is_type_identifier));
|
||||||
|
|
||||||
// 29. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
|
// 29. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
|
||||||
auto result = apply_unicode_extension_to_tag(tag, move(opt), relevant_extension_keys);
|
auto result = apply_unicode_extension_to_tag(tag, move(opt), relevant_extension_keys);
|
||||||
|
|
|
@ -61,11 +61,11 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
|
||||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||||
auto* locale_object = TRY(typed_this_object(vm));
|
auto* locale_object = TRY(typed_this_object(vm));
|
||||||
|
|
||||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
auto locale = ::Locale::parse_unicode_locale_id(locale_object->locale());
|
||||||
VERIFY(locale.has_value());
|
VERIFY(locale.has_value());
|
||||||
|
|
||||||
// 3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set maximal to loc.[[Locale]].
|
// 3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set maximal to loc.[[Locale]].
|
||||||
if (auto maximal = Unicode::add_likely_subtags(locale->language_id); maximal.has_value())
|
if (auto maximal = ::Locale::add_likely_subtags(locale->language_id); maximal.has_value())
|
||||||
locale->language_id = maximal.release_value();
|
locale->language_id = maximal.release_value();
|
||||||
|
|
||||||
// 4. Return ! Construct(%Locale%, maximal).
|
// 4. Return ! Construct(%Locale%, maximal).
|
||||||
|
@ -81,11 +81,11 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
|
||||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||||
auto* locale_object = TRY(typed_this_object(vm));
|
auto* locale_object = TRY(typed_this_object(vm));
|
||||||
|
|
||||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
auto locale = ::Locale::parse_unicode_locale_id(locale_object->locale());
|
||||||
VERIFY(locale.has_value());
|
VERIFY(locale.has_value());
|
||||||
|
|
||||||
// 3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set minimal to loc.[[Locale]].
|
// 3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set minimal to loc.[[Locale]].
|
||||||
if (auto minimal = Unicode::remove_likely_subtags(locale->language_id); minimal.has_value())
|
if (auto minimal = ::Locale::remove_likely_subtags(locale->language_id); minimal.has_value())
|
||||||
locale->language_id = minimal.release_value();
|
locale->language_id = minimal.release_value();
|
||||||
|
|
||||||
// 4. Return ! Construct(%Locale%, minimal).
|
// 4. Return ! Construct(%Locale%, minimal).
|
||||||
|
@ -111,7 +111,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::base_name)
|
||||||
auto* locale_object = TRY(typed_this_object(vm));
|
auto* locale_object = TRY(typed_this_object(vm));
|
||||||
|
|
||||||
// 3. Let locale be loc.[[Locale]].
|
// 3. Let locale be loc.[[Locale]].
|
||||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
auto locale = ::Locale::parse_unicode_locale_id(locale_object->locale());
|
||||||
VERIFY(locale.has_value());
|
VERIFY(locale.has_value());
|
||||||
|
|
||||||
// 4. Return the substring of locale corresponding to the unicode_language_id production.
|
// 4. Return the substring of locale corresponding to the unicode_language_id production.
|
||||||
|
@ -160,7 +160,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::language)
|
||||||
auto* locale_object = TRY(typed_this_object(vm));
|
auto* locale_object = TRY(typed_this_object(vm));
|
||||||
|
|
||||||
// 3. Let locale be loc.[[Locale]].
|
// 3. Let locale be loc.[[Locale]].
|
||||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
auto locale = ::Locale::parse_unicode_locale_id(locale_object->locale());
|
||||||
|
|
||||||
// 4. Assert: locale matches the unicode_locale_id production.
|
// 4. Assert: locale matches the unicode_locale_id production.
|
||||||
VERIFY(locale.has_value());
|
VERIFY(locale.has_value());
|
||||||
|
@ -177,7 +177,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::script)
|
||||||
auto* locale_object = TRY(typed_this_object(vm));
|
auto* locale_object = TRY(typed_this_object(vm));
|
||||||
|
|
||||||
// 3. Let locale be loc.[[Locale]].
|
// 3. Let locale be loc.[[Locale]].
|
||||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
auto locale = ::Locale::parse_unicode_locale_id(locale_object->locale());
|
||||||
|
|
||||||
// 4. Assert: locale matches the unicode_locale_id production.
|
// 4. Assert: locale matches the unicode_locale_id production.
|
||||||
VERIFY(locale.has_value());
|
VERIFY(locale.has_value());
|
||||||
|
@ -198,7 +198,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::region)
|
||||||
auto* locale_object = TRY(typed_this_object(vm));
|
auto* locale_object = TRY(typed_this_object(vm));
|
||||||
|
|
||||||
// 3. Let locale be loc.[[Locale]].
|
// 3. Let locale be loc.[[Locale]].
|
||||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
auto locale = ::Locale::parse_unicode_locale_id(locale_object->locale());
|
||||||
|
|
||||||
// 4. Assert: locale matches the unicode_locale_id production.
|
// 4. Assert: locale matches the unicode_locale_id production.
|
||||||
VERIFY(locale.has_value());
|
VERIFY(locale.has_value());
|
||||||
|
@ -238,7 +238,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::time_zones)
|
||||||
auto* locale_object = TRY(typed_this_object(vm));
|
auto* locale_object = TRY(typed_this_object(vm));
|
||||||
|
|
||||||
// 3. Let locale be loc.[[Locale]].
|
// 3. Let locale be loc.[[Locale]].
|
||||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
auto locale = ::Locale::parse_unicode_locale_id(locale_object->locale());
|
||||||
|
|
||||||
// 4. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined.
|
// 4. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined.
|
||||||
if (!locale.has_value() || !locale->language_id.region.has_value())
|
if (!locale.has_value() || !locale->language_id.region.has_value())
|
||||||
|
|
|
@ -94,13 +94,13 @@ StringView NumberFormat::resolve_currency_display()
|
||||||
m_resolved_currency_display = currency();
|
m_resolved_currency_display = currency();
|
||||||
break;
|
break;
|
||||||
case NumberFormat::CurrencyDisplay::Symbol:
|
case NumberFormat::CurrencyDisplay::Symbol:
|
||||||
m_resolved_currency_display = Unicode::get_locale_short_currency_mapping(data_locale(), currency());
|
m_resolved_currency_display = ::Locale::get_locale_short_currency_mapping(data_locale(), currency());
|
||||||
break;
|
break;
|
||||||
case NumberFormat::CurrencyDisplay::NarrowSymbol:
|
case NumberFormat::CurrencyDisplay::NarrowSymbol:
|
||||||
m_resolved_currency_display = Unicode::get_locale_narrow_currency_mapping(data_locale(), currency());
|
m_resolved_currency_display = ::Locale::get_locale_narrow_currency_mapping(data_locale(), currency());
|
||||||
break;
|
break;
|
||||||
case NumberFormat::CurrencyDisplay::Name:
|
case NumberFormat::CurrencyDisplay::Name:
|
||||||
m_resolved_currency_display = Unicode::get_locale_numeric_currency_mapping(data_locale(), currency());
|
m_resolved_currency_display = ::Locale::get_locale_numeric_currency_mapping(data_locale(), currency());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
|
@ -527,19 +527,19 @@ Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_f
|
||||||
// 2. If x is not-a-number, then
|
// 2. If x is not-a-number, then
|
||||||
if (number.is_nan()) {
|
if (number.is_nan()) {
|
||||||
// a. Let n be an implementation- and locale-dependent (ILD) String value indicating the NaN value.
|
// a. Let n be an implementation- and locale-dependent (ILD) String value indicating the NaN value.
|
||||||
formatted_string = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::NaN).value_or("NaN"sv);
|
formatted_string = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::NaN).value_or("NaN"sv);
|
||||||
}
|
}
|
||||||
// 3. Else if x is positive-infinity, then
|
// 3. Else if x is positive-infinity, then
|
||||||
else if (number.is_positive_infinity()) {
|
else if (number.is_positive_infinity()) {
|
||||||
// a. Let n be an ILD String value indicating positive infinity.
|
// a. Let n be an ILD String value indicating positive infinity.
|
||||||
formatted_string = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::Infinity).value_or("infinity"sv);
|
formatted_string = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Infinity).value_or("infinity"sv);
|
||||||
}
|
}
|
||||||
// 4. Else if x is negative-infinity, then
|
// 4. Else if x is negative-infinity, then
|
||||||
else if (number.is_negative_infinity()) {
|
else if (number.is_negative_infinity()) {
|
||||||
// a. Let n be an ILD String value indicating negative infinity.
|
// a. Let n be an ILD String value indicating negative infinity.
|
||||||
// NOTE: The CLDR does not contain unique strings for negative infinity. The negative sign will
|
// NOTE: The CLDR does not contain unique strings for negative infinity. The negative sign will
|
||||||
// be inserted by the pattern returned from GetNumberFormatPattern.
|
// be inserted by the pattern returned from GetNumberFormatPattern.
|
||||||
formatted_string = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::Infinity).value_or("infinity"sv);
|
formatted_string = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Infinity).value_or("infinity"sv);
|
||||||
}
|
}
|
||||||
// 5. Else,
|
// 5. Else,
|
||||||
else {
|
else {
|
||||||
|
@ -569,7 +569,7 @@ Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_f
|
||||||
number = move(format_number_result.rounded_number);
|
number = move(format_number_result.rounded_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
Unicode::NumberFormat found_pattern {};
|
::Locale::NumberFormat found_pattern {};
|
||||||
|
|
||||||
// 6. Let pattern be GetNumberFormatPattern(numberFormat, x).
|
// 6. Let pattern be GetNumberFormatPattern(numberFormat, x).
|
||||||
auto pattern = get_number_format_pattern(vm, number_format, number, found_pattern);
|
auto pattern = get_number_format_pattern(vm, number_format, number, found_pattern);
|
||||||
|
@ -604,7 +604,7 @@ Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_f
|
||||||
// d. Else if p is equal to "plusSign", then
|
// d. Else if p is equal to "plusSign", then
|
||||||
else if (part == "plusSign"sv) {
|
else if (part == "plusSign"sv) {
|
||||||
// i. Let plusSignSymbol be the ILND String representing the plus sign.
|
// i. Let plusSignSymbol be the ILND String representing the plus sign.
|
||||||
auto plus_sign_symbol = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::PlusSign).value_or("+"sv);
|
auto plus_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::PlusSign).value_or("+"sv);
|
||||||
// ii. Append a new Record { [[Type]]: "plusSign", [[Value]]: plusSignSymbol } as the last element of result.
|
// ii. Append a new Record { [[Type]]: "plusSign", [[Value]]: plusSignSymbol } as the last element of result.
|
||||||
result.append({ "plusSign"sv, plus_sign_symbol });
|
result.append({ "plusSign"sv, plus_sign_symbol });
|
||||||
}
|
}
|
||||||
|
@ -612,7 +612,7 @@ Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_f
|
||||||
// e. Else if p is equal to "minusSign", then
|
// e. Else if p is equal to "minusSign", then
|
||||||
else if (part == "minusSign"sv) {
|
else if (part == "minusSign"sv) {
|
||||||
// i. Let minusSignSymbol be the ILND String representing the minus sign.
|
// i. Let minusSignSymbol be the ILND String representing the minus sign.
|
||||||
auto minus_sign_symbol = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::MinusSign).value_or("-"sv);
|
auto minus_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::MinusSign).value_or("-"sv);
|
||||||
// ii. Append a new Record { [[Type]]: "minusSign", [[Value]]: minusSignSymbol } as the last element of result.
|
// ii. Append a new Record { [[Type]]: "minusSign", [[Value]]: minusSignSymbol } as the last element of result.
|
||||||
result.append({ "minusSign"sv, minus_sign_symbol });
|
result.append({ "minusSign"sv, minus_sign_symbol });
|
||||||
}
|
}
|
||||||
|
@ -620,7 +620,7 @@ Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_f
|
||||||
// f. Else if p is equal to "percentSign" and numberFormat.[[Style]] is "percent", then
|
// f. Else if p is equal to "percentSign" and numberFormat.[[Style]] is "percent", then
|
||||||
else if ((part == "percentSign"sv) && (number_format.style() == NumberFormat::Style::Percent)) {
|
else if ((part == "percentSign"sv) && (number_format.style() == NumberFormat::Style::Percent)) {
|
||||||
// i. Let percentSignSymbol be the ILND String representing the percent sign.
|
// i. Let percentSignSymbol be the ILND String representing the percent sign.
|
||||||
auto percent_sign_symbol = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::PercentSign).value_or("%"sv);
|
auto percent_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::PercentSign).value_or("%"sv);
|
||||||
// ii. Append a new Record { [[Type]]: "percentSign", [[Value]]: percentSignSymbol } as the last element of result.
|
// ii. Append a new Record { [[Type]]: "percentSign", [[Value]]: percentSignSymbol } as the last element of result.
|
||||||
result.append({ "percentSign"sv, percent_sign_symbol });
|
result.append({ "percentSign"sv, percent_sign_symbol });
|
||||||
}
|
}
|
||||||
|
@ -667,7 +667,7 @@ Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_f
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Vector<StringView> separate_integer_into_groups(Unicode::NumberGroupings const& grouping_sizes, StringView integer, NumberFormat::UseGrouping use_grouping)
|
static Vector<StringView> separate_integer_into_groups(::Locale::NumberGroupings const& grouping_sizes, StringView integer, NumberFormat::UseGrouping use_grouping)
|
||||||
{
|
{
|
||||||
Utf8View utf8_integer { integer };
|
Utf8View utf8_integer { integer };
|
||||||
if (utf8_integer.length() <= grouping_sizes.primary_grouping_size)
|
if (utf8_integer.length() <= grouping_sizes.primary_grouping_size)
|
||||||
|
@ -719,7 +719,7 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
|
||||||
// 1. Let result be a new empty List.
|
// 1. Let result be a new empty List.
|
||||||
Vector<PatternPartition> result;
|
Vector<PatternPartition> result;
|
||||||
|
|
||||||
auto grouping_sizes = Unicode::get_number_system_groupings(number_format.data_locale(), number_format.numbering_system());
|
auto grouping_sizes = ::Locale::get_number_system_groupings(number_format.data_locale(), number_format.numbering_system());
|
||||||
if (!grouping_sizes.has_value())
|
if (!grouping_sizes.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -759,7 +759,7 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
|
||||||
// a. Let digits be a List whose 10 String valued elements are the UTF-16 string representations of the 10 digits specified in the "Digits" column of the matching row in Table 12.
|
// a. Let digits be a List whose 10 String valued elements are the UTF-16 string representations of the 10 digits specified in the "Digits" column of the matching row in Table 12.
|
||||||
// b. Replace each digit in n with the value of digits[digit].
|
// b. Replace each digit in n with the value of digits[digit].
|
||||||
// 2. Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.
|
// 2. Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.
|
||||||
formatted_string = Unicode::replace_digits_for_number_system(number_format.numbering_system(), formatted_string);
|
formatted_string = ::Locale::replace_digits_for_number_system(number_format.numbering_system(), formatted_string);
|
||||||
|
|
||||||
// 3. Let decimalSepIndex be StringIndexOf(n, ".", 0).
|
// 3. Let decimalSepIndex be StringIndexOf(n, ".", 0).
|
||||||
auto decimal_sep_index = formatted_string.find('.');
|
auto decimal_sep_index = formatted_string.find('.');
|
||||||
|
@ -789,7 +789,7 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
|
||||||
// 7. Else,
|
// 7. Else,
|
||||||
else {
|
else {
|
||||||
// a. Let groupSepSymbol be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
|
// a. Let groupSepSymbol be the implementation-, locale-, and numbering system-dependent (ILND) String representing the grouping separator.
|
||||||
auto group_sep_symbol = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::Group).value_or(","sv);
|
auto group_sep_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Group).value_or(","sv);
|
||||||
|
|
||||||
// b. Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer, which may depend on the value of numberFormat.[[UseGrouping]].
|
// b. Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer, which may depend on the value of numberFormat.[[UseGrouping]].
|
||||||
auto groups = separate_integer_into_groups(*grouping_sizes, integer, number_format.use_grouping());
|
auto groups = separate_integer_into_groups(*grouping_sizes, integer, number_format.use_grouping());
|
||||||
|
@ -816,7 +816,7 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
|
||||||
// 8. If fraction is not undefined, then
|
// 8. If fraction is not undefined, then
|
||||||
if (fraction.has_value()) {
|
if (fraction.has_value()) {
|
||||||
// a. Let decimalSepSymbol be the ILND String representing the decimal separator.
|
// a. Let decimalSepSymbol be the ILND String representing the decimal separator.
|
||||||
auto decimal_sep_symbol = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::Decimal).value_or("."sv);
|
auto decimal_sep_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Decimal).value_or("."sv);
|
||||||
// b. Append a new Record { [[Type]]: "decimal", [[Value]]: decimalSepSymbol } as the last element of result.
|
// b. Append a new Record { [[Type]]: "decimal", [[Value]]: decimalSepSymbol } as the last element of result.
|
||||||
result.append({ "decimal"sv, decimal_sep_symbol });
|
result.append({ "decimal"sv, decimal_sep_symbol });
|
||||||
// c. Append a new Record { [[Type]]: "fraction", [[Value]]: fraction } as the last element of result.
|
// c. Append a new Record { [[Type]]: "fraction", [[Value]]: fraction } as the last element of result.
|
||||||
|
@ -840,7 +840,7 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
|
||||||
// vi. Else if p is equal to "scientificSeparator", then
|
// vi. Else if p is equal to "scientificSeparator", then
|
||||||
else if (part == "scientificSeparator"sv) {
|
else if (part == "scientificSeparator"sv) {
|
||||||
// 1. Let scientificSeparator be the ILND String representing the exponent separator.
|
// 1. Let scientificSeparator be the ILND String representing the exponent separator.
|
||||||
auto scientific_separator = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::Exponential).value_or("E"sv);
|
auto scientific_separator = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Exponential).value_or("E"sv);
|
||||||
// 2. Append a new Record { [[Type]]: "exponentSeparator", [[Value]]: scientificSeparator } as the last element of result.
|
// 2. Append a new Record { [[Type]]: "exponentSeparator", [[Value]]: scientificSeparator } as the last element of result.
|
||||||
result.append({ "exponentSeparator"sv, scientific_separator });
|
result.append({ "exponentSeparator"sv, scientific_separator });
|
||||||
}
|
}
|
||||||
|
@ -849,7 +849,7 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
|
||||||
// 1. If exponent < 0, then
|
// 1. If exponent < 0, then
|
||||||
if (exponent < 0) {
|
if (exponent < 0) {
|
||||||
// a. Let minusSignSymbol be the ILND String representing the minus sign.
|
// a. Let minusSignSymbol be the ILND String representing the minus sign.
|
||||||
auto minus_sign_symbol = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::MinusSign).value_or("-"sv);
|
auto minus_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::MinusSign).value_or("-"sv);
|
||||||
|
|
||||||
// b. Append a new Record { [[Type]]: "exponentMinusSign", [[Value]]: minusSignSymbol } as the last element of result.
|
// b. Append a new Record { [[Type]]: "exponentMinusSign", [[Value]]: minusSignSymbol } as the last element of result.
|
||||||
result.append({ "exponentMinusSign"sv, minus_sign_symbol });
|
result.append({ "exponentMinusSign"sv, minus_sign_symbol });
|
||||||
|
@ -864,7 +864,7 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
|
||||||
|
|
||||||
// FIXME: The spec does not say to do this, but all of major engines perform this replacement.
|
// FIXME: The spec does not say to do this, but all of major engines perform this replacement.
|
||||||
// Without this, formatting with non-Latin numbering systems will produce non-localized results.
|
// Without this, formatting with non-Latin numbering systems will produce non-localized results.
|
||||||
exponent_result.formatted_string = Unicode::replace_digits_for_number_system(number_format.numbering_system(), exponent_result.formatted_string);
|
exponent_result.formatted_string = ::Locale::replace_digits_for_number_system(number_format.numbering_system(), exponent_result.formatted_string);
|
||||||
|
|
||||||
// 3. Append a new Record { [[Type]]: "exponentInteger", [[Value]]: exponentResult.[[FormattedString]] } as the last element of result.
|
// 3. Append a new Record { [[Type]]: "exponentInteger", [[Value]]: exponentResult.[[FormattedString]] } as the last element of result.
|
||||||
result.append({ "exponentInteger"sv, move(exponent_result.formatted_string) });
|
result.append({ "exponentInteger"sv, move(exponent_result.formatted_string) });
|
||||||
|
@ -1258,21 +1258,21 @@ RawFormatResult to_raw_fixed(MathematicalValue const& number, int min_fraction,
|
||||||
|
|
||||||
// 15.5.11 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-getnumberformatpattern
|
// 15.5.11 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-getnumberformatpattern
|
||||||
// 1.1.14 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-getnumberformatpattern
|
// 1.1.14 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-getnumberformatpattern
|
||||||
Optional<Variant<StringView, String>> get_number_format_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, Unicode::NumberFormat& found_pattern)
|
Optional<Variant<StringView, String>> get_number_format_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern)
|
||||||
{
|
{
|
||||||
// 1. Let localeData be %NumberFormat%.[[LocaleData]].
|
// 1. Let localeData be %NumberFormat%.[[LocaleData]].
|
||||||
// 2. Let dataLocale be numberFormat.[[DataLocale]].
|
// 2. Let dataLocale be numberFormat.[[DataLocale]].
|
||||||
// 3. Let dataLocaleData be localeData.[[<dataLocale>]].
|
// 3. Let dataLocaleData be localeData.[[<dataLocale>]].
|
||||||
// 4. Let patterns be dataLocaleData.[[patterns]].
|
// 4. Let patterns be dataLocaleData.[[patterns]].
|
||||||
// 5. Assert: patterns is a Record (see 15.3.3).
|
// 5. Assert: patterns is a Record (see 15.3.3).
|
||||||
Optional<Unicode::NumberFormat> patterns;
|
Optional<::Locale::NumberFormat> patterns;
|
||||||
|
|
||||||
// 6. Let style be numberFormat.[[Style]].
|
// 6. Let style be numberFormat.[[Style]].
|
||||||
switch (number_format.style()) {
|
switch (number_format.style()) {
|
||||||
// 7. If style is "percent", then
|
// 7. If style is "percent", then
|
||||||
case NumberFormat::Style::Percent:
|
case NumberFormat::Style::Percent:
|
||||||
// a. Let patterns be patterns.[[percent]].
|
// a. Let patterns be patterns.[[percent]].
|
||||||
patterns = Unicode::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), Unicode::StandardNumberFormatType::Percent);
|
patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Percent);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 8. Else if style is "unit", then
|
// 8. Else if style is "unit", then
|
||||||
|
@ -1284,8 +1284,8 @@ Optional<Variant<StringView, String>> get_number_format_pattern(VM& vm, NumberFo
|
||||||
// i. Let unit be "fallback".
|
// i. Let unit be "fallback".
|
||||||
// e. Let patterns be patterns.[[<unit>]].
|
// e. Let patterns be patterns.[[<unit>]].
|
||||||
// f. Let patterns be patterns.[[<unitDisplay>]].
|
// f. Let patterns be patterns.[[<unitDisplay>]].
|
||||||
auto formats = Unicode::get_unit_formats(number_format.data_locale(), number_format.unit(), number_format.unit_display());
|
auto formats = ::Locale::get_unit_formats(number_format.data_locale(), number_format.unit(), number_format.unit_display());
|
||||||
auto plurality = resolve_plural(number_format, Unicode::PluralForm::Cardinal, number.to_value(vm));
|
auto plurality = resolve_plural(number_format, ::Locale::PluralForm::Cardinal, number.to_value(vm));
|
||||||
|
|
||||||
if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality; }); it != formats.end())
|
if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality; }); it != formats.end())
|
||||||
patterns = move(*it);
|
patterns = move(*it);
|
||||||
|
@ -1307,8 +1307,8 @@ Optional<Variant<StringView, String>> get_number_format_pattern(VM& vm, NumberFo
|
||||||
|
|
||||||
// Handling of other [[CurrencyDisplay]] options will occur after [[SignDisplay]].
|
// Handling of other [[CurrencyDisplay]] options will occur after [[SignDisplay]].
|
||||||
if (number_format.currency_display() == NumberFormat::CurrencyDisplay::Name) {
|
if (number_format.currency_display() == NumberFormat::CurrencyDisplay::Name) {
|
||||||
auto formats = Unicode::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), Unicode::CompactNumberFormatType::CurrencyUnit);
|
auto formats = ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::CurrencyUnit);
|
||||||
auto plurality = resolve_plural(number_format, Unicode::PluralForm::Cardinal, number.to_value(vm));
|
auto plurality = resolve_plural(number_format, ::Locale::PluralForm::Cardinal, number.to_value(vm));
|
||||||
|
|
||||||
if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality; }); it != formats.end()) {
|
if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality; }); it != formats.end()) {
|
||||||
patterns = move(*it);
|
patterns = move(*it);
|
||||||
|
@ -1318,10 +1318,10 @@ Optional<Variant<StringView, String>> get_number_format_pattern(VM& vm, NumberFo
|
||||||
|
|
||||||
switch (number_format.currency_sign()) {
|
switch (number_format.currency_sign()) {
|
||||||
case NumberFormat::CurrencySign::Standard:
|
case NumberFormat::CurrencySign::Standard:
|
||||||
patterns = Unicode::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), Unicode::StandardNumberFormatType::Currency);
|
patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Currency);
|
||||||
break;
|
break;
|
||||||
case NumberFormat::CurrencySign::Accounting:
|
case NumberFormat::CurrencySign::Accounting:
|
||||||
patterns = Unicode::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), Unicode::StandardNumberFormatType::Accounting);
|
patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Accounting);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1331,7 +1331,7 @@ Optional<Variant<StringView, String>> get_number_format_pattern(VM& vm, NumberFo
|
||||||
case NumberFormat::Style::Decimal:
|
case NumberFormat::Style::Decimal:
|
||||||
// a. Assert: style is "decimal".
|
// a. Assert: style is "decimal".
|
||||||
// b. Let patterns be patterns.[[decimal]].
|
// b. Let patterns be patterns.[[decimal]].
|
||||||
patterns = Unicode::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), Unicode::StandardNumberFormatType::Decimal);
|
patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Decimal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1423,7 +1423,7 @@ Optional<Variant<StringView, String>> get_number_format_pattern(VM& vm, NumberFo
|
||||||
// we might need to mutate the format pattern to inject a space between the currency display and
|
// we might need to mutate the format pattern to inject a space between the currency display and
|
||||||
// the currency number.
|
// the currency number.
|
||||||
if (number_format.style() == NumberFormat::Style::Currency) {
|
if (number_format.style() == NumberFormat::Style::Currency) {
|
||||||
auto modified_pattern = Unicode::augment_currency_format_pattern(number_format.resolve_currency_display(), pattern);
|
auto modified_pattern = ::Locale::augment_currency_format_pattern(number_format.resolve_currency_display(), pattern);
|
||||||
if (modified_pattern.has_value())
|
if (modified_pattern.has_value())
|
||||||
return modified_pattern.release_value();
|
return modified_pattern.release_value();
|
||||||
}
|
}
|
||||||
|
@ -1447,7 +1447,7 @@ Optional<StringView> get_notation_sub_pattern(NumberFormat& number_format, int e
|
||||||
// 7. If notation is "scientific" or notation is "engineering", then
|
// 7. If notation is "scientific" or notation is "engineering", then
|
||||||
if ((notation == NumberFormat::Notation::Scientific) || (notation == NumberFormat::Notation::Engineering)) {
|
if ((notation == NumberFormat::Notation::Scientific) || (notation == NumberFormat::Notation::Engineering)) {
|
||||||
// a. Return notationSubPatterns.[[scientific]].
|
// a. Return notationSubPatterns.[[scientific]].
|
||||||
auto notation_sub_patterns = Unicode::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), Unicode::StandardNumberFormatType::Scientific);
|
auto notation_sub_patterns = ::Locale::get_standard_number_system_format(number_format.data_locale(), number_format.numbering_system(), ::Locale::StandardNumberFormatType::Scientific);
|
||||||
if (!notation_sub_patterns.has_value())
|
if (!notation_sub_patterns.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -1547,16 +1547,16 @@ int compute_exponent_for_magnitude(NumberFormat& number_format, int magnitude)
|
||||||
|
|
||||||
// b. Let exponent be an implementation- and locale-dependent (ILD) integer by which to scale a number of the given magnitude in compact notation for the current locale.
|
// b. Let exponent be an implementation- and locale-dependent (ILD) integer by which to scale a number of the given magnitude in compact notation for the current locale.
|
||||||
// c. Return exponent.
|
// c. Return exponent.
|
||||||
Vector<Unicode::NumberFormat> format_rules;
|
Vector<::Locale::NumberFormat> format_rules;
|
||||||
|
|
||||||
if (number_format.style() == NumberFormat::Style::Currency)
|
if (number_format.style() == NumberFormat::Style::Currency)
|
||||||
format_rules = Unicode::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), Unicode::CompactNumberFormatType::CurrencyShort);
|
format_rules = ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::CurrencyShort);
|
||||||
else if (number_format.compact_display() == NumberFormat::CompactDisplay::Long)
|
else if (number_format.compact_display() == NumberFormat::CompactDisplay::Long)
|
||||||
format_rules = Unicode::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), Unicode::CompactNumberFormatType::DecimalLong);
|
format_rules = ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::DecimalLong);
|
||||||
else
|
else
|
||||||
format_rules = Unicode::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), Unicode::CompactNumberFormatType::DecimalShort);
|
format_rules = ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::DecimalShort);
|
||||||
|
|
||||||
Unicode::NumberFormat const* best_number_format = nullptr;
|
::Locale::NumberFormat const* best_number_format = nullptr;
|
||||||
|
|
||||||
for (auto const& format_rule : format_rules) {
|
for (auto const& format_rule : format_rules) {
|
||||||
if (format_rule.magnitude > magnitude)
|
if (format_rule.magnitude > magnitude)
|
||||||
|
@ -1751,8 +1751,8 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pat
|
||||||
result = move(start_result);
|
result = move(start_result);
|
||||||
|
|
||||||
// 8. Let rangeSeparator be an ILND String value used to separate two numbers.
|
// 8. Let rangeSeparator be an ILND String value used to separate two numbers.
|
||||||
auto range_separator_symbol = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::RangeSeparator).value_or("-"sv);
|
auto range_separator_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::RangeSeparator).value_or("-"sv);
|
||||||
auto range_separator = Unicode::augment_range_pattern(range_separator_symbol, result.last().value, end_result[0].value);
|
auto range_separator = ::Locale::augment_range_pattern(range_separator_symbol, result.last().value, end_result[0].value);
|
||||||
|
|
||||||
// 9. Append a new Record { [[Type]]: "literal", [[Value]]: rangeSeparator, [[Source]]: "shared" } element to result.
|
// 9. Append a new Record { [[Type]]: "literal", [[Value]]: rangeSeparator, [[Source]]: "shared" } element to result.
|
||||||
PatternPartitionWithSource part;
|
PatternPartitionWithSource part;
|
||||||
|
@ -1779,7 +1779,7 @@ Vector<PatternPartitionWithSource> format_approximately(NumberFormat& number_for
|
||||||
{
|
{
|
||||||
// 1. Let i be an index into result, determined by an implementation-defined algorithm based on numberFormat and result.
|
// 1. Let i be an index into result, determined by an implementation-defined algorithm based on numberFormat and result.
|
||||||
// 2. Let approximatelySign be an ILND String value used to signify that a number is approximate.
|
// 2. Let approximatelySign be an ILND String value used to signify that a number is approximate.
|
||||||
auto approximately_sign = Unicode::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), Unicode::NumericSymbol::ApproximatelySign).value_or("~"sv);
|
auto approximately_sign = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::ApproximatelySign).value_or("~"sv);
|
||||||
|
|
||||||
// 3. Insert a new Record { [[Type]]: "approximatelySign", [[Value]]: approximatelySign } at index i in result.
|
// 3. Insert a new Record { [[Type]]: "approximatelySign", [[Value]]: approximatelySign } at index i in result.
|
||||||
PatternPartitionWithSource partition;
|
PatternPartitionWithSource partition;
|
||||||
|
|
|
@ -205,9 +205,9 @@ public:
|
||||||
void set_unit(String 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(); }
|
||||||
Unicode::Style unit_display() const { return *m_unit_display; }
|
::Locale::Style unit_display() const { return *m_unit_display; }
|
||||||
StringView unit_display_string() const { return Unicode::style_to_string(*m_unit_display); }
|
StringView unit_display_string() const { return ::Locale::style_to_string(*m_unit_display); }
|
||||||
void set_unit_display(StringView unit_display) { m_unit_display = Unicode::style_from_string(unit_display); }
|
void set_unit_display(StringView unit_display) { m_unit_display = ::Locale::style_from_string(unit_display); }
|
||||||
|
|
||||||
UseGrouping use_grouping() const { return m_use_grouping; }
|
UseGrouping use_grouping() const { return m_use_grouping; }
|
||||||
Value use_grouping_to_value(VM&) const;
|
Value use_grouping_to_value(VM&) const;
|
||||||
|
@ -230,8 +230,8 @@ public:
|
||||||
void set_bound_format(NativeFunction* bound_format) { m_bound_format = bound_format; }
|
void set_bound_format(NativeFunction* bound_format) { m_bound_format = bound_format; }
|
||||||
|
|
||||||
bool has_compact_format() const { return m_compact_format.has_value(); }
|
bool has_compact_format() const { return m_compact_format.has_value(); }
|
||||||
void set_compact_format(Unicode::NumberFormat compact_format) { m_compact_format = compact_format; }
|
void set_compact_format(::Locale::NumberFormat compact_format) { m_compact_format = compact_format; }
|
||||||
Unicode::NumberFormat compact_format() const { return *m_compact_format; }
|
::Locale::NumberFormat compact_format() const { return *m_compact_format; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit NumberFormat(Object& prototype);
|
explicit NumberFormat(Object& prototype);
|
||||||
|
@ -246,7 +246,7 @@ private:
|
||||||
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<String> m_unit {}; // [[Unit]]
|
Optional<String> m_unit {}; // [[Unit]]
|
||||||
Optional<Unicode::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]]
|
||||||
Optional<CompactDisplay> m_compact_display {}; // [[CompactDisplay]]
|
Optional<CompactDisplay> m_compact_display {}; // [[CompactDisplay]]
|
||||||
|
@ -257,7 +257,7 @@ private:
|
||||||
Optional<StringView> m_resolved_currency_display;
|
Optional<StringView> m_resolved_currency_display;
|
||||||
|
|
||||||
// Non-standard. Stores the resolved compact number format based on [[Locale]], [[Notation], [[Style]], and [[CompactDisplay]].
|
// Non-standard. Stores the resolved compact number format based on [[Locale]], [[Notation], [[Style]], and [[CompactDisplay]].
|
||||||
Optional<Unicode::NumberFormat> m_compact_format;
|
Optional<::Locale::NumberFormat> m_compact_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FormatResult {
|
struct FormatResult {
|
||||||
|
@ -283,7 +283,7 @@ String format_numeric(VM&, NumberFormat&, MathematicalValue number);
|
||||||
Array* format_numeric_to_parts(VM&, NumberFormat&, MathematicalValue number);
|
Array* format_numeric_to_parts(VM&, NumberFormat&, MathematicalValue number);
|
||||||
RawFormatResult to_raw_precision(MathematicalValue const& number, int min_precision, int max_precision, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
|
RawFormatResult to_raw_precision(MathematicalValue const& number, int min_precision, int max_precision, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
|
||||||
RawFormatResult to_raw_fixed(MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
|
RawFormatResult to_raw_fixed(MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
|
||||||
Optional<Variant<StringView, String>> get_number_format_pattern(VM&, NumberFormat&, MathematicalValue const& number, Unicode::NumberFormat& found_pattern);
|
Optional<Variant<StringView, String>> get_number_format_pattern(VM&, NumberFormat&, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern);
|
||||||
Optional<StringView> get_notation_sub_pattern(NumberFormat&, int exponent);
|
Optional<StringView> get_notation_sub_pattern(NumberFormat&, int exponent);
|
||||||
int compute_exponent(NumberFormat&, MathematicalValue number);
|
int compute_exponent(NumberFormat&, MathematicalValue number);
|
||||||
int compute_exponent_for_magnitude(NumberFormat&, int magnitude);
|
int compute_exponent_for_magnitude(NumberFormat&, int magnitude);
|
||||||
|
|
|
@ -103,7 +103,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat&
|
||||||
// 7. If numberingSystem is not undefined, then
|
// 7. If numberingSystem is not undefined, then
|
||||||
if (!numbering_system.is_undefined()) {
|
if (!numbering_system.is_undefined()) {
|
||||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
if (!::Locale::is_type_identifier(numbering_system.as_string().string()))
|
||||||
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.
|
||||||
|
|
|
@ -18,7 +18,7 @@ PluralRules::PluralRules(Object& prototype)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16.5.1 GetOperands ( s ), https://tc39.es/ecma402/#sec-getoperands
|
// 16.5.1 GetOperands ( s ), https://tc39.es/ecma402/#sec-getoperands
|
||||||
Unicode::PluralOperands get_operands(String const& string)
|
::Locale::PluralOperands get_operands(String const& string)
|
||||||
{
|
{
|
||||||
// 1.Let n be ! ToNumber(s).
|
// 1.Let n be ! ToNumber(s).
|
||||||
char* end { nullptr };
|
char* end { nullptr };
|
||||||
|
@ -77,7 +77,7 @@ Unicode::PluralOperands get_operands(String const& string)
|
||||||
auto significant_fraction = significant_fraction_slice.is_empty() ? 0u : significant_fraction_slice.template to_uint<u64>().value();
|
auto significant_fraction = significant_fraction_slice.is_empty() ? 0u : significant_fraction_slice.template to_uint<u64>().value();
|
||||||
|
|
||||||
// 12. Return a new Record { [[Number]]: abs(n), [[IntegerDigits]]: i, [[FractionDigits]]: f, [[NumberOfFractionDigits]]: fracDigitCount, [[FractionDigitsWithoutTrailing]]: significantFrac, [[NumberOfFractionDigitsWithoutTrailing]]: significantFracDigitCount }.
|
// 12. Return a new Record { [[Number]]: abs(n), [[IntegerDigits]]: i, [[FractionDigits]]: f, [[NumberOfFractionDigits]]: fracDigitCount, [[FractionDigitsWithoutTrailing]]: significantFrac, [[NumberOfFractionDigitsWithoutTrailing]]: significantFracDigitCount }.
|
||||||
return Unicode::PluralOperands {
|
return ::Locale::PluralOperands {
|
||||||
.number = fabs(number),
|
.number = fabs(number),
|
||||||
.integer_digits = integer,
|
.integer_digits = integer,
|
||||||
.fraction_digits = fraction,
|
.fraction_digits = fraction,
|
||||||
|
@ -88,19 +88,19 @@ Unicode::PluralOperands get_operands(String const& string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16.5.2 PluralRuleSelect ( locale, type, n, operands ), https://tc39.es/ecma402/#sec-pluralruleselect
|
// 16.5.2 PluralRuleSelect ( locale, type, n, operands ), https://tc39.es/ecma402/#sec-pluralruleselect
|
||||||
Unicode::PluralCategory plural_rule_select(StringView locale, Unicode::PluralForm type, Value, Unicode::PluralOperands operands)
|
::Locale::PluralCategory plural_rule_select(StringView locale, ::Locale::PluralForm type, Value, ::Locale::PluralOperands operands)
|
||||||
{
|
{
|
||||||
return Unicode::determine_plural_category(locale, type, move(operands));
|
return ::Locale::determine_plural_category(locale, type, move(operands));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16.5.3 ResolvePlural ( pluralRules, n ), https://tc39.es/ecma402/#sec-resolveplural
|
// 16.5.3 ResolvePlural ( pluralRules, n ), https://tc39.es/ecma402/#sec-resolveplural
|
||||||
Unicode::PluralCategory resolve_plural(PluralRules const& plural_rules, Value number)
|
::Locale::PluralCategory resolve_plural(PluralRules const& plural_rules, Value number)
|
||||||
{
|
{
|
||||||
return resolve_plural(plural_rules, plural_rules.type(), number);
|
return resolve_plural(plural_rules, plural_rules.type(), number);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-standard overload of ResolvePlural to allow using the AO without an Intl.PluralRules object.
|
// Non-standard overload of ResolvePlural to allow using the AO without an Intl.PluralRules object.
|
||||||
Unicode::PluralCategory resolve_plural(NumberFormatBase const& number_format, Unicode::PluralForm type, Value number)
|
::Locale::PluralCategory resolve_plural(NumberFormatBase const& number_format, ::Locale::PluralForm type, Value number)
|
||||||
{
|
{
|
||||||
// 1. Assert: Type(pluralRules) is Object.
|
// 1. Assert: Type(pluralRules) is Object.
|
||||||
// 2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot.
|
// 2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot.
|
||||||
|
@ -109,7 +109,7 @@ Unicode::PluralCategory resolve_plural(NumberFormatBase const& number_format, Un
|
||||||
// 4. If n is not a finite Number, then
|
// 4. If n is not a finite Number, then
|
||||||
if (!number.is_finite_number()) {
|
if (!number.is_finite_number()) {
|
||||||
// a. Return "other".
|
// a. Return "other".
|
||||||
return Unicode::PluralCategory::Other;
|
return ::Locale::PluralCategory::Other;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Let locale be pluralRules.[[Locale]].
|
// 5. Let locale be pluralRules.[[Locale]].
|
||||||
|
@ -131,13 +131,13 @@ Unicode::PluralCategory resolve_plural(NumberFormatBase const& number_format, Un
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.1.5 PluralRuleSelectRange ( locale, type, xp, yp ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-pluralruleselectrange
|
// 1.1.5 PluralRuleSelectRange ( locale, type, xp, yp ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-pluralruleselectrange
|
||||||
Unicode::PluralCategory plural_rule_select_range(StringView locale, Unicode::PluralForm, Unicode::PluralCategory start, Unicode::PluralCategory end)
|
::Locale::PluralCategory plural_rule_select_range(StringView locale, ::Locale::PluralForm, ::Locale::PluralCategory start, ::Locale::PluralCategory end)
|
||||||
{
|
{
|
||||||
return Unicode::determine_plural_range(locale, start, end);
|
return ::Locale::determine_plural_range(locale, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.1.6 ResolvePluralRange ( pluralRules, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-resolvepluralrange
|
// 1.1.6 ResolvePluralRange ( pluralRules, x, y ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-resolvepluralrange
|
||||||
ThrowCompletionOr<Unicode::PluralCategory> resolve_plural_range(VM& vm, PluralRules const& plural_rules, Value start, Value end)
|
ThrowCompletionOr<::Locale::PluralCategory> resolve_plural_range(VM& vm, PluralRules const& plural_rules, Value start, Value end)
|
||||||
{
|
{
|
||||||
// 1. Assert: Type(pluralRules) is Object.
|
// 1. Assert: Type(pluralRules) is Object.
|
||||||
// 2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot.
|
// 2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot.
|
||||||
|
|
|
@ -21,21 +21,21 @@ class PluralRules final : public NumberFormatBase {
|
||||||
public:
|
public:
|
||||||
virtual ~PluralRules() override = default;
|
virtual ~PluralRules() override = default;
|
||||||
|
|
||||||
Unicode::PluralForm type() const { return m_type; }
|
::Locale::PluralForm type() const { return m_type; }
|
||||||
StringView type_string() const { return Unicode::plural_form_to_string(m_type); }
|
StringView type_string() const { return ::Locale::plural_form_to_string(m_type); }
|
||||||
void set_type(StringView type) { m_type = Unicode::plural_form_from_string(type); }
|
void set_type(StringView type) { m_type = ::Locale::plural_form_from_string(type); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit PluralRules(Object& prototype);
|
explicit PluralRules(Object& prototype);
|
||||||
|
|
||||||
Unicode::PluralForm m_type { Unicode::PluralForm::Cardinal }; // [[Type]]
|
::Locale::PluralForm m_type { ::Locale::PluralForm::Cardinal }; // [[Type]]
|
||||||
};
|
};
|
||||||
|
|
||||||
Unicode::PluralOperands get_operands(String const& string);
|
::Locale::PluralOperands get_operands(String const& string);
|
||||||
Unicode::PluralCategory plural_rule_select(StringView locale, Unicode::PluralForm type, Value number, Unicode::PluralOperands operands);
|
::Locale::PluralCategory plural_rule_select(StringView locale, ::Locale::PluralForm type, Value number, ::Locale::PluralOperands operands);
|
||||||
Unicode::PluralCategory resolve_plural(PluralRules const&, Value number);
|
::Locale::PluralCategory resolve_plural(PluralRules const&, Value number);
|
||||||
Unicode::PluralCategory resolve_plural(NumberFormatBase const& number_format, Unicode::PluralForm type, Value number);
|
::Locale::PluralCategory resolve_plural(NumberFormatBase const& number_format, ::Locale::PluralForm type, Value number);
|
||||||
Unicode::PluralCategory plural_rule_select_range(StringView locale, Unicode::PluralForm, Unicode::PluralCategory start, Unicode::PluralCategory end);
|
::Locale::PluralCategory plural_rule_select_range(StringView locale, ::Locale::PluralForm, ::Locale::PluralCategory start, ::Locale::PluralCategory end);
|
||||||
ThrowCompletionOr<Unicode::PluralCategory> resolve_plural_range(VM&, PluralRules const&, Value start, Value end);
|
ThrowCompletionOr<::Locale::PluralCategory> resolve_plural_range(VM&, PluralRules const&, Value start, Value end);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select)
|
||||||
|
|
||||||
// 4. Return ! ResolvePlural(pr, n).
|
// 4. Return ! ResolvePlural(pr, n).
|
||||||
auto plurality = resolve_plural(*plural_rules, number);
|
auto plurality = resolve_plural(*plural_rules, number);
|
||||||
return js_string(vm, Unicode::plural_category_to_string(plurality));
|
return js_string(vm, ::Locale::plural_category_to_string(plurality));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.4.4 Intl.PluralRules.prototype.selectRange ( start, end ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-intl.pluralrules.prototype.selectrange
|
// 1.4.4 Intl.PluralRules.prototype.selectRange ( start, end ), https://tc39.es/proposal-intl-numberformat-v3/out/pluralrules/proposed.html#sec-intl.pluralrules.prototype.selectrange
|
||||||
|
@ -72,7 +72,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range)
|
||||||
|
|
||||||
// 6. Return ? ResolvePluralRange(pr, x, y).
|
// 6. Return ? ResolvePluralRange(pr, x, y).
|
||||||
auto plurality = TRY(resolve_plural_range(vm, *plural_rules, x, y));
|
auto plurality = TRY(resolve_plural_range(vm, *plural_rules, x, y));
|
||||||
return js_string(vm, Unicode::plural_category_to_string(plurality));
|
return js_string(vm, ::Locale::plural_category_to_string(plurality));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16.3.4 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions
|
// 16.3.4 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions
|
||||||
|
@ -106,10 +106,10 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
|
||||||
MUST(options->create_data_property_or_throw(vm.names.maximumSignificantDigits, Value(plural_rules->max_significant_digits())));
|
MUST(options->create_data_property_or_throw(vm.names.maximumSignificantDigits, Value(plural_rules->max_significant_digits())));
|
||||||
|
|
||||||
// 5. Let pluralCategories be a List of Strings containing all possible results of PluralRuleSelect for the selected locale pr.[[Locale]].
|
// 5. Let pluralCategories be a List of Strings containing all possible results of PluralRuleSelect for the selected locale pr.[[Locale]].
|
||||||
auto available_categories = Unicode::available_plural_categories(plural_rules->locale(), plural_rules->type());
|
auto available_categories = ::Locale::available_plural_categories(plural_rules->locale(), plural_rules->type());
|
||||||
|
|
||||||
auto* plural_categories = Array::create_from<Unicode::PluralCategory>(realm, available_categories, [&](auto category) {
|
auto* plural_categories = Array::create_from<::Locale::PluralCategory>(realm, available_categories, [&](auto category) {
|
||||||
return js_string(vm, Unicode::plural_category_to_string(category));
|
return js_string(vm, ::Locale::plural_category_to_string(category));
|
||||||
});
|
});
|
||||||
|
|
||||||
// 6. Perform ! CreateDataProperty(options, "pluralCategories", CreateArrayFromList(pluralCategories)).
|
// 6. Perform ! CreateDataProperty(options, "pluralCategories", CreateArrayFromList(pluralCategories)).
|
||||||
|
|
|
@ -54,38 +54,38 @@ StringView RelativeTimeFormat::numeric_string() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// 17.5.1 SingularRelativeTimeUnit ( unit ), https://tc39.es/ecma402/#sec-singularrelativetimeunit
|
// 17.5.1 SingularRelativeTimeUnit ( unit ), https://tc39.es/ecma402/#sec-singularrelativetimeunit
|
||||||
ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(VM& vm, StringView unit)
|
ThrowCompletionOr<::Locale::TimeUnit> singular_relative_time_unit(VM& vm, StringView unit)
|
||||||
{
|
{
|
||||||
// 1. Assert: Type(unit) is String.
|
// 1. Assert: Type(unit) is String.
|
||||||
|
|
||||||
// 2. If unit is "seconds", return "second".
|
// 2. If unit is "seconds", return "second".
|
||||||
if (unit == "seconds"sv)
|
if (unit == "seconds"sv)
|
||||||
return Unicode::TimeUnit::Second;
|
return ::Locale::TimeUnit::Second;
|
||||||
// 3. If unit is "minutes", return "minute".
|
// 3. If unit is "minutes", return "minute".
|
||||||
if (unit == "minutes"sv)
|
if (unit == "minutes"sv)
|
||||||
return Unicode::TimeUnit::Minute;
|
return ::Locale::TimeUnit::Minute;
|
||||||
// 4. If unit is "hours", return "hour".
|
// 4. If unit is "hours", return "hour".
|
||||||
if (unit == "hours"sv)
|
if (unit == "hours"sv)
|
||||||
return Unicode::TimeUnit::Hour;
|
return ::Locale::TimeUnit::Hour;
|
||||||
// 5. If unit is "days", return "day".
|
// 5. If unit is "days", return "day".
|
||||||
if (unit == "days"sv)
|
if (unit == "days"sv)
|
||||||
return Unicode::TimeUnit::Day;
|
return ::Locale::TimeUnit::Day;
|
||||||
// 6. If unit is "weeks", return "week".
|
// 6. If unit is "weeks", return "week".
|
||||||
if (unit == "weeks"sv)
|
if (unit == "weeks"sv)
|
||||||
return Unicode::TimeUnit::Week;
|
return ::Locale::TimeUnit::Week;
|
||||||
// 7. If unit is "months", return "month".
|
// 7. If unit is "months", return "month".
|
||||||
if (unit == "months"sv)
|
if (unit == "months"sv)
|
||||||
return Unicode::TimeUnit::Month;
|
return ::Locale::TimeUnit::Month;
|
||||||
// 8. If unit is "quarters", return "quarter".
|
// 8. If unit is "quarters", return "quarter".
|
||||||
if (unit == "quarters"sv)
|
if (unit == "quarters"sv)
|
||||||
return Unicode::TimeUnit::Quarter;
|
return ::Locale::TimeUnit::Quarter;
|
||||||
// 9. If unit is "years", return "year".
|
// 9. If unit is "years", return "year".
|
||||||
if (unit == "years"sv)
|
if (unit == "years"sv)
|
||||||
return Unicode::TimeUnit::Year;
|
return ::Locale::TimeUnit::Year;
|
||||||
|
|
||||||
// 10. If unit is not one of "second", "minute", "hour", "day", "week", "month", "quarter", or "year", throw a RangeError exception.
|
// 10. If unit is not one of "second", "minute", "hour", "day", "week", "month", "quarter", or "year", throw a RangeError exception.
|
||||||
// 11. Return unit.
|
// 11. Return unit.
|
||||||
if (auto time_unit = Unicode::time_unit_from_string(unit); time_unit.has_value())
|
if (auto time_unit = ::Locale::time_unit_from_string(unit); time_unit.has_value())
|
||||||
return *time_unit;
|
return *time_unit;
|
||||||
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidUnit, unit);
|
return vm.throw_completion<RangeError>(ErrorType::IntlInvalidUnit, unit);
|
||||||
}
|
}
|
||||||
|
@ -124,13 +124,13 @@ ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_patt
|
||||||
// a. Let entry be the string-concatenation of unit and "-narrow".
|
// a. Let entry be the string-concatenation of unit and "-narrow".
|
||||||
// 12. Else,
|
// 12. Else,
|
||||||
// a. Let entry be unit.
|
// a. Let entry be unit.
|
||||||
auto patterns = Unicode::get_relative_time_format_patterns(data_locale, time_unit, tense_or_number, style);
|
auto patterns = ::Locale::get_relative_time_format_patterns(data_locale, time_unit, tense_or_number, style);
|
||||||
|
|
||||||
// 13. If fields doesn't have a field [[<entry>]], then
|
// 13. If fields doesn't have a field [[<entry>]], then
|
||||||
if (patterns.is_empty()) {
|
if (patterns.is_empty()) {
|
||||||
// a. Let entry be unit.
|
// a. Let entry be unit.
|
||||||
// NOTE: In the CLDR, the lack of "short" or "narrow" in the key implies "long".
|
// NOTE: In the CLDR, the lack of "short" or "narrow" in the key implies "long".
|
||||||
patterns = Unicode::get_relative_time_format_patterns(data_locale, time_unit, tense_or_number, Unicode::Style::Long);
|
patterns = ::Locale::get_relative_time_format_patterns(data_locale, time_unit, tense_or_number, ::Locale::Style::Long);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14. Let patterns be fields.[[<entry>]].
|
// 14. Let patterns be fields.[[<entry>]].
|
||||||
|
@ -185,7 +185,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_patt
|
||||||
return Vector<PatternPartitionWithUnit> {};
|
return Vector<PatternPartitionWithUnit> {};
|
||||||
|
|
||||||
// 23. Return ! MakePartsList(pattern, unit, fv).
|
// 23. Return ! MakePartsList(pattern, unit, fv).
|
||||||
return make_parts_list(pattern->pattern, Unicode::time_unit_to_string(time_unit), move(value_partitions));
|
return make_parts_list(pattern->pattern, ::Locale::time_unit_to_string(time_unit), move(value_partitions));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 17.5.3 MakePartsList ( pattern, unit, parts ), https://tc39.es/ecma402/#sec-makepartslist
|
// 17.5.3 MakePartsList ( pattern, unit, parts ), https://tc39.es/ecma402/#sec-makepartslist
|
||||||
|
|
|
@ -44,9 +44,9 @@ public:
|
||||||
String const& numbering_system() const { return m_numbering_system; }
|
String const& numbering_system() const { return m_numbering_system; }
|
||||||
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
void set_numbering_system(String numbering_system) { m_numbering_system = move(numbering_system); }
|
||||||
|
|
||||||
Unicode::Style style() const { return m_style; }
|
::Locale::Style style() const { return m_style; }
|
||||||
void set_style(StringView style) { m_style = Unicode::style_from_string(style); }
|
void set_style(StringView style) { m_style = ::Locale::style_from_string(style); }
|
||||||
StringView style_string() const { return Unicode::style_to_string(m_style); }
|
StringView style_string() const { return ::Locale::style_to_string(m_style); }
|
||||||
|
|
||||||
Numeric numeric() const { return m_numeric; }
|
Numeric numeric() const { return m_numeric; }
|
||||||
void set_numeric(StringView numeric);
|
void set_numeric(StringView numeric);
|
||||||
|
@ -63,13 +63,13 @@ private:
|
||||||
|
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
String m_locale; // [[Locale]]
|
String m_locale; // [[Locale]]
|
||||||
String m_data_locale; // [[DataLocale]]
|
String m_data_locale; // [[DataLocale]]
|
||||||
String m_numbering_system; // [[NumberingSystem]]
|
String m_numbering_system; // [[NumberingSystem]]
|
||||||
Unicode::Style m_style { Unicode::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]]
|
||||||
PluralRules* m_plural_rules { nullptr }; // [[PluralRules]]
|
PluralRules* m_plural_rules { nullptr }; // [[PluralRules]]
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PatternPartitionWithUnit : public PatternPartition {
|
struct PatternPartitionWithUnit : public PatternPartition {
|
||||||
|
@ -82,7 +82,7 @@ struct PatternPartitionWithUnit : public PatternPartition {
|
||||||
StringView unit;
|
StringView unit;
|
||||||
};
|
};
|
||||||
|
|
||||||
ThrowCompletionOr<Unicode::TimeUnit> singular_relative_time_unit(VM&, StringView unit);
|
ThrowCompletionOr<::Locale::TimeUnit> singular_relative_time_unit(VM&, StringView unit);
|
||||||
ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_pattern(VM&, RelativeTimeFormat&, double value, StringView unit);
|
ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_pattern(VM&, RelativeTimeFormat&, double value, StringView unit);
|
||||||
Vector<PatternPartitionWithUnit> make_parts_list(StringView pattern, StringView unit, Vector<PatternPartition> parts);
|
Vector<PatternPartitionWithUnit> make_parts_list(StringView pattern, StringView unit, Vector<PatternPartition> parts);
|
||||||
ThrowCompletionOr<String> format_relative_time(VM&, RelativeTimeFormat&, double value, StringView unit);
|
ThrowCompletionOr<String> format_relative_time(VM&, RelativeTimeFormat&, double value, StringView unit);
|
||||||
|
|
|
@ -101,7 +101,7 @@ ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(VM& vm, R
|
||||||
// 7. If numberingSystem is not undefined, then
|
// 7. If numberingSystem is not undefined, then
|
||||||
if (!numbering_system.is_undefined()) {
|
if (!numbering_system.is_undefined()) {
|
||||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||||
if (!Unicode::is_type_identifier(numbering_system.as_string().string()))
|
if (!::Locale::is_type_identifier(numbering_system.as_string().string()))
|
||||||
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.
|
||||||
|
|
|
@ -328,22 +328,22 @@ static ThrowCompletionOr<String> transform_case(VM& vm, StringView string, Value
|
||||||
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||||
auto requested_locales = TRY(Intl::canonicalize_locale_list(vm, locales));
|
auto requested_locales = TRY(Intl::canonicalize_locale_list(vm, locales));
|
||||||
|
|
||||||
Optional<Unicode::LocaleID> requested_locale;
|
Optional<Locale::LocaleID> requested_locale;
|
||||||
|
|
||||||
// 2. If requestedLocales is not an empty List, then
|
// 2. If requestedLocales is not an empty List, then
|
||||||
if (!requested_locales.is_empty()) {
|
if (!requested_locales.is_empty()) {
|
||||||
// a. Let requestedLocale be requestedLocales[0].
|
// a. Let requestedLocale be requestedLocales[0].
|
||||||
requested_locale = Unicode::parse_unicode_locale_id(requested_locales[0]);
|
requested_locale = Locale::parse_unicode_locale_id(requested_locales[0]);
|
||||||
}
|
}
|
||||||
// 3. Else,
|
// 3. Else,
|
||||||
else {
|
else {
|
||||||
// a. Let requestedLocale be ! DefaultLocale().
|
// a. Let requestedLocale be ! DefaultLocale().
|
||||||
requested_locale = Unicode::parse_unicode_locale_id(Unicode::default_locale());
|
requested_locale = Locale::parse_unicode_locale_id(Locale::default_locale());
|
||||||
}
|
}
|
||||||
VERIFY(requested_locale.has_value());
|
VERIFY(requested_locale.has_value());
|
||||||
|
|
||||||
// 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<Unicode::LocaleExtension>();
|
requested_locale->remove_extension_type<Locale::LocaleExtension>();
|
||||||
auto no_extensions_locale = requested_locale->to_string();
|
auto no_extensions_locale = 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.
|
||||||
|
|
|
@ -163,17 +163,17 @@ static bool is_followed_by_combining_dot_above(Utf8View const& string, size_t in
|
||||||
|
|
||||||
static SpecialCasing const* find_matching_special_case(u32 code_point, Utf8View const& string, Optional<StringView> locale, size_t index, size_t byte_length)
|
static SpecialCasing const* find_matching_special_case(u32 code_point, Utf8View const& string, Optional<StringView> locale, size_t index, size_t byte_length)
|
||||||
{
|
{
|
||||||
auto requested_locale = Locale::None;
|
auto requested_locale = Locale::Locale::None;
|
||||||
|
|
||||||
if (locale.has_value()) {
|
if (locale.has_value()) {
|
||||||
if (auto maybe_locale = locale_from_string(*locale); maybe_locale.has_value())
|
if (auto maybe_locale = Locale::locale_from_string(*locale); maybe_locale.has_value())
|
||||||
requested_locale = *maybe_locale;
|
requested_locale = *maybe_locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto special_casings = special_case_mapping(code_point);
|
auto special_casings = special_case_mapping(code_point);
|
||||||
|
|
||||||
for (auto const* special_casing : special_casings) {
|
for (auto const* special_casing : special_casings) {
|
||||||
if (special_casing->locale != Locale::None && special_casing->locale != requested_locale)
|
if (special_casing->locale != Locale::Locale::None && special_casing->locale != requested_locale)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (special_casing->condition) {
|
switch (special_casing->condition) {
|
||||||
|
|
|
@ -11,18 +11,18 @@
|
||||||
#include <LibUnicode/NumberFormat.h>
|
#include <LibUnicode/NumberFormat.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
HourCycle hour_cycle_from_string(StringView hour_cycle)
|
HourCycle hour_cycle_from_string(StringView hour_cycle)
|
||||||
{
|
{
|
||||||
if (hour_cycle == "h11"sv)
|
if (hour_cycle == "h11"sv)
|
||||||
return Unicode::HourCycle::H11;
|
return HourCycle::H11;
|
||||||
else if (hour_cycle == "h12"sv)
|
else if (hour_cycle == "h12"sv)
|
||||||
return Unicode::HourCycle::H12;
|
return HourCycle::H12;
|
||||||
else if (hour_cycle == "h23"sv)
|
else if (hour_cycle == "h23"sv)
|
||||||
return Unicode::HourCycle::H23;
|
return HourCycle::H23;
|
||||||
else if (hour_cycle == "h24"sv)
|
else if (hour_cycle == "h24"sv)
|
||||||
return Unicode::HourCycle::H24;
|
return HourCycle::H24;
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,12 +125,12 @@ static auto find_regional_values_for_locale(StringView locale, GetRegionalValues
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
|
// https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
|
||||||
Vector<Unicode::HourCycle> get_locale_hour_cycles(StringView locale)
|
Vector<HourCycle> get_locale_hour_cycles(StringView locale)
|
||||||
{
|
{
|
||||||
return find_regional_values_for_locale(locale, get_regional_hour_cycles);
|
return find_regional_values_for_locale(locale, get_regional_hour_cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Unicode::HourCycle> get_default_regional_hour_cycle(StringView locale)
|
Optional<HourCycle> get_default_regional_hour_cycle(StringView locale)
|
||||||
{
|
{
|
||||||
if (auto hour_cycles = get_locale_hour_cycles(locale); !hour_cycles.is_empty())
|
if (auto hour_cycles = get_locale_hour_cycles(locale); !hour_cycles.is_empty())
|
||||||
return hour_cycles.first();
|
return hour_cycles.first();
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <LibTimeZone/TimeZone.h>
|
#include <LibTimeZone/TimeZone.h>
|
||||||
#include <LibUnicode/Forward.h>
|
#include <LibUnicode/Forward.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
enum class Era : u8 {
|
enum class Era : u8 {
|
||||||
BC,
|
BC,
|
||||||
|
@ -189,8 +189,8 @@ StringView calendar_pattern_style_to_string(CalendarPatternStyle style);
|
||||||
|
|
||||||
Optional<HourCycleRegion> hour_cycle_region_from_string(StringView hour_cycle_region);
|
Optional<HourCycleRegion> hour_cycle_region_from_string(StringView hour_cycle_region);
|
||||||
Vector<HourCycle> get_regional_hour_cycles(StringView region);
|
Vector<HourCycle> get_regional_hour_cycles(StringView region);
|
||||||
Vector<Unicode::HourCycle> get_locale_hour_cycles(StringView locale);
|
Vector<HourCycle> get_locale_hour_cycles(StringView locale);
|
||||||
Optional<Unicode::HourCycle> get_default_regional_hour_cycle(StringView locale);
|
Optional<HourCycle> get_default_regional_hour_cycle(StringView locale);
|
||||||
|
|
||||||
Optional<MinimumDaysRegion> minimum_days_region_from_string(StringView minimum_days_region);
|
Optional<MinimumDaysRegion> minimum_days_region_from_string(StringView minimum_days_region);
|
||||||
Optional<u8> get_regional_minimum_days(StringView region);
|
Optional<u8> get_regional_minimum_days(StringView region);
|
||||||
|
@ -215,14 +215,14 @@ Optional<CalendarFormat> get_calendar_time_format(StringView locale, StringView
|
||||||
Optional<CalendarFormat> get_calendar_date_time_format(StringView locale, StringView calendar);
|
Optional<CalendarFormat> get_calendar_date_time_format(StringView locale, StringView calendar);
|
||||||
Optional<CalendarFormat> get_calendar_format(StringView locale, StringView calendar, CalendarFormatType type);
|
Optional<CalendarFormat> get_calendar_format(StringView locale, StringView calendar, CalendarFormatType type);
|
||||||
Vector<CalendarPattern> get_calendar_available_formats(StringView locale, StringView calendar);
|
Vector<CalendarPattern> get_calendar_available_formats(StringView locale, StringView calendar);
|
||||||
Optional<Unicode::CalendarRangePattern> get_calendar_default_range_format(StringView locale, StringView calendar);
|
Optional<CalendarRangePattern> get_calendar_default_range_format(StringView locale, StringView calendar);
|
||||||
Vector<Unicode::CalendarRangePattern> get_calendar_range_formats(StringView locale, StringView calendar, StringView skeleton);
|
Vector<CalendarRangePattern> get_calendar_range_formats(StringView locale, StringView calendar, StringView skeleton);
|
||||||
Vector<Unicode::CalendarRangePattern> get_calendar_range12_formats(StringView locale, StringView calendar, StringView skeleton);
|
Vector<CalendarRangePattern> get_calendar_range12_formats(StringView locale, StringView calendar, StringView skeleton);
|
||||||
|
|
||||||
Optional<StringView> get_calendar_era_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Unicode::Era value);
|
Optional<StringView> get_calendar_era_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Era value);
|
||||||
Optional<StringView> get_calendar_month_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Unicode::Month value);
|
Optional<StringView> get_calendar_month_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Month value);
|
||||||
Optional<StringView> get_calendar_weekday_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Unicode::Weekday value);
|
Optional<StringView> get_calendar_weekday_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Weekday value);
|
||||||
Optional<StringView> get_calendar_day_period_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, Unicode::DayPeriod value);
|
Optional<StringView> get_calendar_day_period_symbol(StringView locale, StringView calendar, CalendarPatternStyle style, DayPeriod value);
|
||||||
Optional<StringView> get_calendar_day_period_symbol_for_hour(StringView locale, StringView calendar, CalendarPatternStyle style, u8 hour);
|
Optional<StringView> get_calendar_day_period_symbol_for_hour(StringView locale, StringView calendar, CalendarPatternStyle style, u8 hour);
|
||||||
|
|
||||||
String format_time_zone(StringView locale, StringView time_zone, CalendarPatternStyle style, AK::Time time);
|
String format_time_zone(StringView locale, StringView time_zone, CalendarPatternStyle style, AK::Time time);
|
||||||
|
|
|
@ -11,6 +11,20 @@
|
||||||
namespace Unicode {
|
namespace Unicode {
|
||||||
|
|
||||||
enum class Block : u16;
|
enum class Block : u16;
|
||||||
|
enum class GeneralCategory : u8;
|
||||||
|
enum class GraphemeBreakProperty : u8;
|
||||||
|
enum class Property : u8;
|
||||||
|
enum class Script : u8;
|
||||||
|
enum class SentenceBreakProperty : u8;
|
||||||
|
enum class WordBreakProperty : u8;
|
||||||
|
|
||||||
|
struct CurrencyCode;
|
||||||
|
struct SpecialCasing;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Locale {
|
||||||
|
|
||||||
enum class CalendarFormatType : u8;
|
enum class CalendarFormatType : u8;
|
||||||
enum class CalendarPatternStyle : u8;
|
enum class CalendarPatternStyle : u8;
|
||||||
enum class CalendarSymbol : u8;
|
enum class CalendarSymbol : u8;
|
||||||
|
@ -22,8 +36,6 @@ enum class DateField : u8;
|
||||||
enum class DayPeriod : u8;
|
enum class DayPeriod : u8;
|
||||||
enum class Era : u8;
|
enum class Era : u8;
|
||||||
enum class FirstDayRegion : u8;
|
enum class FirstDayRegion : u8;
|
||||||
enum class GeneralCategory : u8;
|
|
||||||
enum class GraphemeBreakProperty : u8;
|
|
||||||
enum class HourCycle : u8;
|
enum class HourCycle : u8;
|
||||||
enum class HourCycleRegion : u16;
|
enum class HourCycleRegion : u16;
|
||||||
enum class Key : u8;
|
enum class Key : u8;
|
||||||
|
@ -34,29 +46,23 @@ enum class KeywordColNumeric : u8;
|
||||||
enum class KeywordHours : u8;
|
enum class KeywordHours : u8;
|
||||||
enum class KeywordNumbers : u8;
|
enum class KeywordNumbers : u8;
|
||||||
enum class Language : u16;
|
enum class Language : u16;
|
||||||
enum class ListPatternStyle : u8;
|
|
||||||
enum class ListPatternType : u8;
|
enum class ListPatternType : u8;
|
||||||
enum class Locale : u16;
|
enum class Locale : u16;
|
||||||
enum class MinimumDaysRegion : u8;
|
enum class MinimumDaysRegion : u8;
|
||||||
enum class Month : u8;
|
enum class Month : u8;
|
||||||
enum class NumericSymbol : u8;
|
enum class NumericSymbol : u8;
|
||||||
enum class PluralCategory : u8;
|
enum class PluralCategory : u8;
|
||||||
enum class Property : u8;
|
|
||||||
enum class Script : u8;
|
|
||||||
enum class ScriptTag : u8;
|
enum class ScriptTag : u8;
|
||||||
enum class SentenceBreakProperty : u8;
|
|
||||||
enum class StandardNumberFormatType : u8;
|
enum class StandardNumberFormatType : u8;
|
||||||
enum class Style : u8;
|
enum class Style : u8;
|
||||||
enum class Territory : u8;
|
enum class Territory : u8;
|
||||||
enum class Weekday : u8;
|
enum class Weekday : u8;
|
||||||
enum class WeekendEndRegion : u8;
|
enum class WeekendEndRegion : u8;
|
||||||
enum class WeekendStartRegion : u8;
|
enum class WeekendStartRegion : u8;
|
||||||
enum class WordBreakProperty : u8;
|
|
||||||
|
|
||||||
struct CalendarFormat;
|
struct CalendarFormat;
|
||||||
struct CalendarPattern;
|
struct CalendarPattern;
|
||||||
struct CalendarRangePattern;
|
struct CalendarRangePattern;
|
||||||
struct CurrencyCode;
|
|
||||||
struct Keyword;
|
struct Keyword;
|
||||||
struct LanguageID;
|
struct LanguageID;
|
||||||
struct ListPatterns;
|
struct ListPatterns;
|
||||||
|
@ -66,9 +72,7 @@ struct NumberFormat;
|
||||||
struct NumberGroupings;
|
struct NumberGroupings;
|
||||||
struct OtherExtension;
|
struct OtherExtension;
|
||||||
struct PluralOperands;
|
struct PluralOperands;
|
||||||
struct SpecialCasing;
|
|
||||||
struct TransformedExtension;
|
struct TransformedExtension;
|
||||||
struct TransformedField;
|
struct TransformedField;
|
||||||
struct UnicodeData;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <LibUnicode/DateTimeFormat.h>
|
#include <LibUnicode/DateTimeFormat.h>
|
||||||
#include <LibUnicode/Locale.h>
|
#include <LibUnicode/Locale.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
static bool is_key(StringView key)
|
static bool is_key(StringView key)
|
||||||
{
|
{
|
||||||
|
@ -809,7 +809,7 @@ Optional<String> format_locale_for_display(StringView locale, LocaleID locale_id
|
||||||
auto language_id = move(locale_id.language_id);
|
auto language_id = move(locale_id.language_id);
|
||||||
VERIFY(language_id.language.has_value());
|
VERIFY(language_id.language.has_value());
|
||||||
|
|
||||||
auto patterns = Unicode::get_locale_display_patterns(locale);
|
auto patterns = get_locale_display_patterns(locale);
|
||||||
if (!patterns.has_value())
|
if (!patterns.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibUnicode/Forward.h>
|
#include <LibUnicode/Forward.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
struct LanguageID {
|
struct LanguageID {
|
||||||
String to_string() const;
|
String to_string() const;
|
||||||
|
@ -206,7 +206,7 @@ void resolve_complex_language_aliases(LanguageID& language_id);
|
||||||
Optional<LanguageID> add_likely_subtags(LanguageID const& language_id);
|
Optional<LanguageID> add_likely_subtags(LanguageID const& language_id);
|
||||||
Optional<LanguageID> remove_likely_subtags(LanguageID const& language_id);
|
Optional<LanguageID> remove_likely_subtags(LanguageID const& language_id);
|
||||||
|
|
||||||
Optional<String> resolve_most_likely_territory(Unicode::LanguageID const& language_id);
|
Optional<String> resolve_most_likely_territory(LanguageID const& language_id);
|
||||||
String resolve_most_likely_territory_alias(LanguageID const& language_id, StringView territory_alias);
|
String resolve_most_likely_territory_alias(LanguageID const& language_id, StringView territory_alias);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# include <LibUnicode/UnicodeData.h>
|
# include <LibUnicode/UnicodeData.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
Optional<StringView> __attribute__((weak)) get_number_system_symbol(StringView, StringView, NumericSymbol) { return {}; }
|
Optional<StringView> __attribute__((weak)) get_number_system_symbol(StringView, StringView, NumericSymbol) { return {}; }
|
||||||
Optional<NumberGroupings> __attribute__((weak)) get_number_system_groupings(StringView, StringView) { return {}; }
|
Optional<NumberGroupings> __attribute__((weak)) get_number_system_groupings(StringView, StringView) { return {}; }
|
||||||
|
@ -83,19 +83,19 @@ Optional<String> augment_currency_format_pattern([[maybe_unused]] StringView cur
|
||||||
if (*number_index < *currency_index) {
|
if (*number_index < *currency_index) {
|
||||||
u32 last_pattern_code_point = last_code_point(base_pattern.substring_view(0, *currency_index));
|
u32 last_pattern_code_point = last_code_point(base_pattern.substring_view(0, *currency_index));
|
||||||
|
|
||||||
if (!code_point_has_general_category(last_pattern_code_point, GeneralCategory::Separator)) {
|
if (!Unicode::code_point_has_general_category(last_pattern_code_point, Unicode::GeneralCategory::Separator)) {
|
||||||
u32 first_currency_code_point = *utf8_currency_display.begin();
|
u32 first_currency_code_point = *utf8_currency_display.begin();
|
||||||
|
|
||||||
if (!code_point_has_general_category(first_currency_code_point, GeneralCategory::Symbol))
|
if (!Unicode::code_point_has_general_category(first_currency_code_point, Unicode::GeneralCategory::Symbol))
|
||||||
currency_key_with_spacing = String::formatted("{}{}", spacing, currency_key);
|
currency_key_with_spacing = String::formatted("{}{}", spacing, currency_key);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
u32 last_pattern_code_point = last_code_point(base_pattern.substring_view(0, *number_index));
|
u32 last_pattern_code_point = last_code_point(base_pattern.substring_view(0, *number_index));
|
||||||
|
|
||||||
if (!code_point_has_general_category(last_pattern_code_point, GeneralCategory::Separator)) {
|
if (!Unicode::code_point_has_general_category(last_pattern_code_point, Unicode::GeneralCategory::Separator)) {
|
||||||
u32 last_currency_code_point = last_code_point(currency_display);
|
u32 last_currency_code_point = last_code_point(currency_display);
|
||||||
|
|
||||||
if (!code_point_has_general_category(last_currency_code_point, GeneralCategory::Symbol))
|
if (!Unicode::code_point_has_general_category(last_currency_code_point, Unicode::GeneralCategory::Symbol))
|
||||||
currency_key_with_spacing = String::formatted("{}{}", currency_key, spacing);
|
currency_key_with_spacing = String::formatted("{}{}", currency_key, spacing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,17 +123,17 @@ Optional<String> augment_range_pattern([[maybe_unused]] StringView range_separat
|
||||||
// To determine whether to add spacing, the currently recommended heuristic is:
|
// To determine whether to add spacing, the currently recommended heuristic is:
|
||||||
// 2. If the range pattern does not contain a character having the White_Space binary Unicode property after the {0} or before the {1} placeholders.
|
// 2. If the range pattern does not contain a character having the White_Space binary Unicode property after the {0} or before the {1} placeholders.
|
||||||
for (auto it = utf8_range_separator.begin(); it != utf8_range_separator.end(); ++it) {
|
for (auto it = utf8_range_separator.begin(); it != utf8_range_separator.end(); ++it) {
|
||||||
if (code_point_has_property(*it, Property::White_Space))
|
if (Unicode::code_point_has_property(*it, Unicode::Property::White_Space))
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. If the lower string ends with a character other than a digit, or if the upper string begins with a character other than a digit.
|
// 1. If the lower string ends with a character other than a digit, or if the upper string begins with a character other than a digit.
|
||||||
if (auto it = utf8_upper.begin(); it != utf8_upper.end()) {
|
if (auto it = utf8_upper.begin(); it != utf8_upper.end()) {
|
||||||
if (!code_point_has_general_category(*it, GeneralCategory::Decimal_Number))
|
if (!Unicode::code_point_has_general_category(*it, Unicode::GeneralCategory::Decimal_Number))
|
||||||
return range_pattern_with_spacing();
|
return range_pattern_with_spacing();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!code_point_has_general_category(last_code_point(lower), GeneralCategory::Decimal_Number))
|
if (!Unicode::code_point_has_general_category(last_code_point(lower), Unicode::GeneralCategory::Decimal_Number))
|
||||||
return range_pattern_with_spacing();
|
return range_pattern_with_spacing();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <LibUnicode/Forward.h>
|
#include <LibUnicode/Forward.h>
|
||||||
#include <LibUnicode/PluralRules.h>
|
#include <LibUnicode/PluralRules.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
struct NumberGroupings {
|
struct NumberGroupings {
|
||||||
u8 minimum_grouping_digits { 0 };
|
u8 minimum_grouping_digits { 0 };
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include <LibUnicode/PluralRules.h>
|
#include <LibUnicode/PluralRules.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
PluralForm plural_form_from_string(StringView plural_form)
|
PluralForm plural_form_from_string(StringView plural_form)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <LibUnicode/Forward.h>
|
#include <LibUnicode/Forward.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
enum class PluralForm {
|
enum class PluralForm {
|
||||||
Cardinal,
|
Cardinal,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include <LibUnicode/RelativeTimeFormat.h>
|
#include <LibUnicode/RelativeTimeFormat.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
Optional<TimeUnit> time_unit_from_string(StringView time_unit)
|
Optional<TimeUnit> time_unit_from_string(StringView time_unit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <LibUnicode/Forward.h>
|
#include <LibUnicode/Forward.h>
|
||||||
#include <LibUnicode/Locale.h>
|
#include <LibUnicode/Locale.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Locale {
|
||||||
|
|
||||||
// These are just the subset of fields in the CLDR required for ECMA-402.
|
// These are just the subset of fields in the CLDR required for ECMA-402.
|
||||||
enum class TimeUnit {
|
enum class TimeUnit {
|
||||||
|
|
|
@ -810,7 +810,7 @@ static void print_intl_date_time_format(JS::Intl::DateTimeFormat& date_time_form
|
||||||
if constexpr (IsIntegral<ValueType>) {
|
if constexpr (IsIntegral<ValueType>) {
|
||||||
print_value(JS::Value(*option), seen_objects);
|
print_value(JS::Value(*option), seen_objects);
|
||||||
} else {
|
} else {
|
||||||
auto name = Unicode::calendar_pattern_style_to_string(*option);
|
auto name = Locale::calendar_pattern_style_to_string(*option);
|
||||||
print_value(js_string(date_time_format.vm(), name), seen_objects);
|
print_value(js_string(date_time_format.vm(), name), seen_objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue