PageSourceSearch

https://bestvienna.at/assets/js/cookie-consent.js

js bestvienna.at collected 2026-09-26 04:39:18 UTC 3,926 bytes, 126 lines download raw bytes

1(function () {
2  'use strict';
3
4  var CONSENT_KEY = 'bv-analytics-consent'; // 'granted' | 'denied'
5  var GA_ID = 'G-Q09MJLS86E';
6
7  function getConsent() {
8    try {
9      return localStorage.getItem(CONSENT_KEY);
10    } catch (e) {
11      return null;
12    }
13  }
14
15  function setConsent(value) {
16    try {
17      localStorage.setItem(CONSENT_KEY, value);
18    } catch (e) {
19      /* localStorage unavailable — consent choice won't persist, banner will re-show */
20    }
21  }
22
23  // Google Analytics is only ever requested from here, and only after explicit opt-in.
24  function loadAnalytics() {
25    if (window.__bvAnalyticsLoaded) return;
26    window.__bvAnalyticsLoaded = true;
27
28    window.dataLayer = window.dataLayer || [];
29    window.gtag = function () {
30      window.dataLayer.push(arguments);
31    };
32    window.gtag('js', new Date());
33    window.gtag('config', GA_ID);
34
35    var script = document.createElement('script');
36    script.async = true;
37    script.src = 'https://www.googletagmanager.com/gtag/js?id=' + GA_ID;
38    document.head.appendChild(script);
39  }
40
41  function buildBanner() {
42    var wrap = document.createElement('div');
43    wrap.id = 'cookie-consent-banner';
44    wrap.className = 'cookie-banner';
45    wrap.setAttribute('role', 'dialog');
46    wrap.setAttribute('aria-live', 'polite');
47    wrap.setAttribute('aria-label', 'Cookie consent');
48    wrap.innerHTML =
49      '<div class="cookie-banner-inner">' +
50        '<p class="cookie-banner-text">' +
51          'We\'d like to use Google Analytics to understand how visitors use our site. ' +
52          'It only runs if you click "Accept" — you can change your mind anytime via the ' +
53          '"Cookie Settings" link in the footer. See our ' +
54          '<a href="privacy.html">Privacy Policy</a> for details.' +
55        '</p>' +
56        '<div class="cookie-banner-actions">' +
57          '<button type="button" class="btn btn-outline cookie-btn-reject">Reject</button>' +
58          '<button type="button" class="btn btn-primary cookie-btn-accept">Accept</button>' +
59        '</div>' +
60      '</div>';
61    return wrap;
62  }
63
64  function hideBanner() {
65    var banner = document.getElementById('cookie-consent-banner');
66    if (!banner) return;
67    banner.classList.remove('visible');
68    setTimeout(function () {
69      if (banner.parentNode) banner.parentNode.removeChild(banner);
70    }, 300);
71  }
72
73  function showBanner() {
74    if (document.getElementById('cookie-consent-banner')) return;
75    if (!document.body) {
76      document.addEventListener('DOMContentLoaded', showBanner);
77      return;
78    }
79
80    var banner = buildBanner();
81    document.body.appendChild(banner);
82    requestAnimationFrame(function () {
83      banner.classList.add('visible');
84    });
85
86    banner.querySelector('.cookie-btn-accept').addEventListener('click', function () {
87      setConsent('granted');
88      loadAnalytics();
89      hideBanner();
90    });
91    banner.querySelector('.cookie-btn-reject').addEventListener('click', function () {
92      setConsent('denied');
93      // If analytics was already running (consent withdrawn via "Cookie Settings"),
94      // a reload is the only way to actually stop it — an injected gtag script can't be unloaded.
95      if (window.__bvAnalyticsLoaded) {
96        location.reload();
97      } else {
98        hideBanner();
99      }
100    });
101  }
102
103  function init() {
104    var consent = getConsent();
105    if (consent === 'granted') {
106      loadAnalytics();
107    } else if (consent !== 'denied') {
108      showBanner();
109    }
110  }
111
112  // Lets the footer's "Cookie Settings" link reopen the banner to change consent later.
113  document.addEventListener('click', function (e) {
114    var target = e.target.closest && e.target.closest('#cookie-sett
114ings-link');
115    if (target) {
116      e.preventDefault();
117      showBanner();
118    }
119  });
120
121  if (document.readyState === 'loading') {
122    document.addEventListener('DOMContentLoaded', init);
123  } else {
124    init();
125  }
126})();

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.