/** * Content Blocker – frontend.js * Click-to-load: the real iframe is CREATED only after the user actively * consents per service. Consent is stored in localStorage per service id. */ ( function () { 'use strict'; const STORAGE_PREFIX = 'cb_consent_'; /* ───────────────────────── consent storage ───────────────────────── */ function hasConsent( serviceId ) { try { return localStorage.getItem( STORAGE_PREFIX + serviceId ) === '1'; } catch ( e ) { return false; } } function grantConsent( serviceId ) { try { localStorage.setItem( STORAGE_PREFIX + serviceId, '1' ); } catch ( e ) { // localStorage unavailable; allow the load for this session only. } } /* ───────────────────────── iframe loading ────────────────────────── */ /** Replace a .cb-blocker element with the real iframe. src comes from data-src. */ function loadContent( blockerEl ) { const src = blockerEl.dataset.src; if ( ! src ) { blockerEl.remove(); return; } const iframe = document.createElement( 'iframe' ); if ( blockerEl.dataset.width ) iframe.width = blockerEl.dataset.width; if ( blockerEl.dataset.height ) iframe.height = blockerEl.dataset.height; iframe.setAttribute( 'loading', 'lazy' ); iframe.setAttribute( 'allowfullscreen', '' ); iframe.setAttribute( 'referrerpolicy', 'no-referrer-when-downgrade' ); // Set src last — this is the moment the network request is made. iframe.src = src; blockerEl.parentNode.replaceChild( iframe, blockerEl ); } function loadPreConsented() { document.querySelectorAll( '.cb-blocker[data-cb-id]' ).forEach( function ( el ) { const id = el.dataset.cbId; if ( id && hasConsent( id ) ) { loadContent( el ); } } ); } /* ───────────────────────── consent buttons ───────────────────────── */ function attachButtons() { document.addEventListener( 'click', function ( e ) { const btn = e.target.closest( '.cb-blocker__button' ); if ( ! btn ) return; const serviceId = btn.dataset.cbId; if ( ! serviceId ) return; grantConsent( serviceId ); const wrapper = btn.closest( '.cb-blocker' ); if ( wrapper ) { loadContent( wrapper ); } } ); } /* ───────────────────────── revoke (Art. 7 (3)) ───────────────────── */ window.cbRevokeAll = function () { try { const keysToRemove = []; for ( let i = 0; i < localStorage.length; i++ ) { const key = localStorage.key( i ); if ( key && key.indexOf( STORAGE_PREFIX ) === 0 ) { keysToRemove.push( key ); } } keysToRemove.forEach( function ( k ) { localStorage.removeItem( k ); } ); } catch ( e ) { // Silently ignore if localStorage is unavailable. } window.location.reload(); }; /* ───────────────────────── bootstrap ─────────────────────────────── */ function init() { loadPreConsented(); attachButtons(); } if ( document.readyState === 'loading' ) { document.addEventListener( 'DOMContentLoaded', init ); } else { init(); } } )();