1(function () { 2 'use strict'; 3 console.log('YouTube Embed script loaded'); 4 /* global YT, Drupal */ 5 6 function initYoutubeEmbeds() { 7 console.log('Initializing YouTube Embeds'); 8 // Load YouTube IFrame API 9 if (!window.YT && !window.youtubeAPILoading) { 10 window.youtubeAPILoading = true; 11 var tag = document.createElement('script'); 12 tag.src = 'https://www.youtube.com/iframe_api'; 13 var firstScriptTag = document.getElementsByTagName('script')[0]; 14 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 15 } 16 17 // Initialize YouTube players for regular full article pages 18 var fullContainers = document.querySelectorAll('.youtube-container-full:not(.processed)'); 19 fullContainers.forEach(function (container) { 20 container.classList.add('processed'); 21 22 var youtubeId = container.getAttribute('data-youtube-id'); 23 var playerElement = container.querySelector('[id^="youtube-player-"]'); 24 25 if (!playerElement || !youtubeId) { 26 return; 27 } 28 29 var playerId = playerElement.id; 30 31 // Function to create player 32 var createPlayer = function () { 33 if (window.YT && window.YT.Player) { 34 new YT.Player(playerId, { 35 videoId: youtubeId, 36 width: '100%', 37 height: '100%', 38 playerVars: { 39 autoplay: 0, 40 rel: 0, 41 modestbranding: 1 42 } 43 }); 44 } 45 }; 46 47 // Wait for API to be ready 48 if (window.YT && window.YT.Player) { 49 createPlayer(); 50 } 51 else { 52 var originalCallback = window.onYouTubeIframeAPIReady; 53 window.onYouTubeIframeAPIReady = function () { 54 if (originalCallback) { 55 originalCallback(); 56 } 57 createPlayer(); 58 }; 59 } 60 }); 61 62 // Initialize YouTube players for containers with thumbnail 63 var youtubeContainers = document.querySelectorAll('.youtube-container:not(.processed)'); 64 youtubeContainers.forEach(function (container) { 65 container.classList.add('processed'); 66 var youtubeId = container.getAttribute('data-youtube-id'); 67 if (!youtubeId) { 68 return; 69 } 70 71 var isMobile = window.matchMedia('(max-width: 767px)').matches; 72 var autoplayTriggered = false; 73 // Check if this is a top-story (has article parent with top-story class) 74 var isTopStory = container.closest('.top-story') || container.closest('.node-article'); 75 76 // Click handler for thumbnail 77 container.addEventListener('click', function () { 78 if (!autoplayTriggered) { 79 loadYoutubePlayer(container, youtubeId, true); 80 } 81 }); 82 83 // Autoplay ONLY on top-story and non-mobile (script already loads after window.load) 84 if (isTopStory && !isMobile) { 85 // Small delay to ensure DOM is fully ready 86 setTimeout(function () { 87 autoplayTriggered = true; 88 loadYoutubePlayer(container, youtubeId, true); 89 }, 500); 90 } 91 }); 92 93 initVimeoEmbeds(); 94 } 95 96 function initVimeoEmbeds() { 97 // Initialize Vimeo players for containers with thumbnail 98 var vimeoContainers = document.querySelectorAll('.vimeo-container:not(.processed)'); 99 vimeoContainers.forEach(function (container) { 100 container.classList.add('processed'); 101 var vimeoSrc = container.getAttribute('data-vimeo-src'); 102 if (!vimeoSrc) { 103 return; 104 } 105 106 var isMobile = window.matchMedia('(max-width: 767px)').matches; 107 var autoplayTriggered = false; 108 // Check if this is a top-story (has article parent with top-story class) 109 var isTopStory = container.closest('.top-story') || container.closest('.node-article'); 110 111 // Click handler for thumbnail 112 container.addEventListener('click', function () { 113 if (!autoplayTriggered) { 114 loadVimeoPlayer(container, vimeoSrc, true); 115 } 116 }); 117 118 // Autoplay ONLY on top-story and non-mobile (script already loads after window.load) 119 if (isTopStory && !isMobile) { 120 setTimeout(function () { 121 autoplayTriggered = true; 122 loadVimeoPlayer(container, vimeoSrc, true); 123 }, 500); 124 } 125 }); 126 } 127 128 function loadVimeoPlayer(container, src, autoplay) { 129 // Check if already loaded 130 if (container.classList.contains('vimeo-loaded')) { 131 return; 132 } 133 container.classList.add('vimeo-loaded'); 134 135 // Remove thumbnail and play button 136 var thumbnail = container.querySelector('.vimeo-thumbnail'); 137 var playButton = container.querySelector('.play'); 138 139 if (thumbnail) { 140 thumbnail.remove(); 141 } 142 if (playButton) { 143 playButton.remove(); 144 } 145 146 // Create iframe. Note: autoplay requires muted in most browsers. 147 var iframe = document.createElement('iframe'); 148 var separator = src.indexOf('?') === -1 ? '?' : '&'; 149 var params = autoplay ? 'autoplay=1&muted=1' : ''; 150 iframe.src = params ? src + separator + params : src; 151 iframe.setAttribute('frameborder', '0'); 152 iframe.allow = 'autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media'; 153 iframe.allowFullscreen = true; 154 iframe.style.cssText = 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;'; 155 156 container.appendChild(iframe); 157 } 158 159 function loadYoutubePlayer(container, videoId, autoplay) { 160 // Check if already loaded 161 if (container.classList.contains('youtube-loaded')) { 162 return; 163 } 164 container.classList.add('youtube-loaded'); 165 166 // Remove thumbnail and play button 167 var thumbnail = container.querySelector('.youtube-thumbnail'); 168 var playButton = container.querySelector('.play'); 169 170 if (thumbnail) { 171 thumbnail.remove(); 172 } 173 if (playButton) { 174 playButton.remove(); 175 } 176 177 // Create iframe 178 var iframe = document.createElement('iframe'); 179 // Note: autoplay requires mute in most browsers 180 var autoplayParam = autoplay ? '1' : '0'; 181 var muteParam = '1'; 182 iframe.src = 'https://www.youtube.com/embed/' + videoId + 183 '?autoplay=' + autoplayParam + 184 '&mute=' + muteParam + 185 '&rel=0' + 186 '&modestbranding=1' + 187 '&playsinline=1'; 188 iframe.setAttribute('frameborder', '0'); 189 iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'; 190 iframe.allowFullscreen = true; 191 iframe.style.cssText = 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;'; 192 193 container.appendChild(iframe); 194 } 195 196 // Initialize on DOM ready 197 if (document.readyState === 'loading') { 198 document.addEventListener('DOMContentLoaded', initYoutubeEmbeds); 199 } 200 else { 201 initYoutubeEmbeds(); 202 } 203 204 // Also expose for Drupal behaviors if needed 205 if (window.Drupal && Drupal.behaviors) { 206 Drupal.behaviors.youtubeEmbed = { 207 attach: function () { 208 initYoutubeEmbeds(); 209 } 210 }; 211 } 212 213})();
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.