1"use strict"; 2 3document.addEventListener('DOMContentLoaded', function () { 4 // DOM Elements 5 const consentRoot = document.querySelector('.cookie-consent-root'); 6 const acceptButtons = document.querySelectorAll('.cookie-consent-accept'); 7 const rejectButtons = document.querySelectorAll('.cookie-consent-reject'); 8 const cookieConsentPrefix = consentRoot?.getAttribute('data-cookie-prefix') || 'cookie_consent'; 9 const preferencesCookieName = `${cookieConsentPrefix}_preferences`; 10 11 // Modal Elements 12 const preferencesBtn = document.querySelector('.preferences-btn'); 13 const modal = document.querySelector('.cookie-preferences-modal'); 14 const modalOverlay = document.querySelector('.cookie-preferences-modal-overlay'); 15 const modalClose = document.querySelector('.cookie-preferences-modal-close'); 16 const modalSave = document.querySelector('.cookie-preferences-save'); 17 18 // Initialize banner 19 if (consentRoot) { 20 consentRoot.setAttribute('id', 'legal_policy_cookies'); 21 consentRoot.classList.remove('cookie-consent-hide'); 22 if (consentRoot.classList.contains('cookie-disable-interaction')) { 23 document.documentElement.classList.add('cookie-disable-interaction'); 24 } 25 } 26 27 // Check existing consent 28 const cookieConsent = getCookie(cookieConsentPrefix); 29 if (cookieConsent === 'accepted' || cookieConsent === 'rejected') { 30 hideConsentBanner(); 31 } 32 33 // Accept handler 34 acceptButtons.forEach(button => { 35 button.addEventListener('click', () => { 36 setCookie(cookieConsentPrefix, 'accepted', consentRoot?.getAttribute('data-cookie-lifetime') || 7); 37 setAllPreferences(true); 38 hideConsentBanner(); 39 document.dispatchEvent(new CustomEvent('cookieConsentAccepted')); 40 41 if (typeof loadCookieCategoriesEnabledServices === 'function') { 42 try { 43 loadCookieCategoriesEnabledServices(); 44 } catch (e) { 45 console.info(e); 46 } 47 } 48 }); 49 }); 50 51 // Reject handler 52 rejectButtons.forEach(button => { 53 button.addEventListener('click', () => { 54 setCookie(cookieConsentPrefix, 'rejected', consentRoot?.getAttribute('data-reject-lifetime') || 1); 55 setAllPreferences(false); 56 hideConsentBanner(); 57 document.dispatchEvent(new CustomEvent('cookieConsentRejected')); 58 }); 59 }); 60 61 // Modal controls 62 function showModal() { 63 if (!modal) return; 64 document.body.classList.add('modal-open'); 65 modal.setAttribute('aria-hidden', 'false'); 66 modal.classList.add('is-visible'); 67 68 const savedPreferences = getCookiePreferences(); 69 document.querySelectorAll('.cookie-toggle input:not([disabled])').forEach(toggle => { 70 const category = toggle.dataset.category; 71 toggle.checked = savedPreferences ? savedPreferences[category] !== false : true; 72 }); 73 } 74 75 function hideModal() { 76 if (!modal) return; 77 modal.setAttribute('aria-hidden', 'true'); 78 modal.classList.remove('is-visible'); 79 document.body.classList.remove('modal-open'); 80 } 81 82 function setAllPreferences(accept) { 83 const preferences = {}; 84 document.querySelectorAll('.cookie-toggle input[data-category]').forEach(toggle => { 85 preferences[toggle.dataset.category] = toggle.disabled ? true : accept; 86 }); 87 setCookiePreferences(preferences); 88 } 89 90 // Modal events 91 preferencesBtn?.addEventListener('click', showModal); 92 modalOverlay?.addEventListener('click', hideModal); 93 modalClose?.addEventListener('click', hideModal); 94 95 modalSave?.addEventListener('click', () => { 96 const preferences = {}; 97 document.querySelectorAll('.cookie-toggle input[data-category]').forEach(toggle => { 98 preferences[toggle.dataset.category] = toggle.checked; 99 }); 100 101 setCookiePreferences(preferences); 102 setCookie(cookieConsentPrefix, 'accepted', consentRoot?.getAttribute('data-cookie-lifetime') || 7); 103 104 hideModal(); 105 hideConsentBanner(); 106 document.dispatchEvent(new CustomEvent('cookiePreferencesSaved', { detail: preferences })); 107 document.dispatchEvent(new CustomEvent('cookieConsentAccepted')); 108 109 if (typeof loadCookieCategoriesEnabledServices === 'function') { 110 try { 111 loadCookieCategoriesEnabledServices(); 112 } catch (e) { 113 console.info(e); 114 } 115 } 116 }); 117 118 // Escape key 119 document.addEventListener('keydown', function (e) { 120 if (e.key === 'Escape' && modal?.classList.contains('is-visible')) { 121 hideModal(); 122 } 123 }); 124 125 // Helpers 126 function setCookie(name, value, days) { 127 const date = new Date(); 128 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 129 const expires = "; expires=" + date.toUTCString(); 130 const secureFlag = location.protocol === 'https:' ? "; Secure" : ""; 131 document.cookie = `${name}=${value}; path=/; SameSite=Lax${expires}${secureFlag}`; 132 } 133 134 function getCookie(name) { 135 const nameEQ = name + "="; 136 const cookies = document.cookie.split(';'); 137 for (let cookie of cookies) { 138 cookie = cookie.trim(); 139 if (cookie.indexOf(nameEQ) === 0) { 140 return cookie.substring(nameEQ.length); 141 } 142 } 143 return null; 144 } 145 146 function setCookiePreferences(preferences) { 147 const expires = new Date(); 148 expires.setTime(expires.getTime() + (365 * 24 * 60 * 60 * 1000)); 149 const secureFlag = location.protocol === 'https:' ? "; Secure" : ""; 150 document.cookie = `${preferencesCookieName}=${JSON.stringify(preferences)}; expires=${expires.toUTCString()}; path=/; SameSite=Lax${secureFlag}`; 151 } 152 153 function getCookiePreferences() { 154 const name = `${preferencesCookieName}=`; 155 const decoded = decodeURIComponent(document.cookie); 156 const cookies = decoded.split(';'); 157 for (let cookie of cookies) { 158 cookie = cookie.trim(); 159 if (cookie.indexOf(name) === 0) { 160 try { 161 return JSON.parse(cookie.substring(name.length)); 162 } catch (e) { 163 console.warn('Invalid preferences cookie'); 164 } 165 } 166 } 167 return null; 168 } 169 170 function hideConsentBanner() { 171 if (consentRoot) { 172 consentRoot.classList.add('cookie-consent-hide'); 173 document.documentElement.classList.remove('cookie-disable-interaction'); 174 } 175 hideModal(); 176 } 177 178 // Expose globals 179 window.getCookie = getCookie; 180 window.getCookiePreferences = getCookiePreferences; 181 182 function showHideToggleCookiePreferencesModal() { 183 const modal = document.querySelector('.cookie-preferences-modal'); 184 if (!modal) return; 185 186 const isVisible = modal.classList.contains('is-visible'); 187 if (isVisible) { 188 // Hide modal 189 modal.setAttribute('aria-hidden', 'true'); 190 modal.classList.remove('is-visible'); 191 document.body.classList.remove('modal-open'); 192 } else { 193 // Show modal 194 modal.setAttribute('aria-hidden', 'false'); 195 modal.classList.add('is-visible'); 196 document.body.classList.add('modal-open'); 197 198 // Initialize toggles if needed 199 const savedPreferences = window.getCookiePreferences?.(); 200 document.querySelectorAll('.cookie-toggle input:not([disabled])').forEach(toggle => { 201 const category = toggle.dataset.category; 202 toggle.checked = savedPreferences ? savedPreferences[category] !== false : true; 203 }); 204 } 205 } 206 207 // Expose globally for inline onclick 208 window.showHideToggleCookiePreferencesModal = showHideToggleCookiePreferencesModal; 209 210 document.addEventListener('click', function (e) { 211 if (e.target.classList.contains('showHideToggleCookiePreferencesModal')) { 212 e.preventDefault(); 213 showHideToggleCookiePreferencesModal(); 214 } 215 }); 216 217}); 218 219// Prevent layout shift on modal open 220document.head.insertAdjacentHTML('beforeend', ` 221 <style>
222 .modal-open { 223 overflow: hidden; 224 padding-right: var(--scrollbar-width, 0); 225 } 226 </style> 227`);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.