|
22 | 22 |
|
23 | 23 | "use strict"; |
24 | 24 |
|
25 | | -const languageUi = { |
| 25 | +const NO_LANGUAGE_SELECTED = { lang: "auto", display: "AUTO", name: "Auto" }; |
| 26 | + |
| 27 | +const SUPPORTED_LANGUAGES = [ |
| 28 | + { lang: "et", display: "ET", name: "Eesti" }, |
| 29 | + { lang: "en", display: "EN", name: "English" }, |
| 30 | + { lang: "ru", display: "RU", name: "Русский" }, |
| 31 | + { lang: "fi", display: "FI", name: "Suomi" }, |
| 32 | + { lang: "hr", display: "HR", name: "Hrvatska" }, |
| 33 | + { lang: "de", display: "DE", name: "Deutsch" }, |
| 34 | + { lang: "fr", display: "FR", name: "Française" }, |
| 35 | + { lang: "nl", display: "NL", name: "Nederlands" }, |
| 36 | + { lang: "cs", display: "CS", name: "Čeština" }, |
| 37 | + { lang: "sk", display: "SK", name: "Slovenština" }, |
| 38 | + NO_LANGUAGE_SELECTED |
| 39 | +]; |
| 40 | + |
| 41 | +const languageComponent = { |
26 | 42 | selectedLang: document.querySelector("#selected-lang"), |
27 | 43 | languageButton: document.querySelector("#language-button"), |
28 | 44 | languageMenu: document.querySelector("#language-menu"), |
29 | | - languageOptions: document.querySelectorAll(".language-option") |
| 45 | + languageGrid: document.querySelector(".language-grid"), |
| 46 | + languageOptions: () => document.querySelectorAll(".language-option") |
30 | 47 | }; |
31 | 48 |
|
32 | | -export function setupLanguageSelection(currentLang, onLangChange) { |
33 | | - const selectedOption = Array.from(languageUi.languageOptions) |
34 | | - .find(option => option.dataset.lang === currentLang); |
| 49 | +/** |
| 50 | + * Reads the `lang` query parameter from the current URL and validates it. |
| 51 | + * |
| 52 | + * - Returns the language code (e.g. "en", "et") if present and included in SUPPORTED_LANGUAGES. |
| 53 | + * - Returns `null` if the parameter is missing, empty, or not in the supported list. |
| 54 | + * |
| 55 | + * This ensures that only recognized languages are passed to the app. If `null` |
| 56 | + * is returned, the Web eID application will fall back to the OS default locale. |
| 57 | + */ |
| 58 | +export function getValidatedLangFromUrl() { |
| 59 | + const lang = new URLSearchParams(window.location.search).get("lang"); |
| 60 | + if (!lang) { |
| 61 | + return null; |
| 62 | + } |
| 63 | + const normalizedLang = lang.trim().toLowerCase(); |
| 64 | + const language = SUPPORTED_LANGUAGES.find(lang => lang.lang === normalizedLang); |
| 65 | + return language ? language.lang : null; |
| 66 | +} |
| 67 | + |
| 68 | +/** |
| 69 | + * Creates a language selections in UI component |
| 70 | + * |
| 71 | + * @param lang Language to be selected in component, example en |
| 72 | + * @param onLangChange Action to be executed when language is changed |
| 73 | + */ |
| 74 | +export function setupLanguageSelection(lang, onLangChange) { |
| 75 | + const language = SUPPORTED_LANGUAGES.find(supportedLanguage => supportedLanguage.lang === lang) ?? NO_LANGUAGE_SELECTED; |
| 76 | + |
| 77 | + SUPPORTED_LANGUAGES.forEach(supportedLanguage => { |
| 78 | + if (supportedLanguage === NO_LANGUAGE_SELECTED) { |
| 79 | + return; |
| 80 | + } |
| 81 | + |
| 82 | + const button = document.createElement("button"); |
| 83 | + button.className = "language-option"; |
| 84 | + button.textContent = supportedLanguage.name; |
| 85 | + |
| 86 | + if (supportedLanguage === language) { |
| 87 | + button.classList.add("selected"); |
| 88 | + setSelectedLanguage(supportedLanguage); |
| 89 | + } |
35 | 90 |
|
36 | | - languageUi.selectedLang.textContent = selectedOption ? selectedOption.dataset.display : "EN"; |
| 91 | + button.addEventListener("click", () => { |
| 92 | + languageComponent.languageOptions().forEach(o => o.classList.remove("selected")); |
| 93 | + button.classList.add("selected"); |
37 | 94 |
|
38 | | - languageUi.languageOptions.forEach(option => |
39 | | - option.classList.toggle('selected', option.dataset.lang === currentLang) |
40 | | - ); |
| 95 | + setSelectedLanguage(supportedLanguage); |
| 96 | + hideLanguageSelectionMenu(); |
41 | 97 |
|
42 | | - languageUi.languageButton.onclick = e => { |
| 98 | + onLangChange(supportedLanguage.lang); |
| 99 | + }); |
| 100 | + |
| 101 | + languageComponent.languageGrid.appendChild(button); |
| 102 | + }); |
| 103 | + |
| 104 | + setSelectedLanguage(language); |
| 105 | + |
| 106 | + languageComponent.languageButton.onclick = e => { |
43 | 107 | e.stopPropagation(); |
44 | | - languageUi.languageMenu.classList.toggle('show'); |
45 | | - e.target.classList.toggle('active'); |
| 108 | + showLanguageSelectionMenu(); |
46 | 109 | }; |
47 | 110 |
|
48 | 111 | document.onclick = () => { |
49 | | - languageUi.languageMenu.classList.remove('show'); |
50 | | - languageUi.languageButton.classList.remove('active'); |
| 112 | + hideLanguageSelectionMenu(); |
51 | 113 | }; |
52 | 114 |
|
53 | | - languageUi.languageMenu.onclick = e => e.stopPropagation(); |
54 | | - |
55 | | - languageUi.languageOptions.forEach(option => { |
56 | | - option.onclick = () => { |
57 | | - onLangChange(option.dataset.lang); |
58 | | - languageUi.selectedLang.textContent = option.dataset.display; |
59 | | - languageUi.languageOptions.forEach(o => o.classList.remove('selected')); |
60 | | - option.classList.add('selected'); |
61 | | - languageUi.languageMenu.classList.remove('show'); |
62 | | - languageUi.languageButton.classList.remove('active'); |
63 | | - }; |
64 | | - }); |
| 115 | + languageComponent.languageMenu.onclick = e => e.stopPropagation(); |
| 116 | +} |
| 117 | + |
| 118 | +function setSelectedLanguage(supportedLanguage) { |
| 119 | + languageComponent.selectedLang.textContent = supportedLanguage.display; |
| 120 | +} |
| 121 | + |
| 122 | +function showLanguageSelectionMenu() { |
| 123 | + languageComponent.languageMenu.classList.toggle("show"); |
| 124 | + languageComponent.languageButton.classList.toggle("active"); |
| 125 | +} |
| 126 | + |
| 127 | +function hideLanguageSelectionMenu() { |
| 128 | + languageComponent.languageMenu.classList.remove("show"); |
| 129 | + languageComponent.languageButton.classList.remove("active"); |
65 | 130 | } |
0 commit comments