PluginProbe
Elementor Website Builder – more than just a page builder / 3.4.8
Elementor Website Builder – more than just a page builder v3.4.8
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / assets / js / preloaded-modules.js

preloaded-modules.js in Elementor Website Builder – more than just a page builder 3.4.8, at assets/js/preloaded-modules.js

2,036 lines 61.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*! elementor - v3.4.8 - 16-11-2021 */
2 (self["webpackChunkelementor"] = self["webpackChunkelementor"] || []).push([["preloaded-modules"],{
3
4 /***/ "../assets/dev/js/frontend/handlers/accordion.js":
5 /*!*******************************************************!*\
6 !*** ../assets/dev/js/frontend/handlers/accordion.js ***!
7 \*******************************************************/
8 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
9
10 "use strict";
11
12
13 var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
14
15 Object.defineProperty(exports, "__esModule", ({
16 value: true
17 }));
18 exports.default = void 0;
19
20 var _baseTabs = _interopRequireDefault(__webpack_require__(/*! ./base-tabs */ "../assets/dev/js/frontend/handlers/base-tabs.js"));
21
22 class Accordion extends _baseTabs.default {
23 getDefaultSettings() {
24 const defaultSettings = super.getDefaultSettings();
25 return { ...defaultSettings,
26 showTabFn: 'slideDown',
27 hideTabFn: 'slideUp'
28 };
29 }
30
31 }
32
33 exports.default = Accordion;
34
35 /***/ }),
36
37 /***/ "../assets/dev/js/frontend/handlers/alert.js":
38 /*!***************************************************!*\
39 !*** ../assets/dev/js/frontend/handlers/alert.js ***!
40 \***************************************************/
41 /***/ ((__unused_webpack_module, exports) => {
42
43 "use strict";
44
45
46 Object.defineProperty(exports, "__esModule", ({
47 value: true
48 }));
49 exports.default = void 0;
50
51 class Alert extends elementorModules.frontend.handlers.Base {
52 getDefaultSettings() {
53 return {
54 selectors: {
55 dismissButton: '.elementor-alert-dismiss'
56 }
57 };
58 }
59
60 getDefaultElements() {
61 const selectors = this.getSettings('selectors');
62 return {
63 $dismissButton: this.$element.find(selectors.dismissButton)
64 };
65 }
66
67 bindEvents() {
68 this.elements.$dismissButton.on('click', this.onDismissButtonClick.bind(this));
69 }
70
71 onDismissButtonClick() {
72 this.$element.fadeOut();
73 }
74
75 }
76
77 exports.default = Alert;
78
79 /***/ }),
80
81 /***/ "../assets/dev/js/frontend/handlers/base-tabs.js":
82 /*!*******************************************************!*\
83 !*** ../assets/dev/js/frontend/handlers/base-tabs.js ***!
84 \*******************************************************/
85 /***/ ((__unused_webpack_module, exports) => {
86
87 "use strict";
88
89
90 Object.defineProperty(exports, "__esModule", ({
91 value: true
92 }));
93 exports.default = void 0;
94
95 class baseTabs extends elementorModules.frontend.handlers.Base {
96 getDefaultSettings() {
97 return {
98 selectors: {
99 tablist: '[role="tablist"]',
100 tabTitle: '.elementor-tab-title',
101 tabContent: '.elementor-tab-content'
102 },
103 classes: {
104 active: 'elementor-active'
105 },
106 showTabFn: 'show',
107 hideTabFn: 'hide',
108 toggleSelf: true,
109 hidePrevious: true,
110 autoExpand: true,
111 keyDirection: {
112 ArrowLeft: elementorFrontendConfig.is_rtl ? 1 : -1,
113 ArrowUp: -1,
114 ArrowRight: elementorFrontendConfig.is_rtl ? -1 : 1,
115 ArrowDown: 1
116 }
117 };
118 }
119
120 getDefaultElements() {
121 const selectors = this.getSettings('selectors');
122 return {
123 $tabTitles: this.findElement(selectors.tabTitle),
124 $tabContents: this.findElement(selectors.tabContent)
125 };
126 }
127
128 activateDefaultTab() {
129 const settings = this.getSettings();
130
131 if (!settings.autoExpand || 'editor' === settings.autoExpand && !this.isEdit) {
132 return;
133 }
134
135 const defaultActiveTab = this.getEditSettings('activeItemIndex') || 1,
136 originalToggleMethods = {
137 showTabFn: settings.showTabFn,
138 hideTabFn: settings.hideTabFn
139 }; // Toggle tabs without animation to avoid jumping
140
141 this.setSettings({
142 showTabFn: 'show',
143 hideTabFn: 'hide'
144 });
145 this.changeActiveTab(defaultActiveTab); // Return back original toggle effects
146
147 this.setSettings(originalToggleMethods);
148 }
149
150 handleKeyboardNavigation(event) {
151 const tab = event.currentTarget,
152 $tabList = jQuery(tab.closest(this.getSettings('selectors').tablist)),
153 $tabs = $tabList.find(this.getSettings('selectors').tabTitle),
154 isVertical = 'vertical' === $tabList.attr('aria-orientation');
155
156 switch (event.key) {
157 case 'ArrowLeft':
158 case 'ArrowRight':
159 if (isVertical) {
160 return;
161 }
162
163 break;
164
165 case 'ArrowUp':
166 case 'ArrowDown':
167 if (!isVertical) {
168 return;
169 }
170
171 event.preventDefault();
172 break;
173
174 case 'Home':
175 event.preventDefault();
176 $tabs.first().focus();
177 return;
178
179 case 'End':
180 event.preventDefault();
181 $tabs.last().focus();
182 return;
183
184 default:
185 return;
186 }
187
188 const tabIndex = tab.getAttribute('data-tab') - 1,
189 direction = this.getSettings('keyDirection')[event.key],
190 nextTab = $tabs[tabIndex + direction];
191
192 if (nextTab) {
193 nextTab.focus();
194 } else if (-1 === tabIndex + direction) {
195 $tabs.last().focus();
196 } else {
197 $tabs.first().focus();
198 }
199 }
200
201 deactivateActiveTab(tabIndex) {
202 const settings = this.getSettings(),
203 activeClass = settings.classes.active,
204 activeFilter = tabIndex ? '[data-tab="' + tabIndex + '"]' : '.' + activeClass,
205 $activeTitle = this.elements.$tabTitles.filter(activeFilter),
206 $activeContent = this.elements.$tabContents.filter(activeFilter);
207 $activeTitle.add($activeContent).removeClass(activeClass);
208 $activeTitle.attr({
209 tabindex: '-1',
210 'aria-selected': 'false',
211 'aria-expanded': 'false'
212 });
213 $activeContent[settings.hideTabFn]();
214 $activeContent.attr('hidden', 'hidden');
215 }
216
217 activateTab(tabIndex) {
218 const settings = this.getSettings(),
219 activeClass = settings.classes.active,
220 $requestedTitle = this.elements.$tabTitles.filter('[data-tab="' + tabIndex + '"]'),
221 $requestedContent = this.elements.$tabContents.filter('[data-tab="' + tabIndex + '"]'),
222 animationDuration = 'show' === settings.showTabFn ? 0 : 400;
223 $requestedTitle.add($requestedContent).addClass(activeClass);
224 $requestedTitle.attr({
225 tabindex: '0',
226 'aria-selected': 'true',
227 'aria-expanded': 'true'
228 });
229 $requestedContent[settings.showTabFn](animationDuration, () => elementorFrontend.elements.$window.trigger('resize'));
230 $requestedContent.removeAttr('hidden');
231 }
232
233 isActiveTab(tabIndex) {
234 return this.elements.$tabTitles.filter('[data-tab="' + tabIndex + '"]').hasClass(this.getSettings('classes.active'));
235 }
236
237 bindEvents() {
238 this.elements.$tabTitles.on({
239 keydown: event => {
240 // Support for old markup that includes an `<a>` tag in the tab
241 if (jQuery(event.target).is('a') && `Enter` === event.key) {
242 event.preventDefault();
243 } // We listen to keydowon event for these keys in order to prevent undesired page scrolling
244
245
246 if (['End', 'Home', 'ArrowUp', 'ArrowDown'].includes(event.key)) {
247 this.handleKeyboardNavigation(event);
248 }
249 },
250 keyup: event => {
251 switch (event.key) {
252 case 'ArrowLeft':
253 case 'ArrowRight':
254 this.handleKeyboardNavigation(event);
255 break;
256
257 case 'Enter':
258 case 'Space':
259 event.preventDefault();
260 this.changeActiveTab(event.currentTarget.getAttribute('data-tab'));
261 break;
262 }
263 },
264 click: event => {
265 event.preventDefault();
266 this.changeActiveTab(event.currentTarget.getAttribute('data-tab'));
267 }
268 });
269 }
270
271 onInit(...args) {
272 super.onInit(...args);
273 this.activateDefaultTab();
274 }
275
276 onEditSettingsChange(propertyName) {
277 if ('activeItemIndex' === propertyName) {
278 this.activateDefaultTab();
279 }
280 }
281
282 changeActiveTab(tabIndex) {
283 const isActiveTab = this.isActiveTab(tabIndex),
284 settings = this.getSettings();
285
286 if ((settings.toggleSelf || !isActiveTab) && settings.hidePrevious) {
287 this.deactivateActiveTab();
288 }
289
290 if (!settings.hidePrevious && isActiveTab) {
291 this.deactivateActiveTab(tabIndex);
292 }
293
294 if (!isActiveTab) {
295 this.activateTab(tabIndex);
296 }
297 }
298
299 }
300
301 exports.default = baseTabs;
302
303 /***/ }),
304
305 /***/ "../assets/dev/js/frontend/handlers/counter.js":
306 /*!*****************************************************!*\
307 !*** ../assets/dev/js/frontend/handlers/counter.js ***!
308 \*****************************************************/
309 /***/ ((__unused_webpack_module, exports) => {
310
311 "use strict";
312
313
314 Object.defineProperty(exports, "__esModule", ({
315 value: true
316 }));
317 exports.default = void 0;
318
319 class Counter extends elementorModules.frontend.handlers.Base {
320 getDefaultSettings() {
321 return {
322 selectors: {
323 counterNumber: '.elementor-counter-number'
324 }
325 };
326 }
327
328 getDefaultElements() {
329 const selectors = this.getSettings('selectors');
330 return {
331 $counterNumber: this.$element.find(selectors.counterNumber)
332 };
333 }
334
335 onInit() {
336 super.onInit();
337 this.intersectionObserver = elementorModules.utils.Scroll.scrollObserver({
338 callback: event => {
339 if (event.isInViewport) {
340 this.intersectionObserver.unobserve(this.elements.$counterNumber[0]);
341 const data = this.elements.$counterNumber.data(),
342 decimalDigits = data.toValue.toString().match(/\.(.*)/);
343
344 if (decimalDigits) {
345 data.rounding = decimalDigits[1].length;
346 }
347
348 this.elements.$counterNumber.numerator(data);
349 }
350 }
351 });
352 this.intersectionObserver.observe(this.elements.$counterNumber[0]);
353 }
354
355 }
356
357 exports.default = Counter;
358
359 /***/ }),
360
361 /***/ "../assets/dev/js/frontend/handlers/image-carousel.js":
362 /*!************************************************************!*\
363 !*** ../assets/dev/js/frontend/handlers/image-carousel.js ***!
364 \************************************************************/
365 /***/ ((__unused_webpack_module, exports) => {
366
367 "use strict";
368
369
370 Object.defineProperty(exports, "__esModule", ({
371 value: true
372 }));
373 exports.default = void 0;
374
375 class ImageCarousel extends elementorModules.frontend.handlers.SwiperBase {
376 getDefaultSettings() {
377 return {
378 selectors: {
379 carousel: '.elementor-image-carousel-wrapper',
380 slideContent: '.swiper-slide'
381 }
382 };
383 }
384
385 getDefaultElements() {
386 const selectors = this.getSettings('selectors');
387 const elements = {
388 $swiperContainer: this.$element.find(selectors.carousel)
389 };
390 elements.$slides = elements.$swiperContainer.find(selectors.slideContent);
391 return elements;
392 }
393
394 getSwiperSettings() {
395 const elementSettings = this.getElementSettings(),
396 slidesToShow = +elementSettings.slides_to_show || 3,
397 isSingleSlide = 1 === slidesToShow,
398 elementorBreakpoints = elementorFrontend.config.responsive.activeBreakpoints,
399 defaultSlidesToShowMap = {
400 mobile: 1,
401 tablet: isSingleSlide ? 1 : 2
402 };
403 const swiperOptions = {
404 slidesPerView: slidesToShow,
405 loop: 'yes' === elementSettings.infinite,
406 speed: elementSettings.speed,
407 handleElementorBreakpoints: true
408 };
409 swiperOptions.breakpoints = {};
410 let lastBreakpointSlidesToShowValue = slidesToShow;
411 Object.keys(elementorBreakpoints).reverse().forEach(breakpointName => {
412 // Tablet has a specific default `slides_to_show`.
413 const defaultSlidesToShow = defaultSlidesToShowMap[breakpointName] ? defaultSlidesToShowMap[breakpointName] : lastBreakpointSlidesToShowValue;
414 swiperOptions.breakpoints[elementorBreakpoints[breakpointName].value] = {
415 slidesPerView: +elementSettings['slides_to_show_' + breakpointName] || defaultSlidesToShow,
416 slidesPerGroup: +elementSettings['slides_to_scroll_' + breakpointName] || 1
417 };
418 lastBreakpointSlidesToShowValue = +elementSettings['slides_to_show_' + breakpointName] || defaultSlidesToShow;
419 });
420
421 if ('yes' === elementSettings.autoplay) {
422 swiperOptions.autoplay = {
423 delay: elementSettings.autoplay_speed,
424 disableOnInteraction: 'yes' === elementSettings.pause_on_interaction
425 };
426 }
427
428 if (isSingleSlide) {
429 swiperOptions.effect = elementSettings.effect;
430
431 if ('fade' === elementSettings.effect) {
432 swiperOptions.fadeEffect = {
433 crossFade: true
434 };
435 }
436 } else {
437 swiperOptions.slidesPerGroup = +elementSettings.slides_to_scroll || 1;
438 }
439
440 if (elementSettings.image_spacing_custom) {
441 swiperOptions.spaceBetween = elementSettings.image_spacing_custom.size;
442 }
443
444 const showArrows = 'arrows' === elementSettings.navigation || 'both' === elementSettings.navigation,
445 showDots = 'dots' === elementSettings.navigation || 'both' === elementSettings.navigation;
446
447 if (showArrows) {
448 swiperOptions.navigation = {
449 prevEl: '.elementor-swiper-button-prev',
450 nextEl: '.elementor-swiper-button-next'
451 };
452 }
453
454 if (showDots) {
455 swiperOptions.pagination = {
456 el: '.swiper-pagination',
457 type: 'bullets',
458 clickable: true
459 };
460 }
461
462 return swiperOptions;
463 }
464
465 async onInit(...args) {
466 super.onInit(...args);
467 const elementSettings = this.getElementSettings();
468
469 if (!this.elements.$swiperContainer.length || 2 > this.elements.$slides.length) {
470 return;
471 }
472
473 const Swiper = elementorFrontend.utils.swiper;
474 this.swiper = await new Swiper(this.elements.$swiperContainer, this.getSwiperSettings()); // Expose the swiper instance in the frontend
475
476 this.elements.$swiperContainer.data('swiper', this.swiper);
477
478 if ('yes' === elementSettings.pause_on_hover) {
479 this.togglePauseOnHover(true);
480 }
481 }
482
483 updateSwiperOption(propertyName) {
484 const elementSettings = this.getElementSettings(),
485 newSettingValue = elementSettings[propertyName],
486 params = this.swiper.params; // Handle special cases where the value to update is not the value that the Swiper library accepts.
487
488 switch (propertyName) {
489 case 'image_spacing_custom':
490 params.spaceBetween = newSettingValue.size || 0;
491 break;
492
493 case 'autoplay_speed':
494 params.autoplay.delay = newSettingValue;
495 break;
496
497 case 'speed':
498 params.speed = newSettingValue;
499 break;
500 }
501
502 this.swiper.update();
503 }
504
505 getChangeableProperties() {
506 return {
507 pause_on_hover: 'pauseOnHover',
508 autoplay_speed: 'delay',
509 speed: 'speed',
510 image_spacing_custom: 'spaceBetween'
511 };
512 }
513
514 onElementChange(propertyName) {
515 const changeableProperties = this.getChangeableProperties();
516
517 if (changeableProperties[propertyName]) {
518 // 'pause_on_hover' is implemented by the handler with event listeners, not the Swiper library.
519 if ('pause_on_hover' === propertyName) {
520 const newSettingValue = this.getElementSettings('pause_on_hover');
521 this.togglePauseOnHover('yes' === newSettingValue);
522 } else {
523 this.updateSwiperOption(propertyName);
524 }
525 }
526 }
527
528 onEditSettingsChange(propertyName) {
529 if ('activeItemIndex' === propertyName) {
530 this.swiper.slideToLoop(this.getEditSettings('activeItemIndex') - 1);
531 }
532 }
533
534 }
535
536 exports.default = ImageCarousel;
537
538 /***/ }),
539
540 /***/ "../assets/dev/js/frontend/handlers/progress.js":
541 /*!******************************************************!*\
542 !*** ../assets/dev/js/frontend/handlers/progress.js ***!
543 \******************************************************/
544 /***/ ((__unused_webpack_module, exports) => {
545
546 "use strict";
547
548
549 Object.defineProperty(exports, "__esModule", ({
550 value: true
551 }));
552 exports.default = void 0;
553
554 class Progress extends elementorModules.frontend.handlers.Base {
555 getDefaultSettings() {
556 return {
557 selectors: {
558 progressNumber: '.elementor-progress-bar'
559 }
560 };
561 }
562
563 getDefaultElements() {
564 const selectors = this.getSettings('selectors');
565 return {
566 $progressNumber: this.$element.find(selectors.progressNumber)
567 };
568 }
569
570 onInit() {
571 super.onInit();
572 elementorFrontend.waypoint(this.elements.$progressNumber, () => {
573 const $progressbar = this.elements.$progressNumber;
574 $progressbar.css('width', $progressbar.data('max') + '%');
575 });
576 }
577
578 }
579
580 exports.default = Progress;
581
582 /***/ }),
583
584 /***/ "../assets/dev/js/frontend/handlers/tabs.js":
585 /*!**************************************************!*\
586 !*** ../assets/dev/js/frontend/handlers/tabs.js ***!
587 \**************************************************/
588 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
589
590 "use strict";
591
592
593 var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
594
595 Object.defineProperty(exports, "__esModule", ({
596 value: true
597 }));
598 exports.default = void 0;
599
600 var _baseTabs = _interopRequireDefault(__webpack_require__(/*! ./base-tabs */ "../assets/dev/js/frontend/handlers/base-tabs.js"));
601
602 class Tabs extends _baseTabs.default {
603 getDefaultSettings() {
604 const defaultSettings = super.getDefaultSettings();
605 return { ...defaultSettings,
606 toggleSelf: false
607 };
608 }
609
610 }
611
612 exports.default = Tabs;
613
614 /***/ }),
615
616 /***/ "../assets/dev/js/frontend/handlers/text-editor.js":
617 /*!*********************************************************!*\
618 !*** ../assets/dev/js/frontend/handlers/text-editor.js ***!
619 \*********************************************************/
620 /***/ ((__unused_webpack_module, exports) => {
621
622 "use strict";
623
624
625 Object.defineProperty(exports, "__esModule", ({
626 value: true
627 }));
628 exports.default = void 0;
629
630 class TextEditor extends elementorModules.frontend.handlers.Base {
631 getDefaultSettings() {
632 return {
633 selectors: {
634 paragraph: 'p:first'
635 },
636 classes: {
637 dropCap: 'elementor-drop-cap',
638 dropCapLetter: 'elementor-drop-cap-letter'
639 }
640 };
641 }
642
643 getDefaultElements() {
644 const selectors = this.getSettings('selectors'),
645 classes = this.getSettings('classes'),
646 $dropCap = jQuery('<span>', {
647 class: classes.dropCap
648 }),
649 $dropCapLetter = jQuery('<span>', {
650 class: classes.dropCapLetter
651 });
652 $dropCap.append($dropCapLetter);
653 return {
654 $paragraph: this.$element.find(selectors.paragraph),
655 $dropCap: $dropCap,
656 $dropCapLetter: $dropCapLetter
657 };
658 }
659
660 wrapDropCap() {
661 const isDropCapEnabled = this.getElementSettings('drop_cap');
662
663 if (!isDropCapEnabled) {
664 // If there is an old drop cap inside the paragraph
665 if (this.dropCapLetter) {
666 this.elements.$dropCap.remove();
667 this.elements.$paragraph.prepend(this.dropCapLetter);
668 this.dropCapLetter = '';
669 }
670
671 return;
672 }
673
674 const $paragraph = this.elements.$paragraph;
675
676 if (!$paragraph.length) {
677 return;
678 }
679
680 const paragraphContent = $paragraph.html().replace(/&nbsp;/g, ' '),
681 firstLetterMatch = paragraphContent.match(/^ *([^ ] ?)/);
682
683 if (!firstLetterMatch) {
684 return;
685 }
686
687 const firstLetter = firstLetterMatch[1],
688 trimmedFirstLetter = firstLetter.trim(); // Don't apply drop cap when the content starting with an HTML tag
689
690 if ('<' === trimmedFirstLetter) {
691 return;
692 }
693
694 this.dropCapLetter = firstLetter;
695 this.elements.$dropCapLetter.text(trimmedFirstLetter);
696 const restoredParagraphContent = paragraphContent.slice(firstLetter.length).replace(/^ */, match => {
697 return new Array(match.length + 1).join('&nbsp;');
698 });
699 $paragraph.html(restoredParagraphContent).prepend(this.elements.$dropCap);
700 }
701
702 onInit(...args) {
703 super.onInit(...args);
704 this.wrapDropCap();
705 }
706
707 onElementChange(propertyName) {
708 if ('drop_cap' === propertyName) {
709 this.wrapDropCap();
710 }
711 }
712
713 }
714
715 exports.default = TextEditor;
716
717 /***/ }),
718
719 /***/ "../assets/dev/js/frontend/handlers/toggle.js":
720 /*!****************************************************!*\
721 !*** ../assets/dev/js/frontend/handlers/toggle.js ***!
722 \****************************************************/
723 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
724
725 "use strict";
726
727
728 var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
729
730 Object.defineProperty(exports, "__esModule", ({
731 value: true
732 }));
733 exports.default = void 0;
734
735 var _baseTabs = _interopRequireDefault(__webpack_require__(/*! ./base-tabs */ "../assets/dev/js/frontend/handlers/base-tabs.js"));
736
737 class Toggle extends _baseTabs.default {
738 getDefaultSettings() {
739 const defaultSettings = super.getDefaultSettings();
740 return { ...defaultSettings,
741 showTabFn: 'slideDown',
742 hideTabFn: 'slideUp',
743 hidePrevious: false,
744 autoExpand: 'editor'
745 };
746 }
747
748 }
749
750 exports.default = Toggle;
751
752 /***/ }),
753
754 /***/ "../assets/dev/js/frontend/handlers/video.js":
755 /*!***************************************************!*\
756 !*** ../assets/dev/js/frontend/handlers/video.js ***!
757 \***************************************************/
758 /***/ ((__unused_webpack_module, exports) => {
759
760 "use strict";
761
762
763 Object.defineProperty(exports, "__esModule", ({
764 value: true
765 }));
766 exports.default = void 0;
767
768 class Video extends elementorModules.frontend.handlers.Base {
769 getDefaultSettings() {
770 return {
771 selectors: {
772 imageOverlay: '.elementor-custom-embed-image-overlay',
773 video: '.elementor-video',
774 videoIframe: '.elementor-video-iframe'
775 }
776 };
777 }
778
779 getDefaultElements() {
780 const selectors = this.getSettings('selectors');
781 return {
782 $imageOverlay: this.$element.find(selectors.imageOverlay),
783 $video: this.$element.find(selectors.video),
784 $videoIframe: this.$element.find(selectors.videoIframe)
785 };
786 }
787
788 handleVideo() {
789 if (this.getElementSettings('lightbox')) {
790 return;
791 }
792
793 if ('youtube' === this.getElementSettings('video_type')) {
794 this.apiProvider.onApiReady(apiObject => {
795 this.elements.$imageOverlay.remove();
796 this.prepareYTVideo(apiObject, true);
797 });
798 } else {
799 this.elements.$imageOverlay.remove();
800 this.playVideo();
801 }
802 }
803
804 playVideo() {
805 if (this.elements.$video.length) {
806 // this.youtubePlayer exists only for YouTube videos, and its play function is different.
807 if (this.youtubePlayer) {
808 this.youtubePlayer.playVideo();
809 } else {
810 this.elements.$video[0].play();
811 }
812
813 return;
814 }
815
816 const $videoIframe = this.elements.$videoIframe,
817 lazyLoad = $videoIframe.data('lazy-load');
818
819 if (lazyLoad) {
820 $videoIframe.attr('src', lazyLoad);
821 }
822
823 $videoIframe[0].src = this.apiProvider.getAutoplayURL($videoIframe[0].src);
824 }
825
826 async animateVideo() {
827 const lightbox = await elementorFrontend.utils.lightbox;
828 lightbox.setEntranceAnimation(this.getCurrentDeviceSetting('lightbox_content_animation'));
829 }
830
831 async handleAspectRatio() {
832 const lightbox = await elementorFrontend.utils.lightbox;
833 lightbox.setVideoAspectRatio(this.getElementSettings('aspect_ratio'));
834 }
835
836 async hideLightbox() {
837 const lightbox = await elementorFrontend.utils.lightbox;
838 lightbox.getModal().hide();
839 }
840
841 prepareYTVideo(YT, onOverlayClick) {
842 const elementSettings = this.getElementSettings(),
843 playerOptions = {
844 videoId: this.videoID,
845 events: {
846 onReady: () => {
847 if (elementSettings.mute) {
848 this.youtubePlayer.mute();
849 }
850
851 if (elementSettings.autoplay || onOverlayClick) {
852 this.youtubePlayer.playVideo();
853 }
854 },
855 onStateChange: event => {
856 if (event.data === YT.PlayerState.ENDED && elementSettings.loop) {
857 this.youtubePlayer.seekTo(elementSettings.start || 0);
858 }
859 }
860 },
861 playerVars: {
862 controls: elementSettings.controls ? 1 : 0,
863 rel: elementSettings.rel ? 1 : 0,
864 playsinline: elementSettings.play_on_mobile ? 1 : 0,
865 modestbranding: elementSettings.modestbranding ? 1 : 0,
866 autoplay: elementSettings.autoplay ? 1 : 0,
867 start: elementSettings.start,
868 end: elementSettings.end
869 }
870 }; // To handle CORS issues, when the default host is changed, the origin parameter has to be set.
871
872 if (elementSettings.yt_privacy) {
873 playerOptions.host = 'https://www.youtube-nocookie.com';
874 playerOptions.origin = window.location.hostname;
875 }
876
877 this.youtubePlayer = new YT.Player(this.elements.$video[0], playerOptions);
878 }
879
880 bindEvents() {
881 this.elements.$imageOverlay.on('click', this.handleVideo.bind(this));
882 }
883
884 onInit() {
885 super.onInit();
886 const elementSettings = this.getElementSettings();
887
888 if (elementorFrontend.utils[elementSettings.video_type]) {
889 this.apiProvider = elementorFrontend.utils[elementSettings.video_type];
890 } else {
891 this.apiProvider = elementorFrontend.utils.baseVideoLoader;
892 }
893
894 if ('youtube' !== elementSettings.video_type) {
895 // Currently the only API integration in the Video widget is for the YT API
896 return;
897 }
898
899 this.videoID = this.apiProvider.getVideoIDFromURL(elementSettings.youtube_url); // If there is an image overlay, the YouTube video prep method will be triggered on click
900
901 if (!this.videoID) {
902 return;
903 } // If the user is using an image overlay, loading the API happens on overlay click instead of on init.
904
905
906 if (elementSettings.show_image_overlay && elementSettings.image_overlay.url) {
907 return;
908 }
909
910 if (elementSettings.lazy_load) {
911 this.intersectionObserver = elementorModules.utils.Scroll.scrollObserver({
912 callback: event => {
913 if (event.isInViewport) {
914 this.intersectionObserver.unobserve(this.elements.$video.parent()[0]);
915 this.apiProvider.onApiReady(apiObject => this.prepareYTVideo(apiObject));
916 }
917 }
918 }); // We observe the parent, since the video container has a height of 0.
919
920 this.intersectionObserver.observe(this.elements.$video.parent()[0]);
921 return;
922 } // When Optimized asset loading is set to off, the video type is set to 'Youtube', and 'Privacy Mode' is set
923 // to 'On', there might be a conflict with other videos that are loaded WITHOUT privacy mode, such as a
924 // video bBackground in a section. In these cases, to avoid the conflict, a timeout is added to postpone the
925 // initialization of the Youtube API object.
926
927
928 if (!elementorFrontend.config.experimentalFeatures['e_optimized_assets_loading']) {
929 setTimeout(() => {
930 this.apiProvider.onApiReady(apiObject => this.prepareYTVideo(apiObject));
931 }, 0);
932 } else {
933 this.apiProvider.onApiReady(apiObject => this.prepareYTVideo(apiObject));
934 }
935 }
936
937 onElementChange(propertyName) {
938 if (0 === propertyName.indexOf('lightbox_content_animation')) {
939 this.animateVideo();
940 return;
941 }
942
943 const isLightBoxEnabled = this.getElementSettings('lightbox');
944
945 if ('lightbox' === propertyName && !isLightBoxEnabled) {
946 this.hideLightbox();
947 return;
948 }
949
950 if ('aspect_ratio' === propertyName && isLightBoxEnabled) {
951 this.handleAspectRatio();
952 }
953 }
954
955 }
956
957 exports.default = Video;
958
959 /***/ }),
960
961 /***/ "../assets/dev/js/frontend/preloaded-modules.js":
962 /*!******************************************************!*\
963 !*** ../assets/dev/js/frontend/preloaded-modules.js ***!
964 \******************************************************/
965 /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
966
967 "use strict";
968
969
970 var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
971
972 var _accordion = _interopRequireDefault(__webpack_require__(/*! ./handlers/accordion */ "../assets/dev/js/frontend/handlers/accordion.js"));
973
974 var _alert = _interopRequireDefault(__webpack_require__(/*! ./handlers/alert */ "../assets/dev/js/frontend/handlers/alert.js"));
975
976 var _counter = _interopRequireDefault(__webpack_require__(/*! ./handlers/counter */ "../assets/dev/js/frontend/handlers/counter.js"));
977
978 var _progress = _interopRequireDefault(__webpack_require__(/*! ./handlers/progress */ "../assets/dev/js/frontend/handlers/progress.js"));
979
980 var _tabs = _interopRequireDefault(__webpack_require__(/*! ./handlers/tabs */ "../assets/dev/js/frontend/handlers/tabs.js"));
981
982 var _toggle = _interopRequireDefault(__webpack_require__(/*! ./handlers/toggle */ "../assets/dev/js/frontend/handlers/toggle.js"));
983
984 var _video = _interopRequireDefault(__webpack_require__(/*! ./handlers/video */ "../assets/dev/js/frontend/handlers/video.js"));
985
986 var _imageCarousel = _interopRequireDefault(__webpack_require__(/*! ./handlers/image-carousel */ "../assets/dev/js/frontend/handlers/image-carousel.js"));
987
988 var _textEditor = _interopRequireDefault(__webpack_require__(/*! ./handlers/text-editor */ "../assets/dev/js/frontend/handlers/text-editor.js"));
989
990 var _lightbox = _interopRequireDefault(__webpack_require__(/*! elementor-frontend/utils/lightbox/lightbox */ "../assets/dev/js/frontend/utils/lightbox/lightbox.js"));
991
992 elementorFrontend.elements.$window.on('elementor/frontend/init', () => {
993 elementorFrontend.elementsHandler.elementsHandlers = {
994 'accordion.default': _accordion.default,
995 'alert.default': _alert.default,
996 'counter.default': _counter.default,
997 'progress.default': _progress.default,
998 'tabs.default': _tabs.default,
999 'toggle.default': _toggle.default,
1000 'video.default': _video.default,
1001 'image-carousel.default': _imageCarousel.default,
1002 'text-editor.default': _textEditor.default
1003 };
1004 elementorFrontend.on('components:init', () => {
1005 // We first need to delete the property because by default it's a getter function that cannot be overwritten.
1006 delete elementorFrontend.utils.lightbox;
1007 elementorFrontend.utils.lightbox = new _lightbox.default();
1008 });
1009 });
1010
1011 /***/ }),
1012
1013 /***/ "../assets/dev/js/frontend/utils/lightbox/lightbox.js":
1014 /*!************************************************************!*\
1015 !*** ../assets/dev/js/frontend/utils/lightbox/lightbox.js ***!
1016 \************************************************************/
1017 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
1018
1019 "use strict";
1020
1021
1022 var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js");
1023
1024 var _screenfull = _interopRequireDefault(__webpack_require__(/*! ./screenfull */ "../assets/dev/js/frontend/utils/lightbox/screenfull.js"));
1025
1026 module.exports = elementorModules.ViewModule.extend({
1027 oldAspectRatio: null,
1028 oldAnimation: null,
1029 swiper: null,
1030 player: null,
1031 getDefaultSettings: function () {
1032 return {
1033 classes: {
1034 aspectRatio: 'elementor-aspect-ratio-%s',
1035 item: 'elementor-lightbox-item',
1036 image: 'elementor-lightbox-image',
1037 videoContainer: 'elementor-video-container',
1038 videoWrapper: 'elementor-fit-aspect-ratio',
1039 playButton: 'elementor-custom-embed-play',
1040 playButtonIcon: 'fa',
1041 playing: 'elementor-playing',
1042 hidden: 'elementor-hidden',
1043 invisible: 'elementor-invisible',
1044 preventClose: 'elementor-lightbox-prevent-close',
1045 slideshow: {
1046 container: 'swiper-container',
1047 slidesWrapper: 'swiper-wrapper',
1048 prevButton: 'elementor-swiper-button elementor-swiper-button-prev',
1049 nextButton: 'elementor-swiper-button elementor-swiper-button-next',
1050 prevButtonIcon: 'eicon-chevron-left',
1051 nextButtonIcon: 'eicon-chevron-right',
1052 slide: 'swiper-slide',
1053 header: 'elementor-slideshow__header',
1054 footer: 'elementor-slideshow__footer',
1055 title: 'elementor-slideshow__title',
1056 description: 'elementor-slideshow__description',
1057 counter: 'elementor-slideshow__counter',
1058 iconExpand: 'eicon-frame-expand',
1059 iconShrink: 'eicon-frame-minimize',
1060 iconZoomIn: 'eicon-zoom-in-bold',
1061 iconZoomOut: 'eicon-zoom-out-bold',
1062 iconShare: 'eicon-share-arrow',
1063 shareMenu: 'elementor-slideshow__share-menu',
1064 shareLinks: 'elementor-slideshow__share-links',
1065 hideUiVisibility: 'elementor-slideshow--ui-hidden',
1066 shareMode: 'elementor-slideshow--share-mode',
1067 fullscreenMode: 'elementor-slideshow--fullscreen-mode',
1068 zoomMode: 'elementor-slideshow--zoom-mode'
1069 }
1070 },
1071 selectors: {
1072 image: '.elementor-lightbox-image',
1073 links: 'a, [data-elementor-lightbox]',
1074 slideshow: {
1075 activeSlide: '.swiper-slide-active',
1076 prevSlide: '.swiper-slide-prev',
1077 nextSlide: '.swiper-slide-next'
1078 }
1079 },
1080 modalOptions: {
1081 id: 'elementor-lightbox',
1082 entranceAnimation: 'zoomIn',
1083 videoAspectRatio: 169,
1084 position: {
1085 enable: false
1086 }
1087 }
1088 };
1089 },
1090 getModal: function () {
1091 if (!module.exports.modal) {
1092 this.initModal();
1093 }
1094
1095 return module.exports.modal;
1096 },
1097 initModal: function () {
1098 const modal = module.exports.modal = elementorFrontend.getDialogsManager().createWidget('lightbox', {
1099 className: 'elementor-lightbox',
1100 closeButton: true,
1101 closeButtonOptions: {
1102 iconClass: 'eicon-close',
1103 attributes: {
1104 tabindex: 0,
1105 role: 'button',
1106 'aria-label': elementorFrontend.config.i18n.close + ' (Esc)'
1107 }
1108 },
1109 selectors: {
1110 preventClose: '.' + this.getSettings('classes.preventClose')
1111 },
1112 hide: {
1113 onClick: true
1114 }
1115 });
1116 modal.on('hide', function () {
1117 modal.setMessage('');
1118 });
1119 },
1120 showModal: function (options) {
1121 if (options.url && !options.url.startsWith('http')) {
1122 return;
1123 }
1124
1125 this.elements.$closeButton = this.getModal().getElements('closeButton');
1126 this.$buttons = this.elements.$closeButton;
1127 this.focusedButton = null;
1128 const self = this,
1129 defaultOptions = self.getDefaultSettings().modalOptions;
1130 self.id = options.id;
1131 self.setSettings('modalOptions', jQuery.extend(defaultOptions, options.modalOptions));
1132 const modal = self.getModal();
1133 modal.setID(self.getSettings('modalOptions.id'));
1134
1135 modal.onShow = function () {
1136 DialogsManager.getWidgetType('lightbox').prototype.onShow.apply(modal, arguments);
1137 self.setEntranceAnimation();
1138 };
1139
1140 modal.onHide = function () {
1141 DialogsManager.getWidgetType('lightbox').prototype.onHide.apply(modal, arguments);
1142 modal.getElements('message').removeClass('animated');
1143
1144 if (_screenfull.default.isFullscreen) {
1145 self.deactivateFullscreen();
1146 }
1147
1148 self.unbindHotKeys();
1149 };
1150
1151 switch (options.type) {
1152 case 'video':
1153 self.setVideoContent(options);
1154 break;
1155
1156 case 'image':
1157 const slides = [{
1158 image: options.url,
1159 index: 0,
1160 title: options.title,
1161 description: options.description
1162 }];
1163 options.slideshow = {
1164 slides,
1165 swiper: {
1166 loop: false,
1167 pagination: false
1168 }
1169 };
1170
1171 case 'slideshow':
1172 self.setSlideshowContent(options.slideshow);
1173 break;
1174
1175 default:
1176 self.setHTMLContent(options.html);
1177 }
1178
1179 modal.show();
1180 },
1181 createLightbox: function (element) {
1182 let lightboxData = {};
1183
1184 if (element.dataset.elementorLightbox) {
1185 lightboxData = JSON.parse(element.dataset.elementorLightbox);
1186 }
1187
1188 if (lightboxData.type && 'slideshow' !== lightboxData.type) {
1189 this.showModal(lightboxData);
1190 return;
1191 }
1192
1193 if (!element.dataset.elementorLightboxSlideshow) {
1194 const slideshowID = 'single-img';
1195 this.showModal({
1196 type: 'image',
1197 id: slideshowID,
1198 url: element.href,
1199 title: element.dataset.elementorLightboxTitle,
1200 description: element.dataset.elementorLightboxDescription,
1201 modalOptions: {
1202 id: 'elementor-lightbox-slideshow-' + slideshowID
1203 }
1204 });
1205 return;
1206 }
1207
1208 const initialSlideURL = element.dataset.elementorLightboxVideo || element.href;
1209 this.openSlideshow(element.dataset.elementorLightboxSlideshow, initialSlideURL);
1210 },
1211 setHTMLContent: function (html) {
1212 if (window.elementorCommon) {
1213 elementorCommon.helpers.hardDeprecated('elementorFrontend.utils.lightbox.setHTMLContent', '3.1.4');
1214 }
1215
1216 this.getModal().setMessage(html);
1217 },
1218 setVideoContent: function (options) {
1219 const $ = jQuery,
1220 classes = this.getSettings('classes'),
1221 $videoContainer = $('<div>', {
1222 class: `${classes.videoContainer} ${classes.preventClose}`
1223 }),
1224 $videoWrapper = $('<div>', {
1225 class: classes.videoWrapper
1226 }),
1227 modal = this.getModal();
1228 let $videoElement;
1229
1230 if ('hosted' === options.videoType) {
1231 const videoParams = $.extend({
1232 src: options.url,
1233 autoplay: ''
1234 }, options.videoParams);
1235 $videoElement = $('<video>', videoParams);
1236 } else {
1237 let apiProvider = elementorFrontend.utils.baseVideoLoader;
1238
1239 if (-1 !== options.url.indexOf('vimeo.com')) {
1240 apiProvider = elementorFrontend.utils.vimeo;
1241 } else if (options.url.match(/^(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com)/)) {
1242 apiProvider = elementorFrontend.utils.youtube;
1243 }
1244
1245 $videoElement = $('<iframe>', {
1246 src: apiProvider.getAutoplayURL(options.url),
1247 allowfullscreen: 1
1248 });
1249 }
1250
1251 $videoContainer.append($videoWrapper);
1252 $videoWrapper.append($videoElement);
1253 modal.setMessage($videoContainer);
1254 this.setVideoAspectRatio();
1255 const onHideMethod = modal.onHide;
1256
1257 modal.onHide = function () {
1258 onHideMethod();
1259 this.$buttons = jQuery();
1260 this.focusedButton = null;
1261 modal.getElements('message').removeClass('elementor-fit-aspect-ratio');
1262 };
1263 },
1264 getShareLinks: function () {
1265 const {
1266 i18n
1267 } = elementorFrontend.config,
1268 socialNetworks = {
1269 facebook: i18n.shareOnFacebook,
1270 twitter: i18n.shareOnTwitter,
1271 pinterest: i18n.pinIt
1272 },
1273 $ = jQuery,
1274 classes = this.getSettings('classes'),
1275 selectors = this.getSettings('selectors'),
1276 $linkList = $('<div>', {
1277 class: classes.slideshow.shareLinks
1278 }),
1279 $activeSlide = this.getSlide('active'),
1280 $image = $activeSlide.find(selectors.image),
1281 videoUrl = $activeSlide.data('elementor-slideshow-video');
1282 let itemUrl;
1283
1284 if (videoUrl) {
1285 itemUrl = videoUrl;
1286 } else {
1287 itemUrl = $image.attr('src');
1288 }
1289
1290 $.each(socialNetworks, (key, networkLabel) => {
1291 const $link = $('<a>', {
1292 href: this.createShareLink(key, itemUrl),
1293 target: '_blank'
1294 }).text(networkLabel);
1295 $link.prepend($('<i>', {
1296 class: 'eicon-' + key
1297 }));
1298 $linkList.append($link);
1299 });
1300
1301 if (!videoUrl) {
1302 $linkList.append($('<a>', {
1303 href: itemUrl,
1304 download: ''
1305 }).text(i18n.downloadImage).prepend($('<i>', {
1306 class: 'eicon-download-bold',
1307 'aria-label': i18n.download
1308 })));
1309 }
1310
1311 return $linkList;
1312 },
1313 createShareLink: function (networkName, itemUrl) {
1314 const options = {};
1315
1316 if ('pinterest' === networkName) {
1317 options.image = encodeURIComponent(itemUrl);
1318 } else {
1319 const hash = elementorFrontend.utils.urlActions.createActionHash('lightbox', {
1320 id: this.id,
1321 url: itemUrl
1322 });
1323 options.url = encodeURIComponent(location.href.replace(/#.*/, '')) + hash;
1324 }
1325
1326 return ShareLink.getNetworkLink(networkName, options);
1327 },
1328 getSlideshowHeader: function () {
1329 const {
1330 i18n
1331 } = elementorFrontend.config,
1332 $ = jQuery,
1333 showCounter = 'yes' === elementorFrontend.getKitSettings('lightbox_enable_counter'),
1334 showFullscreen = 'yes' === elementorFrontend.getKitSettings('lightbox_enable_fullscreen'),
1335 showZoom = 'yes' === elementorFrontend.getKitSettings('lightbox_enable_zoom'),
1336 showShare = 'yes' === elementorFrontend.getKitSettings('lightbox_enable_share'),
1337 classes = this.getSettings('classes'),
1338 slideshowClasses = classes.slideshow,
1339 elements = this.elements;
1340
1341 if (!(showCounter || showFullscreen || showZoom || showShare)) {
1342 return;
1343 }
1344
1345 elements.$header = $('<header>', {
1346 class: slideshowClasses.header + ' ' + classes.preventClose
1347 });
1348
1349 if (showShare) {
1350 elements.$iconShare = $('<i>', {
1351 class: slideshowClasses.iconShare,
1352 role: 'button',
1353 'aria-label': i18n.share,
1354 'aria-expanded': false
1355 }).append($('<span>'));
1356 const $shareLinks = $('<div>');
1357 $shareLinks.on('click', e => {
1358 e.stopPropagation();
1359 });
1360 elements.$shareMenu = $('<div>', {
1361 class: slideshowClasses.shareMenu
1362 }).append($shareLinks);
1363 elements.$iconShare.add(elements.$shareMenu).on('click', this.toggleShareMenu);
1364 elements.$header.append(elements.$iconShare, elements.$shareMenu);
1365 this.$buttons = this.$buttons.add(elements.$iconShare);
1366 }
1367
1368 if (showZoom) {
1369 elements.$iconZoom = $('<i>', {
1370 class: slideshowClasses.iconZoomIn,
1371 role: 'switch',
1372 'aria-checked': false,
1373 'aria-label': i18n.zoom
1374 });
1375 elements.$iconZoom.on('click', this.toggleZoomMode);
1376 elements.$header.append(elements.$iconZoom);
1377 this.$buttons = this.$buttons.add(elements.$iconZoom);
1378 }
1379
1380 if (showFullscreen) {
1381 elements.$iconExpand = $('<i>', {
1382 class: slideshowClasses.iconExpand,
1383 role: 'switch',
1384 'aria-checked': false,
1385 'aria-label': i18n.fullscreen
1386 }).append($('<span>'), $('<span>'));
1387 elements.$iconExpand.on('click', this.toggleFullscreen);
1388 elements.$header.append(elements.$iconExpand);
1389 this.$buttons = this.$buttons.add(elements.$iconExpand);
1390 }
1391
1392 if (showCounter) {
1393 elements.$counter = $('<span>', {
1394 class: slideshowClasses.counter
1395 });
1396 elements.$header.append(elements.$counter);
1397 }
1398
1399 return elements.$header;
1400 },
1401 toggleFullscreen: function () {
1402 if (_screenfull.default.isFullscreen) {
1403 this.deactivateFullscreen();
1404 } else if (_screenfull.default.isEnabled) {
1405 this.activateFullscreen();
1406 }
1407 },
1408 toggleZoomMode: function () {
1409 if (1 !== this.swiper.zoom.scale) {
1410 this.deactivateZoom();
1411 } else {
1412 this.activateZoom();
1413 }
1414 },
1415 toggleShareMenu: function () {
1416 if (this.shareMode) {
1417 this.deactivateShareMode();
1418 } else {
1419 this.elements.$shareMenu.html(this.getShareLinks());
1420 this.activateShareMode();
1421 }
1422 },
1423 activateShareMode: function () {
1424 const classes = this.getSettings('classes');
1425 this.elements.$container.addClass(classes.slideshow.shareMode);
1426 this.elements.$iconShare.attr('aria-expanded', true); // Prevent swiper interactions while in share mode
1427
1428 this.swiper.detachEvents(); // Temporarily replace tabbable buttons with share-menu items
1429
1430 this.$originalButtons = this.$buttons;
1431 this.$buttons = this.elements.$iconShare.add(this.elements.$shareMenu.find('a'));
1432 this.shareMode = true;
1433 },
1434 deactivateShareMode: function () {
1435 const classes = this.getSettings('classes');
1436 this.elements.$container.removeClass(classes.slideshow.shareMode);
1437 this.elements.$iconShare.attr('aria-expanded', false);
1438 this.swiper.attachEvents();
1439 this.$buttons = this.$originalButtons;
1440 this.shareMode = false;
1441 },
1442 activateFullscreen: function () {
1443 const classes = this.getSettings('classes');
1444
1445 _screenfull.default.request(this.elements.$container.parents('.dialog-widget')[0]);
1446
1447 this.elements.$iconExpand.removeClass(classes.slideshow.iconExpand).addClass(classes.slideshow.iconShrink).attr('aria-checked', 'true');
1448 this.elements.$container.addClass(classes.slideshow.fullscreenMode);
1449 },
1450 deactivateFullscreen: function () {
1451 const classes = this.getSettings('classes');
1452
1453 _screenfull.default.exit();
1454
1455 this.elements.$iconExpand.removeClass(classes.slideshow.iconShrink).addClass(classes.slideshow.iconExpand).attr('aria-checked', 'false');
1456 this.elements.$container.removeClass(classes.slideshow.fullscreenMode);
1457 },
1458 activateZoom: function () {
1459 const swiper = this.swiper,
1460 elements = this.elements,
1461 classes = this.getSettings('classes');
1462 swiper.zoom.in();
1463 swiper.allowSlideNext = false;
1464 swiper.allowSlidePrev = false;
1465 swiper.allowTouchMove = false;
1466 elements.$container.addClass(classes.slideshow.zoomMode);
1467 elements.$iconZoom.removeClass(classes.slideshow.iconZoomIn).addClass(classes.slideshow.iconZoomOut);
1468 },
1469 deactivateZoom: function () {
1470 const swiper = this.swiper,
1471 elements = this.elements,
1472 classes = this.getSettings('classes');
1473 swiper.zoom.out();
1474 swiper.allowSlideNext = true;
1475 swiper.allowSlidePrev = true;
1476 swiper.allowTouchMove = true;
1477 elements.$container.removeClass(classes.slideshow.zoomMode);
1478 elements.$iconZoom.removeClass(classes.slideshow.iconZoomOut).addClass(classes.slideshow.iconZoomIn);
1479 },
1480 getSlideshowFooter: function () {
1481 const $ = jQuery,
1482 classes = this.getSettings('classes'),
1483 $footer = $('<footer>', {
1484 class: classes.slideshow.footer + ' ' + classes.preventClose
1485 }),
1486 $title = $('<div>', {
1487 class: classes.slideshow.title
1488 }),
1489 $description = $('<div>', {
1490 class: classes.slideshow.description
1491 });
1492 $footer.append($title, $description);
1493 return $footer;
1494 },
1495 setSlideshowContent: function (options) {
1496 const {
1497 i18n
1498 } = elementorFrontend.config,
1499 $ = jQuery,
1500 isSingleSlide = 1 === options.slides.length,
1501 hasTitle = '' !== elementorFrontend.getKitSettings('lightbox_title_src'),
1502 hasDescription = '' !== elementorFrontend.getKitSettings('lightbox_description_src'),
1503 showFooter = hasTitle || hasDescription,
1504 classes = this.getSettings('classes'),
1505 slideshowClasses = classes.slideshow,
1506 $container = $('<div>', {
1507 class: slideshowClasses.container
1508 }),
1509 $slidesWrapper = $('<div>', {
1510 class: slideshowClasses.slidesWrapper
1511 });
1512 let $prevButton, $nextButton;
1513 options.slides.forEach(slide => {
1514 let slideClass = slideshowClasses.slide + ' ' + classes.item;
1515
1516 if (slide.video) {
1517 slideClass += ' ' + classes.video;
1518 }
1519
1520 const $slide = $('<div>', {
1521 class: slideClass
1522 });
1523
1524 if (slide.video) {
1525 $slide.attr('data-elementor-slideshow-video', slide.video);
1526 const $playIcon = $('<div>', {
1527 class: classes.playButton
1528 }).html($('<i>', {
1529 class: classes.playButtonIcon,
1530 'aria-label': i18n.playVideo
1531 }));
1532 $slide.append($playIcon);
1533 } else {
1534 const $zoomContainer = $('<div>', {
1535 class: 'swiper-zoom-container'
1536 }),
1537 $slidePlaceholder = $('<div class="swiper-lazy-preloader"></div>'),
1538 imageAttributes = {
1539 'data-src': slide.image,
1540 class: classes.image + ' ' + classes.preventClose + ' swiper-lazy'
1541 };
1542
1543 if (slide.title) {
1544 imageAttributes['data-title'] = slide.title;
1545 imageAttributes.alt = slide.title;
1546 }
1547
1548 if (slide.description) {
1549 imageAttributes['data-description'] = slide.description;
1550 imageAttributes.alt += ' - ' + slide.description;
1551 }
1552
1553 const $slideImage = $('<img>', imageAttributes);
1554 $zoomContainer.append([$slideImage, $slidePlaceholder]);
1555 $slide.append($zoomContainer);
1556 }
1557
1558 $slidesWrapper.append($slide);
1559 });
1560 this.elements.$container = $container;
1561 this.elements.$header = this.getSlideshowHeader();
1562 $container.prepend(this.elements.$header).append($slidesWrapper);
1563
1564 if (!isSingleSlide) {
1565 $prevButton = $('<div>', {
1566 class: slideshowClasses.prevButton + ' ' + classes.preventClose,
1567 'aria-label': i18n.previous
1568 }).html($('<i>', {
1569 class: slideshowClasses.prevButtonIcon
1570 }));
1571 $nextButton = $('<div>', {
1572 class: slideshowClasses.nextButton + ' ' + classes.preventClose,
1573 'aria-label': i18n.next
1574 }).html($('<i>', {
1575 class: slideshowClasses.nextButtonIcon
1576 }));
1577 $container.append($nextButton, $prevButton);
1578 this.$buttons = this.$buttons.add($nextButton).add($prevButton);
1579 }
1580
1581 if (showFooter) {
1582 this.elements.$footer = this.getSlideshowFooter();
1583 $container.append(this.elements.$footer);
1584 }
1585
1586 this.setSettings('hideUiTimeout', '');
1587 $container.on('click mousemove keypress', this.showLightboxUi);
1588 const modal = this.getModal();
1589 modal.setMessage($container);
1590 const onShowMethod = modal.onShow;
1591
1592 modal.onShow = async () => {
1593 onShowMethod();
1594 const swiperOptions = {
1595 pagination: {
1596 el: '.' + slideshowClasses.counter,
1597 type: 'fraction'
1598 },
1599 on: {
1600 slideChangeTransitionEnd: this.onSlideChange
1601 },
1602 lazy: {
1603 loadPrevNext: true
1604 },
1605 zoom: true,
1606 spaceBetween: 100,
1607 grabCursor: true,
1608 runCallbacksOnInit: false,
1609 loop: true,
1610 keyboard: true,
1611 handleElementorBreakpoints: true
1612 };
1613
1614 if (!isSingleSlide) {
1615 swiperOptions.navigation = {
1616 prevEl: $prevButton,
1617 nextEl: $nextButton
1618 };
1619 }
1620
1621 if (options.swiper) {
1622 $.extend(swiperOptions, options.swiper);
1623 }
1624
1625 const Swiper = elementorFrontend.utils.swiper;
1626 this.swiper = await new Swiper($container, swiperOptions); // Expose the swiper instance in the frontend
1627
1628 $container.data('swiper', this.swiper);
1629 this.setVideoAspectRatio();
1630 this.playSlideVideo();
1631
1632 if (showFooter) {
1633 this.updateFooterText();
1634 }
1635
1636 this.bindHotKeys();
1637 this.makeButtonsAccessible();
1638 };
1639 },
1640 makeButtonsAccessible: function () {
1641 this.$buttons.attr('tabindex', 0).on('keypress', event => {
1642 const ENTER_KEY = 13,
1643 SPACE_KEY = 32;
1644
1645 if (ENTER_KEY === event.which || SPACE_KEY === event.which) {
1646 jQuery(event.currentTarget).trigger('click');
1647 }
1648 });
1649 },
1650 showLightboxUi: function () {
1651 const slideshowClasses = this.getSettings('classes').slideshow;
1652 this.elements.$container.removeClass(slideshowClasses.hideUiVisibility);
1653 clearTimeout(this.getSettings('hideUiTimeout'));
1654 this.setSettings('hideUiTimeout', setTimeout(() => {
1655 if (!this.shareMode) {
1656 this.elements.$container.addClass(slideshowClasses.hideUiVisibility);
1657 }
1658 }, 3500));
1659 },
1660 bindHotKeys: function () {
1661 this.getModal().getElements('window').on('keydown', this.activeKeyDown);
1662 },
1663 unbindHotKeys: function () {
1664 this.getModal().getElements('window').off('keydown', this.activeKeyDown);
1665 },
1666 activeKeyDown: function (event) {
1667 this.showLightboxUi();
1668 const TAB_KEY = 9;
1669
1670 if (event.which === TAB_KEY) {
1671 const $buttons = this.$buttons;
1672 let focusedButton,
1673 isFirst = false,
1674 isLast = false;
1675 $buttons.each(index => {
1676 const item = $buttons[index];
1677
1678 if (jQuery(item).is(':focus')) {
1679 focusedButton = item;
1680 isFirst = 0 === index;
1681 isLast = $buttons.length - 1 === index;
1682 return false;
1683 }
1684 });
1685
1686 if (event.shiftKey) {
1687 if (isFirst) {
1688 event.preventDefault();
1689 $buttons.last().trigger('focus');
1690 }
1691 } else if (isLast || !focusedButton) {
1692 event.preventDefault();
1693 $buttons.first().trigger('focus');
1694 }
1695 }
1696 },
1697 setVideoAspectRatio: function (aspectRatio) {
1698 aspectRatio = aspectRatio || this.getSettings('modalOptions.videoAspectRatio');
1699 const $widgetContent = this.getModal().getElements('widgetContent'),
1700 oldAspectRatio = this.oldAspectRatio,
1701 aspectRatioClass = this.getSettings('classes.aspectRatio');
1702 this.oldAspectRatio = aspectRatio;
1703
1704 if (oldAspectRatio) {
1705 $widgetContent.removeClass(aspectRatioClass.replace('%s', oldAspectRatio));
1706 }
1707
1708 if (aspectRatio) {
1709 $widgetContent.addClass(aspectRatioClass.replace('%s', aspectRatio));
1710 }
1711 },
1712 getSlide: function (slideState) {
1713 return jQuery(this.swiper.slides).filter(this.getSettings('selectors.slideshow.' + slideState + 'Slide'));
1714 },
1715 updateFooterText: function () {
1716 if (!this.elements.$footer) {
1717 return;
1718 }
1719
1720 const classes = this.getSettings('classes'),
1721 $activeSlide = this.getSlide('active'),
1722 $image = $activeSlide.find('.elementor-lightbox-image'),
1723 titleText = $image.data('title'),
1724 descriptionText = $image.data('description'),
1725 $title = this.elements.$footer.find('.' + classes.slideshow.title),
1726 $description = this.elements.$footer.find('.' + classes.slideshow.description);
1727 $title.text(titleText || '');
1728 $description.text(descriptionText || '');
1729 },
1730 playSlideVideo: function () {
1731 const $activeSlide = this.getSlide('active'),
1732 videoURL = $activeSlide.data('elementor-slideshow-video');
1733
1734 if (!videoURL) {
1735 return;
1736 }
1737
1738 const classes = this.getSettings('classes'),
1739 $videoContainer = jQuery('<div>', {
1740 class: classes.videoContainer + ' ' + classes.invisible
1741 }),
1742 $videoWrapper = jQuery('<div>', {
1743 class: classes.videoWrapper
1744 }),
1745 $playIcon = $activeSlide.children('.' + classes.playButton);
1746 let videoType, apiProvider;
1747 $videoContainer.append($videoWrapper);
1748 $activeSlide.append($videoContainer);
1749
1750 if (-1 !== videoURL.indexOf('vimeo.com')) {
1751 videoType = 'vimeo';
1752 apiProvider = elementorFrontend.utils.vimeo;
1753 } else if (videoURL.match(/^(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com)/)) {
1754 videoType = 'youtube';
1755 apiProvider = elementorFrontend.utils.youtube;
1756 }
1757
1758 const videoID = apiProvider.getVideoIDFromURL(videoURL);
1759 apiProvider.onApiReady(apiObject => {
1760 if ('youtube' === videoType) {
1761 this.prepareYTVideo(apiObject, videoID, $videoContainer, $videoWrapper, $playIcon);
1762 } else if ('vimeo' === videoType) {
1763 this.prepareVimeoVideo(apiObject, videoURL, $videoContainer, $videoWrapper, $playIcon);
1764 }
1765 });
1766 $playIcon.addClass(classes.playing).removeClass(classes.hidden);
1767 },
1768 prepareYTVideo: function (YT, videoID, $videoContainer, $videoWrapper, $playIcon) {
1769 const classes = this.getSettings('classes'),
1770 $videoPlaceholderElement = jQuery('<div>');
1771 let startStateCode = YT.PlayerState.PLAYING;
1772 $videoWrapper.append($videoPlaceholderElement); // Since version 67, Chrome doesn't fire the `PLAYING` state at start time
1773
1774 if (window.chrome) {
1775 startStateCode = YT.PlayerState.UNSTARTED;
1776 }
1777
1778 $videoContainer.addClass('elementor-loading' + ' ' + classes.invisible);
1779 this.player = new YT.Player($videoPlaceholderElement[0], {
1780 videoId: videoID,
1781 events: {
1782 onReady: () => {
1783 $playIcon.addClass(classes.hidden);
1784 $videoContainer.removeClass(classes.invisible);
1785 this.player.playVideo();
1786 },
1787 onStateChange: event => {
1788 if (event.data === startStateCode) {
1789 $videoContainer.removeClass('elementor-loading' + ' ' + classes.invisible);
1790 }
1791 }
1792 },
1793 playerVars: {
1794 controls: 0,
1795 rel: 0
1796 }
1797 });
1798 },
1799 prepareVimeoVideo: function (Vimeo, videoURL, $videoContainer, $videoWrapper, $playIcon) {
1800 const classes = this.getSettings('classes'),
1801 vimeoOptions = {
1802 url: videoURL,
1803 autoplay: true,
1804 transparent: false,
1805 playsinline: false
1806 };
1807 this.player = new Vimeo.Player($videoWrapper, vimeoOptions);
1808 this.player.ready().then(() => {
1809 $playIcon.addClass(classes.hidden);
1810 $videoContainer.removeClass(classes.invisible);
1811 });
1812 },
1813 setEntranceAnimation: function (animation) {
1814 animation = animation || elementorFrontend.getCurrentDeviceSetting(this.getSettings('modalOptions'), 'entranceAnimation');
1815 const $widgetMessage = this.getModal().getElements('message');
1816
1817 if (this.oldAnimation) {
1818 $widgetMessage.removeClass(this.oldAnimation);
1819 }
1820
1821 this.oldAnimation = animation;
1822
1823 if (animation) {
1824 $widgetMessage.addClass('animated ' + animation);
1825 }
1826 },
1827 openSlideshow: function (slideshowID, initialSlideURL) {
1828 const $allSlideshowLinks = jQuery(this.getSettings('selectors.links')).filter((index, element) => {
1829 const $element = jQuery(element);
1830 return slideshowID === element.dataset.elementorLightboxSlideshow && !$element.parent('.swiper-slide-duplicate').length && !$element.parents('.slick-cloned').length;
1831 });
1832 const slides = [];
1833 let initialSlideIndex = 0;
1834 $allSlideshowLinks.each(function () {
1835 const slideVideo = this.dataset.elementorLightboxVideo;
1836 let slideIndex = this.dataset.elementorLightboxIndex;
1837
1838 if (undefined === slideIndex) {
1839 slideIndex = $allSlideshowLinks.index(this);
1840 }
1841
1842 if (initialSlideURL === this.href || slideVideo && initialSlideURL === slideVideo) {
1843 initialSlideIndex = slideIndex;
1844 }
1845
1846 const slideData = {
1847 image: this.href,
1848 index: slideIndex,
1849 title: this.dataset.elementorLightboxTitle,
1850 description: this.dataset.elementorLightboxDescription
1851 };
1852
1853 if (slideVideo) {
1854 slideData.video = slideVideo;
1855 }
1856
1857 slides.push(slideData);
1858 });
1859 slides.sort((a, b) => a.index - b.index);
1860 this.showModal({
1861 type: 'slideshow',
1862 id: slideshowID,
1863 modalOptions: {
1864 id: 'elementor-lightbox-slideshow-' + slideshowID
1865 },
1866 slideshow: {
1867 slides: slides,
1868 swiper: {
1869 initialSlide: +initialSlideIndex
1870 }
1871 }
1872 });
1873 },
1874 onSlideChange: function () {
1875 this.getSlide('prev').add(this.getSlide('next')).add(this.getSlide('active')).find('.' + this.getSettings('classes.videoWrapper')).remove();
1876 this.playSlideVideo();
1877 this.updateFooterText();
1878 }
1879 });
1880
1881 /***/ }),
1882
1883 /***/ "../assets/dev/js/frontend/utils/lightbox/screenfull.js":
1884 /*!**************************************************************!*\
1885 !*** ../assets/dev/js/frontend/utils/lightbox/screenfull.js ***!
1886 \**************************************************************/
1887 /***/ ((module) => {
1888
1889 "use strict";
1890
1891
1892 (function () {
1893 'use strict';
1894
1895 var document = typeof window !== 'undefined' && typeof window.document !== 'undefined' ? window.document : {};
1896 var isCommonjs = true && module.exports;
1897
1898 var fn = function () {
1899 var val;
1900 var fnMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'], // New WebKit
1901 ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'], // Old WebKit
1902 ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'], ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'], ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
1903 var i = 0;
1904 var l = fnMap.length;
1905 var ret = {};
1906
1907 for (; i < l; i++) {
1908 val = fnMap[i];
1909
1910 if (val && val[1] in document) {
1911 var valLength = val.length;
1912
1913 for (i = 0; i < valLength; i++) {
1914 ret[fnMap[0][i]] = val[i];
1915 }
1916
1917 return ret;
1918 }
1919 }
1920
1921 return false;
1922 }();
1923
1924 var eventNameMap = {
1925 change: fn.fullscreenchange,
1926 error: fn.fullscreenerror
1927 };
1928 var screenfull = {
1929 request: function (element) {
1930 return new Promise(function (resolve, reject) {
1931 var onFullScreenEntered = function () {
1932 this.off('change', onFullScreenEntered);
1933 resolve();
1934 }.bind(this);
1935
1936 this.on('change', onFullScreenEntered);
1937 element = element || document.documentElement;
1938 Promise.resolve(element[fn.requestFullscreen]()).catch(reject);
1939 }.bind(this));
1940 },
1941 exit: function () {
1942 return new Promise(function (resolve, reject) {
1943 if (!this.isFullscreen) {
1944 resolve();
1945 return;
1946 }
1947
1948 var onFullScreenExit = function () {
1949 this.off('change', onFullScreenExit);
1950 resolve();
1951 }.bind(this);
1952
1953 this.on('change', onFullScreenExit);
1954 Promise.resolve(document[fn.exitFullscreen]()).catch(reject);
1955 }.bind(this));
1956 },
1957 toggle: function (element) {
1958 return this.isFullscreen ? this.exit() : this.request(element);
1959 },
1960 onchange: function (callback) {
1961 this.on('change', callback);
1962 },
1963 onerror: function (callback) {
1964 this.on('error', callback);
1965 },
1966 on: function (event, callback) {
1967 var eventName = eventNameMap[event];
1968
1969 if (eventName) {
1970 document.addEventListener(eventName, callback, false);
1971 }
1972 },
1973 off: function (event, callback) {
1974 var eventName = eventNameMap[event];
1975
1976 if (eventName) {
1977 document.removeEventListener(eventName, callback, false);
1978 }
1979 },
1980 raw: fn
1981 };
1982
1983 if (!fn) {
1984 if (isCommonjs) {
1985 module.exports = {
1986 isEnabled: false
1987 };
1988 } else {
1989 window.screenfull = {
1990 isEnabled: false
1991 };
1992 }
1993
1994 return;
1995 }
1996
1997 Object.defineProperties(screenfull, {
1998 isFullscreen: {
1999 get: function () {
2000 return Boolean(document[fn.fullscreenElement]);
2001 }
2002 },
2003 element: {
2004 enumerable: true,
2005 get: function () {
2006 return document[fn.fullscreenElement];
2007 }
2008 },
2009 isEnabled: {
2010 enumerable: true,
2011 get: function () {
2012 // Coerce to boolean in case of old WebKit
2013 return Boolean(document[fn.fullscreenEnabled]);
2014 }
2015 }
2016 });
2017
2018 if (isCommonjs) {
2019 module.exports = screenfull;
2020 } else {
2021 window.screenfull = screenfull;
2022 }
2023 })();
2024
2025 /***/ })
2026
2027 },
2028 /******/ __webpack_require__ => { // webpackRuntimeModules
2029 /******/ "use strict";
2030 /******/
2031 /******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
2032 /******/ __webpack_require__.O(0, ["frontend","frontend-modules"], () => (__webpack_exec__("../assets/dev/js/frontend/preloaded-modules.js")));
2033 /******/ var __webpack_exports__ = __webpack_require__.O();
2034 /******/ }
2035 ]);
2036 //# sourceMappingURL=preloaded-modules.js.map