1/** 2 * LaunchPass Cookie Consent Manager 3 * GDPR/CCPA compliance for cookie consent 4 * 5 * Shows consent banner to users in regulated jurisdictions (CA, UK, EU) 6 * and conditionally loads tracking scripts based on user consent. 7 */ 8(function(window, document) { 9 'use strict'; 10 11 // Configuration 12 const CONFIG = { 13 CONSENT_COOKIE: 'lpconsent', 14 NO_CONSENT_COOKIE: 'lpnoconsent', 15 COOKIE_DOMAIN: window.location.hostname.includes('launchpass.com') ? '.launchpass.com' : '', 16 COOKIE_EXPIRES_DAYS: 365 17 }; 18 19 // Debug logging 20 const DEBUG = true; 21 const log = DEBUG ? console.log.bind(console, '[CookieConsent]') : () => {}; 22 23 class CookieConsentManager { 24 constructor() { 25 this.init(); 26 } 27 28 init() { 29 log('Initializing cookie consent helper'); 30 31 // If consent already exists, do nothing (PHP will handle loading scripts) 32 if (this.hasConsentCookie()) { 33 log('Consent cookie present; nothing to do'); 34 return; 35 } 36 37 // If user already declined, keep trackers blocked on client as a safeguard and do not show banner again 38 if (this.hasNoConsentCookie()) { 39 log('User has previously declined consent; keeping trackers blocked'); 40 this.blockTrackers(); 41 return; 42 } 43 44 // Decision, banner, and auto-approval are handled by inline script in functions.php 45 log('Consent decision handled by server-injected inline script'); 46 } 47 48 49 hasConsentCookie() { 50 return this.getCookie(CONFIG.CONSENT_COOKIE) === '1'; 51 } 52 53 hasNoConsentCookie() { 54 return this.getCookie(CONFIG.NO_CONSENT_COOKIE) === '1'; 55 } 56 57 getCookie(name) { 58 const value = `; ${document.cookie}`; 59 const parts = value.split(`; ${name}=`); 60 if (parts.length === 2) { 61 return parts.pop().split(';').shift(); 62 } 63 return null; 64 } 65 66 setCookie(name, value, days) { 67 const expires = new Date(); 68 expires.setTime(expires.getTime() + (days * 24 * 60 * 60 * 1000)); 69 const domain = CONFIG.COOKIE_DOMAIN ? `; domain=${CONFIG.COOKIE_DOMAIN}` : ''; 70 document.cookie = `${name}=${value}; expires=${expires.toUTCString()}; path=/${domain}; SameSite=Lax; Secure`; 71 } 72 73 // Banner rendering and consent handling are managed by inline script in functions.php 74 75 blockTrackers() { 76 log('Blocking trackers'); 77 78 // Set global flags 79 window.lpConsentGiven = false; 80 window.lpTrackersBlocked = true; 81 82 // Block common tracker functions 83 this.blockCommonTrackers(); 84 85 this.dispatchConsentEvent('block-trackers'); 86 } 87 88 blockCommonTrackers() { 89 // Create noop functions for common tracking methods 90 const noop = () => {}; 91 92 // Block Google Analytics 93 if (!window.gtag) { 94 window.gtag = noop; 95 window.ga = noop; 96 } 97 98 // Block Facebook Pixel 99 if (!window.fbq) { 100 window.fbq = noop; 101 } 102 103 // Block other common trackers 104 if (!window.mixpanel) { 105 window.mixpanel = { init: noop, track: noop, identify: noop }; 106 } 107 108 // Block Twitter tracking 109 if (!window.twq) { 110 window.twq = noop; 111 } 112 113 // Block TikTok tracking 114 if (!window.ttq) { 115 window.ttq = noop; 116 } 117 118 // Block Reddit tracking 119 if (!window.rdt) { 120 window.rdt = noop; 121 } 122 123 // Block Microsoft/Bing tracking 124 if (!window.uetq) { 125 window.uetq = []; 126 } 127 } 128 129 // No event bus; consent UI and decision flow are handled by server-injected inline script 130 131 // Public API methods 132 static hasConsent() { 133 const instance = window.lpCookieConsent; 134 return instance ? instance.hasConsentCookie() : false; 135 } 136 137 static withdraw() { 138 const instance = window.lpCookieConsent; 139 if (instance) { 140 instance.setCookie(CONFIG.NO_CONSENT_COOKIE, '1', CONFIG.COOKIE_EXPIRES_DAYS); 141 instance.setCookie(CONFIG.CONSENT_COOKIE, '', -1); // Remove consent cookie 142 instance.blockTrackers(); 143 window.location.reload(); 144 } 145 } 146 147 static showBanner() { 148 // No-op; banner is rendered by inline script in functions.php when needed 149 } 150 } 151 152 // Initialize when DOM is ready 153 function initializeConsentManager() { 154 if (window.lpCookieConsent) { 155 log('Cookie consent manager already initialized'); 156 return; 157 } 158 159 window.lpCookieConsent = new CookieConsentManager(); 160 161 // Expose public API 162 window.LaunchPassConsent = { 163 hasConsent: CookieConsentManager.hasConsent, 164 withdraw: CookieConsentManager.withdraw, 165 showBanner: CookieConsentManager.showBanner 166 }; 167 } 168 169 // Initialize immediately if DOM is already loaded, otherwise wait 170 if (document.readyState === 'loading') { 171 document.addEventListener('DOMContentLoaded', initializeConsentManager); 172 } else { 173 console.log('Initializing cookie consent manager'); 174 initializeConsentManager(); 175 } 176 177 // Also initialize on window load as fallback 178 window.addEventListener('load', function() { 179 if (!window.lpCookieConsent) { 180 initializeConsentManager(); 181 } 182 }); 183 184})(window, document);
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.