-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
In the removal of HybridLocalization in PR #110567 the following code was introduced into globalization-locale.ts
locale = locale.toLocaleLowerCase();
if (locale.includes("zh")) {
// browser does not recognize "zh-chs" and "zh-cht" as equivalents of "zh-HANS" "zh-HANT", we are helping, otherwise
// it would throw on getCanonicalLocales with "RangeError: Incorrect locale information provided"
locale = locale.replace("chs", "HANS").replace("cht", "HANT");
}Firstly, the Chinese language check should be a check of startsWith( the prefix "zh-", not include( the more ambiguous "zh". This could lead to problems if someone was using the substring zh in any of the other parts of the locale string. To ensure this works with locales formatted with underscores, we need to move up that locale.replace("_", "-") to the first line.
Secondly, per RFC 5646 the script code should be upper-case initial letter and lower-case the rest, so the replacement constants should be "Hans" and "Hant" respectively. Also, since those replacement patterns for those subparts are supposed to be targeting the script indicator, it would be much safer to include the '-' prefix.
In short, this normalizeLocale function should probably be this:
function normalizeLocale (locale: string | null) {
if (!locale)
return undefined;
try {
locale = locale.toLocaleLowerCase().replace("_", "-");
if (locale.startsWith("zh-")) {
// browser does not recognize "zh-chs" and "zh-cht" as equivalents of "zh-Hans" "zh-Hant", we are helping, otherwise
// it would throw on getCanonicalLocales with "RangeError: Incorrect locale information provided"
locale = locale.replace("-chs", "-Hans").replace("-cht", "-Hant");
}
const canonicalLocales = (Intl as any).getCanonicalLocales(locale);
return canonicalLocales.length > 0 ? canonicalLocales[0] : undefined;
} catch {
return undefined;
}
}