summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-12-03 08:57:54 -0500
committerAndreas Kling <kling@serenityos.org>2021-12-06 15:46:34 +0100
commite42d954743056e476bbb1623cfc60e7797a8a6ca (patch)
tree51e463e0af1b1634d3afa47eabc0303acb4a211e /Userland/Libraries/LibJS
parent9dc9700e3bdd778d4f02a03ba977c0e775f7e201 (diff)
downloadserenity-e42d954743056e476bbb1623cfc60e7797a8a6ca.zip
LibJS: Always respect user-provided format field lengths
ECMA-402 doesn't explicitly handle a note in the TR-35 spec related to expanding field lengths based on user-provided options. Instead, it assumes the "implementation defined" locale data includes the possible values. LibUnicode does not generate every possible combination of field lengths in its implementation of TR-35's "Missing Skeleton Fields", because the number of generated patterns would grow out of control. Instead, it's much simpler to handle this difference at runtime.
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp
index 08f77486ea..dd4bfa5894 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp
@@ -647,6 +647,23 @@ Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern
}
}
+ if (!best_format.has_value())
+ return {};
+
+ // Non-standard, if the user provided options that differ from the best format's options, keep
+ // the user's options. This is expected by TR-35:
+ //
+ // It is not necessary to supply dateFormatItems with skeletons for every field length; fields
+ // in the skeleton and pattern are expected to be expanded in parallel to handle a request.
+ // https://unicode.org/reports/tr35/tr35-dates.html#Matching_Skeletons
+ //
+ // Rather than generating an prohibitively large amount of nearly-duplicate patterns, which only
+ // 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) {
+ if (best_format_field.has_value() && option_field.has_value())
+ best_format_field = option_field;
+ });
+
// 11. Return bestFormat.
return best_format;
}