1/** 2 * Do Not Sell My Personal Information â CCPA Banner 3 * Vanilla JS, no dependencies. 4 */ 5( function () { 6 'use strict'; 7 8 var cfg = window.DNSC || {}; 9 10 // ââ Cookie helpers ââââââââââââââââââââââââââââââââââââââââââââââââââââ 11 function setCookie( name, value, days ) { 12 var expires = ''; 13 if ( days ) { 14 var d = new Date(); 15 d.setTime( d.getTime() + days * 24 * 60 * 60 * 1000 ); 16 expires = '; expires=' + d.toUTCString(); 17 } 18 document.cookie = name + '=' + encodeURIComponent( value ) + expires + 19 '; path=/; SameSite=Lax'; 20 } 21 22 function getCookie( name ) { 23 var nameEQ = name + '='; 24 var ca = document.cookie.split( ';' ); 25 for ( var i = 0; i < ca.length; i++ ) { 26 var c = ca[ i ].trim(); 27 if ( c.indexOf( nameEQ ) === 0 ) { 28 return decodeURIComponent( c.substring( nameEQ.length ) ); 29 } 30 } 31 return null; 32 } 33 34 // ââ Apply dynamic colours from PHP settings âââââââââââââââââââââââââââ 35 function applyStyles() { 36 var banner = document.getElementById( 'dnsc-banner' ); 37 if ( ! banner ) return; 38 39 banner.style.backgroundColor = cfg.bgColor || '#1a1a1a'; 40 banner.style.color = cfg.textColor || '#ffffff'; 41 42 var btn = document.getElementById( 'dnsc-optout-btn' ); 43 if ( btn ) { 44 btn.style.backgroundColor = cfg.buttonBg || '#c0392b'; 45 btn.style.color = cfg.buttonTextColor || '#ffffff'; 46 } 47 } 48 49 // ââ Show / hide banner ââââââââââââââââââââââââââââââââââââââââââââââââ 50 function showBanner() { 51 var banner = document.getElementById( 'dnsc-banner' ); 52 if ( ! banner ) return; 53 54 applyStyles(); 55 banner.style.display = ''; 56 57 // Animate in after a tiny paint delay 58 requestAnimationFrame( function () { 59 requestAnimationFrame( function () { 60 banner.classList.add( 'dnsc-visible' ); 61 } ); 62 } ); 63 64 // Modal: show overlay 65 if ( cfg.position === 'modal' ) { 66 var overlay = document.getElementById( 'dnsc-overlay' ); 67 if ( overlay ) overlay.style.display = ''; 68 } 69 } 70 71 function hideBanner( instantly ) { 72 var banner = document.getElementById( 'dnsc-banner' ); 73 if ( ! banner ) return; 74 75 if ( instantly ) { 76 banner.style.display = 'none'; 77 banner.classList.remove( 'dnsc-visible' ); 78 } else { 79 banner.classList.remove( 'dnsc-visible' ); 80 banner.addEventListener( 'transitionend', function handler() { 81 banner.style.display = 'none'; 82 banner.removeEventListener( 'transitionend', handler ); 83 } ); 84 } 85 86 var overlay = document.getElementById( 'dnsc-overlay' ); 87 if ( overlay ) overlay.style.display = 'none'; 88 } 89 90 // ââ Record opt-out via server-side AJAX âââââââââââââââââââââââââââââââ 91 function recordOptOut() { 92 if ( ! cfg.ajaxUrl ) return; 93 94 var formData = new FormData(); 95 formData.append( 'action', 'dnsc_optout' ); 96 formData.append( 'nonce', cfg.nonce || '' ); 97 98 fetch( cfg.ajaxUrl, { 99 method: 'POST', 100 credentials: 'same-origin', 101 body: formData, 102 } ).catch( function ( err ) { 103 // Non-critical â cookie is already set 104 console.warn( '[DNSC] Server record failed:', err ); 105 } ); 106 107 // Optional external webhook 108 if ( cfg.webhookUrl ) { 109 fetch( cfg.webhookUrl, { 110 method: 'POST', 111 headers: { 'Content-Type': 'application/json' }, 112 body: JSON.stringify( { event: 'ccpa_optout', ts: Date.now() } ), 113 mode: 'no-cors', 114 } ).catch( function () {} ); 115 } 116 } 117 118 // ââ Show confirmation message âââââââââââââââââââââââââââââââââââââââââ 119 function showConfirmation() { 120 var actions = document.querySelector( '.dnsc-actions' ); 121 var confirm = document.getElementById( 'dnsc-confirm' ); 122 123 if ( actions ) actions.style.display = 'none'; 124 125 if ( confirm ) { 126 confirm.textContent = cfg.confirmText || 'Your preference has been saved.'; 127 confirm.style.display = ''; 128 } 129 130 // Auto-hide banner after 4 seconds 131 setTimeout( function () { 132 hideBanner( false ); 133 }, 4000 ); 134 } 135 136 // ââ Handle opt-out button click âââââââââââââââââââââââââââââââââââââââ 137 function handleOptOut() { 138 // 1. Set persistent opt-out cookie
139 setCookie( cfg.cookieName || 'dnsc_optout', '1', cfg.cookieDays || 365 ); 140 141 // 2. Dispatch a custom event other scripts can listen to 142 document.dispatchEvent( new CustomEvent( 'dnsc:optout', { bubbles: true } ) ); 143 144 // 3. Record server-side (non-blocking) 145 recordOptOut(); 146 147 // 4. Show confirmation in banner 148 showConfirmation(); 149 } 150 151 // ââ Dismiss (close without opting out) âââââââââââââââââââââââââââââââ 152 function handleDismiss() { 153 // Store a session-level flag so the banner doesn't reappear this visit 154 sessionStorage.setItem( 'dnsc_dismissed', '1' ); 155 hideBanner( false ); 156 } 157 158 // ââ Initialise ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 159 function init() { 160 // Already opted out? Never show. 161 if ( getCookie( cfg.cookieName || 'dnsc_o
161ptout' ) === '1' ) return; 162 163 // Dismissed this session? 164 if ( sessionStorage && sessionStorage.getItem( 'dnsc_dismissed' ) === '1' ) return; 165 166 // Bind buttons 167 var optOutBtn = document.getElementById( 'dnsc-optout-btn' ); 168 var closeBtn = document.getElementById( 'dnsc-close-btn' ); 169 170 if ( optOutBtn ) optOutBtn.addEventListener( 'click', handleOptOut ); 171 if ( closeBtn ) closeBtn.addEventListener( 'click', handleDismiss ); 172 173 // Close modal on overlay click 174 var overlay = document.getElementById( 'dnsc-overlay' ); 175 if ( overlay ) overlay.addEventListener( 'click', handleDismiss ); 176 177 // Keyboard: Escape closes banner 178 document.addEventListener( 'keydown', function ( e ) { 179 if ( e.key === 'Escape' ) handleDismiss(); 180 } ); 181 182 // Small delay before showing â avoids layout flash on page load 183 // setTimeout( showBanner, 800 ); 184 185 // Select ALL links with the class '.dnsmi-btn' 186 const dnsmiButton = document.querySelectorAll('.dnsmi-btn'); 187 // Loop through each links to add an event listener 188 dnsmiButton.forEach(link => { link.addEventListener('click', showBanner); }); 189 } 190 191 if ( document.readyState === 'loading' ) { 192 document.addEventListener( 'DOMContentLoaded', init ); 193 } else { 194 init(); 195 } 196 197 198 function adjustDivHeight() { 199 const div1 = document.querySelector('.cky-consent-container'); 200 const div2 = document.querySelector('#dnsc-banner'); 201 202 if (div1) { 203 //console.log(div1.offsetHeight); 204 div2.style.bottom = (div1.offsetHeight + 50 + 'px'); 205 } 206 } 207 208 document.addEventListener('DOMContentLoaded', adjustDivHeight); 209 window.addEventListener('resize', adjustDivHeight); 210} )();
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.