66 lines
No EOL
2.9 KiB
JavaScript
66 lines
No EOL
2.9 KiB
JavaScript
// [x-locale-key="<key>"]
|
|
// html[x0-locale-file="<url>"] - which file to use for locale
|
|
// html[x0-locale-no-cache] - do not cache locale
|
|
// html[x0-locale-watch] - watch document for changes and update
|
|
// html[x0-locale-default="en"] - default "en"
|
|
// html[x0-locale-prefer="en"] - prefer locale "en"
|
|
(async () => {
|
|
if (!document.querySelector("html").hasAttribute("x0-locale-file")) return;
|
|
|
|
const getLocale = async (url) => {
|
|
let locale = (document.querySelector("html").hasAttribute("x0-locale-no-cache") ? undefined : localStorage.getItem(url)) ?? (await (await fetch(url)).text());
|
|
if (!document.querySelector("html").hasAttribute("x0-locale-no-cache"))
|
|
fetch(url).then(r => r.text().then(t => localStorage.setItem(url, t)));
|
|
localStorage.setItem(url, locale);
|
|
return JSON.parse(locale);
|
|
};
|
|
|
|
let backupElements = window.x0?.registerStorage("locale") ?? {};
|
|
let locale = await getLocale(document.querySelector("html").getAttribute("x0-locale-file")) ?? {};
|
|
|
|
const getValueFromPath = (obj, path) => path.split(".").reduce((obj, key) => obj && obj[key], obj);
|
|
|
|
function updateLocale() {
|
|
document.querySelectorAll("[x-locale-key]:not([x1-locale-uuid])")
|
|
.forEach(e => {
|
|
let uuid = (Math.random() + new Date().getTime()).toString(36);
|
|
e.setAttribute("x1-locale-uuid", uuid);
|
|
backupElements[uuid] = e.innerHTML;
|
|
let v = getValueFromPath(locale, e.getAttribute("x-locale-key"));
|
|
if (typeof v === 'object') {
|
|
[
|
|
document.querySelector("html").getAttribute("x0-locale-prefer"),
|
|
new URLSearchParams(window.location.search).get("locale"),
|
|
navigator.userLanguage || navigator.language || navigator.browserLanguage,
|
|
...navigator.languages,
|
|
document.querySelector("html").getAttribute("x0-locale-default") ?? "en"
|
|
]
|
|
.filter(l => l)
|
|
.map(l => l.toLowerCase())
|
|
.forEach(l => v = v[l] ?? v)
|
|
if (typeof v === 'object')
|
|
v = '%%definition not found%%'
|
|
}
|
|
e.innerHTML = v;
|
|
})
|
|
}
|
|
|
|
updateLocale();
|
|
|
|
if (document.querySelector("html").hasAttribute("x1-locale-watch"))
|
|
document.querySelector("html").onchange = updateLocale;
|
|
|
|
window.x0?.registerModuleUpdateHook("locale", updateLocale);
|
|
|
|
window.x0?.registerModuleRemoveHook("locale", (s) => {
|
|
console.log(s);
|
|
Object.keys(s)
|
|
.forEach(uuid => {
|
|
let el = document.querySelector(`[x1-locale-uuid="${uuid}"]`);
|
|
requestAnimationFrame(() => {
|
|
el.removeAttribute("x1-locale-uuid");
|
|
el.innerHTML = s[uuid];
|
|
})
|
|
})
|
|
})
|
|
})() |