PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.4.8
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.4.8
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 6 months ago vendor 9 months ago admin.build.js 7 months ago admin.js 9 months ago analytics-tracker.js 9 months ago analytics.build.js 6 months ago blocks.build.js 6 months ago carousel.js 1 year ago documents-viewer-script.js 3 years ago feature-notices.js 7 months ago front.js 6 months ago frontend.build.js 9 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 9 months ago instafeed.js 7 months ago lazy-load.js 6 months ago license.js 7 months ago meetup-timezone.js 6 months ago preview.js 9 months ago settings.js 6 months ago sponsored.js 9 months ago
initplyr.js
317 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 if (posterElement && posterElement.style.backgroundImage) {
246 wrapper.style.opacity = '1';
247 clearInterval(interval);
248 }
249 }, 200);
250
251 }
252
253 }
254
255 // Check for the existence of the player's pip button at regular intervals
256 const pipInterval = setInterval(() => {
257
258 let playerPip = document.querySelector(`[data-playerid="${playerId}"] [data-plyr="pip"]`);
259 if (playerPip) {
260 clearInterval(pipInterval);
261
262 let options = document.querySelector(`[data-playerid="${playerId}"]`).getAttribute('data-options');
263
264 options = JSON.parse(options);
265 if (!options.self_hosted) {
266
267 const iframeSelector = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper`);
268
269 // Add click event listener to toggle the pip mode
270 playerPip.addEventListener('click', () => {
271 iframeSelector.classList.toggle('pip-mode');
272
273 let parentElement = iframeSelector.parentElement;
274 while (parentElement) {
275 parentElement.style.zIndex = '9999';
276 parentElement = parentElement.parentElement;
277 }
278
279 });
280
281
282
283 if (options.pip) {
284 iframeSelector.appendChild(pipPlayIconElement);
285 iframeSelector.appendChild(pipPauseIconElement);
286 iframeSelector.appendChild(pipCloseElement);
287 const pipPlay = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-play`);
288 const pipPause = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-pause`);
289 const pipClose = document.querySelector(`[data-playerid="${playerId}"] .plyr__video-wrapper .pip-close`);
290
291 pipClose.addEventListener('click', () => {
292 iframeSelector.classList.remove('pip-mode');
293 });
294
295
296 iframeSelector.addEventListener('click', () => {
297 const ariaPressedValue = document.querySelector(`[data-playerid="${playerId}"] .plyr__controls [data-plyr="play"]`).getAttribute('aria-pressed');
298
299 if (ariaPressedValue === 'true') {
300 pipPause.style.display = 'none';
301 pipPlay.style.display = 'flex';
302 } else {
303 pipPlay.style.display = 'none';
304 pipPause.style.display = 'flex';
305 }
306 });
307
308 }
309
310
311 }
312 }
313
314 }, 200);
315
316 }
317