PageSourceSearch

https://www.kartarkysvetla.cz/wp-content/plugins/tritonit-cookie-bar/assets/js/cookie-bar.js?ver=fef848d3

js kartarkysvetla.cz collected 2026-10-08 09:47:00 UTC 17,261 bytes, 398 lines download raw bytes

1function escapeHtml(str) {
2    return String(str == null ? '' : str)
3        .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
4        .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
5}
6
7function removeWildcardCookie(name) {
8    try {
9        var host = window.location.hostname;
10        var parts = host.split('.');
11        for (var i = 1; i < parts.length - 1; i++) {
12            var d = '.' + parts.slice(i).join('.');
13            document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=' + d;
14        }
15    } catch (e) {}
16}
17
18function setCookie(name, value, days) {
19    var hostOnly = !!(window.cookie_bar && window.cookie_bar.settings && window.cookie_bar.settings.forceHostOnly);
20    if (hostOnly) {
21        removeWildcardCookie(name);
22    }
23    // Intentionally omit `domain` so the cookie is host-only per RFC 6265 (no Domain attribute).
24    Cookies.set(name, (value || ""), { expires: days, path: '/', sameSite: 'Lax' });
25}
26
27function getCookieValue(name) {
28    const cookie = document.cookie.match(new RegExp(`(^|; )${name}=([^;]*)`));
29    return cookie ? decodeURIComponent(cookie[2]) : null;
30}
31
32class CookieBar {
33    constructor(settings = {}, categories = []) {
34        this.defaultSettings = {
35            'settingsDuration': 3600 * 24 * 365,
36            'htmlFile': 'cookie_bar.html',
37            'appearDelay': 10,
38            'settingsCookieName': 'settings66'
39        };
40
41        this.consentSettings = { 'granted': [], 'denied': [] };
42        this.show = true;
43        this.snippets = {};
44        this.settings = { ...this.defaultSettings, ...settings };
45        this.categories = categories;
46
47        this.defaultConsentSettings = {
48            'granted': this.categories.filter(c => c.required).map(c => c.id),
49            'denied': this.categories.filter(c => !c.required).map(c => c.id)
50        };
51
52        this.gcmMapping = {};
53        this.categories.forEach(cat => {
54            this.gcmMapping[cat.id] = cat.gcm_types || [];
55        });
56
57        let setConsentSettingsScript = "setCookie('" + this.settings['settingsCookieName'] + "', JSON.stringify(window.cookie_bar.getConsentSettings()), 365);";
58        this.addSnippet(setConsentSettingsScript, "essential");
59
60        if ((this.consentSettings = this.getConsentSettingsFromStorage()) === false) {
61            this.consentSettings = this.defaultConsentSettings;
62        } else {
63            if (this.isFullConsentStatusKnown()) {
64                this.show = false;
65                this.setDataLayerConsentStatus();
66            }
67        }
68    }
69
70    start() {
71        if (this.show) {
72            this.render();
73        } else {
74            this.executeSnippets();
75            this.addReopenButton();
76        }
77    }
78
79    addSnippet(snippet, requiredKey) {
80        if (this.snippets.hasOwnProperty(requiredKey) && (this.snippets[requiredKey].indexOf(snippet) === -1)) {
81            this.snippets[requiredKey].push(snippet);
82        } else {
83            this.snippets[requiredKey] = [snippet];
84        }
85    }
86
87    executeSnippets() {
88        let snippetsQueue = [];
89        let resolvedKeys = new Set();
90
91        for (let categoryId of this.consentSettings.granted) {
92            resolvedKeys.add(categoryId);
93            if (this.gcmMapping[categoryId]) {
94                this.gcmMapping[categoryId].forEach(gcmType => resolvedKeys.add(gcmType));
95            }
96        }
97
98        for (let key of resolvedKeys) {
99            if (this.snippets.hasOwnProperty(key)) {
100                snippetsQueue = snippetsQueue.concat(this.snippets[key]);
101            }
102        }
103
104        // "Consent changed" snippets always run, and always last
105        if (this.snippets.hasOwnProperty('__consent_changed')) {
106            snippetsQueue = snippetsQueue.concat(this.snippets['__consent_changed']);
107        }
108
109        for (let snippet of snippetsQueue) {
110            var script = document.createElement('script');
111            script.type = 'text/javascript';
112            script.innerHTML = snippet;
113            document.head.appendChild(script);
114        }
115    }
116
117    getConsentSettingsFromStorage() {
118        let storage = JSON.parse(getCookieValue(this.settings['settingsCookieName']));
119        if (!storage) return false;
120
121        let categoryIds = this.categories.map(c => c.id);
122        let allStored = [...(storage.granted || []), ...(storage.denied || [])];
123        let hasOldFormat = allStored.length > 0 && !allStored.some(key => categoryIds.includes(key));
124        if (hasOldFormat) return false;
125
126        return storage;
127    }
128
129    isFullConsentStatusKnown() {
130        let categoryIds = this.categories.map(c => c.id);
131        let allConsentValues = new Set([
132            ...this.consentSettings.granted,
133            ...this.consentSettings.denied,
134        ]);
135        return categoryIds.every(id => allConsentValues.has(id));
136    }
137
138    addReopenButton() {
139        let existing = document.getElementById('cookie-settings-reopen');
140        if (existing) return;
141
142        let btn = document.createElement('button');
143        btn.id = 'cookie-settings-reopen';
144        btn.className = 'cookie-settings-reopen';
145        btn.title = this.settings.reopenLabel || 'Cookie settings';
146        btn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>';
147        document.body.appendChild(btn);
148
149        let theClass = this;
150        btn.addEventListener('click', function () {
151            theClass.reopenSettings();
152        });
153    }
154
155    reopenSettings() {
156        let existingWrap = document.querySelector('.cookie-bar-wrap');
157        if (existingWrap) existingWrap.remove();
158        let reopenBtn = document.getElementById('cookie-settings-reopen');
159        if (reopenBtn) reopenBtn.remove();
160        this.show = true;
161        this.render();
162    }
163
164    hideBanner() {
165        document.querySelector(".cookie-bar-wrap").classList.add("hidden");
166        this.addReopenButton();
167    }
168
169    rejectAll() {
170        let cs = this.getConsentSettings();
171        cs.granted = this.categories.filter(c => c.required).map(c => c.id);
172        cs.denied = this.categories.filter(c => !c.required).map(c => c.id);
173        this.setConsentSettings(cs);
174        this.hideBanner();
175    }
176
177    acceptAll() {
178        let cs = this.getConsentSettings();
179        cs.granted = this.categories.map(c => c.id);
180        cs.denied = [];
181        this.setConsentSettings(cs);
182        this.hideBanner();
183    }
184
185    saveSelected() {
186        let cs = this.getConsentSettings();
187        let checkboxes = document.querySelectorAll(".cookie-bar-wrap .cb-switch-input");
188        let newGranted = [];
189        let newDenied = [];
190        checkboxes.forEach(function (cb) {
191            if (cb.checked) newGranted.push(cb.id);
192            else newDenied.push(cb.id);
193        });
194        cs.granted = newGranted;
195        cs.denied = newDenied;
196        this.setConsentSettings(cs);
197        this.hideBanner();
198    }
199
200    render() {
201        let showDelay = this.settings['appearDelay'];
202        let theClass = this;
203
204        var request = new XMLHttpRequest();
205        request.open('GET', this.settings['htmlFile'], true);
206        request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
207        request.onload = function () {
208            if (this.status >= 200 && this.status < 400) {
209                document.querySelector("body").insertAdjacentHTML("afterbegin", this.response);
210
211                // Build layer 2 categories
212                let catContainer = document.querySelector(".cookie-bar-wrap .cb-categories");
213
214                theClass.categories.forEach(category => {
215                    let isGranted = theClass.consentSettings.granted.includes(category.id);
216                    let checked = (category.required || isGranted) ? " checked" : "";
217                    let disabled = category.required ? " disabled" : "";
218
219                    let servicesHtml = '';
220                    if (category.services && category.services.length > 0) {
221                        let isDetailed = typeof category.services[0] === 'object' && category.services[0] !== null;
222                        let listInner;
223                        if (isDetailed) {
224                            let cols = theClass.settings.serviceColumns || {
225                                name: 'Name', provider: 'Provider / Domain', expiration: 'Expiration', description: 'Description'
226                            };
227                            let head =
228                                '<tr>' +
229                                    '<th>' + escapeHtml(cols.name) + '</th>' +
230                                    '<th>' + escapeHtml(cols.provider) + '</th>' +
231                                    '<th>' + escapeHtml(cols.expiration) + '</th>' +
232                                    '<th>' + escapeHtml(cols.description) + '</th>' +
233                                '</tr>';
234                            let rows = category.services.map(s =>
235                                '<tr>' +
236                                    '<td>' + escapeHtml(s.name || '') + '</td>' +
237                                    '<td>' + escapeHtml(s.provider || '') + '</td>' +
238                                    '<td>' + escapeHtml(s.expiration || '') + '</td>' +
239                                    '<td>' + escapeHtml(s.description || '') + '</td>' +
240                                '</tr>'
241                            ).join('');
242                            listInner = '<table class="cb-services-table"><thead>' + head + '</thead><tbody>' + rows + '</tbody></table>';
243                        } else {
244                            listInner = category.services.map(s => '<span class="cb-service-item">' + escapeHtml(s) + '</span>').join('');
245                        }
246                        servicesHtml =
247                            '<div class="cb-services">' +
248                                '<button class="cb-services-toggle" type="button">' +
249                                    (theClass.settings.servicesLabel || 'Services') +
250                                    ' <span class="cb-chevron"></span>' +
251                                '</button>' +
252                                '<div class="cb-services-list' + (isDetailed ? ' cb-services-list--table' : '') + ' cb-hidden">' + listInner + '</div>' +
253                            '</div>';
254                    }
255
256                    let cat = document.createElement('div');
257                    cat.className = 'cb-category';
258                    cat.innerHTML =
259                        '<div class="cb-category-header">' +
260                            '<div class="cb-category-info">' +
261                                '<span class="cb-category-title">' + category.title + '</span>' +
262                                '<span class="cb-category-desc">' + (category.desc || '') + '</span>' +
263                            '</div>' +
264                            '<label class="cb-switch">' +
265                                '<input class="cb-switch-input" type="checkbox" id="' + category.id + '"' + checked + disabled + '>' +
266                                '<span class="cb-switch-track"></span>' +
267                            '</label>' +
268                        '</div>' +
269                        servicesHtml;
270
271                    catContainer.appendChild(cat);
272
273                    if (!category.required) {
274                        cat.querySelector('.cb-switch-input').addEventListener("change", function () {
275                            theClass.updateConsentSettings(category.id, this.checked);
276                        });
277                    }
278                });
279
280                // Services expand toggles
281                document.querySelectorAll('.cb-services-toggle').forEach(function (btn) {
282                    btn.addEventListener('click', function () {
283                        let list = this.nextElementSibling;
284                        list.classList.toggle('cb-hidden');
285                        this.querySelector('.cb-chevron').classList.toggle('cb-chevron--open');
286                    });
287                });
288
289                // Domains expand toggle
290                let domainToggle = document.querySelector('.cb-domains-toggle');
291                if (domainToggle) {
292                    domainToggle.addEventListener('click', function () {
293                        let list = this.nextElementSibling;
294                        list.classList.toggle('cb-hidden');
295                        this.querySelector('.cb-chevron').classList.toggle('cb-chevron--open');
296                    });
297                }
298
299                // Layer switching
300                let layer1 = document.getElementById('cb-layer-1');
301                let layer2 = document.getElementById('cb-layer-2');
302
303                document.getElementById('customize-btn').addEventListener('click', function () {
304                    layer1.classList.add('cb-hidden');
305                    layer2.classList.remove('cb-hidden');
306                });
307
308                document.getElementById('cb-back').addEventListener('click', function () {
309                    layer2.classList.add('cb-hidden');
310                    layer1.classList.remove('cb-hidden');
311                });
312
313                // Close button (X) = reject all
314                document.getElementById('cb-close').addEventListener('click', function () {
315                    theClass.rejectAll();
316                });
317
318                // Layer 1 buttons
319                document.getElementById('accept-all').addEventListener('click', function () { theClass.acceptAll(); });
320                document.getElementById('reject-all').addEventListener('click', function () { theClass.rejectAll(); });
321
322                // Layer 2 buttons
323                document.getElementById('accept-all-2').addEventListener('click', function () { theClass.acceptAll(); });
324                document.getElementById('reject-all-2').addEventListener('click', function () { theClass.rejectAll(); });
325                document.getElementById('accept-selected').addEventListener('click', function () { theClass.saveSelected(); });
326
327                // Show
328                setTimeout(function () {
329                    document.querySelector(".cookie-bar-wrap").classList.remove("hidden");
330                }, showDelay);
331
332            } else {
333                console.log("Cookie bar HTML could not be loaded.");
334            }
335        };
336
337        request.onerror = function () {
338            console.log("Cookie bar HTML could not be loaded.");
339        };
340        request.send();
341    }
342
343    getConsentSettings() {
344        return this.consentSettings;
345    }
346
347    setConsentSettings(consentSettings) {
348        this.consentSettings = consentSettings;
349
350        // First: explicitly deny all GCM types for denied categories
351        let deniedGcmTypes = new Set();
352        let grantedGcmTypes = new Set();
353
354        for (let categoryId of this.consentSettings.denied) {
355            if (this.gcmMapping[categoryId]) {
356                this.gcmMapping[categoryId].forEach(gcmType => deniedGcmTypes.add(gcmType));
357            }
358        }
359        for (let categoryId of this.consentSettings.granted) {
360            if (this.gcmMapping[categoryId]) {
361                this.gcmMapping[categoryId].forEach(gcmType => grantedGcmTypes.add(gcmType));
362            }
363        }
364
365        // Send denied updates for GCM types that are not granted
366        let consentUpdate = {};
367        deniedGcmTypes.forEach(function(gcmType) {
368            if (!grantedGcmTypes.has(gcmType)) {
369                consentUpdate[gcmType] = 'denied';
370            }
371        });
372        if (Object.keys(consentUpdate).length > 0 && typeof gtag === 'function') {
373            gtag('consent', 'update', consentUpdate);
374        }
375
376        // Then execute granted snippets
377        this.executeSnippets();
378        this.setDataLayerConsentStatus();
379    }
380
381    updateConsentSettings(categoryId, granted) {
382        var isGranted = this.consentSettings['granted'].indexOf(categoryId);
383        var isDenied = this.consentSettings['denied'].indexOf(categoryId);
384
385        if (granted) {
386            if (isGranted === -1) this.consentSettings['granted'].push(categoryId);
387            if (isDenied !== -1) this.consentSettings['denied'].splice(isDenied, 1);
388        } else {
389            if (isDenied === -1) this.consentSettings['denied'].push(categoryId);
390            if (isGranted !== -1) this.consentSettings['granted'].splice(isGranted, 1);
391        }
392    }
393
394    setDataLayerConsentStatus() {
395        window.dataLayer = window.dataLayer || [];
396        window.dataLayer.push({ 'event': '' });
397    }
398}

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.