457 lines
16 KiB
JavaScript
457 lines
16 KiB
JavaScript
/**
|
|
* GDPR Cookie Consent Module for PrestaShop
|
|
*
|
|
* @author Walzen665
|
|
* @copyright Copyright (c) 2025
|
|
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
|
*/
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Store for blocked scripts
|
|
const scriptStore = {
|
|
functional: [],
|
|
analytics: [],
|
|
marketing: []
|
|
};
|
|
|
|
// Cookie functions
|
|
function setCookie(name, value, days) {
|
|
var expires = '';
|
|
if (days) {
|
|
var date = new Date();
|
|
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
|
expires = '; expires=' + date.toUTCString();
|
|
}
|
|
document.cookie = name + '=' + (value || '') + expires + '; path=/; SameSite=Lax';
|
|
}
|
|
|
|
function getCookie(name) {
|
|
var nameEQ = name + '=';
|
|
var ca = document.cookie.split(';');
|
|
for (var i = 0; i < ca.length; i++) {
|
|
var c = ca[i];
|
|
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
|
|
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Show manage preferences button when cookies are already set
|
|
function showManageButton() {
|
|
document.getElementById('gdpr-cookie-manage-button').style.display = 'block';
|
|
}
|
|
|
|
// After user consents, hide banner and modal and show the manage button
|
|
function afterConsent() {
|
|
// Hide banner and modal
|
|
hideModal();
|
|
document.getElementById('gdpr-cookie-banner').style.display = 'none';
|
|
|
|
// Show manage button
|
|
showManageButton();
|
|
}
|
|
|
|
// Block scripts based on type
|
|
function blockScripts() {
|
|
// Find and process script tags with data-cookieconsent attribute
|
|
const scripts = document.querySelectorAll('script[data-cookieconsent]');
|
|
|
|
scripts.forEach(script => {
|
|
const consentType = script.getAttribute('data-cookieconsent');
|
|
|
|
if (!consentType || consentType === 'necessary') {
|
|
// Necessary scripts always run
|
|
return;
|
|
}
|
|
|
|
// Store script information
|
|
const scriptData = {
|
|
src: script.getAttribute('src'),
|
|
content: script.innerHTML,
|
|
type: script.getAttribute('type') || 'text/javascript',
|
|
async: script.async,
|
|
defer: script.defer
|
|
};
|
|
|
|
// Add to appropriate store
|
|
if (scriptStore[consentType]) {
|
|
scriptStore[consentType].push(scriptData);
|
|
}
|
|
|
|
// Remove the script from DOM
|
|
script.parentNode.removeChild(script);
|
|
});
|
|
|
|
// Also block iframe embeds with data-cookieconsent attribute
|
|
const iframes = document.querySelectorAll('iframe[data-cookieconsent]');
|
|
|
|
iframes.forEach(iframe => {
|
|
const consentType = iframe.getAttribute('data-cookieconsent');
|
|
|
|
if (!consentType || consentType === 'necessary') {
|
|
// Necessary iframes always load
|
|
return;
|
|
}
|
|
|
|
// Create placeholder
|
|
const placeholder = document.createElement('div');
|
|
placeholder.className = 'gdpr-blocked-content-placeholder';
|
|
placeholder.setAttribute('data-cookieconsent', consentType);
|
|
placeholder.setAttribute('data-src', iframe.getAttribute('src'));
|
|
placeholder.style.width = iframe.width + 'px' || '100%';
|
|
placeholder.style.height = iframe.height + 'px' || '150px';
|
|
placeholder.style.border = '1px dashed #ccc';
|
|
placeholder.style.display = 'flex';
|
|
placeholder.style.alignItems = 'center';
|
|
placeholder.style.justifyContent = 'center';
|
|
placeholder.style.backgroundColor = '#f9f9f9';
|
|
placeholder.style.color = '#666';
|
|
placeholder.innerHTML = `<div>
|
|
<p>Content blocked due to ${consentType} cookies preferences</p>
|
|
<button class="gdpr-load-blocked-content" data-type="${consentType}">Load content</button>
|
|
</div>`;
|
|
|
|
// Replace iframe with placeholder
|
|
iframe.parentNode.replaceChild(placeholder, iframe);
|
|
});
|
|
|
|
// Add event listeners to load content buttons
|
|
document.querySelectorAll('.gdpr-load-blocked-content').forEach(button => {
|
|
button.addEventListener('click', function(e) {
|
|
const type = this.getAttribute('data-type');
|
|
const placeholder = this.closest('.gdpr-blocked-content-placeholder');
|
|
|
|
if (placeholder) {
|
|
// Get iframe src
|
|
const src = placeholder.getAttribute('data-src');
|
|
|
|
// Create iframe
|
|
const iframe = document.createElement('iframe');
|
|
iframe.src = src;
|
|
iframe.width = placeholder.style.width;
|
|
iframe.height = placeholder.style.height;
|
|
iframe.frameBorder = '0';
|
|
|
|
// Replace placeholder with iframe
|
|
placeholder.parentNode.replaceChild(iframe, placeholder);
|
|
|
|
// Update consent for this content type
|
|
const preferences = JSON.parse(getCookie('gdpr_cookie_consent') || '{"necessary":true}');
|
|
preferences[type] = true;
|
|
setCookie('gdpr_cookie_consent', JSON.stringify(preferences), 365);
|
|
|
|
// Update checkboxes in modal if it exists
|
|
const checkbox = document.querySelector(`#gdpr-cookie-${type}`);
|
|
if (checkbox) {
|
|
checkbox.checked = true;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Load scripts based on consent
|
|
function loadConsentedScripts(preferences) {
|
|
// For each script type
|
|
Object.keys(scriptStore).forEach(type => {
|
|
if (preferences[type]) {
|
|
// Load all scripts of this type
|
|
scriptStore[type].forEach(scriptData => {
|
|
const script = document.createElement('script');
|
|
|
|
if (scriptData.src) {
|
|
script.src = scriptData.src;
|
|
}
|
|
|
|
script.type = scriptData.type;
|
|
script.async = scriptData.async;
|
|
script.defer = scriptData.defer;
|
|
|
|
if (scriptData.content) {
|
|
script.innerHTML = scriptData.content;
|
|
}
|
|
|
|
document.head.appendChild(script);
|
|
});
|
|
|
|
// Clear the store for this type
|
|
scriptStore[type] = [];
|
|
}
|
|
});
|
|
|
|
// Also load blocked iframes
|
|
document.querySelectorAll('.gdpr-blocked-content-placeholder').forEach(placeholder => {
|
|
const type = placeholder.getAttribute('data-cookieconsent');
|
|
|
|
if (preferences[type]) {
|
|
// Get iframe src
|
|
const src = placeholder.getAttribute('data-src');
|
|
|
|
// Create iframe
|
|
const iframe = document.createElement('iframe');
|
|
iframe.src = src;
|
|
iframe.width = placeholder.style.width;
|
|
iframe.height = placeholder.style.height;
|
|
iframe.frameBorder = '0';
|
|
|
|
// Replace placeholder with iframe
|
|
placeholder.parentNode.replaceChild(iframe, placeholder);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Check if cookie consent is already set
|
|
var cookieConsent = getCookie('gdpr_cookie_consent');
|
|
|
|
// Always block non-necessary scripts first
|
|
blockScripts();
|
|
|
|
if (!cookieConsent) {
|
|
// Show the cookie banner if consent is not set
|
|
document.getElementById('gdpr-cookie-banner').style.display = 'block';
|
|
} else {
|
|
// Apply cookie preferences
|
|
var consentPreferences = JSON.parse(cookieConsent);
|
|
applyConsentPreferences(consentPreferences);
|
|
|
|
// Show the manage button since consent was already given
|
|
showManageButton();
|
|
}
|
|
|
|
// Banner buttons
|
|
document.getElementById('gdpr-cookie-banner-accept').addEventListener('click', function() {
|
|
acceptAllCookies();
|
|
});
|
|
|
|
if(!gdprCookieOnlyRequired) {
|
|
document.getElementById('gdpr-cookie-banner-decline').addEventListener('click', function() {
|
|
declineAllCookies();
|
|
});
|
|
}
|
|
|
|
document.getElementById('gdpr-cookie-banner-settings').addEventListener('click', function() {
|
|
showModal();
|
|
});
|
|
|
|
// Modal buttons
|
|
if(!gdprCookieOnlyRequired) {
|
|
document.getElementById('gdpr-cookie-decline').addEventListener('click', function() {
|
|
declineAllCookies();
|
|
});
|
|
|
|
document.getElementById('gdpr-cookie-accept-selected').addEventListener('click', function() {
|
|
acceptSelectedCookies();
|
|
});
|
|
}
|
|
|
|
document.getElementById('gdpr-cookie-accept-all').addEventListener('click', function() {
|
|
acceptAllCookies();
|
|
});
|
|
|
|
// Manage button (for after consent is given)
|
|
document.getElementById('gdpr-cookie-manage').addEventListener('click', function() {
|
|
showModal();
|
|
});
|
|
|
|
// Functions
|
|
function showModal() {
|
|
document.getElementById('gdpr-cookie-banner').style.display = 'none';
|
|
document.getElementById('gdpr-cookie-modal').style.display = 'block';
|
|
|
|
// Load saved preferences if they exist
|
|
var cookieConsent = getCookie('gdpr_cookie_consent');
|
|
if (cookieConsent) {
|
|
var preferences = JSON.parse(cookieConsent);
|
|
|
|
// Set checkboxes based on saved preferences
|
|
document.querySelectorAll('.gdpr-cookie-checkbox').forEach(function(checkbox) {
|
|
var category = checkbox.getAttribute('data-cookie-category');
|
|
if (preferences[category]) {
|
|
checkbox.checked = true;
|
|
} else {
|
|
checkbox.checked = false;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function hideModal() {
|
|
document.getElementById('gdpr-cookie-modal').style.display = 'none';
|
|
}
|
|
|
|
function acceptAllCookies() {
|
|
var preferences = {
|
|
necessary: true,
|
|
functional: true,
|
|
analytics: true,
|
|
marketing: true
|
|
};
|
|
|
|
setCookie('gdpr_cookie_consent', JSON.stringify(preferences), 365);
|
|
applyConsentPreferences(preferences);
|
|
afterConsent(); // Use the new function for consistent post-consent behavior
|
|
}
|
|
|
|
function declineAllCookies() {
|
|
var preferences = {
|
|
necessary: true, // Necessary cookies are always accepted
|
|
functional: false,
|
|
analytics: false,
|
|
marketing: false
|
|
};
|
|
|
|
setCookie('gdpr_cookie_consent', JSON.stringify(preferences), 365);
|
|
applyConsentPreferences(preferences);
|
|
afterConsent(); // Use the new function for consistent post-consent behavior
|
|
}
|
|
|
|
function acceptSelectedCookies() {
|
|
var preferences = {
|
|
necessary: true // Necessary cookies are always accepted
|
|
};
|
|
|
|
// Get selected preferences
|
|
document.querySelectorAll('.gdpr-cookie-checkbox').forEach(function(checkbox) {
|
|
var category = checkbox.getAttribute('data-cookie-category');
|
|
preferences[category] = checkbox.checked;
|
|
});
|
|
|
|
setCookie('gdpr_cookie_consent', JSON.stringify(preferences), 365);
|
|
applyConsentPreferences(preferences);
|
|
afterConsent(); // Use the new function for consistent post-consent behavior
|
|
}
|
|
|
|
function applyConsentPreferences(preferences) {
|
|
// Load consented scripts
|
|
loadConsentedScripts(preferences);
|
|
|
|
// Functional cookies
|
|
if (!preferences.functional) {
|
|
// Disable functional cookies
|
|
removeFunctionalCookies();
|
|
}
|
|
|
|
// Analytics cookies
|
|
if (!preferences.analytics) {
|
|
// Disable analytics cookies (like Google Analytics)
|
|
disableAnalytics();
|
|
} else {
|
|
// Enable analytics
|
|
enableAnalytics();
|
|
}
|
|
|
|
// Marketing cookies
|
|
if (!preferences.marketing) {
|
|
// Disable marketing cookies
|
|
disableMarketing();
|
|
} else {
|
|
// Enable marketing
|
|
enableMarketing();
|
|
}
|
|
}
|
|
|
|
// Helper functions to implement consent preferences
|
|
function removeFunctionalCookies() {
|
|
// This is just an example - implement based on your specific needs
|
|
var functionalCookies = ['prefs', 'language', 'theme', 'user_preferences'];
|
|
var domains = [window.location.hostname, '.' + window.location.hostname];
|
|
|
|
functionalCookies.forEach(function(cookie) {
|
|
domains.forEach(function(domain) {
|
|
document.cookie = cookie + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=' + domain;
|
|
});
|
|
});
|
|
}
|
|
|
|
function disableAnalytics() {
|
|
// Google Analytics
|
|
window['ga-disable-UA-XXXXXXXX-X'] = true;
|
|
window['ga-disable-G-XXXXXXXX'] = true;
|
|
|
|
// Remove existing GA cookies
|
|
var analyticsCookies = ['_ga', '_gid', '_gat', '__utma', '__utmb', '__utmc', '__utmt', '__utmz', '_hjid', '_hjAbsoluteSessionInProgress'];
|
|
var domains = [window.location.hostname, '.' + window.location.hostname];
|
|
|
|
analyticsCookies.forEach(function(cookie) {
|
|
domains.forEach(function(domain) {
|
|
document.cookie = cookie + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=' + domain;
|
|
});
|
|
});
|
|
}
|
|
|
|
function enableAnalytics() {
|
|
// Google Analytics
|
|
window['ga-disable-UA-XXXXXXXX-X'] = false;
|
|
window['ga-disable-G-XXXXXXXX'] = false;
|
|
}
|
|
|
|
function disableMarketing() {
|
|
// Common marketing cookies
|
|
var marketingCookies = ['_fbp', 'fr', 'IDE', 'MUID', 'personalization_id', 'VISITOR_INFO1_LIVE', 'YSC', 'NID'];
|
|
var domains = [window.location.hostname, '.' + window.location.hostname, '.google.com', '.facebook.com', '.youtube.com'];
|
|
|
|
marketingCookies.forEach(function(cookie) {
|
|
domains.forEach(function(domain) {
|
|
document.cookie = cookie + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Domain=' + domain;
|
|
});
|
|
});
|
|
}
|
|
|
|
function enableMarketing() {
|
|
// For enabling marketing, we load the scripts that were blocked
|
|
// This happens in the loadConsentedScripts function
|
|
}
|
|
|
|
// Function to detect which script is associated with each cookie category
|
|
function detectThirdPartyScripts() {
|
|
// This function would scan the page for known third-party scripts
|
|
// and auto-assign data-cookieconsent attributes
|
|
const knownScriptPatterns = {
|
|
analytics: [
|
|
/google-analytics\.com\/analytics\.js/i,
|
|
/googletagmanager\.com\/gtag/i,
|
|
/google-analytics\.com\/ga\.js/i,
|
|
/hotjar\.com/i,
|
|
/analytics/i,
|
|
/matomo/i,
|
|
/stats/i
|
|
],
|
|
marketing: [
|
|
/facebook\.net/i,
|
|
/doubleclick\.net/i,
|
|
/googlesyndication\.com/i,
|
|
/ads/i,
|
|
/adservices/i,
|
|
/pixel/i,
|
|
/track/i
|
|
],
|
|
functional: [
|
|
/recaptcha/i,
|
|
/fonts\.googleapis\.com/i,
|
|
/cloudflare/i,
|
|
/cdn/i,
|
|
/livechat/i,
|
|
/chat/i,
|
|
/support/i
|
|
]
|
|
};
|
|
|
|
const scripts = document.querySelectorAll('script:not([data-cookieconsent])');
|
|
|
|
scripts.forEach(script => {
|
|
if (!script.src) return; // Skip inline scripts
|
|
|
|
for (const [category, patterns] of Object.entries(knownScriptPatterns)) {
|
|
for (const pattern of patterns) {
|
|
if (pattern.test(script.src)) {
|
|
script.setAttribute('data-cookieconsent', category);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Run script detection
|
|
detectThirdPartyScripts();
|
|
}); |