From 6fa41fb3a67f00216ee544a489a043906912ea61 Mon Sep 17 00:00:00 2001 From: s4luorth Date: Mon, 8 Jun 2026 13:30:59 +0200 Subject: [PATCH] fix: kein weissraum unter blocker + originalgroesse nach einwilligung (v1.4.4) Der weissraum kam nicht von meinem platzhalter, sondern vom seitenverhaeltnis- container (z. B. Elementor .e-youtube-base mit 16:9, oder wp-block-embed aspect-ratio) - das reserviert die hoehe per CSS, unabhaengig vom inhalt. - collapseAncestors(): bekannte aspect-ratio/video-wrapper um einen platzhalter werden eingeklappt (aspect-ratio/min-height/height auto !important), solange der blocker steht -> kein leerraum darunter. Laeuft fuer server-platzhalter (autodetect) und JS-gebaute (Elementor-widgets). - restoreCollapsed(): bei einwilligung wird die reservierung wieder entfernt, sodass das embed in originalgroesse laedt. - Elementor JS-widgets (e-youtube-base etc.) nutzen jetzt durchgaengig den reload-pfad bei einwilligung -> Elementor rendert das video nativ in voller originalgroesse statt eines geratenen iframes. + version 1.4.4 (assets cache-busting). Co-Authored-By: Claude Opus 4.8 --- gdpr-content-blocker/assets/frontend.js | 65 ++++++++++++++++--- gdpr-content-blocker/gdpr-content-blocker.php | 4 +- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/gdpr-content-blocker/assets/frontend.js b/gdpr-content-blocker/assets/frontend.js index 3374bdb..a09dbc1 100644 --- a/gdpr-content-blocker/assets/frontend.js +++ b/gdpr-content-blocker/assets/frontend.js @@ -46,6 +46,45 @@ window.location.reload(); }; + /* ─────────────── height-reservation (no whitespace) ─────────────── */ + + // Wrappers that force a fixed aspect ratio / height around an embed. While the + // placeholder is shown we collapse them so there is no empty space; on consent + // we restore them so the real embed loads at its original size. + const WRAP_SEL = '.e-youtube-base, .e-vimeo-base, .elementor-fit-aspect-ratio, ' + + '.elementor-open-inline, .elementor-wrapper, .wp-has-aspect-ratio, ' + + '.wp-block-embed__wrapper, .elementor-widget-video'; + + function collapseAncestors( blocker ) { + let el = blocker.parentElement; + let n = 0; + while ( el && n < 6 ) { + if ( el.matches && el.matches( WRAP_SEL ) ) { + el.setAttribute( 'data-cb-collapsed', '1' ); + el.style.setProperty( 'aspect-ratio', 'auto', 'important' ); + el.style.setProperty( 'min-height', '0', 'important' ); + el.style.setProperty( 'height', 'auto', 'important' ); + } + el = el.parentElement; + n++; + } + } + + function restoreCollapsed( node ) { + let el = node.parentElement; + let n = 0; + while ( el && n < 6 ) { + if ( el.getAttribute && el.getAttribute( 'data-cb-collapsed' ) === '1' ) { + el.style.removeProperty( 'aspect-ratio' ); + el.style.removeProperty( 'min-height' ); + el.style.removeProperty( 'height' ); + el.removeAttribute( 'data-cb-collapsed' ); + } + el = el.parentElement; + n++; + } + } + /* ───────────────────────── iframe loading ────────────────────────── */ /** Replace a .cb-blocker element with the real iframe. src comes from data-src. */ @@ -56,6 +95,9 @@ return; } + // Give the wrappers their reserved size back so the embed loads full-size. + restoreCollapsed( blockerEl ); + const iframe = document.createElement( 'iframe' ); if ( blockerEl.dataset.width ) iframe.width = blockerEl.dataset.width; @@ -266,6 +308,7 @@ const placeholder = buildPlaceholder( svc, rawSrc, dims ); if ( iframe.parentNode ) { iframe.parentNode.replaceChild( placeholder, iframe ); + collapseAncestors( placeholder ); } } @@ -345,17 +388,19 @@ widget.removeAttribute( 'data-settings' ); const placeholder = buildPlaceholder( svc, embed, {} ); - // No embed URL → we can't build the iframe ourselves. Make the button - // grant consent and reload; Elementor then renders the video normally - // (scripts are released after consent). Drop the "load once" option. - if ( ! embed ) { - placeholder.setAttribute( 'data-cb-reload', '1' ); - const remember = placeholder.querySelector( '.cb-blocker__remember' ); - if ( remember ) remember.remove(); - } + // These widgets are built entirely by JS (no server iframe we could + // catch). Rather than guess the embed size, reload on consent so + // Elementor renders the player natively at its ORIGINAL size. Drop the + // "load once" option (it can't apply here). + placeholder.setAttribute( 'data-cb-reload', '1' ); + const remember = placeholder.querySelector( '.cb-blocker__remember' ); + if ( remember ) remember.remove(); container.innerHTML = ''; container.appendChild( placeholder ); + // Collapse the wrapper's reserved aspect height so there is no + // whitespace while the (small) placeholder is shown. + collapseAncestors( placeholder ); } ); } @@ -388,6 +433,10 @@ handleElementorVideos(); scanExistingIframes(); startObserver(); + // Collapse the reserved aspect height around every remaining placeholder + // (also the server-rendered ones from the PHP autodetect) so the blocker + // shows no empty space below it. + document.querySelectorAll( '.cb-blocker' ).forEach( collapseAncestors ); } if ( document.readyState === 'loading' ) { diff --git a/gdpr-content-blocker/gdpr-content-blocker.php b/gdpr-content-blocker/gdpr-content-blocker.php index 00bd881..614c8cf 100644 --- a/gdpr-content-blocker/gdpr-content-blocker.php +++ b/gdpr-content-blocker/gdpr-content-blocker.php @@ -3,7 +3,7 @@ * Plugin Name: GDPR Content Blocker * Plugin URI: https://lucas-orth.de * Description: DSGVO-konformer Consent-Blocker für externe iframes. Lädt Drittinhalte erst nach aktiver Einwilligung. - * Version: 1.4.3 + * Version: 1.4.4 * Author: Lucas Orth * Author URI: https://lucas-orth.de * Text Domain: gdpr-content-blocker @@ -15,7 +15,7 @@ defined( 'ABSPATH' ) || exit; -define( 'CB_VERSION', '1.4.3' ); +define( 'CB_VERSION', '1.4.4' ); define( 'CB_FILE', __FILE__ ); define( 'CB_DIR', plugin_dir_path( __FILE__ ) ); define( 'CB_URL', plugin_dir_url( __FILE__ ) );