(function () { var STORAGE_KEY = 'hyapp_h5_lang'; var DEFAULT_LANG = 'en'; var SUPPORTED = ['en', 'ar', 'tr', 'es']; var messages = {}; var currentLang = ''; function queryLang() { return new URLSearchParams(window.location.search).get('lang') || ''; } function normalizeLang(value) { var lang = String(value || '') .trim() .toLowerCase() .replace('_', '-'); if (!lang) return ''; if (lang.indexOf('ar') === 0) return 'ar'; if (lang.indexOf('tr') === 0) return 'tr'; if (lang.indexOf('es') === 0) return 'es'; return SUPPORTED.indexOf(lang) >= 0 ? lang : ''; } function resolveLang() { return ( normalizeLang(queryLang()) || normalizeLang(window.localStorage.getItem(STORAGE_KEY)) || normalizeLang(window.navigator.language) || DEFAULT_LANG ); } function load(lang) { var normalized = normalizeLang(lang) || DEFAULT_LANG; return window .fetch('../common/locales/' + normalized + '.json', { cache: 'no-store', }) .then(function (response) { if (!response.ok) throw new Error('locale_not_found'); return response.json(); }) .then(function (json) { messages = json || {}; currentLang = normalized; window.localStorage.setItem(STORAGE_KEY, currentLang); apply(); return messages; }) .catch(function () { if (normalized === DEFAULT_LANG) { messages = {}; currentLang = DEFAULT_LANG; apply(); return messages; } return load(DEFAULT_LANG); }); } function t(key, fallback) { return Object.prototype.hasOwnProperty.call(messages, key) ? messages[key] : fallback || key; } function apply(root) { var scope = root || document; document.documentElement.lang = currentLang || DEFAULT_LANG; document.documentElement.dir = currentLang === 'ar' ? 'rtl' : 'ltr'; scope.querySelectorAll('[data-i18n]').forEach(function (node) { node.textContent = t( node.getAttribute('data-i18n'), node.textContent ); }); scope .querySelectorAll('[data-i18n-placeholder]') .forEach(function (node) { node.setAttribute( 'placeholder', t( node.getAttribute('data-i18n-placeholder'), node.getAttribute('placeholder') || '' ) ); }); scope.querySelectorAll('[data-i18n-aria]').forEach(function (node) { node.setAttribute( 'aria-label', t( node.getAttribute('data-i18n-aria'), node.getAttribute('aria-label') || '' ) ); }); scope.querySelectorAll('[data-lang-option]').forEach(function (node) { node.classList.toggle( 'is-active', node.getAttribute('data-lang-option') === currentLang ); }); scope.querySelectorAll('[data-current-lang]').forEach(function (node) { node.textContent = (currentLang || DEFAULT_LANG).toUpperCase(); }); window.dispatchEvent( new CustomEvent('hyapp:i18n-ready', { detail: { lang: currentLang, messages: messages }, }) ); } function initLanguageMenu() { document.addEventListener('click', function (event) { var toggle = event.target.closest('[data-language-toggle]'); var menu = document.querySelector('[data-language-menu]'); if (toggle && menu) { var expanded = toggle.getAttribute('aria-expanded') === 'true'; toggle.setAttribute( 'aria-expanded', expanded ? 'false' : 'true' ); menu.hidden = expanded; return; } var option = event.target.closest('[data-lang-option]'); if (option) { if (menu) menu.hidden = true; var button = document.querySelector('[data-language-toggle]'); if (button) button.setAttribute('aria-expanded', 'false'); load(option.getAttribute('data-lang-option')); return; } if (menu && !event.target.closest('.language-switcher')) { menu.hidden = true; var languageButton = document.querySelector( '[data-language-toggle]' ); if (languageButton) languageButton.setAttribute('aria-expanded', 'false'); } }); } window.HyAppI18n = { load: load, apply: apply, t: t, lang: function () { return currentLang || DEFAULT_LANG; }, supported: SUPPORTED.slice(), }; document.addEventListener('DOMContentLoaded', function () { initLanguageMenu(); load(resolveLang()); }); })();