fix: elementor-youtube-widget (per JS gebaut) zuverlaessig erkennen
Nach dem script-blocking blieb ein per YouTube-iframe_api gebautes
Elementor-video leer: die API wird blockiert, also baut Elementor kein
iframe -> mein iframe-basierter platzhalter griff nicht, und das
data-settings enthielt nur {"video_type":"youtube"} (keine URL).
videoUrlForWidget() findet die video-URL jetzt aus mehreren quellen:
- explizite keys (youtube_url/vimeo_url/...) im data-settings
- beliebige youtube/vimeo-URL im data-settings (regex, escaped slashes)
- bereits server-gerendertes iframe im widget
- YouTube-thumbnail (i.ytimg.com/vi/ID/) bei lazyload/overlay-modus
Greift auch fuer .elementor-widget[data-widget_type^="video"] und ueberspringt
widgets, die der server-autodetect schon zum platzhalter gemacht hat.
Extraktions-logik isoliert getestet (thumbnail, escaped-json, vimeo).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -261,17 +261,61 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** Elementor video widgets store the URL in data-settings and build the
|
||||
* player via JS — handle them before that happens. */
|
||||
/** Reconstruct a YouTube watch URL from a thumbnail (i.ytimg.com/vi/ID/…). */
|
||||
function ytIdFromThumb( s ) {
|
||||
const m = String( s || '' ).match( /(?:i\.ytimg\.com|img\.youtube\.com)\/vi\/([\w-]{6,})\// );
|
||||
return m ? m[ 1 ] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the embedded video URL of an Elementor video widget. Elementor often
|
||||
* does NOT put the URL in data-settings (only {"video_type":"youtube"}) and
|
||||
* builds the player via the JS API — so we look in several places.
|
||||
*/
|
||||
function videoUrlForWidget( widget ) {
|
||||
const ds = widget.getAttribute( 'data-settings' ) || '';
|
||||
|
||||
// 1) Explicit URL keys in data-settings (older/other Elementor versions).
|
||||
try {
|
||||
const s = JSON.parse( ds || '{}' );
|
||||
const u = s.youtube_url || s.vimeo_url || s.video_url || s.external_url
|
||||
|| s.hosted_url || ( s.link && s.link.url ) || '';
|
||||
if ( u ) return u;
|
||||
} catch ( e ) { /* not JSON / no keys */ }
|
||||
|
||||
// 2) Any youtube/vimeo URL anywhere in the data-settings string (JSON values
|
||||
// are quoted, so stop at a quote/space; tolerate escaped slashes \/).
|
||||
const m = ds.match( /https?:[^"\s]*?(?:youtube\.com|youtu\.be|vimeo\.com)[^"\s]*/i );
|
||||
if ( m ) return m[ 0 ].replace( /\\\//g, '/' ).replace( /\\/g, '' );
|
||||
|
||||
// 3) A server-rendered iframe already inside the widget.
|
||||
const ifr = widget.querySelector( 'iframe[src]' );
|
||||
if ( ifr ) return ifr.getAttribute( 'src' );
|
||||
|
||||
// 4) A YouTube thumbnail (lazyload / image-overlay mode) → rebuild the URL.
|
||||
const thumb = widget.querySelector(
|
||||
'img[src*="ytimg.com/vi/"], img[src*="img.youtube.com/vi/"], [style*="ytimg.com/vi/"]'
|
||||
);
|
||||
if ( thumb ) {
|
||||
const id = ytIdFromThumb( thumb.getAttribute( 'src' ) || thumb.getAttribute( 'style' ) || '' );
|
||||
if ( id ) return 'https://www.youtube.com/watch?v=' + id;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/** Elementor video widgets build the player via JS — replace them with our
|
||||
* consent placeholder before that happens. */
|
||||
function handleElementorVideos() {
|
||||
document.querySelectorAll( '.elementor-widget-video[data-settings]' ).forEach( function ( widget ) {
|
||||
let settings;
|
||||
try {
|
||||
settings = JSON.parse( widget.dataset.settings );
|
||||
} catch ( e ) {
|
||||
return;
|
||||
}
|
||||
const raw = settings.youtube_url || settings.vimeo_url || settings.external_url || '';
|
||||
const widgets = document.querySelectorAll(
|
||||
'.elementor-widget-video, .elementor-widget[data-widget_type^="video"]'
|
||||
);
|
||||
widgets.forEach( function ( widget ) {
|
||||
const container = widget.querySelector( '.elementor-widget-container' ) || widget;
|
||||
// Already turned into a placeholder (e.g. by the server-side autodetect
|
||||
// catching a rendered iframe) → leave it.
|
||||
if ( container.querySelector( '.cb-blocker' ) ) return;
|
||||
|
||||
const raw = videoUrlForWidget( widget );
|
||||
if ( ! raw ) return;
|
||||
|
||||
const embed = toEmbedUrl( raw );
|
||||
@@ -282,7 +326,6 @@
|
||||
|
||||
// Neutralise Elementor so it won't build the player / load the overlay.
|
||||
widget.removeAttribute( 'data-settings' );
|
||||
const container = widget.querySelector( '.elementor-widget-container' ) || widget;
|
||||
container.innerHTML = '';
|
||||
container.appendChild( buildPlaceholder( svc, embed, {} ) );
|
||||
} );
|
||||
|
||||
Reference in New Issue
Block a user