зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1762659 - Use MozIntl for stand-alone display names in LangPackMatcher.jsm; r=Mardak,nordzilla
Differential Revision: https://phabricator.services.mozilla.com/D142730
This commit is contained in:
Родитель
b2c631dcf0
Коммит
852ecad7f2
|
@ -1157,20 +1157,15 @@ function useLanguageSwitcher(appAndSystemLocaleInfo, screens, screenIndex, setSc
|
|||
}
|
||||
|
||||
(async () => {
|
||||
const langPack = await window.AWNegotiateLangPackForLanguageMismatch(appAndSystemLocaleInfo);
|
||||
const {
|
||||
langPack,
|
||||
langPackDisplayName
|
||||
} = await window.AWNegotiateLangPackForLanguageMismatch(appAndSystemLocaleInfo);
|
||||
|
||||
if (langPack) {
|
||||
// Convert the BCP 47 identifiers into the proper display names.
|
||||
// e.g. "fr-CA" -> "Canadian French".
|
||||
const appDN = new Intl.DisplayNames(appAndSystemLocaleInfo.appLocaleRaw, {
|
||||
type: "language"
|
||||
});
|
||||
const langPackDN = new Intl.DisplayNames(langPack.target_locale, {
|
||||
type: "language"
|
||||
});
|
||||
setNegotiatedLanguage({
|
||||
langPackDisplayName: langPackDN.of(langPack.target_locale),
|
||||
appDisplayName: appDN.of(appAndSystemLocaleInfo.appLocaleRaw),
|
||||
langPackDisplayName,
|
||||
appDisplayName: appAndSystemLocaleInfo.displayNames.appLanguage,
|
||||
langPack,
|
||||
requestSystemLocales: [langPack.target_locale, appAndSystemLocaleInfo.appLocaleRaw],
|
||||
originalAppLocales: [appAndSystemLocaleInfo.appLocaleRaw]
|
||||
|
|
|
@ -36,23 +36,16 @@ export function useLanguageSwitcher(
|
|||
}
|
||||
|
||||
(async () => {
|
||||
const langPack = await window.AWNegotiateLangPackForLanguageMismatch(
|
||||
const {
|
||||
langPack,
|
||||
langPackDisplayName,
|
||||
} = await window.AWNegotiateLangPackForLanguageMismatch(
|
||||
appAndSystemLocaleInfo
|
||||
);
|
||||
if (langPack) {
|
||||
// Convert the BCP 47 identifiers into the proper display names.
|
||||
// e.g. "fr-CA" -> "Canadian French".
|
||||
const appDN = new Intl.DisplayNames(
|
||||
appAndSystemLocaleInfo.appLocaleRaw,
|
||||
{ type: "language" }
|
||||
);
|
||||
const langPackDN = new Intl.DisplayNames(langPack.target_locale, {
|
||||
type: "language",
|
||||
});
|
||||
|
||||
setNegotiatedLanguage({
|
||||
langPackDisplayName: langPackDN.of(langPack.target_locale),
|
||||
appDisplayName: appDN.of(appAndSystemLocaleInfo.appLocaleRaw),
|
||||
langPackDisplayName,
|
||||
appDisplayName: appAndSystemLocaleInfo.displayNames.appLanguage,
|
||||
langPack,
|
||||
requestSystemLocales: [
|
||||
langPack.target_locale,
|
||||
|
|
|
@ -228,7 +228,7 @@ mr2-onboarding-start-browsing-button-label = Start browsing
|
|||
## The following language names are generated by the browser's Intl.DisplayNames API.
|
||||
##
|
||||
## Variables:
|
||||
## $negotiatedLanguage (String) - The name of the langpack's language, e.g. "European Spanish"
|
||||
## $negotiatedLanguage (String) - The name of the langpack's language, e.g. "Español (ES)"
|
||||
|
||||
onboarding-live-language-header = Choose your language
|
||||
|
||||
|
|
|
@ -23,13 +23,20 @@ if (Services.appinfo.processType !== Services.appinfo.PROCESS_TYPE_DEFAULT) {
|
|||
* Attempts to find an appropriate langpack for a given language. The async function
|
||||
* is infallible, but may not return a langpack.
|
||||
*
|
||||
* @returns {LangPack | null}
|
||||
* @returns {{
|
||||
* langPack: LangPack | null,
|
||||
* langPackDisplayName: string | null
|
||||
* }}
|
||||
*/
|
||||
async function negotiateLangPackForLanguageMismatch() {
|
||||
const localeInfo = getAppAndSystemLocaleInfo();
|
||||
const nullResult = {
|
||||
langPack: null,
|
||||
langPackDisplayName: null,
|
||||
};
|
||||
if (!localeInfo.systemLocale) {
|
||||
// The system locale info was not valid.
|
||||
return null;
|
||||
return nullResult;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,14 +46,14 @@ async function negotiateLangPackForLanguageMismatch() {
|
|||
*/
|
||||
const availableLangpacks = await mockable.getAvailableLangpacks();
|
||||
if (!availableLangpacks) {
|
||||
return null;
|
||||
return nullResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Figure out a langpack to recommend.
|
||||
* @type {LangPack | null}
|
||||
*/
|
||||
return (
|
||||
const langPack =
|
||||
// First look for a langpack that matches the baseName.
|
||||
// e.g. system "fr-FR" matches langpack "fr-FR"
|
||||
// system "en-GB" matches langpack "en-GB".
|
||||
|
@ -65,8 +72,20 @@ async function negotiateLangPackForLanguageMismatch() {
|
|||
availableLangpacks.find(({ target_locale }) =>
|
||||
target_locale.startsWith(`${localeInfo.systemLocale.language}-`)
|
||||
) ||
|
||||
null
|
||||
);
|
||||
null;
|
||||
|
||||
if (!langPack) {
|
||||
return nullResult;
|
||||
}
|
||||
|
||||
return {
|
||||
langPack,
|
||||
langPackDisplayName: Services.intl.getLocaleDisplayNames(
|
||||
undefined,
|
||||
[langPack.target_locale],
|
||||
{ preferNative: true }
|
||||
)[0],
|
||||
};
|
||||
}
|
||||
|
||||
// If a langpack is being installed, allow blocking on that.
|
||||
|
@ -278,10 +297,6 @@ function getAppAndSystemLocaleInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
const displayNames = new Services.intl.DisplayNames(appLocaleRaw, {
|
||||
type: "language",
|
||||
});
|
||||
|
||||
// Live reloading with bidi switching may not be supported.
|
||||
let canLiveReload = null;
|
||||
if (systemLocale && appLocale) {
|
||||
|
@ -295,7 +310,6 @@ function getAppAndSystemLocaleInfo() {
|
|||
);
|
||||
canLiveReload = systemDirection === appDirection || supportsBidiSwitching;
|
||||
}
|
||||
|
||||
return {
|
||||
// Return the Intl.Locale in a serializable form.
|
||||
systemLocaleRaw,
|
||||
|
@ -308,9 +322,17 @@ function getAppAndSystemLocaleInfo() {
|
|||
// These can be used as Fluent message args.
|
||||
displayNames: {
|
||||
systemLanguage: systemLocale
|
||||
? displayNames.of(systemLocale.baseName)
|
||||
? Services.intl.getLocaleDisplayNames(
|
||||
undefined,
|
||||
[systemLocale.baseName],
|
||||
{ preferNative: true }
|
||||
)[0]
|
||||
: null,
|
||||
appLanguage: appLocale
|
||||
? Services.intl.getLocaleDisplayNames(undefined, [appLocale.baseName], {
|
||||
preferNative: true,
|
||||
})[0]
|
||||
: null,
|
||||
appLanguage: appLocale ? displayNames.of(appLocale.baseName) : null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ add_task(function test_appLocaleLanguageMismatch() {
|
|||
matchType: "language-mismatch",
|
||||
canLiveReload: true,
|
||||
displayNames: {
|
||||
systemLanguage: "European Spanish",
|
||||
appLanguage: "American English",
|
||||
systemLanguage: "Español (ES)",
|
||||
appLanguage: "English (US)",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
@ -57,8 +57,8 @@ add_task(function test_appLocaleRegionMismatch() {
|
|||
matchType: "region-mismatch",
|
||||
canLiveReload: true,
|
||||
displayNames: {
|
||||
systemLanguage: "Canadian English",
|
||||
appLanguage: "American English",
|
||||
systemLanguage: "English (CA)",
|
||||
appLanguage: "English (US)",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
@ -80,8 +80,8 @@ add_task(function test_appLocaleScriptMismatch() {
|
|||
matchType: "match",
|
||||
canLiveReload: true,
|
||||
displayNames: {
|
||||
systemLanguage: "简体中文(中国)",
|
||||
appLanguage: "中文(中国)",
|
||||
systemLanguage: "Chinese (Hans, China)",
|
||||
appLanguage: "简体中文",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
@ -102,7 +102,7 @@ add_task(function test_appLocaleInvalidSystem() {
|
|||
appLocale: { baseName: "en-US", language: "en", region: "US" },
|
||||
matchType: "unknown",
|
||||
canLiveReload: null,
|
||||
displayNames: { systemLanguage: null, appLanguage: "American English" },
|
||||
displayNames: { systemLanguage: null, appLanguage: "English (US)" },
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -128,7 +128,7 @@ add_task(function test_bidiSwitchDisabled() {
|
|||
canLiveReload: false,
|
||||
displayNames: {
|
||||
systemLanguage: "Arabic (Egypt)",
|
||||
appLanguage: "American English",
|
||||
appLanguage: "English (US)",
|
||||
},
|
||||
});
|
||||
Services.prefs.clearUserPref("intl.multilingual.liveReloadBidirectional");
|
||||
|
@ -153,7 +153,7 @@ add_task(async function test_bidiSwitchEnabled() {
|
|||
canLiveReload: true,
|
||||
displayNames: {
|
||||
systemLanguage: "Arabic (Egypt)",
|
||||
appLanguage: "American English",
|
||||
appLanguage: "English (US)",
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -173,48 +173,60 @@ add_task(async function test_negotiateLangPacks() {
|
|||
// Exact match found.
|
||||
systemLocale: "en-US",
|
||||
availableLangPacks: ["en", "en-US", "zh", "zh-CN", "zh-Hans-CN"],
|
||||
expected: "en-US",
|
||||
expectedLangPack: "en-US",
|
||||
expectedDisplayName: "English (US)",
|
||||
},
|
||||
{
|
||||
// Region-less match.
|
||||
systemLocale: "en-CA",
|
||||
availableLangPacks: ["en", "en-US", "zh", "zh-CN", "zh-Hans-CN"],
|
||||
expected: "en",
|
||||
expectedLangPack: "en",
|
||||
expectedDisplayName: "English",
|
||||
},
|
||||
{
|
||||
// Fallback to a different region.
|
||||
systemLocale: "en-CA",
|
||||
availableLangPacks: ["en-US", "zh", "zh-CN", "zh-Hans-CN"],
|
||||
expected: "en-US",
|
||||
expectedLangPack: "en-US",
|
||||
expectedDisplayName: "English (US)",
|
||||
},
|
||||
{
|
||||
// Match with a script. zh-Hans-CN is the locale used with simplified
|
||||
// Chinese scripts, while zh-CN uses the Latin script.
|
||||
systemLocale: "zh-Hans-CN",
|
||||
availableLangPacks: ["en", "en-US", "zh", "zh-CN", "zh-Hans-CN"],
|
||||
expected: "zh-Hans-CN",
|
||||
expectedLangPack: "zh-Hans-CN",
|
||||
expectedDisplayName: "Chinese (Hans, China)",
|
||||
},
|
||||
{
|
||||
// No reasonable match could be found.
|
||||
systemLocale: "tlh", // Klingon
|
||||
availableLangPacks: ["en", "en-US", "zh", "zh-CN", "zh-Hans-CN"],
|
||||
expected: null,
|
||||
expectedLangPack: null,
|
||||
expectedDisplayName: null,
|
||||
},
|
||||
{
|
||||
// Weird, but valid locale identifiers.
|
||||
systemLocale: "en-US-u-hc-h23-ca-islamic-civil-ss-true",
|
||||
availableLangPacks: ["en", "en-US", "zh", "zh-CN", "zh-Hans-CN"],
|
||||
expected: "en-US",
|
||||
expectedLangPack: "en-US",
|
||||
expectedDisplayName: "English (US)",
|
||||
},
|
||||
{
|
||||
// Invalid system locale
|
||||
systemLocale: "Not valid",
|
||||
availableLangPacks: ["en", "en-US", "zh", "zh-CN", "zh-Hans-CN"],
|
||||
expected: null,
|
||||
expectedLangPack: null,
|
||||
expectedDisplayName: null,
|
||||
},
|
||||
];
|
||||
|
||||
for (const { systemLocale, availableLangPacks, expected } of negotiations) {
|
||||
for (const {
|
||||
systemLocale,
|
||||
availableLangPacks,
|
||||
expectedLangPack,
|
||||
expectedDisplayName,
|
||||
} of negotiations) {
|
||||
sandbox.restore();
|
||||
const { resolveLangPacks } = mockAddonAndLocaleAPIs({
|
||||
sandbox,
|
||||
|
@ -225,14 +237,19 @@ add_task(async function test_negotiateLangPacks() {
|
|||
// Shuffle the order to ensure that this test doesn't require on ordering of the
|
||||
// langpack responses.
|
||||
resolveLangPacks(shuffle(availableLangPacks));
|
||||
const actual = (await promise)?.target_locale;
|
||||
const { langPack, langPackDisplayName } = await promise;
|
||||
equal(
|
||||
actual,
|
||||
expected,
|
||||
langPack?.target_locale,
|
||||
expectedLangPack,
|
||||
`Resolve the systemLocale "${systemLocale}" with available langpacks: ${JSON.stringify(
|
||||
availableLangPacks
|
||||
)}`
|
||||
);
|
||||
equal(
|
||||
langPackDisplayName,
|
||||
expectedDisplayName,
|
||||
"The display name matches."
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -246,7 +263,7 @@ add_task(async function test_ensureLangPackInstalled() {
|
|||
|
||||
const negotiatePromise = LangPackMatcher.negotiateLangPackForLanguageMismatch();
|
||||
resolveLangPacks(["es-ES"]);
|
||||
const langPack = await negotiatePromise;
|
||||
const { langPack } = await negotiatePromise;
|
||||
|
||||
const installPromise1 = LangPackMatcher.ensureLangPackInstalled(langPack);
|
||||
const installPromise2 = LangPackMatcher.ensureLangPackInstalled(langPack);
|
||||
|
|
Загрузка…
Ссылка в новой задаче