Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
96 lines
3.0 KiB
Plaintext
96 lines
3.0 KiB
Plaintext
import { BestFitMatcher } from "./BestFitMatcher.js";
|
|
import { CanonicalizeUValue } from "./CanonicalizeUValue.js";
|
|
import { InsertUnicodeExtensionAndCanonicalize } from "./InsertUnicodeExtensionAndCanonicalize.js";
|
|
import { LookupMatcher } from "./LookupMatcher.js";
|
|
import { UnicodeExtensionComponents } from "./UnicodeExtensionComponents.js";
|
|
import { invariant } from "./utils.js";
|
|
/**
|
|
* https://tc39.es/ecma402/#sec-resolvelocale
|
|
*/
|
|
export function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) {
|
|
const matcher = options.localeMatcher;
|
|
let r;
|
|
if (matcher === "lookup") {
|
|
r = LookupMatcher(Array.from(availableLocales), requestedLocales, getDefaultLocale);
|
|
} else {
|
|
r = BestFitMatcher(Array.from(availableLocales), requestedLocales, getDefaultLocale);
|
|
}
|
|
if (r == null) {
|
|
r = {
|
|
locale: getDefaultLocale(),
|
|
extension: ""
|
|
};
|
|
}
|
|
let foundLocale = r.locale;
|
|
let foundLocaleData = localeData[foundLocale];
|
|
// TODO: We can't really guarantee that the locale data is available
|
|
// invariant(
|
|
// foundLocaleData !== undefined,
|
|
// `Missing locale data for ${foundLocale}`
|
|
// )
|
|
const result = {
|
|
locale: "en",
|
|
dataLocale: foundLocale
|
|
};
|
|
let components;
|
|
let keywords;
|
|
if (r.extension) {
|
|
components = UnicodeExtensionComponents(r.extension);
|
|
keywords = components.keywords;
|
|
} else {
|
|
keywords = [];
|
|
}
|
|
let supportedKeywords = [];
|
|
for (const key of relevantExtensionKeys) {
|
|
// TODO: Shouldn't default to empty array, see TODO above
|
|
let keyLocaleData = foundLocaleData?.[key] ?? [];
|
|
invariant(Array.isArray(keyLocaleData), `keyLocaleData for ${key} must be an array`);
|
|
let value = keyLocaleData[0];
|
|
invariant(value === undefined || typeof value === "string", `value must be a string or undefined`);
|
|
let supportedKeyword;
|
|
let entry = keywords.find((k) => k.key === key);
|
|
if (entry) {
|
|
let requestedValue = entry.value;
|
|
if (requestedValue !== "") {
|
|
if (keyLocaleData.indexOf(requestedValue) > -1) {
|
|
value = requestedValue;
|
|
supportedKeyword = {
|
|
key,
|
|
value
|
|
};
|
|
}
|
|
} else if (keyLocaleData.indexOf("true") > -1) {
|
|
value = "true";
|
|
supportedKeyword = {
|
|
key,
|
|
value
|
|
};
|
|
}
|
|
}
|
|
let optionsValue = options[key];
|
|
invariant(optionsValue == null || typeof optionsValue === "string", `optionsValue must be a string or undefined`);
|
|
if (typeof optionsValue === "string") {
|
|
let ukey = key.toLowerCase();
|
|
optionsValue = CanonicalizeUValue(ukey, optionsValue);
|
|
if (optionsValue === "") {
|
|
optionsValue = "true";
|
|
}
|
|
}
|
|
if (optionsValue !== value && keyLocaleData.indexOf(optionsValue) > -1) {
|
|
value = optionsValue;
|
|
supportedKeyword = undefined;
|
|
}
|
|
if (supportedKeyword) {
|
|
supportedKeywords.push(supportedKeyword);
|
|
}
|
|
result[key] = value;
|
|
}
|
|
let supportedAttributes = [];
|
|
if (supportedKeywords.length > 0) {
|
|
supportedAttributes = [];
|
|
foundLocale = InsertUnicodeExtensionAndCanonicalize(foundLocale, supportedAttributes, supportedKeywords);
|
|
}
|
|
result.locale = foundLocale;
|
|
return result;
|
|
}
|