Skip to content

Commit 6cbda0d

Browse files
authored
banner.js: Factor in language preference list from browser and more robust locales selection
1 parent a8eefaf commit 6cbda0d

File tree

1 file changed

+74
-21
lines changed

1 file changed

+74
-21
lines changed

public/banner.js

Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -66,27 +66,79 @@
6666
var params = getScriptParams();
6767

6868
// ── Determine locale ──────────────────────────────────────────────────
69-
function resolveLocale(tag) {
70-
if (!tag) return "en";
71-
if (messages[tag]) return tag;
72-
var lower = tag.toLowerCase();
73-
for (var key in messages) {
74-
if (key.toLowerCase() === lower) return key;
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;
7588
}
76-
var base = tag.split("-")[0].toLowerCase();
77-
if (messages[base]) return base;
78-
for (var key2 in messages) {
79-
if (key2.toLowerCase().split("-")[0] === base) return key2;
89+
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;
111+
break;
112+
}
113+
}
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;
120+
} 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) {}
125+
}
126+
if (bW === null || w < bW) {
127+
b = key;
128+
bW = w;
129+
}
80130
}
81-
return "en";
131+
return b;
82132
}
83133

84-
var locale = resolveLocale(
85-
params.lang ||
134+
var locales = navigator.languages;
135+
var preferred = params.lang ||
86136
document.documentElement.lang ||
87137
navigator.language ||
88-
navigator.userLanguage
89-
);
138+
navigator.userLanguage;
139+
if (!locales || !locales.length || preferred !== locales[0]) locales = [...preferred.split(',').map(p => p.trim()), ...locales];
140+
141+
var locale = messages[locales[0]] ? locales[0] : getBestLocale(locales, messages) || 'en';
90142

91143
// ── Size variant ──────────────────────────────────────────────────────
92144
var size = params.size === "mini" ? "mini" : "normal";
@@ -306,8 +358,8 @@
306358
var p = pfx[offset];
307359
var s = sfx[offset];
308360
return string.slice(
309-
trimConjunction && p || (p == 1 && string[0] === "+") ? pfx[offset] : 0,
310-
trimSuffix && s ? -sfx[offset] : string.length
361+
trimConjunction && p || (p == 1 && string[0] === "+") ? p : 0,
362+
trimSuffix && s ? -s : string.length
311363
);
312364
}
313365

@@ -319,6 +371,11 @@
319371
var now = new Date().getTime();
320372
var distance = countDownDate - now;
321373

374+
if (distance < 0) {
375+
clearInterval(timer);
376+
return;
377+
}
378+
322379
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
323380
var hours = Math.floor(
324381
(distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
@@ -342,10 +399,6 @@
342399
remaining[6] = getLocalizedUnit(seconds, "second", parts++, false);
343400

344401
countdownSpan.textContent = remaining.join("");
345-
346-
if (distance < 0) {
347-
clearInterval(timer);
348-
}
349402
}
350403

351404
timer = setInterval(updateBanner, 1000);

0 commit comments

Comments
 (0)