1/** 2 * Note: This is complex initialization, but it is necessary for Gutenberg and Elementor compatibility. There are some known issues in Gutenberg that require this complex setup. 3 */ 4var playerInit = []; 5 6// Event listener for when the DOM content is loaded 7document.addEventListener('DOMContentLoaded', function () { 8 9 10 const overlayMask = document.createElement('div'); 11 overlayMask.className = 'overlay-mask'; 12 13 14 // Select all embed wrappers with the class 'ep-embed-content-wraper' 15 let embedWrappers = document.querySelectorAll('.ep-embed-content-wraper'); 16 17 // Initialize the player for each embed wrapper 18 embedWrappers.forEach(wrapper => { 19 initPlayer(wrapper); 20 }); 21 22 // Mutation observer to detect any changes in the DOM 23 const observer = new MutationObserver(mutations => { 24 mutations.forEach(mutation => { 25 const addedNodes = Array.from(mutation.addedNodes); 26 addedNodes.forEach(node => { 27 traverseAndInitPlayer(node); 28 }); 29 }); 30 }); 31 32 // Start observing changes in the entire document body and its subtree 33 observer.observe(document.body, { childList: true, subtree: true }); 34 35 // Recursive function to traverse the DOM and initialize the player for each embed wrapper 36 function traverseAndInitPlayer(node) { 37 if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('ep-embed-content-wraper')) { 38 initPlayer(node); 39 } 40 41 if (node.hasChildNodes()) { 42 node.childNodes.forEach(childNode => { 43 traverseAndInitPlayer(childNode); 44 }); 45 } 46 } 47 48 49}); 50 51 52// Function to initialize the player for a given wrapper 53function initPlayer(wrapper) { 54 const playerId = wrapper.getAttribute('data-playerid'); 55 56 // Get the options for the player from the wrapper's data attribute
57 let options = document.querySelector(`[data-playerid="${playerId}"]`)?.getAttribute('data-options'); 58 59 if(!options) { 60 return false; 61 } 62 63 // Parse the options string into a JSON object 64 options = JSON.parse(options); 65 66 // Create DOM elements from the icon strings 67 const pipPlayIconElement = document.createElement('div'); 68 pipPlayIconElement.className = 'pip-play'; 69 pipPlayIconElement.innerHTML = '<svg width="20" height="20" viewBox="-0.15 -0.112 0.9 0.9" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin" class="jam jam-play"><path fill="#fff" d="M.518.357A.037.037 0 0 0 .506.306L.134.08a.039.039 0 0 0-.02-.006.038.038 0 0 0-.038.037v.453c0 .007.002.014.006.02a.039.039 0 0 0 .052.012L.506.37A.034.034 0 0 0 .518.358zm.028.075L.174.658A.115.115 0 0 1 .017.622.109.109 0 0 1 0 .564V.111C0 .05.051 0 .114 0c.021 0 .042.006.06.017l.372.226a.11.11 0 0 1 0 .189z"/></svg>'; 70 pipPlayIconElement.style.display = 'none'; 71 72 73 const pipPauseIconElement = document.createElement('div'); 74 pipPauseIconElement.className = 'pip-pause'; 75 pipPauseIconElement.innerHTML = '<svg fill="#fff" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 2.5 2.5" xml:space="preserve"><path d="M1.013.499 1.006.5V.499H.748a.054.054 0 0 0-.054.054v1.394c0 .03.024.054.054.054h.266a.054.054 0 0 0 .054-.054V.553a.054.054 0 0 0-.054-.054zm.793 1.448V.553a.054.054 0 0 0-.054-.054L1.745.5V.499h-.258a.054.054 0 0 0-.054.054v1.394c0 .03.024.054.054.054h.265a.054.054 0 0 0 .054-.054z"/></svg>'; 76 77 const pipCloseElement = document.createElement('div'); 78 pipCloseElement.className = 'pip-close'; 79 pipCloseElement.innerHTML = '<svg width="20" height="20" viewBox="0 0 0.9 0.9" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M.198.198a.037.037 0 0 1 .053 0L.45.397.648.199a.037.037 0 1 1 .053.053L.503.45l.198.198a.037.037 0 0 1-.053.053L.45.503.252.701A.037.037 0 0 1 .199.648L.397.45.198.252a.037.037 0 0 1 0-.053z" fill="#fff"/></svg>'; 80 81 // Check if the player has not been initialized for this wrapper 82 if (playerId && !wrapper.classList.contains('plyr-initialized')) { 83 84 85 let selector = `[data-playerid="${playerId}"] .ose-embedpress-responsive`; 86 87 if (options.self_hosted && options.hosted_format === 'video') { 88 selector = `[data-playerid="${playerId}"] .ose-embedpress-responsive video`; 89 } 90 else if (options.self_hosted && options.hosted_format === 'audio') { 91 selector = `[data-playerid="${playerId}"] .ose-embedpress-responsive audio`; 92 } 93 94 95 // Set the main color of the player
96 document.querySelector(`[data-playerid="${playerId}"]`).style.setProperty('--plyr-color-main', options.player_color); 97 document.querySelector(`[data-playerid="${playerId}"].custom-player-preset-1, [data-playerid="${playerId}"].custom-player-preset-3, [data-playerid="${playerId}"].custom-player-preset-4`)?.style.setProperty('--plyr-range-fill-background', '#ffffff'); 98 99 // Set the poster thumbnail for the player 100 if (document.querySelector(`[data-playerid="${playerId}"] iframe`)) { 101 document.querySelector(`[data-playerid="${playerId}"] iframe`).setAttribute('data-poster', options.poster_thumbnail); 102 } 103 104 105 // Define the controls to be displayed 106 const controls = [ 107 'play-large', 108 options.restart ? 'restart' : '', 109 options.rewind ? 'rewind' : '', 110 'play', 111 options.fast_forward ? 'fast-forward' : '', 112 'progress', 113 'current-time', 114 'duration', 115 'mute', 116 'volume', 117 'captions', 118 'settings', 119 options.pip ? 'pip' : '', 120 'airplay', 121 options.download ? 'download' : '', 122 options.fullscreen ? 'fullscreen' : '', 123 124 ].filter(control => control !== ''); 125 126 // Create a new Plyr player instance with the specified options and controls 127 const player = new Plyr(selector, { 128 controls: controls, 129 seekTime: 10, 130 poster: options.poster_thumbnail, 131 storage: { 132 enabled: true, 133 key: 'plyr_volume' 134 }, 135 displayDuration: true, 136 tooltips: { controls: options.player_tooltip, seek: options.player_tooltip }, 137 hideControls: options.hide_controls, 138 youtube: { 139 ...(options.autoplay && { autoplay: options.autoplay }), 140 ...(options.start && { start: options.start }), 141 ...(options.end && { end: options.end }), 142 ...(options.rel && { rel: options.rel }), 143 ...(options.fullscreen && { fs: options.fullscreen }) 144 }, 145 vimeo: { 146 byline: false, 147 portrait: false, 148 title: false, 149 speed: true, 150 transparent: false, 151 controls: false, 152 ...(options.t && { t: options.t }), 153 ...(options.vautoplay && { autoplay: options.vautoplay }), 154 ...(options.autopause && { autopause: options.autopause }), 155 ...(options.dnt && { dnt: options.dnt }), 156 } 157 }); 158 159 playerInit[playerId] = player; 160 161 162 163 // Mark the wrapper as initialized 164 wrapper.classList.add('plyr-initialized'); 165 } 166 167 // Check for the existence of the player's pip button at regular intervals 168 const pipInterval = setInterval(() => { 169
170 let playerPip = document.querySelector(`[data-playerid="${playerId}"] [data-plyr="pip"]`); 171 if (playerPip) { 172 clearInterval(pipInterval); 173 174 let options = document.querySelector(`[data-playerid="${playerId}"]`).getAttribute('data-options'); 175 176 options = JSON.parse(options); 177 if (!options.self_hosted) { 178 179 const iframeSelector = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper`); 180 181 // Add click event listener to toggle the pip mode 182 playerPip.addEventListener('click', () => { 183 iframeSelector.classList.toggle('pip-mode'); 184 185 let parentElement = iframeSelector.parentElement; 186 while (parentElement) { 187 parentElement.style.zIndex = '9999'; 188 parentElement = parentElement.parentElement; 189 } 190 191 }); 192 193 194 if (options.pip) { 195 iframeSelector.appendChild(pipPlayIconElement); 196 iframeSelector.appendChild(pipPauseIconElement); 197 iframeSelector.appendChild(pipCloseElement);
198 const pipPlay = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-play`); 199 const pipPause = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-pause`); 200 const pipClose = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-close`); 201 202 console.log(pipClose); 203 204 pipClose.addEventListener('click', () => { 205 iframeSelector.classList.remove('pip-mode'); 206 console.log(iframeSelector.classList); 207 }); 208 209 210 iframeSelector.addEventListener('click', () => { 211 const ariaPressedValue = document.querySelector(`[data-playerid="${playerId}"] .plyr__controls [data-plyr="play"]`).getAttribute('aria-pressed'); 212 213 console.log(ariaPressedValue); 214 if (ariaPressedValue === 'true') { 215 pipPause.style.display = 'none'; 216 pipPlay.style.display = 'flex'; 217 } else { 218 pipPlay.style.display = 'none'; 219 pipPause.style.display = 'flex'; 220 } 221 }); 222 223 } 224 225 226 } 227 } 228 229 }, 200); 230 231}
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.