/** * ATT Consent Banner UI * * Handles banner display, preferences modal, floating widget, anchor link * triggers, focus trapping, and user interactions. * Depends on AttConsent (consent-manager.js) for consent state management. */ (function() { 'use strict'; var banner = document.getElementById('att-cc-banner'); var modal = document.getElementById('att-cc-modal'); var widget = document.getElementById('att-cc-widget'); if (!banner || !modal) { return; } // --- Modal buttons --- var saveBtn = modal.querySelector('[data-att-cc="save-preferences"]'); var closeBtn = modal.querySelector('[data-att-cc="close-modal"]'); var overlay = modal.querySelector('.att-cc-modal__overlay'); if (saveBtn) { saveBtn.addEventListener('click', function() { var categories = { functional: document.getElementById('att-cc-functional').checked, analytics: document.getElementById('att-cc-analytics').checked, marketing: document.getElementById('att-cc-marketing').checked }; AttConsent.update(categories); closeModal(); hideBanner(); showWidget(); }); } if (closeBtn) { closeBtn.addEventListener('click', function() { closeModal(); }); } if (overlay) { overlay.addEventListener('click', function() { closeModal(); }); } // --- Floating widget click handler --- if (widget) { widget.addEventListener('click', function() { openModal(); }); } // --- Anchor link listener --- document.addEventListener('click', function(e) { var link = e.target.closest('a[href="#att-cc-preferences"]'); if (link) { e.preventDefault(); openModal(); } }); // --- Initial state --- if (AttConsent.hasConsent()) { hideBanner(); showWidget(); } else { // Move focus to banner so screen readers announce it. banner.focus(); // --- Banner buttons (only needed for first-time visitors) --- var acceptBtn = banner.querySelector('[data-att-cc="accept-all"]'); var rejectBtn = banner.querySelector('[data-att-cc="reject-all"]'); var prefsBtn = banner.querySelector('[data-att-cc="preferences"]'); if (acceptBtn) { acceptBtn.addEventListener('click', function() { AttConsent.update({ functional: true, analytics: true, marketing: true }); hideBanner(); showWidget(); }); } if (rejectBtn) { rejectBtn.addEventListener('click', function() { AttConsent.update({ functional: false, analytics: false, marketing: false }); hideBanner(); showWidget(); }); } if (prefsBtn) { prefsBtn.addEventListener('click', function() { openModal(); }); } } // --- Helper functions --- // Tracks the current focus trap handler for cleanup. var activeTrapHandler = null; function hideBanner() { banner.setAttribute('aria-hidden', 'true'); banner.classList.add('att-cc-hidden'); } function showWidget() { if (widget) { widget.style.display = ''; } } function openModal() { // Pre-fill checkboxes with existing consent if available. var existing = AttConsent.getConsent(); if (existing) { setCheckbox('att-cc-functional', existing.functional); setCheckbox('att-cc-analytics', existing.analytics); setCheckbox('att-cc-marketing', existing.marketing); } modal.setAttribute('aria-hidden', 'false'); modal.classList.add('att-cc-modal--open'); document.body.classList.add('att-cc-modal-active'); trapFocus(modal); } function closeModal() { modal.setAttribute('aria-hidden', 'true'); modal.classList.remove('att-cc-modal--open'); document.body.classList.remove('att-cc-modal-active'); // Clean up focus trap listener. if (activeTrapHandler) { modal.removeEventListener('keydown', activeTrapHandler); activeTrapHandler = null; } // Return focus to the widget if visible, otherwise the banner prefs button. if (widget && widget.style.display !== 'none') { widget.focus(); } else { var prefsBtn = banner.querySelector('[data-att-cc="preferences"]'); if (prefsBtn) { prefsBtn.focus(); } } } function setCheckbox(id, value) { var el = document.getElementById(id); if (el) { el.checked = !!value; } } /** * Trap keyboard focus within an element. * * @param {HTMLElement} element The container to trap focus in. */ function trapFocus(element) { var focusable = element.querySelectorAll( 'button, [href], input:not([disabled]), select, textarea, [tabindex]:not([tabindex="-1"])' ); if (focusable.length === 0) { return; } var first = focusable[0]; var last = focusable[focusable.length - 1]; first.focus(); function handleKeydown(e) { if (e.key === 'Escape') { closeModal(); return; } if (e.key !== 'Tab') { return; } if (e.shiftKey) { if (document.activeElement === first) { last.focus(); e.preventDefault(); } } else { if (document.activeElement === last) { first.focus(); e.preventDefault(); } } } activeTrapHandler = handleKeydown; element.addEventListener('keydown', handleKeydown); } })();