|
66 | 66 | var params = getScriptParams(); |
67 | 67 |
|
68 | 68 | // ── Determine locale ────────────────────────────────────────────────── |
69 | | - function getBestLocale(desired, available) { |
70 | | - var dLen = 0; |
71 | | - if (!desired || !(dLen = desired.length) || !available) return null; |
72 | | - |
73 | | - var d = new Array(dLen); |
74 | | - var dS = new Array(dLen); |
75 | | - var dC = new Array(dLen); |
76 | | - |
77 | | - function matchLang(k, d) { |
78 | | - var kLen = k.length; |
79 | | - var dLen = d.length; |
80 | | - var kChr; |
81 | | - var dChr; |
82 | | - var kBal; |
83 | | - var dBal; |
84 | | - for (var i = 0; (kBal = i < kLen && (kChr = k[i]) !== '-') & (dBal = i < dLen && (dChr = d[i]) !== '-'); i++) { |
85 | | - if (kChr !== dChr && kChr.toLowerCase() !== dChr.toLowerCase()) return ~i; |
86 | | - } |
87 | | - return kBal || dBal ? ~i : i; |
88 | | - } |
| 69 | + function resolveLocale(tags) { |
| 70 | + var preferences = tags.map(tag => { |
| 71 | + try { return new Intl.Locale(tag); } catch (e) {} |
| 72 | + }); |
89 | 73 |
|
90 | | - var b = null; |
91 | | - var bW = null; |
92 | | - for (var key in available) { |
93 | | - var a = null; |
94 | | - var s = null; |
95 | | - var prio = -1; |
96 | | - var l = null; |
97 | | - var script = null; |
98 | | - for (var i = 0; i < dLen; i++) { |
99 | | - var sep = matchLang(key, desired[i]); |
100 | | - if (sep < 0) continue; |
101 | | - if (!a) try { |
102 | | - a = new Intl.Locale(key); |
103 | | - s = a.script || a.maximize().script; |
104 | | - } catch (e) {} |
105 | | - l = d[i]; |
106 | | - try { |
107 | | - script = l ? l.script || dS[i] : (l = d[i] = new Intl.Locale(desired[i])).script || (dS[i] ||= l.maximize().script); |
108 | | - } catch (e) {} |
109 | | - if (script === s) { |
110 | | - prio = i; |
| 74 | + var best = null; |
| 75 | + var bestWeight = null; |
| 76 | + for (var k in messages) { |
| 77 | + var key = new Intl.Locale(k); |
| 78 | + var script = key.script || key.maximize().script; |
| 79 | + var preferred = -1; |
| 80 | + var preference = null; |
| 81 | + for (var p = 0; p < preferences.length; p++) { |
| 82 | + tag = preferences[p]; |
| 83 | + if (tag && key.language === tag.language && script === (tag.script || tag.maximize().script)) { |
| 84 | + preferred = p; |
| 85 | + preference = tag; |
111 | 86 | break; |
112 | 87 | } |
113 | 88 | } |
114 | | - if (prio < 0) continue; |
115 | | - s = a.script; |
116 | | - var c = a.region; |
117 | | - var w = prio << 5 | (sep + (s ? s.length + 1 : 0) + (c ? c.length + 1 : 0) != key.length) << 4; |
118 | | - if ((s && l.script || c && l.region) && c === l.region) { |
119 | | - w |= !s | !c << 1 | !(s === l.script) << 2; |
| 89 | + if (preferred < 0) continue; |
| 90 | + var country = key.region; |
| 91 | + var weight = preferred << 4; |
| 92 | + if ((script && preference.script || country && preference.region) && country === preference.region) { |
| 93 | + weight |= !script | !country << 1 | !(script === preference.script) << 2; |
120 | 94 | } else { |
121 | | - w |= 8 | !!c << 2 | !!s << 1; |
122 | | - if (c) try { |
123 | | - w |= c !== (dC[prio] ||= new Intl.Locale(d[prio].language, { script: script }).maximize().region); |
124 | | - } catch (e) {} |
| 95 | + weight |= 8 | !!country << 2 | !!script << 1 | (country && country !== new Intl.Locale(preference.language, { script: script }).maximize().region); |
125 | 96 | } |
126 | | - if (bW === null || w < bW) { |
127 | | - b = key; |
128 | | - bW = w; |
| 97 | + if (bestWeight === null || weight < bestWeight) { |
| 98 | + best = key; |
| 99 | + bestWeight = weight; |
129 | 100 | } |
130 | 101 | } |
131 | | - return b; |
| 102 | + return best; |
132 | 103 | } |
133 | 104 |
|
134 | 105 | var locales = navigator.languages; |
135 | | - var preferred = params.lang || |
| 106 | + var prefer = params.lang || |
136 | 107 | document.documentElement.lang || |
137 | 108 | navigator.language || |
138 | 109 | navigator.userLanguage; |
139 | | - if (!locales || !locales.length || preferred !== locales[0]) locales = [...preferred.split(',').map(p => p.trim()), ...locales]; |
| 110 | + if (!locales || !locales.length || prefer !== locales[0]) locales = [...prefer.split(',').map(p => p.trim()), ...locales]; |
140 | 111 |
|
141 | | - var locale = messages[locales[0]] ? locales[0] : getBestLocale(locales, messages) || 'en'; |
| 112 | + var locale = messages[locales[0]] ? locales[0] : resolveLocale(locales) || 'en'; |
142 | 113 |
|
143 | 114 | // ── Size variant ────────────────────────────────────────────────────── |
144 | 115 | var size = params.size === "mini" ? "mini" : "normal"; |
|
0 commit comments