PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / trunk
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more vtrunk
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 / front.js
embedpress / assets / js Last commit date
chunks 1 week ago vendor 8 months ago admin.build.js 1 week ago admin.js 3 months ago analytics-tracker.js 4 weeks ago analytics.build.js 1 week ago blocks.build.js 1 week ago carousel.js 1 year ago custom-player.build.js 1 week ago documents-viewer-script.js 3 months ago ep-pdf-lightbox.js 3 months ago ep-view-count.js 1 week ago ep-yt-queue.js 4 weeks ago feature-notices.js 7 months ago front.js 4 weeks ago frontend.build.js 3 months ago gallery-justify.js 1 week ago gutneberg-script.js 1 month ago index.html 7 years ago initCarousel.js 2 years ago initplyr.js 1 month ago instafeed.js 4 weeks ago instagram-shortcode-generator.js 1 month ago lazy-load.js 6 months ago license.js 3 months ago meetup-timezone.js 3 months ago onboarding.build.js 1 week ago pdf-gallery-elementor-editor.js 3 months ago pdf-gallery.js 3 months ago preview.js 8 months ago settings.js 3 months ago sponsored.js 9 months ago
front.js
1571 lines
1 /**
2 * @package EmbedPress
3 * @author EmbedPress <help@embedpress.com>
4 * @copyright Copyright (C) 2023 EmbedPress. All rights reserved.
5 * @license GPLv2 or later
6 * @since 1.7.0
7 */
8
9
10
11 let epGlobals = {};
12
13 (function ($) {
14 'use strict';
15 // function equivalent to jquery ready()
16 function ready(fn) {
17 if (document.readyState !== 'loading') {
18 fn();
19 } else {
20 document.addEventListener('DOMContentLoaded', fn);
21 }
22 }
23
24 ready(function () {
25 let option = {
26 forceObject: true,
27 };
28 let selector = document.querySelectorAll('.embedpress-embed-document-pdf');
29 if (selector.length) {
30 selector.forEach((function (value, index, thisArg) {
31 let id = value.dataset['emid'];
32 let src = value.dataset['emsrc'];
33 PDFObject?.embed(src, "." + id, option);
34 }));
35 }
36 if (typeof epGlobals.youtubeChannelGallery === 'function') {
37 epGlobals.youtubeChannelGallery();
38 }
39 });
40
41 /**
42 *
43 * Make embeds responsive so they don't overflow their container.
44 */
45
46 /**
47 * Add max-width & max-height to <iframe> elements, depending on their width & height props.
48 *
49 *
50 * @return {void}
51 */
52 function embedPressResponsiveEmbeds() {
53 var proportion, parentWidth;
54
55 // Loop iframe elements.
56 document.querySelectorAll('iframe').forEach(function (iframe) {
57 // Only continue if the iframe has a width & height defined.
58 if (iframe.width && iframe.height) {
59 // Calculate the proportion/ratio based on the width & height.
60 proportion = parseFloat(iframe.width) / parseFloat(iframe.height);
61 // Get the parent element's width.
62 parentWidth = parseFloat(window.getComputedStyle(iframe.parentElement, null).width.replace('px', ''));
63 // Set the max-width & height.
64 iframe.style.maxWidth = '100%';
65 iframe.style.maxHeight = Math.round(parentWidth / proportion).toString() + 'px';
66 }
67 });
68 }
69
70 epGlobals.handlePosterImageLoad = function () {
71 var posterImages = document.querySelectorAll(".plyr__poster");
72 var videoWrappers = document.querySelectorAll("[data-playerid]");
73
74 // If no poster images found, make all players visible immediately
75 if (!posterImages.length) {
76 videoWrappers.forEach(function (videoWrapper) {
77 videoWrapper.style.opacity = "1";
78 });
79 return;
80 }
81
82 posterImages.forEach(function (posterImage) {
83 if (posterImage) {
84 videoWrappers.forEach(function (videoWrapper) {
85 // Check if already visible via computed style
86 var posterImageStyle = window.getComputedStyle(posterImage);
87 if (posterImageStyle.getPropertyValue('background-image') !== 'none') {
88 videoWrapper.style.opacity = "1";
89 return;
90 }
91
92 var observer = new MutationObserver(function (mutationsList, observer) {
93 var posterImageStyle = window.getComputedStyle(posterImage);
94 if (posterImageStyle.getPropertyValue('background-image') !== 'none') {
95 setTimeout(function () {
96 videoWrapper.style.opacity = "1";
97 }, 200);
98 observer.disconnect();
99 }
100 });
101
102 observer.observe(posterImage, { attributes: true, attributeFilter: ['style'] });
103
104 // Fallback timeout to ensure player becomes visible
105 setTimeout(function () {
106 observer.disconnect();
107 videoWrapper.style.opacity = "1";
108 }, 5000);
109 });
110 }
111 });
112 }
113
114 // Run on initial load.
115 embedPressResponsiveEmbeds();
116
117 // Run on resize.
118 window.onresize = embedPressResponsiveEmbeds;
119
120
121 function hasClass(ele, cls) {
122 return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
123 }
124
125 function addClass(ele, cls) {
126 if (!hasClass(ele, cls)) ele.className += " " + cls;
127 }
128
129 function removeClass(ele, cls) {
130 if (hasClass(ele, cls)) {
131 var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
132 ele.className = ele.className.replace(reg, " ");
133 }
134 }
135 if (!Element.prototype.matches) {
136 Element.prototype.matches =
137 Element.prototype.matchesSelector ||
138 Element.prototype.webkitMatchesSelector ||
139 Element.prototype.mozMatchesSelector ||
140 Element.prototype.msMatchesSelector ||
141 Element.prototype.oMatchesSelector ||
142 function (s) {
143 var matches = (this.document || this.ownerDocument).querySelectorAll(s),
144 i = matches.length;
145 while (--i >= 0 && matches.item(i) !== this) { }
146 return i > -1;
147 };
148 }
149 var delegate = function (el, evt, sel, handler) {
150 el.addEventListener(evt, function (event) {
151 var t = event.target;
152 while (t && t !== this) {
153 if (t.matches(sel)) {
154 handler.call(t, event);
155 }
156 t = t.parentNode;
157 }
158 });
159 };
160
161 function sendRequest(url, postData, callback) {
162 var req = createXMLHTTPObject();
163 if (!req) return;
164 var method = postData ? "POST" : "GET";
165 req.open(method, url, true);
166 if (postData) {
167 req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
168 }
169 req.onreadystatechange = function () {
170 if (req.readyState != 4) return;
171 if (req.status != 200 && req.status != 304) {
172 return;
173 }
174 callback(req);
175 };
176 if (req.readyState == 4) return;
177 req.send(postData);
178 }
179
180 var XMLHttpFactories = [
181 function () {
182 return new XMLHttpRequest();
183 },
184 function () {
185 return new ActiveXObject("Msxml3.XMLHTTP");
186 },
187 function () {
188 return new ActiveXObject("Msxml2.XMLHTTP.6.0");
189 },
190 function () {
191 return new ActiveXObject("Msxml2.XMLHTTP.3.0");
192 },
193 function () {
194 return new ActiveXObject("Msxml2.XMLHTTP");
195 },
196 function () {
197 return new ActiveXObject("Microsoft.XMLHTTP");
198 },
199 ];
200
201 function createXMLHTTPObject() {
202 var xmlhttp = false;
203 for (var i = 0; i < XMLHttpFactories.length; i++) {
204 try {
205 xmlhttp = XMLHttpFactories[i]();
206 } catch (e) {
207 continue;
208 }
209 break;
210 }
211 return xmlhttp;
212 }
213
214 epGlobals.youtubeChannelGallery = function () {
215 var playerWraps = document.getElementsByClassName("ep-player-wrap");
216 if (playerWraps && playerWraps.length) {
217 for (var i = 0, im = playerWraps.length; im > i; i++) {
218 youtubeChannelEvents(playerWraps[i])
219 }
220 }
221 }
222
223 function youtubeChannelEvents(playerWrap) {
224
225 delegate(playerWrap, "click", ".item", function (event) {
226 var embed = "https://www.youtube.com/embed/";
227 var vid = this.getAttribute("data-vid");
228 var iframe = playerWrap.getElementsByTagName("iframe");
229
230 console.log
231
232 if (vid) {
233 if (iframe) {
234 var vidSrc = iframe[0]?.src.replace(/(.*\/embed\/)([^\?&"'>]+)(.+)?/, `\$1${vid}\$3`);
235 if (vidSrc.indexOf('autoplay') > 0) {
236 vidSrc = vidSrc.replace('autoplay=0', 'autoplay=1');
237 }
238 else {
239 vidSrc += '&autoplay=1';
240 }
241 iframe[0].src = vidSrc;
242 playerWrap.scrollIntoView();
243 }
244 }
245 });
246
247 var currentPage = 1;
248
249 // The new layout-queue uses a different shell (.ep-yt-queue) with its
250 // own JS in ep-yt-queue.js, so .ep-youtube__content__block won't exist
251 // and we should bail out of the legacy channel-gallery pagination/click
252 // wiring instead of throwing.
253 let epContentBlock = playerWrap.querySelector('.ep-youtube__content__block');
254 if (!epContentBlock) return;
255 let nearestEpContentId = epContentBlock.getAttribute('data-unique-id');
256 let parentElement = epContentBlock.parentElement;
257
258 // Get the value of data-channel-url attribute from a sibling
259 let channelUrlEl = parentElement.querySelector('[data-channel-url]');
260 let channelUrl = channelUrlEl ? channelUrlEl.getAttribute('data-channel-url') : '';
261
262
263 delegate(playerWrap, "click", ".ep-next, .ep-prev", function (event) {
264 const totalPages = event.target.closest('.ose-youtube').getAttribute('data-total-pages');
265 const closestClass = event.target.closest('.ose-youtube').classList;
266
267 const activePage = document.querySelector(`.${closestClass[1]} .embedpress-page-active`);
268 if (activePage) {
269 document.querySelector(`.${closestClass[1]} .embedpress-page-active`).classList.remove('embedpress-page-active');
270 }
271
272
273
274 var isNext = this.classList.contains("ep-next");
275
276 if (isNext) {
277 currentPage++;
278 } else {
279 currentPage--;
280 }
281
282 var data = {
283 action: "youtube_rest_api",
284 playlistid: this.getAttribute("data-playlistid"),
285 pagetoken: this.getAttribute("data-pagetoken"),
286 pagesize: this.getAttribute("data-pagesize"),
287 channelUrl: channelUrl,
288 currentpage: currentPage
289 };
290
291 var formBody = [];
292 for (var property in data) {
293 var encodedKey = encodeURIComponent(property);
294 var encodedValue = encodeURIComponent(data[property]);
295 formBody.push(encodedKey + "=" + encodedValue);
296 }
297 formBody = formBody.join("&");
298
299 var galleryWrapper = playerWrap.getElementsByClassName(
300 "ep-youtube__content__block"
301 );
302
303 playerWrap.setAttribute('data-current-page', currentPage);
304
305
306 let x = 1;
307
308 sendRequest(embedpressFrontendData.ajaxurl, formBody, function (request) {
309 if (galleryWrapper && galleryWrapper[0] && request.responseText) {
310 var response = JSON.parse(request.responseText);
311 galleryWrapper[0].outerHTML = response.html;
312
313 var currentPageNode =
314 galleryWrapper[0].getElementsByClassName("current-page");
315 if (currentPageNode && currentPageNode[0]) {
316 currentPageNode[0].textContent = currentPage;
317
318 }
319 }
320 });
321
322 const intervalID = setInterval(() => {
323 x++
324
325 if (playerWrap.querySelector('.ep-youtube__content__block')) {
326 const newNearestEpContentId = playerWrap
327 .querySelector('.ep-youtube__content__block')
328 .getAttribute('data-unique-id');
329
330 if (newNearestEpContentId !== nearestEpContentId && playerWrap.querySelector(`[data-page="${currentPage}"]`)) {
331 playerWrap.querySelector(`[data-page="${currentPage}"]`).classList.add('embedpress-page-active');
332 nearestEpContentId = newNearestEpContentId;
333 clearInterval(intervalID);
334 }
335 }
336
337 if (x > 100) {
338 clearInterval(intervalID);
339 }
340 }, 100);
341
342 });
343 }
344
345 //Load more for OpenaSea collection
346 const epLoadMore = () => {
347
348 $('.embedpress-gutenberg-wrapper .ep-nft-gallery-wrapper').each(function () {
349 let selctorEl = `[data-nftid='${$(this).data('nftid')}']`;
350
351 let loadmorelabel = $(selctorEl).data('loadmorelabel');
352 let iconcolor = $(selctorEl + " .nft-loadmore").data('iconcolor');
353
354 let spinicon = `<svg width="18" height="18" fill="${iconcolor || '#fff'}" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.spinner_GuJz{transform-origin:center;animation:spinner_STY6 1.5s linear infinite}@keyframes spinner_STY6{100%{transform:rotate(360deg)}}</style><g class="spinner_GuJz"><circle cx="3" cy="12" r="2"/><circle cx="21" cy="12" r="2"/><circle cx="12" cy="21" r="2"/><circle cx="12" cy="3" r="2"/><circle cx="5.64" cy="5.64" r="2"/><circle cx="18.36" cy="18.36" r="2"/><circle cx="5.64" cy="18.36" r="2"/><circle cx="18.36" cy="5.64" r="2"/></g></svg>`;
355
356 $(selctorEl + ` .ep_nft_item`).slice(0, $(selctorEl).data('itemparpage')).show();
357 $('.embedpress-gutenberg-wrapper .ep-nft-gallery-wrapper .ep-loadmore-wrapper button').css('display', 'flex');
358
359 $(selctorEl + " .nft-loadmore").click(function (e) {
360 //change the text of the button
361 $(this).html(loadmorelabel + spinicon);
362 //disable the button
363 $(this).prop("disabled", true);
364 //wait for 1 seconds
365 setTimeout(function () {
366 //change the text back
367 $(selctorEl + " .nft-loadmore").text(loadmorelabel);
368 //enable the button
369 $(selctorEl + " .nft-loadmore").prop("disabled", false);
370 $(selctorEl + " .ep_nft_item:hidden").slice(0, $(selctorEl).data('itemparpage')).fadeIn("slow");
371 if ($(selctorEl + " .ep_nft_item:hidden").length == 0) {
372 $(selctorEl + " .nft-loadmore").fadeOut("slow");
373 }
374 }, 500);
375 });
376 });
377 };
378
379 if ($('.embedpress-gutenberg-wrapper .ep-nft-gallery-wrapper').length > 0) {
380 epLoadMore();
381 }
382
383 // Content protection system function
384 const unlockSubmitHander = (perentSel, that) => {
385 var ep_client_id = jQuery(that).closest('form').find('input[name="ep_client_id"]').val();
386 var password = jQuery(`input[name="pass_${ep_client_id}"]`).val();
387 var post_id = jQuery(`input[name="post_id"]`).val();
388 const buttonText = jQuery(that).closest('.password-form-container').find('input[type="submit"]').val();
389 const unlokingText = jQuery(that).data('unlocking-text');
390
391
392 var data = {
393 'action': 'lock_content_form_handler',
394 'client_id': ep_client_id,
395 'password': password,
396 'post_id': post_id,
397 };
398
399 jQuery('#' + perentSel + '-' + ep_client_id + ' .password-form input[type="submit"]').val(unlokingText);
400
401 jQuery.post(embedpressFrontendData.ajaxurl, data, function (response) {
402 if (response.success) {
403 if (!response.embedHtml) {
404 jQuery('#' + perentSel + '-' + ep_client_id + ' .password-form input[type="submit"]').val(buttonText);
405 jQuery('#' + perentSel + '-' + ep_client_id + ' .password-form input[type="password"]').val('');
406 jQuery(that).closest('.password-form-container').find('.error-message').removeClass('hidden');
407 }
408 else {
409 // Replace the content inside the wrapper, keeping the wrapper itself
410 const wrapperEl = jQuery('#' + perentSel + '-' + ep_client_id);
411 const parentWrapper = wrapperEl.parent('.ep-embed-content-wraper');
412
413 if (parentWrapper.length > 0) {
414 // If there's a parent .ep-embed-content-wraper, replace its content
415 parentWrapper.html(response.embedHtml);
416 } else {
417 // Otherwise replace the wrapper content directly
418 wrapperEl.html(response.embedHtml);
419 }
420
421 if (jQuery('#' + perentSel + '-' + ep_client_id + ' .ose-youtube').length > 0) {
422 epGlobals.youtubeChannelGallery();
423 }
424
425 if ($('.embedpress-gutenberg-wrapper .ep-nft-gallery-wrapper').length > 0) {
426 epLoadMore();
427 }
428
429 // Custom player initialization when content protection enabled
430 const targetEl = parentWrapper.length > 0 ? parentWrapper[0] : wrapperEl[0];
431 targetEl?.classList?.remove('plyr-initialized');
432
433 if (typeof initPlayer === 'function') {
434 initPlayer(targetEl);
435 }
436 if (embedpressFrontendData.isProPluginActive) {
437 const adIdEl = document.querySelector('#' + perentSel + '-' + ep_client_id + ' [data-sponsored-id]');
438 if (typeof adInitialization === 'function') {
439 adInitialization(adIdEl, adIdEl?.getAttribute('data-ad-index'));
440 }
441 }
442
443 }
444 } else {
445 jQuery('#password-error_' + ep_client_id).html(response.form);
446 jQuery('#password-error_' + ep_client_id).show();
447 }
448 }, 'json');
449 }
450
451 // unlockSubmitHander called for gutentberg
452 jQuery('.ep-gutenberg-content .password-form').submit(function (e) {
453 e.preventDefault(); // Prevent the default form submission
454 unlockSubmitHander('ep-gutenberg-content', this);
455 });
456
457 jQuery('.ep-shortcode-content .password-form').submit(function (e) {
458 e.preventDefault(); // Prevent the default form submission
459 unlockSubmitHander('ep-shortcode-content', this);
460 });
461
462 window.addEventListener('load', function (e) {
463 const urlParams = new URLSearchParams(window.location.search);
464 const hash = urlParams.get('hash');
465
466 // find the element with the matching id
467 const element = document.getElementById(hash);
468
469 if (element) {
470 element.scrollIntoView({ behavior: 'smooth' });
471 }
472
473 });
474
475 // Get the insta-gallery container element
476 const getPopupTemplate = (instPost, hashtag = '', accountType) => {
477
478 let instaPostData = JSON.parse(instPost);
479
480
481 let likeIcon = '<svg aria-label="Like" class="x1lliihq x1n2onr6" color="#262626" fill="#262626" height="24" viewBox="0 0 24 24" width="24"><path d="M16.792 3.904A4.989 4.989 0 0 1 21.5 9.122c0 3.072-2.652 4.959-5.197 7.222-2.512 2.243-3.865 3.469-4.303 3.752-.477-.309-2.143-1.823-4.303-3.752C5.141 14.072 2.5 12.167 2.5 9.122a4.989 4.989 0 0 1 4.708-5.218 4.21 4.21 0 0 1 3.675 1.941c.84 1.175.98 1.763 1.12 1.763s.278-.588 1.11-1.766a4.17 4.17 0 0 1 3.679-1.938m0-2a6.04 6.04 0 0 0-4.797 2.127 6.052 6.052 0 0 0-4.787-2.127A6.985 6.985 0 0 0 .5 9.122c0 3.61 2.55 5.827 5.015 7.97.283.246.569.494.853.747l1.027.918a44.998 44.998 0 0 0 3.518 3.018 2 2 0 0 0 2.174 0 45.263 45.263 0 0 0 3.626-3.115l.922-.824c.293-.26.59-.519.885-.774 2.334-2.025 4.98-4.32 4.98-7.94a6.985 6.985 0 0 0-6.708-7.218Z"/></svg>';
482
483 if (instaPostData.like_count > 0) {
484 likeIcon = '<svg aria-label="Unlike" class="x1lliihq x1n2onr6" color="#FF3040" fill="#FF3040" height="24" viewBox="0 0 48 48" width="24"><path d="M34.6 3.1c-4.5 0-7.9 1.8-10.6 5.6-2.7-3.7-6.1-5.5-10.6-5.5C6 3.1 0 9.6 0 17.6c0 7.3 5.4 12 10.6 16.5.6.5 1.3 1.1 1.9 1.7l2.3 2c4.4 3.9 6.6 5.9 7.6 6.5.5.3 1.1.5 1.6.5s1.1-.2 1.6-.5c1-.6 2.8-2.2 7.8-6.8l2-1.8c.7-.6 1.3-1.2 2-1.7C42.7 29.6 48 25 48 17.6c0-8-6-14.5-13.4-14.5z"/></svg>';
485 }
486
487 const commentsIcon = '<svg aria-label="Comment" class="x1lliihq x1n2onr6" color="#000" height="24" viewBox="0 0 24 24" width="24"><path d="M20.656 17.008a9.993 9.993 0 1 0-3.59 3.615L22 22Z" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="2"/></svg>';
488
489 const shareIcon = '<svg width="20" height="20" viewBox="0 0 0.6 0.6" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg"><path stroke-width="1" d="m.543.282-.2-.2A.025.025 0 0 0 .3.1v.089a.275.275 0 0 0-.25.274V.5a.025.025 0 0 0 .045.015.3.3 0 0 1 .197-.101L.3.413V.5a.025.025 0 0 0 .043.018l.2-.2a.025.025 0 0 0 0-.035M.35.44V.388A.025.025 0 0 0 .325.363L.286.365a.35.35 0 0 0-.185.074.225.225 0 0 1 .224-.201A.025.025 0 0 0 .35.213V.16L.49.3Z"/></svg>';
490
491 const instaIcon = '<svg width="18" height="18" viewBox="0 0 0.338 0.338" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M.248.079H.27M.102.012h.135a.09.09 0 0 1 .09.09v.135a.09.09 0 0 1-.09.09H.102a.09.09 0 0 1-.09-.09V.102a.09.09 0 0 1 .09-.09ZM.17.237a.068.068 0 1 1 0-.135.068.068 0 0 1 0 .135Z" stroke="#000" stroke-width=".032"/></svg>';
492
493
494
495 const instaUserInfo = instPost.user_info;
496
497 let getDate = new Date(instaPostData.timestamp);
498 getDate = getDate.toLocaleString('en-US', { day: 'numeric', month: 'short', year: 'numeric' });
499
500 let getTime = new Date(instaPostData.timestamp);
501 getTime = getTime.toLocaleString('en-US', { hour12: false, hour: 'numeric', minute: 'numeric', second: 'numeric' });
502
503 let captionText = instaPostData.caption ? instaPostData.caption : '';
504 const tagRegex = /(#\w+)/g;
505
506 const wrapTag = (match) => {
507 const tag = match.substring(1); // Remove the '#' character
508 const tagUrl = `https://www.instagram.com/explore/tags/${tag}`;
509 return `<span class="tag-wrapper"><a target="_blank" href="${tagUrl}">${match}</a></span>`;
510 };
511
512 captionText = captionText.replace(tagRegex, wrapTag);
513
514 let carouselTemplate = '';
515 if (instaPostData.media_type === 'CAROUSEL_ALBUM') {
516 carouselTemplate += `<div class="popup-carousel"><div class="cg-carousel__track js-carousel__track">`;
517
518 instaPostData.children.data?.map((item) => {
519 if (item.media_type?.toLowerCase() === 'video') {
520 carouselTemplate += `<video width="630" class="popup-media-image cg-carousel__slide js-carousel__slide" controls src="${item.media_url || ''}" alt="${item.caption || ''}" controlsList="nodownload"></video>`;
521 }
522 else {
523 carouselTemplate += `<img width="630" class="popup-media-image cg-carousel__slide js-carousel__slide" src="${item.media_url || ''}" alt="${item.caption || ''}" />`;
524 }
525 });
526
527 carouselTemplate += `</div></div>`;
528
529 carouselTemplate += `<div class="cg-carousel__btns">
530 <button type="button" class="cg-carousel__btn js-carousel__prev-1" aria-label="Previous"><svg aria-hidden="true" focusable="false" width="20" height="30" viewBox="-5 0 23 23" xmlns="http://www.w3.org/2000/svg"><path d="M11.24.29.361 10.742l-.06.054a.97.97 0 0 0-.301.642v.124a.97.97 0 0 0 .3.642l.054.044L11.239 22.71a1.061 1.061 0 0 0 1.459 0 .964.964 0 0 0 0-1.402l-10.15-9.746 10.15-9.87a.964.964 0 0 0 0-1.402 1.061 1.061 0 0 0-1.459 0Z" fill="#fff"/></svg></button>
531
532 <button type="button" class="cg-carousel__btn js-carousel__next-1" aria-label="Next"><svg aria-hidden="true" focusable="false" width="20" height="30" viewBox="-5 0 23 23" xmlns="http://www.w3.org/2000/svg"><path d="m1.76.29 10.879 10.452.06.054a.97.97 0 0 1 .301.642v.124a.97.97 0 0 1-.3.642l-.054.044L1.761 22.71a1.061 1.061 0 0 1-1.459 0 .964.964 0 0 1 0-1.402l10.15-9.746-10.15-9.87a.964.964 0 0 1 0-1.402 1.061 1.061 0 0 1 1.459 0Z" fill="#fff"/></svg></button>
533 </div>`
534 }
535 else {
536 if (instaPostData.media_type?.toLowerCase() === 'video') {
537 carouselTemplate += `<video width="630" class="popup-media-image" controls src="${instaPostData.media_url || ''}" alt="${instaPostData.caption || ''}"></video>`;
538 }
539 else {
540 carouselTemplate += `<img width="630" class="popup-media-image" src="${instaPostData.media_url || ''}" alt="${instaPostData.caption || ''}" />`;
541 }
542 }
543
544 let srcUrl = `https://www.instagram.com/${instaPostData.username}/`;
545
546 if (hashtag) {
547 instaPostData.username = '#' + hashtag;
548 srcUrl = `https://www.instagram.com/explore/tags/${hashtag}/`;
549 }
550
551
552 let likeComments = '';
553
554 if (embedpressFrontendData.isProPluginActive) {
555 if (instaPostData.show_likes_count == 'true') {
556 likeComments += `
557 <div class="embedpress-inline popup-like-button"><a target="_blank" href="${instaPostData.permalink}">${likeIcon} ${instaPostData.like_count || 0}</a></div>
558 `;
559 }
560 if (instaPostData.show_comments_count == 'true') {
561 likeComments += `
562 <div class="embedpress-inline"><a target="_blank" href="${instaPostData.permalink}">${commentsIcon} ${instaPostData.comments_count || 0}</a></div>
563 `;
564 }
565 }
566
567
568 let followBtn = '';
569 if (instaPostData.popup_follow_button_text == 'false') {
570 instaPostData.popup_follow_button_text = '';
571 }
572 if (instaPostData.popup_follow_button == 'true' || instaPostData.popup_follow_button == 'yes') {
573 followBtn = `<div class="insta-followbtn">
574 <a target="_new" href="${srcUrl}" type="button" class="btn btn-primary">${instaPostData.popup_follow_button_text}</a>
575 </div>`;
576 }
577
578 let popupHtml = '';
579 popupHtml += `
580 <div class="popup-container">
581 <div class="popup-md-9 white">
582 <div class="embedpress-popup-block embedpress-popup-img" id="post-${instaPostData.id}">
583 ${carouselTemplate}
584 </div>
585 </div>
586 <div class="popup-md-3 red">
587 <div class="embedpress-popup-block embedpress-popup-info">
588 <div class="embedpress-popup-header">
589 <div class="embedpress-popup-header-img"> <a target="_blank" href="${srcUrl}"
590 target="_blank" class="embedpress-href">
591 <img decoding="async" loading="lazy" class="embedpress-popup-round" src="${instaPostData.profile_picture_url}" width="30" height="30"> <span class="embedpress-popup-username">${instaPostData.username}</span>
592 </a>
593 </div>
594 ${followBtn}
595 </div>
596 <div class="embedpress-popup-text">${captionText}</div>
597 <div class="embedpress-popup-stats">
598 ${likeComments}
599 <div class="embedpress-inline">
600 <div class="embedpress-popup-share-buttons"> <a
601 href="https://www.facebook.com/sharer/sharer.php?u=${instaPostData.permalink}" target="_blank">
602 <span class="dashicons dashicons-facebook"></span></a> <a
603 href="https://twitter.com/intent/tweet?url=${instaPostData.permalink}"
604 target="_blank"><span>
605 <svg viewBox="0 0 18 18" aria-hidden="true" class="r-4qtqp9 r-yyyyoo r-dnmrzs r-bnwqim r-1plcrui r-lrvibr r-lrsllp r-18jsvk2 r-16y2uox r-8kz0gk" width="18" height="18"><path d="M13.683 1.688h2.481l-5.42 6.195 6.377 8.43h-4.993L8.217 11.2l-4.474 5.113H1.26l5.798-6.626L.941 1.688H6.06l3.535 4.673zm-.871 13.14h1.375L5.313 3.095H3.838z"/></svg>
606 </span></a>
607 <a href="https://www.linkedin.com/shareArticle?mini=true&amp;url=${instaPostData.permalink}"
608 target="_blank"><span class="dashicons dashicons-linkedin"></span></a> <a
609 href="https://pinterest.com/pin/create/button/?url=${instaPostData.permalink}"
610 target="_blank"><span class="dashicons dashicons-pinterest"></span></a></div>
611 <div class="embedpress-href embedpress-popup-share">${shareIcon}</div>
612 </div><div class="embedpress-inline embedpress-popup-instagram-buttons"><a
613 href="${instaPostData.permalink}" target="_blank"
614 class="embedpress-href">${instaIcon}</a></div>
615 </div>
616
617 </div>
618 </div>
619 </div>
620 `;
621
622 // INIT CAROUSEL
623
624
625 return popupHtml;
626 }
627
628 // Add a click event listener to the insta-gallery container
629 epGlobals.instaPopup = (container) => {
630 container?.addEventListener('click', function (event) {
631 // Check if the clicked element has the class insta-gallery-item
632 const instaItem = event.target.closest('.insta-gallery-item');
633
634 if (instaItem) {
635
636 const postData = instaItem.dataset.postdata;
637
638 const postid = instaItem.getAttribute('data-insta-postid');
639 const accountType = container?.closest('.instagram-container')?.getAttribute('data-connected-acc-type');
640
641 let hashtag = '';
642
643 if (instaItem.closest('.instagram-container').getAttribute('data-hashtag')) {
644 hashtag = instaItem?.closest('.instagram-container')?.getAttribute('data-hashtag');
645 }
646
647 const closestPopup = event.target.closest('.ose-instagram-feed')?.querySelector('.insta-popup');
648
649 if (closestPopup) {
650 closestPopup.style.display = 'block';
651 }
652
653
654 var feedElement = event.target.closest('.ose-instagram-feed');
655 if (feedElement) {
656 var popupElement = feedElement.querySelector('.popup-is-initialized');
657 if (popupElement) {
658 popupElement.innerHTML = getPopupTemplate(postData, hashtag, accountType);
659 }
660 }
661
662 if (!document.querySelector(`#post-${postid}`)?.classList.contains('carousel-is-initialized')) {
663 const carousel = new CgCarousel(`#post-${postid}`, { slidesPerView: 1, loop: true }, {});
664
665 const next = document.querySelector(`#post-${postid} .js-carousel__next-1`);
666 next?.addEventListener('click', () => carousel.next());
667
668 const prev = document.querySelector(`#post-${postid} .js-carousel__prev-1`);
669 prev?.addEventListener('click', () => carousel.prev());
670
671 document.querySelector(`#post-${postid}`)?.classList.add('carousel-is-initialized');
672 }
673
674 }
675 });
676 }
677
678
679 const instaContainers = document.querySelectorAll('.embedpress-gutenberg-wrapper .insta-gallery');
680 if (instaContainers.length > 0) {
681 instaContainers.forEach((container) => {
682 epGlobals.instaPopup(container);
683 });
684 }
685
686 $('.popup-close').click(function (e) {
687 // Hide the popup by setting display to none
688 $('.insta-popup').hide();
689 $('.popup-container').remove();
690 });
691
692 $(document).on('click', function (e) {
693 if (e.target.classList.contains('popup-wrapper')) {
694 $('.insta-popup').hide();
695 $('.popup-container').remove();
696 }
697 });
698
699
700 const instafeeds = document.querySelectorAll('.ose-instagram-feed');
701
702 epGlobals.initializeTabs = (containerEl) => {
703
704 // Initial tab selection
705 showItems('ALL');
706
707 containerEl.addEventListener('click', function (event) {
708 const clickedElement = event.target;
709 if (!clickedElement) {
710 return; // No element clicked, ignore the event
711 }
712
713 if (containerEl.querySelector('.load-more-button-container') && (clickedElement.getAttribute('data-media-type') === 'VIDEO' || clickedElement.getAttribute('data-media-type') === 'CAROUSEL_ALBUM')) {
714 containerEl.querySelector('.load-more-button-container').style.display = 'none';
715 }
716 else if (containerEl.querySelector('.load-more-button-container') && (clickedElement.getAttribute('data-media-type') === 'ALL')) {
717 containerEl.querySelector('.load-more-button-container').style.display = 'flex';
718 }
719
720 // Handle tab click
721 if (clickedElement.matches('.tabs li')) {
722 if (clickedElement.classList.contains('active')) {
723 return;
724 } else {
725 const mediaType = clickedElement.getAttribute('data-media-type');
726 showItems(mediaType);
727
728 const tabs = containerEl.querySelectorAll('.tabs li');
729 tabs.forEach(t => t.classList.remove('active'));
730 clickedElement.classList.add('active');
731 }
732 }
733
734 });
735
736 function showItems(mediaType) {
737 const items = containerEl.getElementsByClassName('insta-gallery-item');
738 for (let i = 0; i < items.length; i++) {
739 const item = items[i];
740 if (mediaType === 'ALL' || item.getAttribute('data-media-type') === mediaType) {
741 item.style.display = 'block';
742 } else {
743 item.style.display = 'none';
744 }
745 }
746 }
747 }
748
749 epGlobals.instaLoadMore = () => {
750 // Unbind any previously bound click event to avoid multiple bindings
751 $('.insta-load-more-button').off('click').on('click', function (e) {
752 const that = $(this);
753 const loadmoreBtn = that.closest('.load-more-button-container');
754 const loadmoreKey = loadmoreBtn.data('loadmorekey');
755 const connectedAccount = that.closest('.instagram-container').data('connected-acc-type');
756 const feedType = that.closest('.instagram-container').data('feed-type');
757 const hashtagId = that.closest('.instagram-container').data('hashtag-id');
758 const userId = that.closest('.instagram-container').data('uid');
759 let loadedPosts = loadmoreBtn.data('loaded-posts') || 0;
760 let postsPerPage = loadmoreBtn.data('posts-per-page') || 0;
761 const params = JSON.stringify(that.closest('.instagram-container').data('params'));
762
763
764 const instaContainer = that.closest('.instagram-container');
765
766 const spinicon = `<svg class="insta-loadmore-spinicon" width="18" height="18" fill="${'#fff'}" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.spinner_GuJz{transform-origin:center;animation:spinner_STY6 1.5s linear infinite}@keyframes spinner_STY6{100%{transform:rotate(360deg)}}</style><g class="spinner_GuJz"><circle cx="3" cy="12" r="2"/><circle cx="21" cy="12" r="2"/><circle cx="12" cy="21" r="2"/><circle cx="12" cy="3" r="2"/><circle cx="5.64" cy="5.64" r="2"/><circle cx="18.36" cy="18.36" r="2"/><circle cx="5.64" cy="18.36" r="2"/><circle cx="18.36" cy="5.64" r="2"/></g></svg>`;
767
768 // Check if no spinicon exists
769 if (instaContainer.find('.insta-loadmore-spinicon').length === 0) {
770 that.append(spinicon);
771 }
772
773 that.attr('disabled', true);
774
775 var data = {
776 'action': 'loadmore_data_handler',
777 'user_id': userId,
778 'loaded_posts': loadedPosts,
779 'posts_per_page': postsPerPage,
780 'feed_type': feedType,
781 'connected_account_type': connectedAccount,
782 'loadmore_key': loadmoreKey,
783 'params': params,
784 '_nonce': embedpressFrontendData.nonce
785 };
786
787 if (feedType === 'hashtag_type') {
788 data.hashtag_id = hashtagId;
789 }
790
791 jQuery.post(embedpressFrontendData.ajaxurl, data, function (response) {
792 if (response.total_feed_posts >= response.next_post_index) {
793 var $responseHtml = $(response.html);
794
795 instaContainer.find('.insta-gallery').append($responseHtml);
796 that.removeAttr('disabled');
797
798 instaContainer.find('.insta-loadmore-spinicon').remove();
799
800 loadedPosts = response.next_post_index;
801
802 loadmoreBtn.data('loaded-posts', loadedPosts);
803
804 // After loading more items, reinitialize the tabs for the specific container
805 const containerEl = loadmoreBtn.closest('.ose-instagram-feed')[0];
806 epGlobals.initializeTabs(containerEl);
807
808 if (response.total_feed_posts === response.next_post_index) {
809 loadmoreBtn.remove();
810 }
811 } else {
812 loadmoreBtn.remove();
813 }
814 });
815 });
816 }
817
818
819 if (instafeeds.length > 0) {
820 instafeeds.forEach(function (feed) {
821 epGlobals.initializeTabs(feed);
822 });
823 }
824
825 if ($('.embedpress-gutenberg-wrapper .ose-instagram-feed').length > 0) {
826 epGlobals.instaLoadMore();
827 }
828
829 $(document).on({
830 mouseenter: function () {
831 $('.embedpress-popup-share-buttons').addClass('show');
832 },
833 mouseleave: function () {
834 var buttons = $('.embedpress-popup-share-buttons');
835 setTimeout(function () {
836 if (!buttons.is(':hover')) buttons.removeClass('show');
837 }, 200);
838 }
839 }, '.embedpress-href.embedpress-popup-share, .embedpress-popup-share-buttons');
840
841 $(document).on({
842 mouseenter: function () {
843 $(this).addClass('show');
844 },
845 mouseleave: function () {
846 $(this).removeClass('show');
847 }
848 }, '.embedpress-popup-share-buttons');
849
850
851
852
853
854 })(jQuery);
855
856
857
858 document.addEventListener('DOMContentLoaded', function () {
859
860 epGlobals.initCarousel = (carouselSelector, options, carouselId) => {
861
862 const carouselOptions = {
863 slidesPerView: options.slideshow,
864 spacing: options.spacing,
865 loop: options.loop,
866 autoplay: options.autoplay,
867 transitionSpeed: options.transitionspeed,
868 autoplaySpeed: options.autoplayspeed,
869 arrows: options.arrows,
870 breakpoints: {
871 0: {
872 slidesPerView: 1
873 },
874 768: {
875 slidesPerView: Math.max(1, parseInt(options.slideshow, 10) - 1)
876 },
877 1024: {
878 slidesPerView: Math.max(1, parseInt(options.slideshow, 10))
879 }
880 }
881 };
882
883 // INIT CAROUSEL
884 const carousel = new CgCarousel(carouselSelector, carouselOptions, {});
885
886 // Navigation
887 const next = document.querySelector(`[data-carouselid="${carouselId}"] #js-carousel__next-1`);
888 next?.addEventListener('click', () => carousel.next());
889
890 const prev = document.querySelector(`[data-carouselid="${carouselId}"] #js-carousel__prev-1`);
891 prev?.addEventListener('click', () => carousel.prev());
892 }
893
894 const instaWrappers = document.querySelectorAll('.ep-embed-content-wraper');
895
896 if (instaWrappers.length > 0) {
897 instaWrappers.forEach((wrapper) => {
898 const carouselId = wrapper.getAttribute('data-carouselid');
899
900 if (!carouselId) return;
901
902 let options = wrapper.getAttribute(`data-carousel-options`);
903
904 options = JSON.parse(options);
905 const carouselSelector = `[data-carouselid="${carouselId}"] .embedpress-insta-container`;
906
907 if (options.arrows) {
908 document.querySelector(`[data-carouselid="${carouselId}"] .cg-carousel__btns`).classList.remove('hidden');
909 }
910
911 epGlobals.initCarousel(carouselSelector, options, carouselId);
912
913 });
914 }
915
916 // Youtube Channel Carousel
917
918 const youtubeCarouselWraper = document.querySelectorAll('[data-youtube-channel-carousel]');
919
920 if (youtubeCarouselWraper.length > 0) {
921 youtubeCarouselWraper.forEach((wrapper) => {
922 const carouselId = wrapper.getAttribute('data-youtube-channel-carousel');
923 if (!carouselId) return;
924
925 // let options = wrapper.getAttribute(`data-carousel-options`);
926
927 // options = JSON.parse(options);
928
929 const carouselSelector = `[data-youtube-channel-carousel="${carouselId}"] .youtube__content__body`;
930
931 // if (options.arrows) {
932 // document.querySelector(`[data-youtube-channel-carousel="${carouselId}"] .cg-carousel__btns`).classList.remove('hidden');
933 // }
934
935 const options = {
936 slidesPerView: 2,
937 autoplay: true,
938 loop: true,
939 breakpoints: {
940 768: {
941 slidesPerView: 2
942 },
943 1024: {
944 slidesPerView: 4
945 }
946 }
947 }
948
949 // epGlobals.initCarousel(carouselSelector, options, {});
950
951 });
952 }
953
954
955
956 });
957
958 document.addEventListener('DOMContentLoaded', () => {
959 const carousel = document.querySelector('.youtube-carousel');
960
961 if (!carousel) {
962 return;
963 }
964
965 const items = document.querySelectorAll('.item');
966 const prevButton = document.querySelector('.preview');
967 const nextButton = document.querySelector('.next');
968
969 let itemsToShow = getItemsToShow(); // Determine items to show based on screen width
970
971 const totalItems = items.length;
972 let currentIndex = 0;
973
974 function updateCarousel() {
975 const offset = -currentIndex * (100 / itemsToShow);
976 carousel.style.transform = `translateX(${offset}%)`;
977 }
978
979 function nextSlide() {
980 const remainingItems = totalItems - (currentIndex + itemsToShow);
981 if (remainingItems >= itemsToShow) {
982 currentIndex += itemsToShow;
983 } else if (remainingItems > 0) {
984 currentIndex += remainingItems;
985 } else {
986 currentIndex = 0;
987 }
988 updateCarousel();
989 }
990
991 function prevSlide() {
992 if (currentIndex > 0) {
993 currentIndex -= itemsToShow;
994 if (currentIndex < 0) {
995 currentIndex = 0;
996 }
997 } else {
998 currentIndex = totalItems - itemsToShow;
999 }
1000 updateCarousel();
1001 }
1002
1003 nextButton?.addEventListener('click', nextSlide);
1004 prevButton?.addEventListener('click', prevSlide);
1005
1006 // Optional: Autoplay
1007 let autoplay = false;
1008 const autoplayInterval = 3000; // Change the time as needed
1009 let autoplayId;
1010
1011 function startAutoplay() {
1012 autoplayId = setInterval(nextSlide, autoplayInterval);
1013 }
1014
1015 function stopAutoplay() {
1016 clearInterval(autoplayId);
1017 }
1018
1019 if (autoplay) {
1020 startAutoplay();
1021
1022 // Stop autoplay on mouseover, resume on mouseout
1023 carousel.addEventListener('mouseover', stopAutoplay);
1024 carousel.addEventListener('mouseout', startAutoplay);
1025 }
1026
1027 // Handle responsive behavior
1028 window.addEventListener('resize', () => {
1029 itemsToShow = getItemsToShow();
1030 updateCarousel();
1031
1032 });
1033
1034 function getItemsToShow() {
1035 const width = window.innerWidth;
1036 if (width >= 1024) {
1037 return 3;
1038 } else if (width >= 768) {
1039 return 2;
1040 } else {
1041 return 1;
1042 }
1043 }
1044 });
1045
1046
1047
1048
1049 jQuery(window).on("elementor/frontend/init", function () {
1050
1051 var filterableGalleryHandler = function ($scope, $) {
1052
1053 // Get the Elementor unique selector for this widget
1054 let classes = $scope[0].className;
1055 let selectorEl = '.' + classes.split(' ').join('.');
1056
1057 const epElLoadMore = () => {
1058
1059 const spinicon = '<svg width="18" height="18" fill="#fff" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>.spinner_GuJz{transform-origin:center;animation:spinner_STY6 1.5s linear infinite}@keyframes spinner_STY6{100%{transform:rotate(360deg)}}</style><g class="spinner_GuJz"><circle cx="3" cy="12" r="2"/><circle cx="21" cy="12" r="2"/><circle cx="12" cy="21" r="2"/><circle cx="12" cy="3" r="2"/><circle cx="5.64" cy="5.64" r="2"/><circle cx="18.36" cy="18.36" r="2"/><circle cx="5.64" cy="18.36" r="2"/><circle cx="18.36" cy="5.64" r="2"/></g></svg>';
1060
1061 $('.elementor-widget-embedpres_elementor .ep-nft-gallery-wrapper').each(function () {
1062 let selctorEl = `.elementor-widget-embedpres_elementor [data-nftid='${$(this).data('nftid')}']`;
1063 let loadmorelabel = $(selctorEl).data('loadmorelabel');
1064 $(selctorEl + ` .ep_nft_item`).slice(0, $(selctorEl).data('itemparpage')).show();
1065 $('.elementor-widget-embedpres_elementor .ep-nft-gallery-wrapper .ep-loadmore-wrapper button').css('display', 'flex');
1066
1067 $(selctorEl + " .nft-loadmore").click(function (e) {
1068 //change the text of the button
1069 $(this).html(loadmorelabel + spinicon);
1070
1071 //disable the button
1072 $(this).prop("disabled", true);
1073 //wait for 1 seconds
1074 setTimeout(function () {
1075 //change the text back
1076 $(selctorEl + " .nft-loadmore").text(loadmorelabel);
1077 //enable the button
1078 $(selctorEl + " .nft-loadmore").prop("disabled", false);
1079 $(selctorEl + " .ep_nft_item:hidden").slice(0, $(selctorEl).data('itemparpage')).fadeIn("slow");
1080 if ($(selctorEl + " .ep_nft_item:hidden").length == 0) {
1081 $(selctorEl + " .nft-loadmore").fadeOut("slow");
1082 }
1083 }, 500);
1084 });
1085 });
1086 };
1087
1088 if ($('.elementor-widget-embedpres_elementor .ep-nft-gallery-wrapper').length > 0) {
1089 epElLoadMore();
1090 }
1091
1092 // Content protection system function
1093 const unlockElSubmitHander = (perentSel, that) => {
1094 var ep_client_id = jQuery(that).closest('form').find('input[name="ep_client_id"]').val();
1095 var password = jQuery(`input[name="pass_${ep_client_id}"]`).val();
1096 var post_id = jQuery(`input[name="post_id"]`).val();
1097 const buttonText = jQuery(that).closest('.password-form-container').find('input[type="submit"]').val();
1098 const unlokingText = jQuery(that).data('unlocking-text');
1099
1100 var data = {
1101 'action': 'lock_content_form_handler',
1102 'client_id': ep_client_id,
1103 'password': password,
1104 'post_id': post_id,
1105 };
1106
1107 jQuery('#' + perentSel + '-' + ep_client_id + ' .password-form input[type="submit"]').val(unlokingText);
1108
1109 jQuery.post(embedpressFrontendData.ajaxurl, data, function (response) {
1110 if (response.success) {
1111 if (!response.embedHtml) {
1112 jQuery('#' + perentSel + '-' + ep_client_id + ' .password-form input[type="submit"]').val(buttonText);
1113 jQuery('#' + perentSel + '-' + ep_client_id + ' .password-form input[type="password"]').val('');
1114 jQuery(that).closest('.password-form-container').find('.error-message').removeClass('hidden');
1115 }
1116 else {
1117 if ($('.ep-content-locked').has('#' + perentSel + '-' + ep_client_id).length) {
1118 $('.ep-content-locked').removeClass('ep-content-locked');
1119 }
1120
1121 jQuery('#' + perentSel + '-' + ep_client_id + ' .ep-embed-content-wraper').html(response.embedHtml);
1122
1123 $('#' + perentSel + '-' + ep_client_id).removeClass('ep-content-protection-enabled');
1124
1125 if (jQuery('#' + perentSel + '-' + ep_client_id + ' .ose-youtube').length > 0) {
1126 epGlobals.youtubeChannelGallery();
1127 }
1128
1129 if ($('.elementor-widget-embedpres_elementor .ep-nft-gallery-wrapper').length > 0) {
1130 epElLoadMore();
1131 }
1132 }
1133 } else {
1134 jQuery('#password-error_' + ep_client_id).html(response.form);
1135 jQuery('#password-error_' + ep_client_id).show();
1136 }
1137 }, 'json');
1138 }
1139
1140 // unlockElSubmitHander called for Elementor
1141 jQuery('.ep-elementor-content .password-form').submit(function (e) {
1142 e.preventDefault(); // Prevent the default form submission
1143 unlockElSubmitHander('ep-elementor-content', this);
1144 });
1145
1146
1147 const instaWrappers = document.querySelectorAll('.ep-embed-content-wrapper');
1148
1149 if (instaWrappers.length > 0) {
1150
1151 instaWrappers.forEach((wrapper) => {
1152 wrapper.classList.add('class-content-wrapper');
1153 const carouselId = wrapper.getAttribute('data-carouselid');
1154
1155 if (!carouselId) return;
1156
1157 let options = wrapper.getAttribute(`data-carousel-options`);
1158
1159 options = JSON.parse(options);
1160 const carouselSelector = `[data-carouselid="${carouselId}"] .embedpress-insta-container`;
1161
1162
1163 if (options.arrows) {
1164 document.querySelector(`[data-carouselid="${carouselId}"] .cg-carousel__btns`).classList.remove('hidden');
1165 }
1166
1167 epGlobals.initCarousel(carouselSelector, options, carouselId);
1168
1169 });
1170 }
1171
1172
1173 const instaFeed = document.querySelector(`${selectorEl} .ose-instagram-feed`);
1174 const instaGallery = document.querySelector(`${selectorEl} .insta-gallery`);
1175 if (instaFeed) {
1176 epGlobals.initializeTabs(instaFeed);
1177 }
1178 if (instaGallery) {
1179 epGlobals.instaPopup(instaGallery);
1180
1181 $('.popup-close').click(function (e) {
1182 // Hide the popup by setting display to none
1183 $('.insta-popup').hide();
1184 $('.popup-container').remove();
1185 });
1186
1187 }
1188
1189 if ($('.elementor-widget-embedpres_elementor .ose-instagram-feed').length > 0) {
1190 epGlobals.instaLoadMore();
1191 }
1192
1193 };
1194
1195 const adsHandler = function ($scope, $) {
1196 window.epAdIndex = typeof (window.epAdIndex) === 'undefined' ? 0 : window.epAdIndex + 1;
1197 let classes = $scope[0].className;
1198 let classJoint = '.' + classes.split(' ').join('.');
1199 const selectorEl = document.querySelector(classJoint + ' [data-sponsored-id]');
1200
1201 if (jQuery('body').hasClass('elementor-editor-active') && embedpressFrontendData.isProPluginActive) {
1202 if (typeof adInitialization === 'function') {
1203 adInitialization(selectorEl, window.epAdIndex);
1204 }
1205 }
1206
1207 }
1208
1209 elementorFrontend.hooks.addAction("frontend/element_ready/embedpres_elementor.default", filterableGalleryHandler);
1210 elementorFrontend.hooks.addAction("frontend/element_ready/embedpress_pdf.default", filterableGalleryHandler);
1211 elementorFrontend.hooks.addAction("frontend/element_ready/embedpres_document.default", filterableGalleryHandler);
1212 elementorFrontend.hooks.addAction("frontend/element_ready/embedpres_elementor.default", adsHandler);
1213 elementorFrontend.hooks.addAction("frontend/element_ready/embedpres_elementor.default", epGlobals.handlePosterImageLoad);
1214
1215 // Re-initialize custom player when Elementor widget becomes ready
1216 var customPlayerHandler = function ($scope, $) {
1217 var wrappers = $scope[0].querySelectorAll('.ep-embed-content-wraper');
1218 if (typeof initPlayer === 'function') {
1219 wrappers.forEach(function (wrapper) {
1220 var playerId = wrapper.getAttribute('data-playerid');
1221
1222 // Destroy existing player instance so initPlayer can re-create it
1223 if (playerId && wrapper.classList.contains('plyr-initialized')) {
1224 if (typeof playerInit !== 'undefined' && playerInit[playerId]) {
1225 try {
1226 playerInit[playerId].destroy();
1227 } catch (e) {
1228 // Player may already be detached
1229 }
1230 delete playerInit[playerId];
1231 }
1232 wrapper.classList.remove('plyr-initialized');
1233 }
1234
1235 if (playerId) {
1236 initPlayer(wrapper);
1237 }
1238 });
1239 } else {
1240 // Fallback: ensure embeds are visible even if Plyr scripts failed to load
1241 wrappers.forEach(function (wrapper) {
1242 if (wrapper.hasAttribute('data-playerid')) {
1243 wrapper.style.opacity = '1';
1244 }
1245 });
1246 }
1247
1248 // Re-initialize lazy loaded iframes for this widget
1249 if (typeof window.epReinitLazyLoad === 'function') {
1250 window.epReinitLazyLoad();
1251 }
1252 };
1253 elementorFrontend.hooks.addAction("frontend/element_ready/embedpres_elementor.default", customPlayerHandler);
1254 });
1255
1256
1257 function presentationModeForIOS(iframes) {
1258 iframes?.forEach(function (iframe) {
1259 iframe.onload = function () {
1260 var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
1261 var button = iframeDoc?.querySelector('#presentationMode.presentationMode');
1262 button?.addEventListener('click', function () {
1263 iframe.classList.toggle('presentationModeEnabledIosDevice');
1264 });
1265 iframeDoc?.addEventListener('keydown', function (event) {
1266 if (event.keyCode === 27) {
1267 iframe.classList.remove('presentationModeEnabledIosDevice');
1268 }
1269 });
1270 };
1271 });
1272 }
1273
1274 function isIOSDevice() {
1275 return /iPhone|iPad|iPod/i.test(navigator.userAgent);
1276 }
1277
1278 if (isIOSDevice()) {
1279 var iframes = document.querySelectorAll('.embedpress-embed-document-pdf');
1280 presentationModeForIOS(iframes)
1281 }
1282
1283 document.addEventListener("DOMContentLoaded", epGlobals.handlePosterImageLoad);
1284
1285
1286 jQuery(document).ready(function ($) {
1287
1288 let currentIndex = -1;
1289
1290 function createVideoPopup() {
1291 const videoPopupHtml = `
1292 <div id="videoPopup" class="video-popup">
1293 <div class="video-popup-content">
1294 <span class="close">&times;</span>
1295 <div class="video-popup-inner-content">
1296 <iframe id="videoIframe" frameborder="0" allowfullscreen allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"></iframe>
1297 <div id="videoDescription"></div>
1298 </div>
1299 <div class="popup-controls">
1300 <span id="prevVideo" class="nav-icon prev-icon">&#10094;</span>
1301 <span id="nextVideo" class="nav-icon next-icon">&#10095;</span>
1302 </div>
1303 </div>
1304 </div>`;
1305 return $(videoPopupHtml).appendTo('body');
1306 }
1307
1308 function openVideoPopup(index) {
1309 const items = $('.layout-grid .item, .layout-list .item, .layout-carousel .item');
1310 if (index >= 0 && index < items.length) {
1311 // Remove any existing video popup before creating a new one
1312 $('#videoPopup').remove();
1313
1314 currentIndex = index;
1315 const videoId = $(items[currentIndex]).data('vid');
1316 const videoPopup = createVideoPopup();
1317 const videoIframe = videoPopup.find('#videoIframe');
1318 const videoDescriptionContainer = videoPopup.find('#videoDescription');
1319 const closeBtn = videoPopup.find('.close');
1320 const nextBtn = videoPopup.find('#nextVideo');
1321 const prevBtn = videoPopup.find('#prevVideo');
1322
1323 if (videoId) {
1324 fetchVideoData(videoId, videoIframe, videoDescriptionContainer);
1325 videoPopup.show();
1326 updateNavigationButtons(nextBtn, prevBtn, items);
1327
1328 closeBtn.on('click', () => {
1329 closeVideoPopup(videoPopup);
1330 });
1331
1332 $(window).on('click', function (event) {
1333 if ($(event.target).is(videoPopup)) {
1334 closeVideoPopup(videoPopup);
1335 }
1336 });
1337
1338 nextBtn.on('click', function () {
1339 if (currentIndex >= 0 && currentIndex < items.length - 1) {
1340 openVideoPopup(currentIndex + 1);
1341 }
1342 });
1343
1344 prevBtn.on('click', function () {
1345 if (currentIndex > 0) {
1346 openVideoPopup(currentIndex - 1);
1347 }
1348 });
1349 }
1350 }
1351 }
1352
1353
1354 function closeVideoPopup(videoPopup) {
1355 videoPopup.remove();
1356 currentIndex = -1; // Reset the index
1357 }
1358
1359 function updateNavigationButtons(nextBtn, prevBtn, items) {
1360 prevBtn.toggle(currentIndex > 0);
1361 nextBtn.toggle(currentIndex < items.length - 1);
1362 }
1363
1364 function fetchVideoData(videoId, videoIframe, videoDescriptionContainer) {
1365 const data = {
1366 action: 'fetch_video_description',
1367 vid: videoId
1368 };
1369
1370 $.post(embedpressFrontendData.ajaxurl, data, function (response) {
1371 if (response.success) {
1372 videoIframe.attr('src', `https://www.youtube.com/embed/${videoId}?autoplay=1`);
1373 videoDescriptionContainer.html(response.data.description);
1374 } else {
1375 console.error('Error fetching video data:', response?.data?.error);
1376 }
1377 });
1378 }
1379
1380 $(document).on('click', '.layout-grid .item, .layout-list .item, .layout-carousel .item', function () {
1381 const items = $('.layout-grid .item, .layout-list .item, .layout-carousel .item');
1382 const index = items.index(this);
1383 openVideoPopup(index);
1384 });
1385 });
1386 jQuery(document).ready(function ($) {
1387 let currentIndex = 0;
1388 const $photos = $('.photo-item');
1389
1390 function createPopupGooglePhotos() {
1391 if ($('#ep-popup-overlay').length === 0) {
1392 const photoPopup = `
1393 <div class="popup-overlay" id="ep-popup-overlay" style="display: none!important">
1394
1395 <div class="popup">
1396 <span class="close-btn" id="close-btn">
1397 <svg width="20" height="20" viewBox="0 0 0.6 0.6" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M.132.132a.025.025 0 0 1 .035 0L.3.265.432.133a.025.025 0 1 1 .035.035L.335.3l.132.132a.025.025 0 0 1-.035.035L.3.335.168.467A.025.025 0 0 1 .133.432L.265.3.132.168a.025.025 0 0 1 0-.035" fill="#fff"/></svg>
1398 </span>
1399 <button type="button" class="prev-btn" id="prev-btn" aria-label="Previous">
1400 <svg aria-hidden="true" focusable="false" width="20" height="20" viewBox="0 0 0.6 0.6" data-name="Flat Color" xmlns="http://www.w3.org/2000/svg" class="icon flat-color"><path d="M.525.275h-.39L.268.143A.025.025 0 1 0 .233.108L.058.283a.025.025 0 0 0 0 .035l.175.175a.025.025 0 0 0 .035 0 .025.025 0 0 0 0-.035L.135.325h.39a.025.025 0 0 0 0-.05" style="fill:#fff"/></svg>
1401 </button>
1402 <div id="popup-content" class="loading">
1403 <div class="photo-loader"></div>
1404 <img id="popup-image" src="" style="display:none;" loading="lazy" />
1405 </div>
1406 <button type="button" class="next-btn" id="next-btn" aria-label="Next">
1407 <svg aria-hidden="true" focusable="false" width="20" height="20" viewBox="0 0 0.6 0.6" data-name="Flat Color" xmlns="http://www.w3.org/2000/svg" class="icon flat-color"><path d="M.543.282.368.107a.025.025 0 0 0-.035.035l.133.132H.075a.025.025 0 0 0 0 .05h.39L.332.456a.025.025 0 0 0 0 .035.025.025 0 0 0 .035 0L.542.316a.025.025 0 0 0 0-.035" style="fill:#fff"/></svg>
1408 </button>
1409 </div>
1410 </div>`;
1411 $('body').append(photoPopup);
1412
1413 // Loader spinner CSS (can be moved to your CSS file)
1414 const spinnerStyles = `
1415 <style>
1416 .popup #popup-content .photo-loader {
1417 display: none;
1418 }
1419 .popup #popup-content.loading .photo-loader {
1420 width: 40px;
1421 height: 40px;
1422 border: 4px solid #fff;
1423 border-top: 4px solid transparent;
1424 border-radius: 50%;
1425 animation: spin 1s linear infinite;
1426 margin: 40px auto;
1427 display: block;
1428 }
1429 @keyframes spin {
1430 0% { transform: rotate(0deg); }
1431 100% { transform: rotate(360deg); }
1432 }
1433 </style>`;
1434 $('head').append(spinnerStyles);
1435
1436 // Events
1437 $('#ep-popup-overlay').on('click', function (e) {
1438 if ($(e.target).is('#ep-popup-overlay') || $(e.target).is('.popup')) {
1439 $('#ep-popup-overlay').hide();
1440 }
1441 });
1442
1443 $('#close-btn').on('click', function () {
1444 $('#ep-popup-overlay').hide();
1445 });
1446
1447 $('#prev-btn').on('click', function () {
1448 currentIndex = (currentIndex - 1 + $photos.length) % $photos.length;
1449 updatePopupImage();
1450 });
1451
1452 $('#next-btn').on('click', function () {
1453 currentIndex = (currentIndex + 1) % $photos.length;
1454 updatePopupImage();
1455 });
1456 }
1457 }
1458
1459 function updatePopupImage() {
1460 const imgSrc = $photos.eq(currentIndex).find('img').attr('data-photo-src');
1461 const $popupImage = $('#popup-image');
1462 const $popupContent = $('#popup-content');
1463
1464 $popupContent.addClass('loading');
1465 $popupImage.hide();
1466
1467 const preload = new Image();
1468 preload.src = imgSrc;
1469
1470 preload.onload = function () {
1471 $popupImage.attr('src', imgSrc);
1472 $popupContent.removeClass('loading');
1473 $popupImage.fadeIn();
1474 };
1475 }
1476
1477 $('.photo-item').on('click', function () {
1478 currentIndex = $photos.index(this);
1479 createPopupGooglePhotos();
1480 updatePopupImage();
1481 $('#ep-popup-overlay').show();
1482 });
1483 });
1484
1485
1486 // pause audio/video
1487
1488 jQuery(document).ready(function () {
1489 const players = jQuery('.enabled-auto-pause audio, .enabled-auto-pause video');
1490
1491 function pauseAllExcept(currentPlayer) {
1492 players.each(function () {
1493 if (this !== currentPlayer[0]) {
1494 this.pause();
1495 }
1496 });
1497 }
1498
1499 players.on('play', function () {
1500 pauseAllExcept(jQuery(this));
1501 });
1502 });
1503
1504 // Meetup Events Load More
1505 jQuery(document).on('click', '.ep-load-more-button', function(e) {
1506 e.preventDefault();
1507
1508 const button = jQuery(this);
1509 const container = button.closest('.embedpress-meetup-events');
1510 const eventsContainer = container.find('.embedpress-meetup-events-list');
1511
1512 // Get data attributes
1513 const embedId = button.data('embed-id');
1514 const currentPage = parseInt(container.data('page')) || 1;
1515 const perPage = parseInt(container.data('per-page')) || 10;
1516 const nextPage = currentPage + 1;
1517
1518 // Show loading state
1519 const loadingText = button.find('.ep-load-more-text');
1520 const spinner = button.find('.ep-load-more-spinner');
1521 loadingText.hide();
1522 spinner.show();
1523 button.prop('disabled', true);
1524
1525 // Make AJAX request
1526 jQuery.ajax({
1527 url: embedpressFrontendData.ajaxurl,
1528 type: 'POST',
1529 data: {
1530 action: 'embedpress_meetup_load_more',
1531 nonce: embedpressFrontendData.nonce,
1532 embed_id: embedId,
1533 page: nextPage,
1534 per_page: perPage
1535 },
1536 success: function(response) {
1537 if (response.success) {
1538 // Append new events
1539 eventsContainer.append(response.data.html);
1540
1541 // Update page number
1542 container.data('page', nextPage);
1543
1544 // Trigger custom event for timezone conversion
1545 document.dispatchEvent(new Event('embedpress:meetup:loaded'));
1546
1547 // Hide button if no more events
1548 if (!response.data.has_more) {
1549 button.closest('.ep-events-load-more').fadeOut();
1550 } else {
1551 loadingText.show();
1552 spinner.hide();
1553 button.prop('disabled', false);
1554 }
1555 } else {
1556 alert(response.data.message || 'Error loading more events');
1557 loadingText.show();
1558 spinner.hide();
1559 button.prop('disabled', false);
1560 }
1561 },
1562 error: function() {
1563 alert('Error loading more events');
1564 loadingText.show();
1565 spinner.hide();
1566 button.prop('disabled', false);
1567 }
1568 });
1569 });
1570
1571