UNPKG

124 kBJavaScriptView Raw
1import { useRef, useCallback, useEffect, createElement } from 'react';
2
3/*! *****************************************************************************
4Copyright (c) Microsoft Corporation.
5
6Permission to use, copy, modify, and/or distribute this software for any
7purpose with or without fee is hereby granted.
8
9THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15PERFORMANCE OF THIS SOFTWARE.
16***************************************************************************** */
17
18function __rest(s, e) {
19 var t = {};
20 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
21 t[p] = s[p];
22 if (s != null && typeof Object.getOwnPropertySymbols === "function")
23 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
24 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
25 t[p[i]] = s[p[i]];
26 }
27 return t;
28}
29
30/*!
31 * lightgallery | 2.7.1 | January 11th 2023
32 * http://www.lightgalleryjs.com/
33 * Copyright (c) 2020 Sachin Neravath;
34 * @license GPLv3
35 */
36
37/*! *****************************************************************************
38Copyright (c) Microsoft Corporation.
39
40Permission to use, copy, modify, and/or distribute this software for any
41purpose with or without fee is hereby granted.
42
43THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
44REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
45AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
46INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
47LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
48OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
49PERFORMANCE OF THIS SOFTWARE.
50***************************************************************************** */
51
52var __assign = function() {
53 __assign = Object.assign || function __assign(t) {
54 for (var s, i = 1, n = arguments.length; i < n; i++) {
55 s = arguments[i];
56 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
57 }
58 return t;
59 };
60 return __assign.apply(this, arguments);
61};
62
63function __spreadArrays() {
64 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
65 for (var r = Array(s), k = 0, i = 0; i < il; i++)
66 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
67 r[k] = a[j];
68 return r;
69}
70
71/**
72 * List of lightGallery events
73 * All events should be documented here
74 * Below interfaces are used to build the website documentations
75 * */
76var lGEvents = {
77 afterAppendSlide: 'lgAfterAppendSlide',
78 init: 'lgInit',
79 hasVideo: 'lgHasVideo',
80 containerResize: 'lgContainerResize',
81 updateSlides: 'lgUpdateSlides',
82 afterAppendSubHtml: 'lgAfterAppendSubHtml',
83 beforeOpen: 'lgBeforeOpen',
84 afterOpen: 'lgAfterOpen',
85 slideItemLoad: 'lgSlideItemLoad',
86 beforeSlide: 'lgBeforeSlide',
87 afterSlide: 'lgAfterSlide',
88 posterClick: 'lgPosterClick',
89 dragStart: 'lgDragStart',
90 dragMove: 'lgDragMove',
91 dragEnd: 'lgDragEnd',
92 beforeNextSlide: 'lgBeforeNextSlide',
93 beforePrevSlide: 'lgBeforePrevSlide',
94 beforeClose: 'lgBeforeClose',
95 afterClose: 'lgAfterClose',
96 rotateLeft: 'lgRotateLeft',
97 rotateRight: 'lgRotateRight',
98 flipHorizontal: 'lgFlipHorizontal',
99 flipVertical: 'lgFlipVertical',
100 autoplay: 'lgAutoplay',
101 autoplayStart: 'lgAutoplayStart',
102 autoplayStop: 'lgAutoplayStop',
103};
104
105var lightGalleryCoreSettings = {
106 mode: 'lg-slide',
107 easing: 'ease',
108 speed: 400,
109 licenseKey: '0000-0000-000-0000',
110 height: '100%',
111 width: '100%',
112 addClass: '',
113 startClass: 'lg-start-zoom',
114 backdropDuration: 300,
115 container: '',
116 startAnimationDuration: 400,
117 zoomFromOrigin: true,
118 hideBarsDelay: 0,
119 showBarsAfter: 10000,
120 slideDelay: 0,
121 supportLegacyBrowser: true,
122 allowMediaOverlap: false,
123 videoMaxSize: '1280-720',
124 loadYouTubePoster: true,
125 defaultCaptionHeight: 0,
126 ariaLabelledby: '',
127 ariaDescribedby: '',
128 resetScrollPosition: true,
129 hideScrollbar: false,
130 closable: true,
131 swipeToClose: true,
132 closeOnTap: true,
133 showCloseIcon: true,
134 showMaximizeIcon: false,
135 loop: true,
136 escKey: true,
137 keyPress: true,
138 trapFocus: true,
139 controls: true,
140 slideEndAnimation: true,
141 hideControlOnEnd: false,
142 mousewheel: false,
143 getCaptionFromTitleOrAlt: true,
144 appendSubHtmlTo: '.lg-sub-html',
145 subHtmlSelectorRelative: false,
146 preload: 2,
147 numberOfSlideItemsInDom: 10,
148 selector: '',
149 selectWithin: '',
150 nextHtml: '',
151 prevHtml: '',
152 index: 0,
153 iframeWidth: '100%',
154 iframeHeight: '100%',
155 iframeMaxWidth: '100%',
156 iframeMaxHeight: '100%',
157 download: true,
158 counter: true,
159 appendCounterTo: '.lg-toolbar',
160 swipeThreshold: 50,
161 enableSwipe: true,
162 enableDrag: true,
163 dynamic: false,
164 dynamicEl: [],
165 extraProps: [],
166 exThumbImage: '',
167 isMobile: undefined,
168 mobileSettings: {
169 controls: false,
170 showCloseIcon: false,
171 download: false,
172 },
173 plugins: [],
174 strings: {
175 closeGallery: 'Close gallery',
176 toggleMaximize: 'Toggle maximize',
177 previousSlide: 'Previous slide',
178 nextSlide: 'Next slide',
179 download: 'Download',
180 playVideo: 'Play video',
181 },
182};
183
184function initLgPolyfills() {
185 (function () {
186 if (typeof window.CustomEvent === 'function')
187 return false;
188 function CustomEvent(event, params) {
189 params = params || {
190 bubbles: false,
191 cancelable: false,
192 detail: null,
193 };
194 var evt = document.createEvent('CustomEvent');
195 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
196 return evt;
197 }
198 window.CustomEvent = CustomEvent;
199 })();
200 (function () {
201 if (!Element.prototype.matches) {
202 Element.prototype.matches =
203 Element.prototype.msMatchesSelector ||
204 Element.prototype.webkitMatchesSelector;
205 }
206 })();
207}
208var lgQuery = /** @class */ (function () {
209 function lgQuery(selector) {
210 this.cssVenderPrefixes = [
211 'TransitionDuration',
212 'TransitionTimingFunction',
213 'Transform',
214 'Transition',
215 ];
216 this.selector = this._getSelector(selector);
217 this.firstElement = this._getFirstEl();
218 return this;
219 }
220 lgQuery.generateUUID = function () {
221 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
222 var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;
223 return v.toString(16);
224 });
225 };
226 lgQuery.prototype._getSelector = function (selector, context) {
227 if (context === void 0) { context = document; }
228 if (typeof selector !== 'string') {
229 return selector;
230 }
231 context = context || document;
232 var fl = selector.substring(0, 1);
233 if (fl === '#') {
234 return context.querySelector(selector);
235 }
236 else {
237 return context.querySelectorAll(selector);
238 }
239 };
240 lgQuery.prototype._each = function (func) {
241 if (!this.selector) {
242 return this;
243 }
244 if (this.selector.length !== undefined) {
245 [].forEach.call(this.selector, func);
246 }
247 else {
248 func(this.selector, 0);
249 }
250 return this;
251 };
252 lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) {
253 // prettier-ignore
254 var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) {
255 return group1.toUpperCase();
256 });
257 if (this.cssVenderPrefixes.indexOf(property) !== -1) {
258 el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value;
259 el.style['webkit' + property] = value;
260 el.style['moz' + property] = value;
261 el.style['ms' + property] = value;
262 el.style['o' + property] = value;
263 }
264 else {
265 el.style[property] = value;
266 }
267 };
268 lgQuery.prototype._getFirstEl = function () {
269 if (this.selector && this.selector.length !== undefined) {
270 return this.selector[0];
271 }
272 else {
273 return this.selector;
274 }
275 };
276 lgQuery.prototype.isEventMatched = function (event, eventName) {
277 var eventNamespace = eventName.split('.');
278 return event
279 .split('.')
280 .filter(function (e) { return e; })
281 .every(function (e) {
282 return eventNamespace.indexOf(e) !== -1;
283 });
284 };
285 lgQuery.prototype.attr = function (attr, value) {
286 if (value === undefined) {
287 if (!this.firstElement) {
288 return '';
289 }
290 return this.firstElement.getAttribute(attr);
291 }
292 this._each(function (el) {
293 el.setAttribute(attr, value);
294 });
295 return this;
296 };
297 lgQuery.prototype.find = function (selector) {
298 return $LG(this._getSelector(selector, this.selector));
299 };
300 lgQuery.prototype.first = function () {
301 if (this.selector && this.selector.length !== undefined) {
302 return $LG(this.selector[0]);
303 }
304 else {
305 return $LG(this.selector);
306 }
307 };
308 lgQuery.prototype.eq = function (index) {
309 return $LG(this.selector[index]);
310 };
311 lgQuery.prototype.parent = function () {
312 return $LG(this.selector.parentElement);
313 };
314 lgQuery.prototype.get = function () {
315 return this._getFirstEl();
316 };
317 lgQuery.prototype.removeAttr = function (attributes) {
318 var attrs = attributes.split(' ');
319 this._each(function (el) {
320 attrs.forEach(function (attr) { return el.removeAttribute(attr); });
321 });
322 return this;
323 };
324 lgQuery.prototype.wrap = function (className) {
325 if (!this.firstElement) {
326 return this;
327 }
328 var wrapper = document.createElement('div');
329 wrapper.className = className;
330 this.firstElement.parentNode.insertBefore(wrapper, this.firstElement);
331 this.firstElement.parentNode.removeChild(this.firstElement);
332 wrapper.appendChild(this.firstElement);
333 return this;
334 };
335 lgQuery.prototype.addClass = function (classNames) {
336 if (classNames === void 0) { classNames = ''; }
337 this._each(function (el) {
338 // IE doesn't support multiple arguments
339 classNames.split(' ').forEach(function (className) {
340 if (className) {
341 el.classList.add(className);
342 }
343 });
344 });
345 return this;
346 };
347 lgQuery.prototype.removeClass = function (classNames) {
348 this._each(function (el) {
349 // IE doesn't support multiple arguments
350 classNames.split(' ').forEach(function (className) {
351 if (className) {
352 el.classList.remove(className);
353 }
354 });
355 });
356 return this;
357 };
358 lgQuery.prototype.hasClass = function (className) {
359 if (!this.firstElement) {
360 return false;
361 }
362 return this.firstElement.classList.contains(className);
363 };
364 lgQuery.prototype.hasAttribute = function (attribute) {
365 if (!this.firstElement) {
366 return false;
367 }
368 return this.firstElement.hasAttribute(attribute);
369 };
370 lgQuery.prototype.toggleClass = function (className) {
371 if (!this.firstElement) {
372 return this;
373 }
374 if (this.hasClass(className)) {
375 this.removeClass(className);
376 }
377 else {
378 this.addClass(className);
379 }
380 return this;
381 };
382 lgQuery.prototype.css = function (property, value) {
383 var _this = this;
384 this._each(function (el) {
385 _this._setCssVendorPrefix(el, property, value);
386 });
387 return this;
388 };
389 // Need to pass separate namespaces for separate elements
390 lgQuery.prototype.on = function (events, listener) {
391 var _this = this;
392 if (!this.selector) {
393 return this;
394 }
395 events.split(' ').forEach(function (event) {
396 if (!Array.isArray(lgQuery.eventListeners[event])) {
397 lgQuery.eventListeners[event] = [];
398 }
399 lgQuery.eventListeners[event].push(listener);
400 _this.selector.addEventListener(event.split('.')[0], listener);
401 });
402 return this;
403 };
404 // @todo - test this
405 lgQuery.prototype.once = function (event, listener) {
406 var _this = this;
407 this.on(event, function () {
408 _this.off(event);
409 listener(event);
410 });
411 return this;
412 };
413 lgQuery.prototype.off = function (event) {
414 var _this = this;
415 if (!this.selector) {
416 return this;
417 }
418 Object.keys(lgQuery.eventListeners).forEach(function (eventName) {
419 if (_this.isEventMatched(event, eventName)) {
420 lgQuery.eventListeners[eventName].forEach(function (listener) {
421 _this.selector.removeEventListener(eventName.split('.')[0], listener);
422 });
423 lgQuery.eventListeners[eventName] = [];
424 }
425 });
426 return this;
427 };
428 lgQuery.prototype.trigger = function (event, detail) {
429 if (!this.firstElement) {
430 return this;
431 }
432 var customEvent = new CustomEvent(event.split('.')[0], {
433 detail: detail || null,
434 });
435 this.firstElement.dispatchEvent(customEvent);
436 return this;
437 };
438 // Does not support IE
439 lgQuery.prototype.load = function (url) {
440 var _this = this;
441 fetch(url)
442 .then(function (res) { return res.text(); })
443 .then(function (html) {
444 _this.selector.innerHTML = html;
445 });
446 return this;
447 };
448 lgQuery.prototype.html = function (html) {
449 if (html === undefined) {
450 if (!this.firstElement) {
451 return '';
452 }
453 return this.firstElement.innerHTML;
454 }
455 this._each(function (el) {
456 el.innerHTML = html;
457 });
458 return this;
459 };
460 lgQuery.prototype.append = function (html) {
461 this._each(function (el) {
462 if (typeof html === 'string') {
463 el.insertAdjacentHTML('beforeend', html);
464 }
465 else {
466 el.appendChild(html);
467 }
468 });
469 return this;
470 };
471 lgQuery.prototype.prepend = function (html) {
472 this._each(function (el) {
473 el.insertAdjacentHTML('afterbegin', html);
474 });
475 return this;
476 };
477 lgQuery.prototype.remove = function () {
478 this._each(function (el) {
479 el.parentNode.removeChild(el);
480 });
481 return this;
482 };
483 lgQuery.prototype.empty = function () {
484 this._each(function (el) {
485 el.innerHTML = '';
486 });
487 return this;
488 };
489 lgQuery.prototype.scrollTop = function (scrollTop) {
490 if (scrollTop !== undefined) {
491 document.body.scrollTop = scrollTop;
492 document.documentElement.scrollTop = scrollTop;
493 return this;
494 }
495 else {
496 return (window.pageYOffset ||
497 document.documentElement.scrollTop ||
498 document.body.scrollTop ||
499 0);
500 }
501 };
502 lgQuery.prototype.scrollLeft = function (scrollLeft) {
503 if (scrollLeft !== undefined) {
504 document.body.scrollLeft = scrollLeft;
505 document.documentElement.scrollLeft = scrollLeft;
506 return this;
507 }
508 else {
509 return (window.pageXOffset ||
510 document.documentElement.scrollLeft ||
511 document.body.scrollLeft ||
512 0);
513 }
514 };
515 lgQuery.prototype.offset = function () {
516 if (!this.firstElement) {
517 return {
518 left: 0,
519 top: 0,
520 };
521 }
522 var rect = this.firstElement.getBoundingClientRect();
523 var bodyMarginLeft = $LG('body').style().marginLeft;
524 // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value
525 return {
526 left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(),
527 top: rect.top + this.scrollTop(),
528 };
529 };
530 lgQuery.prototype.style = function () {
531 if (!this.firstElement) {
532 return {};
533 }
534 return (this.firstElement.currentStyle ||
535 window.getComputedStyle(this.firstElement));
536 };
537 // Width without padding and border even if box-sizing is used.
538 lgQuery.prototype.width = function () {
539 var style = this.style();
540 return (this.firstElement.clientWidth -
541 parseFloat(style.paddingLeft) -
542 parseFloat(style.paddingRight));
543 };
544 // Height without padding and border even if box-sizing is used.
545 lgQuery.prototype.height = function () {
546 var style = this.style();
547 return (this.firstElement.clientHeight -
548 parseFloat(style.paddingTop) -
549 parseFloat(style.paddingBottom));
550 };
551 lgQuery.eventListeners = {};
552 return lgQuery;
553}());
554function $LG(selector) {
555 initLgPolyfills();
556 return new lgQuery(selector);
557}
558
559var defaultDynamicOptions = [
560 'src',
561 'sources',
562 'subHtml',
563 'subHtmlUrl',
564 'html',
565 'video',
566 'poster',
567 'slideName',
568 'responsive',
569 'srcset',
570 'sizes',
571 'iframe',
572 'downloadUrl',
573 'download',
574 'width',
575 'facebookShareUrl',
576 'tweetText',
577 'iframeTitle',
578 'twitterShareUrl',
579 'pinterestShareUrl',
580 'pinterestText',
581 'fbHtml',
582 'disqusIdentifier',
583 'disqusUrl',
584];
585// Convert html data-attribute to camalcase
586function convertToData(attr) {
587 // FInd a way for lgsize
588 if (attr === 'href') {
589 return 'src';
590 }
591 attr = attr.replace('data-', '');
592 attr = attr.charAt(0).toLowerCase() + attr.slice(1);
593 attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
594 return attr;
595}
596var utils = {
597 /**
598 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option
599 */
600 getSize: function (el, container, spacing, defaultLgSize) {
601 if (spacing === void 0) { spacing = 0; }
602 var LGel = $LG(el);
603 var lgSize = LGel.attr('data-lg-size') || defaultLgSize;
604 if (!lgSize) {
605 return;
606 }
607 var isResponsiveSizes = lgSize.split(',');
608 // if at-least two viewport sizes are available
609 if (isResponsiveSizes[1]) {
610 var wWidth = window.innerWidth;
611 for (var i = 0; i < isResponsiveSizes.length; i++) {
612 var size_1 = isResponsiveSizes[i];
613 var responsiveWidth = parseInt(size_1.split('-')[2], 10);
614 if (responsiveWidth > wWidth) {
615 lgSize = size_1;
616 break;
617 }
618 // take last item as last option
619 if (i === isResponsiveSizes.length - 1) {
620 lgSize = size_1;
621 }
622 }
623 }
624 var size = lgSize.split('-');
625 var width = parseInt(size[0], 10);
626 var height = parseInt(size[1], 10);
627 var cWidth = container.width();
628 var cHeight = container.height() - spacing;
629 var maxWidth = Math.min(cWidth, width);
630 var maxHeight = Math.min(cHeight, height);
631 var ratio = Math.min(maxWidth / width, maxHeight / height);
632 return { width: width * ratio, height: height * ratio };
633 },
634 /**
635 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option
636 * @param {jQuery Element}
637 * @returns {String} Transform CSS string
638 */
639 getTransform: function (el, container, top, bottom, imageSize) {
640 if (!imageSize) {
641 return;
642 }
643 var LGel = $LG(el).find('img').first();
644 if (!LGel.get()) {
645 return;
646 }
647 var containerRect = container.get().getBoundingClientRect();
648 var wWidth = containerRect.width;
649 // using innerWidth to include mobile safari bottom bar
650 var wHeight = container.height() - (top + bottom);
651 var elWidth = LGel.width();
652 var elHeight = LGel.height();
653 var elStyle = LGel.style();
654 var x = (wWidth - elWidth) / 2 -
655 LGel.offset().left +
656 (parseFloat(elStyle.paddingLeft) || 0) +
657 (parseFloat(elStyle.borderLeft) || 0) +
658 $LG(window).scrollLeft() +
659 containerRect.left;
660 var y = (wHeight - elHeight) / 2 -
661 LGel.offset().top +
662 (parseFloat(elStyle.paddingTop) || 0) +
663 (parseFloat(elStyle.borderTop) || 0) +
664 $LG(window).scrollTop() +
665 top;
666 var scX = elWidth / imageSize.width;
667 var scY = elHeight / imageSize.height;
668 var transform = 'translate3d(' +
669 (x *= -1) +
670 'px, ' +
671 (y *= -1) +
672 'px, 0) scale3d(' +
673 scX +
674 ', ' +
675 scY +
676 ', 1)';
677 return transform;
678 },
679 getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) {
680 var title = iframeTitle ? 'title="' + iframeTitle + '"' : '';
681 return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:" + iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\" allowfullscreen=\"true\"></iframe>\n </div>";
682 },
683 getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) {
684 var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : '';
685 var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : '';
686 var imgMarkup = "<img " + altAttr + " " + srcsetAttr + " " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />";
687 var sourceTag = '';
688 if (sources) {
689 var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources;
690 sourceTag = sourceObj.map(function (source) {
691 var attrs = '';
692 Object.keys(source).forEach(function (key) {
693 // Do not remove the first space as it is required to separate the attributes
694 attrs += " " + key + "=\"" + source[key] + "\"";
695 });
696 return "<source " + attrs + "></source>";
697 });
698 }
699 return "" + sourceTag + imgMarkup;
700 },
701 // Get src from responsive src
702 getResponsiveSrc: function (srcItms) {
703 var rsWidth = [];
704 var rsSrc = [];
705 var src = '';
706 for (var i = 0; i < srcItms.length; i++) {
707 var _src = srcItms[i].split(' ');
708 // Manage empty space
709 if (_src[0] === '') {
710 _src.splice(0, 1);
711 }
712 rsSrc.push(_src[0]);
713 rsWidth.push(_src[1]);
714 }
715 var wWidth = window.innerWidth;
716 for (var j = 0; j < rsWidth.length; j++) {
717 if (parseInt(rsWidth[j], 10) > wWidth) {
718 src = rsSrc[j];
719 break;
720 }
721 }
722 return src;
723 },
724 isImageLoaded: function (img) {
725 if (!img)
726 return false;
727 // During the onload event, IE correctly identifies any images that
728 // weren’t downloaded as not complete. Others should too. Gecko-based
729 // browsers act like NS4 in that they report this incorrectly.
730 if (!img.complete) {
731 return false;
732 }
733 // However, they do have two very useful properties: naturalWidth and
734 // naturalHeight. These give the true size of the image. If it failed
735 // to load, either of these should be zero.
736 if (img.naturalWidth === 0) {
737 return false;
738 }
739 // No other way of checking: assume it’s ok.
740 return true;
741 },
742 getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) {
743 var videoClass = '';
744 if (_isVideo && _isVideo.youtube) {
745 videoClass = 'lg-has-youtube';
746 }
747 else if (_isVideo && _isVideo.vimeo) {
748 videoClass = 'lg-has-vimeo';
749 }
750 else {
751 videoClass = 'lg-has-html5';
752 }
753 return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n <div class=\"lg-video-play-button\">\n <svg\n viewBox=\"0 0 20 20\"\n preserveAspectRatio=\"xMidYMid\"\n focusable=\"false\"\n aria-labelledby=\"" + playVideoString + "\"\n role=\"img\"\n class=\"lg-video-play-icon\"\n >\n <title>" + playVideoString + "</title>\n <polygon class=\"lg-video-play-icon-inner\" points=\"1,0 20,10 1,20\"></polygon>\n </svg>\n <svg class=\"lg-video-play-icon-bg\" viewBox=\"0 0 50 50\" focusable=\"false\">\n <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle></svg>\n <svg class=\"lg-video-play-icon-circle\" viewBox=\"0 0 50 50\" focusable=\"false\">\n <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle>\n </svg>\n </div>\n " + (dummyImg || '') + "\n <img class=\"lg-object lg-video-poster\" src=\"" + _poster + "\" />\n </div>";
754 },
755 getFocusableElements: function (container) {
756 var elements = container.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])');
757 var visibleElements = [].filter.call(elements, function (element) {
758 var style = window.getComputedStyle(element);
759 return style.display !== 'none' && style.visibility !== 'hidden';
760 });
761 return visibleElements;
762 },
763 /**
764 * @desc Create dynamic elements array from gallery items when dynamic option is false
765 * It helps to avoid frequent DOM interaction
766 * and avoid multiple checks for dynamic elments
767 *
768 * @returns {Array} dynamicEl
769 */
770 getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) {
771 var dynamicElements = [];
772 var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps);
773 [].forEach.call(items, function (item) {
774 var dynamicEl = {};
775 for (var i = 0; i < item.attributes.length; i++) {
776 var attr = item.attributes[i];
777 if (attr.specified) {
778 var dynamicAttr = convertToData(attr.name);
779 var label = '';
780 if (availableDynamicOptions.indexOf(dynamicAttr) > -1) {
781 label = dynamicAttr;
782 }
783 if (label) {
784 dynamicEl[label] = attr.value;
785 }
786 }
787 }
788 var currentItem = $LG(item);
789 var alt = currentItem.find('img').first().attr('alt');
790 var title = currentItem.attr('title');
791 var thumb = exThumbImage
792 ? currentItem.attr(exThumbImage)
793 : currentItem.find('img').first().attr('src');
794 dynamicEl.thumb = thumb;
795 if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) {
796 dynamicEl.subHtml = title || alt || '';
797 }
798 dynamicEl.alt = alt || title || '';
799 dynamicElements.push(dynamicEl);
800 });
801 return dynamicElements;
802 },
803 isMobile: function () {
804 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
805 },
806 /**
807 * @desc Check the given src is video
808 * @param {String} src
809 * @return {Object} video type
810 * Ex:{ youtube : ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] }
811 *
812 * @todo - this information can be moved to dynamicEl to avoid frequent calls
813 */
814 isVideo: function (src, isHTML5VIdeo, index) {
815 if (!src) {
816 if (isHTML5VIdeo) {
817 return {
818 html5: true,
819 };
820 }
821 else {
822 console.error('lightGallery :- data-src is not provided on slide item ' +
823 (index + 1) +
824 '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/');
825 return;
826 }
827 }
828 var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i);
829 var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i);
830 var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/);
831 if (youtube) {
832 return {
833 youtube: youtube,
834 };
835 }
836 else if (vimeo) {
837 return {
838 vimeo: vimeo,
839 };
840 }
841 else if (wistia) {
842 return {
843 wistia: wistia,
844 };
845 }
846 },
847};
848
849// @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio
850// @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html
851// Unique id for each gallery
852var lgId = 0;
853var LightGallery = /** @class */ (function () {
854 function LightGallery(element, options) {
855 this.lgOpened = false;
856 this.index = 0;
857 // lightGallery modules
858 this.plugins = [];
859 // false when lightGallery load first slide content;
860 this.lGalleryOn = false;
861 // True when a slide animation is in progress
862 this.lgBusy = false;
863 this.currentItemsInDom = [];
864 // Scroll top value before lightGallery is opened
865 this.prevScrollTop = 0;
866 this.bodyPaddingRight = 0;
867 this.isDummyImageRemoved = false;
868 this.dragOrSwipeEnabled = false;
869 this.mediaContainerPosition = {
870 top: 0,
871 bottom: 0,
872 };
873 if (!element) {
874 return this;
875 }
876 lgId++;
877 this.lgId = lgId;
878 this.el = element;
879 this.LGel = $LG(element);
880 this.generateSettings(options);
881 this.buildModules();
882 // When using dynamic mode, ensure dynamicEl is an array
883 if (this.settings.dynamic &&
884 this.settings.dynamicEl !== undefined &&
885 !Array.isArray(this.settings.dynamicEl)) {
886 throw 'When using dynamic mode, you must also define dynamicEl as an Array.';
887 }
888 this.galleryItems = this.getItems();
889 this.normalizeSettings();
890 // Gallery items
891 this.init();
892 this.validateLicense();
893 return this;
894 }
895 LightGallery.prototype.generateSettings = function (options) {
896 // lightGallery settings
897 this.settings = __assign(__assign({}, lightGalleryCoreSettings), options);
898 if (this.settings.isMobile &&
899 typeof this.settings.isMobile === 'function'
900 ? this.settings.isMobile()
901 : utils.isMobile()) {
902 var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings);
903 this.settings = __assign(__assign({}, this.settings), mobileSettings);
904 }
905 };
906 LightGallery.prototype.normalizeSettings = function () {
907 if (this.settings.slideEndAnimation) {
908 this.settings.hideControlOnEnd = false;
909 }
910 if (!this.settings.closable) {
911 this.settings.swipeToClose = false;
912 }
913 // And reset it on close to get the correct value next time
914 this.zoomFromOrigin = this.settings.zoomFromOrigin;
915 // At the moment, Zoom from image doesn't support dynamic options
916 // @todo add zoomFromOrigin support for dynamic images
917 if (this.settings.dynamic) {
918 this.zoomFromOrigin = false;
919 }
920 if (!this.settings.container) {
921 this.settings.container = document.body;
922 }
923 // settings.preload should not be grater than $item.length
924 this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length);
925 };
926 LightGallery.prototype.init = function () {
927 var _this = this;
928 this.addSlideVideoInfo(this.galleryItems);
929 this.buildStructure();
930 this.LGel.trigger(lGEvents.init, {
931 instance: this,
932 });
933 if (this.settings.keyPress) {
934 this.keyPress();
935 }
936 setTimeout(function () {
937 _this.enableDrag();
938 _this.enableSwipe();
939 _this.triggerPosterClick();
940 }, 50);
941 this.arrow();
942 if (this.settings.mousewheel) {
943 this.mousewheel();
944 }
945 if (!this.settings.dynamic) {
946 this.openGalleryOnItemClick();
947 }
948 };
949 LightGallery.prototype.openGalleryOnItemClick = function () {
950 var _this = this;
951 var _loop_1 = function (index) {
952 var element = this_1.items[index];
953 var $element = $LG(element);
954 // Using different namespace for click because click event should not unbind if selector is same object('this')
955 // @todo manage all event listners - should have namespace that represent element
956 var uuid = lgQuery.generateUUID();
957 $element
958 .attr('data-lg-id', uuid)
959 .on("click.lgcustom-item-" + uuid, function (e) {
960 e.preventDefault();
961 var currentItemIndex = _this.settings.index || index;
962 _this.openGallery(currentItemIndex, element);
963 });
964 };
965 var this_1 = this;
966 // Using for loop instead of using bubbling as the items can be any html element.
967 for (var index = 0; index < this.items.length; index++) {
968 _loop_1(index);
969 }
970 };
971 /**
972 * Module constructor
973 * Modules are build incrementally.
974 * Gallery should be opened only once all the modules are initialized.
975 * use moduleBuildTimeout to make sure this
976 */
977 LightGallery.prototype.buildModules = function () {
978 var _this = this;
979 this.settings.plugins.forEach(function (plugin) {
980 _this.plugins.push(new plugin(_this, $LG));
981 });
982 };
983 LightGallery.prototype.validateLicense = function () {
984 if (!this.settings.licenseKey) {
985 console.error('Please provide a valid license key');
986 }
987 else if (this.settings.licenseKey === '0000-0000-000-0000') {
988 console.warn("lightGallery: " + this.settings.licenseKey + " license key is not valid for production use");
989 }
990 };
991 LightGallery.prototype.getSlideItem = function (index) {
992 return $LG(this.getSlideItemId(index));
993 };
994 LightGallery.prototype.getSlideItemId = function (index) {
995 return "#lg-item-" + this.lgId + "-" + index;
996 };
997 LightGallery.prototype.getIdName = function (id) {
998 return id + "-" + this.lgId;
999 };
1000 LightGallery.prototype.getElementById = function (id) {
1001 return $LG("#" + this.getIdName(id));
1002 };
1003 LightGallery.prototype.manageSingleSlideClassName = function () {
1004 if (this.galleryItems.length < 2) {
1005 this.outer.addClass('lg-single-item');
1006 }
1007 else {
1008 this.outer.removeClass('lg-single-item');
1009 }
1010 };
1011 LightGallery.prototype.buildStructure = function () {
1012 var _this = this;
1013 var container = this.$container && this.$container.get();
1014 if (container) {
1015 return;
1016 }
1017 var controls = '';
1018 var subHtmlCont = '';
1019 // Create controls
1020 if (this.settings.controls) {
1021 controls = "<button type=\"button\" id=\"" + this.getIdName('lg-prev') + "\" aria-label=\"" + this.settings.strings['previousSlide'] + "\" class=\"lg-prev lg-icon\"> " + this.settings.prevHtml + " </button>\n <button type=\"button\" id=\"" + this.getIdName('lg-next') + "\" aria-label=\"" + this.settings.strings['nextSlide'] + "\" class=\"lg-next lg-icon\"> " + this.settings.nextHtml + " </button>";
1022 }
1023 if (this.settings.appendSubHtmlTo !== '.lg-item') {
1024 subHtmlCont =
1025 '<div class="lg-sub-html" role="status" aria-live="polite"></div>';
1026 }
1027 var addClasses = '';
1028 if (this.settings.allowMediaOverlap) {
1029 // Do not remove space before last single quote
1030 addClasses += 'lg-media-overlap ';
1031 }
1032 var ariaLabelledby = this.settings.ariaLabelledby
1033 ? 'aria-labelledby="' + this.settings.ariaLabelledby + '"'
1034 : '';
1035 var ariaDescribedby = this.settings.ariaDescribedby
1036 ? 'aria-describedby="' + this.settings.ariaDescribedby + '"'
1037 : '';
1038 var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : '');
1039 var closeIcon = this.settings.closable && this.settings.showCloseIcon
1040 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>"
1041 : '';
1042 var maximizeIcon = this.settings.showMaximizeIcon
1043 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>"
1044 : '';
1045 var template = "\n <div class=\"" + containerClassName + "\" id=\"" + this.getIdName('lg-container') + "\" tabindex=\"-1\" aria-modal=\"true\" " + ariaLabelledby + " " + ariaDescribedby + " role=\"dialog\"\n >\n <div id=\"" + this.getIdName('lg-backdrop') + "\" class=\"lg-backdrop\"></div>\n\n <div id=\"" + this.getIdName('lg-outer') + "\" class=\"lg-outer lg-use-css3 lg-css3 lg-hide-items " + addClasses + " \">\n\n <div id=\"" + this.getIdName('lg-content') + "\" class=\"lg-content\">\n <div id=\"" + this.getIdName('lg-inner') + "\" class=\"lg-inner\">\n </div>\n " + controls + "\n </div>\n <div id=\"" + this.getIdName('lg-toolbar') + "\" class=\"lg-toolbar lg-group\">\n " + maximizeIcon + "\n " + closeIcon + "\n </div>\n " + (this.settings.appendSubHtmlTo === '.lg-outer'
1046 ? subHtmlCont
1047 : '') + "\n <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n " + (this.settings.appendSubHtmlTo === '.lg-sub-html'
1048 ? subHtmlCont
1049 : '') + "\n </div>\n </div>\n </div>\n ";
1050 $LG(this.settings.container).append(template);
1051 if (document.body !== this.settings.container) {
1052 $LG(this.settings.container).css('position', 'relative');
1053 }
1054 this.outer = this.getElementById('lg-outer');
1055 this.$lgComponents = this.getElementById('lg-components');
1056 this.$backdrop = this.getElementById('lg-backdrop');
1057 this.$container = this.getElementById('lg-container');
1058 this.$inner = this.getElementById('lg-inner');
1059 this.$content = this.getElementById('lg-content');
1060 this.$toolbar = this.getElementById('lg-toolbar');
1061 this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms');
1062 var outerClassNames = this.settings.mode + " ";
1063 this.manageSingleSlideClassName();
1064 if (this.settings.enableDrag) {
1065 outerClassNames += 'lg-grab ';
1066 }
1067 this.outer.addClass(outerClassNames);
1068 this.$inner.css('transition-timing-function', this.settings.easing);
1069 this.$inner.css('transition-duration', this.settings.speed + 'ms');
1070 if (this.settings.download) {
1071 this.$toolbar.append("<a id=\"" + this.getIdName('lg-download') + "\" target=\"_blank\" rel=\"noopener\" aria-label=\"" + this.settings.strings['download'] + "\" download class=\"lg-download lg-icon\"></a>");
1072 }
1073 this.counter();
1074 $LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () {
1075 _this.refreshOnResize();
1076 });
1077 this.hideBars();
1078 this.manageCloseGallery();
1079 this.toggleMaximize();
1080 this.initModules();
1081 };
1082 LightGallery.prototype.refreshOnResize = function () {
1083 if (this.lgOpened) {
1084 var currentGalleryItem = this.galleryItems[this.index];
1085 var __slideVideoInfo = currentGalleryItem.__slideVideoInfo;
1086 this.mediaContainerPosition = this.getMediaContainerPosition();
1087 var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom;
1088 this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize);
1089 if (__slideVideoInfo) {
1090 this.resizeVideoSlide(this.index, this.currentImageSize);
1091 }
1092 if (this.zoomFromOrigin && !this.isDummyImageRemoved) {
1093 var imgStyle = this.getDummyImgStyles(this.currentImageSize);
1094 this.outer
1095 .find('.lg-current .lg-dummy-img')
1096 .first()
1097 .attr('style', imgStyle);
1098 }
1099 this.LGel.trigger(lGEvents.containerResize);
1100 }
1101 };
1102 LightGallery.prototype.resizeVideoSlide = function (index, imageSize) {
1103 var lgVideoStyle = this.getVideoContStyle(imageSize);
1104 var currentSlide = this.getSlideItem(index);
1105 currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle);
1106 };
1107 /**
1108 * Update slides dynamically.
1109 * Add, edit or delete slides dynamically when lightGallery is opened.
1110 * Modify the current gallery items and pass it via updateSlides method
1111 * @note
1112 * - Do not mutate existing lightGallery items directly.
1113 * - Always pass new list of gallery items
1114 * - You need to take care of thumbnails outside the gallery if any
1115 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method.
1116 * @param items Gallery items
1117 * @param index After the update operation, which slide gallery should navigate to
1118 * @category lGPublicMethods
1119 * @example
1120 * const plugin = lightGallery();
1121 *
1122 * // Adding slides dynamically
1123 * let galleryItems = [
1124 * // Access existing lightGallery items
1125 * // galleryItems are automatically generated internally from the gallery HTML markup
1126 * // or directly from galleryItems when dynamic gallery is used
1127 * ...plugin.galleryItems,
1128 * ...[
1129 * {
1130 * src: 'img/img-1.png',
1131 * thumb: 'img/thumb1.png',
1132 * },
1133 * ],
1134 * ];
1135 * plugin.updateSlides(
1136 * galleryItems,
1137 * plugin.index,
1138 * );
1139 *
1140 *
1141 * // Remove slides dynamically
1142 * galleryItems = JSON.parse(
1143 * JSON.stringify(updateSlideInstance.galleryItems),
1144 * );
1145 * galleryItems.shift();
1146 * updateSlideInstance.updateSlides(galleryItems, 1);
1147 * @see <a href="/demos/update-slides/">Demo</a>
1148 */
1149 LightGallery.prototype.updateSlides = function (items, index) {
1150 if (this.index > items.length - 1) {
1151 this.index = items.length - 1;
1152 }
1153 if (items.length === 1) {
1154 this.index = 0;
1155 }
1156 if (!items.length) {
1157 this.closeGallery();
1158 return;
1159 }
1160 var currentSrc = this.galleryItems[index].src;
1161 this.galleryItems = items;
1162 this.updateControls();
1163 this.$inner.empty();
1164 this.currentItemsInDom = [];
1165 var _index = 0;
1166 // Find the current index based on source value of the slide
1167 this.galleryItems.some(function (galleryItem, itemIndex) {
1168 if (galleryItem.src === currentSrc) {
1169 _index = itemIndex;
1170 return true;
1171 }
1172 return false;
1173 });
1174 this.currentItemsInDom = this.organizeSlideItems(_index, -1);
1175 this.loadContent(_index, true);
1176 this.getSlideItem(_index).addClass('lg-current');
1177 this.index = _index;
1178 this.updateCurrentCounter(_index);
1179 this.LGel.trigger(lGEvents.updateSlides);
1180 };
1181 // Get gallery items based on multiple conditions
1182 LightGallery.prototype.getItems = function () {
1183 // Gallery items
1184 this.items = [];
1185 if (!this.settings.dynamic) {
1186 if (this.settings.selector === 'this') {
1187 this.items.push(this.el);
1188 }
1189 else if (this.settings.selector) {
1190 if (typeof this.settings.selector === 'string') {
1191 if (this.settings.selectWithin) {
1192 var selectWithin = $LG(this.settings.selectWithin);
1193 this.items = selectWithin
1194 .find(this.settings.selector)
1195 .get();
1196 }
1197 else {
1198 this.items = this.el.querySelectorAll(this.settings.selector);
1199 }
1200 }
1201 else {
1202 this.items = this.settings.selector;
1203 }
1204 }
1205 else {
1206 this.items = this.el.children;
1207 }
1208 return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage);
1209 }
1210 else {
1211 return this.settings.dynamicEl || [];
1212 }
1213 };
1214 LightGallery.prototype.shouldHideScrollbar = function () {
1215 return (this.settings.hideScrollbar &&
1216 document.body === this.settings.container);
1217 };
1218 LightGallery.prototype.hideScrollbar = function () {
1219 if (!this.shouldHideScrollbar()) {
1220 return;
1221 }
1222 this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight);
1223 var bodyRect = document.documentElement.getBoundingClientRect();
1224 var scrollbarWidth = window.innerWidth - bodyRect.width;
1225 $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px');
1226 $LG(document.body).addClass('lg-overlay-open');
1227 };
1228 LightGallery.prototype.resetScrollBar = function () {
1229 if (!this.shouldHideScrollbar()) {
1230 return;
1231 }
1232 $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px');
1233 $LG(document.body).removeClass('lg-overlay-open');
1234 };
1235 /**
1236 * Open lightGallery.
1237 * Open gallery with specific slide by passing index of the slide as parameter.
1238 * @category lGPublicMethods
1239 * @param {Number} index - index of the slide
1240 * @param {HTMLElement} element - Which image lightGallery should zoom from
1241 *
1242 * @example
1243 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo');
1244 * const dynamicGallery = lightGallery($dynamicGallery, {
1245 * dynamic: true,
1246 * dynamicEl: [
1247 * {
1248 * src: 'img/1.jpg',
1249 * thumb: 'img/thumb-1.jpg',
1250 * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>',
1251 * },
1252 * ...
1253 * ],
1254 * });
1255 * $dynamicGallery.addEventListener('click', function () {
1256 * // Starts with third item.(Optional).
1257 * // This is useful if you want use dynamic mode with
1258 * // custom thumbnails (thumbnails outside gallery),
1259 * dynamicGallery.openGallery(2);
1260 * });
1261 *
1262 */
1263 LightGallery.prototype.openGallery = function (index, element) {
1264 var _this = this;
1265 if (index === void 0) { index = this.settings.index; }
1266 // prevent accidental double execution
1267 if (this.lgOpened)
1268 return;
1269 this.lgOpened = true;
1270 this.outer.removeClass('lg-hide-items');
1271 this.hideScrollbar();
1272 // Add display block, but still has opacity 0
1273 this.$container.addClass('lg-show');
1274 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index);
1275 this.currentItemsInDom = itemsToBeInsertedToDom;
1276 var items = '';
1277 itemsToBeInsertedToDom.forEach(function (item) {
1278 items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>");
1279 });
1280 this.$inner.append(items);
1281 this.addHtml(index);
1282 var transform = '';
1283 this.mediaContainerPosition = this.getMediaContainerPosition();
1284 var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
1285 if (!this.settings.allowMediaOverlap) {
1286 this.setMediaContainerPosition(top, bottom);
1287 }
1288 var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo;
1289 if (this.zoomFromOrigin && element) {
1290 this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize);
1291 transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize);
1292 }
1293 if (!this.zoomFromOrigin || !transform) {
1294 this.outer.addClass(this.settings.startClass);
1295 this.getSlideItem(index).removeClass('lg-complete');
1296 }
1297 var timeout = this.settings.zoomFromOrigin
1298 ? 100
1299 : this.settings.backdropDuration;
1300 setTimeout(function () {
1301 _this.outer.addClass('lg-components-open');
1302 }, timeout);
1303 this.index = index;
1304 this.LGel.trigger(lGEvents.beforeOpen);
1305 // add class lg-current to remove initial transition
1306 this.getSlideItem(index).addClass('lg-current');
1307 this.lGalleryOn = false;
1308 // Store the current scroll top value to scroll back after closing the gallery..
1309 this.prevScrollTop = $LG(window).scrollTop();
1310 setTimeout(function () {
1311 // Need to check both zoomFromOrigin and transform values as we need to set set the
1312 // default opening animation if user missed to add the lg-size attribute
1313 if (_this.zoomFromOrigin && transform) {
1314 var currentSlide_1 = _this.getSlideItem(index);
1315 currentSlide_1.css('transform', transform);
1316 setTimeout(function () {
1317 currentSlide_1
1318 .addClass('lg-start-progress lg-start-end-progress')
1319 .css('transition-duration', _this.settings.startAnimationDuration + 'ms');
1320 _this.outer.addClass('lg-zoom-from-image');
1321 });
1322 setTimeout(function () {
1323 currentSlide_1.css('transform', 'translate3d(0, 0, 0)');
1324 }, 100);
1325 }
1326 setTimeout(function () {
1327 _this.$backdrop.addClass('in');
1328 _this.$container.addClass('lg-show-in');
1329 }, 10);
1330 setTimeout(function () {
1331 if (_this.settings.trapFocus &&
1332 document.body === _this.settings.container) {
1333 _this.trapFocus();
1334 }
1335 }, _this.settings.backdropDuration + 50);
1336 // lg-visible class resets gallery opacity to 1
1337 if (!_this.zoomFromOrigin || !transform) {
1338 setTimeout(function () {
1339 _this.outer.addClass('lg-visible');
1340 }, _this.settings.backdropDuration);
1341 }
1342 // initiate slide function
1343 _this.slide(index, false, false, false);
1344 _this.LGel.trigger(lGEvents.afterOpen);
1345 });
1346 if (document.body === this.settings.container) {
1347 $LG('html').addClass('lg-on');
1348 }
1349 };
1350 /**
1351 * Note - Changing the position of the media on every slide transition creates a flickering effect.
1352 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption.
1353 * if you have dynamic captions for each media,
1354 * you can provide an appropriate height for the captions via allowMediaOverlap option
1355 */
1356 LightGallery.prototype.getMediaContainerPosition = function () {
1357 if (this.settings.allowMediaOverlap) {
1358 return {
1359 top: 0,
1360 bottom: 0,
1361 };
1362 }
1363 var top = this.$toolbar.get().clientHeight || 0;
1364 var subHtml = this.outer.find('.lg-components .lg-sub-html').get();
1365 var captionHeight = this.settings.defaultCaptionHeight ||
1366 (subHtml && subHtml.clientHeight) ||
1367 0;
1368 var thumbContainer = this.outer.find('.lg-thumb-outer').get();
1369 var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0;
1370 var bottom = thumbHeight + captionHeight;
1371 return {
1372 top: top,
1373 bottom: bottom,
1374 };
1375 };
1376 LightGallery.prototype.setMediaContainerPosition = function (top, bottom) {
1377 if (top === void 0) { top = 0; }
1378 if (bottom === void 0) { bottom = 0; }
1379 this.$content.css('top', top + 'px').css('bottom', bottom + 'px');
1380 };
1381 LightGallery.prototype.hideBars = function () {
1382 var _this = this;
1383 // Hide controllers if mouse doesn't move for some period
1384 setTimeout(function () {
1385 _this.outer.removeClass('lg-hide-items');
1386 if (_this.settings.hideBarsDelay > 0) {
1387 _this.outer.on('mousemove.lg click.lg touchstart.lg', function () {
1388 _this.outer.removeClass('lg-hide-items');
1389 clearTimeout(_this.hideBarTimeout);
1390 // Timeout will be cleared on each slide movement also
1391 _this.hideBarTimeout = setTimeout(function () {
1392 _this.outer.addClass('lg-hide-items');
1393 }, _this.settings.hideBarsDelay);
1394 });
1395 _this.outer.trigger('mousemove.lg');
1396 }
1397 }, this.settings.showBarsAfter);
1398 };
1399 LightGallery.prototype.initPictureFill = function ($img) {
1400 if (this.settings.supportLegacyBrowser) {
1401 try {
1402 picturefill({
1403 elements: [$img.get()],
1404 });
1405 }
1406 catch (e) {
1407 console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.');
1408 }
1409 }
1410 };
1411 /**
1412 * @desc Create image counter
1413 * Ex: 1/10
1414 */
1415 LightGallery.prototype.counter = function () {
1416 if (this.settings.counter) {
1417 var counterHtml = "<div class=\"lg-counter\" role=\"status\" aria-live=\"polite\">\n <span id=\"" + this.getIdName('lg-counter-current') + "\" class=\"lg-counter-current\">" + (this.index + 1) + " </span> /\n <span id=\"" + this.getIdName('lg-counter-all') + "\" class=\"lg-counter-all\">" + this.galleryItems.length + " </span></div>";
1418 this.outer.find(this.settings.appendCounterTo).append(counterHtml);
1419 }
1420 };
1421 /**
1422 * @desc add sub-html into the slide
1423 * @param {Number} index - index of the slide
1424 */
1425 LightGallery.prototype.addHtml = function (index) {
1426 var subHtml;
1427 var subHtmlUrl;
1428 if (this.galleryItems[index].subHtmlUrl) {
1429 subHtmlUrl = this.galleryItems[index].subHtmlUrl;
1430 }
1431 else {
1432 subHtml = this.galleryItems[index].subHtml;
1433 }
1434 if (!subHtmlUrl) {
1435 if (subHtml) {
1436 // get first letter of sub-html
1437 // if first letter starts with . or # get the html form the jQuery object
1438 var fL = subHtml.substring(0, 1);
1439 if (fL === '.' || fL === '#') {
1440 if (this.settings.subHtmlSelectorRelative &&
1441 !this.settings.dynamic) {
1442 subHtml = $LG(this.items)
1443 .eq(index)
1444 .find(subHtml)
1445 .first()
1446 .html();
1447 }
1448 else {
1449 subHtml = $LG(subHtml).first().html();
1450 }
1451 }
1452 }
1453 else {
1454 subHtml = '';
1455 }
1456 }
1457 if (this.settings.appendSubHtmlTo !== '.lg-item') {
1458 if (subHtmlUrl) {
1459 this.outer.find('.lg-sub-html').load(subHtmlUrl);
1460 }
1461 else {
1462 this.outer.find('.lg-sub-html').html(subHtml);
1463 }
1464 }
1465 else {
1466 var currentSlide = $LG(this.getSlideItemId(index));
1467 if (subHtmlUrl) {
1468 currentSlide.load(subHtmlUrl);
1469 }
1470 else {
1471 currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>");
1472 }
1473 }
1474 // Add lg-empty-html class if title doesn't exist
1475 if (typeof subHtml !== 'undefined' && subHtml !== null) {
1476 if (subHtml === '') {
1477 this.outer
1478 .find(this.settings.appendSubHtmlTo)
1479 .addClass('lg-empty-html');
1480 }
1481 else {
1482 this.outer
1483 .find(this.settings.appendSubHtmlTo)
1484 .removeClass('lg-empty-html');
1485 }
1486 }
1487 this.LGel.trigger(lGEvents.afterAppendSubHtml, {
1488 index: index,
1489 });
1490 };
1491 /**
1492 * @desc Preload slides
1493 * @param {Number} index - index of the slide
1494 * @todo preload not working for the first slide, Also, should work for the first and last slide as well
1495 */
1496 LightGallery.prototype.preload = function (index) {
1497 for (var i = 1; i <= this.settings.preload; i++) {
1498 if (i >= this.galleryItems.length - index) {
1499 break;
1500 }
1501 this.loadContent(index + i, false);
1502 }
1503 for (var j = 1; j <= this.settings.preload; j++) {
1504 if (index - j < 0) {
1505 break;
1506 }
1507 this.loadContent(index - j, false);
1508 }
1509 };
1510 LightGallery.prototype.getDummyImgStyles = function (imageSize) {
1511 if (!imageSize)
1512 return '';
1513 return "width:" + imageSize.width + "px;\n margin-left: -" + imageSize.width / 2 + "px;\n margin-top: -" + imageSize.height / 2 + "px;\n height:" + imageSize.height + "px";
1514 };
1515 LightGallery.prototype.getVideoContStyle = function (imageSize) {
1516 if (!imageSize)
1517 return '';
1518 return "width:" + imageSize.width + "px;\n height:" + imageSize.height + "px";
1519 };
1520 LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) {
1521 var $currentItem;
1522 if (!this.settings.dynamic) {
1523 $currentItem = $LG(this.items).eq(index);
1524 }
1525 if ($currentItem) {
1526 var _dummyImgSrc = void 0;
1527 if (!this.settings.exThumbImage) {
1528 _dummyImgSrc = $currentItem.find('img').first().attr('src');
1529 }
1530 else {
1531 _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage);
1532 }
1533 if (!_dummyImgSrc)
1534 return '';
1535 var imgStyle = this.getDummyImgStyles(this.currentImageSize);
1536 var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />";
1537 $currentSlide.addClass('lg-first-slide');
1538 this.outer.addClass('lg-first-slide-loading');
1539 return dummyImgContent;
1540 }
1541 return '';
1542 };
1543 LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) {
1544 var currentGalleryItem = this.galleryItems[index];
1545 var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;
1546 // Use the thumbnail as dummy image which will be resized to actual image size and
1547 // displayed on top of actual image
1548 var imgContent = '';
1549 var altAttr = alt ? 'alt="' + alt + '"' : '';
1550 if (this.isFirstSlideWithZoomAnimation()) {
1551 imgContent = this.getDummyImageContent($currentSlide, index, altAttr);
1552 }
1553 else {
1554 imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources);
1555 }
1556 var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>";
1557 $currentSlide.prepend(imgMarkup);
1558 };
1559 LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) {
1560 var mediaObject = $slide.find('.lg-object').first();
1561 if (utils.isImageLoaded(mediaObject.get()) ||
1562 isHTML5VideoWithoutPoster) {
1563 onLoad();
1564 }
1565 else {
1566 mediaObject.on('load.lg error.lg', function () {
1567 onLoad && onLoad();
1568 });
1569 mediaObject.on('error.lg', function () {
1570 onError && onError();
1571 });
1572 }
1573 };
1574 /**
1575 *
1576 * @param $el Current slide item
1577 * @param index
1578 * @param delay Delay is 0 except first time
1579 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin
1580 * @param isFirstSlide
1581 */
1582 LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) {
1583 var _this = this;
1584 this.onSlideObjectLoad(currentSlide, isHTML5VideoWithoutPoster, function () {
1585 _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide);
1586 }, function () {
1587 currentSlide.addClass('lg-complete lg-complete_');
1588 currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>');
1589 });
1590 };
1591 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) {
1592 var _this = this;
1593 var currentGalleryItem = this.galleryItems[index];
1594 // Adding delay for video slides without poster for better performance and user experience
1595 // Videos should start playing once once the gallery is completely loaded
1596 var _speed = isFirstSlide &&
1597 this.getSlideType(currentGalleryItem) === 'video' &&
1598 !currentGalleryItem.poster
1599 ? speed
1600 : 0;
1601 setTimeout(function () {
1602 $currentSlide.addClass('lg-complete lg-complete_');
1603 _this.LGel.trigger(lGEvents.slideItemLoad, {
1604 index: index,
1605 delay: delay || 0,
1606 isFirstSlide: isFirstSlide,
1607 });
1608 }, _speed);
1609 };
1610 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () {
1611 return !!(!this.lGalleryOn &&
1612 this.zoomFromOrigin &&
1613 this.currentImageSize);
1614 };
1615 // Add video slideInfo
1616 LightGallery.prototype.addSlideVideoInfo = function (items) {
1617 var _this = this;
1618 items.forEach(function (element, index) {
1619 element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index);
1620 if (element.__slideVideoInfo &&
1621 _this.settings.loadYouTubePoster &&
1622 !element.poster &&
1623 element.__slideVideoInfo.youtube) {
1624 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg";
1625 }
1626 });
1627 };
1628 /**
1629 * Load slide content into slide.
1630 * This is used to load content into slides that is not visible too
1631 * @param {Number} index - index of the slide.
1632 * @param {Boolean} rec - if true call loadcontent() function again.
1633 */
1634 LightGallery.prototype.loadContent = function (index, rec) {
1635 var _this = this;
1636 var currentGalleryItem = this.galleryItems[index];
1637 var $currentSlide = $LG(this.getSlideItemId(index));
1638 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;
1639 var src = currentGalleryItem.src;
1640 var video = currentGalleryItem.video;
1641 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video;
1642 if (currentGalleryItem.responsive) {
1643 var srcDyItms = currentGalleryItem.responsive.split(',');
1644 src = utils.getResponsiveSrc(srcDyItms) || src;
1645 }
1646 var videoInfo = currentGalleryItem.__slideVideoInfo;
1647 var lgVideoStyle = '';
1648 var iframe = !!currentGalleryItem.iframe;
1649 var isFirstSlide = !this.lGalleryOn;
1650 // delay for adding complete class. it is 0 except first time.
1651 var delay = 0;
1652 if (isFirstSlide) {
1653 if (this.zoomFromOrigin && this.currentImageSize) {
1654 delay = this.settings.startAnimationDuration + 10;
1655 }
1656 else {
1657 delay = this.settings.backdropDuration + 10;
1658 }
1659 }
1660 if (!$currentSlide.hasClass('lg-loaded')) {
1661 if (videoInfo) {
1662 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom;
1663 var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize);
1664 lgVideoStyle = this.getVideoContStyle(videoSize);
1665 }
1666 if (iframe) {
1667 var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle);
1668 $currentSlide.prepend(markup);
1669 }
1670 else if (poster) {
1671 var dummyImg = '';
1672 var hasStartAnimation = isFirstSlide &&
1673 this.zoomFromOrigin &&
1674 this.currentImageSize;
1675 if (hasStartAnimation) {
1676 dummyImg = this.getDummyImageContent($currentSlide, index, '');
1677 }
1678 var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo);
1679 $currentSlide.prepend(markup);
1680 }
1681 else if (videoInfo) {
1682 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>";
1683 $currentSlide.prepend(markup);
1684 }
1685 else {
1686 this.setImgMarkup(src, $currentSlide, index);
1687 if (srcset || sources) {
1688 var $img = $currentSlide.find('.lg-object');
1689 this.initPictureFill($img);
1690 }
1691 }
1692 if (poster || videoInfo) {
1693 this.LGel.trigger(lGEvents.hasVideo, {
1694 index: index,
1695 src: src,
1696 html5Video: _html5Video,
1697 hasPoster: !!poster,
1698 });
1699 }
1700 this.LGel.trigger(lGEvents.afterAppendSlide, { index: index });
1701 if (this.lGalleryOn &&
1702 this.settings.appendSubHtmlTo === '.lg-item') {
1703 this.addHtml(index);
1704 }
1705 }
1706 // For first time add some delay for displaying the start animation.
1707 var _speed = 0;
1708 // Do not change the delay value because it is required for zoom plugin.
1709 // If gallery opened from direct url (hash) speed value should be 0
1710 if (delay && !$LG(document.body).hasClass('lg-from-hash')) {
1711 _speed = delay;
1712 }
1713 // Only for first slide and zoomFromOrigin is enabled
1714 if (this.isFirstSlideWithZoomAnimation()) {
1715 setTimeout(function () {
1716 $currentSlide
1717 .removeClass('lg-start-end-progress lg-start-progress')
1718 .removeAttr('style');
1719 }, this.settings.startAnimationDuration + 100);
1720 if (!$currentSlide.hasClass('lg-loaded')) {
1721 setTimeout(function () {
1722 if (_this.getSlideType(currentGalleryItem) === 'image') {
1723 var alt = currentGalleryItem.alt;
1724 var altAttr = alt ? 'alt="' + alt + '"' : '';
1725 $currentSlide
1726 .find('.lg-img-wrap')
1727 .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources));
1728 if (srcset || sources) {
1729 var $img = $currentSlide.find('.lg-object');
1730 _this.initPictureFill($img);
1731 }
1732 }
1733 if (_this.getSlideType(currentGalleryItem) === 'image' ||
1734 (_this.getSlideType(currentGalleryItem) === 'video' &&
1735 poster)) {
1736 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false);
1737 // load remaining slides once the slide is completely loaded
1738 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () {
1739 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
1740 }, function () {
1741 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
1742 });
1743 }
1744 }, this.settings.startAnimationDuration + 100);
1745 }
1746 }
1747 // SLide content has been added to dom
1748 $currentSlide.addClass('lg-loaded');
1749 if (!this.isFirstSlideWithZoomAnimation() ||
1750 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) {
1751 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster));
1752 }
1753 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling
1754 if ((!this.zoomFromOrigin || !this.currentImageSize) &&
1755 $currentSlide.hasClass('lg-complete_') &&
1756 !this.lGalleryOn) {
1757 setTimeout(function () {
1758 $currentSlide.addClass('lg-complete');
1759 }, this.settings.backdropDuration);
1760 }
1761 // Content loaded
1762 // Need to set lGalleryOn before calling preload function
1763 this.lGalleryOn = true;
1764 if (rec === true) {
1765 if (!$currentSlide.hasClass('lg-complete_')) {
1766 $currentSlide
1767 .find('.lg-object')
1768 .first()
1769 .on('load.lg error.lg', function () {
1770 _this.preload(index);
1771 });
1772 }
1773 else {
1774 this.preload(index);
1775 }
1776 }
1777 };
1778 /**
1779 * @desc Remove dummy image content and load next slides
1780 * Called only for the first time if zoomFromOrigin animation is enabled
1781 * @param index
1782 * @param $currentSlide
1783 * @param speed
1784 */
1785 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) {
1786 var _this = this;
1787 setTimeout(function () {
1788 $currentSlide.find('.lg-dummy-img').remove();
1789 $currentSlide.removeClass('lg-first-slide');
1790 _this.outer.removeClass('lg-first-slide-loading');
1791 _this.isDummyImageRemoved = true;
1792 _this.preload(index);
1793 }, speed + 300);
1794 };
1795 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) {
1796 var _this = this;
1797 if (numberOfItems === void 0) { numberOfItems = 0; }
1798 var itemsToBeInsertedToDom = [];
1799 // Minimum 2 items should be there
1800 var possibleNumberOfItems = Math.max(numberOfItems, 3);
1801 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length);
1802 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex;
1803 if (this.galleryItems.length <= 3) {
1804 this.galleryItems.forEach(function (_element, index) {
1805 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index);
1806 });
1807 return itemsToBeInsertedToDom;
1808 }
1809 if (index < (this.galleryItems.length - 1) / 2) {
1810 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) {
1811 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
1812 }
1813 var numberOfExistingItems = itemsToBeInsertedToDom.length;
1814 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
1815 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1));
1816 }
1817 }
1818 else {
1819 for (var idx = index; idx <= this.galleryItems.length - 1 &&
1820 idx < index + possibleNumberOfItems / 2; idx++) {
1821 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
1822 }
1823 var numberOfExistingItems = itemsToBeInsertedToDom.length;
1824 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
1825 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1));
1826 }
1827 }
1828 if (this.settings.loop) {
1829 if (index === this.galleryItems.length - 1) {
1830 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0);
1831 }
1832 else if (index === 0) {
1833 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1));
1834 }
1835 }
1836 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) {
1837 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex);
1838 }
1839 return itemsToBeInsertedToDom;
1840 };
1841 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) {
1842 var _this = this;
1843 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom);
1844 itemsToBeInsertedToDom.forEach(function (item) {
1845 if (_this.currentItemsInDom.indexOf(item) === -1) {
1846 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>");
1847 }
1848 });
1849 this.currentItemsInDom.forEach(function (item) {
1850 if (itemsToBeInsertedToDom.indexOf(item) === -1) {
1851 $LG("#" + item).remove();
1852 }
1853 });
1854 return itemsToBeInsertedToDom;
1855 };
1856 /**
1857 * Get previous index of the slide
1858 */
1859 LightGallery.prototype.getPreviousSlideIndex = function () {
1860 var prevIndex = 0;
1861 try {
1862 var currentItemId = this.outer
1863 .find('.lg-current')
1864 .first()
1865 .attr('id');
1866 prevIndex = parseInt(currentItemId.split('-')[3]) || 0;
1867 }
1868 catch (error) {
1869 prevIndex = 0;
1870 }
1871 return prevIndex;
1872 };
1873 LightGallery.prototype.setDownloadValue = function (index) {
1874 if (this.settings.download) {
1875 var currentGalleryItem = this.galleryItems[index];
1876 var hideDownloadBtn = currentGalleryItem.downloadUrl === false ||
1877 currentGalleryItem.downloadUrl === 'false';
1878 if (hideDownloadBtn) {
1879 this.outer.addClass('lg-hide-download');
1880 }
1881 else {
1882 var $download = this.getElementById('lg-download');
1883 this.outer.removeClass('lg-hide-download');
1884 $download.attr('href', currentGalleryItem.downloadUrl ||
1885 currentGalleryItem.src);
1886 if (currentGalleryItem.download) {
1887 $download.attr('download', currentGalleryItem.download);
1888 }
1889 }
1890 }
1891 };
1892 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) {
1893 var _this = this;
1894 if (this.lGalleryOn) {
1895 previousSlideItem.addClass('lg-slide-progress');
1896 }
1897 setTimeout(function () {
1898 // remove all transitions
1899 _this.outer.addClass('lg-no-trans');
1900 _this.outer
1901 .find('.lg-item')
1902 .removeClass('lg-prev-slide lg-next-slide');
1903 if (direction === 'prev') {
1904 //prevslide
1905 currentSlideItem.addClass('lg-prev-slide');
1906 previousSlideItem.addClass('lg-next-slide');
1907 }
1908 else {
1909 // next slide
1910 currentSlideItem.addClass('lg-next-slide');
1911 previousSlideItem.addClass('lg-prev-slide');
1912 }
1913 // give 50 ms for browser to add/remove class
1914 setTimeout(function () {
1915 _this.outer.find('.lg-item').removeClass('lg-current');
1916 currentSlideItem.addClass('lg-current');
1917 // reset all transitions
1918 _this.outer.removeClass('lg-no-trans');
1919 }, 50);
1920 }, this.lGalleryOn ? this.settings.slideDelay : 0);
1921 };
1922 /**
1923 * Goto a specific slide.
1924 * @param {Number} index - index of the slide
1925 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag
1926 * @param {Boolean} fromThumb - true if slide function called via thumbnail click
1927 * @param {String} direction - Direction of the slide(next/prev)
1928 * @category lGPublicMethods
1929 * @example
1930 * const plugin = lightGallery();
1931 * // to go to 3rd slide
1932 * plugin.slide(2);
1933 *
1934 */
1935 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) {
1936 var _this = this;
1937 var prevIndex = this.getPreviousSlideIndex();
1938 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex);
1939 // Prevent multiple call, Required for hsh plugin
1940 if (this.lGalleryOn && prevIndex === index) {
1941 return;
1942 }
1943 var numberOfGalleryItems = this.galleryItems.length;
1944 if (!this.lgBusy) {
1945 if (this.settings.counter) {
1946 this.updateCurrentCounter(index);
1947 }
1948 var currentSlideItem = this.getSlideItem(index);
1949 var previousSlideItem_1 = this.getSlideItem(prevIndex);
1950 var currentGalleryItem = this.galleryItems[index];
1951 var videoInfo = currentGalleryItem.__slideVideoInfo;
1952 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem));
1953 this.setDownloadValue(index);
1954 if (videoInfo) {
1955 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom;
1956 var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize);
1957 this.resizeVideoSlide(index, videoSize);
1958 }
1959 this.LGel.trigger(lGEvents.beforeSlide, {
1960 prevIndex: prevIndex,
1961 index: index,
1962 fromTouch: !!fromTouch,
1963 fromThumb: !!fromThumb,
1964 });
1965 this.lgBusy = true;
1966 clearTimeout(this.hideBarTimeout);
1967 this.arrowDisable(index);
1968 if (!direction) {
1969 if (index < prevIndex) {
1970 direction = 'prev';
1971 }
1972 else if (index > prevIndex) {
1973 direction = 'next';
1974 }
1975 }
1976 if (!fromTouch) {
1977 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1);
1978 }
1979 else {
1980 this.outer
1981 .find('.lg-item')
1982 .removeClass('lg-prev-slide lg-current lg-next-slide');
1983 var touchPrev = void 0;
1984 var touchNext = void 0;
1985 if (numberOfGalleryItems > 2) {
1986 touchPrev = index - 1;
1987 touchNext = index + 1;
1988 if (index === 0 && prevIndex === numberOfGalleryItems - 1) {
1989 // next slide
1990 touchNext = 0;
1991 touchPrev = numberOfGalleryItems - 1;
1992 }
1993 else if (index === numberOfGalleryItems - 1 &&
1994 prevIndex === 0) {
1995 // prev slide
1996 touchNext = 0;
1997 touchPrev = numberOfGalleryItems - 1;
1998 }
1999 }
2000 else {
2001 touchPrev = 0;
2002 touchNext = 1;
2003 }
2004 if (direction === 'prev') {
2005 this.getSlideItem(touchNext).addClass('lg-next-slide');
2006 }
2007 else {
2008 this.getSlideItem(touchPrev).addClass('lg-prev-slide');
2009 }
2010 currentSlideItem.addClass('lg-current');
2011 }
2012 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened
2013 if (!this.lGalleryOn) {
2014 this.loadContent(index, true);
2015 }
2016 else {
2017 setTimeout(function () {
2018 _this.loadContent(index, true);
2019 // Add title if this.settings.appendSubHtmlTo === lg-sub-html
2020 if (_this.settings.appendSubHtmlTo !== '.lg-item') {
2021 _this.addHtml(index);
2022 }
2023 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay));
2024 }
2025 setTimeout(function () {
2026 _this.lgBusy = false;
2027 previousSlideItem_1.removeClass('lg-slide-progress');
2028 _this.LGel.trigger(lGEvents.afterSlide, {
2029 prevIndex: prevIndex,
2030 index: index,
2031 fromTouch: fromTouch,
2032 fromThumb: fromThumb,
2033 });
2034 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay));
2035 }
2036 this.index = index;
2037 };
2038 LightGallery.prototype.updateCurrentCounter = function (index) {
2039 this.getElementById('lg-counter-current').html(index + 1 + '');
2040 };
2041 LightGallery.prototype.updateCounterTotal = function () {
2042 this.getElementById('lg-counter-all').html(this.galleryItems.length + '');
2043 };
2044 LightGallery.prototype.getSlideType = function (item) {
2045 if (item.__slideVideoInfo) {
2046 return 'video';
2047 }
2048 else if (item.iframe) {
2049 return 'iframe';
2050 }
2051 else {
2052 return 'image';
2053 }
2054 };
2055 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) {
2056 var distanceX = endCoords.pageX - startCoords.pageX;
2057 var distanceY = endCoords.pageY - startCoords.pageY;
2058 var allowSwipe = false;
2059 if (this.swipeDirection) {
2060 allowSwipe = true;
2061 }
2062 else {
2063 if (Math.abs(distanceX) > 15) {
2064 this.swipeDirection = 'horizontal';
2065 allowSwipe = true;
2066 }
2067 else if (Math.abs(distanceY) > 15) {
2068 this.swipeDirection = 'vertical';
2069 allowSwipe = true;
2070 }
2071 }
2072 if (!allowSwipe) {
2073 return;
2074 }
2075 var $currentSlide = this.getSlideItem(this.index);
2076 if (this.swipeDirection === 'horizontal') {
2077 e === null || e === void 0 ? void 0 : e.preventDefault();
2078 // reset opacity and transition duration
2079 this.outer.addClass('lg-dragging');
2080 // move current slide
2081 this.setTranslate($currentSlide, distanceX, 0);
2082 // move next and prev slide with current slide
2083 var width = $currentSlide.get().offsetWidth;
2084 var slideWidthAmount = (width * 15) / 100;
2085 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100);
2086 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0);
2087 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0);
2088 }
2089 else if (this.swipeDirection === 'vertical') {
2090 if (this.settings.swipeToClose) {
2091 e === null || e === void 0 ? void 0 : e.preventDefault();
2092 this.$container.addClass('lg-dragging-vertical');
2093 var opacity = 1 - Math.abs(distanceY) / window.innerHeight;
2094 this.$backdrop.css('opacity', opacity);
2095 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2);
2096 this.setTranslate($currentSlide, 0, distanceY, scale, scale);
2097 if (Math.abs(distanceY) > 100) {
2098 this.outer
2099 .addClass('lg-hide-items')
2100 .removeClass('lg-components-open');
2101 }
2102 }
2103 }
2104 };
2105 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) {
2106 var _this = this;
2107 var distance;
2108 // keep slide animation for any mode while dragg/swipe
2109 if (this.settings.mode !== 'lg-slide') {
2110 this.outer.addClass('lg-slide');
2111 }
2112 // set transition duration
2113 setTimeout(function () {
2114 _this.$container.removeClass('lg-dragging-vertical');
2115 _this.outer
2116 .removeClass('lg-dragging lg-hide-items')
2117 .addClass('lg-components-open');
2118 var triggerClick = true;
2119 if (_this.swipeDirection === 'horizontal') {
2120 distance = endCoords.pageX - startCoords.pageX;
2121 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX);
2122 if (distance < 0 &&
2123 distanceAbs > _this.settings.swipeThreshold) {
2124 _this.goToNextSlide(true);
2125 triggerClick = false;
2126 }
2127 else if (distance > 0 &&
2128 distanceAbs > _this.settings.swipeThreshold) {
2129 _this.goToPrevSlide(true);
2130 triggerClick = false;
2131 }
2132 }
2133 else if (_this.swipeDirection === 'vertical') {
2134 distance = Math.abs(endCoords.pageY - startCoords.pageY);
2135 if (_this.settings.closable &&
2136 _this.settings.swipeToClose &&
2137 distance > 100) {
2138 _this.closeGallery();
2139 return;
2140 }
2141 else {
2142 _this.$backdrop.css('opacity', 1);
2143 }
2144 }
2145 _this.outer.find('.lg-item').removeAttr('style');
2146 if (triggerClick &&
2147 Math.abs(endCoords.pageX - startCoords.pageX) < 5) {
2148 // Trigger click if distance is less than 5 pix
2149 var target = $LG(event.target);
2150 if (_this.isPosterElement(target)) {
2151 _this.LGel.trigger(lGEvents.posterClick);
2152 }
2153 }
2154 _this.swipeDirection = undefined;
2155 });
2156 // remove slide class once drag/swipe is completed if mode is not slide
2157 setTimeout(function () {
2158 if (!_this.outer.hasClass('lg-dragging') &&
2159 _this.settings.mode !== 'lg-slide') {
2160 _this.outer.removeClass('lg-slide');
2161 }
2162 }, this.settings.speed + 100);
2163 };
2164 LightGallery.prototype.enableSwipe = function () {
2165 var _this = this;
2166 var startCoords = {};
2167 var endCoords = {};
2168 var isMoved = false;
2169 var isSwiping = false;
2170 if (this.settings.enableSwipe) {
2171 this.$inner.on('touchstart.lg', function (e) {
2172 _this.dragOrSwipeEnabled = true;
2173 var $item = _this.getSlideItem(_this.index);
2174 if (($LG(e.target).hasClass('lg-item') ||
2175 $item.get().contains(e.target)) &&
2176 !_this.outer.hasClass('lg-zoomed') &&
2177 !_this.lgBusy &&
2178 e.touches.length === 1) {
2179 isSwiping = true;
2180 _this.touchAction = 'swipe';
2181 _this.manageSwipeClass();
2182 startCoords = {
2183 pageX: e.touches[0].pageX,
2184 pageY: e.touches[0].pageY,
2185 };
2186 }
2187 });
2188 this.$inner.on('touchmove.lg', function (e) {
2189 if (isSwiping &&
2190 _this.touchAction === 'swipe' &&
2191 e.touches.length === 1) {
2192 endCoords = {
2193 pageX: e.touches[0].pageX,
2194 pageY: e.touches[0].pageY,
2195 };
2196 _this.touchMove(startCoords, endCoords, e);
2197 isMoved = true;
2198 }
2199 });
2200 this.$inner.on('touchend.lg', function (event) {
2201 if (_this.touchAction === 'swipe') {
2202 if (isMoved) {
2203 isMoved = false;
2204 _this.touchEnd(endCoords, startCoords, event);
2205 }
2206 else if (isSwiping) {
2207 var target = $LG(event.target);
2208 if (_this.isPosterElement(target)) {
2209 _this.LGel.trigger(lGEvents.posterClick);
2210 }
2211 }
2212 _this.touchAction = undefined;
2213 isSwiping = false;
2214 }
2215 });
2216 }
2217 };
2218 LightGallery.prototype.enableDrag = function () {
2219 var _this = this;
2220 var startCoords = {};
2221 var endCoords = {};
2222 var isDraging = false;
2223 var isMoved = false;
2224 if (this.settings.enableDrag) {
2225 this.outer.on('mousedown.lg', function (e) {
2226 _this.dragOrSwipeEnabled = true;
2227 var $item = _this.getSlideItem(_this.index);
2228 if ($LG(e.target).hasClass('lg-item') ||
2229 $item.get().contains(e.target)) {
2230 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) {
2231 e.preventDefault();
2232 if (!_this.lgBusy) {
2233 _this.manageSwipeClass();
2234 startCoords = {
2235 pageX: e.pageX,
2236 pageY: e.pageY,
2237 };
2238 isDraging = true;
2239 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
2240 _this.outer.get().scrollLeft += 1;
2241 _this.outer.get().scrollLeft -= 1;
2242 // *
2243 _this.outer
2244 .removeClass('lg-grab')
2245 .addClass('lg-grabbing');
2246 _this.LGel.trigger(lGEvents.dragStart);
2247 }
2248 }
2249 }
2250 });
2251 $LG(window).on("mousemove.lg.global" + this.lgId, function (e) {
2252 if (isDraging && _this.lgOpened) {
2253 isMoved = true;
2254 endCoords = {
2255 pageX: e.pageX,
2256 pageY: e.pageY,
2257 };
2258 _this.touchMove(startCoords, endCoords);
2259 _this.LGel.trigger(lGEvents.dragMove);
2260 }
2261 });
2262 $LG(window).on("mouseup.lg.global" + this.lgId, function (event) {
2263 if (!_this.lgOpened) {
2264 return;
2265 }
2266 var target = $LG(event.target);
2267 if (isMoved) {
2268 isMoved = false;
2269 _this.touchEnd(endCoords, startCoords, event);
2270 _this.LGel.trigger(lGEvents.dragEnd);
2271 }
2272 else if (_this.isPosterElement(target)) {
2273 _this.LGel.trigger(lGEvents.posterClick);
2274 }
2275 // Prevent execution on click
2276 if (isDraging) {
2277 isDraging = false;
2278 _this.outer.removeClass('lg-grabbing').addClass('lg-grab');
2279 }
2280 });
2281 }
2282 };
2283 LightGallery.prototype.triggerPosterClick = function () {
2284 var _this = this;
2285 this.$inner.on('click.lg', function (event) {
2286 if (!_this.dragOrSwipeEnabled &&
2287 _this.isPosterElement($LG(event.target))) {
2288 _this.LGel.trigger(lGEvents.posterClick);
2289 }
2290 });
2291 };
2292 LightGallery.prototype.manageSwipeClass = function () {
2293 var _touchNext = this.index + 1;
2294 var _touchPrev = this.index - 1;
2295 if (this.settings.loop && this.galleryItems.length > 2) {
2296 if (this.index === 0) {
2297 _touchPrev = this.galleryItems.length - 1;
2298 }
2299 else if (this.index === this.galleryItems.length - 1) {
2300 _touchNext = 0;
2301 }
2302 }
2303 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide');
2304 if (_touchPrev > -1) {
2305 this.getSlideItem(_touchPrev).addClass('lg-prev-slide');
2306 }
2307 this.getSlideItem(_touchNext).addClass('lg-next-slide');
2308 };
2309 /**
2310 * Go to next slide
2311 * @param {Boolean} fromTouch - true if slide function called via touch event
2312 * @category lGPublicMethods
2313 * @example
2314 * const plugin = lightGallery();
2315 * plugin.goToNextSlide();
2316 * @see <a href="/demos/methods/">Demo</a>
2317 */
2318 LightGallery.prototype.goToNextSlide = function (fromTouch) {
2319 var _this = this;
2320 var _loop = this.settings.loop;
2321 if (fromTouch && this.galleryItems.length < 3) {
2322 _loop = false;
2323 }
2324 if (!this.lgBusy) {
2325 if (this.index + 1 < this.galleryItems.length) {
2326 this.index++;
2327 this.LGel.trigger(lGEvents.beforeNextSlide, {
2328 index: this.index,
2329 });
2330 this.slide(this.index, !!fromTouch, false, 'next');
2331 }
2332 else {
2333 if (_loop) {
2334 this.index = 0;
2335 this.LGel.trigger(lGEvents.beforeNextSlide, {
2336 index: this.index,
2337 });
2338 this.slide(this.index, !!fromTouch, false, 'next');
2339 }
2340 else if (this.settings.slideEndAnimation && !fromTouch) {
2341 this.outer.addClass('lg-right-end');
2342 setTimeout(function () {
2343 _this.outer.removeClass('lg-right-end');
2344 }, 400);
2345 }
2346 }
2347 }
2348 };
2349 /**
2350 * Go to previous slides
2351 * @param {Boolean} fromTouch - true if slide function called via touch event
2352 * @category lGPublicMethods
2353 * @example
2354 * const plugin = lightGallery({});
2355 * plugin.goToPrevSlide();
2356 * @see <a href="/demos/methods/">Demo</a>
2357 *
2358 */
2359 LightGallery.prototype.goToPrevSlide = function (fromTouch) {
2360 var _this = this;
2361 var _loop = this.settings.loop;
2362 if (fromTouch && this.galleryItems.length < 3) {
2363 _loop = false;
2364 }
2365 if (!this.lgBusy) {
2366 if (this.index > 0) {
2367 this.index--;
2368 this.LGel.trigger(lGEvents.beforePrevSlide, {
2369 index: this.index,
2370 fromTouch: fromTouch,
2371 });
2372 this.slide(this.index, !!fromTouch, false, 'prev');
2373 }
2374 else {
2375 if (_loop) {
2376 this.index = this.galleryItems.length - 1;
2377 this.LGel.trigger(lGEvents.beforePrevSlide, {
2378 index: this.index,
2379 fromTouch: fromTouch,
2380 });
2381 this.slide(this.index, !!fromTouch, false, 'prev');
2382 }
2383 else if (this.settings.slideEndAnimation && !fromTouch) {
2384 this.outer.addClass('lg-left-end');
2385 setTimeout(function () {
2386 _this.outer.removeClass('lg-left-end');
2387 }, 400);
2388 }
2389 }
2390 }
2391 };
2392 LightGallery.prototype.keyPress = function () {
2393 var _this = this;
2394 $LG(window).on("keydown.lg.global" + this.lgId, function (e) {
2395 if (_this.lgOpened &&
2396 _this.settings.escKey === true &&
2397 e.keyCode === 27) {
2398 e.preventDefault();
2399 if (_this.settings.allowMediaOverlap &&
2400 _this.outer.hasClass('lg-can-toggle') &&
2401 _this.outer.hasClass('lg-components-open')) {
2402 _this.outer.removeClass('lg-components-open');
2403 }
2404 else {
2405 _this.closeGallery();
2406 }
2407 }
2408 if (_this.lgOpened && _this.galleryItems.length > 1) {
2409 if (e.keyCode === 37) {
2410 e.preventDefault();
2411 _this.goToPrevSlide();
2412 }
2413 if (e.keyCode === 39) {
2414 e.preventDefault();
2415 _this.goToNextSlide();
2416 }
2417 }
2418 });
2419 };
2420 LightGallery.prototype.arrow = function () {
2421 var _this = this;
2422 this.getElementById('lg-prev').on('click.lg', function () {
2423 _this.goToPrevSlide();
2424 });
2425 this.getElementById('lg-next').on('click.lg', function () {
2426 _this.goToNextSlide();
2427 });
2428 };
2429 LightGallery.prototype.arrowDisable = function (index) {
2430 // Disable arrows if settings.hideControlOnEnd is true
2431 if (!this.settings.loop && this.settings.hideControlOnEnd) {
2432 var $prev = this.getElementById('lg-prev');
2433 var $next = this.getElementById('lg-next');
2434 if (index + 1 === this.galleryItems.length) {
2435 $next.attr('disabled', 'disabled').addClass('disabled');
2436 }
2437 else {
2438 $next.removeAttr('disabled').removeClass('disabled');
2439 }
2440 if (index === 0) {
2441 $prev.attr('disabled', 'disabled').addClass('disabled');
2442 }
2443 else {
2444 $prev.removeAttr('disabled').removeClass('disabled');
2445 }
2446 }
2447 };
2448 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) {
2449 if (scaleX === void 0) { scaleX = 1; }
2450 if (scaleY === void 0) { scaleY = 1; }
2451 $el.css('transform', 'translate3d(' +
2452 xValue +
2453 'px, ' +
2454 yValue +
2455 'px, 0px) scale3d(' +
2456 scaleX +
2457 ', ' +
2458 scaleY +
2459 ', 1)');
2460 };
2461 LightGallery.prototype.mousewheel = function () {
2462 var _this = this;
2463 var lastCall = 0;
2464 this.outer.on('wheel.lg', function (e) {
2465 if (!e.deltaY || _this.galleryItems.length < 2) {
2466 return;
2467 }
2468 e.preventDefault();
2469 var now = new Date().getTime();
2470 if (now - lastCall < 1000) {
2471 return;
2472 }
2473 lastCall = now;
2474 if (e.deltaY > 0) {
2475 _this.goToNextSlide();
2476 }
2477 else if (e.deltaY < 0) {
2478 _this.goToPrevSlide();
2479 }
2480 });
2481 };
2482 LightGallery.prototype.isSlideElement = function (target) {
2483 return (target.hasClass('lg-outer') ||
2484 target.hasClass('lg-item') ||
2485 target.hasClass('lg-img-wrap'));
2486 };
2487 LightGallery.prototype.isPosterElement = function (target) {
2488 var playButton = this.getSlideItem(this.index)
2489 .find('.lg-video-play-button')
2490 .get();
2491 return (target.hasClass('lg-video-poster') ||
2492 target.hasClass('lg-video-play-button') ||
2493 (playButton && playButton.contains(target.get())));
2494 };
2495 /**
2496 * Maximize minimize inline gallery.
2497 * @category lGPublicMethods
2498 */
2499 LightGallery.prototype.toggleMaximize = function () {
2500 var _this = this;
2501 this.getElementById('lg-maximize').on('click.lg', function () {
2502 _this.$container.toggleClass('lg-inline');
2503 _this.refreshOnResize();
2504 });
2505 };
2506 LightGallery.prototype.invalidateItems = function () {
2507 for (var index = 0; index < this.items.length; index++) {
2508 var element = this.items[index];
2509 var $element = $LG(element);
2510 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id'));
2511 }
2512 };
2513 LightGallery.prototype.trapFocus = function () {
2514 var _this = this;
2515 this.$container.get().focus({
2516 preventScroll: true,
2517 });
2518 $LG(window).on("keydown.lg.global" + this.lgId, function (e) {
2519 if (!_this.lgOpened) {
2520 return;
2521 }
2522 var isTabPressed = e.key === 'Tab' || e.keyCode === 9;
2523 if (!isTabPressed) {
2524 return;
2525 }
2526 var focusableEls = utils.getFocusableElements(_this.$container.get());
2527 var firstFocusableEl = focusableEls[0];
2528 var lastFocusableEl = focusableEls[focusableEls.length - 1];
2529 if (e.shiftKey) {
2530 if (document.activeElement === firstFocusableEl) {
2531 lastFocusableEl.focus();
2532 e.preventDefault();
2533 }
2534 }
2535 else {
2536 if (document.activeElement === lastFocusableEl) {
2537 firstFocusableEl.focus();
2538 e.preventDefault();
2539 }
2540 }
2541 });
2542 };
2543 LightGallery.prototype.manageCloseGallery = function () {
2544 var _this = this;
2545 if (!this.settings.closable)
2546 return;
2547 var mousedown = false;
2548 this.getElementById('lg-close').on('click.lg', function () {
2549 _this.closeGallery();
2550 });
2551 if (this.settings.closeOnTap) {
2552 // If you drag the slide and release outside gallery gets close on chrome
2553 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer
2554 this.outer.on('mousedown.lg', function (e) {
2555 var target = $LG(e.target);
2556 if (_this.isSlideElement(target)) {
2557 mousedown = true;
2558 }
2559 else {
2560 mousedown = false;
2561 }
2562 });
2563 this.outer.on('mousemove.lg', function () {
2564 mousedown = false;
2565 });
2566 this.outer.on('mouseup.lg', function (e) {
2567 var target = $LG(e.target);
2568 if (_this.isSlideElement(target) && mousedown) {
2569 if (!_this.outer.hasClass('lg-dragging')) {
2570 _this.closeGallery();
2571 }
2572 }
2573 });
2574 }
2575 };
2576 /**
2577 * Close lightGallery if it is opened.
2578 *
2579 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery
2580 * @return returns the estimated time to close gallery completely including the close animation duration
2581 * @category lGPublicMethods
2582 * @example
2583 * const plugin = lightGallery();
2584 * plugin.closeGallery();
2585 *
2586 */
2587 LightGallery.prototype.closeGallery = function (force) {
2588 var _this = this;
2589 if (!this.lgOpened || (!this.settings.closable && !force)) {
2590 return 0;
2591 }
2592 this.LGel.trigger(lGEvents.beforeClose);
2593 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) {
2594 $LG(window).scrollTop(this.prevScrollTop);
2595 }
2596 var currentItem = this.items[this.index];
2597 var transform;
2598 if (this.zoomFromOrigin && currentItem) {
2599 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom;
2600 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster;
2601 var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize);
2602 transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize);
2603 }
2604 if (this.zoomFromOrigin && transform) {
2605 this.outer.addClass('lg-closing lg-zoom-from-image');
2606 this.getSlideItem(this.index)
2607 .addClass('lg-start-end-progress')
2608 .css('transition-duration', this.settings.startAnimationDuration + 'ms')
2609 .css('transform', transform);
2610 }
2611 else {
2612 this.outer.addClass('lg-hide-items');
2613 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true
2614 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts
2615 this.outer.removeClass('lg-zoom-from-image');
2616 }
2617 // Unbind all events added by lightGallery
2618 // @todo
2619 //this.$el.off('.lg.tm');
2620 this.destroyModules();
2621 this.lGalleryOn = false;
2622 this.isDummyImageRemoved = false;
2623 this.zoomFromOrigin = this.settings.zoomFromOrigin;
2624 clearTimeout(this.hideBarTimeout);
2625 this.hideBarTimeout = false;
2626 $LG('html').removeClass('lg-on');
2627 this.outer.removeClass('lg-visible lg-components-open');
2628 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity.
2629 this.$backdrop.removeClass('in').css('opacity', 0);
2630 var removeTimeout = this.zoomFromOrigin && transform
2631 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration)
2632 : this.settings.backdropDuration;
2633 this.$container.removeClass('lg-show-in');
2634 // Once the closign animation is completed and gallery is invisible
2635 setTimeout(function () {
2636 if (_this.zoomFromOrigin && transform) {
2637 _this.outer.removeClass('lg-zoom-from-image');
2638 }
2639 _this.$container.removeClass('lg-show');
2640 // Reset scrollbar
2641 _this.resetScrollBar();
2642 // Need to remove inline opacity as it is used in the stylesheet as well
2643 _this.$backdrop
2644 .removeAttr('style')
2645 .css('transition-duration', _this.settings.backdropDuration + 'ms');
2646 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
2647 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress');
2648 _this.$inner.empty();
2649 if (_this.lgOpened) {
2650 _this.LGel.trigger(lGEvents.afterClose, {
2651 instance: _this,
2652 });
2653 }
2654 if (_this.$container.get()) {
2655 _this.$container.get().blur();
2656 }
2657 _this.lgOpened = false;
2658 }, removeTimeout + 100);
2659 return removeTimeout + 100;
2660 };
2661 LightGallery.prototype.initModules = function () {
2662 this.plugins.forEach(function (module) {
2663 try {
2664 module.init();
2665 }
2666 catch (err) {
2667 console.warn("lightGallery:- make sure lightGallery module is properly initiated");
2668 }
2669 });
2670 };
2671 LightGallery.prototype.destroyModules = function (destroy) {
2672 this.plugins.forEach(function (module) {
2673 try {
2674 if (destroy) {
2675 module.destroy();
2676 }
2677 else {
2678 module.closeGallery && module.closeGallery();
2679 }
2680 }
2681 catch (err) {
2682 console.warn("lightGallery:- make sure lightGallery module is properly destroyed");
2683 }
2684 });
2685 };
2686 /**
2687 * Refresh lightGallery with new set of children.
2688 *
2689 * @description This is useful to update the gallery when the child elements are changed without calling destroy method.
2690 *
2691 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery
2692 * @see <a href="/demos/dynamic-mode/">Demo</a>
2693 * @category lGPublicMethods
2694 * @example
2695 * const plugin = lightGallery();
2696 * // Delete or add children, then call
2697 * plugin.refresh();
2698 *
2699 */
2700 LightGallery.prototype.refresh = function (galleryItems) {
2701 if (!this.settings.dynamic) {
2702 this.invalidateItems();
2703 }
2704 if (galleryItems) {
2705 this.galleryItems = galleryItems;
2706 }
2707 else {
2708 this.galleryItems = this.getItems();
2709 }
2710 this.updateControls();
2711 this.openGalleryOnItemClick();
2712 this.LGel.trigger(lGEvents.updateSlides);
2713 };
2714 LightGallery.prototype.updateControls = function () {
2715 this.addSlideVideoInfo(this.galleryItems);
2716 this.updateCounterTotal();
2717 this.manageSingleSlideClassName();
2718 };
2719 LightGallery.prototype.destroyGallery = function () {
2720 this.destroyModules(true);
2721 if (!this.settings.dynamic) {
2722 this.invalidateItems();
2723 }
2724 $LG(window).off(".lg.global" + this.lgId);
2725 this.LGel.off('.lg');
2726 this.$container.remove();
2727 };
2728 /**
2729 * Destroy lightGallery.
2730 * Destroy lightGallery and its plugin instances completely
2731 *
2732 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance.
2733 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed.
2734 * You can use refresh method most of the times.
2735 * @category lGPublicMethods
2736 * @example
2737 * const plugin = lightGallery();
2738 * plugin.destroy();
2739 *
2740 */
2741 LightGallery.prototype.destroy = function () {
2742 var closeTimeout = this.closeGallery(true);
2743 if (closeTimeout) {
2744 setTimeout(this.destroyGallery.bind(this), closeTimeout);
2745 }
2746 else {
2747 this.destroyGallery();
2748 }
2749 return closeTimeout;
2750 };
2751 return LightGallery;
2752}());
2753
2754function lightGallery(el, options) {
2755 return new LightGallery(el, options);
2756}
2757
2758var LgMethods = {
2759 onAfterAppendSlide: 'lgAfterAppendSlide',
2760 onInit: 'lgInit',
2761 onHasVideo: 'lgHasVideo',
2762 onContainerResize: 'lgContainerResize',
2763 onUpdateSlides: 'lgUpdateSlides',
2764 onAfterAppendSubHtml: 'lgAfterAppendSubHtml',
2765 onBeforeOpen: 'lgBeforeOpen',
2766 onAfterOpen: 'lgAfterOpen',
2767 onSlideItemLoad: 'lgSlideItemLoad',
2768 onBeforeSlide: 'lgBeforeSlide',
2769 onAfterSlide: 'lgAfterSlide',
2770 onPosterClick: 'lgPosterClick',
2771 onDragStart: 'lgDragStart',
2772 onDragMove: 'lgDragMove',
2773 onDragEnd: 'lgDragEnd',
2774 onBeforeNextSlide: 'lgBeforeNextSlide',
2775 onBeforePrevSlide: 'lgBeforePrevSlide',
2776 onBeforeClose: 'lgBeforeClose',
2777 onAfterClose: 'lgAfterClose',
2778 onRotateLeft: 'lgRotateLeft',
2779 onRotateRight: 'lgRotateRight',
2780 onFlipHorizontal: 'lgFlipHorizontal',
2781 onFlipVertical: 'lgFlipVertical',
2782};
2783var LG = function (_a) {
2784 var children = _a.children, elementClassNames = _a.elementClassNames, onAfterAppendSlide = _a.onAfterAppendSlide, onInit = _a.onInit, onHasVideo = _a.onHasVideo, onContainerResize = _a.onContainerResize, onAfterAppendSubHtml = _a.onAfterAppendSubHtml, onBeforeOpen = _a.onBeforeOpen, onAfterOpen = _a.onAfterOpen, onSlideItemLoad = _a.onSlideItemLoad, onBeforeSlide = _a.onBeforeSlide, onAfterSlide = _a.onAfterSlide, onPosterClick = _a.onPosterClick, onDragStart = _a.onDragStart, onDragMove = _a.onDragMove, onDragEnd = _a.onDragEnd, onBeforeNextSlide = _a.onBeforeNextSlide, onBeforePrevSlide = _a.onBeforePrevSlide, onBeforeClose = _a.onBeforeClose, onAfterClose = _a.onAfterClose, onRotateLeft = _a.onRotateLeft, onRotateRight = _a.onRotateRight, onFlipHorizontal = _a.onFlipHorizontal, onFlipVertical = _a.onFlipVertical, restProps = __rest(_a, ["children", "elementClassNames", "onAfterAppendSlide", "onInit", "onHasVideo", "onContainerResize", "onAfterAppendSubHtml", "onBeforeOpen", "onAfterOpen", "onSlideItemLoad", "onBeforeSlide", "onAfterSlide", "onPosterClick", "onDragStart", "onDragMove", "onDragEnd", "onBeforeNextSlide", "onBeforePrevSlide", "onBeforeClose", "onAfterClose", "onRotateLeft", "onRotateRight", "onFlipHorizontal", "onFlipVertical"]);
2785 var $lg = useRef(null);
2786 var registerEvents = useCallback(function () {
2787 if (onAfterAppendSlide && $lg && $lg.current) {
2788 $lg.current.addEventListener(LgMethods.onAfterAppendSlide, (function (event) {
2789 onAfterAppendSlide(event.detail);
2790 }));
2791 }
2792 if (onInit && $lg && $lg.current) {
2793 $lg.current.addEventListener(LgMethods.onInit, (function (event) {
2794 onInit(event.detail);
2795 }));
2796 }
2797 if (onHasVideo && $lg && $lg.current) {
2798 $lg.current.addEventListener(LgMethods.onHasVideo, (function (event) {
2799 onHasVideo(event.detail);
2800 }));
2801 }
2802 if (onContainerResize && $lg && $lg.current) {
2803 $lg.current.addEventListener(LgMethods.onContainerResize, (function (event) {
2804 onContainerResize(event.detail);
2805 }));
2806 }
2807 if (onAfterAppendSubHtml && $lg && $lg.current) {
2808 $lg.current.addEventListener(LgMethods.onAfterAppendSubHtml, (function (event) {
2809 onAfterAppendSubHtml(event.detail);
2810 }));
2811 }
2812 if (onBeforeOpen && $lg && $lg.current) {
2813 $lg.current.addEventListener(LgMethods.onBeforeOpen, (function (event) {
2814 onBeforeOpen(event.detail);
2815 }));
2816 }
2817 if (onAfterOpen && $lg && $lg.current) {
2818 $lg.current.addEventListener(LgMethods.onAfterOpen, (function (event) {
2819 onAfterOpen(event.detail);
2820 }));
2821 }
2822 if (onSlideItemLoad && $lg && $lg.current) {
2823 $lg.current.addEventListener(LgMethods.onSlideItemLoad, (function (event) {
2824 onSlideItemLoad(event.detail);
2825 }));
2826 }
2827 if (onBeforeSlide && $lg && $lg.current) {
2828 $lg.current.addEventListener(LgMethods.onBeforeSlide, (function (event) {
2829 onBeforeSlide(event.detail);
2830 }));
2831 }
2832 if (onAfterSlide && $lg && $lg.current) {
2833 $lg.current.addEventListener(LgMethods.onAfterSlide, (function (event) {
2834 onAfterSlide(event.detail);
2835 }));
2836 }
2837 if (onPosterClick && $lg && $lg.current) {
2838 $lg.current.addEventListener(LgMethods.onPosterClick, (function (event) {
2839 onPosterClick(event.detail);
2840 }));
2841 }
2842 if (onDragStart && $lg && $lg.current) {
2843 $lg.current.addEventListener(LgMethods.onDragStart, (function (event) {
2844 onDragStart(event.detail);
2845 }));
2846 }
2847 if (onDragMove && $lg && $lg.current) {
2848 $lg.current.addEventListener(LgMethods.onDragMove, (function (event) {
2849 onDragMove(event.detail);
2850 }));
2851 }
2852 if (onDragEnd && $lg && $lg.current) {
2853 $lg.current.addEventListener(LgMethods.onDragEnd, (function (event) {
2854 onDragEnd(event.detail);
2855 }));
2856 }
2857 if (onBeforeNextSlide && $lg && $lg.current) {
2858 $lg.current.addEventListener(LgMethods.onBeforeNextSlide, (function (event) {
2859 onBeforeNextSlide(event.detail);
2860 }));
2861 }
2862 if (onBeforePrevSlide && $lg && $lg.current) {
2863 $lg.current.addEventListener(LgMethods.onBeforePrevSlide, (function (event) {
2864 onBeforePrevSlide(event.detail);
2865 }));
2866 }
2867 if (onBeforeClose && $lg && $lg.current) {
2868 $lg.current.addEventListener(LgMethods.onBeforeClose, (function (event) {
2869 onBeforeClose(event.detail);
2870 }));
2871 }
2872 if (onAfterClose && $lg && $lg.current) {
2873 $lg.current.addEventListener(LgMethods.onAfterClose, (function (event) {
2874 onAfterClose(event.detail);
2875 }));
2876 }
2877 if (onRotateLeft && $lg && $lg.current) {
2878 $lg.current.addEventListener(LgMethods.onRotateLeft, (function (event) {
2879 onRotateLeft(event.detail);
2880 }));
2881 }
2882 if (onRotateRight && $lg && $lg.current) {
2883 $lg.current.addEventListener(LgMethods.onRotateRight, (function (event) {
2884 onRotateRight(event.detail);
2885 }));
2886 }
2887 if (onFlipHorizontal && $lg && $lg.current) {
2888 $lg.current.addEventListener(LgMethods.onFlipHorizontal, (function (event) {
2889 onFlipHorizontal(event.detail);
2890 }));
2891 }
2892 if (onFlipVertical && $lg && $lg.current) {
2893 $lg.current.addEventListener(LgMethods.onFlipVertical, (function (event) {
2894 onFlipVertical(event.detail);
2895 }));
2896 }
2897 }, [
2898 onAfterAppendSlide,
2899 onAfterAppendSubHtml,
2900 onAfterClose,
2901 onRotateLeft,
2902 onRotateRight,
2903 onFlipHorizontal,
2904 onFlipVertical,
2905 onAfterOpen,
2906 onAfterSlide,
2907 onBeforeClose,
2908 onBeforeNextSlide,
2909 onBeforeOpen,
2910 onBeforePrevSlide,
2911 onBeforeSlide,
2912 onContainerResize,
2913 onDragEnd,
2914 onDragMove,
2915 onDragStart,
2916 onHasVideo,
2917 onInit,
2918 onPosterClick,
2919 onSlideItemLoad,
2920 ]);
2921 useEffect(function () {
2922 registerEvents();
2923 var lightGallery$1 = lightGallery($lg.current, restProps);
2924 return function cleanup() {
2925 lightGallery$1.destroy();
2926 };
2927 }, [registerEvents, restProps]);
2928 return (createElement("div", { className: "lg-react-element " + (elementClassNames ? elementClassNames : ''), ref: $lg }, children));
2929};
2930
2931export default LG;
2932//# sourceMappingURL=Lightgallery.es5.js.map