PageSourceSearch

http://acroniscoupon.info/js/cookie-consent-settings0829.js

js acroniscoupon.info collected 2026-10-04 13:27:52 UTC 15,098 bytes, 353 lines download raw bytes

1"use strict"
2
3function CookieConsentSettings(props) {
4
5    const self = this
6    let detailedSettingsShown = false
7    this.props = {
8        privacyPolicyUrl: undefined, // the URL of your privacy policy page
9        legalNoticeUrl: undefined, // the URL of you legal notice page (Impressum)
10        contentURL: "/cookie-consent-content", // this folder must contain the language-files in the needed languages (`[lang].js`)
11        buttonAgreeClass: "btn btn-primary", // the "Agree to all" buttons class
12        buttonDontAgreeClass: "btn btn-link text-decoration-none", // the "I do not agree" buttons class
13        buttonSaveClass: "btn btn-secondary", // the "Save selection" buttons class
14        autoShowModal: true, // disable autoShowModal on the privacy policy and legal notice pages, to make these pages readable
15        alsoUseLocalStorage: true, // if true, the settings are stored in localStorage, too
16        postSelectionCallback: undefined, // callback function, called after the user has saved the settings
17        lang: navigator.language, // the language, in which the modal is shown
18        defaultLang: "en", // default language, if `lang` is not available as translation in `cookie-consent-content`
19        categories: ["necessary", "statistics", "marketing", "personalization"], // the categories for selection, must be contained in the language files
20        cookieName: "cookie-consent-settings",  // the name of the cookie in which the configuration is stored as JSON
21        cookieStorageDays: 365, // the duration the cookie configuration is stored on the client
22        modalId: "cookieConsentSettingsModal" // the id of the modal dialog element
23    }
24    if (!props.privacyPolicyUrl) {
25        console.error("please set `privacyPolicyUrl` in the props of cookieConsentSettings")
26    }
27    if (!props.legalNoticeUrl) {
28        console.error("please set `legalNoticeUrl` in the props of cookieConsentSettings")
29    }
30    for (const property in props) {
31        // noinspection JSUnfilteredForInLoop
32        this.props[property] = props[property]
33    }
34    this.lang = this.props.lang
35    if (this.lang.indexOf("-") !== -1) {
36        this.lang = this.lang.split("-")[0]
37    }
38
39    // read the cookie, and if its content does not fit the categories, remove it
40    const cookieContent = getCookie(this.props.cookieName)
41    if (cookieContent) {
42        try {
43            for (const category of this.props.categories) {
44                if (cookieContent[category] === undefined) {
45                    console.log("cookie settings changed, removing settings cookie")
46                    removeCookie(this.props.cookieName)
47                    break
48                }
49            }
50        } catch (e) {
51            // problems with the cookie, remove it
52            console.warn("cookie settings changed, removing settings cookie", e)
53            removeCookie(this.props.cookieName)
54        }
55    }
56
57    /**
58     * Read the language file and render the modal
59     */
60    fetchContent(self.lang, (result) => {
61        self.content = JSON.parse(result)
62        renderModal()
63    })
64
65    function renderModal() {
66        const _t = self.content
67        const linkPrivacyPolicy = '<a href="' + self.props.privacyPolicyUrl + '" class="text-underline">' + _t.privacyPolicy + '</a>'
68        const linkLegalNotice = '<a href="' + self.props.legalNoticeUrl + '"  class="btn btn-secondary btn-sm">' + _t.legalNotice + '</a>'
69        if (self.content[self.lang] === undefined) {
70            self.lang = self.props.defaultLang
71        }
72        self.content.body = self.content.body.replace(/--privacy-policy--/, linkPrivacyPolicy)
73        let optionsHtml = ""
74        for (const category of self.props.categories) {
75            const categoryContent = self.content.categories[category]
76            if (!categoryContent) {
77                console.error("no content for category", category, "found in language file", self.lang)
78            }
79            let descriptionList = ""
80            for (const descriptionElement of categoryContent.description) {
81                descriptionList += `<li class='list-group-item' style='font-size:90%;'>${descriptionElement}</li>`
82            }
83            optionsHtml += `<hr><div class="bccs-option" style='font-size:90%;' data-name="${category}">
84                    <div class="mb-1">
85                        <div class="form-check form-switch">
86                            <input class="form-check-input" type="checkbox" role="switch" id="bccs-checkbox-${category}" checked>
87                            <label class="form-check-label" for="bccs-checkbox-${category}"><b>${categoryContent.title}</b></label>
88                        </div>
89                    </div>
90                    <ul class='list-group list-group-flush'>
91                        ${descriptionList}
92                    </ul>
93                </div>`
94        }
95        self.modalContent = `
96<div class="modal-dialog modal-lg shadow" role="document">
97    <div class="modal-content">
98        <div class="modal-header">
99            <img src="https://img.coupontools.com/2020/logo/logo3.svg" height="57.52" width="300" alt="Logo Coupontools.com | Coupontools Digital Loyalty Cards, Coupons and Digital Payment Vouchers.">
100            <h4 class="modal-title">${self.content.title}</h4>
101        </div>
102        <div class="modal-body">
103            <div class="bccs-body-text mb-2" style="font-size: 80%">
104                <p>${self.content.body}</p>
105            </div>
106            <p class="d-flex justify-content-between mb-0">
107                ${linkLegalNotice}
108                <a href="#bccs-options" class='btn btn-secondary btn-sm' data-toggle="collapse">${self.content.mySettings}</a>
109            </p>
110            <div id="bccs-options" class="collapse">
111                <div class="mt-4">
112                    ${optionsHtml}
113                </div>
114            </div>
115        </div>
116        <div class="modal-footer">
117            <button id="bccs-buttonSave" type="button" class="${self.props.buttonSaveClass}">
118                ${self.content.buttonSaveSelection}
119            </button>
120            <button id="bccs-buttonAgreeAll" type="button" class="${self.props.buttonAgreeClass}">${self.content.buttonAgreeAll}</button>
121            <button id="bccs-buttonAgree" type="button" class="${self.props.buttonAgreeClass}">${self.content.buttonAgree}</button>
122        </div>
123    </div>
124</div>`
125        if (!getCookie(self.props.cookieName) && self.props.autoShowModal) {
126            showDialog()
127        }
128    }
129
130    function showDialog() {
131        documentReady(function () {
132            self.modalElement = document.getElementById(self.props.modalId)
133            if (!self.modalElement) {
134                self.modalElement = document.createElement("div")
135                self.modalElement.id = self.props.modalId
136                self.modalElement.setAttribute("class", "modal fade")
137                self.modalElement.setAttribute("tabindex", "-1")
138                self.modalElement.setAttribute("role", "dialog")
139                self.modalElement.setAttribute("aria-labelledby", self.props.modalId)
140                self.modalElement.innerHTML = self.modalContent
141                document.body.append(self.modalElement)
142                if (self.props.postSelectionCallback) {
143                    $("#"+self.props.modalId).on("hidden.bs.modal", function () {
144                        self.props.postSelectionCallback()
145                    })
146                }
147                self.modal = new bootstrap.Modal(self.modalElement, {
148                    backdrop: "static",
149                    keyboard: false
150                })
151                self.modal.show()
152                //self.buttonDoNotAgree = self.modalElement.querySelector("#bccs-buttonDoNotAgree")
153                self.buttonAgree = self.modalElement.querySelector("#bccs-buttonAgree")
154                self.buttonSave = self.modalElement.querySelector("#bccs-buttonSave")
155                self.buttonAgreeAll = self.modalElement.querySelector("#bccs-buttonAgreeAll")
156                updateButtons()
157                updateOptionsFromCookie()
158                $('#bccs-options').on('hide.bs.collapse', function () {
159                    detailedSettingsShown = false
160                    updateButtons()
161                });
162                $('#bccs-options').on('show.bs.collapse', function () {
163                    detailedSettingsShown = true
164                    updateButtons()
165                });
166
167                /*self.buttonDoNotAgree.addEventListener("click", function () {
168                    doNotAgree()
169                })*/
170                self.buttonAgree.addEventListener("click", function () {
171                    agreeAll()
172                })
173                self.buttonSave.addEventListener("click", function () {
174                    saveSettings()
175                })
176                self.buttonAgreeAll.addEventListener("click", function () {
177                    agreeAll()
178                })
179            } else {
180                self.modal.show()
181            }
182        }.bind(this))
183    }
184
185    function updateOptionsFromCookie() {
186        const settings = self.getSettings()
187        if (settings) {
188            for (let setting in settings) {
189                const checkboxElement = self.modalElement.querySelector("#bccs-checkbox-" + setting)
190                checkboxElement.checked = settings[setting] === "true"
191            }
192        }
193        const checkboxNecessary = self.modalElement.querySelector("#bccs-checkbox-necessary")
194        checkboxNecessary.checked = true
195        checkboxNecessary.disabled = true
196    }
197
198    function updateButtons() {
199        if (detailedSettingsShown) {
200            //self.buttonDoNotAgree.style.display = "none"
201            self.buttonAgree.style.display = "none"
202            self.buttonSave.style.removeProperty("display")
203            self.buttonAgreeAll.style.removeProperty("display")
204        } else {
205            //self.buttonDoNotAgree.style.removeProperty("display")
206            self.buttonAgree.style.removeProperty("display")
207            self.buttonSave.style.display = "none"
208            self.buttonAgreeAll.style.display = "none"
209        }
210    }
211
212    function gatherOptions(setAllTo = undefined) {
213        const options = {}
214        for (const category of self.props.categories) {
215            if (setAllTo === undefined) {
216                const checkbox = self.modalElement.querySelector("#bccs-checkbox-" + category)
217                if (!checkbox) {
218                    console.error("checkbox not found for category", category)
219                }
220                options[category] = checkbox.checked
221            } else {
222                options[category] = setAllTo
223            }
224        }
225        options["necessary"] = true // necessary is necessary
226        return options
227    }
228
229    function agreeAll() {
230        setCookie(self.props.cookieName, gatherOptions(true), self.props.cookieStorageDays)
231        self.modal.hide()
232    }
233
234    function doNotAgree() {
235        setCookie(self.props.cookieName, gatherOptions(false), self.props.cookieStorageDays)
236        self.modal.hide()
237    }
238
239    function saveSettings() {
240        setCookie(self.props.cookieName, gatherOptions(), self.props.cookieStorageDays)
241        self.modal.hide()
242    }
243
244    function fetchContent(lang, callback) {
245        const request = new XMLHttpRequest()
246        request.overrideMimeType("application/json");
247        const url = self.props.contentURL + '/en.json';
248        request.open('GET', url, true)
249        request.onreadystatechange = function () {
250            if (request.readyState === 4 && request.status === 200) {
251                if (request.status === 200) {
252                    callback(request.responseText)
253                } else {
254                    console.error(url, request.status)
255                }
256            }
257        }
258        request.onloadend = function () {
259            if (request.status === 404 && lang !== self.props.defaultLang) {
260                console.warn("language " + lang + " not found trying defaultLang " + self.props.defaultLang)
261                fetchContent(self.props.defaultLang, callback)
262            }
263        }
264        request.send(null)
265    }
266
267    function setCookie(name, object, days) {
268        let expires = ""
269        if (days) {
270            const date = new Date()
271            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000))
272            expires = "; expires=" + date.toUTCString()
273        }
274        const value = new URLSearchParams(object).toString()
275        document.cookie = name + "=" + (value || "") + expires + "; Path=/; SameSite=Strict;"
276        // store value also in localStorage
277        localStorage.setItem(name, value)
278    }
279
280    function getCookie(name) {
281        const nameEQ = name + "="
282        const ca = document.cookie.split(';')
283        for (let i = 0; i < ca.length; i++) {
284            let c = ca[i]
285            while (c.charAt(0) === ' ') {
286                c = c.substring(1, c.length)
287            }
288            if (c.indexOf(nameEQ) === 0) {
289                const urlSearchParams = new URLSearchParams(c.substring(nameEQ.length, c.length))
290                const result = {}
291                for (const [key, value] of urlSearchParams) {
292                    result[key] = value
293                }
294                return result
295            }
296        }
297        // if cookie not found, try localStorage
298        const value = localStorage.getItem(name)
299        if (value) {
300            const urlSearchParams = new URLSearchParams(value)
301            const result = {}
302            for (const [key, value] of urlSearchParams) {
303                result[key] = value
304            }
305            setCookie(name, result, self.props.cookieStorageDays)
306            return result
307        }
308        return null
309    }
310
311    function removeCookie(name) {
312        document.cookie = name + '=; Path=/; SameSite=Strict; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'
313    }
314
315    function documentReady(callback) {
316        if (document.readyState !== 'loading') {
317            callback()
318        } else {
319            document.addEventListener('DOMContentLoaded', callback)
320        }
321    }
322
323    // API
324    this.showDialog = function () {
325        showDialog()
326    }
327    this.getSettings = function (optionName) {
328        const cookieContent = getCookie(self.props.cookieName)
329        if (cookieContent) {
330            if (optionName === undefined) {
331                return cookieContent
332            } else {
333                if (cookieContent) {
334                    return cookieContent[optionName]
335                } else {
336                    return false
337                }
338            }
339        } else {
340            return undefined
341        }
342    }
343    this.setSetting = function (name, value) {
344        let settings = self.getSettings() || {}
345        for (const category of this.props.categories) {
346            if(settings[category] === undefined) {
347                settings[category] = true
348            }
349        }
350        settings[name] = value
351        setCookie(self.props.cookieName, settings, self.props.cookieStorageDays)
352    }
353}

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.