/** * LanguageSwitcher – Global language toggle in the header navbar. * Shares language preference with HelpTooltip & GuidedTour via localStorage. */ (function () { 'use strict'; var STORAGE_KEY = 'onnx_explorer_help_lang'; var DEFAULT_LANG = 'en'; var LANGS = [ { code: 'en', label: 'EN', flag: '🇬🇧' }, { code: 'vi', label: 'VI', flag: '🇻🇳' }, { code: 'ja', label: 'JA', flag: '🇯🇵' } ]; function LanguageSwitcher() { this._wrapper = null; this._currentBtn = null; this._dropdown = null; this._docClickHandler = null; } /** Read saved language from localStorage. */ LanguageSwitcher.prototype._getLang = function () { try { var val = localStorage.getItem(STORAGE_KEY); if (val && LANGS.some(function (l) { return l.code === val; })) return val; } catch (_) {} return DEFAULT_LANG; }; /** Save language to localStorage (shared with HelpTooltip & GuidedTour). */ LanguageSwitcher.prototype._setLang = function (code) { try { localStorage.setItem(STORAGE_KEY, code); } catch (_) {} }; /** Find lang config by code. */ LanguageSwitcher.prototype._findLang = function (code) { for (var i = 0; i < LANGS.length; i++) { if (LANGS[i].code === code) return LANGS[i]; } return LANGS[0]; }; /** Create the switcher UI and insert into the header navbar. */ LanguageSwitcher.prototype.init = function () { var navbar = document.querySelector('.navbar-nav.ms-auto'); if (!navbar) return; var current = this._getLang(); var currentLang = this._findLang(current); // Wrapper var wrapper = document.createElement('div'); wrapper.className = 'lang-switcher d-inline-block me-2'; wrapper.style.position = 'relative'; // Toggle button var btn = document.createElement('button'); btn.className = 'btn btn-outline-light btn-sm'; btn.id = 'langSwitcherBtn'; btn.type = 'button'; btn.title = 'Switch language'; btn.innerHTML = '' + currentLang.label; this._currentBtn = btn; // Dropdown var dropdown = document.createElement('div'); dropdown.className = 'lang-switcher-dropdown'; dropdown.style.display = 'none'; for (var i = 0; i < LANGS.length; i++) { var lang = LANGS[i]; var option = document.createElement('button'); option.className = 'lang-switcher-option' + (lang.code === current ? ' active' : ''); option.type = 'button'; option.dataset.lang = lang.code; option.innerHTML = lang.flag + ' ' + lang.label; dropdown.appendChild(option); } wrapper.appendChild(btn); wrapper.appendChild(dropdown); this._wrapper = wrapper; this._dropdown = dropdown; // Insert as the first item in the navbar navbar.insertBefore(wrapper, navbar.firstChild); // Bind events this._bindEvents(); console.log('[LanguageSwitcher] Initialized with lang:', current); }; LanguageSwitcher.prototype._bindEvents = function () { var self = this; // Toggle dropdown this._currentBtn.addEventListener('click', function (e) { e.stopPropagation(); var visible = self._dropdown.style.display !== 'none'; self._dropdown.style.display = visible ? 'none' : 'block'; }); // Option click this._dropdown.addEventListener('click', function (e) { var option = e.target.closest('.lang-switcher-option'); if (!option) return; var code = option.dataset.lang; self._dropdown.style.display = 'none'; self._applyLanguage(code); }); // Close on outside click this._docClickHandler = function () { if (self._dropdown) self._dropdown.style.display = 'none'; }; document.addEventListener('click', this._docClickHandler); }; /** Apply language change globally. */ LanguageSwitcher.prototype._applyLanguage = function (code) { var langObj = this._findLang(code); this._setLang(code); // Update button label if (this._currentBtn) { this._currentBtn.innerHTML = '' + langObj.label; } // Update active state in dropdown if (this._dropdown) { var options = this._dropdown.querySelectorAll('.lang-switcher-option'); for (var i = 0; i < options.length; i++) { options[i].classList.toggle('active', options[i].dataset.lang === code); } } // Sync with HelpTooltip if available if (window._onnxApp && window._onnxApp.getHelpTooltip) { var ht = window._onnxApp.getHelpTooltip(); if (ht && ht.setLanguage) ht.setLanguage(code); } // Update GuidedTour button label var tourBtn = document.getElementById('tourBtn'); if (tourBtn) { var labels = { en: 'Guide', vi: 'Hướng dẫn', ja: 'ガイド' }; tourBtn.innerHTML = ' ' + (labels[code] || labels.en); tourBtn.title = { en: 'User guide', vi: 'Hướng dẫn sử dụng', ja: 'ユーザーガイド' }[code] || 'User guide'; } console.log('[LanguageSwitcher] Language changed to:', code); }; LanguageSwitcher.prototype.destroy = function () { if (this._docClickHandler) { document.removeEventListener('click', this._docClickHandler); this._docClickHandler = null; } if (this._wrapper && this._wrapper.parentNode) { this._wrapper.parentNode.removeChild(this._wrapper); } this._wrapper = null; this._currentBtn = null; this._dropdown = null; }; window.LanguageSwitcher = LanguageSwitcher; })();