PluginProbe
Elementor Website Builder – more than just a page builder / 3.4.3
Elementor Website Builder – more than just a page builder v3.4.3
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.3, at assets/js/preloaded-modules.js

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