// Einwilligung ohne Neuladen (ADR 115). // // Ohne dieses Skript schicken der Hinweis und der Knopf am eingebetteten Inhalt ein Formular ab, // der Server setzt das Cookie und leitet auf dieselbe Seite zurück - die Seite lädt neu. Mit dem // Skript geht dasselbe Formular im Hintergrund an denselben Endpunkt; die Kopfzeile // X-Kant-Consent sagt dem Server, dass keine Weiterleitung nötig ist. Danach holt das Skript die // Seite noch einmal und übernimmt daraus nur, was sich durch die Entscheidung ändert: die // eingebetteten Inhalte und die Zeile „Rechtliches“. Die Adresse eines Inhalts steht so weiterhin // erst nach der Einwilligung im Dokument. // // Geht dabei etwas schief, schickt das Skript das Formular ganz normal ab: lieber einmal neu // laden als eine Entscheidung, die nicht ankommt. (() => { const forms = document.querySelectorAll('.consent-bar form, .embed-blocked form'); if (forms.length === 0) { return; } const replaceFrom = async () => { const response = await fetch(location.href, { credentials: 'same-origin', headers: { Accept: 'text/html' } }); if (!response.ok) { throw new Error('Seite nicht geladen'); } const fresh = new DOMParser().parseFromString(await response.text(), 'text/html'); for (const blocked of document.querySelectorAll('.embed-blocked[id]')) { const next = fresh.getElementById(blocked.id); if (next && !next.classList.contains('embed-blocked')) { blocked.replaceWith(document.importNode(next, true)); } } for (const legal of document.querySelectorAll('.block-legal[id]')) { const next = fresh.getElementById(legal.id); if (next) { legal.replaceWith(document.importNode(next, true)); } } }; for (const form of forms) { form.addEventListener('submit', async (event) => { event.preventDefault(); const button = event.submitter; const body = new FormData(form, button); const placeholder = form.closest('.embed-blocked'); for (const control of form.querySelectorAll('button')) { control.disabled = true; } try { const saved = await fetch(form.action, { method: 'POST', body, credentials: 'same-origin', headers: { 'X-Kant-Consent': '1' } }); if (!saved.ok) { throw new Error('Entscheidung nicht gespeichert'); } // Wer etwas erlaubt hat, bekommt die Inhalte jetzt; wer abgelehnt hat, braucht keinen // zweiten Abruf - es ändert sich nichts außer dem Hinweis. if (body.get('choice') !== 'none' && document.querySelector('.embed-blocked')) { await replaceFrom(); } document.querySelector('.consent-bar')?.remove(); if (placeholder) { // Der Knopf ist mit dem Platzhalter verschwunden; der Fokus geht an den Inhalt, der an // seiner Stelle steht. const frame = document.getElementById(placeholder.id)?.querySelector('iframe'); frame?.focus(); } else { // Entschieden im Hinweis: der Fokus beginnt wieder am Seitenanfang, wie nach dem // Neuladen - der nächste Tab führt zu „Zum Inhalt springen“. document.getElementById('seitenanfang')?.focus({ preventScroll: true }); } } catch { // Rückfall: das Formular normal absenden, samt gedrücktem Knopf. for (const control of form.querySelectorAll('button')) { control.disabled = false; } withChoice(form, button).submit(); } }); } // form.submit() schickt den gedrückten Knopf nicht mit; sein Wert wandert als verstecktes Feld // ins Formular, damit der Rückfall dieselbe Entscheidung sendet. function withChoice(form, button) { if (button?.name) { const field = document.createElement('input'); field.type = 'hidden'; field.name = button.name; field.value = button.value; form.append(field); } return form; } })();