UNPKG

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