UNPKG

3.66 kBJavaScriptView Raw
1const parseLanguageList = require('./parse-language-list');
2const availableLocaleIds = require('./locale-ids');
3
4/**
5 * 根据输入返回项目匹配的语言包ID (localeId)
6 * 如果没有匹配,返回项目语言包ID的第一项
7 * 注:仅为返回,没有赋值操作
8 *
9 * @param {string|string[]} input
10 * @param {string[]} [localeIds] 可选语言ID列表
11 * @returns 匹配的语言包ID localeId 或 availableLocaleIds[0]
12 */
13const parseLocaleId = (input, localeIds = availableLocaleIds) => {
14 // 检查是否包含分号,如果是,按语言列表处理为array
15 // eg: zh-CN,zh;q=0.8,en;q=0.6
16 if (typeof input === 'string' && input.indexOf(';') > -1)
17 input = parseLanguageList(input);
18
19 // 检查是否为array
20 if (Array.isArray(input)) {
21 let id;
22
23 input.some(thisId => {
24 id = checkItem(thisId, localeIds);
25 return id;
26 });
27
28 return id || localeIds[0];
29 } else if (!input && typeof navigator !== 'undefined')
30 return parseLocaleId(
31 navigator.languages ||
32 navigator.language ||
33 navigator.browserLanguage ||
34 navigator.systemLanguage ||
35 navigator.userLanguage ||
36 localeIds[0],
37 localeIds
38 );
39 else if (input) return checkItem(input, localeIds) || localeIds[0];
40
41 return localeIds[0];
42};
43
44module.exports = parseLocaleId;
45
46// ============================================================================
47
48/**
49 * 标准化语言包ID,方便匹配
50 * - 全部小写
51 * - `_` 变为 `-`
52 * @param {string} input
53 * @returns {string}
54 */
55const normalize = localeId => localeId.toLowerCase().replace(/_/g, '-');
56
57/**
58 * 获取基础语种
59 * @param {string} localeId
60 * @param {string} [seperator='-'] 连接线,默认为 `-`
61 * @returns {string}
62 */
63const getLocaleBase = (localeId, seperator = '-') =>
64 localeId.split(seperator)[0];
65
66/**
67 * 检查单项,如果和availableLocales内的项目有匹配,返回匹配,否则返回null
68 * @param {string} input 检查项
69 * @param {string[]} [localeIds] 可选语言ID列表
70 * @returns 匹配的 localeId 或 null
71 */
72const checkItem = (input, localeIds = availableLocaleIds) => {
73 const inputNormalized = normalize(input);
74 const localeIdsNormalized = localeIds.map(normalize);
75
76 let result;
77
78 // 如果有完整匹配的项,直接返回结果
79 localeIdsNormalized.some((thisLocaleId, index) => {
80 if (thisLocaleId === inputNormalized) {
81 result = localeIds[index];
82 return true;
83 }
84 return false;
85 });
86 if (result) return result;
87
88 // 之后根据基础语种进行检查
89
90 /** 基础语种 (eg: `zh-CN` 基础语种为 `zh`) */
91 const baseLocale = getLocaleBase(inputNormalized, '-');
92
93 // 如果可选列表中有对应的基础语种,返回该结果
94 localeIdsNormalized.some((thisLocaleId, index) => {
95 if (thisLocaleId === baseLocale) {
96 result = localeIds[index];
97 return true;
98 }
99 return false;
100 });
101 if (result) return result;
102
103 // 检查可选列表中每一项的基础语种,返回第一个匹配
104 localeIdsNormalized.some((thisLocaleId, index) => {
105 const thisBaseLocale = getLocaleBase(thisLocaleId, '-');
106 if (thisBaseLocale === baseLocale) {
107 result = localeIds[index];
108 return true;
109 }
110 return false;
111 });
112 if (result) return result;
113
114 return null;
115};