PageSourceSearch

https://www.tvsuedostschweiz.ch/wp-content/plugins/sotv-mediathek/assets/js/consent.js?ver=1782679179

js tvsuedostschweiz.ch collected 2026-10-06 18:48:31 UTC 4,701 bytes, 153 lines download raw bytes

1(function () {
2  'use strict';
3
4  const STORAGE_KEY = 'sotvConsent';
5  const COOKIE_KEY = 'sotvConsent';
6  const BANNER_ID = 'sotv-consent-banner';
7  const COOKIE_MAX_AGE = 60 * 60 * 24 * 365; // 1 Jahr
8
9  const activateDeferredResources = () => {
10    const scriptNodes = document.querySelectorAll('script[type="text/plain"][data-consent]');
11    scriptNodes.forEach((node) => {
12      const replacement = document.createElement('script');
13      Array.from(node.attributes).forEach((attr) => {
14        if (attr.name === 'type' || attr.name === 'data-consent') {
15          return;
16        }
17        replacement.setAttribute(attr.name, attr.value);
18      });
19      replacement.textContent = node.textContent || '';
20      node.replaceWith(replacement);
21    });
22
23    const lazyFrames = document.querySelectorAll('[data-consent-src]');
24    lazyFrames.forEach((el) => {
25      if (el.dataset.consentLoaded === '1') {
26        return;
27      }
28      const src = el.getAttribute('data-consent-src');
29      if (!src) {
30        return;
31      }
32      el.setAttribute('src', src);
33      el.dataset.consentLoaded = '1';
34    });
35  };
36
37  document.addEventListener('DOMContentLoaded', () => {
38    const banner = document.getElementById(BANNER_ID);
39    const reopen = document.querySelector('[data-consent-open]');
40    const docEl = document.documentElement;
41    const version = banner?.dataset?.consentVersion || '1';
42
43    const syncNavColors = () => {
44      const nav = document.querySelector('header nav, .navbar, .site-header, header');
45      if (!nav || !docEl) return;
46      const styles = window.getComputedStyle(nav);
47      const bg = styles.backgroundColor || '';
48      const text = styles.color || '';
49      if (bg) docEl.style.setProperty('--sotv-nav-bg', bg);
50      if (text) docEl.style.setProperty('--sotv-nav-text', text);
51    };
52
53    const readCookie = () => {
54      try {
55        const match = document.cookie.match(new RegExp(`(?:^|; )${COOKIE_KEY}=([^;]+)`));
56        if (!match || !match[1]) return null;
57        const parsed = JSON.parse(decodeURIComponent(match[1]));
58        return parsed && parsed.version === version ? parsed : null;
59      } catch (err) {
60        return null;
61      }
62    };
63
64    const writeCookie = (entry) => {
65      try {
66        const payload = encodeURIComponent(JSON.stringify(entry));
67        document.cookie = `${COOKIE_KEY}=${payload};path=/;max-age=${COOKIE_MAX_AGE};SameSite=Lax`;
68      } catch (err) {
69        // Ignore cookie errors
70      }
71    };
72
73    const readStored = () => {
74      try {
75        const raw = localStorage.getItem(STORAGE_KEY);
76        if (!raw) {
77          return readCookie();
78        }
79        const parsed = JSON.parse(raw);
80        if (!parsed || parsed.version !== version) {
81          return readCookie();
82        }
83        return parsed;
84      } catch (err) {
85        return readCookie();
86      }
87    };
88
89    const setPreference = (state, hideAfter = true) => {
90      const entry = { state, version, ts: Date.now() };
91      try {
92        localStorage.setItem(STORAGE_KEY, JSON.stringify(entry));
93      } catch (err) {
94        // Ignore storage errors (e.g. private mode)
95      }
96      writeCookie(entry);
97      if (docEl) {
98        docEl.setAttribute('data-sotv-consent', state);
99      }
100      window.dispatchEvent(new CustomEvent('sotvConsentChanged', { detail: entry }));
101      if (state === 'granted') {
102        activateDeferredResources();
103      }
104      if (hideAfter) {
105        hideBanner();
106      }
107      return entry;
108    };
109
110    const hideBanner = () => {
111      banner?.classList.remove('is-visible');
112    };
113
114    const showBanner = () => {
115      banner?.classList.add('is-visible');
116    };
117
118    if (!banner) {
119      return;
120    }
121
122    const acceptBtn = banner.querySelector('[data-consent-accept]');
123    const declineBtn = banner.querySelector('[data-consent-decline]');
124
125    const stored = readStored();
126    if (stored) {
127      if (docEl) {
128        docEl.setAttribute('data-sotv-consent', stored.state);
129      }
130      if (stored.state === 'granted') {
131        activateDeferredResources();
132      }
133      // Broadcast stored state so other scripts (z.B. SPA) can react on initial load.
134      window.dispatchEvent(new CustomEvent('sotvConsentChanged', { detail: stored }));
135      hideBanner();
136    } else {
137      showBanner();
138    }
139
140    syncNavColors();
141
142    acceptBtn?.addEventListener('click', () => setPreference('granted'));
143    declineBtn?.addEventListener('click', () => setPreference('denied'));
144    reopen?.addEventListener('click', () => showBanner());
145
146    window.sotvConsent = {
147      get: readStored,
148      set: setPreference,
149      activateDeferred: activateDeferredResources,
150      open: showBanner,
151    };
152  });
153})();

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.