PageSourceSearch

https://www.stoertebeker-brauquartier.com/typo3temp/assets/compres…a040f57e44b9bb4a9fc68b15e6b03.js?1776953602

js stoertebeker-brauquartier.com collected 2026-10-05 02:17:35 UTC 15,550 bytes, 453 lines download raw bytes

1
2console.log("TYPO3 LOVE 🍺");
3document.addEventListener("DOMContentLoaded", function () {
4
5  /**
6   * 
7   * Accordion Header 
8   */
9  
10  function createAccordion(id,header,content,on=false) {
11    if (!header || !content) return;
12    // Bootstrap-Klassen setzen
13    content.classList.add("collapse");
14    if(on) {
15      content.classList.add("show");
16    }else{
17      header.classList.add("collapsed");
18    }
19    content.id = "collapse-" + id;
20
21    // Toggle-Attribute für Bootstrap hinzufügen
22    header.setAttribute("data-bs-toggle", "collapse");
23    header.setAttribute("data-bs-target", "#collapse-" + id);
24    header.style.cursor = "pointer"; // Optional für UX
25  }
26
27  document.querySelectorAll(
28    ".frame-type-menu_card_list.frame-layout-accordion, .frame-type-menu_card_list.frame-layout-accordion-on"
29  ).forEach((item) => {
30    const id = item.id;
31    const header = item.querySelector(".frame-header");
32    const content = item.querySelector(".card-carousel");
33
34    const isOpen = item.classList.contains("frame-layout-accordion-on");
35    createAccordion(id, header, content, isOpen);
36  });
37
38  document.querySelectorAll(
39    ".frame-type-card_group.frame-layout-accordion, .frame-type-card_group.frame-layout-accordion-on"
40  ).forEach((item) => {
41    const id = item.id;
42    const header = item.querySelector(".frame-header");
43    const content = item.querySelector(".card-group-element");
44
45    const isOpen = item.classList.contains("frame-layout-accordion-on");
46    createAccordion(id, header, content, isOpen);
47  });
48
49 
50
51
52
53});
54
55
56// Consent class
57const serviceConfigs = JSON.parse(JSON.stringify(allServiceSettings));
58
59// Function to retrieve a cookie by its name
60function getCookie(name) {
61	var nameEQ = name + "=";
62	var ca = document.cookie.split(';');
63	for (var i = 0; i < ca.length; i++) {
64		var c = ca[i];
65		while (c.charAt(0) == ' ') c = c.substring(1);
66		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
67	}
68	return null;
69}
70
71// Function to set a cookie with a specified name, value, and expiration date
72function setCookie(name, value, daysToExpire) {
73	var expires = "";
74	if (daysToExpire) {
75		var date = new Date();
76		date.setTime(date.getTime() + (daysToExpire * 24 * 60 * 60 * 1000));
77		expires = "; expires=" + date.toUTCString();
78	}
79	document.cookie = name + "=" + (value || "") + expires + "; path=/";
80}
81
82// Function to evaluate the final consent value based on service settings
83function evaluateFinalValue(serviceSettings, settingKey) {
84	let hasGranted = false;
85	let hasDenied = false;
86	
87	// Iterate through all services and check their consent settings
88	serviceSettings.forEach(settings => {
89		if (settings[settingKey] === 'granted')
90		if (settings[settingKey] === 'granted') hasGranted = true;
91		else if (settings[settingKey] === 'denied') hasDenied = true;
92	});
93	
94	// If there is at least one "denied" value, return "denied"
95	if (hasDenied)  return 'denied';
96	
97	// If there is only one "granted" value, return "granted"
98	if (hasGranted) return 'granted';
99	
100	// If all values are "not set" or there are no explicit "granted"/"denied" values, return "denied"
101	return 'denied';
102}
103
104// Function to update the cookie with the final consent values
105function updateCookieWithFinalConsent(name, daysToExpire, services) {
106	const cookieValue = getCookie(name);
107	if (cookieValue !== null) {
108		const obj = JSON.parse(decodeURIComponent(cookieValue));
109    
110		// Evaluate and set the final values for each consent setting
111		['ad_storage','analytics_storage','ad_user_data','ad_personalization',
112		 'personalization_storage','functionality_storage','security_storage']
113		  .forEach(key => {
114			obj[key] = evaluateFinalValue(services, key);
115		  });
116		
117		setCookie(name, encodeURIComponent(JSON.stringify(obj)), daysToExpire);
118		pushTriggerAfterConsentChanged(obj);
119	} else {
120		console.log("Cookie name '" + name + "' does not exist.");
121	}
122}
123
124// Function to push the trigger for gtm after consent changed
125function pushTriggerAfterConsentChanged(changes) {
126	window.dataLayer = window.dataLayer || [];
127	window.dataLayer.push({
128		event: 'cmp_we_cookie_consent_changed',   // Custom-Event-Name
129		we_consent_state: {                       // Add all final states 
130			ad_storage             : changes.ad_storage,
131			analytics_storage      : changes.analytics_storage,
132			ad_user_data           : changes.ad_user_data,
133			ad_personalization     : changes.ad_personalization,
134			personalization_storage: changes.personalization_storage,
135			functionality_storage  : changes.functionality_storage,
136			security_storage       : changes.security_storage
137		}
138	});
139}
140
141// Debug function to log all stored service settings
142function getAllServiceSettings() {
143	// Log all service settings to the console
144	console.log(allServiceSettings);
145	// Optionally return allServiceSettings;
146	// return allServiceSettings;
147}
148
149// main controller
150let ConsentApp = new function ConsentController() {
151	// public functions
152	/**
153     * Callback function for GoogleTagManager Script to handle consent state changes and fire the dataLayer trigger
154     * @param bool state
155     * @param object service
156     */
157    this.consentChanged = function(state, service) {
158		// Check if the service is related to Google Tag Manager
159		const isGTM = service.name.indexOf('google-tagmanager-service') !== -1;
160		if (isGTM) {
161			// A) Remap all services - only the service that has just been changed receives either its config values (if state=true) or "denied" all-over.
162			allServiceSettings = allServiceSettings.map(tempSettings => {
163				if (tempSettings.serviceId !== service.name) {
164					// Unmodified copy
165					return { 
166						serviceId:               tempSettings.serviceId,
167						serviceConsent:          tempSettings.serviceConsent,
168						ad_storage:              tempSettings.ad_storage,
169						analytics_storage:       tempSettings.analytics_storage,
170						ad_user_data:            tempSettings.ad_user_data,
171						ad_personalization:      tempSettings.ad_personalization,
172						functionality_storage:   tempSettings.functionality_storage,
173						personalization_storage: tempSettings.personalization_storage,
174						security_storage:        tempSettings.security_storage
175					};
176				}
177				
178				// Get the original config
179				const originalConfig = serviceConfigs.find(original => original.serviceId === tempSettings.serviceId);
180				const updated = { serviceId: tempSettings.serviceId, serviceConsent: state };
181				
182				// For every consent type
183				['ad_storage','analytics_storage','ad_user_data','ad_personalization',
184			     'personalization_storage','functionality_storage','security_storage']
185				  .forEach(key => {
186					// if consent is granted: accept from config
187					// if consent is denied: always 'denied'
188					updated[key] = state ? originalConfig[key] : 'denied';
189				});
190
191				return updated;
192			});
193			
194			// B) Evaluate only the granted services
195			// Filter allServiceSettings to include only services with serviceConsent = true
196			// Update cookie
197			const relevantServices = allServiceSettings.filter(relevant => relevant.serviceConsent);
198			updateCookieWithFinalConsent(storageName, cookieExpiresAfterDays, relevantServices);
199			
200			// C) dataLayer-Push based on the state
201			window.dataLayer = window.dataLayer || [];
202			window.dataLayer.push({
203				event: service.gtm.trigger,
204				[service.gtm.variable]: state
205			});
206		}
207				
208		// D) Check if the own callback function is allready defined
209		if (service.ownCallback) {
210			if (typeof window[service.ownCallback] === 'function') {
211				window[service.ownCallback](state, service);
212            } else {
213				console.error('The Callback function ' + service.ownCallback + ' is not yet defined. Please create it first.');
214            }
215        }
216	};
217
218    // constructor (modal and safari)
219	(function contruct() {
220		document.addEventListener('DOMContentLoaded', function () {
221			// Listener for the button on the privacy page, to edit the consent
222			document.addEventListener('click', function (event) {
223				if (event.target.closest('.js-showConsentModal')) {
224					event.preventDefault();
225					klaro.show();
226				}
227			});
228		});
229	})();
230
231    const isSafari = navigator.vendor && 
232        navigator.vendor.indexOf('Apple') > -1 &&
233        navigator.userAgent &&
234        navigator.userAgent.indexOf('CriOS') == -1 &&
235        navigator.userAgent.indexOf('FxiOS') == -1;
236
237	document.addEventListener('DOMContentLoaded', function() {
238		setTimeout(function() {
239
240			setServiceSuccessVarBtn();
241
242			document.addEventListener('click', function (event) {
243				if (event.target.matches('.cn-decline')) {
244					setServiceSuccessVarBtn();
245				}
246			});
247
248			document.addEventListener('click', function (event) {
249				if (event.target.matches('.cm-btn-accept')) {
250					setServiceSuccessVarBtn();
251				}
252			});
253
254			document.addEventListener('click', function (event) {
255				if (event.target.matches('.cm-btn-decline')) {
256					setServiceSuccessVarBtn();
257				}
258			});
259
260			if (isSafari!==true) {
261				document.getElementById('klaro').classList.remove('safari');
262			} else {
263				document.getElementById('klaro').classList.add('safari');
264			}
265		})
266    });
267};
268// End main controller
269
270var optOutLink = document.getElementById("ga-opt-out");
271
272if(optOutLink) {
273	optOutLink.onclick = function() {
274		document.cookie = 'ga-opt-out=true; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/';
275		this.innerHTML = "Google Analytics opt-out successful";
276		return false;
277	}
278}
279
280// Functions after window.load():
281window.addEventListener('load', function () {
282	const iframes = document.querySelectorAll('iframe');
283
284	if (iframes.length > 0) {
285		iframes.forEach(function (iframe) {
286			let attrDataSrc = iframe.getAttribute('src');
287			if (!attrDataSrc) {
288				attrDataSrc = iframe.getAttribute('data-src');
289			}
290
291			if (attrDataSrc && (attrDataSrc.includes('youtube') || attrDataSrc.includes('vimeo'))) {
292				// Adjust measures for videoOverlay similar to iframe:
293				const parent = iframe.parentElement;
294				const contextNotice = parent.querySelector('.klaro.cm-as-context-notice');
295
296				if (contextNotice) {
297					iframe.style.display = 'block';
298
299					// Set the width of .klaro.cm-as-context-notice to the iframe's width
300					contextNotice.style.width = iframe.offsetWidth + 'px';
301
302					if (iframe.offsetHeight < contextNotice.offsetHeight) {
303						const cmButtons = contextNotice.querySelector('.cm-buttons');
304						if (cmButtons) {
305							cmButtons.style.marginTop = '1em';
306						}
307					}
308				}
309			}
310		});
311	}
312
313	// Add class for small context-notice box: if video integration within small iframes (width < 300px)
314	document.querySelectorAll('.klaro.we_cookie_consent.cm-as-context-notice').forEach(function(element) {
315		if (element.offsetWidth <= 300) {
316			element.classList.add('notice--minified');
317		}
318	});
319
320	// Add class to avoid Google to crawl consent info text
321	document.querySelectorAll('.klaro.we_cookie_consent .cn-body').forEach(function(element) {
322		element.setAttribute('data-nosnippet', 'data-nosnippet');
323	});
324});
325
326// Workaround: Show "Always" Button for overlay (for example youtube videos) only when the klaro cookie is set
327function setServiceSuccessVarBtn()
328{
329	const klaroCookie = getCookie('klaro');
330
331	if (klaroCookie) {
332		const allServiceSuccessVarBtn = document.querySelectorAll('.cm-btn-success-var');
333		if (allServiceSuccessVarBtn.length > 0) {
334			allServiceSuccessVarBtn.forEach((serviceSuccessVarBtn) => {
335					serviceSuccessVarBtn.style.setProperty('display', 'block', 'important');
336				}
337			)
338		}
339	}
340}
341
342document.addEventListener('DOMContentLoaded', function () {
343
344    if (checkCookieExists('klaro')) {
345        createTooltip();
346    }
347
348    setTimeout(function () {
349        const klaroDiv = document.getElementById('klaro');
350        const buttons = klaroDiv.querySelectorAll('button');
351
352        function handleClick(event) {
353            createTooltip();
354            if (document.querySelector('#klaro .cookie-notice') == null && document.querySelector('#klaro .cookie-modal') == null) {
355            }
356        }
357
358        buttons.forEach(button => {
359            button.addEventListener('click', handleClick);
360        });
361    });
362
363    setTimeout(function () {
364        if (document.querySelector('.cm-link')) {
365            document.querySelector('.cm-link').addEventListener('click', function () {
366                if (document.querySelector('.cm-btn-success')) {
367                    document.querySelector('.cm-btn-success').addEventListener('click', function () {
368                        createTooltip();
369                    });
370                }
371
372                if (document.querySelector('.cn-decline')) {
373                    document.querySelector('.cn-decline').addEventListener('click', function () {
374                        createTooltip();
375                    });
376                }
377
378                if (document.querySelector('.cm-btn-accept-all')) {
379                    document.querySelector('.cm-btn-accept-all').addEventListener('click', function () {
380                        createTooltip();
381                    });
382                }
383            });
384        }
385    }, 1000);
386});
387
388function checkCookieExists(cookieName) {
389    let cookies = document.cookie.split(';');
390
391    for (let i = 0; i < cookies.length; i++) {
392        let cookie = cookies[i];
393        // Remove leading spaces (if any)
394        while (cookie.charAt(0) == ' ') {
395            cookie = cookie.substring(1);
396        }
397        // Check if the cookie name matches
398        if (cookie.indexOf(cookieName + '=') == 0) {
399            return true;
400        }
401    }
402    return false;
403}
404
405function createTooltip() {
406    if (cookieIconPermanentlyAvailable === '1') {
407        let iconTooltip = document.createElement('div');
408        let iconImgTag = document.createElement('img');
409        let iconBtn = document.createElement('button');
410        let iconContainer = document.createElement('div');
411
412        // Button
413        iconBtn.type = 'button';
414        iconBtn.className = 'consent-trigger js-showConsentModal';
415        iconBtn.setAttribute('aria-label', translatedButtonTextCookieSettings);
416        iconBtn.setAttribute('aria-haspopup', 'dialog');
417
418        // Image
419        iconImgTag.src = cookieSettingsImgPathDefault;
420        iconImgTag.alt = '';
421        iconImgTag.setAttribute('aria-hidden', 'true');
422        iconImgTag.width = 85; iconImgTag.height = 85;
423        iconImgTag.style.cssText = 'margin-right:0px;width:85px;height:85px;';
424
425        // Hover/Fokus (Image & Tooltip)
426        function showTip(){ iconTooltip.style.display = 'block'; iconImgTag.src = cookieSettingsImgPathHover; }
427        function hideTip(){ iconTooltip.style.display = 'none';  iconImgTag.src = cookieSettingsImgPathDefault; }
428
429        iconBtn.addEventListener('mouseover', showTip);
430        iconBtn.addEventListener('mouseout',  hideTip);
431        iconBtn.addEventListener('focusin',   showTip);
432        iconBtn.addEventListener('focusout',  hideTip);
433
434        // Tooltip
435        iconTooltip.textContent = translatedButtonTextCookieSettings;
436        iconTooltip.classList.add('consent-cookie-text');
437        iconTooltip.style.cssText = 'display:none;';
438        // (optional ARIA)
439        // tooltip.id = 'consent-tooltip';
440        // tooltip.setAttribute('role', 'tooltip');
441        // btn.setAttribute('aria-describedby', 'consent-tooltip');
442
443        // Container
444        iconContainer.classList.add('consent-cookie');
445        iconContainer.style.cssText = 'display:flex;';
446
447        // DOM
448        iconBtn.appendChild(iconImgTag);
449        iconContainer.appendChild(iconBtn);
450        iconContainer.appendChild(iconTooltip);
451        document.body.appendChild(iconContainer);
452    }
453}

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.