mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
LibJS: Allow specifying keyword values not directly defined for a locale
For example, consider the locales "en-u-nu-fullwide" or "en-u-nu-arab". The CLDR only declares the "latn" numbering system for the "en" locale, thus ResolveLocale would change the locale to "en-u-nu-latn". This patch allows using non-latn numbering systems digits.
This commit is contained in:
parent
b24b9c0a65
commit
aafcdc4c72
Notes:
sideshowbarker
2024-07-17 08:55:16 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/aafcdc4c72 Pull-request: https://github.com/SerenityOS/serenity/pull/14585
6 changed files with 42 additions and 12 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
|
* Copyright (c) 2021-2022, Tim Flynn <trflynn89@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -425,13 +425,15 @@ 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_keywords_for_locale(found_locale, key);
|
auto key_locale_data = Unicode::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
|
||||||
|
// alphabetically, so we get the locale's preferred value from LibUnicode.
|
||||||
Optional<String> value;
|
Optional<String> value;
|
||||||
if (!key_locale_data.is_empty())
|
if (auto preference = Unicode::get_preferred_keyword_value_for_locale(found_locale, key); preference.has_value())
|
||||||
value = key_locale_data[0];
|
value = *preference;
|
||||||
|
|
||||||
// g. Let supportedExtensionAddition be "".
|
// g. Let supportedExtensionAddition be "".
|
||||||
Optional<Unicode::Keyword> supported_extension_addition {};
|
Optional<Unicode::Keyword> supported_extension_addition {};
|
||||||
|
|
|
@ -64,12 +64,12 @@ describe("correct behavior", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("numberingSystem option limited to known 'nu' values", () => {
|
test("numberingSystem option limited to known 'nu' values", () => {
|
||||||
["latn", "arab"].forEach(numberingSystem => {
|
["latn", "foo"].forEach(numberingSystem => {
|
||||||
const en = Intl.DateTimeFormat("en", { numberingSystem: numberingSystem });
|
const en = Intl.DateTimeFormat("en", { numberingSystem: numberingSystem });
|
||||||
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
||||||
});
|
});
|
||||||
|
|
||||||
["latn", "arab"].forEach(numberingSystem => {
|
["latn", "foo"].forEach(numberingSystem => {
|
||||||
const en = Intl.DateTimeFormat(`en-u-nu-${numberingSystem}`);
|
const en = Intl.DateTimeFormat(`en-u-nu-${numberingSystem}`);
|
||||||
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,12 +33,12 @@ describe("correct behavior", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("numberingSystem option limited to known 'nu' values", () => {
|
test("numberingSystem option limited to known 'nu' values", () => {
|
||||||
["latn", "arab"].forEach(numberingSystem => {
|
["latn", "foo"].forEach(numberingSystem => {
|
||||||
const en = new Intl.DurationFormat("en", { numberingSystem: numberingSystem });
|
const en = new Intl.DurationFormat("en", { numberingSystem: numberingSystem });
|
||||||
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
||||||
});
|
});
|
||||||
|
|
||||||
["latn", "arab"].forEach(numberingSystem => {
|
["latn", "foo"].forEach(numberingSystem => {
|
||||||
const en = new Intl.DurationFormat(`en-u-nu-${numberingSystem}`);
|
const en = new Intl.DurationFormat(`en-u-nu-${numberingSystem}`);
|
||||||
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
||||||
});
|
});
|
||||||
|
|
|
@ -207,6 +207,21 @@ describe("style=decimal", () => {
|
||||||
expect(en.format(12000000)).toBe("12 million");
|
expect(en.format(12000000)).toBe("12 million");
|
||||||
expect(en.format(12900000)).toBe("13 million");
|
expect(en.format(12900000)).toBe("13 million");
|
||||||
|
|
||||||
|
const enFullwide = new Intl.NumberFormat("en", {
|
||||||
|
notation: "compact",
|
||||||
|
compactDisplay: "long",
|
||||||
|
numberingSystem: "fullwide",
|
||||||
|
});
|
||||||
|
expect(enFullwide.format(1)).toBe("1");
|
||||||
|
expect(enFullwide.format(1200)).toBe("1.2 thousand");
|
||||||
|
expect(enFullwide.format(1290)).toBe("1.3 thousand");
|
||||||
|
expect(enFullwide.format(12000)).toBe("12 thousand");
|
||||||
|
expect(enFullwide.format(12900)).toBe("13 thousand");
|
||||||
|
expect(enFullwide.format(1200000)).toBe("1.2 million");
|
||||||
|
expect(enFullwide.format(1290000)).toBe("1.3 million");
|
||||||
|
expect(enFullwide.format(12000000)).toBe("12 million");
|
||||||
|
expect(enFullwide.format(12900000)).toBe("13 million");
|
||||||
|
|
||||||
const ar = new Intl.NumberFormat("ar", { notation: "compact", compactDisplay: "long" });
|
const ar = new Intl.NumberFormat("ar", { notation: "compact", compactDisplay: "long" });
|
||||||
expect(ar.format(1)).toBe("\u0661");
|
expect(ar.format(1)).toBe("\u0661");
|
||||||
expect(ar.format(1200)).toBe("\u0661\u066b\u0662 ألف");
|
expect(ar.format(1200)).toBe("\u0661\u066b\u0662 ألف");
|
||||||
|
@ -579,6 +594,19 @@ describe("style=percent", () => {
|
||||||
expect(en.format(0.123)).toBe("12%");
|
expect(en.format(0.123)).toBe("12%");
|
||||||
expect(en.format(0.1234)).toBe("12%");
|
expect(en.format(0.1234)).toBe("12%");
|
||||||
|
|
||||||
|
const enFullwide = new Intl.NumberFormat("en", {
|
||||||
|
style: "percent",
|
||||||
|
notation: "compact",
|
||||||
|
numberingSystem: "fullwide",
|
||||||
|
});
|
||||||
|
expect(enFullwide.format(0.01)).toBe("1%");
|
||||||
|
expect(enFullwide.format(0.012)).toBe("1.2%");
|
||||||
|
expect(enFullwide.format(0.0123)).toBe("1.2%");
|
||||||
|
expect(enFullwide.format(0.0129)).toBe("1.3%");
|
||||||
|
expect(enFullwide.format(0.12)).toBe("12%");
|
||||||
|
expect(enFullwide.format(0.123)).toBe("12%");
|
||||||
|
expect(enFullwide.format(0.1234)).toBe("12%");
|
||||||
|
|
||||||
const ar = new Intl.NumberFormat("ar", { style: "percent", notation: "compact" });
|
const ar = new Intl.NumberFormat("ar", { style: "percent", notation: "compact" });
|
||||||
expect(ar.format(0.01)).toBe("\u0661\u066a\u061c");
|
expect(ar.format(0.01)).toBe("\u0661\u066a\u061c");
|
||||||
expect(ar.format(0.012)).toBe("\u0661\u066b\u0662\u066a\u061c");
|
expect(ar.format(0.012)).toBe("\u0661\u066b\u0662\u066a\u061c");
|
||||||
|
|
|
@ -36,12 +36,12 @@ describe("correct behavior", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("numberingSystem option limited to known 'nu' values", () => {
|
test("numberingSystem option limited to known 'nu' values", () => {
|
||||||
["latn", "arab"].forEach(numberingSystem => {
|
["latn", "foo"].forEach(numberingSystem => {
|
||||||
const en = Intl.NumberFormat("en", { numberingSystem: numberingSystem });
|
const en = Intl.NumberFormat("en", { numberingSystem: numberingSystem });
|
||||||
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
||||||
});
|
});
|
||||||
|
|
||||||
["latn", "arab"].forEach(numberingSystem => {
|
["latn", "foo"].forEach(numberingSystem => {
|
||||||
const en = Intl.NumberFormat(`en-u-nu-${numberingSystem}`);
|
const en = Intl.NumberFormat(`en-u-nu-${numberingSystem}`);
|
||||||
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,12 +36,12 @@ describe("correct behavior", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("numberingSystem option limited to known 'nu' values", () => {
|
test("numberingSystem option limited to known 'nu' values", () => {
|
||||||
["latn", "arab"].forEach(numberingSystem => {
|
["latn", "foo"].forEach(numberingSystem => {
|
||||||
const en = new Intl.RelativeTimeFormat("en", { numberingSystem: numberingSystem });
|
const en = new Intl.RelativeTimeFormat("en", { numberingSystem: numberingSystem });
|
||||||
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
||||||
});
|
});
|
||||||
|
|
||||||
["latn", "arab"].forEach(numberingSystem => {
|
["latn", "foo"].forEach(numberingSystem => {
|
||||||
const en = new Intl.RelativeTimeFormat(`en-u-nu-${numberingSystem}`);
|
const en = new Intl.RelativeTimeFormat(`en-u-nu-${numberingSystem}`);
|
||||||
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
expect(en.resolvedOptions().numberingSystem).toBe("latn");
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue