PageSourceSearch

https://visitfaroeislands.com/views/main/js/cookies.js?v=1791538633

js visitfaroeislands.com collected 2026-10-09 22:17:39 UTC 14,760 bytes, 449 lines download raw bytes

1
2// The cookies should bewrapped in an object if more tracking gets added, currently we only enable or disable.
3
4// GA4 measurement id of this site. It comes from the site's VFI_SITES entry ("ga4") and is
5// put on this script tag by index.html.twig; with no id nothing is sent to Google Analytics.
6const gaTarget = (document.currentScript && document.currentScript.dataset.ga4Id) || '';
7
8// A GTM container on the page (its snippet has already pushed "gtm.start") loads gtag.js by itself
9// for the "config" command below; loading it here as well downloaded the same 175 KB twice.
10const gtmOnPage = (window.dataLayer || []).some((entry) => entry && entry['gtm.start']);
11
12if (gaTarget && !gtmOnPage) {
13    const s = document.createElement('script');
14    s.async = true;
15    s.src = 'https://www.googletagmanager.com/gtag/js?id=' + gaTarget;
16    document.head.appendChild(s);
17}
18
19window.dataLayer = window.dataLayer || [];
20function gtag() { dataLayer.push(arguments); }
21gtag('js', new Date());
22
23if (gaTarget) {
24    gtag('config', gaTarget, {
25        'ad_storage': 'denied'
26    });
27}
28
29function setCookies(val  /* boolean */) {
30    if (!gaTarget) {
31        return;
32    }
33    if (val) {
34        gtag('config', gaTarget, {
35            'analytics_storage': 'permitted',
36            'anonymize_ip': false
37        });
38    } else {
39        gtag('config', gaTarget, {
40            'ad_storage': 'denied',
41            'analytics_storage': 'denied',
42            'anonymize_ip': true
43        });
44    }
45}
46
47// Policy panel links
48const links = [
49    {
50        href: '/privacy-policy',
51        text: 'Go to Privacy & Policy'
52    },
53    {
54        href: '/cookies-and-analytics',
55        text: 'Go to Cookies & Analytics'
56    }
57];
58
59document.addEventListener('DOMContentLoaded', (event) => {
60    // Initial cookie card
61    var initCookieCard = document.querySelector('.init-cookie-card');
62    var acceptCookiesBtn = document.querySelector('.accept-cookies');
63    var neccesaryBtn = document.querySelector('.accept-necessary-cookies');
64
65    // Settings button
66    var settingsBtn = document.querySelectorAll('.cookie-settings-btn');
67
68    // Settings overlay, card and elements
69    var cookieSettings = document.querySelector('.cookie-settings-overlay');
70    var exitBtn = document.querySelector('.cookie-settings-exit-btn');
71
72    // Navigation buttons
73    var aboutPanelBtn = document.querySelector('.about-panel-btn');
74    var settingsPanelBtn = document.querySelector('.settings-panel-btn');
75    var policyPanelBtn = document.querySelector('.privacy-panel-btn');
76
77    // Panels
78    var aboutPanelDesktop = document.querySelector('.cookie-about-panel-desktop');
79    // var aboutPanelMobile = document.querySelector('.cookie-about-panel-mobile');
80    var settingsPanel = document.getElementsByClassName('cookie-settings-panel');
81    var policyPanel = document.getElementsByClassName('cookie-policy-panel');
82
83    [].forEach.call(settingsPanel, panel => {
84
85        // Container for wrapping Title and seettings buttons
86        let topContainer = document.createElement('div');
87        topContainer.classList.add('settings-content-container')
88
89        let title = document.createElement('h1');
90        title.classList.add('title');
91        title.innerHTML = 'Settings';
92        title.appendChild(document.createElement('hr'));
93        topContainer.appendChild(title);
94
95        // Create a container for each toggle switch
96        let checkBoxContainer = document.createElement('div');
97        checkBoxContainer.classList.add('accept-cookie-container');
98
99        // Toggle button
100        let checkBox = document.createElement('button');
101        checkBox.classList.add('accept-cookie-toggle');
102
103        // Toggle slider
104        let slider = document.createElement('div');
105        slider.classList.add('slider');
106        checkBox.appendChild(slider);
107        let text = document.createElement('div');
108        text.innerHTML = 'Allow third party cookies';
109
110        checkBoxContainer.appendChild(text);
111        checkBoxContainer.appendChild(checkBox);
112        topContainer.appendChild(checkBoxContainer);
113
114        panel.appendChild(topContainer);
115
116        // Contianer for buttons in settings panel
117        let btnContainer = document.createElement('div');
118        btnContainer.classList.add('btn-container');
119
120        // Accept all button
121        let acceptAll = document.createElement('button');
122        acceptAll.classList.add('accept-all-cookies');
123        acceptAll.classList.add('btn');
124        acceptAll.innerHTML = 'Accept all';
125
126        btnContainer.appendChild(acceptAll);
127
128        // Settings settings button
129        let save = document.createElement('button');
130        save.classList.add('save-cookie-settings');
131        save.classList.add('btn');
132        save.innerHTML = 'Save changes';
133
134        btnContainer.appendChild(save);
135
136        panel.appendChild(btnContainer);
137    });
138
139    // Add links to policy panel
140    [].forEach.call(policyPanel, panel => {
141
142        let linkContainer = document.createElement('div');
143        linkContainer.classList.add('link-container');
144
145        links.forEach(link => {
146            let a = document.createElement('a');
147            a.href = link.href;
148            a.target = '_blank';
149            a.innerHTML = link.text;
150
151            linkContainer.appendChild(a);
152        });
153
154        panel.appendChild(linkContainer);
155    });
156
157
158    // Could've stored the checkboxes/toggle-buttons in an array when initalizing them, but this works too.
159    var accpetCheckbox = document.getElementsByClassName('accept-cookie-toggle');
160
161    // 
162    var saveChanges = document.getElementsByClassName('save-cookie-settings');
163    var acceptAllSettings = document.getElementsByClassName('accept-all-cookies');
164
165    // Settings change flag
166    let changes = false;
167
168    // Add state for each cookie (currently only Google Analytics)
169    // Could wrap it in a cookie state object
170    let checkState = false;
171
172    // Helper functions for the floating button
173    const btnDisplay = () => {
174        // Displays the floating button
175        settingsBtn.forEach((elm) => {
176            elm.classList.contains('active') ?
177                elm.classList.remove('active') :
178                elm.classList.add('active');
179        })
180    }
181
182    const settingsDisplay = () => {
183        // Displays the settings popup
184        cookieSettings.classList.contains('active') ?
185            cookieSettings.classList.remove('active') :
186            cookieSettings.classList.add('active');
187    }
188
189    // Resetting settings popup when closing
190    const settingsInitReset = () => {
191        [].forEach.call(saveChanges, btn => {
192            btn.classList.remove('changes');
193        });
194
195        policyPanelBtn.classList.remove('selected');
196
197        settingsPanelBtn.classList.remove('selected');
198
199        aboutPanelBtn.classList.add('selected');
200
201        // Mobile
202        policyPanelBtn.classList.remove('mobile-selected');
203        settingsPanelBtn.classList.remove('mobile-selected');
204    }
205
206    // Checks the state of the users cookies, if not set it will open an initial popup that only gets shown once
207    if (!(localStorage.getItem("cookies") === null)) {
208        btnDisplay();
209        initCookieCard.classList.remove('active');
210
211        checkState = (localStorage.getItem("cookies") == 'true');
212        setCookies(checkState);
213
214        [].forEach.call(accpetCheckbox, btn => {
215            checkState ? btn.classList.add('toggled') : btn.classList.remove('toggled');
216        });
217    } else {
218        initCookieCard.classList.add('active');
219        setCookies(checkState);
220    }
221
222    // Accepts all cookies (Init popup)
223    acceptCookiesBtn.addEventListener("click", (e) => {
224        localStorage.setItem('cookies', true);
225
226        [].forEach.call(accpetCheckbox, btn => {
227            btn.classList.add('toggled');
228        });
229
230        checkState = true;
231
232        setCookies(checkState);
233
234        initCookieCard.remove();
235        btnDisplay();
236    });
237
238    // Only accept necessary (Init popup)
239    neccesaryBtn.addEventListener("click", (e) => {
240        localStorage.setItem('cookies', false);
241
242        [].forEach.call(accpetCheckbox, btn => {
243            btn.classList.remove('toggled');
244        });
245
246        checkState = false;
247
248        setCookies(checkState);
249
250        initCookieCard.remove();
251        btnDisplay();
252    });
253
254    // Exit cookie settings
255    exitBtn.addEventListener("click", (e) => {
256        changes = false;
257        [].forEach.call(accpetCheckbox, btn => {
258            checkState = (localStorage.getItem("cookies") == 'true');
259            (localStorage.getItem("cookies") == 'true') ? btn.classList.add('toggled') : btn.classList.remove('toggled');
260        });
261
262        // Mobile
263        policyPanel[0].classList.remove('active');
264        settingsPanel[0].classList.remove('active');
265
266        // Desktop
267        aboutPanelDesktop.classList.add('active');
268        policyPanel[1].classList.remove('active');
269        settingsPanel[1].classList.remove('active');
270
271        settingsInitReset();
272
273        settingsDisplay();
274        btnDisplay();
275    });
276
277    // Settings panel / button
278    settingsBtn.forEach((elm) => {
279        elm.addEventListener("click", (e) => {
280            // Opens cookie settings
281            if (elm.classList.contains('link-to-settings')) {
282                initCookieCard.classList.remove('active')
283            }
284            settingsDisplay();
285            btnDisplay();
286        });
287    })
288
289    // Panels
290
291    aboutPanelBtn.addEventListener("click", (e) => {
292
293        // Desktop
294        aboutPanelDesktop.classList.add('active');
295        policyPanel[1].classList.remove('active');
296        settingsPanel[1].classList.remove('active');
297
298        // Mobile
299        settingsPanel[0].classList.contains('active') ?
300            settingsPanel[0].classList.remove('active') :
301            settingsPanel[0].classList.add('active');
302
303        settingsPanelBtn.classList.contains('mobile-selected') ?
304            settingsPanelBtn.classList.remove('mobile-selected') :
305            settingsPanelBtn.classList.add('mobile-selected');
306
307        // Common
308        aboutPanelBtn.classList.add('selected');
309        settingsPanelBtn.classList.remove('selected');
310        policyPanelBtn.classList.remove('selected');
311
312    });
313
314    settingsPanelBtn.addEventListener("click", (e) => {
315        // Desktop
316        aboutPanelDesktop.classList.remove('active');
317        policyPanel[1].classList.remove('active');
318        settingsPanel[1].classList.add('active');
319
320        // Mobile
321        settingsPanel[0].classList.contains('active') ?
322            settingsPanel[0].classList.remove('active') :
323            settingsPanel[0].classList.add('active');
324
325        settingsPanelBtn.classList.contains('mobile-selected') ?
326            settingsPanelBtn.classList.remove('mobile-selected') :
327            settingsPanelBtn.classList.add('mobile-selected');
328
329        // Common
330        aboutPanelBtn.classList.remove('selected');
331        settingsPanelBtn.classList.add('selected');
332        policyPanelBtn.classList.remove('selected');
333
334    });
335
336    // Policy panel/button
337    policyPanelBtn.addEventListener("click", (e) => {
338
339        // Desktop
340        aboutPanelDesktop.classList.remove('active');
341        policyPanel[1].classList.add('active');
342        settingsPanel[1].classList.remove('active');
343
344        // Mobile
345        policyPanel[0].classList.contains('active') ?
346            policyPanel[0].classList.remove('active') :
347            policyPanel[0].classList.add('active');
348
349        policyPanelBtn.classList.contains('mobile-selected') ?
350            policyPanelBtn.classList.remove('mobile-selected') :
351            policyPanelBtn.classList.add('mobile-selected');
352
353        // Common
354        aboutPanelBtn.classList.remove('selected');
355        settingsPanelBtn.classList.remove('selected');
356        policyPanelBtn.classList.add('selected');
357    });
358
359    // Accept cookie checkbox
360    [].forEach.call(accpetCheckbox, container => {
361
362        container.addEventListener("click", (e) => {
363            checkState = !checkState;
364
365            changes = true;
366            [].forEach.call(accpetCheckbox, btn => {
367                checkState ? btn.classList.add('toggled') : btn.classList.remove('toggled');
368            });
369            [].forEach.call(saveChanges, btn => {
370                btn.classList.add('changes');
371            });
372        });
373    });
374
375    // Accept all cookies button
376    [].forEach.call(acceptAllSettings, btn => {
377        btn.addEventListener("click", (e) => {
378            // Accept all cookies
379            checkState = true;
380            setCookies(checkState);
381            changes = false;
382            localStorage.setItem('cookies', true);
383            [].forEach.call(accpetCheckbox, btn => {
384                btn.classList.add('toggled');
385            });
386
387            // Mobile
388            policyPanel[0].classList.remove('active');
389            settingsPanel[0].classList.remove('active');
390
391            // Desktop
392            aboutPanelDesktop.classList.add('active');
393            policyPanel[1].classList.remove('active');
394            settingsPanel[1].classList.remove('active');
395
396            settingsInitReset();
397
398            settingsDisplay();
399            btnDisplay();
400        });
401    });
402
403    // Save changes button
404    [].forEach.call(saveChanges, btn => {
405        btn.addEventListener("click", (e) => {
406            if (changes) {
407                changes = false;
408                localStorage.setItem('cookies', checkState);
409
410                setCookies(checkState);
411
412                // Mobile
413                policyPanel[0].classList.remove('active');
414                settingsPanel[0].classList.remove('active');
415
416                // Desktop
417                aboutPanelDesktop.classList.add('active');
418                policyPanel[1].classList.remove('active');
419                settingsPanel[1].classList.remove('active');
420
421                settingsInitReset();
422
423                settingsDisplay();
424                btnDisplay();
425            }
426        });
427    });
428
429    document.querySelector('.nav-tab').addEventListener('click', () => {
430        // Desktop
431        aboutPanelDesktop.classList.remove('active');
432        policyPanel[1].classList.add('active');
433        settingsPanel[1].classList.remove('active');
434
435        // Mobile
436        policyPanel[0].classList.contains('active') ?
437            policyPanel[0].classList.remove('active') :
438            policyPanel[0].classList.add('active');
439
440        policyPanelBtn.classList.contains('mobile-selected') ?
441            policyPanelBtn.classList.remove('mobile-selected') :
442            policyPanelBtn.classList.add('mobile-selected');
443
444        // Common
445        aboutPanelBtn.classList.remove('selected');
446        settingsPanelBtn.classList.remove('selected');
447        policyPanelBtn.classList.add('selected');
448    });
449});

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.