155 lines
4.3 KiB
JavaScript
155 lines
4.3 KiB
JavaScript
/* =========================================================================
|
|
cookie-consent.js — GDPR-style consent manager.
|
|
Non-essential scripts must be added to the page as:
|
|
<script type="text/plain" data-cookiecategory="analytics"> ... </script>
|
|
They stay inert until the visitor grants that category, at which point this
|
|
module reactivates them. Consent is stored in localStorage.
|
|
========================================================================= */
|
|
(function () {
|
|
"use strict";
|
|
|
|
var STORAGE_KEY = "cookieConsent";
|
|
var CATEGORIES = ["necessary", "analytics", "marketing"];
|
|
|
|
function readConsent() {
|
|
try {
|
|
return JSON.parse(localStorage.getItem(STORAGE_KEY) || "null");
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function writeConsent(consent) {
|
|
consent.necessary = true; // always on
|
|
consent.ts = Date.now();
|
|
try {
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(consent));
|
|
} catch (e) {
|
|
/* ignore */
|
|
}
|
|
activateScripts(consent);
|
|
}
|
|
|
|
function activateScripts(consent) {
|
|
var nodes = document.querySelectorAll(
|
|
'script[type="text/plain"][data-cookiecategory]'
|
|
);
|
|
Array.prototype.forEach.call(nodes, function (node) {
|
|
if (node.getAttribute("data-cookie-activated") === "1") return;
|
|
var cat = node.getAttribute("data-cookiecategory");
|
|
if (!consent[cat]) return;
|
|
|
|
var s = document.createElement("script");
|
|
for (var i = 0; i < node.attributes.length; i++) {
|
|
var attr = node.attributes[i];
|
|
if (attr.name === "type" || attr.name === "data-cookiecategory") continue;
|
|
s.setAttribute(attr.name, attr.value);
|
|
}
|
|
s.type = "text/javascript";
|
|
if (!node.src) {
|
|
s.text = node.textContent;
|
|
}
|
|
node.parentNode.insertBefore(s, node.nextSibling);
|
|
node.setAttribute("data-cookie-activated", "1");
|
|
});
|
|
}
|
|
|
|
function banner() {
|
|
return document.getElementById("cookie-consent");
|
|
}
|
|
|
|
function showBanner() {
|
|
var b = banner();
|
|
if (b) b.hidden = false;
|
|
}
|
|
|
|
function hideBanner() {
|
|
var b = banner();
|
|
if (b) b.hidden = true;
|
|
}
|
|
|
|
function acceptAll() {
|
|
var consent = { necessary: true };
|
|
CATEGORIES.forEach(function (c) {
|
|
consent[c] = true;
|
|
});
|
|
writeConsent(consent);
|
|
hideBanner();
|
|
}
|
|
|
|
function rejectNonEssential() {
|
|
var consent = { necessary: true, analytics: false, marketing: false };
|
|
writeConsent(consent);
|
|
hideBanner();
|
|
}
|
|
|
|
function savePreferences() {
|
|
var b = banner();
|
|
var consent = { necessary: true };
|
|
CATEGORIES.forEach(function (c) {
|
|
if (c === "necessary") return;
|
|
var box = b
|
|
? b.querySelector('[data-cc-category="' + c + '"]')
|
|
: null;
|
|
consent[c] = !!(box && box.checked);
|
|
});
|
|
writeConsent(consent);
|
|
hideBanner();
|
|
}
|
|
|
|
function toggleManage() {
|
|
var b = banner();
|
|
if (!b) return;
|
|
var panel = b.querySelector("[data-cc-panel]");
|
|
if (panel) panel.hidden = !panel.hidden;
|
|
}
|
|
|
|
function init() {
|
|
var b = banner();
|
|
var existing = readConsent();
|
|
|
|
if (existing) {
|
|
activateScripts(existing);
|
|
if (b) b.hidden = true;
|
|
} else if (b) {
|
|
b.hidden = false;
|
|
}
|
|
|
|
if (!b) return;
|
|
|
|
var accept = b.querySelector("[data-cc-accept-all]");
|
|
if (accept) accept.addEventListener("click", acceptAll);
|
|
|
|
var reject = b.querySelector("[data-cc-reject]");
|
|
if (reject) reject.addEventListener("click", rejectNonEssential);
|
|
|
|
var save = b.querySelector("[data-cc-save]");
|
|
if (save) save.addEventListener("click", savePreferences);
|
|
|
|
var manage = b.querySelector("[data-cc-manage]");
|
|
if (manage) manage.addEventListener("click", toggleManage);
|
|
}
|
|
|
|
// Public: reopen the consent banner (used by footer / cookie-policy links).
|
|
window.openCookieSettings = function () {
|
|
var existing = readConsent();
|
|
var b = banner();
|
|
if (b && existing) {
|
|
CATEGORIES.forEach(function (c) {
|
|
if (c === "necessary") return;
|
|
var box = b.querySelector('[data-cc-category="' + c + '"]');
|
|
if (box) box.checked = !!existing[c];
|
|
});
|
|
var panel = b.querySelector("[data-cc-panel]");
|
|
if (panel) panel.hidden = false;
|
|
}
|
|
showBanner();
|
|
};
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", init);
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|