diff --git a/public/banner.js b/public/banner.js index 2216db4..4192c42 100644 --- a/public/banner.js +++ b/public/banner.js @@ -66,27 +66,50 @@ var params = getScriptParams(); // ── Determine locale ────────────────────────────────────────────────── - function resolveLocale(tag) { - if (!tag) return "en"; - if (messages[tag]) return tag; - var lower = tag.toLowerCase(); - for (var key in messages) { - if (key.toLowerCase() === lower) return key; - } - var base = tag.split("-")[0].toLowerCase(); - if (messages[base]) return base; - for (var key2 in messages) { - if (key2.toLowerCase().split("-")[0] === base) return key2; + function resolveLocale(tags) { + var preferences = tags.map(tag => { + try { return new Intl.Locale(tag); } catch (e) {} + }); + + var best = null; + var bestWeight = null; + for (var k in messages) { + var key = new Intl.Locale(k); + var script = key.script || key.maximize().script; + var preferred = -1; + var preference = null; + for (var p = 0; p < preferences.length; p++) { + tag = preferences[p]; + if (tag && key.language === tag.language && script === (tag.script || tag.maximize().script)) { + preferred = p; + preference = tag; + break; + } + } + if (preferred < 0) continue; + var country = key.region; + var weight = preferred << 4; + if ((script && preference.script || country && preference.region) && country === preference.region) { + weight |= !script | !country << 1 | !(script === preference.script) << 2; + } else { + weight |= 8 | !!country << 2 | !!script << 1 | (country && country !== new Intl.Locale(preference.language, { script: script }).maximize().region); + } + if (bestWeight === null || weight < bestWeight) { + best = key; + bestWeight = weight; + } } - return "en"; + return best; } - var locale = resolveLocale( - params.lang || + var locales = navigator.languages; + var prefer = params.lang || document.documentElement.lang || navigator.language || - navigator.userLanguage - ); + navigator.userLanguage; + if (!locales || !locales.length || prefer !== locales[0]) locales = [...prefer.split(',').map(p => p.trim()), ...locales]; + + var locale = messages[locales[0]] ? locales[0] : resolveLocale(locales) || 'en'; // ── Size variant ────────────────────────────────────────────────────── var size = params.size === "mini" ? "mini" : "normal"; @@ -295,10 +318,10 @@ } } - cacheFormattingInfo(1, "day"); - cacheFormattingInfo(2, "hour"); - cacheFormattingInfo(3, "minute"); - cacheFormattingInfo(4, "second"); + cacheFormattingInfo(11, "day"); + cacheFormattingInfo(22, "hour"); + cacheFormattingInfo(33, "minute"); + cacheFormattingInfo(44, "second"); function getLocalizedUnit(value, unit, trimConjunction, trimSuffix) { var offset = getOffset(unit); @@ -306,8 +329,8 @@ var p = pfx[offset]; var s = sfx[offset]; return string.slice( - trimConjunction && p || (p == 1 && string[0] === "+") ? pfx[offset] : 0, - trimSuffix && s ? -sfx[offset] : string.length + trimConjunction && p || (p == 1 && string[0] === "+") ? p : 0, + trimSuffix && s ? -s : string.length ); } @@ -319,6 +342,11 @@ var now = new Date().getTime(); var distance = countDownDate - now; + if (distance < 0) { + clearInterval(timer); + return; + } + var days = Math.floor(distance / (1000 * 60 * 60 * 24)); var hours = Math.floor( (distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) @@ -342,10 +370,6 @@ remaining[6] = getLocalizedUnit(seconds, "second", parts++, false); countdownSpan.textContent = remaining.join(""); - - if (distance < 0) { - clearInterval(timer); - } } timer = setInterval(updateBanner, 1000);