// setting up the default language with 2 letters (fr, en, pt ...) var user_lang = ( navigator.userLanguage || navigator.browserLanguage || navigator.language || "fr" ).substr(0, 2); // check if the browser support local storage var isStorageEnabled = !(typeof localStorage === "undefined"); let uniqueIdCounter = 0; const toggleLangFlag = (lang) => { const langFlag = document.getElementById(`flag-${lang}`); if (langFlag) { [...langFlag.parentElement.children].map((child) => { child.classList.remove("active"); }); langFlag.classList.toggle("active"); } }; const toggleContentByLang = (lang) => { const elements = document.querySelectorAll(`[lang]`); if (elements) { [...elements].forEach((elt) => { if (elt === document.documentElement) return; if (elt.getAttribute("lang") === lang) { elt.classList.remove("hide"); } else { elt.classList.add("hide"); } }); } }; // get the language parameter from the URL query string const getLangParam = () => { var arr = /lang=([a-z]{2})/g.exec(location.search); return arr ? arr[1] : null; }; // get the language value from the local storage const getLangFromStorage = () => isStorageEnabled ? localStorage.getItem("lang") : undefined; // set the user language or get it from the local storage or from the URL query string user_lang = getLangParam() || getLangFromStorage() || user_lang; // set the user language on the local storage if (isStorageEnabled) { localStorage.setItem("lang", user_lang); } //test if the element is a text node or a comment node or a br node const isTextNode = (elt) => elt.textContent.match(/[^\s]/) && elt.nodeType === elt.TEXT_NODE; const isCommentedNode = (elt) => elt.textContent.match(/[^\s]/) && elt.nodeType === elt.COMMENT_NODE; const isBr = (elt) => elt.tagName && elt.tagName.toLowerCase() === "br"; const isOption = (elt) => elt.tagName && elt.tagName.toLowerCase() === "option"; const translations = {}; // iterate over all translations.node (where the translation comes from) // replace the textContent with the user_lang translation const applyLang = () => { for (let i = 0; i < uniqueIdCounter; i++) { const translation = translations[`translation_${i}`]; if (translation) { translation.node.textContent = translation[user_lang]; } } toggleLangFlag(user_lang); toggleContentByLang(user_lang); }; // set the user language and update the translated text accordingly const setLang = (lang) => { user_lang = lang; if (isStorageEnabled) { localStorage.setItem("lang", user_lang); } applyLang(); }; // add the text node to the global dictionary const addToGlobalDict = (node) => { if ( isTextNode(node) || isCommentedNode(node) || isBr(node) || isOption(node) ) { if (isBr(node)) { node.remove(); } else { const text = node.textContent; let eng = text.match(/\[\[en\]\]([^[\]]*?)(?:\[\[|$)/); let fra = text.match(/\[\[fr\]\]([^[\]]*?)(?:\[\[|$)/); let ptg = text.match(/\[\[pt\]\]([^[\]]*?)(?:\[\[|$)/); if (eng) eng = eng[1]; if (fra) fra = fra[1]; if (ptg) ptg = ptg[1]; const uniqueId = `translation_${uniqueIdCounter++}`; translations[uniqueId] = !!eng || !!fra || !!ptg ? { id: uniqueId, en: eng, fr: fra, pt: ptg, } : { id: uniqueId, en: node.textContent, fr: node.textContent, pt: node.textContent, }; translations[uniqueId].node = node; node.textContent = translations[uniqueId][user_lang]; } } }; // observe the document and add the text node to the global dictionary const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeType === 3 && !node.textContent.trim()) node.remove(); else addToGlobalDict(node); }); }); }); observer.observe(document, { childList: true, subtree: true, }); document.addEventListener("DOMContentLoaded", () => { toggleLangFlag(user_lang); toggleContentByLang(user_lang); var anchors = document.getElementsByTagName("*"); var i; var anchor; for (i = 0; i < anchors.length; i++) { anchor = anchors[i]; anchor.onclick = function () { var code = this.getAttribute("whenClick"); // biome-ignore lint/security/noGlobalEval: false positive eval(code); }; } });