Spaces:
Running
Running
| /** | |
| * 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 = '<i class="fas fa-globe me-1"></i>' + 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 = '<i class="fas fa-globe me-1"></i>' + 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 = '<i class="fas fa-question-circle"></i> ' + (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; | |
| })(); | |