import Cookies from "js-cookie";
class ConsentManager {
// Options should contain the following keys:
// - modal - HTML element of the data consent modal (e.g. "
Foo bar
")
// - categories - Available data consent categories (e.g. ["essential", "preferences", "analytics", "marketing"])
// - cookieName - Name of the cookie saved in the browser (e.g. "decidim-consent")
// - warningElement - HTML element to be shown when user has not given the necessary data consent to display the content.
constructor(options) {
this.modal = options.modal;
this.categories = options.categories;
this.cookieName = options.cookieName;
this.cookie = Cookies.get(this.cookieName);
this.warningElement = options.warningElement;
if (this.cookie) {
this.updateState(JSON.parse(this.cookie));
} else {
this.updateState({});
}
}
updateState(newState) {
this.state = newState;
Cookies.set(this.cookieName, JSON.stringify(this.state), {
domain: document.location.host.split(":")[0],
sameSite: "Lax",
expires: 365,
secure: window.location.protocol === "https:"
});
this.updateModalSelections();
this.triggerState();
}
triggerJavaScripts() {
document.querySelectorAll("script[type='text/plain'][data-consent]").forEach((script) => {
if (this.state[script.dataset.consent]) {
const activeScript = document.createElement("script");
if (script.src.length > 0) {
activeScript.src = script.src;
} else {
activeScript.innerHTML = script.innerHTML;
}
script.parentNode.replaceChild(activeScript, script);
}
});
const event = new CustomEvent("dataconsent", { detail: this.state });
document.dispatchEvent(event);
}
triggerIframes() {
if (this.allAccepted()) {
document.querySelectorAll(".disabled-iframe").forEach((original) => {
if (original.childNodes && original.childNodes.length) {
const content = Array.from(original.childNodes).find((childNode) => {
return childNode.nodeType === Node.COMMENT_NODE;
});
if (!content) {
return;
}
const newElement = document.createElement("div");
newElement.innerHTML = content.nodeValue;
original.parentNode.replaceChild(newElement.firstElementChild, original);
}
});
} else {
document.querySelectorAll("iframe").forEach((original) => {
const newElement = document.createElement("div");
newElement.className = "disabled-iframe";
newElement.appendChild(document.createComment(`${original.outerHTML}`));
original.parentNode.replaceChild(newElement, original);
});
}
}
triggerWarnings() {
document.querySelectorAll(".disabled-iframe").forEach((original) => {
if (original.querySelector(".dataconsent-warning")) {
return;
}
let cloned = this.warningElement.cloneNode(true);
cloned.classList.remove("hide");
original.appendChild(cloned);
});
}
triggerState() {
this.triggerJavaScripts();
this.triggerIframes();
this.triggerWarnings();
}
allAccepted() {
return this.categories.every((category) => {
return this.state[category] === true;
});
}
updateModalSelections() {
const categoryElements = this.modal.querySelectorAll(".category-wrapper");
categoryElements.forEach((categoryEl) => {
const categoryInput = categoryEl.querySelector("input");
if (this.state && this.state[categoryInput.name]) {
categoryInput.checked = true;
} else if (!categoryInput.disabled) {
categoryInput.checked = false;
}
});
}
saveSettings(newState) {
this.updateState(newState);
}
acceptAll() {
const newState = {};
this.categories.forEach((category) => {
newState[category] = true;
});
this.updateState(newState);
}
rejectAll() {
this.updateState({
essential: true
});
}
getState() {
return this.state;
}
}
export default ConsentManager