1// Globale Variablen beibehalten 2let GCMS_MTRACK_DATA = []; 3let GCMS_enableHandler = false; 4let GCMS_enableHandler1 = false; 5let GCMS_MTIME = new Date(); 6let GCMS_ONLINE = true; 7let GCMS_ANI = false; 8let GCMS_FORM = []; 9 10// Funktion zum Senden von POST-Daten (ersetzt $.post) 11async function GCMS_sendPostData(url, data) { 12 const formData = new URLSearchParams(); 13 for (const key in data) { 14 if (Object.prototype.hasOwnProperty.call(data, key)) { 15 if (Array.isArray(data[key]) || (typeof data[key] === 'object' && data[key] !== null && ! (data[key] instanceof File))) { 16 formData.append(key, JSON.stringify(data[key])); 17 } else { 18 formData.append(key, data[key]); 19 } 20 } 21 } 22 23 try { 24 const response = await fetch(url, { 25 method: 'POST', 26 headers: { 27 'Content-Type': 'application/x-www-form-urlencoded', 28 }, 29 body: formData 30 }); 31 if (!response.ok) { 32 console.error('Network response was not ok:', response.statusText); 33 throw new Error(`HTTP error! status: ${response.status}`); 34 } 35 return response.text(); // Oder response.json(), je nachdem was der Server zurückgibt 36 } catch (error) { 37 console.error('Error sending POST data:', error); 38 throw error; // Fehler weiterleiten 39 } 40} 41 42// Prüfen auf mobile Geräte und Cursor setzen 43if (/ip(hone|od)|ipad/i.test(navigator.userAgent)) { 44 document.body.style.cursor = "pointer"; 45} 46 47function GCMS_MTRACK(seid, spid, hash, time, event, typ, zusatz) { 48 var akt = new Date(); 49 var diff = akt.getTime() - GCMS_MTIME.getTime(); 50 var data = typ + ',' + diff + ','; 51 var send = false; 52 GCMS_MTIME = akt; 53 if (typ == "cl") { 54 data += window.innerWidth + ',' + event.pageX + ',' + event.pageY + ',' + zusatz; 55 send = true; 56 } else if (typ == "mo") { 57 data += event.pageX + ',' + event.pageY + ',' + window.scrollY + ',' + window.scrollX; 58 } else if (typ == "rc") { 59 data += event.pageX + ',' + event.pageY; 60 } else if (typ == "sc") { 61 data += window.scrollY + ',' + window.scrollX; 62 } else if (typ == "re") { 63 data += window.innerWidth + ',' + window.innerHeight; 64 } else if (typ == "ke") { 65 // Event data is not explicitly added here in the original, so keeping it consistent 66 } 67 GCMS_MTRACK_DATA.push(data); 68 if(GCMS_ONLINE){ 69 const payload = { data0: seid + "," + spid + "," + hash + "," + time, data1: GCMS_MTRACK_DATA }; 70 const jsonString = JSON.stringify(payload); 71 const byteSize = new TextEncoder().encode(jsonString).length; 72 if(byteSize > 60000){ 73 // sendbeacon limit 64kb 74 GCMS_sendPostData("/index.php?gstat=3", { data0: seid + "," + spid + "," + hash + "," + time, data1: GCMS_MTRACK_DATA }); 75 GCMS_MTRACK_DATA = []; 76 } 77 } 78 return true; 79} 80 81function GCMS_ZIEL(stzid){ 82 const data = { data0: stzid, data1: GCMS_SL }; 83 if (navigator.sendBeacon) { 84 const blob = new Blob([JSON.stringify(data)], { type: "application/json" }); 85 navigator.sendBeacon("/index.php?gstat=4", blob); 86 } else { 87 GCMS_sendPostData("/index.php?gstat=4", data); 88 } 89} 90 91function GCMS_tr(seid, spid, hash, time, heatmap) { 92 window.addEventListener("pagehide", function () { 93 if (GCMS_MTRACK_DATA.length > 0) { 94 try { 95 const data = { data0: seid + "," + spid + "," + hash + "," + time, data1: GCMS_MTRACK_DATA }; 96 const blob = new Blob([JSON.stringify(data)], { type: "application/json" }); 97 if (navigator.sendBeacon) { 98 GCMS_MTRACK_DATA = []; 99 navigator.sendBeacon("/index.php?gstat=3", blob); 100 } 101 } catch (e) { 102 //console.error("Fehler beim Senden der Daten:", e); 103 } 104 } 105 }); 106 107 if(heatmap) GCMS_MTRACK(seid, spid, hash, time, "", "re"); 108 109 // Zielvorhaben 110 if (typeof GCMS_Z_TI !== 'undefined') { 111 GCMS_Z_TI.forEach(function(item, index) { 112 window.setTimeout(function(){ 113 GCMS_ZIEL(index); 114 },item*1000); 115 }); 116 } 117 118 if (typeof GCMS_Z_ELID !== 'undefined') {
119 GCMS_Z_ELID.forEach(function(item, index) { 120 CustomAppear.init('#' + item, { force_process: true }); 121 document.body.addEventListener('appear', function(e) { 122 const target = e.detail.element; 123 if (target.matches('#' + item)) { 124 if (!GCMS_Z_ELID1[index]) { 125 GCMS_Z_ELID1[index] = true; 126 GCMS_ZIEL(index); 127 } 128 } 129 }); 130 }); 131 } 132 133 if (typeof GCMS_Z_ELKLA !== 'undefined') { 134 GCMS_Z_ELKLA.forEach(function(item, index) { 135 let checkkla = item.split(" "); 136 let itemkla = ''; 137 checkkla.forEach(function(item1) { 138 item1 = item1.trim(); 139 if(item1 !== " ") itemkla += "." + item1; 140 }); 141 CustomAppear.init(itemkla, { force_process: true }); 142 document.body.addEventListener('appear', function(e) { 143 const target = e.detail.element; 144 if (target.matches(itemkla)) { 145 if (!GCMS_Z_ELKLA1[index]) { 146 GCMS_Z_ELKLA1[index] = true; 147 GCMS_ZIEL(index); 148 } 149 } 150 }); 151 }); 152 } 153 154 if(heatmap){ 155 document.body.addEventListener("mousemove", function(event) { 156 if (GCMS_enableHandler) { 157 GCMS_MTRACK(seid, spid, hash, time, event, "mo"); 158 GCMS_enableHandler = false; 159 } 160 }); 161 document.body.addEventListener("contextmenu", function(event) { 162 GCMS_MTRACK(seid, spid, hash, time, event, "rc"); 163 }); 164 } 165 166 document.addEventListener('click', function (event) { 167 const target = event.target; 168 // Funktion zur Erzeugung des DOM-Pfads 169 function GCMS_getDomPath(el) { 170 const path = []; 171 while (el && el.nodeType === Node.ELEMENT_NODE) { 172 let selector = el.tagName.toLowerCase(); 173 if (el.id) { 174 selector += `#${el.id}`; 175 } 176 if (el.className && typeof el.className === 'string') { 177 const classNames = el.className.trim().split(/\s+/).filter(Boolean); 178 if (classNames.length > 0) { 179 selector += '.' + classNames.join('.'); 180 } 181 } 182 path.unshift(selector); 183 el = el.parentElement; 184 } 185 return path.join(' '); 186 } 187 let el_id = target.id || null; 188 let el_class = target.className || null; 189 let el_href = target.tagName === 'A' ? target.href : null; 190 const onclickAttr = target?.getAttribute('onclick'); 191 let el_onclickhref = null; 192 if (onclickAttr && onclickAttr.includes('location.href')) { 193 const match = onclickAttr.match(/location\.href\s*=\s*'([^']+)'/); 194 if (match && match[1]) { 195 el_onclickhref = match[1]; 196 try { 197 const absoluteUrl = new URL(el_onclickhref, window.location.href); 198 el_onclickhref = absoluteUrl.href; 199 } catch (e) { 200 // console.error("Invalid URL in onclick attribute:", e); 201 } 202 } 203 } 204 // Zielvorhaben 205 if(el_id && typeof GCMS_Z_KLID !== 'undefined') { 206 GCMS_Z_KLID.forEach(function(item, index) { 207 if(el_id === item) GCMS_ZIEL(index); 208 }); 209 } 210 if(el_class && typeof GCMS_Z_KLA !== 'undefined') { 211 let splitkla = el_class.split(" "); 212 GCMS_Z_KLA.forEach(function(item, index) { 213 let checkkla = item.split(" "); 214 let foundkla = false; 215 checkkla.forEach(function(item1) { 216 if(splitkla.includes(item1)){ 217 foundkla = true; 218 } 219 }); 220 if(foundkla) GCMS_ZIEL(index); 221 }); 222 } 223 if(el_href && typeof GCMS_Z_KLURL !== 'undefined') { 224 GCMS_Z_KLURL.forEach(function(item, index) { 225 if(el_href === item || el_href === item + "/") GCMS_ZIEL(index); 226 }); 227 } 228 if(el_onclickhref && typeof GCMS_Z_KLURL !== 'undefined') { 229 GCMS_Z_KLURL.forEach(function(item, index) { 230 if(el_onclickhref === item || el_onclickhref === item + "/") GCMS_ZIEL(index); 231 }); 232 } 233 if(heatmap) GCMS_MTRACK(seid, spid, hash, time, event, "cl", GCMS_getDomPath(target)); 234 }); 235 236 window.addEventListener('scroll', function() { 237 if (GCMS_enableHandler) { 238 if(heatmap) GCMS_MTRACK(seid, spid, hash, time, "", "sc"); 239 GCMS_enableHandler = false;
240 // Zielvorhaben 241 if (typeof GCMS_Z_SCR !== 'undefined') { 242 let scrollh = document.body.scrollHeight - window.innerHeight; 243 GCMS_Z_SCR.forEach(function(item, index) { 244 if(!GCMS_Z_SCR1[index]){ 245 let prozw = scrollh * item / 100; 246 if(window.scrollY >= prozw){ 247 GCMS_Z_SCR1[index] = true; 248 GCMS_ZIEL(index); 249 } 250 } 251 }); 252 } 253 } 254 }); 255 256 if(heatmap){ 257 window.addEventListener('resize', function() { 258 if (GCMS_enableHandler) { 259 GCMS_MTRACK(seid, spid, hash, time, "", "re"); 260 GCMS_enableHandler = false; 261 } 262 }); 263 document.querySelectorAll("input[type=text],textarea,input[type=password],input[type=number],input[type=date],input[type=month],input[type=week],input[type=time],input[type=datetime-local],input[type=email],input[type=search],input[type=tel],input[type=url]").forEach(function(element) { 264 element.addEventListener("keyup", function(event) { 265 if (GCMS_enableHandler1) { 266 GCMS_MTRACK(seid, spid, hash, time, event, "ke"); 267 GCMS_enableHandler1 = false; 268 } 269 }); 270 }); 271 } 272 273 GCMS_timer = window.setInterval(function() { 274 GCMS_enableHandler = true; 275 }, 200); 276 GCMS_timer1 = window.setInterval(function() { 277 GCMS_enableHandler1 = true; 278 }, 500); 279} 280 281function gcms_umfrage_next(spid) { 282 $.post("/index.php?spid="+spid+"&UMFRAGERES=1¬ype=1", $("#form_fumfrage").serialize(), function(data) { 283 if (data.substr(0, 5) == "false") $("#gcms_umfrage_load").html(data); 284 else $("#gcms_umfrage_inhalt").html(data); 285 }); 286 return false; 287} 288function gcms_umfrage_prev(spid) { 289 $.post("/index.php?spid="+spid+"&UMFRAGERES=1¬ype=1&page=" + GCMS_umfrage[$("#akt_page").val()], $("#form_fumfrage").serialize(), function(data) { 290 $("#gcms_umfrage_inhalt").html(data); 291 }); 292 return false; 293} 294 295function gcms_nothing() { return; } 296 297let gcmsImageProtectEventListeners = {}; // Object to store event listeners for off/on behavior 298 299function gcms_image_protect() { 300 document.querySelectorAll("img:not(.gcms_image_protect)").forEach(function(th) { 301 if (!th.closest(".GCMS_NOPROTECT")) { 302 th.classList.add("gcms_image_protect"); 303 th.style.webkitTouchCallout = "none"; 304 } 305 }); 306 307 // Remove existing specific event listeners before adding new ones 308 document.querySelectorAll('.gcms_image_protect').forEach(function(img) { 309 if (gcmsImageProtectEventListeners[img]) { 310 for (const eventType in gcmsImageProtectEventListeners[img]) { 311 img.removeEventListener(eventType, gcmsImageProtectEventListeners[img][eventType]); 312 } 313 } 314 gcmsImageProtectEventListeners[img] = {}; // Clear for this image 315 }); 316 317 document.querySelectorAll('.gcms_image_protect').forEach(function(img) { 318 const handler = function(event) { event.preventDefault(); }; 319 img.addEventListener('dragstart', handler); 320 img.addEventListener('contextmenu', handler); 321 img.addEventListener('mousedown', handler); 322 // For taphold, consider a custom implementation or a library if needed, as it's not a native event 323 // For simplicity, omitting taphold for now as it's jQuery Mobile specific. 324 325 // Store for later removal 326 gcmsImageProtectEventListeners[img]['dragstart'] = handler; 327 gcmsImageProtectEventListeners[img]['contextmenu'] = handler; 328 gcmsImageProtectEventListeners[img]['mousedown'] = handler; 329 }); 330 331 // Delegated contextmenu and click events for .copy-context 332 // Removed existing listener based on namespace if it exists (simple approach) 333 document.removeEventListener("contextmenu", GCMS_handleCopyContextContextMenu); 334 document.removeEventListener("click", GCMS_handleCopyContextClick); 335 336 // Add new listeners 337 document.addEventListener("contextmenu", GCMS_handleCopyContextContextMenu); 338 document.addEventListener("click", GCMS_handleCopyContextClick); 339} 340 341function GCMS_handleCopyContextContextMenu(event) { 342 const target = event.target; 343 if (target.closest(".copy-context")) { 344 event.preventDefault(); 345 event.stopImmediatePropagation(); 346 const th = target.closest(".copy-context"); 347 const copyright = th.dataset.copyright; // Replaced .data("copyright") 348 document.querySelectorAll(".gcms_copyright-tooltip").forEach(el => el.remove()); 349 if (copyright !== undefined && copyright !== "") { 350 // Assume GCMS_BS is a global boolean 351 if(!window.GCMS_BS) event.preventDefault(); 352 const tooltip = document.createElement('div'); 353 tooltip.className = 'gcms_copyright-tooltip gcms_copyright-div'; 354 tooltip.style.position = 'absolute'; 355 tooltip.style.left = event.pageX + 'px'; 356 tooltip.style.top = event.pageY + 'px'; 357 tooltip.style.minWidth = '100px'; 358 tooltip.style.textAlign = 'center'; 359 tooltip.innerHTML = '<div class="gcms_copyright-div" style="padding-bottom:2px;font-weight:bold">Copyright</div>' + copyright; 360 document.body.appendChild(tooltip); 361 } 362 } 363} 364 365function GCMS_handleCopyContextClick(e) { 366 if (!e.target.closest(".gcms_copyright-div")) { 367 document.querySelectorAll(".gcms_copyright-tooltip").forEach(el => el.remove()); 368 } else { 369 window.setTimeout(function() { 370 document.querySelectorAll(".gcms_copyright-tooltip").forEach(el => el.remove()); 371 }, 5000); 372 } 373} 374 375async function gcms_save_cookie_extern(spid,ds,co) { 376 const data = { 377 dst: "2", 378 kat1: "true", 379 kat2: "true", 380 kat3: "true", 381 ds: ds, 382 co: co, 383 loc: encodeURIComponent(window.location.href) 384 }; 385 try { 386 await GCMS_sendPostData("/index.php?gcookiesave=1&spid="+spid, data); 387 document.location.reload(); 388 } catch (error) { 389 console.error("Error saving cookie externally:", error); 390 } 391} 392 393/* Cookie v2 (2026-09-23): Button "Cookie-Einstellungen" im Platzhalter
394 (Variante ohne Inline-Schalter). Der Banner-Code (_CMS_show_cookie_ 395 einstellung aus parse/cookie_v2.php) ist nur auf Seiten vorhanden, die 396 den Banner ausliefern - nach einer gespeicherten Entscheidung also 397 nicht mehr. Vorher lief der Klick dort in einen ReferenceError und der 398 Besucher konnte den Inhalt nie freigeben. Fallback: Cookie-Erklaerung 399 (dort liegt der Dialog versteckt bereit), sonst Datenschutzerklaerung. */ 400function GCMS_openCookieSettings(el) { 401 var box = el && el.closest ? el.closest("[data-gcms-requires]") : null; 402 if (typeof window._CMS_show_cookie_einstellung === "function" 403 && (document.getElementById("gcms_cookie_manager") || document.getElementById("gcms_einwilligung_dialog"))) { 404 window._CMS_show_cookie_einstellung(); 405 return false; 406 } 407 var ziel = box ? (parseInt(box.getAttribute("data-gcms-co"), 10) || parseInt(box.getAttribute("data-gcms-ds"), 10) || 0) : 0; 408 if (ziel > 0) window.location.href = "index.php?seid=" + ziel; 409 return false; 410} 411 412/* Cookie v2: Per-Element-Umschalter ohne Reload (an/aus). */ 413function GCMS_gatedTarget(el, gatedId) { 414 if (gatedId && typeof gatedId === "string") { 415 var byId = document.getElementById(gatedId); 416 if (byId) return byId; 417 } 418 if (el && el.closest) { 419 var gated = el.closest("[data-gcms-gated]"); 420 if (gated) return gated; 421 var ph = el.closest(".gcms_cookie_placeholder"); 422 if (ph) return ph; 423 return el.closest("[id^='gcms_gated_']"); 424 } 425 return null; 426} 427 428function GCMS_saveGatedPlaceholderHtml(target) { 429 if (!target || target.getAttribute("data-gcms-placeholder-html")) return; 430 target.setAttribute("data-gcms-placeholder-html", target.innerHTML); 431} 432 433function GCMS_restoreGatedPlaceholder(target) { 434 if (!target) return; 435 var html = target.getAttribute("data-gcms-placeholder-html"); 436 if (!html) return; 437 target.innerHTML = html; 438 target.classList.remove("gcms_cookie_gated_active"); 439 target.removeAttribute("data-gcms-activated"); 440 var cb = target.querySelector(".gcms_extern_toggle input[type='checkbox']"); 441 if (cb) cb.checked = false; 442} 443 444function GCMS_consentFromRequired(required, mergeCurrent) { 445 var cats = (required || "").split(","); 446 var kat1 = cats.indexOf("pref") !== -1; 447 var kat2 = cats.indexOf("stat") !== -1; 448 var kat3 = cats.indexOf("market") !== -1; 449 if (mergeCurrent && typeof window.GCMS_getConsent === "function") { 450 var cur = window.GCMS_getConsent(); 451 if (cur.pref) kat1 = true; 452 if (cur.stat) kat2 = true; 453 if (cur.market) kat3 = true; 454 } 455 return { pref: kat1, stat: kat2, market: kat3 }; 456} 457 458async function gcms_extern_noreload(el, spid, ds, co, required, gatedId) { 459 var target = GCMS_gatedTarget(el, gatedId); 460 if (!el) return; 461 462 if (!el.checked) { 463 await gcms_extern_revoke_noreload(spid, required, target); 464 return; 465 } 466 467 GCMS_saveGatedPlaceholderHtml(target); 468 469 var vorher = typeof window.GCMS_getConsent === "function" 470 ? window.GCMS_getConsent() 471 : { pref: false, stat: false, market: false }; 472 var c = GCMS_consentFromRequired(required, true); 473 var data = { 474 kat1: c.pref ? "true" : "false", 475 kat2: c.stat ? "true" : "false", 476 kat3: c.market ? "true" : "false", 477 ds: ds, 478 co: co, 479 loc: encodeURIComponent(window.location.href) 480 }; 481 /* 2026-09-23: Statistik sofort. Wird ueber die Box erstmals Statistik 482 freigegeben, zaehlt der gcookiesave-Handler in Page_pb.php den 483 AKTUELLEN Seitenaufruf direkt (stat=1 + orseid, gleicher Pfad wie 484 "Alle akzeptieren" im Banner) statt erst ab dem naechsten Klick. 485 seid/ink liefert getCookieGatedContent() als data-Attribute. */ 486 if (c.stat && !vorher.stat && target && target.getAttribute("data-gcms-seid")) { 487 data.stat = "1"; 488 data.orseid = target.getAttribute("data-gcms-seid"); 489 data.ink = target.getAttribute("data-gcms-ink") || "0"; 490 data.refer = document.referrer || ""; 491 data.st_res = screen.width + "x" + screen.height; 492 data.st_col = screen.colorDepth; 493 data.st_je = navigator.javaEnabled && navigator.javaEnabled() ? 1 : 0; 494 } 495 try { 496 await GCMS_sendPostData("/index.php?gcookiesave=1&spid=" + spid, data); 497 document.dispatchEvent(new CustomEvent("gcms:consent:granted", { 498 detail: { pref: c.pref, stat: c.stat, market: c.market, source: "extern" } 499 })); 500 } catch (error) {
501 console.error("Error granting external content:", error); 502 document.location.reload(); 503 } 504} 505 506async function gcms_extern_revoke_noreload(spid, required, target) { 507 var cur = typeof window.GCMS_getConsent === "function" 508 ? window.GCMS_getConsent() 509 : { pref: false, stat: false, market: false }; 510 var cats = (required || "").split(","); 511 var kat1 = cur.pref; 512 var kat2 = cur.stat; 513 var kat3 = cur.market; 514 if (cats.indexOf("pref") !== -1) kat1 = false; 515 if (cats.indexOf("stat") !== -1) kat2 = false; 516 if (cats.indexOf("market") !== -1) kat3 = false; 517 518 var data = { 519 kat1: kat1 ? "true" : "false", 520 kat2: kat2 ? "true" : "false", 521 kat3: kat3 ? "true" : "false", 522 loc: encodeURIComponent(window.location.href) 523 }; 524 /* Server liefert das Video schon ohne Platzhalter-HTML (nur gcms_video_out). 525 Dann erst speichern, danach neu laden. Vorher wurde nur neu geladen, 526 der Cookie blieb an und der Schalter sprang wieder auf ja. */ 527 var restore = target && target.getAttribute("data-gcms-placeholder-html"); 528 try { 529 await GCMS_sendPostData("/index.php?gcookiesave=1&spid=" + spid, data); 530 if (!restore) { 531 document.location.reload(); 532 return; 533 } 534 var iframes = target.querySelectorAll("iframe[src]"); 535 iframes.forEach(function (f) { 536 f.removeAttribute("src"); 537 }); 538 GCMS_restoreGatedPlaceholder(target); 539 document.dispatchEvent(new CustomEvent("gcms:consent:granted", { 540 detail: { pref: kat1, stat: kat2, market: kat3, source: "revoke" } 541 })); 542 } catch (error) { 543 console.error("Error revoking external content:", error); 544 document.location.reload(); 545 } 546} 547 548async function gcms_unset_cookie_extern(spid,ds,co) { 549 const data = { 550 unset: "1", 551 ds: ds, 552 co: co, 553 loc: encodeURIComponent(window.location.href) 554 }; 555 try { 556 await GCMS_sendPostData("/index.php?gcookiesave=1&spid="+spid, data); 557 document.location.reload(); 558 } catch (error) { 559 console.error("Error unsetting cookie externally:", error); 560 } 561} 562 563async function GCMS_checkformuh(formid,fo2id) { 564 if(formid && fo2id) { 565 var formuh = localStorage.getItem("formuh"); 566 var uh = false; 567 if(formuh) { 568 var now = Date.now(); 569 var uhsplit = formuh.split("|"); 570 // 20 Minuten 571 if(now - uhsplit[0] > 20 * 60 * 1000){ 572 localStorage.removeItem("formuh"); 573 }else uh = uhsplit[1]; 574 } 575 if(!uh) { 576 const feUhtmpElement = document.getElementById("fe_uhtmp"+formid); 577 if (feUhtmpElement) { 578 uh = feUhtmpElement.value; // Replaced .val() 579 await GCMS_sendPostData("/index.php", { GFORMID: fo2id, GFORMUH: uh ,GFAKT: "open"}); // Replaced $.post 580 } else { 581 console.warn(`Element #fe_uhtmp${formid} not found.`); 582 } 583 } 584 const feUhElement = document.getElementById("fe_uh"+formid); 585 if (feUhElement) { 586 feUhElement.value = uh; // Replaced .val() 587 } else { 588 console.warn(`Element #fe_uh${formid} not found.`); 589 } 590 localStorage.setItem("formuh",Date.now()+"|"+uh); 591 }else if(formid){ 592 const feUhElement = document.getElementById("fe_uh"+formid); 593 const feUhtmpElement = document.getElementById("fe_uhtmp"+formid); 594 if (feUhElement && feUhtmpElement) { 595 feUhElement.value = feUhtmpElement.value; 596 } else { 597 console.warn(`One or both elements (#fe_uh${formid}, #fe_uhtmp${formid}) not found.`); 598 } 599 } 600} 601 602async function GCMS_checkformfill(fo2id) { 603 if(fo2id) { 604 var formuh = localStorage.getItem("formuh"); 605 var uh = false; 606 if(formuh) { 607 var uhsplit = formuh.split("|"); 608 uh = uhsplit[1]; 609 if(GCMS_FORM.indexOf(fo2id)==-1){ 610 GCMS_FORM.push(fo2id); 611 await GCMS_sendPostData("/index.php", { GFORMID: fo2id, GFORMUH: uh ,GFAKT: "fill"}); // Replaced $.post 612 } 613 } 614 } 615} 616 617async function GCMS_errorform(fo2id) { 618 if(fo2id) { 619 var formuh = localStorage.getItem("formuh"); 620 var uh = false;
621 if(formuh) { 622 var uhsplit = formuh.split("|"); 623 uh = uhsplit[1]; 624 if(GCMS_FORM.indexOf(fo2id)==-1){ 625 GCMS_FORM.push(fo2id); 626 await GCMS_sendPostData("/index.php", { GFORMID: fo2id, GFORMUH: uh ,GFAKT: "error"}); // Replaced $.post 627 } 628 } 629 } 630} 631 632function GCMS_formback(formid){ 633 const feFormbackElement = document.getElementById("fe_formback"+formid); 634 if (feFormbackElement) { 635 feFormbackElement.value = 0; // Replaced .val() 636 } else { 637 console.warn(`Element #fe_formback${formid} not found.`); 638 } 639 const form = document.getElementById("form_"+formid); 640 if (form) { 641 const tmpForm = document.createElement('form'); 642 tmpForm.id = "gcms_tmp_form"; 643 tmpForm.method = "post"; 644 tmpForm.action = form.action; // Replaced .attr("action") 645 tmpForm.style.display = "none"; 646 tmpForm.innerHTML = form.innerHTML; // Replaced .html() 647 document.body.appendChild(tmpForm); // Replaced $("body").append() 648 tmpForm.submit(); // Replaced .submit() 649 } else { 650 console.warn(`Form #form_${formid} not found.`); 651 } 652} 653 654function GCMS_form_reset(fo2id) { 655 var regex = new RegExp("([?;&])reload[^&;]*[;&]?"); 656 var query = window.location.href.split("#")[0].replace(regex, "$1").replace(/&$/, ""); 657 window.location.href = 658 (window.location.href.indexOf("?") < 0 ? "?" : query + (query.slice(-1) != "?" ? "&" : "")) 659 + "reload=" + new Date().getTime() + "#fo"+fo2id; 660} 661 662// GSAP Animation Definitions (from/to states for each animation type) 663const GSAP_ANIMATIONS = { 664 fadeIn: { from: { opacity: 0 }, to: { opacity: 1 } }, 665 fadeInUp: { from: { opacity: 0, y: 50 }, to: { opacity: 1, y: 0 } }, 666 fadeInDown: { from: { opacity: 0, y: -50 }, to: { opacity: 1, y: 0 } }, 667 fadeInLeft: { from: { opacity: 0, x: -60 }, to: { opacity: 1, x: 0 } }, 668 fadeInRight: { from: { opacity: 0, x: 60 }, to: { opacity: 1, x: 0 } }, 669 zoomIn: { from: { opacity: 0, scale: 0.7 }, to: { opacity: 1, scale: 1 } }, 670 zoomInUp: { from: { opacity: 0, scale: 0.7, y: 50 }, to: { opacity: 1, scale: 1, y: 0 } }, 671 zoomInDown: { from: { opacity: 0, scale: 0.7, y: -50 }, to: { opacity: 1, scale: 1, y: 0 } }, 672 slideInUp: { from: { opacity: 0, y: 100 }, to: { opacity: 1, y: 0 } }, 673 slideInDown: { from: { opacity: 0, y: -100 }, to: { opacity: 1, y: 0 } }, 674 slideInLeft: { from: { opacity: 0, x: -100 }, to: { opacity: 1, x: 0 } }, 675 slideInRight: { from: { opacity: 0, x: 100 }, to: { opacity: 1, x: 0 } }, 676 bounceIn: { from: { opacity: 0, scale: 0.3 }, to: { opacity: 1, scale: 1 } }, 677 elsticIn: { from: { opacity: 0, scale: 0.5 }, to: { opacity: 1, scale: 1 } }, 678 elsticInUp: { from: { opacity: 0, scale: 0.5, y: 60 }, to: { opacity: 1, scale: 1, y: 0 } }, 679 blurIn: { from: { opacity: 0, filter: 'blur(20px)' }, to: { opacity: 1, filter: 'blur(0px)' } }, 680 blurInUp: { from: { opacity: 0, filter: 'blur(20px)', y: 40 }, to: { opacity: 1, filter: 'blur(0px)', y: 0 } }, 681 flipInX: { from: { opacity: 0, rotationX: 90, transformPerspective: 600 }, to: { opacity: 1, rotationX: 0 } }, 682}; 683 684function GCMS_easeFromStr(ease) { 685 switch(ease) { 686 case "none": return "none"; 687 case "easeOut": return "power2.out"; 688 case "easeInOut": return "power2.inOut"; 689 case "backOut": return "back.out(1.7)"; 690 case "elastic": return "elastic.out(1, 0.3)"; 691 case "bounceOut": return "bounce.out"; 692 default: return "power2.out"; 693 } 694} 695 696function GCMS_initGSAPAnimations() { 697 if (typeof gsap === 'undefined' || typeof ScrollTrigger === 'undefined') return; 698 gsap.registerPlugin(ScrollTrigger); 699 700 var prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; 701 702 document.querySelectorAll('.GCMS_ANIMATE').forEach(function(el) { 703 var animData = el.dataset.animation; 704 if (!animData) return; 705 706 var parts = animData.split(','); 707 if (!parseInt(parts[0])) return; 708 709 var type = parts[1] || 'fadeIn'; 710 var duration = parseFloat(parts[2]) || 1.0; 711 var delay = parseFloat(parts[3]) || 0; 712 var easing = prefersReducedMotion ? 'none' : GCMS_easeFromStr(parts[4] || 'easeOut'); 713 var scrollStart = parseInt(parts[5]) || 80; 714 var textEnabled = parseInt(parts[6]) || 0; 715 var textType = parts[7] || 'fadeInUp'; 716 var textEach = parseFloat(parts[8]) || 0.15; 717 var textDur = parseFloat(parts[9]) || 0.6; 718 719 if (prefersReducedMotion) { duration = 0.01; textDur = 0.01; } 720 721 var animDef = GSAP_ANIMATIONS[type]; 722 if (!animDef) return; 723 724 var textChildren = textEnabled ? Array.from(el.querySelectorAll('h1,h2,h3,h4,h5,h6,p,li')) : []; 725 var textDef = (textEnabled && textChildren.length > 0) ? (GSAP_ANIMATIONS[textType] || GSAP_ANIMATIONS['fadeInUp']) : null; 726 727 // Set initial hidden state immediately 728 gsap.set(el, animDef.from); 729 if (textDef) gsap.set(textChildren, textDef.from); 730 731 ScrollTrigger.create({ 732 trigger: el, 733 start: 'top ' + scrollStart + '%', 734 once: true, 735 onEnter: function() { 736 var tl = gsap.timeline(); 737 tl.fromTo(el, animDef.from, Object.assign({}, animDef.to, { duration: duration, delay: delay, ease: easing })); 738 if (textDef) { 739 tl.fromTo( 740 textChildren, 741 textDef.from, 742 Object.assign({}, textDef.to, { duration: textDur, ease: easing, stagger: { each: textEach } }), 743 '>-0.2' 744 ); 745 } 746 } 747 }); 748 }); 749} 750 751function GCMS_computeHoverCSS(type, intensity) { 752 intensity = intensity || 1.0; 753 let result = {}; 754 755 switch(type) { 756 case 'lift': 757 result.transform = `translateY(${-8 * intensity}px)`; 758 result.boxShadow = `0 ${Math.round(20 * intensity)}px ${Math.round(40 * intensity)}px rgba(0,0,0,${0.1 + 0.05 * intensity})`; 759 break; 760 case 'scale': 761 result.transform = `scale(${1 + 0.06 * intensity})`; 762 break; 763 case 'glow': 764 result.filter = `brightness(${1 + 0.08 * intensity})`; 765 result.boxShadow = `0 0 ${Math.round(20 * intensity)}px rgba(0,143,213,${0.2 + 0.1 * intensity})`; 766 break; 767 case 'shadow': 768 result.transform = `translateY(${-2 * intensity}px)`; 769 result.boxShadow = `0 ${Math.round(8 * intensity)}px ${Math.round(20 * intensity)}px rgba(0,0,0,${0.08 + 0.04 * intensity})`; 770 break; 771 case 'brighten': 772 result.filter = `brightness(${1 + 0.12 * intensity}) saturate(${1 + 0.2 * intensity})`; 773 break; 774 case 'darken': 775 result.filter = `brightness(${1 - 0.18 * intensity}) contrast(${1 + 0.05 * intensity})`; 776 break; 777 case 'dropShadow': 778 result.filter = `drop-shadow(0 ${Math.round(8 * intensity)}px ${Math.round(20 * intensity)}px rgba(0,0,0,${0.18 + 0.08 * intensity}))`; 779 break; 780 case 'shrink': 781 result.transform = `scale(${1 - 0.05 * intensity})`; 782 break; 783 case 'slideUp': 784 result.transform = `translateY(${-6 * intensity}px)`; 785 break; 786 case 'grayscale': 787 result.filter = `grayscale(${Math.min(1, 0.6 + 0.4 * intensity)}) brightness(${1 + 0.05 * intensity})`; 788 break; 789 case 'float': 790 result.transform = `translateY(${-14 * intensity}px)`; 791 break; 792 case 'squeeze': 793 result.transform = `scaleX(${1 - 0.04 * intensity}) scaleY(${1 + 0.04 * intensity})`; 794 break; 795 case 'pushDown': 796 result.transform = `translateY(${5 * intensity}px) scale(${1 - 0.01 * intensity})`; 797 break; 798 case 'contrast': 799 result.filter = `contrast(${1 + 0.2 * intensity}) brightness(${1 + 0.02 * intensity})`; 800 break; 801 802 } 803 return result; 804} 805 806// Vanilla JS Ersatz für jQuery.appear 807const CustomAppear = (function() { 808 const selectors = []; 809 const priorAppeared = []; // Array of arrays, one for each selector
810 let checkBinded = false; 811 let checkLock = false; // Prevents process() from running concurrently or being scheduled too often 812 const defaults = { 813 interval: 250, 814 force_process: false 815 }; 816 let globalOptions = { ...defaults }; // Stores global options like interval 817 818 function isAppeared(element) { 819 // Check if element is truly visible (not display:none, visibility:hidden, or detached from DOM) 820 if (!element.offsetParent || element.style.display === 'none' || element.style.visibility === 'hidden') { 821 return false; 822 } 823 824 const rect = element.getBoundingClientRect(); 825 const windowHeight = window.innerHeight || document.documentElement.clientHeight; 826 const windowWidth = window.innerWidth || document.documentElement.clientWidth; 827 828 const topOffset = parseFloat(element.dataset.appearTopOffset || 0); 829 const leftOffset = parseFloat(element.dataset.appearLeftOffset || 0); 830 831 // Check vertical visibility 832 const verticallyVisible = (rect.bottom >= 0) && (rect.top - topOffset <= windowHeight); 833 834 // Check horizontal visibility (added for full jQuery.appear parity) 835 const horizontallyVisible = (rect.right >= 0) && (rect.left - leftOffset <= windowWidth); 836 837 return verticallyVisible && horizontallyVisible; 838 } 839 840 function process() { 841 if (checkLock) { 842 // A process is already running or scheduled, so skip this call 843 return; 844 } 845 checkLock = true; // Set lock to prevent new processes from starting immediately 846 847 setTimeout(() => { 848 for (let i = 0; i < selectors.length; i++) { 849 const currentSelector = selectors[i]; 850 const elements = Array.from(document.querySelectorAll(currentSelector)); 851 const appearedElements = elements.filter(isAppeared); 852 853 const prevAppeared = priorAppeared[i] || []; 854 855 // Dispatch 'appear' for newly visible elements 856 appearedElements.forEach(el => { 857 if (!prevAppeared.includes(el)) { 858 el.dispatchEvent(new CustomEvent('appear', { detail: { element: el }, bubbles: true })); 859 } 860 }); 861 862 // Dispatch 'disappear' for elements that are no longer visible or no longer exist 863 prevAppeared.forEach(el => { 864 if (!elements.includes(el) || !appearedElements.includes(el)) { 865 el.dispatchEvent(new CustomEvent('disappear', { detail: { element: el }, bubbles: true })); 866 } 867 }); 868 869 priorAppeared[i] = appearedElements; // Update for next cycle 870 } 871 checkLock = false; // Release lock after all processing is done 872 }, globalOptions.interval); // Use the global interval for the processing delay 873 } 874 875 function addSelector(selector) { 876 // Only add if not already present 877 if (!selectors.includes(selector)) { 878 selectors.push(selector); 879 priorAppeared.push([]); // Initialize tracking array for this selector 880 } 881 } 882 883 function setupEventListeners() { 884 if (!checkBinded) { 885 window.addEventListener('scroll', process); 886 window.addEventListener('resize', process); 887 checkBinded = true; 888 } 889 } 890 891 return { 892 // Public method to register elements for appearance checks 893 init: function(selector, options = {}) { 894 // Merge options, but interval/force_process will act globally if multiple init calls have different values. 895 // This behavior mimics jQuery.appear which used a single interval for all elements. 896 globalOptions = { ...defaults, ...options }; 897 898 setupEventListeners(); 899 addSelector(selector); 900 901 // Force a process immediately if requested, but only if not already locked 902 if (globalOptions.force_process && !checkLock) { 903 process(); 904 } 905 }, 906 // Public method to force an appearance check 907 forceAppear: function() { 908 if (checkBinded) { 909 process(); 910 return true; 911 } 912 return false;
913 } 914 }; 915})(); 916 917document.addEventListener('DOMContentLoaded', function() { 918 919 if(window.GCMS_BS) { // Assuming GCMS_BS is a global boolean 920 gcms_image_protect(); 921 window.setTimeout(function() { 922 gcms_image_protect(); 923 },500); 924 window.addEventListener("resize", function() { 925 gcms_image_protect(); 926 }); 927 // $(document).on("ajaxComplete") is tricky in vanilla JS as there's no native global ajaxComplete event. 928 // You'd need to hook into your own fetch/XHR calls. For now, this part is omitted or needs manual integration. 929 // Placeholder: If you have custom AJAX, call gcms_image_protect() in its success/complete callback. 930 const observer = new MutationObserver(() => gcms_image_protect()); 931 observer.observe(document.body, { childList: true, subtree: true }); 932 933 document.addEventListener("mouseup", function() { 934 window.setTimeout(function() { 935 gcms_image_protect(); 936 },200); 937 window.setTimeout(function() { 938 gcms_image_protect(); 939 },1100); 940 }); 941 } else { 942 // Redundant with gcms_image_protect logic, but kept for consistency if GCMS_BS is false 943 // These listeners are already managed by gcms_image_protect, 944 // which removes and re-adds them. Keeping this block here for 945 // explicit intent, though the effect is the same as the function call. 946 document.removeEventListener("contextmenu", GCMS_handleCopyContextContextMenu); // Ensure cleanup 947 document.removeEventListener("click", GCMS_handleCopyContextClick); // Ensure cleanup 948 949 document.addEventListener("contextmenu", GCMS_handleCopyContextContextMenu); 950 document.addEventListener("click", GCMS_handleCopyContextClick); 951 } 952 953 // alle cookie switch back auf checked bei reload 954 document.querySelectorAll(".gcms_extern_toggle1 .gcms_extern_switch input[type='checkbox']").forEach(function(checkbox) { 955 checkbox.checked = true; // Replaced .prop("checked",true) 956 }); 957 // alle cookie switch auf nicht checked bei reload 958 document.querySelectorAll(".gcms_extern_toggle .gcms_extern_switch input[type='checkbox']").forEach(function(checkbox) { 959 checkbox.checked = false; // Replaced .prop("checked",false) 960 }); 961 962 // Event delegation für GCMS_HOVER (auch nachträglich hinzugefügte Elemente) 963 document.addEventListener('mouseenter', function(e) { 964 if (e.target instanceof Element && e.target.matches('.GCMS_HOVER')) { 965 var hover_data = e.target.dataset.hover.split(","); 966 var css = GCMS_computeHoverCSS(hover_data[1], hover_data[2]); 967 Object.assign(e.target.style, css); 968 } 969 }, true); 970 document.addEventListener('mouseleave', function(e) { 971 if (e.target instanceof Element && e.target.matches('.GCMS_HOVER')) { 972 e.target.style.transform = ""; 973 e.target.style.filter = ""; 974 } 975 }, true); 976 977 // Lottie animations 978 CustomAppear.init('.gcms_lottie', { force_process: true }); 979 document.body.addEventListener('appear', function(e) { 980 const element = e.detail.element; 981 if (element.matches('.gcms_lottie')) { 982 var para = ""; 983 var dataplay = ""; 984 if(element.dataset.play) dataplay = element.dataset.play; // Replaced .data("play") 985 if(dataplay=="autoplay") para += " autoplay"; 986 else if(dataplay=="hover") para += " hover"; 987 else if(dataplay=="view") para += ' class="gcms_lootieview"'; 988 if(element.dataset.loop) para += " loop"; // Replaced .data("loop") 989 if(element.dataset.controls) para += " controls"; // Replaced .data("controls") 990 if(element.dataset.mode) para += ' mode="'+element.dataset.mode+'"'; // Replaced .data("mode") 991 if(element.dataset.direction) para += ' direction="'+element.dataset.direction+'"'; // Replaced .data("direction") 992 if(element.dataset.speed) para += ' speed="'+element.dataset.speed+'"'; // Replaced .data("speed") 993 para += ' src="'+element.dataset.src+'"'; // Replaced .data("src") 994 element.insertAdjacentHTML('afterend', '<lottie-player background="transparent"'+para+'></lottie-player>'); // Replaced .after() 995 element.parentNode.removeChild(element); // Replaced .remove() 996 } 997 }); 998 999 CustomAppear.init('.gcms_lootieview', { force_process: true }); 1000 document.body.addEventListener('appear', function(e) { 1001 const element = e.detail.element; 1002 if (element.matches('.gcms_lootieview')) { 1003 if (element.play) element.play(); // Check if play method exists 1004 } 1005 }); 1006 document.body.addEventListener('disappear', function(e) { 1007 const element = e.detail.element; 1008 if (element.matches('.gcms_lootieview')) { 1009 if (element.pause) element.pause(); // Check if pause method exists 1010 } 1011 }); 1012}); 1013 1014// Original online/offline event listeners (already vanilla JS) 1015if (window.addEventListener) { 1016 window.addEventListener("offline", function() { 1017 GCMS_ONLINE = false;
1018 }, false); 1019 window.addEventListener("online", function() { 1020 GCMS_ONLINE = true; 1021 }, false); 1022} else if (window.attachEvent) { // For older IE versions 1023 window.attachEvent("offline", function() { 1024 GCMS_ONLINE = false; 1025 }); 1026 window.attachEvent("online", function() { 1027 GCMS_ONLINE = true; 1028 }); 1029} 1030 1031/* ============================================================================= 1032 * GCMS Cookie v2 â No-Reload-Aktivierung externer Inhalte 1033 * ----------------------------------------------------------------------------- 1034 * Lauscht auf das DOM-Event `gcms:consent:granted`, das das v2-Banner nach 1035 * erfolgreicher Speicherung dispatcht: 1036 * document.dispatchEvent(new CustomEvent('gcms:consent:granted', { 1037 * detail: { pref: true|false, stat: ..., market: ..., source: 'banner' } 1038 * })); 1039 * 1040 * Aktiviert anschlieÃend alle Inhalte, die für die jeweilige Kategorie gegated 1041 * sind. Drei einfache, kombinierbare Patterns werden unterstützt: 1042 * 1043 * 1) <iframe data-gcms-src="https://..." data-gcms-requires="pref"></iframe> 1044 * â bei Consent wird `src` gesetzt (lazy iframe) 1045 * 1046 * 2) <link rel="stylesheet" data-gcms-href="https://..." data-gcms-requires="pref"> 1047 * â bei Consent wird `href` gesetzt (z. B. Google Fonts) 1048 * 1049 * 3) <div class="gcms_cookie_placeholder" data-gcms-requires="pref"> 1050 * ...Platzhalter-Markup... 1051 * <template data-gcms-requires="pref" data-gcms-target="#id"> 1052 * ...echtes HTML mit iframe/script/... 1053 * </template> 1054 * </div> 1055 * â bei Consent wird der Inhalt des <template> in #id eingefügt. 1056 * 1057 * Ist beim Seitenaufruf bereits Consent vorhanden, wird das Event beim Laden 1058 * der Seite automatisch einmal nachgefeuert (Replay), damit die Aktivierung 1059 * idempotent funktioniert. 1060 * ============================================================================= */ 1061(function () { 1062 function GCMS_currentConsent() { 1063 var raw = ''; 1064 var ca = document.cookie.split(';'); 1065 for (var i = 0; i < ca.length; i++) { 1066 var c = ca[i].trim(); 1067 if (c.indexOf('cms_cookie=') === 0) { raw = decodeURIComponent(c.substring('cms_cookie='.length)); break; } 1068 } 1069 if (!raw || raw === '1') return { pref: false, stat: false, market: false }; 1070 try { 1071 var j = JSON.parse(raw); 1072 return { pref: !!j.pref, stat: !!j.stat, market: !!j.market }; 1073 } catch (e) { return { pref: false, stat: false, market: false }; } 1074 } 1075 1076 function GCMS_categoriesGranted(detail) { 1077 var d = detail || GCMS_currentConsent(); 1078 var granted = []; 1079 if (d.pref) granted.push('pref'); 1080 if (d.stat) granted.push('stat'); 1081 if (d.market) granted.push('market'); 1082 granted.push('req'); // notwendig: immer 1083 return granted; 1084 } 1085 1086 /** Eine Kategorie oder kommagetrennt (z. B. stat,market = beide nötig). */ 1087 function GCMS_requiresMet(req, granted) { 1088 if (!req) return false; 1089 var parts = req.split(','); 1090 if (parts.length > 1) { 1091 for (var i = 0; i < parts.length; i++) { 1092 var r = parts[i].trim(); 1093 if (r && granted.indexOf(r) === -1) return false; 1094 } 1095 return true; 1096 } 1097 return granted.indexOf(req) !== -1; 1098 } 1099 1100 function GCMS_activateGated(granted) { 1101 // 1) Lazy iframes (data-gcms-src) 1102 var iframes = document.querySelectorAll('iframe[data-gcms-src][data-gcms-requires]'); 1103 iframes.forEach(function (el) { 1104 var req = el.getAttribute('data-gcms-requires'); 1105 if (!GCMS_requiresMet(req, granted)) return; 1106 if (el.getAttribute('src')) return; // schon aktiv 1107 el.setAttribute('src', el.getAttribute('data-gcms-src')); 1108 el.removeAttribute('data-gcms-src'); 1109 }); 1110 1111 // 2) Lazy stylesheets (data-gcms-href) 1112 var links = document.querySelectorAll('link[data-gcms-href][data-gcms-requires]'); 1113 links.forEach(function (el) { 1114 var req = el.getAttribute('data-gcms-requires'); 1115 if (!GCMS_requiresMet(req, granted)) return; 1116 if (el.getAttribute('href')) return; 1117 el.setAttribute('href', el.getAttribute('data-gcms-href')); 1118 el.removeAttribute('data-gcms-href'); 1119 }); 1120 1121 // 3) Lazy scripts (data-gcms-src auf <script>) 1122 var scripts = document.querySelectorAll('script[type="text/plain"][data-gcms-src][data-gcms-requires]');
1123 scripts.forEach(function (el) { 1124 var req = el.getAttribute('data-gcms-requires'); 1125 if (!GCMS_requiresMet(req, granted)) return; 1126 var s = document.createElement('script'); 1127 s.src = el.getAttribute('data-gcms-src'); 1128 if (el.async) s.async = true; 1129 if (el.defer) s.defer = true; 1130 el.parentNode.insertBefore(s, el.nextSibling); 1131 el.parentNode.removeChild(el); 1132 }); 1133 1134 // 4) Placeholder + <template>. innerHTML statt cloneNode, danach 1135 // Skripte neu einhaengen: aus <template> geklonte <script> laufen 1136 // sonst nicht (Karten, Social-Embeds blieben leer). 1137 // data-gcms-activated: das Banner aktiviert dieselbe Box schon 1138 // inline, dieser Lauf darf sie nicht ein zweites Mal leeren. 1139 var templates = document.querySelectorAll('template[data-gcms-requires]'); 1140 templates.forEach(function (tmpl) { 1141 var req = tmpl.getAttribute('data-gcms-requires'); 1142 if (!GCMS_requiresMet(req, granted)) return; 1143 var sel = tmpl.getAttribute('data-gcms-target'); 1144 var target = sel ? document.querySelector(sel) : tmpl.parentNode; 1145 if (!target || target.getAttribute('data-gcms-activated') === '1') return; 1146 var html = tmpl.innerHTML; 1147 if (!html || !html.replace(/\s/g, '')) return; 1148 GCMS_saveGatedPlaceholderHtml(target); 1149 target.setAttribute('data-gcms-activated', '1'); 1150 target.innerHTML = html; 1151 target.classList.add('gcms_cookie_gated_active'); 1152 target.querySelectorAll('script').forEach(function (old) { 1153 if (!old.parentNode) return; 1154 var s = document.createElement('script'); 1155 for (var a = 0; a < old.attributes.length; a++) { 1156 s.setAttribute(old.attributes[a].name, old.attributes[a].value); 1157 } 1158 s.text = old.text || old.textContent || ''; 1159 old.parentNode.replaceChild(s, old); 1160 }); 1161 var backCb = target.querySelector('.gcms_extern_toggle1 input[type="checkbox"]'); 1162 if (backCb) backCb.checked = true; 1163 if (typeof window._CMS_unwrap_video_gate === 'function') { 1164 window._CMS_unwrap_video_gate(target); 1165 } else if (target.classList && target.classList.contains('gcms_extern')) { 1166 var video = target.querySelector(':scope > .gcms_video_out'); 1167 if (video && target.parentNode) { 1168 var rest = []; 1169 for (var c = 0; c < target.children.length; c++) { 1170 if (target.children[c] !== video) rest.push(target.children[c]); 1171 } 1172 rest.forEach(function (el) { video.appendChild(el); }); 1173 target.parentNode.replaceChild(video, target); 1174 } 1175 } 1176 }); 1177 /* Alte Video-Box (gcms_save_cookie_extern, ohne template): Schalter 1178 * umlegen und einmal neu laden, wenn Präferenzen + Marketing frei 1179 * sind. Nicht die onclick-Funktion ausführen (die setzt alle 1180 * Kategorien). Flag verhindert eine Reload-Schleife. */ 1181 if (granted.indexOf('pref') !== -1 && granted.indexOf('market') !== -1) { 1182 var legacy = document.querySelectorAll('.gcms_extern_toggle input[type="checkbox"]'); 1183 var offen = []; 1184 legacy.forEach(function (cb) { 1185 var oc = cb.getAttribute('onchange') || ''; 1186 if (oc.indexOf('gcms_save_cookie_extern') === -1 || cb.checked) return; 1187 offen.push(cb); 1188 }); 1189 try { 1190 if (!offen.length) { 1191 sessionStorage.removeItem('gcms_legacy_extern_reload'); 1192 } else if (!window.__gcmsLegacyReload) { 1193 offen.forEach(function (cb) { cb.checked = true; }); 1194 if (sessionStorage.getItem('gcms_legacy_extern_reload') === '1') { 1195 sessionStorage.removeItem('gcms_legacy_extern_reload'); 1196 } else { 1197 window.__gcmsLegacyReload = true; 1198 sessionStorage.setItem('gcms_legacy_extern_reload', '1'); 1199 document.location.reload(); 1200 } 1201 } 1202 } catch (e) { /* still */ } 1203 } 1204 } 1205 1206 function GCMS_onConsentGranted(ev) { 1207 var detail = (ev && ev.detail) ? ev.detail : null; 1208 GCMS_activateGated(GCMS_categoriesGranted(detail)); 1209 } 1210 1211 // Event-Listener 1212 document.addEventListener('gcms:consent:granted', GCMS_onConsentGranted); 1213 1214 // Replay bei vorhandenem Consent (idempotent) 1215 function GCMS_consentReplay() { 1216 var c = GCMS_currentConsent(); 1217 if (c.pref || c.stat || c.market) { 1218 GCMS_activateGated(GCMS_categoriesGranted(c)); 1219 } 1220 } 1221 if (document.readyState === 'loading') { 1222 document.addEventListener('DOMContentLoaded', GCMS_consentReplay); 1223 } else { 1224 GCMS_consentReplay(); 1225 } 1226 1227 // Ãffentlich verfügbar machen (für manuelle Auslöser, Tests) 1228 window.GCMS_activateGatedContent = function (detail) { 1229 GCMS_activateGated(GCMS_categoriesGranted(detail || null)); 1230 }; 1231 window.GCMS_getConsent = GCMS_currentConsent; 1232})();
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.