language-observer
Version:
The LanguageObserver class provides a simple way to manage internationalization in your web application. It automates the process of applying translations and simplifies support for multiple languages.
94 lines (93 loc) • 3.09 kB
JavaScript
class c {
lang = "ru";
observer = null;
constructor() {
this.initializeObserver();
}
static getNestedTranslation(t, a) {
return a.split(".").reduce((e, s) => {
if (e && typeof e == "object" && s in e) return e[s];
}, t);
}
safeGetTranslation(t, a) {
if (!t) return;
const e = c.getNestedTranslation(t, a);
return typeof e == "string" ? e : void 0;
}
checkInitialLanguage() {
if (this.lang && this.lang !== "ru") return;
const t = this.detectLanguageFromParams();
if (t) this.loadLanguage(t);
else {
const a = this.detectLanguageFromClass();
this.loadLanguage(a);
}
}
detectLanguageFromParams() {
if (typeof window > "u") return null;
const t = new URLSearchParams(window.location.search).get("land-geo");
return t && globalThis.translations[t] ? (this.updateBodyClass(t), t) : null;
}
detectLanguageFromClass() {
const t = Array.from(document.body.classList).find((e) => e.startsWith("locale-")), a = t ? t.replace("locale-", "") : "ru";
return globalThis.translations[a] ? a : "ru";
}
updateBodyClass(t) {
document.body.classList.forEach((a) => {
a.startsWith("locale-") && document.body.classList.remove(a);
}), document.body.classList.add(`locale-${t}`);
}
loadLanguage(t) {
const a = globalThis.translations;
this.lang = a[t] ? t : "ru", this.applyTranslations();
}
applyTranslations() {
const t = globalThis.translations, a = t[this.lang], e = t.ru;
a && document.querySelectorAll("[data-i18n], [data-i18n-attr]").forEach((s) => {
const r = s.getAttribute("data-i18n"), o = s.getAttribute("data-i18n-attr");
if (r) {
let n = this.safeGetTranslation(a, r);
!n && e && (n = this.safeGetTranslation(e, r)), n && this.updateElementText(s, n);
}
if (o) {
let n;
try {
n = JSON.parse(o);
} catch {
return;
}
Object.entries(n).forEach(([u, l]) => {
let i = this.safeGetTranslation(a, l);
!i && e && (i = this.safeGetTranslation(e, l)), i && s.setAttribute(u, i);
});
}
});
}
updateElementText(t, a) {
t.hasChildNodes() ? t.childNodes.forEach((e) => {
e.nodeType === Node.TEXT_NODE && (e.textContent = a);
}) : t.textContent = a;
}
initializeObserver() {
this.observer = new MutationObserver((t) => {
for (const a of t) if (a.type === "attributes" && a.attributeName === "class") {
const e = this.detectLanguageFromClass();
e !== this.lang && this.loadLanguage(e);
}
}), this.observer.observe(document.body, { attributes: !0, attributeFilter: ["class"] });
}
init(t = {}) {
const { lang: a } = t;
a ? (this.updateBodyClass(a), this.lang = a, this.loadLanguage(a)) : this.checkInitialLanguage();
}
updateTranslations() {
this.applyTranslations();
}
async loadTranslations(t, a) {
const e = await a(t);
globalThis.translations[t] = e, t === this.lang && this.applyTranslations();
}
}
export {
c as default
};