fix missing info dialog selectors
Sonarqube Scanner / Build and analyze (push) Canceled after 0s

This commit is contained in:
2026-08-29 16:22:32 +02:00
parent fd16c66142
commit cbe50b1a28
+55 -25
View File
@@ -2,16 +2,26 @@
'use strict'; 'use strict';
const DROPDOWN_ANIMATION_MS = 180; const DROPDOWN_ANIMATION_MS = 180;
const dialog = document.getElementById('info-dialog');
const title = document.getElementById('info-dialog-title');
const dropdown = document.getElementById('info-dropdown');
const closeButton = document.getElementById('info-close');
const infoButton = document.getElementById('info-button');
const pageTitles = Object.freeze({ const pageTitles = Object.freeze({
privacy: 'Datenschutzerklärung', privacy: 'Datenschutzerklärung',
imprint: 'Impressum', imprint: 'Impressum',
technology: 'Cookies und Technik' technology: 'Cookies und Technik'
}); });
const dialog = document.getElementById('info-dialog');
const title = document.getElementById('info-dialog-title')
?? dialog?.querySelector('h1, h2, .info-dialog-title')
?? null;
const dropdown = document.getElementById('info-dropdown')
?? document.querySelector('.info-dropdown')
?? null;
const infoButton = document.getElementById('info-button')
?? document.querySelector('[aria-controls="info-dropdown"], .info-button')
?? null;
const closeButton = document.getElementById('info-close')
?? dialog?.querySelector('[data-info-close], .info-close, .info-dialog-close, button[aria-label="Dialog schließen"], button[aria-label="Schließen"]')
?? null;
let dropdownOpen = false; let dropdownOpen = false;
let dropdownCloseTimer = null; let dropdownCloseTimer = null;
@@ -23,7 +33,7 @@
} }
function activate(element, handler) { function activate(element, handler) {
if (!element) return; if (!element || typeof element.addEventListener !== 'function') return;
element.addEventListener('pointerup', event => { element.addEventListener('pointerup', event => {
if (!isActivation(event)) return; if (!isActivation(event)) return;
event.preventDefault(); event.preventDefault();
@@ -96,8 +106,18 @@
return elementContains(infoButton, target) || elementContains(dropdown, target); return elementContains(infoButton, target) || elementContains(dropdown, target);
} }
function isProgressStorageEnabled() {
if (!ns.PrivacyStorage || typeof ns.PrivacyStorage.isProgressStorageEnabled !== 'function') return false;
return ns.PrivacyStorage.isProgressStorageEnabled();
}
function setProgressStorageEnabled(enabled) {
if (!ns.PrivacyStorage || typeof ns.PrivacyStorage.setProgressStorageEnabled !== 'function') return false;
return ns.PrivacyStorage.setProgressStorageEnabled(enabled);
}
function syncStorageToggles() { function syncStorageToggles() {
const enabled = ns.PrivacyStorage.isProgressStorageEnabled(); const enabled = isProgressStorageEnabled();
document.querySelectorAll('.progress-storage-toggle').forEach(toggle => { document.querySelectorAll('.progress-storage-toggle').forEach(toggle => {
toggle.checked = enabled; toggle.checked = enabled;
}); });
@@ -110,7 +130,7 @@
const page = document.querySelector(`[data-info-page="${name}"]`); const page = document.querySelector(`[data-info-page="${name}"]`);
if (!page) return; if (!page) return;
title.textContent = pageTitles[name] ?? 'Informationen'; if (title) title.textContent = pageTitles[name] ?? 'Informationen';
document.querySelectorAll('[data-info-page]').forEach(item => { document.querySelectorAll('[data-info-page]').forEach(item => {
item.hidden = item !== page; item.hidden = item !== page;
}); });
@@ -118,7 +138,13 @@
if (content) content.scrollTop = 0; if (content) content.scrollTop = 0;
} }
function focusSafely(element) {
if (!element || typeof element.focus !== 'function') return;
element.focus({ preventScroll: true });
}
function openDialog(name = 'privacy') { function openDialog(name = 'privacy') {
if (!dialog) return;
const pageName = Object.prototype.hasOwnProperty.call(pageTitles, name) ? name : 'privacy'; const pageName = Object.prototype.hasOwnProperty.call(pageTitles, name) ? name : 'privacy';
setDropdownOpen(false); setDropdownOpen(false);
showPage(pageName); showPage(pageName);
@@ -127,20 +153,22 @@
if (typeof dialog.showModal === 'function') dialog.showModal(); if (typeof dialog.showModal === 'function') dialog.showModal();
else dialog.setAttribute('open', ''); else dialog.setAttribute('open', '');
} }
closeButton.focus(); focusSafely(closeButton ?? dialog);
} }
function closeDialog() { function closeDialog() {
if (typeof dialog.close === 'function') dialog.close(); if (dialog) {
else dialog.removeAttribute('open'); if (typeof dialog.close === 'function') dialog.close();
else dialog.removeAttribute('open');
}
setDropdownOpen(false); setDropdownOpen(false);
infoButton.focus(); focusSafely(infoButton);
} }
function bindStorageToggles() { function bindStorageToggles() {
document.querySelectorAll('.progress-storage-toggle').forEach(toggle => { document.querySelectorAll('.progress-storage-toggle').forEach(toggle => {
toggle.addEventListener('change', event => { toggle.addEventListener('change', event => {
const enabled = ns.PrivacyStorage.setProgressStorageEnabled(event.currentTarget.checked); const enabled = setProgressStorageEnabled(event.currentTarget.checked);
syncStorageToggles(); syncStorageToggles();
document.dispatchEvent(new CustomEvent('wegwichtel:progress-storage-changed', { document.dispatchEvent(new CustomEvent('wegwichtel:progress-storage-changed', {
detail: { enabled } detail: { enabled }
@@ -160,22 +188,24 @@
setDropdownOpen(false); setDropdownOpen(false);
}); });
document.addEventListener('keydown', event => { document.addEventListener('keydown', event => {
if (!dropdownOpen || event.key !== 'Escape' || dialog.open) return; if (!dropdownOpen || event.key !== 'Escape' || dialog?.open) return;
event.preventDefault(); event.preventDefault();
setDropdownOpen(false); setDropdownOpen(false);
infoButton.focus(); focusSafely(infoButton);
}); });
dialog.addEventListener('pointerup', event => { if (dialog) {
if (event.target !== dialog || !isActivation(event)) return; dialog.addEventListener('pointerup', event => {
event.preventDefault(); if (event.target !== dialog || !isActivation(event)) return;
event.stopPropagation(); event.preventDefault();
closeDialog(); event.stopPropagation();
}); closeDialog();
dialog.addEventListener('cancel', event => { });
event.preventDefault(); dialog.addEventListener('cancel', event => {
closeDialog(); event.preventDefault();
}); closeDialog();
});
}
bindStorageToggles(); bindStorageToggles();
syncStorageToggles(); syncStorageToggles();