UNPKG

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