diff --git a/public/js/legal-ui.js b/public/js/legal-ui.js index a619fc1..61bd959 100644 --- a/public/js/legal-ui.js +++ b/public/js/legal-ui.js @@ -36,6 +36,7 @@ function qsa(selector, root = document) { if (root && typeof root.querySelectorAll === 'function') return Array.from(root.querySelectorAll(selector)); if (root !== document && typeof document.querySelectorAll === 'function') return Array.from(document.querySelectorAll(selector)); + if (root === document && typeof document.querySelectorAll === 'function') return Array.from(document.querySelectorAll(selector)); return []; } @@ -112,8 +113,7 @@ 'aria-label': 'Informationsmenü öffnen', title: 'Informationen' }); - const icon = createElement('span', { 'aria-hidden': 'true' }, 'i'); - append(infoButton, icon); + append(infoButton, createElement('span', { 'aria-hidden': 'true' }, 'i')); append(control, infoButton); } @@ -134,7 +134,7 @@ if (typeof infoButton.getAttribute !== 'function' || !infoButton.getAttribute('aria-label')) { setAttribute(infoButton, 'aria-label', 'Informationsmenü öffnen'); } - if (!String(infoButton.textContent ?? '').trim() && typeof document.createElement === 'function') { + if (!String(infoButton.textContent ?? '').trim()) { append(infoButton, createElement('span', { 'aria-hidden': 'true' }, 'i')); } } @@ -145,8 +145,8 @@ menuEntries.forEach(([target, label]) => { let button = qs(`[data-info-target="${target}"]`, dropdown) - || qsa('[data-info-target]').find(item => item.dataset?.infoTarget === target); - if (!button && typeof document.createElement === 'function') { + || qsa('[data-info-target]', dropdown).find(item => item.dataset?.infoTarget === target); + if (!button) { button = createElement('button', { type: 'button', dataset: { infoTarget: target } @@ -231,26 +231,20 @@ } } - if (dialog) { - setAttribute(dialog, 'aria-labelledby', 'info-dialog-title'); - } + if (dialog) setAttribute(dialog, 'aria-labelledby', 'info-dialog-title'); if (backButton) { setAttribute(backButton, 'type', 'button'); setAttribute(backButton, 'aria-label', 'Zurück zum Informationsmenü'); backButton.hidden = true; } - if (legacyMenu) { - legacyMenu.hidden = true; - } + if (legacyMenu) legacyMenu.hidden = true; if (closeButton) { setAttribute(closeButton, 'type', 'button'); setAttribute(closeButton, 'aria-label', 'Informationsfenster schließen'); if (!String(closeButton.textContent ?? '').trim()) closeButton.textContent = '×'; } - if (content) { - Object.keys(pageTitles).forEach(name => ensureInfoPage(content, name)); - } + if (content) Object.keys(pageTitles).forEach(name => ensureInfoPage(content, name)); return { dialog, title, backButton, legacyMenu, closeButton, content }; } @@ -302,8 +296,31 @@ setAttribute(elements.infoButton, 'aria-expanded', dropdownOpen ? 'true' : 'false'); } - function toggleDropdown() { - setDropdownOpen(!dropdownOpen); + function hidePages() { + qsa('[data-info-page]').forEach(item => { + item.hidden = true; + }); + } + + function openLegacyMenu() { + if (!elements?.dialog) return; + hidePages(); + if (elements.title) elements.title.textContent = 'Informationen'; + if (elements.legacyMenu) elements.legacyMenu.hidden = false; + if (elements.backButton) elements.backButton.hidden = true; + if (!elements.dialog.open) { + if (typeof elements.dialog.showModal === 'function') elements.dialog.showModal(); + else setAttribute(elements.dialog, 'open', ''); + } + focusSafely(elements.closeButton ?? elements.dialog); + } + + function handleInfoButton() { + if (elements?.dropdown) { + setDropdownOpen(!dropdownOpen); + return; + } + openLegacyMenu(); } function elementContains(element, target) { @@ -361,6 +378,8 @@ if (!elements?.dialog) return; const pageName = Object.prototype.hasOwnProperty.call(pageTitles, name) ? name : 'privacy'; setDropdownOpen(false); + if (elements?.legacyMenu) elements.legacyMenu.hidden = true; + if (elements?.backButton) elements.backButton.hidden = !elements?.legacyMenu; showPage(pageName); syncStorageToggles(); if (!elements.dialog.open) { @@ -384,7 +403,7 @@ if (toggle.dataset?.wegwichtelStorageBound === 'true') return; if (toggle.dataset) toggle.dataset.wegwichtelStorageBound = 'true'; toggle.addEventListener('change', event => { - const source = event.currentTarget || toggle; + const source = event.currentTarget || event.target || toggle; const enabled = setProgressStorageEnabled(Boolean(source.checked)); syncStorageToggles(); document.dispatchEvent(new CustomEvent('wegwichtel:progress-storage-changed', { @@ -394,12 +413,18 @@ }); } - function bindDialog() { - activate(elements?.infoButton, toggleDropdown); - activate(elements?.closeButton, closeDialog); - activate(elements?.backButton, () => setDropdownOpen(true)); + function infoTargetButtons() { + if (elements?.dropdown) return qsa('[data-info-target]', elements.dropdown); + if (elements?.legacyMenu) return qsa('[data-info-target]', elements.legacyMenu); + return qsa('[data-info-target]'); + } - qsa('[data-info-target]', elements?.dropdown).forEach(button => { + function bindDialog() { + activate(elements?.infoButton, handleInfoButton); + activate(elements?.closeButton, closeDialog); + activate(elements?.backButton, openLegacyMenu); + + infoTargetButtons().forEach(button => { activate(button, () => openDialog(button.dataset?.infoTarget)); }); @@ -441,7 +466,7 @@ ns.LegalUi = Object.freeze({ open: openDialog, close: closeDialog, - toggleMenu: toggleDropdown, + toggleMenu: handleInfoButton, closeMenu: () => setDropdownOpen(false), syncStorageToggles });