Bug 1635561 - Add Locale to MozIntl; r=zbraniecki

This adds Locale to MozIntl and uses it to replaces some instances where we
used regular expressions to parse language tags. It is based on work done by
André Bargull in Bug 1639515.

Differential Revision: https://phabricator.services.mozilla.com/D98393
This commit is contained in:
Dan Minor 2020-12-07 19:27:54 +00:00
Родитель 9c8c96ad54
Коммит e96efeb12e
5 изменённых файлов: 27 добавлений и 28 удалений

Просмотреть файл

@ -81,6 +81,7 @@ interface mozIMozIntl : nsISupports
readonly attribute jsval Collator;
readonly attribute jsval DateTimeFormat;
readonly attribute jsval ListFormat;
readonly attribute jsval Locale;
readonly attribute jsval NumberFormat;
readonly attribute jsval PluralRules;
readonly attribute jsval RelativeTimeFormat;

Просмотреть файл

@ -12,9 +12,10 @@ const osPrefs = Cc["@mozilla.org/intl/ospreferences;1"].getService(
);
/**
* RegExp used to parse a BCP47 language tag (ex: en-US, sr-Cyrl-RU etc.)
* RegExp used to parse variant subtags from a BCP47 language tag.
* For example: ca-valencia
*/
const languageTagMatch = /^([a-z]{2,3}|[a-z]{4}|[a-z]{5,8})(?:[-_]([a-z]{4}))?(?:[-_]([A-Z]{2}|[0-9]{3}))?((?:[-_](?:[a-z0-9]{5,8}|[0-9][a-z0-9]{3}))*)(?:[-_][a-wy-z0-9](?:[-_][a-z0-9]{2,8})+)*(?:[-_]x(?:[-_][a-z0-9]{1,8})+)?$/i;
const variantSubtagsMatch = /(?:-(?:[a-z0-9]{5,8}|[0-9][a-z0-9]{3}))+$/;
function getDateTimePatternStyle(option) {
switch (option) {
@ -729,6 +730,7 @@ class MozRelativeTimeFormat extends Intl.RelativeTimeFormat {
class MozIntl {
Collator = Intl.Collator;
ListFormat = Intl.ListFormat;
Locale = Intl.Locale;
NumberFormat = Intl.NumberFormat;
PluralRules = Intl.PluralRules;
RelativeTimeFormat = MozRelativeTimeFormat;
@ -842,21 +844,21 @@ class MozIntl {
if (typeof localeCode !== "string") {
throw new TypeError("All locale codes must be strings.");
}
// Get the display name for this dictionary.
// XXX: To be replaced with Intl.Locale once it lands - bug 1433303.
const match = localeCode.match(languageTagMatch);
if (match === null) {
let locale;
try {
locale = new Intl.Locale(localeCode.replaceAll("_", "-"));
} catch {
return localeCode;
}
const [
,
/* languageTag */ languageSubtag,
scriptSubtag,
regionSubtag,
variantSubtags,
] = match;
const {
language: languageSubtag,
script: scriptSubtag,
region: regionSubtag,
} = locale;
const variantSubtags = locale.baseName.match(variantSubtagsMatch);
const displayName = [
this.getLanguageDisplayNames(locales, [languageSubtag])[0],
@ -873,7 +875,7 @@ class MozIntl {
}
if (variantSubtags) {
displayName.push(...variantSubtags.substr(1).split(/[-_]/)); // Collapse multiple variants.
displayName.push(...variantSubtags[0].substr(1).split("-")); // Collapse multiple variants.
}
let modifiers;

Просмотреть файл

@ -25,6 +25,7 @@ function test_methods_calling() {
Services.intl.getLocaleInfo("de");
new Services.intl.DateTimeFormat("fr");
new Services.intl.ListFormat("fr");
new Services.intl.Locale("fr");
new Services.intl.RelativeTimeFormat("fr");
ok(true);
}

Просмотреть файл

@ -308,12 +308,11 @@ NarrateControls.prototype = {
_getLanguageName(lang) {
try {
// This may throw if the lang doesn't match.
// XXX: Replace with Intl.Locale once bug 1433303 lands.
let langCode = lang.match(/^[a-z]{2,3}/)[0];
// This may throw if the lang can't be parsed.
let langCode = new Services.intl.Locale(lang).language;
return Services.intl.getLanguageDisplayNames(undefined, [langCode]);
} catch (e) {
} catch {
return "";
}
},

Просмотреть файл

@ -108,9 +108,12 @@ var DateTimePickerPanel = class {
}
initPicker(detail) {
// TODO: When bug 1376616 lands, replace this.setGregorian with
// mozIntl.Locale for setting calendar to Gregorian
let locale = this.setGregorian(Services.locale.webExposedLocales[0]);
let locale = new Services.intl.Locale(
Services.locale.webExposedLocales[0],
{
calendar: "gregory",
}
).toString();
// Workaround for bug 1418061, while we wait for resolution of
// http://bugs.icu-project.org/trac/ticket/13592: drop the PT region code,
@ -292,13 +295,6 @@ var DateTimePickerPanel = class {
return keys.map(key => displayNames.values[key]);
}
setGregorian(locale) {
if (locale.match(/u-ca-/)) {
return locale.replace(/u-ca-[^-]+/, "u-ca-gregory");
}
return locale + "-u-ca-gregory";
}
handleEvent(aEvent) {
switch (aEvent.type) {
case "load": {