fix: Localisation-matching algorithm missing some edgecase (#4692)

This commit is contained in:
Frank Elsinga 2024-04-21 14:23:34 +02:00 committed by GitHub
parent e797abd108
commit add5c128ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 48 additions and 19 deletions

View file

@ -63,9 +63,22 @@ const rtlLangs = [ "fa", "ar-SY", "ur" ];
* @returns {string} the locale that should be displayed * @returns {string} the locale that should be displayed
*/ */
export function currentLocale() { export function currentLocale() {
const potentialLocales = [ localStorage.locale, navigator.language, navigator.language.substring(0, 2), ...navigator.languages ]; for (const locale of [ localStorage.locale, navigator.language, ...navigator.languages ]) {
const availableLocales = potentialLocales.filter(l => languageList[l]); // localstorage might not have a value or there might not be a language in `navigator.language`
return availableLocales[0] || "en"; if (!locale) {
continue;
}
if (locale in messages) {
return locale;
}
// some locales are further specified such as "en-US".
// If we only have a generic locale for this, we can use it too
const genericLocale = locale.split("-")[0];
if (genericLocale in messages) {
return genericLocale;
}
}
return "en";
} }
export const localeDirection = () => { export const localeDirection = () => {

View file

@ -3,46 +3,62 @@ import { currentLocale } from "../../../src/i18n";
describe("Test i18n.js", () => { describe("Test i18n.js", () => {
it("currentLocale()", () => { it("currentLocale()", () => {
const setLanguage = (language) => { const setLanguages = (languages) => {
Object.defineProperty(window.navigator, 'language', { Object.defineProperty(navigator, 'language', {
value: language, value: languages[0],
writable: true writable: true
}); });
Object.defineProperty(window.navigator, 'languages', { Object.defineProperty(navigator, 'languages', {
value: [language], value: languages,
writable: true writable: true
}); });
} }
setLanguage('en-EN');
setLanguages(['en-EN']);
expect(currentLocale()).equal("en"); expect(currentLocale()).equal("en");
setLanguage('zh-HK'); setLanguages(['zh-HK']);
expect(currentLocale()).equal("zh-HK"); expect(currentLocale()).equal("zh-HK");
// Note that in Safari on iOS prior to 10.2, the country code returned is lowercase: "en-us", "fr-fr" etc. // Note that in Safari on iOS prior to 10.2, the country code returned is lowercase: "en-us", "fr-fr" etc.
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language
setLanguage('zh-hk'); setLanguages(['zh-hk']);
expect(currentLocale()).equal("en"); expect(currentLocale()).equal("en");
setLanguage('en-US'); setLanguages(['en-US']);
expect(currentLocale()).equal("en"); expect(currentLocale()).equal("en");
setLanguage('ja-ZZ'); setLanguages(['ja-ZZ']);
expect(currentLocale()).equal("ja"); expect(currentLocale()).equal("ja");
setLanguage('zz-ZZ'); setLanguages(['zz-ZZ']);
expect(currentLocale()).equal("en"); expect(currentLocale()).equal("en");
setLanguage('zz-ZZ'); setLanguages(['zz-ZZ']);
expect(currentLocale()).equal("en"); expect(currentLocale()).equal("en");
setLanguage('en'); setLanguages(['en-US', 'en', 'pl', 'ja']);
localStorage.locale = "en";
expect(currentLocale()).equal("en"); expect(currentLocale()).equal("en");
localStorage.locale = "zh-HK"; setLanguages(['en-US', 'pl', 'ja']);
expect(currentLocale()).equal("zh-HK"); expect(currentLocale()).equal("en");
setLanguages(['abc', 'en-US', 'pl', 'ja']);
expect(currentLocale()).equal("en");
setLanguages(['fil-PH', 'pl']);
expect(currentLocale()).equal("pl");
setLanguages(['shi-Latn-MA', 'pl']);
expect(currentLocale()).equal("pl");
setLanguages(['pl']);
localStorage.locale = "ja-ZZ";
expect(currentLocale()).equal("ja");
setLanguages(['pl']);
localStorage.locale = "invalid-lang";
expect(currentLocale()).equal("pl");
}); });
}); });