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.
2 lines (1 loc) • 2.3 kB
JavaScript
;class o{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=o.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?(this.updateBodyClass(t),t):null}detectLanguageFromClass(){const t=Array.from(document.body.classList).find(a=>a.startsWith("locale-"));return t?t.replace("locale-",""):"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"),l=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(l){let n;try{n=JSON.parse(l)}catch{return}Object.entries(n).forEach(([u,c])=>{let i=this.safeGetTranslation(a,c);!i&&e&&(i=this.safeGetTranslation(e,c)),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()}}module.exports=o;