PageSourceSearch

https://www.nulaodpadu.sk/sites/all/themes/multipurpose_zymphonies_theme/js/cookie-consent-1.js

js nulaodpadu.sk collected 2026-10-04 21:55:56 UTC 14,373 bytes, 356 lines download raw bytes

1/**
2 * Cookie consent banner - jeden a ten isty subor pre vsetkych 5 domen
3 * (kazda domena ma vlastnu temu, ale kod sa nemusi upravovat - konfiguracia
4 * podla domeny je v SITE_CONFIG nizsie).
5 *
6 * Funguje nezavisle od Drupal 6 / Drupal 7 (ciste JS, ziadne Drupal API).
7 *
8 * VERZIA S GOOGLE CONSENT MODE V2
9 * --------------------------------
10 * Rozdiel oproti povodnej verzii:
11 * - gtag.js sa nacitava HNED pri otvoreni stranky (nie az po suhlase),
12 *   pricom vsetky consent kategorie su defaultne "denied". Google teda
13 *   nezbiera ziadne osobne udaje, kym pouzivatel nesuhlasi, ale zaroven
14 *   vie zaznamenat (anonymizovanu/modelovanu) navstevu.
15 * - Po kliknuti na "Suhlasim" sa iba zavola gtag('consent','update', ...)
16 *   a hned nato sa manualne odosle page_view pre aktualnu stranku.
17 *   Vdaka tomu sa zaznamenaju aj jednorazove navstevy, ktore by pri
18 *   povodnom "nacitat GA az po suhlase" pristupe zostali nezachytene
19 *   (pouzivatel klikne suhlas a hned odide, GA sa nestihne nacitat).
20 * - Ziadny reload stranky nie je potrebny.
21 *
22 * POUZITIE (rovnake pre vsetkych 5 tem):
23 * 1. Skopirujte tento subor bezo zmeny do
24 *      /sites/all/themes/VASA_TEMA/js/cookie-consent.js
25 *    v kazdej z piatich tem.
26 * 2. Pred znacku </body> v page.tpl.php danej temy pridajte:
27 *      <script src="/sites/all/themes/VASA_TEMA/js/cookie-consent.js"></script>
28 * 3. Nic dalsie upravovat netreba - skript sam podla location.hostname
29 *    zisti, ktora domena bezi, a pouzije jej GA kod a odkaz na zasady.
30 *
31 * Ak pribudne novy web alebo sa zmeni GA kod, staci upravit iba SITE_CONFIG
32 * tu na jednom mieste a skopirovat aktualizovany subor do vsetkych tem.
33 */
34(function () {
35  "use strict";
36
37  var COOKIE_NAME = "cookie_consent";
38  var COOKIE_DAYS = 365;
39
40  // --- KONFIGURACIA PODLA DOMENY -----------------------------------------
41  // gaId: GA4 Measurement ID (format G-XXXXXXXXXX)
42  // privacyUrl: odkaz na stranku so zasadami cookies/GDPR pre danu domenu
43  var SITE_CONFIG = {
44    "nulaodpadu.sk":        { gaId: "G-KEPZG2X5RW",  privacyUrl: "https://www.priateliazeme.sk/spz/ochrana-osobnych-udajov" },
45    "stopspalovniam.sk":    { gaId: "G-NT7K41KE27",  privacyUrl: "https://www.priateliazeme.sk/spz/ochrana-osobnych-udajov" },
46    "zerowastecities.sk":   { gaId: "G-GT5ZZWLWG3",  privacyUrl: "https://www.priateliazeme.sk/spz/ochrana-osobnych-udajov" },
47    // pathPrefix: ak je nastavene, banner + tracking sa spusti LEN ak
48    // window.location.pathname zacina tymto retazcom (napr. zvysok domeny
49    // pouziva iny system/tracking - napr. CEPA - a tento skript sa ho
50    // netyka).
51    "priateliazeme.sk":     { gaId: "G-39E2F5KQSB",  pathPrefix: "/spz", privacyUrl: "https://www.priateliazeme.sk/spz/ochrana-osobnych-udajov" },
52    "kompost.sk":           { gaId: "G-ZG5WBDYRTS",  privacyUrl: "https://www.priateliazeme.sk/spz/ochrana-osobnych-udajov" }
53  };
54  // Ak nastavenie pre domenu chyba (napr. neocakavany subdomena tvar),
55  // pouzije sa toto:
56  var DEFAULT_CONFIG = { gaId: null, privacyUrl: "https://www.priateliazeme.sk/spz/ochrana-osobnych-udajov" };
57
58  function getSiteConfig() {
59    var host = window.location.hostname.replace(/^www\./, "").toLowerCase();
60    return SITE_CONFIG[host] || DEFAULT_CONFIG;
61  }
62
63  function getCookie(name) {
64    var match = document.cookie.match(new RegExp("(?:^|; )" + name + "=([^;]*)"));
65    return match ? decodeURIComponent(match[1]) : null;
66  }
67
68  function setCookie(name, value, days) {
69    var expires = new Date();
70    expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000);
71    document.cookie =
72      name + "=" + encodeURIComponent(value) +
73      "; expires=" + expires.toUTCString() +
74      "; path=/; SameSite=Lax";
75  }
76
77  function removeBanner(banner) {
78    if (banner && banner.parentNode) {
79      banner.parentNode.removeChild(banner);
80    }
81  }
82
83  // --- JEDNODUCHY POCITADLO NAVSTEVNOSTI (bez cookies, bez GA) -----------
84  // Zavola sa VZDY, bez ohladu na to, ci pouzivatel suhlasi s analytickymi
85  // cookies alebo nie - kedze nezapisuje ziadne cookie a nezaznamenava
86  // ziadny osobny udaj, nepodlieha cookie suhlasu. Sluzi len na to, aby
87  // ste mali aspon holy pocet navstev za den, aj od tych, ktori GA4
88  // odmietnu. Vyzaduje na serveri subor pageview-counter.php v tom istom
89  // priecinku ako tento skript (viz pageview-counter.php).
90  function getOwnScriptSrc() {
91    // document.currentScript funguje spolahlivo LEN pocas synchronneho
92    // vykonavania skriptu pri prvom nacitani - ak sa tato funkcia zavola
93    // neskor (napr. z DOMContentLoaded listenera), currentScript uz je
94    // null. Preto namiesto "posledneho skriptu na stranke" (nespolahlive,
95    // kedze medzitym mozu pribudnut dalsie <script> tagy) najdeme presne
96    // ten <script>, ktoreho src konci na "cookie-consent.js" - to funguje
97    // vzdy, bez ohladu na timing.
98    if (document.currentScript && document.currentScript.src) {
99      return document.currentScript.src;
100    }
101    var scripts = document.getElementsByTagName("script");
102    for (var i = 0; i < scripts.length; i++) {
103      if (scripts[i].src && /cookie-consent[^\/]*\.js(\?.*)?(#.*)?$/.test(scripts[i].src)) {
104        return scripts[i].src;
105      }
106    }
107    return "";
108  }
109
110  function pingPageviewCounter() {
111    try {
112      var src = getOwnScriptSrc();
113      if (!src) {
114        return;
115      }
116      var counterUrl = src.replace(/[^\/]*$/, "pageview-counter.php");
117      var img = new Image();
118      img.src = counterUrl + (counterUrl.indexOf("?") === -1 ? "?" : "&") + "t=" + Date.now();
119    } catch (e) {
120      // ticho ignorovat - pocitadlo nesmie nijak ovplyvnit fungovanie stranky
121    }
122  }
123
124  // --- GOOGLE CONSENT MODE V2 ---------------------------------------------
125  // gtag.js sa nacitava VZDY, hned pri starte stranky. Pred akymkolvek
126  // suhlasom vsak beziu vsetky ulozne kategorie s hodnotou "denied", takze
127  // sa neuklada ziadne osobne cookie a Google nezbiera identifikovatelne
128  // udaje - iba anonymizovany/modelovany signal.
129  window.dataLayer = window.dataLayer || [];
130  window.gtag = window.gtag || function () {
131    window.dataLayer.push(arguments);
132  };
133
134  function setDefaultConsent() {
135    // Musi byt zavolane PRED nacitanim gtag.js / config, inak Google
136    // defaultne pouziva "granted" a tento krok stráca zmysel.
137    window.gtag("consent", "default", {
138      ad_storage: "denied",
139      ad_user_data: "denied",
140      ad_personalization: "denied",
141      analytics_storage: "denied",
142      wait_for_update: 500
143    });
144  }
145
146  function bootAnalytics(gaId) {
147    if (!gaId || window.__gaBooted) {
148      return;
149    }
150    window.__gaBooted = true;
151
152    setDefaultConsent();
153
154    window.gtag("js", new Date());
155    // send_page_view: false - prvy page_view riadime rucne (viz nizsie),
156    // aby sme mali istotu, ze sa odosle az po nacitani skriptu / po
157    // prip. udeleni suhlasu, a aby sme predisli duplicitnym hitom.
158    window.gtag("config", gaId, { send_page_view: false });
159
160    var s = document.createElement("script");
161    s.async = true;
162    s.src = "https://www.googletagmanager.com/gtag/js?id=" + encodeURIComponent(gaId);
163    s.onload = function () {
164      window.__gaScriptReady = true;
165      // Ak uz medzitym pouzivatel udelil suhlas skor, nez sa skript stihol
166      // nacitat, odosleme page_view az teraz.
167      if (window.__consentGrantedBeforeReady) {
168        sendPageView();
169      } else {
170        // Bez suhlasu Google aj tak posle anonymizovany/cookieless signal
171        // (potrebny pre "consent mode modeling"), takze zavolame page_view
172        // aj tu - realny pouzivatel s cookies sa zaznamena az po suhlase.
173        sendPageView();
174      }
175    };
176    document.head.appendChild(s);
177  }
178
179  function sendPageView() {
180    window.gtag("event", "page_view", {
181      page_title: document.title,
182      page_location: window.location.href,
183      page_path: window.location.pathname
184    });
185  }
186
187  function grantConsent() {
188    window.gtag("consent", "update", {
189      analytics_storage: "granted"
190      // ad_storage / ad_user_data / ad_personalization ostavaju "denied",
191      // kedze web nepouziva reklamny remarketing. Ak by sa to niekedy
192      // zmenilo, pridaj sem aj ich "granted".
193    });
194
195    if (window.__gaScriptReady) {
196      sendPageView();
197    } else {
198      // gtag.js sa este stale stahuje - hned ako dobehne onload vyssie,
199      // page_view sa odosle automaticky.
200      window.__consentGrantedBeforeReady = true;
201    }
202  }
203
204  function injectStyles() {
205    var css = [
206      "#cookie-consent-banner{position:fixed;left:0;right:0;bottom:0;z-index:99999;",
207      "background:#222;color:#fff;padding:14px 18px;font-family:Arial,Helvetica,sans-serif;",
208      "font-size:14px;line-height:1.5;box-shadow:0 -2px 8px rgba(0,0,0,.3);",
209      "padding-bottom:calc(14px + env(safe-area-inset-bottom));}",
210      "#cookie-consent-inner{max-width:1100px;margin:0 auto;display:flex;flex-wrap:wrap;",
211      "align-items:center;gap:14px;justify-content:space-between;}",
212      "#cookie-consent-inner p{margin:0;flex:1 1 320px;}",
213      "#cookie-consent-inner a{color:#9fd88d;text-decoration:underline;}",
214      "#cookie-consent-buttons{display:flex;gap:8px;flex:0 0 auto;}",
215      "#cookie-consent-buttons button{cursor:pointer;border-radius:4px;padding:9px 16px;",
216      "font-size:13px;font-weight:bold;}",
217      "#cookie-consent-accept{background:#4a9c3e;color:#fff;border:1px solid #4a9c3e;}",
218      "#cookie-consent-decline{background:transparent;color:#fff;border:1px solid #fff;}",
219      "@media (max-width:640px){#cookie-consent-inner{flex-direction:column;align-items:stretch;}",
220      "#cookie-consent-buttons{justify-content:stretch;}#cookie-consent-buttons button{flex:1;}}"
221    ].join("");
222    var style = document.createElement("style");
223    style.appendChild(document.createTextNode(css));
224    document.head.appendChild(style);
225  }
226
227  // --- PREKLADY -----------------------------------------------------------
228  // Jazyk sa zisťuje z atribútu <html lang="..."> danej stránky (bežné aj
229  // v mnohojazyčných Drupal weboch). Ak nie je "en", použije sa slovenčina.
230  var TRANSLATIONS = {
231    sk: {
232      ariaLabel: "Súhlas s používaním cookies",
233      accept: "Súhlasím s používaním cookies",
234      decline: "Nesúhlasím s používaním cookies",
235      text:
236        "Na správne fungovanie webovej stránky a analýzu návštevnosti používame súbory cookie. " +
237        "Konkrétne informácie o tom ako cookies používame a taktiež informácie o ochrane osobných " +
238        'údajov (GDPR), nájdete na <a href="{privacyUrl}" target="_blank" rel="noopener">tejto adrese</a>.'
239    },
240    en: {
241      ariaLabel: "Cookie consent",
242      accept: "I agree to the use of cookies",
243      decline: "I do not agree to the use of cookies",
244      text:
245        "To ensure the website functions correctly and to analyze traffic, we use cookies. " +
246        "For details on how we use cookies, as well as information about personal data protection " +
247        '(GDPR), please visit <a href="{privacyUrl}" target="_blank" rel="noopener">this page</a>.'
248    }
249  };
250
251  function getLang() {
252    var path = window.location.pathname.toLowerCase();
253    if (/(^|\/)en(\/|$)/.test(path)) {
254      return "en";
255    }
256    // Fallback pre Drupal weby bez "clean URLs", kde je skutočná cesta
257    // v query stringu (napr. /?q=spz/en/titulka namiesto /spz/en/titulka)
258    var search = window.location.search.toLowerCase();
259    if (/(^|\/|=)en(\/|$|&)/.test(search)) {
260      return "en";
261    }
262    return "sk";
263  }
264
265  function createBanner(privacyUrl, onAccept, onDecline) {
266    var t = TRANSLATIONS[getLang()];
267    var textHtml = t.text.replace("{privacyUrl}", privacyUrl);
268
269    var banner = document.createElement("div");
270    banner.id = "cookie-consent-banner";
271    banner.setAttribute("role", "region");
272    banner.setAttribute("aria-label", t.ariaLabel);
273
274    var inner = document.createElement("div");
275    inner.id = "cookie-consent-inner";
276
277    var text = document.createElement("p");
278    text.innerHTML = textHtml;
279
280    var buttons = document.createElement("div");
281    buttons.id = "cookie-consent-buttons";
282
283    var acceptBtn = document.createElement("button");
284    acceptBtn.type = "button";
285    acceptBtn.id = "cookie-consent-accept";
286    acceptBtn.textContent = t.accept;
287    acceptBtn.addEventListener("click", function () {
288      onAccept();
289      removeBanner(banner);
290    });
291
292    var declineBtn = document.createElement("button");
293    declineBtn.type = "button";
294    declineBtn.id = "cookie-consent-decline";
295    declineBtn.textContent = t.decline;
296    declineBtn.addEventListener("click", function () {
297      onDecline();
298      removeBanner(banner);
299    });
300
301    buttons.appendChild(acceptBtn);
302    buttons.appendChild(declineBtn);
303    inner.appendChild(text);
304    inner.appendChild(buttons);
305    banner.appendChild(inner);
306    document.body.appendChild(banner);
307  }
308
309  function init() {
310    var config = getSiteConfig();
311
312    // Ak ma domena nastaveny pathPrefix, skript (banner aj tracking) sa
313    // ma spustit LEN na strankach, ktorych cesta danym prefixom zacina.
314    // Zvysok domeny (napr. sekcie mimo /spz) tento skript vobec nezasahuje
315    // - typicky preto, ze tam bezi iny system/tracking (napr. CEPA).
316    if (config.pathPrefix && window.location.pathname.indexOf(config.pathPrefix) !== 0) {
317      return;
318    }
319
320    // Holy pocet navstev - vzdy, bez ohladu na cookie suhlas (viz vyssie).
321    pingPageviewCounter();
322
323    // gtag.js sa nacitava VZDY hned na zaciatku, bez ohladu na to, ci uz
324    // suhlas existuje - vdaka Consent Mode v2 defaultom (denied) je to
325    // v poriadku aj z hladiska GDPR.
326    bootAnalytics(config.gaId);
327
328    var consent = getCookie(COOKIE_NAME);
329
330    if (consent === "1") {
331      grantConsent();
332      return; // súhlas už bol daný skôr, banner sa nezobrazuje znova
333    }
334    if (consent === "0") {
335      return; // nesúhlas už bol daný skôr, banner sa nezobrazuje znova
336    }
337
338    injectStyles();
339    createBanner(
340      config.privacyUrl,
341      function onAccept() {
342        setCookie(COOKIE_NAME, "1", COOKIE_DAYS);
343        grantConsent();
344      },
345      function onDecline() {
346        setCookie(COOKIE_NAME, "0", COOKIE_DAYS);
347      }
348    );
349  }
350
351  if (document.readyState === "loading") {
352    document.addEventListener("DOMContentLoaded", init);
353  } else {
354    init();
355  }
356})();

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.