PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.5.1
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.5.1
4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / assets / js / initplyr.js
embedpress / assets / js Last commit date
chunks 2 months ago vendor 9 months ago admin.build.js 2 months ago admin.js 3 months ago analytics-tracker.js 9 months ago analytics.build.js 2 months ago blocks.build.js 2 months ago carousel.js 1 year ago documents-viewer-script.js 3 months ago ep-pdf-lightbox.js 3 months ago feature-notices.js 7 months ago front.js 3 months ago frontend.build.js 3 months ago gallery-justify.js 9 months ago gutneberg-script.js 1 year ago index.html 7 years ago initCarousel.js 2 years ago initplyr.js 3 months ago instafeed.js 7 months ago lazy-load.js 6 months ago license.js 3 months ago meetup-timezone.js 3 months ago onboarding.build.js 2 months ago pdf-gallery-elementor-editor.js 3 months ago pdf-gallery.js 3 months ago preview.js 9 months ago settings.js 3 months ago sponsored.js 9 months ago
initplyr.js
326 lines
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 var playerInit = [];
5
6
7 // Event listener for when the DOM content is loaded
8 document.addEventListener('DOMContentLoaded', function () {
9
10
11 const overlayMask = document.createElement('div');
12 overlayMask.className = 'overlay-mask';
13
14
15 // Select all embed wrappers with the class 'ep-embed-content-wraper'
16 let embedWrappers = document.querySelectorAll('.ep-embed-content-wraper');
17
18 // Initialize the player for each embed wrapper
19 embedWrappers.forEach(wrapper => {
20 initPlayer(wrapper);
21 });
22
23 // Mutation observer to detect any changes in the DOM
24 const observer = new MutationObserver(mutations => {
25 mutations.forEach(mutation => {
26 const addedNodes = Array.from(mutation.addedNodes);
27 addedNodes.forEach(node => {
28 traverseAndInitPlayer(node);
29 });
30 });
31 });
32
33 // Start observing changes in the entire document body and its subtree
34 observer.observe(document.body, { childList: true, subtree: true });
35
36 // Recursive function to traverse the DOM and initialize the player for each embed wrapper
37 function traverseAndInitPlayer(node) {
38 if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('ep-embed-content-wraper')) {
39 initPlayer(node);
40 }
41
42 if (node.hasChildNodes()) {
43 node.childNodes.forEach(childNode => {
44 traverseAndInitPlayer(childNode);
45 });
46 }
47 }
48
49
50 });
51
52
53 // Function to initialize the player for a given wrapper
54 function 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
61
62 if (!options) {
63 return false;
64 }
65
66 // Parse the options string into a JSON object
67 if (typeof options === 'string') {
68 try {
69 options = JSON.parse(options);
70 } catch (e) {
71 return;
72 }
73 } else {
74 return;
75 }
76
77
78 if (!options.poster_thumbnail) {
79 wrapper.style.opacity = "1";
80 }
81
82 // Create DOM elements from the icon strings
83 const pipPlayIconElement = document.createElement('div');
84 pipPlayIconElement.className = 'pip-play';
85 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>';
86 pipPlayIconElement.style.display = 'none';
87
88
89 const pipPauseIconElement = document.createElement('div');
90 pipPauseIconElement.className = 'pip-pause';
91 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>';
92
93 const pipCloseElement = document.createElement('div');
94 pipCloseElement.className = 'pip-close';
95 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>';
96
97 // Check if the player has not been initialized for this wrapper
98 if (playerId && !wrapper.classList.contains('plyr-initialized')) {
99
100
101 let selector = `[data-playerid='${playerId}'] .ose-embedpress-responsive`;
102
103
104 if (options.self_hosted && options.hosted_format === 'video') {
105 selector = `[data-playerid='${playerId}'] .ose-embedpress-responsive video`;
106 }
107 else if (options.self_hosted && options.hosted_format === 'audio') {
108 selector = `[data-playerid='${playerId}'] .ose-embedpress-responsive audio`;
109 wrapper.style.opacity = "1";
110 }
111
112
113 // Set the main color of the player
114 document.querySelector(`[data-playerid='${playerId}']`).style.setProperty('--plyr-color-main', options.player_color);
115 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');
116
117 // Set the poster thumbnail for the player
118 if (document.querySelector(`[data-playerid='${playerId}'] iframe`)) {
119 document.querySelector(`[data-playerid='${playerId}'] iframe`).setAttribute('data-poster', options.poster_thumbnail);
120 }
121 if (document.querySelector(`[data-playerid='${playerId}'] video`)) {
122 document.querySelector(`[data-playerid='${playerId}'] video`).setAttribute('data-poster', options.poster_thumbnail);
123 }
124
125 // Define the controls to be displayed
126 const controls = [
127 'play-large',
128 options.restart ? 'restart' : '',
129 options.rewind ? 'rewind' : '',
130 'play',
131 options.fast_forward ? 'fast-forward' : '',
132 'progress',
133 'current-time',
134 'duration',
135 'mute',
136 'volume',
137 'captions',
138 'settings',
139 options.pip ? 'pip' : '',
140 'airplay',
141 options.download ? 'download' : '',
142 options.fullscreen ? 'fullscreen' : '',
143
144 ].filter(control => control !== '');
145
146 // Detect if we're on iOS
147 const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
148
149 // Detect if this is a YouTube video
150 const isYouTube = document.querySelector(`[data-playerid='${playerId}'] iframe[src*="youtube"]`) !== null;
151
152 // For iOS YouTube videos, we need to use fallback fullscreen instead of native
153 // because webkitEnterFullscreen() doesn't work on iframes
154 const shouldUseFallbackFullscreen = isIOS && isYouTube;
155
156
157
158 // Create a new Plyr player instance with the specified options and controls
159 const player = new Plyr(selector, {
160 controls: controls,
161 seekTime: 10,
162 poster: options.poster_thumbnail,
163 storage: {
164 enabled: true,
165 key: 'plyr_volume'
166 },
167 displayDuration: true,
168 tooltips: { controls: options.player_tooltip, seek: options.player_tooltip },
169 hideControls: options.hide_controls,
170 // iOS fullscreen configuration - use fallback for YouTube on iOS
171 fullscreen: {
172 enabled: options.fullscreen !== false,
173 fallback: true,
174 iosNative: !shouldUseFallbackFullscreen // Disable iosNative for YouTube on iOS
175 },
176 // Enable playsinline for iOS devices to allow custom controls
177 playsinline: true,
178 youtube: {
179 ...(options.autoplay && { autoplay: options.autoplay }),
180 ...(options.start && { start: options.start }),
181 ...(options.end && { end: options.end }),
182 ...(options.rel && { rel: options.rel }),
183 ...(options.fullscreen && { fs: options.fullscreen })
184 },
185 vimeo: {
186 byline: false,
187 portrait: false,
188 title: false,
189 speed: true,
190 transparent: false,
191 controls: false,
192 ...(options.t && { t: options.t }),
193 ...(options.vautoplay && { autoplay: options.vautoplay }),
194 ...(options.autopause && { autopause: options.autopause }),
195 ...(options.dnt && { dnt: options.dnt }),
196 }
197 });
198
199 playerInit[playerId] = player;
200
201
202 // iOS YouTube fullscreen fix: Ensure iframe has proper attributes
203 if (shouldUseFallbackFullscreen) {
204 const iframe = document.querySelector(`[data-playerid='${playerId}'] iframe[src*="youtube"]`);
205 if (iframe) {
206 // Ensure the iframe allows fullscreen
207 iframe.setAttribute('allowfullscreen', '');
208 iframe.setAttribute('webkitallowfullscreen', '');
209 iframe.setAttribute('mozallowfullscreen', '');
210
211 // Add iOS-specific class for styling
212 iframe.classList.add('ios-youtube-iframe');
213
214 // Listen for fullscreen events to handle iOS-specific behavior
215 player.on('enterfullscreen', () => {
216 // Force viewport meta tag update for better fullscreen experience
217 const viewport = document.querySelector('meta[name="viewport"]');
218 if (viewport) {
219 const originalContent = viewport.getAttribute('content');
220 viewport.setAttribute('data-original-content', originalContent);
221 viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover');
222 }
223 });
224
225 player.on('exitfullscreen', () => {
226 // Restore original viewport meta tag
227 const viewport = document.querySelector('meta[name="viewport"]');
228 if (viewport && viewport.hasAttribute('data-original-content')) {
229 viewport.setAttribute('content', viewport.getAttribute('data-original-content'));
230 viewport.removeAttribute('data-original-content');
231 }
232 });
233 }
234 }
235
236
237
238 // Mark the wrapper as initialized
239 wrapper.classList.add('plyr-initialized');
240
241 const posterElement = wrapper.querySelector('.plyr__poster');
242
243 if (posterElement) {
244 const interval = setInterval(() => {
245 const computedBg = window.getComputedStyle(posterElement).getPropertyValue('background-image');
246 if (posterElement.style.backgroundImage || (computedBg && computedBg !== 'none')) {
247 wrapper.style.opacity = '1';
248 clearInterval(interval);
249 }
250 }, 200);
251
252 // Fallback: ensure the player becomes visible even if poster never loads
253 setTimeout(() => {
254 clearInterval(interval);
255 wrapper.style.opacity = '1';
256 }, 5000);
257 } else {
258 // No poster element found — show the player immediately
259 wrapper.style.opacity = '1';
260 }
261
262 }
263
264 // Check for the existence of the player's pip button at regular intervals
265 const pipInterval = setInterval(() => {
266
267 let playerPip = document.querySelector(`[data-playerid="${playerId}"] [data-plyr="pip"]`);
268 if (playerPip) {
269 clearInterval(pipInterval);
270
271 let options = document.querySelector(`[data-playerid="${playerId}"]`).getAttribute('data-options');
272
273 options = JSON.parse(options);
274 if (!options.self_hosted) {
275
276 const iframeSelector = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper`);
277
278 // Add click event listener to toggle the pip mode
279 playerPip.addEventListener('click', () => {
280 iframeSelector.classList.toggle('pip-mode');
281
282 let parentElement = iframeSelector.parentElement;
283 while (parentElement) {
284 parentElement.style.zIndex = '9999';
285 parentElement = parentElement.parentElement;
286 }
287
288 });
289
290
291
292 if (options.pip) {
293 iframeSelector.appendChild(pipPlayIconElement);
294 iframeSelector.appendChild(pipPauseIconElement);
295 iframeSelector.appendChild(pipCloseElement);
296 const pipPlay = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-play`);
297 const pipPause = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-pause`);
298 const pipClose = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-close`);
299
300 pipClose.addEventListener('click', () => {
301 iframeSelector.classList.remove('pip-mode');
302 });
303
304
305 iframeSelector.addEventListener('click', () => {
306 const ariaPressedValue = document.querySelector(`[data-playerid="${playerId}"] .plyr__controls [data-plyr="play"]`).getAttribute('aria-pressed');
307
308 if (ariaPressedValue === 'true') {
309 pipPause.style.display = 'none';
310 pipPlay.style.display = 'flex';
311 } else {
312 pipPlay.style.display = 'none';
313 pipPause.style.display = 'flex';
314 }
315 });
316
317 }
318
319
320 }
321 }
322
323 }, 200);
324
325 }
326