/** * 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 = `

Content blocked due to ${consentType} cookies preferences

`; // 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(); });