PageSourceSearch

https://lesachtal.gv.at/typo3temp/assets/compressed/ConsentControl…a372e31534fe702bbef9e7ad63b7a.js?1787664774

js lesachtal.gv.at collected 2026-10-02 20:20:49 UTC 9,878 bytes, 285 lines download raw bytes

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.