1function fupi_iframes(){ 2 3 let iframesTrigger = false; 4 5 function loadIframe( wrap ){ 6 7 let iframe_data_el = FP.findFirst('.fupi_iframe_data', wrap); 8 9 if ( iframe_data_el ) { 10 11 // make sure that the loaded iframe has a "src" 12 if ( ! iframe_data_el.hasAttribute('src') && iframe_data_el.dataset.src ) iframe_data_el.setAttribute('src', iframe_data_el.dataset.src); 13 14 // add lazy loading 15 let lazy = iframe_data_el.getAttribute('loading') ? '' : fp.notice.iframe_lazy ? ' loading="lazy"' : '', 16 new_html = iframe_data_el.outerHTML.replaceAll('<div ','<iframe ' + lazy); 17 18 new_html = new_html.replaceAll('/div>','/iframe>'); 19 20 // If we have a Gutenberg embed or a Bricks Builder "Video" element... 21 if ( wrap.parentElement.classList.contains('wp-block-embed__wrapper') || wrap.parentElement.classList.contains('brxe-video') ){ 22 // ...create standard iframe. Gutenberg styles make it responsive 23 wrap.insertAdjacentHTML('afterend', new_html); 24 // ... if not... 25 } else { 26 // ...create responsive iframe. An FP's wrapper makes it responsive 27 let aspect = getIframeAspect(wrap, iframe_data_el); 28 wrap.insertAdjacentHTML('afterend', '<div class="fupi_responsive_iframe" style="padding-bottom: ' + aspect + '; position: relative;">' + new_html + '</div>' ); 29 }; 30 31 wrap.remove(); 32 } 33 } 34 35 function get_domain_from_url( url_string ){ 36 let url = ''; 37 try { 38 url = new URL( url_string ); 39 } catch (e) { 40 if ( fp.main.debug ) console.error('[FP] Incorrect URL provided for iframe. Current value: ' + url_string ); 41 return false; 42 }; 43 return url.hostname; 44 } 45 46 function getIframeAspect( wrap, iframe_data ){ 47 48 // if this iframe was embedded with a Gutenberg block 49 if ( wrap.parentElement.classList.contains('wp-block-embed__wrapper') ) { 50 wrap.classList.add('fupi_fit_to_guten_embed'); 51 return '0'; 52 53 // if this iframe was embedded with a Bricks Builder "Video" element 54 } else if ( wrap.parentElement.classList.contains('brxe-video') ) { 55 wrap.classList.add('fupi_fit_to_bricks_embed'); 56 return '0'; 57 58 // if it wasn't 59 } else { 60 61 // if this iframe was embedded with a Brakedance block 62 if ( wrap.parentElement.classList.contains('ee-video-container') ) { 63 wrap.classList.add('fupi_fit_to_breakdance_embed'); 64 // set the padding on parent's container to 0 65 wrap.parentElement.style.paddingTop = 0; 66 } 67 68 let width = iframe_data.getAttribute('width'), 69 height = iframe_data.getAttribute('height'), 70 aspect = width && height ? Math.round( parseInt( height ) / parseInt ( width ) * 10000 ) / 100 + '%' : wrap.dataset.aspect || '56.25%'; 71 72 wrap.dataset.aspect = aspect; 73 return aspect; 74 75 }; // AND IF SOMETHING ELSE: aspect = Math.round ( wrap.parentElement.offsetHeight / wrap.parentElement.offsetWidth * 10000 ) / 100 + '%'; 76 } 77 78 // 79 // GET VIDEO THUMBNAIL -- START 80 // 81 82 function getIframeThumbSrc( wrap, iframe_data, src, vid_domain ){ 83 84 if ( ! vid_domain ) return false; 85 86 if ( vid_domain.includes( 'youtube.com' ) ){ 87 88 return getYouTubeThumbURL( src ); 89 90 } else if ( vid_domain.includes( 'vimeo.com' ) ){ 91 92 let vimeoID = extractVimeoId( src ); 93 if ( ! vimeoID ) return false; 94 95 wrap.id = 'fupi_vimeo_' + vimeoID; 96 requestVimeoThumbURL( vimeoID, iframe_data ); // this will request the image from vimeo and replace it in the placeholder after it gets it 97 return false; 98 } 99 } 100 101 function getYouTubeThumbURL( src ){ 102 const yt_vid = src.match(/(?:\?v=|\/embed\/|\.be\/|\/v\/|\/\d{1,2}\/|\/embed\/|\/shorts\/|\/youtu.be\/|\/watch\?v=|&v=|embed\/|youtu.be\/|v\/|watch\?v=)([^#\&\?]{11,11})/); 103 return yt_vid ? `https://img.youtube.com/vi/${yt_vid[1]}/maxresdefault.jpg` : null; 104 } 105 106 function extractVimeoId(url) { 107 let regex = /video\/(\d+)/, 108 match = url.match(regex); 109 if (match && match[1]) { 110 return match[1]; 111 }; 112 return null; 113 } 114 115 FP.loadVimeoThumb = function( data ){ // this is added to FP object because it needs to be accessible by the callback in the requestVimeoThumbURL function below 116 var id_img = "#fupi_vimeo_" + data[0].id; 117 FP.findFirst( id_img + ' .fupi_iframe_placeholder' ).style.backgroundImage = 'url(\'' + data[0].thumbnail_large + '\')'; 118 } 119 120 function requestVimeoThumbURL( vimeoID, iframe_data ){
121 let url = "https://vimeo.com/api/v2/video/" + vimeoID + ".json?callback=FP.loadVimeoThumb"; 122 FP.getScript( url, false, {async : true} ); 123 } 124 125 // GET VIDEO THUMBNAIL -- END 126 127 function makeIframePlaceholder(wrap){ 128 129 let iframe_data = FP.findFirst( '.fupi_iframe_data', wrap ), 130 src = iframe_data.getAttribute('src') || iframe_data.dataset.src || false; 131 132 if ( ! src ) return; 133 134 let privacy_url = wrap.dataset.privacy || fp.notice.privacy_url || false, 135 descr_text = fupi_iframe_texts.iframe_caption_txt, 136 aspect = getIframeAspect( wrap, iframe_data ), 137 vid_domain = get_domain_from_url( src ); 138 placeholder = wrap.dataset.placeholder || wrap.dataset.image || getIframeThumbSrc( wrap, iframe_data, src, vid_domain ) || fp.notice.iframe_img, 139 src_name = wrap.dataset.name; 140 141 // make placeholder CSS 142 placeholder_img = placeholder ? 'background-image: url(\'' + placeholder + '\');' : ''; 143 144 // insert the privacy URL and the source name in the description text 145 descr_text = privacy_url ? descr_text.replace('{{', '<a href="' + privacy_url + '">').replace('}}', '</a>') : descr_text.replace('{{', '').replace('}}', '') 146 descr_text = src_name ? descr_text.replace(/\[\[.*?\]\]/, src_name ) : descr_text.replace('[[', '').replace(']]', ''); 147 148 // ALL TOGETHER 149 let output = '<div class="fupi_iframe_placeholder" style="padding-bottom: ' + aspect + '; ' + placeholder_img + ' background-size: cover; background-position: center;"><div class="fupi_iframe_content"><div class="fupi_inner"><p class="fupi_iframe_descr">' + descr_text + '</p>
149<p class="fupi_iframe_btn_wrap"><button type="button" class="fupi_iframe_consent_btn" data-vid_domain="' + vid_domain + '">' + fupi_iframe_texts.iframe_btn_text + '</button></p></div></div></div>'; 150 151 wrap.insertAdjacentHTML( 'afterbegin', output ); 152 }; 153 154 // This function is triggered after all the iframes in HTML and also by the consent banner 155 156 function shouldIframeLoad( wrap, cons_data ){ 157 158 let should_load = true, 159 iframe_data_el = FP.findFirst('.fupi_iframe_data', wrap), 160 src = iframe_data_el.getAttribute('src') || iframe_data_el.dataset.src || false; 161 162 if ( ! src ) return false; 163 164 if ( ! fpdata.cookies ) { 165 should_load = wrap.dataset.pers == '0' && wrap.dataset.stats == '0' && wrap.dataset.market == '0'; 166 } else { 167 if ( 168 ( wrap.dataset.stats == '1' && ! fpdata.cookies.stats ) || 169 ( wrap.dataset.market == '1' && ! fpdata.cookies.marketing ) || 170 ( wrap.dataset.pers == '1' && ! fpdata.cookies.personalisation ) 171 ) should_load = false; 172 }; 173 174 if ( ! should_load && cons_data ) { 175 cons_data.forEach( consented_source => { 176 if ( src.includes( consented_source ) ) should_load = true; 177 } ); 178 } 179 180 return should_load; 181 } 182 183 // INIT 184 185 FP.loadIframes = () => { 186 187 let wrappers = FP.findAll('.fupi_blocked_iframe'), // wrappers of blocked iframes 188 cons_cookie = FP.readCookie('fp_iframes_consent'), 189 cons_data = cons_cookie ? JSON.parse(cons_cookie) : false; 190 191 // FOR EACH WRAPPER 192 wrappers.forEach( wrap => { 193 194 let should_load = shouldIframeLoad(wrap, cons_data); 195 196 if ( should_load ) { 197 // load iframe 198 if ( ! wrap.classList.contains('fupi_iframe_loaded') ) { 199 wrap.classList.add('fupi_iframe_loaded'); 200 loadIframe( wrap ); 201 } 202 } else { 203 // load placeholder 204 if ( ! wrap.classList.contains('fupi_has_iframe_placeholder') ) { 205 wrap.classList.add('fupi_has_iframe_placeholder'); 206 makeIframePlaceholder( wrap ); 207 } 208 } 209 } ) 210 } 211 212 if ( document.readyState === "complete" ) { 213 FP.loadIframes(); 214 } else { 215 document.addEventListener('DOMContentLoaded', FP.loadIframes ); 216 } 217 218 setInterval( ()=>{FP.loadIframes();}, 1000); 219 220 // Load iframes when a "Load content" button is clicked 221 222 document.addEventListener('click', e => { 223 224 if ( ! e.target.classList.contains('fupi_iframe_consent_btn') ) return; 225 226 // get the iframe's source domain 227 let vid_domain = e.target.dataset.vid_domain; 228 229 if ( vid_domain ){ 230 231 // remember in a cookie that a user agreed to see content from this domain 232 let iframe_data_els = FP.findAll('.fupi_iframe_data[src*="' + vid_domain + '"], .fupi_iframe_data[data-src*="' + vid_domain + '"]'), 233 cons_cookie = FP.readCookie('fp_iframes_consent'); 234 235 if ( cons_cookie ) { 236 let cons_data = JSON.parse(cons_cookie); 237 cons_data.push(vid_domain); 238 FP.setCookie( 'fp_iframes_consent', JSON.stringify(cons_data), 180 ); 239 } else { 240 FP.setCookie( 'fp_iframes_consent', JSON.stringify([vid_domain]), 180 ); 241 } 242 243 // load all iframes from this source 244 iframe_data_els.forEach( el => loadIframe( el.parentElement ) ); 245 } 246 }) 247 248 FP.loaded('iframes_blocker'); 249}; 250 251if ( ! fp.main.is_bricks_builder ) FP.load('iframes_blocker', 'fupi_iframes', ['head_helpers']);
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.