1// Consent class 2const serviceConfigs = JSON.parse(JSON.stringify(allServiceSettings)); 3 4// Function to retrieve a cookie by its name 5function getCookie(name) { 6 var nameEQ = name + "="; 7 var ca = document.cookie.split(';'); 8 for (var i = 0; i < ca.length; i++) { 9 var c = ca[i]; 10 while (c.charAt(0) == ' ') c = c.substring(1); 11 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); 12 } 13 return null; 14} 15 16// Function to set a cookie with a specified name, value, and expiration date 17function setCookie(name, value, daysToExpire) { 18 var expires = ""; 19 if (daysToExpire) { 20 var date = new Date(); 21 date.setTime(date.getTime() + (daysToExpire * 24 * 60 * 60 * 1000)); 22 expires = "; expires=" + date.toUTCString(); 23 } 24 document.cookie = name + "=" + (value || "") + expires + "; path=/"; 25} 26 27// Function to evaluate the final consent value based on service settings 28function evaluateFinalValue(serviceSettings, settingKey) { 29 let hasGranted = false; 30 let hasDenied = false; 31 32 // Iterate through all services and check their consent settings 33 serviceSettings.forEach(settings => { 34 if (settings[settingKey] === 'granted') 35 if (settings[settingKey] === 'granted') hasGranted = true; 36 else if (settings[settingKey] === 'denied') hasDenied = true; 37 }); 38 39 // If there is at least one "denied" value, return "denied" 40 if (hasDenied) return 'denied'; 41 42 // If there is only one "granted" value, return "granted" 43 if (hasGranted) return 'granted'; 44 45 // If all values are "not set" or there are no explicit "granted"/"denied" values, return "denied" 46 return 'denied'; 47} 48 49// Function to update the cookie with the final consent values 50function updateCookieWithFinalConsent(name, daysToExpire, services) { 51 const cookieValue = getCookie(name); 52 if (cookieValue !== null) { 53 const obj = JSON.parse(decodeURIComponent(cookieValue)); 54 55 // Evaluate and set the final values for each consent setting 56 ['ad_storage','analytics_storage','ad_user_data','ad_personalization', 57 'personalization_storage','functionality_storage','security_storage'] 58 .forEach(key => { 59 obj[key] = evaluateFinalValue(services, key); 60 }); 61 62 setCookie(name, encodeURIComponent(JSON.stringify(obj)), daysToExpire); 63 pushTriggerAfterConsentChanged(obj); 64 } else { 65 console.log("Cookie name '" + name + "' does not exist."); 66 } 67} 68 69// Function to push the trigger for gtm after consent changed 70function pushTriggerAfterConsentChanged(changes) { 71 window.dataLayer = window.dataLayer || []; 72 window.dataLayer.push({ 73 event: 'cmp_we_cookie_consent_changed', // Custom-Event-Name 74 we_consent_state: { // Add all final states 75 ad_storage : changes.ad_storage, 76 analytics_storage : changes.analytics_storage, 77 ad_user_data : changes.ad_user_data, 78 ad_personalization : changes.ad_personalization, 79 personalization_storage: changes.personalization_storage, 80 functionality_storage : changes.functionality_storage, 81 security_storage : changes.security_storage 82 } 83 }); 84} 85 86// Debug function to log all stored service settings 87function getAllServiceSettings() { 88 // Log all service settings to the console 89 console.log(allServiceSettings); 90 // Optionally return allServiceSettings; 91 // return allServiceSettings; 92} 93 94// main controller 95let ConsentApp = new function ConsentController() { 96 // public functions 97 /** 98 * Callback function for GoogleTagManager Script to handle consent state changes and fire the dataLayer trigger 99 * @param bool state 100 * @param object service 101 */ 102 this.consentChanged = function(state, service) { 103 // Check if the service is related to Google Tag Manager 104 const isGTM = service.name.indexOf('google-tagmanager-service') !== -1; 105 if (isGTM) { 106 // A) Remap all services - only the service that has just been changed receives either its config values (if state=true) or "denied" all-over. 107 allServiceSettings = allServiceSettings.map(tempSettings => { 108 if (tempSettings.serviceId !== service.name) { 109 // Unmodified copy 110 return { 111 serviceId: tempSettings.serviceId, 112 serviceConsent: tempSettings.serviceConsent, 113 ad_storage: tempSettings.ad_storage, 114 analytics_storage: tempSettings.analytics_storage, 115 ad_user_data: tempSettings.ad_user_data, 116 ad_personalization: tempSettings.ad_personalization, 117 functionality_storage: tempSettings.functionality_storage, 118 personalization_storage: tempSettings.personalization_storage, 119 security_storage: tempSettings.security_storage 120 }; 121 } 122 123 // Get the original config 124 const originalConfig = serviceConfigs.find(original => original.serviceId === tempSettings.serviceId); 125 const updated = { serviceId: tempSettings.serviceId, serviceConsent: state }; 126 127 // For every consent type 128 ['ad_storage','analytics_storage','ad_user_data','ad_personalization', 129 'personalization_storage','functionality_storage','security_storage'] 130 .forEach(key => { 131 // if consent is granted: accept from config 132 // if consent is denied: always 'denied' 133 updated[key] = state ? originalConfig[key] : 'denied'; 134 }); 135 136 return updated; 137 }); 138 139 // B) Evaluate only the granted services 140 // Filter allServiceSettings to include only services with serviceConsent = true 141 // Update cookie 142 const relevantServices = allServiceSettings.filter(relevant => relevant.serviceConsent); 143 updateCookieWithFinalConsent(storageName, cookieExpiresAfterDays, relevantServices); 144 145 // C) dataLayer-Push based on the state 146 window.dataLayer = window.dataLayer || []; 147 window.dataLayer.push({ 148 event: service.gtm.trigger, 149 [service.gtm.variable]: state 150 }); 151 } 152 153 // D) Check if the own callback function is allready defined 154 if (service.ownCallback) { 155 if (typeof window[service.ownCallback] === 'function') { 156 window[service.ownCallback](state, service); 157 } else { 158 console.error('The Callback function ' + service.ownCallback + ' is not yet defined. Please create it first.'); 159 } 160 } 161 }; 162 163 // constructor (modal and safari) 164 (function contruct() { 165 document.addEventListener('DOMContentLoaded', function () { 166 // Listener for the button on the privacy page, to edit the consent 167 document.addEventListener('click', function (event) { 168 if (event.target.closest('.js-showConsentModal')) { 169 event.preventDefault(); 170 klaro.show(); 171 } 172 }); 173 }); 174 })(); 175 176 const isSafari = navigator.vendor && 177 navigator.vendor.indexOf('Apple') > -1 && 178 navigator.userAgent && 179 navigator.userAgent.indexOf('CriOS') == -1 && 180 navigator.userAgent.indexOf('FxiOS') == -1; 181 182 document.addEventListener('DOMContentLoaded', function() { 183 setTimeout(function() { 184 185 setServiceSuccessVarBtn(); 186 187 document.addEventListener('click', function (event) { 188 if (event.target.matches('.cn-decline')) { 189 setServiceSuccessVarBtn(); 190 } 191 }); 192 193 document.addEventListener('click', function (event) {
194 if (event.target.matches('.cm-btn-accept')) { 195 setServiceSuccessVarBtn(); 196 } 197 }); 198 199 document.addEventListener('click', function (event) { 200 if (event.target.matches('.cm-btn-decline')) { 201 setServiceSuccessVarBtn(); 202 } 203 }); 204 205 if (isSafari!==true) { 206 document.getElementById('klaro').classList.remove('safari'); 207 } else { 208 document.getElementById('klaro').classList.add('safari'); 209 } 210 }) 211 }); 212}; 213// End main controller 214 215var optOutLink = document.getElementById("ga-opt-out"); 216 217if(optOutLink) { 218 optOutLink.onclick = function() { 219 document.cookie = 'ga-opt-out=true; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/'; 220 this.innerHTML = "Google Analytics opt-out successful"; 221 return false; 222 } 223} 224 225// Functions after window.load(): 226window.addEventListener('load', function () { 227 const iframes = document.querySelectorAll('iframe'); 228 229 if (iframes.length > 0) { 230 iframes.forEach(function (iframe) { 231 let attrDataSrc = iframe.getAttribute('src'); 232 if (!attrDataSrc) { 233 attrDataSrc = iframe.getAttribute('data-src'); 234 } 235 236 if (attrDataSrc && (attrDataSrc.includes('youtube') || attrDataSrc.includes('vimeo'))) { 237 // Adjust measures for videoOverlay similar to iframe: 238 const parent = iframe.parentElement; 239 const contextNotice = parent.querySelector('.klaro.cm-as-context-notice'); 240 241 if (contextNotice) { 242 iframe.style.display = 'block'; 243 244 // Set the width of .klaro.cm-as-context-notice to the iframe's width 245 contextNotice.style.width = iframe.offsetWidth + 'px'; 246 247 if (iframe.offsetHeight < contextNotice.offsetHeight) { 248 const cmButtons = contextNotice.querySelector('.cm-buttons'); 249 if (cmButtons) { 250 cmButtons.style.marginTop = '1em'; 251 } 252 } 253 } 254 } 255 }); 256 } 257 258 // Add class for small context-notice box: if video integration within small iframes (width < 300px) 259 document.querySelectorAll('.klaro.we_cookie_consent.cm-as-context-notice').forEach(function(element) { 260 if (element.offsetWidth <= 300) { 261 element.classList.add('notice--minified'); 262 } 263 }); 264 265 // Add class to avoid Google to crawl consent info text 266 document.querySelectorAll('.klaro.we_cookie_consent .cn-body').forEach(function(element) { 267 element.setAttribute('data-nosnippet', 'data-nosnippet'); 268 }); 269}); 270 271// Workaround: Show "Always" Button for overlay (for example youtube videos) only when the klaro cookie is set 272function setServiceSuccessVarBtn() 273{ 274 const klaroCookie = getCookie('klaro'); 275 276 if (klaroCookie) { 277 const allServiceSuccessVarBtn = document.querySelectorAll('.cm-btn-success-var'); 278 if (allServiceSuccessVarBtn.length > 0) {
279 allServiceSuccessVarBtn.forEach((serviceSuccessVarBtn) => { 280 serviceSuccessVarBtn.style.setProperty('display', 'block', 'important'); 281 } 282 ) 283 } 284 } 285}
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.