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 */ 4 5// Event listener for when the DOM content is loaded 6document.addEventListener('DOMContentLoaded', function () { 7 8 9 const overlayMask = document.createElement('div'); 10 overlayMask.className = 'overlay-mask'; 11 12 13 // Select all embed wrappers with the class 'ep-embed-content-wraper' 14 let embedWrappers = document.querySelectorAll('.ep-embed-content-wraper'); 15 16 // Initialize the player for each embed wrapper 17 embedWrappers.forEach(wrapper => { 18 initPlayer(wrapper); 19 }); 20 21 // Mutation observer to detect any changes in the DOM 22 const observer = new MutationObserver(mutations => { 23 mutations.forEach(mutation => { 24 const addedNodes = Array.from(mutation.addedNodes); 25 addedNodes.forEach(node => { 26 traverseAndInitPlayer(node); 27 }); 28 }); 29 }); 30 31 // Start observing changes in the entire document body and its subtree 32 observer.observe(document.body, { childList: true, subtree: true }); 33 34 // Recursive function to traverse the DOM and initialize the player for each embed wrapper 35 function traverseAndInitPlayer(node) { 36 if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('ep-embed-content-wraper')) { 37 initPlayer(node); 38 } 39 40 if (node.hasChildNodes()) { 41 node.childNodes.forEach(childNode => { 42 traverseAndInitPlayer(childNode); 43 }); 44 } 45 } 46 47 48 49 50}); 51 52 53// Function to initialize the player for a given wrapper 54function initPlayer(wrapper) { 55 const playerId = wrapper.getAttribute('data-playerid'); 56 57 // Get the options for the player from the wrapper's data attribute
58 let options = document.querySelector(`[data-playerid="${playerId}"]`)?.getAttribute('data-options'); 59 60 if(!options) { 61 return false; 62 } 63 64 // Parse the options string into a JSON object 65 options = JSON.parse(options); 66 67 // Create DOM elements from the icon strings 68 const pipPlayIconElement = document.createElement('div'); 69 pipPlayIconElement.className = 'pip-play'; 70 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>'; 71 pipPlayIconElement.style.display = 'none'; 72 73 74 const pipPauseIconElement = document.createElement('div'); 75 pipPauseIconElement.className = 'pip-pause'; 76 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>'; 77 78 const pipCloseElement = document.createElement('div'); 79 pipCloseElement.className = 'pip-close'; 80 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>'; 81 82 // Check if the player has not been initialized for this wrapper 83 if (playerId && !wrapper.classList.contains('plyr-initialized')) { 84 85 86 let selector = `[data-playerid="${playerId}"] .ose-embedpress-responsive`; 87 88 if (options.self_hosted && options.hosted_format === 'video') { 89 selector = `[data-playerid="${playerId}"] .ose-embedpress-responsive video`; 90 } 91 else if (options.self_hosted && options.hosted_format === 'audio') { 92 selector = `[data-playerid="${playerId}"] .ose-embedpress-responsive audio`; 93 } 94 95 96 // Set the main color of the player
97 document.querySelector(`[data-playerid="${playerId}"]`).style.setProperty('--plyr-color-main', options.player_color); 98 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'); 99 100 // Set the poster thumbnail for the player 101 if (document.querySelector(`[data-playerid="${playerId}"] iframe`)) { 102 document.querySelector(`[data-playerid="${playerId}"] iframe`).setAttribute('data-poster', options.poster_thumbnail); 103 } 104 105 106 // Define the controls to be displayed 107 const controls = [ 108 'play-large', 109 options.restart ? 'restart' : '', 110 options.rewind ? 'rewind' : '', 111 'play', 112 options.fast_forward ? 'fast-forward' : '', 113 'progress', 114 'current-time', 115 'duration', 116 'mute', 117 'volume', 118 'captions', 119 'settings', 120 options.pip ? 'pip' : '', 121 'airplay', 122 options.download ? 'download' : '', 123 options.fullscreen ? 'fullscreen' : '', 124 125 ].filter(control => control !== ''); 126 127 // Create a new Plyr player instance with the specified options and controls 128 const player = new Plyr(selector, { 129 controls: controls, 130 seekTime: 10, 131 poster: options.poster_thumbnail, 132 storage: { 133 enabled: true, 134 key: 'plyr_volume' 135 }, 136 displayDuration: true, 137 tooltips: { controls: options.player_tooltip, seek: options.player_tooltip }, 138 hideControls: options.hide_controls, 139 youtube: { 140 ...(options.autoplay && { autoplay: options.autoplay }), 141 ...(options.start && { start: options.start }), 142 ...(options.end && { end: options.end }), 143 ...(options.rel && { rel: options.rel }), 144 ...(options.fullscreen && { fs: options.fullscreen }) 145 }, 146 vimeo: { 147 byline: false, 148 portrait: false, 149 title: false, 150 speed: true, 151 transparent: false, 152 controls: false, 153 ...(options.t && { t: options.t }), 154 ...(options.vautoplay && { autoplay: options.vautoplay }), 155 ...(options.autopause && { autopause: options.autopause }), 156 ...(options.dnt && { dnt: options.dnt }), 157 } 158 }); 159 160 // Mark the wrapper as initialized 161 wrapper.classList.add('plyr-initialized'); 162 } 163 164 // Check for the existence of the player's pip button at regular intervals 165 const pipInterval = setInterval(() => { 166
167 let playerPip = document.querySelector(`[data-playerid="${playerId}"] [data-plyr="pip"]`); 168 if (playerPip) { 169 clearInterval(pipInterval); 170 171 let options = document.querySelector(`[data-playerid="${playerId}"]`).getAttribute('data-options'); 172 173 options = JSON.parse(options); 174 if (!options.self_hosted) { 175 176 const iframeSelector = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper`); 177 178 // Add click event listener to toggle the pip mode 179 playerPip.addEventListener('click', () => { 180 iframeSelector.classList.toggle('pip-mode'); 181 182 let parentElement = iframeSelector.parentElement; 183 while (parentElement) { 184 parentElement.style.zIndex = '9999'; 185 parentElement = parentElement.parentElement; 186 } 187 188 }); 189 190 191 if (options.pip) { 192 iframeSelector.appendChild(pipPlayIconElement); 193 iframeSelector.appendChild(pipPauseIconElement); 194 iframeSelector.appendChild(pipCloseElement);
195 const pipPlay = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-play`); 196 const pipPause = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-pause`); 197 const pipClose = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-close`); 198 199 console.log(pipClose); 200 201 pipClose.addEventListener('click', () => { 202 iframeSelector.classList.remove('pip-mode'); 203 console.log(iframeSelector.classList); 204 }); 205 206 207 iframeSelector.addEventListener('click', () => { 208 const ariaPressedValue = document.querySelector(`[data-playerid="${playerId}"] .plyr__controls [data-plyr="play"]`).getAttribute('aria-pressed'); 209 210 console.log(ariaPressedValue); 211 if (ariaPressedValue === 'true') { 212 pipPause.style.display = 'none'; 213 pipPlay.style.display = 'flex'; 214 } else { 215 pipPlay.style.display = 'none'; 216 pipPause.style.display = 'flex'; 217 } 218 }); 219 220 } 221 222 223 } 224 } 225 226 }, 200); 227 228}
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.