1// See message body above for the full contents; keep exactly that version 2// --- START OF FILE --- 3(function (Drupal, once) { 4 Drupal.behaviors.rathbonesVideoConsent = { 5 attach(context) { 6 7 var inited = new WeakSet(); 8 9 function getGroupsCsv() { return (window.OptanonActiveGroups || window.OnetrustActiveGroups || '') + ''; } 10 function getGroupsArr() { var csv = getGroupsCsv(); return csv ? csv.split(',').map(function(s){return s.trim();}).filter(Boolean) : []; } 11 function hasConsentFor(wrap) { 12 var need = wrap.getAttribute('data-consent') || (window.drupalSettings?.rathbones_cookiepro?.consent) || 'C0004'; 13 return getGroupsArr().indexOf(need) !== -1; 14 } 15 function neededGroup(wrap) { return wrap.getAttribute('data-consent') || (window.drupalSettings?.rathbones_cookiepro?.consent) || 'C0004'; } 16 17 function ensureFrame(wrap) { 18 var frame = wrap.querySelector('.rathbones-video-frame'); 19 if (!frame) { frame = document.createElement('div'); frame.className = 'rathbones-video-frame'; wrap.appendChild(frame); } 20 if (!frame.id) frame.id = 'rbv-' + Math.random().toString(36).slice(2); 21 return frame; 22 } 23 24 function withYouTubeApiParams(src) { 25 if (!src || !/youtube(?:-nocookie)?\.com\/embed\//i.test(src)) return src; 26 try { 27 var url = new URL(src, window.location.href); 28 if (!url.searchParams.has('enablejsapi')) url.searchParams.set('enablejsapi', '1'); 29 if (!url.searchParams.has('origin')) url.searchParams.set('origin', window.location.origin); 30 if (!url.searchParams.has('widgetid')) url.searchParams.set('widgetid', '1'); 31 return url.toString(); 32 } catch (e) { return src; } 33 } 34 35 function buildIframeHtml(wrap) { 36 var src = withYouTubeApiParams(wrap.getAttribute('data-src')); 37 if (!src) return ''; 38 var iframeId = 'rbv-yt-' + Math.random().toString(36).slice(2); 39 var allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share'; 40 return '<iframe id="' + iframeId + '" src="' + src + '" title="Embedded video" frameborder="0" allow="' + allow + '" allowfullscreen data-ot-ignore style="width:100%; height:100%;"></iframe>'; 41 } 42 43 function notifyIframeInserted(wrap) { 44 function fire(iframe) { 45 try { 46 document.dispatchEvent(new CustomEvent('rbv:iframe-inserted', { 47 detail: { wrapper: wrap, iframe: iframe } 48 })); 49 } catch (e) {} 50 } 51 52 function wait(attempts) { 53 var iframe = wrap.querySelector('.rathbones-video-frame iframe'); 54 if (iframe) { 55 fire(iframe); 56 return; 57 } 58 if (attempts > 0) { 59 setTimeout(function () { wait(attempts - 1); }, 100); 60 } 61 } 62 63 wait(20); 64 } 65 66 function showPlaceholder(wrap) { 67 var ph = wrap.querySelector('.rathbones-video-placeholder'); if (ph) ph.style.display = ''; 68 var frame = wrap.querySelector('.rathbones-video-frame'); if (frame) frame.innerHTML = ''; 69 wrap.dataset.loaded = '0'; 70 } 71 72 function pauseAndRemove(wrap) { 73 try { 74 var iframe = wrap.querySelector('.rathbones-video-frame iframe'); 75 if (iframe && iframe.contentWindow) { 76 iframe.contentWindow.postMessage(JSON.stringify({ event:'command', func:'pauseVideo', args:[] }), '*'); 77 iframe.contentWindow.postMessage(JSON.stringify({ method:'pause' }), '*'); 78 } 79 } catch (e) {} 80 var frame = wrap.querySelector('.rathbones-video-frame'); if (frame) frame.innerHTML = ''; 81 var ph = wrap.querySelector('.rathbones-video-placeholder'); if (ph) ph.style.display = ''; 82 wrap.dataset.loaded = '0'; 83 } 84 85 function insertViaCMP(wrap) { 86 var html = buildIframeHtml(wrap); if (!html) return; 87 var frame = ensureFrame(wrap); 88 var api = null; 89 if (window.OneTrust && typeof OneTrust.InsertHTML === 'function') api = OneTrust; 90 else if (window.Optanon && typeof Optanon.InsertHTML === 'function') api = Optanon; 91 92 if (api) { api.InsertHTML(html, frame.id, null, null, neededGroup(wrap)); } 93 else { if (hasConsentFor(wrap)) frame.innerHTML = html; else return; } 94 95 var ph = wrap.querySelector('.rathbones-video-placeholder'); if (ph) ph.style.display = 'none'; 96 wrap.dataset.loaded = '1'; 97 notifyIframeInserted(wrap); 98 } 99 100 function initWrapper(wrap) { 101 if (!wrap || inited.has(wrap)) return; 102 inited.add(wrap); 103 104 var ph = wrap.querySelector('.rathbones-video-placeholder'); 105 if (ph) { 106 var cta = ph.querySelector('.rathbones-video-pref-link'); 107 if (cta) cta.addEventListener('click', function () { 108 try { (window.OneTrust && OneTrust.ToggleInfoDisplay()) || (window.Optanon && Optanon.ToggleInfoDisplay()); } catch (e) {} 109 }); 110 } 111 112 if (hasConsentFor(wrap)) insertViaCMP(wrap); else showPlaceholder(wrap); 113 114 var last = hasConsentFor(wrap); 115 function onConsentChange() { 116 var now = hasConsentFor(wrap); 117 if (now && !last) insertViaCMP(wrap); 118 else if (!now && last) pauseAndRemove(wrap); 119 last = now; 120 } 121 122 window.addEventListener('OneTrustGroupsUpdated', onConsentChange); 123 window.addEventListener('OTConsentApplied', onConsentChange); 124 if (window.OneTrust && typeof OneTrust.OnConsentChanged === 'function') { 125 try { OneTrust.OnConsentChanged(onConsentChange); } catch (e) {} 126 } 127 } 128 129 document.querySelectorAll('.rathbones-video-wrapper').forEach(initWrapper); 130 131 document.addEventListener('rbv:wrapper-added', function (ev) { 132 if (ev && ev.detail && ev.detail.wrapper) initWrapper(ev.detail.wrapper); 133 }); 134 135 var mo = new MutationObserver(function (muts) {
136 muts.forEach(function (m) { 137 if (m.addedNodes && m.addedNodes.length) { 138 m.addedNodes.forEach(function (n) { 139 if (n.nodeType !== 1) return; 140 if (n.matches && n.matches('.rathbones-video-wrapper')) initWrapper(n); 141 else { 142 var list = n.querySelectorAll ? n.querySelectorAll('.rathbones-video-wrapper') : []; 143 list && list.forEach && list.forEach(initWrapper); 144 } 145 }); 146 } 147 }); 148 }); 149 mo.observe(document.documentElement, { childList: true, subtree: true }); 150 } 151 }; 152})(Drupal, once); 153// --- END OF FILE ---
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.