@formatjs/intl-getcanonicallocales 1.2.0 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/dist/canonicalizer.d.ts +1 -1
- package/dist/canonicalizer.d.ts.map +1 -1
- package/dist/canonicalizer.js +120 -29
- package/dist/canonicalizer.js.map +1 -1
- package/dist/polyfill.js +4 -2
- package/dist/polyfill.js.map +1 -1
- package/dist/umd/intl-locale.js +119 -29
- package/dist/umd/intl-locale.js.map +1 -1
- package/dist/umd/intl-locale.min.js +1 -1
- package/dist/umd/intl-locale.min.js.map +1 -1
- package/dist/umd/polyfill.js +122 -30
- package/dist/umd/polyfill.js.map +1 -1
- package/dist-es6/canonicalizer.d.ts +1 -1
- package/dist-es6/canonicalizer.d.ts.map +1 -1
- package/dist-es6/canonicalizer.js +111 -29
- package/dist-es6/canonicalizer.js.map +1 -1
- package/dist-es6/polyfill.js +4 -2
- package/dist-es6/polyfill.js.map +1 -1
- package/lib/canonicalizer.d.ts +1 -1
- package/lib/canonicalizer.d.ts.map +1 -1
- package/lib/canonicalizer.js +120 -29
- package/lib/canonicalizer.js.map +1 -1
- package/lib/polyfill.js +4 -2
- package/lib/polyfill.js.map +1 -1
- package/package.json +7 -10
- package/src/aliases.ts +5 -654
- package/src/canonicalizer.ts +145 -29
- package/src/polyfill.ts +8 -2
package/src/canonicalizer.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
SEPARATOR,
|
|
13
13
|
} from './parser';
|
|
14
14
|
import * as likelySubtags from 'cldr-core/supplemental/likelySubtags.json';
|
|
15
|
+
import {emitUnicodeLanguageId} from './emitter';
|
|
15
16
|
|
|
16
17
|
function canonicalizeAttrs(strs: string[]): string[] {
|
|
17
18
|
return Object.keys(
|
|
@@ -47,6 +48,16 @@ function compareExtension(e1: Extension, e2: Extension): number {
|
|
|
47
48
|
return e1.type < e2.type ? -1 : e1.type > e2.type ? 1 : 0;
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
function mergeVariants(v1: string[], v2: string[]): string[] {
|
|
52
|
+
const result = [...v1];
|
|
53
|
+
for (const v of v2) {
|
|
54
|
+
if (v1.indexOf(v) < 0) {
|
|
55
|
+
result.push(v);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
50
61
|
/**
|
|
51
62
|
* CAVEAT: We don't do this section in the spec bc they have no JSON data
|
|
52
63
|
* Use the bcp47 data to replace keys, types, tfields, and tvalues by their canonical forms. See Section 3.6.4 U Extension Data Files) and Section 3.7.1 T Extension Data Files. The aliases are in the alias attribute value, while the canonical is in the name attribute value. For example,
|
|
@@ -56,30 +67,132 @@ We get the following transformation:
|
|
|
56
67
|
en-u-ms-imperial ⇒ en-u-ms-uksystem
|
|
57
68
|
* @param lang
|
|
58
69
|
*/
|
|
59
|
-
export function canonicalizeUnicodeLanguageId(
|
|
70
|
+
export function canonicalizeUnicodeLanguageId(
|
|
71
|
+
unicodeLanguageId: UnicodeLanguageId
|
|
72
|
+
): UnicodeLanguageId {
|
|
60
73
|
/**
|
|
61
|
-
* If the language subtag matches the type attribute of a languageAlias element in Supplemental Data,
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* - Five special deprecated grandfathered codes (such as i-default) are in type attributes, and are also replaced.
|
|
74
|
+
* If the language subtag matches the type attribute of a languageAlias element in Supplemental Data, replace the language subtag with the replacement value.
|
|
75
|
+
* 1. If there are additional subtags in the replacement value, add them to the result, but only if there is no corresponding subtag already in the tag.
|
|
76
|
+
* 2. Five special deprecated grandfathered codes (such as i-default) are in type attributes, and are also replaced.
|
|
65
77
|
*/
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
|
|
79
|
+
// From https://github.com/unicode-org/icu/blob/master/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java#L1246
|
|
80
|
+
|
|
81
|
+
// Try language _ variant
|
|
82
|
+
let finalLangAst = unicodeLanguageId;
|
|
83
|
+
if (unicodeLanguageId.variants.length) {
|
|
84
|
+
let replacedLang: string = '';
|
|
85
|
+
for (const variant of unicodeLanguageId.variants) {
|
|
86
|
+
if (
|
|
87
|
+
(replacedLang =
|
|
88
|
+
languageAlias[
|
|
89
|
+
emitUnicodeLanguageId({
|
|
90
|
+
lang: unicodeLanguageId.lang,
|
|
91
|
+
variants: [variant],
|
|
92
|
+
})
|
|
93
|
+
])
|
|
94
|
+
) {
|
|
95
|
+
const replacedLangAst = parseUnicodeLanguageId(
|
|
96
|
+
replacedLang.split(SEPARATOR)
|
|
97
|
+
);
|
|
98
|
+
finalLangAst = {
|
|
99
|
+
lang: replacedLangAst.lang,
|
|
100
|
+
script: finalLangAst.script || replacedLangAst.script,
|
|
101
|
+
region: finalLangAst.region || replacedLangAst.region,
|
|
102
|
+
variants: mergeVariants(
|
|
103
|
+
finalLangAst.variants,
|
|
104
|
+
replacedLangAst.variants
|
|
105
|
+
),
|
|
106
|
+
};
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
73
110
|
}
|
|
74
|
-
|
|
75
|
-
|
|
111
|
+
|
|
112
|
+
// language _ script _ country
|
|
113
|
+
// ug-Arab-CN -> ug-CN
|
|
114
|
+
if (finalLangAst.script && finalLangAst.region) {
|
|
115
|
+
const replacedLang =
|
|
116
|
+
languageAlias[
|
|
117
|
+
emitUnicodeLanguageId({
|
|
118
|
+
lang: finalLangAst.lang,
|
|
119
|
+
script: finalLangAst.script,
|
|
120
|
+
region: finalLangAst.region,
|
|
121
|
+
variants: [],
|
|
122
|
+
})
|
|
123
|
+
];
|
|
124
|
+
if (replacedLang) {
|
|
125
|
+
const replacedLangAst = parseUnicodeLanguageId(
|
|
126
|
+
replacedLang.split(SEPARATOR)
|
|
127
|
+
);
|
|
128
|
+
finalLangAst = {
|
|
129
|
+
lang: replacedLangAst.lang,
|
|
130
|
+
script: replacedLangAst.script,
|
|
131
|
+
region: replacedLangAst.region,
|
|
132
|
+
variants: finalLangAst.variants,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// language _ country
|
|
138
|
+
// eg. az_AZ -> az_Latn_A
|
|
139
|
+
if (finalLangAst.region) {
|
|
140
|
+
const replacedLang =
|
|
141
|
+
languageAlias[
|
|
142
|
+
emitUnicodeLanguageId({
|
|
143
|
+
lang: finalLangAst.lang,
|
|
144
|
+
region: finalLangAst.region,
|
|
145
|
+
variants: [],
|
|
146
|
+
})
|
|
147
|
+
];
|
|
148
|
+
if (replacedLang) {
|
|
149
|
+
const replacedLangAst = parseUnicodeLanguageId(
|
|
150
|
+
replacedLang.split(SEPARATOR)
|
|
151
|
+
);
|
|
152
|
+
finalLangAst = {
|
|
153
|
+
lang: replacedLangAst.lang,
|
|
154
|
+
script: finalLangAst.script || replacedLangAst.script,
|
|
155
|
+
region: replacedLangAst.region,
|
|
156
|
+
variants: finalLangAst.variants,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// only language
|
|
161
|
+
// e.g. twi -> ak
|
|
162
|
+
const replacedLang =
|
|
163
|
+
languageAlias[
|
|
164
|
+
emitUnicodeLanguageId({
|
|
165
|
+
lang: finalLangAst.lang,
|
|
166
|
+
variants: [],
|
|
167
|
+
})
|
|
168
|
+
];
|
|
169
|
+
if (replacedLang) {
|
|
170
|
+
const replacedLangAst = parseUnicodeLanguageId(
|
|
171
|
+
replacedLang.split(SEPARATOR)
|
|
172
|
+
);
|
|
173
|
+
finalLangAst = {
|
|
174
|
+
lang: replacedLangAst.lang,
|
|
175
|
+
script: finalLangAst.script || replacedLangAst.script,
|
|
176
|
+
region: finalLangAst.region || replacedLangAst.region,
|
|
177
|
+
variants: finalLangAst.variants,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (finalLangAst.region) {
|
|
182
|
+
const region = finalLangAst.region.toUpperCase();
|
|
76
183
|
const regionAlias = territoryAlias[region];
|
|
77
184
|
let replacedRegion: string | undefined;
|
|
78
185
|
if (regionAlias) {
|
|
79
186
|
const regions = regionAlias.split(' ');
|
|
80
187
|
replacedRegion = regions[0];
|
|
81
188
|
const likelySubtag =
|
|
82
|
-
likelySubtags.supplemental.likelySubtags[
|
|
189
|
+
likelySubtags.supplemental.likelySubtags[
|
|
190
|
+
emitUnicodeLanguageId({
|
|
191
|
+
lang: finalLangAst.lang,
|
|
192
|
+
script: finalLangAst.script,
|
|
193
|
+
variants: [],
|
|
194
|
+
}) as 'aa'
|
|
195
|
+
];
|
|
83
196
|
if (likelySubtag) {
|
|
84
197
|
const {region: likelyRegion} = parseUnicodeLanguageId(
|
|
85
198
|
likelySubtag.split(SEPARATOR)
|
|
@@ -90,32 +203,35 @@ export function canonicalizeUnicodeLanguageId(lang: UnicodeLanguageId): void {
|
|
|
90
203
|
}
|
|
91
204
|
}
|
|
92
205
|
if (replacedRegion) {
|
|
93
|
-
|
|
206
|
+
finalLangAst.region = replacedRegion;
|
|
94
207
|
}
|
|
208
|
+
finalLangAst.region = finalLangAst.region.toUpperCase();
|
|
95
209
|
}
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
210
|
+
if (finalLangAst.script) {
|
|
211
|
+
finalLangAst.script =
|
|
212
|
+
finalLangAst.script[0].toUpperCase() +
|
|
213
|
+
finalLangAst.script.slice(1).toLowerCase();
|
|
214
|
+
if (scriptAlias[finalLangAst.script]) {
|
|
215
|
+
finalLangAst.script = scriptAlias[finalLangAst.script];
|
|
101
216
|
}
|
|
102
217
|
}
|
|
103
218
|
|
|
104
|
-
if (
|
|
105
|
-
for (let i = 0; i <
|
|
106
|
-
let variant =
|
|
219
|
+
if (finalLangAst.variants.length) {
|
|
220
|
+
for (let i = 0; i < finalLangAst.variants.length; i++) {
|
|
221
|
+
let variant = finalLangAst.variants[i].toLowerCase();
|
|
107
222
|
if (variantAlias[variant]) {
|
|
108
223
|
const alias = variantAlias[variant];
|
|
109
224
|
if (isUnicodeVariantSubtag(alias)) {
|
|
110
|
-
|
|
225
|
+
finalLangAst.variants[i] = alias;
|
|
111
226
|
} else if (isUnicodeLanguageSubtag(alias)) {
|
|
112
227
|
// Yes this can happen per the spec
|
|
113
|
-
|
|
228
|
+
finalLangAst.lang = alias;
|
|
114
229
|
}
|
|
115
230
|
}
|
|
116
231
|
}
|
|
117
|
-
|
|
232
|
+
finalLangAst.variants.sort();
|
|
118
233
|
}
|
|
234
|
+
return finalLangAst;
|
|
119
235
|
}
|
|
120
236
|
|
|
121
237
|
/**
|
|
@@ -128,7 +244,7 @@ export function canonicalizeUnicodeLanguageId(lang: UnicodeLanguageId): void {
|
|
|
128
244
|
export function canonicalizeUnicodeLocaleId(
|
|
129
245
|
locale: UnicodeLocaleId
|
|
130
246
|
): UnicodeLocaleId {
|
|
131
|
-
canonicalizeUnicodeLanguageId(locale.lang);
|
|
247
|
+
locale.lang = canonicalizeUnicodeLanguageId(locale.lang);
|
|
132
248
|
if (locale.extensions) {
|
|
133
249
|
for (const extension of locale.extensions) {
|
|
134
250
|
switch (extension.type) {
|
|
@@ -140,7 +256,7 @@ export function canonicalizeUnicodeLocaleId(
|
|
|
140
256
|
break;
|
|
141
257
|
case 't':
|
|
142
258
|
if (extension.lang) {
|
|
143
|
-
canonicalizeUnicodeLanguageId(extension.lang);
|
|
259
|
+
extension.lang = canonicalizeUnicodeLanguageId(extension.lang);
|
|
144
260
|
}
|
|
145
261
|
extension.fields = canonicalizeKVs(extension.fields);
|
|
146
262
|
break;
|
package/src/polyfill.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {getCanonicalLocales} from '
|
|
2
|
-
if (
|
|
1
|
+
import {getCanonicalLocales} from '.';
|
|
2
|
+
if (
|
|
3
|
+
!('getCanonicalLocales' in Intl) ||
|
|
4
|
+
// Native Intl.getCanonicalLocales is just buggy
|
|
5
|
+
((Intl as any).getCanonicalLocales as typeof getCanonicalLocales)(
|
|
6
|
+
'und-x-private'
|
|
7
|
+
)[0] === 'x-private'
|
|
8
|
+
) {
|
|
3
9
|
Object.defineProperty(Intl, 'getCanonicalLocales', {
|
|
4
10
|
value: getCanonicalLocales,
|
|
5
11
|
writable: true,
|