UNPKG

83.9 kBJavaScriptView Raw
1"use strict";
2var __assign = (this && this.__assign) || function () {
3 __assign = Object.assign || function(t) {
4 for (var s, i = 1, n = arguments.length; i < n; i++) {
5 s = arguments[i];
6 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7 t[p] = s[p];
8 }
9 return t;
10 };
11 return __assign.apply(this, arguments);
12};
13Object.defineProperty(exports, "__esModule", { value: true });
14exports.LightGallery = void 0;
15var lg_events_1 = require("./lg-events");
16var lg_settings_1 = require("./lg-settings");
17var lg_utils_1 = require("./lg-utils");
18var lgQuery_1 = require("./lgQuery");
19// @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio
20// @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html
21// Unique id for each gallery
22var lgId = 0;
23var LightGallery = /** @class */ (function () {
24 function LightGallery(element, options) {
25 this.lgOpened = false;
26 this.index = 0;
27 // lightGallery modules
28 this.plugins = [];
29 // false when lightGallery load first slide content;
30 this.lGalleryOn = false;
31 // True when a slide animation is in progress
32 this.lgBusy = false;
33 this.currentItemsInDom = [];
34 // Scroll top value before lightGallery is opened
35 this.prevScrollTop = 0;
36 this.bodyPaddingRight = 0;
37 this.isDummyImageRemoved = false;
38 this.dragOrSwipeEnabled = false;
39 this.mediaContainerPosition = {
40 top: 0,
41 bottom: 0,
42 };
43 if (!element) {
44 return this;
45 }
46 lgId++;
47 this.lgId = lgId;
48 this.el = element;
49 this.LGel = lgQuery_1.$LG(element);
50 this.generateSettings(options);
51 this.buildModules();
52 // When using dynamic mode, ensure dynamicEl is an array
53 if (this.settings.dynamic &&
54 this.settings.dynamicEl !== undefined &&
55 !Array.isArray(this.settings.dynamicEl)) {
56 throw 'When using dynamic mode, you must also define dynamicEl as an Array.';
57 }
58 this.galleryItems = this.getItems();
59 this.normalizeSettings();
60 // Gallery items
61 this.init();
62 this.validateLicense();
63 return this;
64 }
65 LightGallery.prototype.generateSettings = function (options) {
66 // lightGallery settings
67 this.settings = __assign(__assign({}, lg_settings_1.lightGalleryCoreSettings), options);
68 if (this.settings.isMobile &&
69 typeof this.settings.isMobile === 'function'
70 ? this.settings.isMobile()
71 : lg_utils_1.default.isMobile()) {
72 var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings);
73 this.settings = __assign(__assign({}, this.settings), mobileSettings);
74 }
75 };
76 LightGallery.prototype.normalizeSettings = function () {
77 if (this.settings.slideEndAnimation) {
78 this.settings.hideControlOnEnd = false;
79 }
80 if (!this.settings.closable) {
81 this.settings.swipeToClose = false;
82 }
83 // And reset it on close to get the correct value next time
84 this.zoomFromOrigin = this.settings.zoomFromOrigin;
85 // At the moment, Zoom from image doesn't support dynamic options
86 // @todo add zoomFromOrigin support for dynamic images
87 if (this.settings.dynamic) {
88 this.zoomFromOrigin = false;
89 }
90 if (!this.settings.container) {
91 this.settings.container = document.body;
92 }
93 // settings.preload should not be grater than $item.length
94 this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length);
95 };
96 LightGallery.prototype.init = function () {
97 var _this = this;
98 this.addSlideVideoInfo(this.galleryItems);
99 this.buildStructure();
100 this.LGel.trigger(lg_events_1.lGEvents.init, {
101 instance: this,
102 });
103 if (this.settings.keyPress) {
104 this.keyPress();
105 }
106 setTimeout(function () {
107 _this.enableDrag();
108 _this.enableSwipe();
109 _this.triggerPosterClick();
110 }, 50);
111 this.arrow();
112 if (this.settings.mousewheel) {
113 this.mousewheel();
114 }
115 if (!this.settings.dynamic) {
116 this.openGalleryOnItemClick();
117 }
118 };
119 LightGallery.prototype.openGalleryOnItemClick = function () {
120 var _this = this;
121 var _loop_1 = function (index) {
122 var element = this_1.items[index];
123 var $element = lgQuery_1.$LG(element);
124 // Using different namespace for click because click event should not unbind if selector is same object('this')
125 // @todo manage all event listners - should have namespace that represent element
126 var uuid = lgQuery_1.lgQuery.generateUUID();
127 $element
128 .attr('data-lg-id', uuid)
129 .on("click.lgcustom-item-" + uuid, function (e) {
130 e.preventDefault();
131 var currentItemIndex = _this.settings.index || index;
132 _this.openGallery(currentItemIndex, element);
133 });
134 };
135 var this_1 = this;
136 // Using for loop instead of using bubbling as the items can be any html element.
137 for (var index = 0; index < this.items.length; index++) {
138 _loop_1(index);
139 }
140 };
141 /**
142 * Module constructor
143 * Modules are build incrementally.
144 * Gallery should be opened only once all the modules are initialized.
145 * use moduleBuildTimeout to make sure this
146 */
147 LightGallery.prototype.buildModules = function () {
148 var _this = this;
149 this.settings.plugins.forEach(function (plugin) {
150 _this.plugins.push(new plugin(_this, lgQuery_1.$LG));
151 });
152 };
153 LightGallery.prototype.validateLicense = function () {
154 if (!this.settings.licenseKey) {
155 console.error('Please provide a valid license key');
156 }
157 else if (this.settings.licenseKey === '0000-0000-000-0000') {
158 console.warn("lightGallery: " + this.settings.licenseKey + " license key is not valid for production use");
159 }
160 };
161 LightGallery.prototype.getSlideItem = function (index) {
162 return lgQuery_1.$LG(this.getSlideItemId(index));
163 };
164 LightGallery.prototype.getSlideItemId = function (index) {
165 return "#lg-item-" + this.lgId + "-" + index;
166 };
167 LightGallery.prototype.getIdName = function (id) {
168 return id + "-" + this.lgId;
169 };
170 LightGallery.prototype.getElementById = function (id) {
171 return lgQuery_1.$LG("#" + this.getIdName(id));
172 };
173 LightGallery.prototype.manageSingleSlideClassName = function () {
174 if (this.galleryItems.length < 2) {
175 this.outer.addClass('lg-single-item');
176 }
177 else {
178 this.outer.removeClass('lg-single-item');
179 }
180 };
181 LightGallery.prototype.buildStructure = function () {
182 var _this = this;
183 var container = this.$container && this.$container.get();
184 if (container) {
185 return;
186 }
187 var controls = '';
188 var subHtmlCont = '';
189 // Create controls
190 if (this.settings.controls) {
191 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>";
192 }
193 if (this.settings.appendSubHtmlTo !== '.lg-item') {
194 subHtmlCont =
195 '<div class="lg-sub-html" role="status" aria-live="polite"></div>';
196 }
197 var addClasses = '';
198 if (this.settings.allowMediaOverlap) {
199 // Do not remove space before last single quote
200 addClasses += 'lg-media-overlap ';
201 }
202 var ariaLabelledby = this.settings.ariaLabelledby
203 ? 'aria-labelledby="' + this.settings.ariaLabelledby + '"'
204 : '';
205 var ariaDescribedby = this.settings.ariaDescribedby
206 ? 'aria-describedby="' + this.settings.ariaDescribedby + '"'
207 : '';
208 var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : '');
209 var closeIcon = this.settings.closable && this.settings.showCloseIcon
210 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>"
211 : '';
212 var maximizeIcon = this.settings.showMaximizeIcon
213 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>"
214 : '';
215 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'
216 ? subHtmlCont
217 : '') + "\n <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n " + (this.settings.appendSubHtmlTo === '.lg-sub-html'
218 ? subHtmlCont
219 : '') + "\n </div>\n </div>\n </div>\n ";
220 lgQuery_1.$LG(this.settings.container).append(template);
221 if (document.body !== this.settings.container) {
222 lgQuery_1.$LG(this.settings.container).css('position', 'relative');
223 }
224 this.outer = this.getElementById('lg-outer');
225 this.$lgComponents = this.getElementById('lg-components');
226 this.$backdrop = this.getElementById('lg-backdrop');
227 this.$container = this.getElementById('lg-container');
228 this.$inner = this.getElementById('lg-inner');
229 this.$content = this.getElementById('lg-content');
230 this.$toolbar = this.getElementById('lg-toolbar');
231 this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms');
232 var outerClassNames = this.settings.mode + " ";
233 this.manageSingleSlideClassName();
234 if (this.settings.enableDrag) {
235 outerClassNames += 'lg-grab ';
236 }
237 this.outer.addClass(outerClassNames);
238 this.$inner.css('transition-timing-function', this.settings.easing);
239 this.$inner.css('transition-duration', this.settings.speed + 'ms');
240 if (this.settings.download) {
241 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>");
242 }
243 this.counter();
244 lgQuery_1.$LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () {
245 _this.refreshOnResize();
246 });
247 this.hideBars();
248 this.manageCloseGallery();
249 this.toggleMaximize();
250 this.initModules();
251 };
252 LightGallery.prototype.refreshOnResize = function () {
253 if (this.lgOpened) {
254 var currentGalleryItem = this.galleryItems[this.index];
255 var __slideVideoInfo = currentGalleryItem.__slideVideoInfo;
256 this.mediaContainerPosition = this.getMediaContainerPosition();
257 var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom;
258 this.currentImageSize = lg_utils_1.default.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize);
259 if (__slideVideoInfo) {
260 this.resizeVideoSlide(this.index, this.currentImageSize);
261 }
262 if (this.zoomFromOrigin && !this.isDummyImageRemoved) {
263 var imgStyle = this.getDummyImgStyles(this.currentImageSize);
264 this.outer
265 .find('.lg-current .lg-dummy-img')
266 .first()
267 .attr('style', imgStyle);
268 }
269 this.LGel.trigger(lg_events_1.lGEvents.containerResize);
270 }
271 };
272 LightGallery.prototype.resizeVideoSlide = function (index, imageSize) {
273 var lgVideoStyle = this.getVideoContStyle(imageSize);
274 var currentSlide = this.getSlideItem(index);
275 currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle);
276 };
277 /**
278 * Update slides dynamically.
279 * Add, edit or delete slides dynamically when lightGallery is opened.
280 * Modify the current gallery items and pass it via updateSlides method
281 * @note
282 * - Do not mutate existing lightGallery items directly.
283 * - Always pass new list of gallery items
284 * - You need to take care of thumbnails outside the gallery if any
285 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method.
286 * @param items Gallery items
287 * @param index After the update operation, which slide gallery should navigate to
288 * @category lGPublicMethods
289 * @example
290 * const plugin = lightGallery();
291 *
292 * // Adding slides dynamically
293 * let galleryItems = [
294 * // Access existing lightGallery items
295 * // galleryItems are automatically generated internally from the gallery HTML markup
296 * // or directly from galleryItems when dynamic gallery is used
297 * ...plugin.galleryItems,
298 * ...[
299 * {
300 * src: 'img/img-1.png',
301 * thumb: 'img/thumb1.png',
302 * },
303 * ],
304 * ];
305 * plugin.updateSlides(
306 * galleryItems,
307 * plugin.index,
308 * );
309 *
310 *
311 * // Remove slides dynamically
312 * galleryItems = JSON.parse(
313 * JSON.stringify(updateSlideInstance.galleryItems),
314 * );
315 * galleryItems.shift();
316 * updateSlideInstance.updateSlides(galleryItems, 1);
317 * @see <a href="/demos/update-slides/">Demo</a>
318 */
319 LightGallery.prototype.updateSlides = function (items, index) {
320 if (this.index > items.length - 1) {
321 this.index = items.length - 1;
322 }
323 if (items.length === 1) {
324 this.index = 0;
325 }
326 if (!items.length) {
327 this.closeGallery();
328 return;
329 }
330 var currentSrc = this.galleryItems[index].src;
331 this.galleryItems = items;
332 this.updateControls();
333 this.$inner.empty();
334 this.currentItemsInDom = [];
335 var _index = 0;
336 // Find the current index based on source value of the slide
337 this.galleryItems.some(function (galleryItem, itemIndex) {
338 if (galleryItem.src === currentSrc) {
339 _index = itemIndex;
340 return true;
341 }
342 return false;
343 });
344 this.currentItemsInDom = this.organizeSlideItems(_index, -1);
345 this.loadContent(_index, true);
346 this.getSlideItem(_index).addClass('lg-current');
347 this.index = _index;
348 this.updateCurrentCounter(_index);
349 this.LGel.trigger(lg_events_1.lGEvents.updateSlides);
350 };
351 // Get gallery items based on multiple conditions
352 LightGallery.prototype.getItems = function () {
353 // Gallery items
354 this.items = [];
355 if (!this.settings.dynamic) {
356 if (this.settings.selector === 'this') {
357 this.items.push(this.el);
358 }
359 else if (this.settings.selector) {
360 if (typeof this.settings.selector === 'string') {
361 if (this.settings.selectWithin) {
362 var selectWithin = lgQuery_1.$LG(this.settings.selectWithin);
363 this.items = selectWithin
364 .find(this.settings.selector)
365 .get();
366 }
367 else {
368 this.items = this.el.querySelectorAll(this.settings.selector);
369 }
370 }
371 else {
372 this.items = this.settings.selector;
373 }
374 }
375 else {
376 this.items = this.el.children;
377 }
378 return lg_utils_1.default.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage);
379 }
380 else {
381 return this.settings.dynamicEl || [];
382 }
383 };
384 LightGallery.prototype.shouldHideScrollbar = function () {
385 return (this.settings.hideScrollbar &&
386 document.body === this.settings.container);
387 };
388 LightGallery.prototype.hideScrollbar = function () {
389 if (!this.shouldHideScrollbar()) {
390 return;
391 }
392 this.bodyPaddingRight = parseFloat(lgQuery_1.$LG('body').style().paddingRight);
393 var bodyRect = document.documentElement.getBoundingClientRect();
394 var scrollbarWidth = window.innerWidth - bodyRect.width;
395 lgQuery_1.$LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px');
396 lgQuery_1.$LG(document.body).addClass('lg-overlay-open');
397 };
398 LightGallery.prototype.resetScrollBar = function () {
399 if (!this.shouldHideScrollbar()) {
400 return;
401 }
402 lgQuery_1.$LG(document.body).css('padding-right', this.bodyPaddingRight + 'px');
403 lgQuery_1.$LG(document.body).removeClass('lg-overlay-open');
404 };
405 /**
406 * Open lightGallery.
407 * Open gallery with specific slide by passing index of the slide as parameter.
408 * @category lGPublicMethods
409 * @param {Number} index - index of the slide
410 * @param {HTMLElement} element - Which image lightGallery should zoom from
411 *
412 * @example
413 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo');
414 * const dynamicGallery = lightGallery($dynamicGallery, {
415 * dynamic: true,
416 * dynamicEl: [
417 * {
418 * src: 'img/1.jpg',
419 * thumb: 'img/thumb-1.jpg',
420 * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>',
421 * },
422 * ...
423 * ],
424 * });
425 * $dynamicGallery.addEventListener('click', function () {
426 * // Starts with third item.(Optional).
427 * // This is useful if you want use dynamic mode with
428 * // custom thumbnails (thumbnails outside gallery),
429 * dynamicGallery.openGallery(2);
430 * });
431 *
432 */
433 LightGallery.prototype.openGallery = function (index, element) {
434 var _this = this;
435 if (index === void 0) { index = this.settings.index; }
436 // prevent accidental double execution
437 if (this.lgOpened)
438 return;
439 this.lgOpened = true;
440 this.outer.removeClass('lg-hide-items');
441 this.hideScrollbar();
442 // Add display block, but still has opacity 0
443 this.$container.addClass('lg-show');
444 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index);
445 this.currentItemsInDom = itemsToBeInsertedToDom;
446 var items = '';
447 itemsToBeInsertedToDom.forEach(function (item) {
448 items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>");
449 });
450 this.$inner.append(items);
451 this.addHtml(index);
452 var transform = '';
453 this.mediaContainerPosition = this.getMediaContainerPosition();
454 var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
455 if (!this.settings.allowMediaOverlap) {
456 this.setMediaContainerPosition(top, bottom);
457 }
458 var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo;
459 if (this.zoomFromOrigin && element) {
460 this.currentImageSize = lg_utils_1.default.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize);
461 transform = lg_utils_1.default.getTransform(element, this.outer, top, bottom, this.currentImageSize);
462 }
463 if (!this.zoomFromOrigin || !transform) {
464 this.outer.addClass(this.settings.startClass);
465 this.getSlideItem(index).removeClass('lg-complete');
466 }
467 var timeout = this.settings.zoomFromOrigin
468 ? 100
469 : this.settings.backdropDuration;
470 setTimeout(function () {
471 _this.outer.addClass('lg-components-open');
472 }, timeout);
473 this.index = index;
474 this.LGel.trigger(lg_events_1.lGEvents.beforeOpen);
475 // add class lg-current to remove initial transition
476 this.getSlideItem(index).addClass('lg-current');
477 this.lGalleryOn = false;
478 // Store the current scroll top value to scroll back after closing the gallery..
479 this.prevScrollTop = lgQuery_1.$LG(window).scrollTop();
480 setTimeout(function () {
481 // Need to check both zoomFromOrigin and transform values as we need to set set the
482 // default opening animation if user missed to add the lg-size attribute
483 if (_this.zoomFromOrigin && transform) {
484 var currentSlide_1 = _this.getSlideItem(index);
485 currentSlide_1.css('transform', transform);
486 setTimeout(function () {
487 currentSlide_1
488 .addClass('lg-start-progress lg-start-end-progress')
489 .css('transition-duration', _this.settings.startAnimationDuration + 'ms');
490 _this.outer.addClass('lg-zoom-from-image');
491 });
492 setTimeout(function () {
493 currentSlide_1.css('transform', 'translate3d(0, 0, 0)');
494 }, 100);
495 }
496 setTimeout(function () {
497 _this.$backdrop.addClass('in');
498 _this.$container.addClass('lg-show-in');
499 }, 10);
500 setTimeout(function () {
501 if (_this.settings.trapFocus &&
502 document.body === _this.settings.container) {
503 _this.trapFocus();
504 }
505 }, _this.settings.backdropDuration + 50);
506 // lg-visible class resets gallery opacity to 1
507 if (!_this.zoomFromOrigin || !transform) {
508 setTimeout(function () {
509 _this.outer.addClass('lg-visible');
510 }, _this.settings.backdropDuration);
511 }
512 // initiate slide function
513 _this.slide(index, false, false, false);
514 _this.LGel.trigger(lg_events_1.lGEvents.afterOpen);
515 });
516 if (document.body === this.settings.container) {
517 lgQuery_1.$LG('html').addClass('lg-on');
518 }
519 };
520 /**
521 * Note - Changing the position of the media on every slide transition creates a flickering effect.
522 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption.
523 * if you have dynamic captions for each media,
524 * you can provide an appropriate height for the captions via allowMediaOverlap option
525 */
526 LightGallery.prototype.getMediaContainerPosition = function () {
527 if (this.settings.allowMediaOverlap) {
528 return {
529 top: 0,
530 bottom: 0,
531 };
532 }
533 var top = this.$toolbar.get().clientHeight || 0;
534 var subHtml = this.outer.find('.lg-components .lg-sub-html').get();
535 var captionHeight = this.settings.defaultCaptionHeight ||
536 (subHtml && subHtml.clientHeight) ||
537 0;
538 var thumbContainer = this.outer.find('.lg-thumb-outer').get();
539 var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0;
540 var bottom = thumbHeight + captionHeight;
541 return {
542 top: top,
543 bottom: bottom,
544 };
545 };
546 LightGallery.prototype.setMediaContainerPosition = function (top, bottom) {
547 if (top === void 0) { top = 0; }
548 if (bottom === void 0) { bottom = 0; }
549 this.$content.css('top', top + 'px').css('bottom', bottom + 'px');
550 };
551 LightGallery.prototype.hideBars = function () {
552 var _this = this;
553 // Hide controllers if mouse doesn't move for some period
554 setTimeout(function () {
555 _this.outer.removeClass('lg-hide-items');
556 if (_this.settings.hideBarsDelay > 0) {
557 _this.outer.on('mousemove.lg click.lg touchstart.lg', function () {
558 _this.outer.removeClass('lg-hide-items');
559 clearTimeout(_this.hideBarTimeout);
560 // Timeout will be cleared on each slide movement also
561 _this.hideBarTimeout = setTimeout(function () {
562 _this.outer.addClass('lg-hide-items');
563 }, _this.settings.hideBarsDelay);
564 });
565 _this.outer.trigger('mousemove.lg');
566 }
567 }, this.settings.showBarsAfter);
568 };
569 LightGallery.prototype.initPictureFill = function ($img) {
570 if (this.settings.supportLegacyBrowser) {
571 try {
572 picturefill({
573 elements: [$img.get()],
574 });
575 }
576 catch (e) {
577 console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.');
578 }
579 }
580 };
581 /**
582 * @desc Create image counter
583 * Ex: 1/10
584 */
585 LightGallery.prototype.counter = function () {
586 if (this.settings.counter) {
587 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>";
588 this.outer.find(this.settings.appendCounterTo).append(counterHtml);
589 }
590 };
591 /**
592 * @desc add sub-html into the slide
593 * @param {Number} index - index of the slide
594 */
595 LightGallery.prototype.addHtml = function (index) {
596 var subHtml;
597 var subHtmlUrl;
598 if (this.galleryItems[index].subHtmlUrl) {
599 subHtmlUrl = this.galleryItems[index].subHtmlUrl;
600 }
601 else {
602 subHtml = this.galleryItems[index].subHtml;
603 }
604 if (!subHtmlUrl) {
605 if (subHtml) {
606 // get first letter of sub-html
607 // if first letter starts with . or # get the html form the jQuery object
608 var fL = subHtml.substring(0, 1);
609 if (fL === '.' || fL === '#') {
610 if (this.settings.subHtmlSelectorRelative &&
611 !this.settings.dynamic) {
612 subHtml = lgQuery_1.$LG(this.items)
613 .eq(index)
614 .find(subHtml)
615 .first()
616 .html();
617 }
618 else {
619 subHtml = lgQuery_1.$LG(subHtml).first().html();
620 }
621 }
622 }
623 else {
624 subHtml = '';
625 }
626 }
627 if (this.settings.appendSubHtmlTo !== '.lg-item') {
628 if (subHtmlUrl) {
629 this.outer.find('.lg-sub-html').load(subHtmlUrl);
630 }
631 else {
632 this.outer.find('.lg-sub-html').html(subHtml);
633 }
634 }
635 else {
636 var currentSlide = lgQuery_1.$LG(this.getSlideItemId(index));
637 if (subHtmlUrl) {
638 currentSlide.load(subHtmlUrl);
639 }
640 else {
641 currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>");
642 }
643 }
644 // Add lg-empty-html class if title doesn't exist
645 if (typeof subHtml !== 'undefined' && subHtml !== null) {
646 if (subHtml === '') {
647 this.outer
648 .find(this.settings.appendSubHtmlTo)
649 .addClass('lg-empty-html');
650 }
651 else {
652 this.outer
653 .find(this.settings.appendSubHtmlTo)
654 .removeClass('lg-empty-html');
655 }
656 }
657 this.LGel.trigger(lg_events_1.lGEvents.afterAppendSubHtml, {
658 index: index,
659 });
660 };
661 /**
662 * @desc Preload slides
663 * @param {Number} index - index of the slide
664 * @todo preload not working for the first slide, Also, should work for the first and last slide as well
665 */
666 LightGallery.prototype.preload = function (index) {
667 for (var i = 1; i <= this.settings.preload; i++) {
668 if (i >= this.galleryItems.length - index) {
669 break;
670 }
671 this.loadContent(index + i, false);
672 }
673 for (var j = 1; j <= this.settings.preload; j++) {
674 if (index - j < 0) {
675 break;
676 }
677 this.loadContent(index - j, false);
678 }
679 };
680 LightGallery.prototype.getDummyImgStyles = function (imageSize) {
681 if (!imageSize)
682 return '';
683 return "width:" + imageSize.width + "px;\n margin-left: -" + imageSize.width / 2 + "px;\n margin-top: -" + imageSize.height / 2 + "px;\n height:" + imageSize.height + "px";
684 };
685 LightGallery.prototype.getVideoContStyle = function (imageSize) {
686 if (!imageSize)
687 return '';
688 return "width:" + imageSize.width + "px;\n height:" + imageSize.height + "px";
689 };
690 LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) {
691 var $currentItem;
692 if (!this.settings.dynamic) {
693 $currentItem = lgQuery_1.$LG(this.items).eq(index);
694 }
695 if ($currentItem) {
696 var _dummyImgSrc = void 0;
697 if (!this.settings.exThumbImage) {
698 _dummyImgSrc = $currentItem.find('img').first().attr('src');
699 }
700 else {
701 _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage);
702 }
703 if (!_dummyImgSrc)
704 return '';
705 var imgStyle = this.getDummyImgStyles(this.currentImageSize);
706 var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />";
707 $currentSlide.addClass('lg-first-slide');
708 this.outer.addClass('lg-first-slide-loading');
709 return dummyImgContent;
710 }
711 return '';
712 };
713 LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) {
714 var currentGalleryItem = this.galleryItems[index];
715 var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;
716 // Use the thumbnail as dummy image which will be resized to actual image size and
717 // displayed on top of actual image
718 var imgContent = '';
719 var altAttr = alt ? 'alt="' + alt + '"' : '';
720 if (this.isFirstSlideWithZoomAnimation()) {
721 imgContent = this.getDummyImageContent($currentSlide, index, altAttr);
722 }
723 else {
724 imgContent = lg_utils_1.default.getImgMarkup(index, src, altAttr, srcset, sizes, sources);
725 }
726 var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>";
727 $currentSlide.prepend(imgMarkup);
728 };
729 LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) {
730 var mediaObject = $slide.find('.lg-object').first();
731 if (lg_utils_1.default.isImageLoaded(mediaObject.get()) ||
732 isHTML5VideoWithoutPoster) {
733 onLoad();
734 }
735 else {
736 mediaObject.on('load.lg error.lg', function () {
737 onLoad && onLoad();
738 });
739 mediaObject.on('error.lg', function () {
740 onError && onError();
741 });
742 }
743 };
744 /**
745 *
746 * @param $el Current slide item
747 * @param index
748 * @param delay Delay is 0 except first time
749 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin
750 * @param isFirstSlide
751 */
752 LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) {
753 var _this = this;
754 this.onSlideObjectLoad(currentSlide, isHTML5VideoWithoutPoster, function () {
755 _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide);
756 }, function () {
757 currentSlide.addClass('lg-complete lg-complete_');
758 currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>');
759 });
760 };
761 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) {
762 var _this = this;
763 var currentGalleryItem = this.galleryItems[index];
764 // Adding delay for video slides without poster for better performance and user experience
765 // Videos should start playing once once the gallery is completely loaded
766 var _speed = isFirstSlide &&
767 this.getSlideType(currentGalleryItem) === 'video' &&
768 !currentGalleryItem.poster
769 ? speed
770 : 0;
771 setTimeout(function () {
772 $currentSlide.addClass('lg-complete lg-complete_');
773 _this.LGel.trigger(lg_events_1.lGEvents.slideItemLoad, {
774 index: index,
775 delay: delay || 0,
776 isFirstSlide: isFirstSlide,
777 });
778 }, _speed);
779 };
780 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () {
781 return !!(!this.lGalleryOn &&
782 this.zoomFromOrigin &&
783 this.currentImageSize);
784 };
785 // Add video slideInfo
786 LightGallery.prototype.addSlideVideoInfo = function (items) {
787 var _this = this;
788 items.forEach(function (element, index) {
789 element.__slideVideoInfo = lg_utils_1.default.isVideo(element.src, !!element.video, index);
790 if (element.__slideVideoInfo &&
791 _this.settings.loadYouTubePoster &&
792 !element.poster &&
793 element.__slideVideoInfo.youtube) {
794 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg";
795 }
796 });
797 };
798 /**
799 * Load slide content into slide.
800 * This is used to load content into slides that is not visible too
801 * @param {Number} index - index of the slide.
802 * @param {Boolean} rec - if true call loadcontent() function again.
803 */
804 LightGallery.prototype.loadContent = function (index, rec) {
805 var _this = this;
806 var currentGalleryItem = this.galleryItems[index];
807 var $currentSlide = lgQuery_1.$LG(this.getSlideItemId(index));
808 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;
809 var src = currentGalleryItem.src;
810 var video = currentGalleryItem.video;
811 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video;
812 if (currentGalleryItem.responsive) {
813 var srcDyItms = currentGalleryItem.responsive.split(',');
814 src = lg_utils_1.default.getResponsiveSrc(srcDyItms) || src;
815 }
816 var videoInfo = currentGalleryItem.__slideVideoInfo;
817 var lgVideoStyle = '';
818 var iframe = !!currentGalleryItem.iframe;
819 var isFirstSlide = !this.lGalleryOn;
820 // delay for adding complete class. it is 0 except first time.
821 var delay = 0;
822 if (isFirstSlide) {
823 if (this.zoomFromOrigin && this.currentImageSize) {
824 delay = this.settings.startAnimationDuration + 10;
825 }
826 else {
827 delay = this.settings.backdropDuration + 10;
828 }
829 }
830 if (!$currentSlide.hasClass('lg-loaded')) {
831 if (videoInfo) {
832 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom;
833 var videoSize = lg_utils_1.default.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize);
834 lgVideoStyle = this.getVideoContStyle(videoSize);
835 }
836 if (iframe) {
837 var markup = lg_utils_1.default.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle);
838 $currentSlide.prepend(markup);
839 }
840 else if (poster) {
841 var dummyImg = '';
842 var hasStartAnimation = isFirstSlide &&
843 this.zoomFromOrigin &&
844 this.currentImageSize;
845 if (hasStartAnimation) {
846 dummyImg = this.getDummyImageContent($currentSlide, index, '');
847 }
848 var markup = lg_utils_1.default.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo);
849 $currentSlide.prepend(markup);
850 }
851 else if (videoInfo) {
852 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>";
853 $currentSlide.prepend(markup);
854 }
855 else {
856 this.setImgMarkup(src, $currentSlide, index);
857 if (srcset || sources) {
858 var $img = $currentSlide.find('.lg-object');
859 this.initPictureFill($img);
860 }
861 }
862 if (poster || videoInfo) {
863 this.LGel.trigger(lg_events_1.lGEvents.hasVideo, {
864 index: index,
865 src: src,
866 html5Video: _html5Video,
867 hasPoster: !!poster,
868 });
869 }
870 this.LGel.trigger(lg_events_1.lGEvents.afterAppendSlide, { index: index });
871 if (this.lGalleryOn &&
872 this.settings.appendSubHtmlTo === '.lg-item') {
873 this.addHtml(index);
874 }
875 }
876 // For first time add some delay for displaying the start animation.
877 var _speed = 0;
878 // Do not change the delay value because it is required for zoom plugin.
879 // If gallery opened from direct url (hash) speed value should be 0
880 if (delay && !lgQuery_1.$LG(document.body).hasClass('lg-from-hash')) {
881 _speed = delay;
882 }
883 // Only for first slide and zoomFromOrigin is enabled
884 if (this.isFirstSlideWithZoomAnimation()) {
885 setTimeout(function () {
886 $currentSlide
887 .removeClass('lg-start-end-progress lg-start-progress')
888 .removeAttr('style');
889 }, this.settings.startAnimationDuration + 100);
890 if (!$currentSlide.hasClass('lg-loaded')) {
891 setTimeout(function () {
892 if (_this.getSlideType(currentGalleryItem) === 'image') {
893 var alt = currentGalleryItem.alt;
894 var altAttr = alt ? 'alt="' + alt + '"' : '';
895 $currentSlide
896 .find('.lg-img-wrap')
897 .append(lg_utils_1.default.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources));
898 if (srcset || sources) {
899 var $img = $currentSlide.find('.lg-object');
900 _this.initPictureFill($img);
901 }
902 }
903 if (_this.getSlideType(currentGalleryItem) === 'image' ||
904 (_this.getSlideType(currentGalleryItem) === 'video' &&
905 poster)) {
906 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false);
907 // load remaining slides once the slide is completely loaded
908 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () {
909 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
910 }, function () {
911 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
912 });
913 }
914 }, this.settings.startAnimationDuration + 100);
915 }
916 }
917 // SLide content has been added to dom
918 $currentSlide.addClass('lg-loaded');
919 if (!this.isFirstSlideWithZoomAnimation() ||
920 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) {
921 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster));
922 }
923 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling
924 if ((!this.zoomFromOrigin || !this.currentImageSize) &&
925 $currentSlide.hasClass('lg-complete_') &&
926 !this.lGalleryOn) {
927 setTimeout(function () {
928 $currentSlide.addClass('lg-complete');
929 }, this.settings.backdropDuration);
930 }
931 // Content loaded
932 // Need to set lGalleryOn before calling preload function
933 this.lGalleryOn = true;
934 if (rec === true) {
935 if (!$currentSlide.hasClass('lg-complete_')) {
936 $currentSlide
937 .find('.lg-object')
938 .first()
939 .on('load.lg error.lg', function () {
940 _this.preload(index);
941 });
942 }
943 else {
944 this.preload(index);
945 }
946 }
947 };
948 /**
949 * @desc Remove dummy image content and load next slides
950 * Called only for the first time if zoomFromOrigin animation is enabled
951 * @param index
952 * @param $currentSlide
953 * @param speed
954 */
955 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) {
956 var _this = this;
957 setTimeout(function () {
958 $currentSlide.find('.lg-dummy-img').remove();
959 $currentSlide.removeClass('lg-first-slide');
960 _this.outer.removeClass('lg-first-slide-loading');
961 _this.isDummyImageRemoved = true;
962 _this.preload(index);
963 }, speed + 300);
964 };
965 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) {
966 var _this = this;
967 if (numberOfItems === void 0) { numberOfItems = 0; }
968 var itemsToBeInsertedToDom = [];
969 // Minimum 2 items should be there
970 var possibleNumberOfItems = Math.max(numberOfItems, 3);
971 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length);
972 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex;
973 if (this.galleryItems.length <= 3) {
974 this.galleryItems.forEach(function (_element, index) {
975 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index);
976 });
977 return itemsToBeInsertedToDom;
978 }
979 if (index < (this.galleryItems.length - 1) / 2) {
980 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) {
981 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
982 }
983 var numberOfExistingItems = itemsToBeInsertedToDom.length;
984 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
985 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1));
986 }
987 }
988 else {
989 for (var idx = index; idx <= this.galleryItems.length - 1 &&
990 idx < index + possibleNumberOfItems / 2; idx++) {
991 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
992 }
993 var numberOfExistingItems = itemsToBeInsertedToDom.length;
994 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
995 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1));
996 }
997 }
998 if (this.settings.loop) {
999 if (index === this.galleryItems.length - 1) {
1000 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0);
1001 }
1002 else if (index === 0) {
1003 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1));
1004 }
1005 }
1006 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) {
1007 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex);
1008 }
1009 return itemsToBeInsertedToDom;
1010 };
1011 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) {
1012 var _this = this;
1013 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom);
1014 itemsToBeInsertedToDom.forEach(function (item) {
1015 if (_this.currentItemsInDom.indexOf(item) === -1) {
1016 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>");
1017 }
1018 });
1019 this.currentItemsInDom.forEach(function (item) {
1020 if (itemsToBeInsertedToDom.indexOf(item) === -1) {
1021 lgQuery_1.$LG("#" + item).remove();
1022 }
1023 });
1024 return itemsToBeInsertedToDom;
1025 };
1026 /**
1027 * Get previous index of the slide
1028 */
1029 LightGallery.prototype.getPreviousSlideIndex = function () {
1030 var prevIndex = 0;
1031 try {
1032 var currentItemId = this.outer
1033 .find('.lg-current')
1034 .first()
1035 .attr('id');
1036 prevIndex = parseInt(currentItemId.split('-')[3]) || 0;
1037 }
1038 catch (error) {
1039 prevIndex = 0;
1040 }
1041 return prevIndex;
1042 };
1043 LightGallery.prototype.setDownloadValue = function (index) {
1044 if (this.settings.download) {
1045 var currentGalleryItem = this.galleryItems[index];
1046 var hideDownloadBtn = currentGalleryItem.downloadUrl === false ||
1047 currentGalleryItem.downloadUrl === 'false';
1048 if (hideDownloadBtn) {
1049 this.outer.addClass('lg-hide-download');
1050 }
1051 else {
1052 var $download = this.getElementById('lg-download');
1053 this.outer.removeClass('lg-hide-download');
1054 $download.attr('href', currentGalleryItem.downloadUrl ||
1055 currentGalleryItem.src);
1056 if (currentGalleryItem.download) {
1057 $download.attr('download', currentGalleryItem.download);
1058 }
1059 }
1060 }
1061 };
1062 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) {
1063 var _this = this;
1064 if (this.lGalleryOn) {
1065 previousSlideItem.addClass('lg-slide-progress');
1066 }
1067 setTimeout(function () {
1068 // remove all transitions
1069 _this.outer.addClass('lg-no-trans');
1070 _this.outer
1071 .find('.lg-item')
1072 .removeClass('lg-prev-slide lg-next-slide');
1073 if (direction === 'prev') {
1074 //prevslide
1075 currentSlideItem.addClass('lg-prev-slide');
1076 previousSlideItem.addClass('lg-next-slide');
1077 }
1078 else {
1079 // next slide
1080 currentSlideItem.addClass('lg-next-slide');
1081 previousSlideItem.addClass('lg-prev-slide');
1082 }
1083 // give 50 ms for browser to add/remove class
1084 setTimeout(function () {
1085 _this.outer.find('.lg-item').removeClass('lg-current');
1086 currentSlideItem.addClass('lg-current');
1087 // reset all transitions
1088 _this.outer.removeClass('lg-no-trans');
1089 }, 50);
1090 }, this.lGalleryOn ? this.settings.slideDelay : 0);
1091 };
1092 /**
1093 * Goto a specific slide.
1094 * @param {Number} index - index of the slide
1095 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag
1096 * @param {Boolean} fromThumb - true if slide function called via thumbnail click
1097 * @param {String} direction - Direction of the slide(next/prev)
1098 * @category lGPublicMethods
1099 * @example
1100 * const plugin = lightGallery();
1101 * // to go to 3rd slide
1102 * plugin.slide(2);
1103 *
1104 */
1105 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) {
1106 var _this = this;
1107 var prevIndex = this.getPreviousSlideIndex();
1108 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex);
1109 // Prevent multiple call, Required for hsh plugin
1110 if (this.lGalleryOn && prevIndex === index) {
1111 return;
1112 }
1113 var numberOfGalleryItems = this.galleryItems.length;
1114 if (!this.lgBusy) {
1115 if (this.settings.counter) {
1116 this.updateCurrentCounter(index);
1117 }
1118 var currentSlideItem = this.getSlideItem(index);
1119 var previousSlideItem_1 = this.getSlideItem(prevIndex);
1120 var currentGalleryItem = this.galleryItems[index];
1121 var videoInfo = currentGalleryItem.__slideVideoInfo;
1122 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem));
1123 this.setDownloadValue(index);
1124 if (videoInfo) {
1125 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom;
1126 var videoSize = lg_utils_1.default.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize);
1127 this.resizeVideoSlide(index, videoSize);
1128 }
1129 this.LGel.trigger(lg_events_1.lGEvents.beforeSlide, {
1130 prevIndex: prevIndex,
1131 index: index,
1132 fromTouch: !!fromTouch,
1133 fromThumb: !!fromThumb,
1134 });
1135 this.lgBusy = true;
1136 clearTimeout(this.hideBarTimeout);
1137 this.arrowDisable(index);
1138 if (!direction) {
1139 if (index < prevIndex) {
1140 direction = 'prev';
1141 }
1142 else if (index > prevIndex) {
1143 direction = 'next';
1144 }
1145 }
1146 if (!fromTouch) {
1147 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1);
1148 }
1149 else {
1150 this.outer
1151 .find('.lg-item')
1152 .removeClass('lg-prev-slide lg-current lg-next-slide');
1153 var touchPrev = void 0;
1154 var touchNext = void 0;
1155 if (numberOfGalleryItems > 2) {
1156 touchPrev = index - 1;
1157 touchNext = index + 1;
1158 if (index === 0 && prevIndex === numberOfGalleryItems - 1) {
1159 // next slide
1160 touchNext = 0;
1161 touchPrev = numberOfGalleryItems - 1;
1162 }
1163 else if (index === numberOfGalleryItems - 1 &&
1164 prevIndex === 0) {
1165 // prev slide
1166 touchNext = 0;
1167 touchPrev = numberOfGalleryItems - 1;
1168 }
1169 }
1170 else {
1171 touchPrev = 0;
1172 touchNext = 1;
1173 }
1174 if (direction === 'prev') {
1175 this.getSlideItem(touchNext).addClass('lg-next-slide');
1176 }
1177 else {
1178 this.getSlideItem(touchPrev).addClass('lg-prev-slide');
1179 }
1180 currentSlideItem.addClass('lg-current');
1181 }
1182 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened
1183 if (!this.lGalleryOn) {
1184 this.loadContent(index, true);
1185 }
1186 else {
1187 setTimeout(function () {
1188 _this.loadContent(index, true);
1189 // Add title if this.settings.appendSubHtmlTo === lg-sub-html
1190 if (_this.settings.appendSubHtmlTo !== '.lg-item') {
1191 _this.addHtml(index);
1192 }
1193 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay));
1194 }
1195 setTimeout(function () {
1196 _this.lgBusy = false;
1197 previousSlideItem_1.removeClass('lg-slide-progress');
1198 _this.LGel.trigger(lg_events_1.lGEvents.afterSlide, {
1199 prevIndex: prevIndex,
1200 index: index,
1201 fromTouch: fromTouch,
1202 fromThumb: fromThumb,
1203 });
1204 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay));
1205 }
1206 this.index = index;
1207 };
1208 LightGallery.prototype.updateCurrentCounter = function (index) {
1209 this.getElementById('lg-counter-current').html(index + 1 + '');
1210 };
1211 LightGallery.prototype.updateCounterTotal = function () {
1212 this.getElementById('lg-counter-all').html(this.galleryItems.length + '');
1213 };
1214 LightGallery.prototype.getSlideType = function (item) {
1215 if (item.__slideVideoInfo) {
1216 return 'video';
1217 }
1218 else if (item.iframe) {
1219 return 'iframe';
1220 }
1221 else {
1222 return 'image';
1223 }
1224 };
1225 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) {
1226 var distanceX = endCoords.pageX - startCoords.pageX;
1227 var distanceY = endCoords.pageY - startCoords.pageY;
1228 var allowSwipe = false;
1229 if (this.swipeDirection) {
1230 allowSwipe = true;
1231 }
1232 else {
1233 if (Math.abs(distanceX) > 15) {
1234 this.swipeDirection = 'horizontal';
1235 allowSwipe = true;
1236 }
1237 else if (Math.abs(distanceY) > 15) {
1238 this.swipeDirection = 'vertical';
1239 allowSwipe = true;
1240 }
1241 }
1242 if (!allowSwipe) {
1243 return;
1244 }
1245 var $currentSlide = this.getSlideItem(this.index);
1246 if (this.swipeDirection === 'horizontal') {
1247 e === null || e === void 0 ? void 0 : e.preventDefault();
1248 // reset opacity and transition duration
1249 this.outer.addClass('lg-dragging');
1250 // move current slide
1251 this.setTranslate($currentSlide, distanceX, 0);
1252 // move next and prev slide with current slide
1253 var width = $currentSlide.get().offsetWidth;
1254 var slideWidthAmount = (width * 15) / 100;
1255 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100);
1256 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0);
1257 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0);
1258 }
1259 else if (this.swipeDirection === 'vertical') {
1260 if (this.settings.swipeToClose) {
1261 e === null || e === void 0 ? void 0 : e.preventDefault();
1262 this.$container.addClass('lg-dragging-vertical');
1263 var opacity = 1 - Math.abs(distanceY) / window.innerHeight;
1264 this.$backdrop.css('opacity', opacity);
1265 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2);
1266 this.setTranslate($currentSlide, 0, distanceY, scale, scale);
1267 if (Math.abs(distanceY) > 100) {
1268 this.outer
1269 .addClass('lg-hide-items')
1270 .removeClass('lg-components-open');
1271 }
1272 }
1273 }
1274 };
1275 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) {
1276 var _this = this;
1277 var distance;
1278 // keep slide animation for any mode while dragg/swipe
1279 if (this.settings.mode !== 'lg-slide') {
1280 this.outer.addClass('lg-slide');
1281 }
1282 // set transition duration
1283 setTimeout(function () {
1284 _this.$container.removeClass('lg-dragging-vertical');
1285 _this.outer
1286 .removeClass('lg-dragging lg-hide-items')
1287 .addClass('lg-components-open');
1288 var triggerClick = true;
1289 if (_this.swipeDirection === 'horizontal') {
1290 distance = endCoords.pageX - startCoords.pageX;
1291 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX);
1292 if (distance < 0 &&
1293 distanceAbs > _this.settings.swipeThreshold) {
1294 _this.goToNextSlide(true);
1295 triggerClick = false;
1296 }
1297 else if (distance > 0 &&
1298 distanceAbs > _this.settings.swipeThreshold) {
1299 _this.goToPrevSlide(true);
1300 triggerClick = false;
1301 }
1302 }
1303 else if (_this.swipeDirection === 'vertical') {
1304 distance = Math.abs(endCoords.pageY - startCoords.pageY);
1305 if (_this.settings.closable &&
1306 _this.settings.swipeToClose &&
1307 distance > 100) {
1308 _this.closeGallery();
1309 return;
1310 }
1311 else {
1312 _this.$backdrop.css('opacity', 1);
1313 }
1314 }
1315 _this.outer.find('.lg-item').removeAttr('style');
1316 if (triggerClick &&
1317 Math.abs(endCoords.pageX - startCoords.pageX) < 5) {
1318 // Trigger click if distance is less than 5 pix
1319 var target = lgQuery_1.$LG(event.target);
1320 if (_this.isPosterElement(target)) {
1321 _this.LGel.trigger(lg_events_1.lGEvents.posterClick);
1322 }
1323 }
1324 _this.swipeDirection = undefined;
1325 });
1326 // remove slide class once drag/swipe is completed if mode is not slide
1327 setTimeout(function () {
1328 if (!_this.outer.hasClass('lg-dragging') &&
1329 _this.settings.mode !== 'lg-slide') {
1330 _this.outer.removeClass('lg-slide');
1331 }
1332 }, this.settings.speed + 100);
1333 };
1334 LightGallery.prototype.enableSwipe = function () {
1335 var _this = this;
1336 var startCoords = {};
1337 var endCoords = {};
1338 var isMoved = false;
1339 var isSwiping = false;
1340 if (this.settings.enableSwipe) {
1341 this.$inner.on('touchstart.lg', function (e) {
1342 _this.dragOrSwipeEnabled = true;
1343 var $item = _this.getSlideItem(_this.index);
1344 if ((lgQuery_1.$LG(e.target).hasClass('lg-item') ||
1345 $item.get().contains(e.target)) &&
1346 !_this.outer.hasClass('lg-zoomed') &&
1347 !_this.lgBusy &&
1348 e.touches.length === 1) {
1349 isSwiping = true;
1350 _this.touchAction = 'swipe';
1351 _this.manageSwipeClass();
1352 startCoords = {
1353 pageX: e.touches[0].pageX,
1354 pageY: e.touches[0].pageY,
1355 };
1356 }
1357 });
1358 this.$inner.on('touchmove.lg', function (e) {
1359 if (isSwiping &&
1360 _this.touchAction === 'swipe' &&
1361 e.touches.length === 1) {
1362 endCoords = {
1363 pageX: e.touches[0].pageX,
1364 pageY: e.touches[0].pageY,
1365 };
1366 _this.touchMove(startCoords, endCoords, e);
1367 isMoved = true;
1368 }
1369 });
1370 this.$inner.on('touchend.lg', function (event) {
1371 if (_this.touchAction === 'swipe') {
1372 if (isMoved) {
1373 isMoved = false;
1374 _this.touchEnd(endCoords, startCoords, event);
1375 }
1376 else if (isSwiping) {
1377 var target = lgQuery_1.$LG(event.target);
1378 if (_this.isPosterElement(target)) {
1379 _this.LGel.trigger(lg_events_1.lGEvents.posterClick);
1380 }
1381 }
1382 _this.touchAction = undefined;
1383 isSwiping = false;
1384 }
1385 });
1386 }
1387 };
1388 LightGallery.prototype.enableDrag = function () {
1389 var _this = this;
1390 var startCoords = {};
1391 var endCoords = {};
1392 var isDraging = false;
1393 var isMoved = false;
1394 if (this.settings.enableDrag) {
1395 this.outer.on('mousedown.lg', function (e) {
1396 _this.dragOrSwipeEnabled = true;
1397 var $item = _this.getSlideItem(_this.index);
1398 if (lgQuery_1.$LG(e.target).hasClass('lg-item') ||
1399 $item.get().contains(e.target)) {
1400 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) {
1401 e.preventDefault();
1402 if (!_this.lgBusy) {
1403 _this.manageSwipeClass();
1404 startCoords = {
1405 pageX: e.pageX,
1406 pageY: e.pageY,
1407 };
1408 isDraging = true;
1409 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
1410 _this.outer.get().scrollLeft += 1;
1411 _this.outer.get().scrollLeft -= 1;
1412 // *
1413 _this.outer
1414 .removeClass('lg-grab')
1415 .addClass('lg-grabbing');
1416 _this.LGel.trigger(lg_events_1.lGEvents.dragStart);
1417 }
1418 }
1419 }
1420 });
1421 lgQuery_1.$LG(window).on("mousemove.lg.global" + this.lgId, function (e) {
1422 if (isDraging && _this.lgOpened) {
1423 isMoved = true;
1424 endCoords = {
1425 pageX: e.pageX,
1426 pageY: e.pageY,
1427 };
1428 _this.touchMove(startCoords, endCoords);
1429 _this.LGel.trigger(lg_events_1.lGEvents.dragMove);
1430 }
1431 });
1432 lgQuery_1.$LG(window).on("mouseup.lg.global" + this.lgId, function (event) {
1433 if (!_this.lgOpened) {
1434 return;
1435 }
1436 var target = lgQuery_1.$LG(event.target);
1437 if (isMoved) {
1438 isMoved = false;
1439 _this.touchEnd(endCoords, startCoords, event);
1440 _this.LGel.trigger(lg_events_1.lGEvents.dragEnd);
1441 }
1442 else if (_this.isPosterElement(target)) {
1443 _this.LGel.trigger(lg_events_1.lGEvents.posterClick);
1444 }
1445 // Prevent execution on click
1446 if (isDraging) {
1447 isDraging = false;
1448 _this.outer.removeClass('lg-grabbing').addClass('lg-grab');
1449 }
1450 });
1451 }
1452 };
1453 LightGallery.prototype.triggerPosterClick = function () {
1454 var _this = this;
1455 this.$inner.on('click.lg', function (event) {
1456 if (!_this.dragOrSwipeEnabled &&
1457 _this.isPosterElement(lgQuery_1.$LG(event.target))) {
1458 _this.LGel.trigger(lg_events_1.lGEvents.posterClick);
1459 }
1460 });
1461 };
1462 LightGallery.prototype.manageSwipeClass = function () {
1463 var _touchNext = this.index + 1;
1464 var _touchPrev = this.index - 1;
1465 if (this.settings.loop && this.galleryItems.length > 2) {
1466 if (this.index === 0) {
1467 _touchPrev = this.galleryItems.length - 1;
1468 }
1469 else if (this.index === this.galleryItems.length - 1) {
1470 _touchNext = 0;
1471 }
1472 }
1473 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide');
1474 if (_touchPrev > -1) {
1475 this.getSlideItem(_touchPrev).addClass('lg-prev-slide');
1476 }
1477 this.getSlideItem(_touchNext).addClass('lg-next-slide');
1478 };
1479 /**
1480 * Go to next slide
1481 * @param {Boolean} fromTouch - true if slide function called via touch event
1482 * @category lGPublicMethods
1483 * @example
1484 * const plugin = lightGallery();
1485 * plugin.goToNextSlide();
1486 * @see <a href="/demos/methods/">Demo</a>
1487 */
1488 LightGallery.prototype.goToNextSlide = function (fromTouch) {
1489 var _this = this;
1490 var _loop = this.settings.loop;
1491 if (fromTouch && this.galleryItems.length < 3) {
1492 _loop = false;
1493 }
1494 if (!this.lgBusy) {
1495 if (this.index + 1 < this.galleryItems.length) {
1496 this.index++;
1497 this.LGel.trigger(lg_events_1.lGEvents.beforeNextSlide, {
1498 index: this.index,
1499 });
1500 this.slide(this.index, !!fromTouch, false, 'next');
1501 }
1502 else {
1503 if (_loop) {
1504 this.index = 0;
1505 this.LGel.trigger(lg_events_1.lGEvents.beforeNextSlide, {
1506 index: this.index,
1507 });
1508 this.slide(this.index, !!fromTouch, false, 'next');
1509 }
1510 else if (this.settings.slideEndAnimation && !fromTouch) {
1511 this.outer.addClass('lg-right-end');
1512 setTimeout(function () {
1513 _this.outer.removeClass('lg-right-end');
1514 }, 400);
1515 }
1516 }
1517 }
1518 };
1519 /**
1520 * Go to previous slides
1521 * @param {Boolean} fromTouch - true if slide function called via touch event
1522 * @category lGPublicMethods
1523 * @example
1524 * const plugin = lightGallery({});
1525 * plugin.goToPrevSlide();
1526 * @see <a href="/demos/methods/">Demo</a>
1527 *
1528 */
1529 LightGallery.prototype.goToPrevSlide = function (fromTouch) {
1530 var _this = this;
1531 var _loop = this.settings.loop;
1532 if (fromTouch && this.galleryItems.length < 3) {
1533 _loop = false;
1534 }
1535 if (!this.lgBusy) {
1536 if (this.index > 0) {
1537 this.index--;
1538 this.LGel.trigger(lg_events_1.lGEvents.beforePrevSlide, {
1539 index: this.index,
1540 fromTouch: fromTouch,
1541 });
1542 this.slide(this.index, !!fromTouch, false, 'prev');
1543 }
1544 else {
1545 if (_loop) {
1546 this.index = this.galleryItems.length - 1;
1547 this.LGel.trigger(lg_events_1.lGEvents.beforePrevSlide, {
1548 index: this.index,
1549 fromTouch: fromTouch,
1550 });
1551 this.slide(this.index, !!fromTouch, false, 'prev');
1552 }
1553 else if (this.settings.slideEndAnimation && !fromTouch) {
1554 this.outer.addClass('lg-left-end');
1555 setTimeout(function () {
1556 _this.outer.removeClass('lg-left-end');
1557 }, 400);
1558 }
1559 }
1560 }
1561 };
1562 LightGallery.prototype.keyPress = function () {
1563 var _this = this;
1564 lgQuery_1.$LG(window).on("keydown.lg.global" + this.lgId, function (e) {
1565 if (_this.lgOpened &&
1566 _this.settings.escKey === true &&
1567 e.keyCode === 27) {
1568 e.preventDefault();
1569 if (_this.settings.allowMediaOverlap &&
1570 _this.outer.hasClass('lg-can-toggle') &&
1571 _this.outer.hasClass('lg-components-open')) {
1572 _this.outer.removeClass('lg-components-open');
1573 }
1574 else {
1575 _this.closeGallery();
1576 }
1577 }
1578 if (_this.lgOpened && _this.galleryItems.length > 1) {
1579 if (e.keyCode === 37) {
1580 e.preventDefault();
1581 _this.goToPrevSlide();
1582 }
1583 if (e.keyCode === 39) {
1584 e.preventDefault();
1585 _this.goToNextSlide();
1586 }
1587 }
1588 });
1589 };
1590 LightGallery.prototype.arrow = function () {
1591 var _this = this;
1592 this.getElementById('lg-prev').on('click.lg', function () {
1593 _this.goToPrevSlide();
1594 });
1595 this.getElementById('lg-next').on('click.lg', function () {
1596 _this.goToNextSlide();
1597 });
1598 };
1599 LightGallery.prototype.arrowDisable = function (index) {
1600 // Disable arrows if settings.hideControlOnEnd is true
1601 if (!this.settings.loop && this.settings.hideControlOnEnd) {
1602 var $prev = this.getElementById('lg-prev');
1603 var $next = this.getElementById('lg-next');
1604 if (index + 1 === this.galleryItems.length) {
1605 $next.attr('disabled', 'disabled').addClass('disabled');
1606 }
1607 else {
1608 $next.removeAttr('disabled').removeClass('disabled');
1609 }
1610 if (index === 0) {
1611 $prev.attr('disabled', 'disabled').addClass('disabled');
1612 }
1613 else {
1614 $prev.removeAttr('disabled').removeClass('disabled');
1615 }
1616 }
1617 };
1618 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) {
1619 if (scaleX === void 0) { scaleX = 1; }
1620 if (scaleY === void 0) { scaleY = 1; }
1621 $el.css('transform', 'translate3d(' +
1622 xValue +
1623 'px, ' +
1624 yValue +
1625 'px, 0px) scale3d(' +
1626 scaleX +
1627 ', ' +
1628 scaleY +
1629 ', 1)');
1630 };
1631 LightGallery.prototype.mousewheel = function () {
1632 var _this = this;
1633 var lastCall = 0;
1634 this.outer.on('wheel.lg', function (e) {
1635 if (!e.deltaY || _this.galleryItems.length < 2) {
1636 return;
1637 }
1638 e.preventDefault();
1639 var now = new Date().getTime();
1640 if (now - lastCall < 1000) {
1641 return;
1642 }
1643 lastCall = now;
1644 if (e.deltaY > 0) {
1645 _this.goToNextSlide();
1646 }
1647 else if (e.deltaY < 0) {
1648 _this.goToPrevSlide();
1649 }
1650 });
1651 };
1652 LightGallery.prototype.isSlideElement = function (target) {
1653 return (target.hasClass('lg-outer') ||
1654 target.hasClass('lg-item') ||
1655 target.hasClass('lg-img-wrap'));
1656 };
1657 LightGallery.prototype.isPosterElement = function (target) {
1658 var playButton = this.getSlideItem(this.index)
1659 .find('.lg-video-play-button')
1660 .get();
1661 return (target.hasClass('lg-video-poster') ||
1662 target.hasClass('lg-video-play-button') ||
1663 (playButton && playButton.contains(target.get())));
1664 };
1665 /**
1666 * Maximize minimize inline gallery.
1667 * @category lGPublicMethods
1668 */
1669 LightGallery.prototype.toggleMaximize = function () {
1670 var _this = this;
1671 this.getElementById('lg-maximize').on('click.lg', function () {
1672 _this.$container.toggleClass('lg-inline');
1673 _this.refreshOnResize();
1674 });
1675 };
1676 LightGallery.prototype.invalidateItems = function () {
1677 for (var index = 0; index < this.items.length; index++) {
1678 var element = this.items[index];
1679 var $element = lgQuery_1.$LG(element);
1680 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id'));
1681 }
1682 };
1683 LightGallery.prototype.trapFocus = function () {
1684 var _this = this;
1685 this.$container.get().focus({
1686 preventScroll: true,
1687 });
1688 lgQuery_1.$LG(window).on("keydown.lg.global" + this.lgId, function (e) {
1689 if (!_this.lgOpened) {
1690 return;
1691 }
1692 var isTabPressed = e.key === 'Tab' || e.keyCode === 9;
1693 if (!isTabPressed) {
1694 return;
1695 }
1696 var focusableEls = lg_utils_1.default.getFocusableElements(_this.$container.get());
1697 var firstFocusableEl = focusableEls[0];
1698 var lastFocusableEl = focusableEls[focusableEls.length - 1];
1699 if (e.shiftKey) {
1700 if (document.activeElement === firstFocusableEl) {
1701 lastFocusableEl.focus();
1702 e.preventDefault();
1703 }
1704 }
1705 else {
1706 if (document.activeElement === lastFocusableEl) {
1707 firstFocusableEl.focus();
1708 e.preventDefault();
1709 }
1710 }
1711 });
1712 };
1713 LightGallery.prototype.manageCloseGallery = function () {
1714 var _this = this;
1715 if (!this.settings.closable)
1716 return;
1717 var mousedown = false;
1718 this.getElementById('lg-close').on('click.lg', function () {
1719 _this.closeGallery();
1720 });
1721 if (this.settings.closeOnTap) {
1722 // If you drag the slide and release outside gallery gets close on chrome
1723 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer
1724 this.outer.on('mousedown.lg', function (e) {
1725 var target = lgQuery_1.$LG(e.target);
1726 if (_this.isSlideElement(target)) {
1727 mousedown = true;
1728 }
1729 else {
1730 mousedown = false;
1731 }
1732 });
1733 this.outer.on('mousemove.lg', function () {
1734 mousedown = false;
1735 });
1736 this.outer.on('mouseup.lg', function (e) {
1737 var target = lgQuery_1.$LG(e.target);
1738 if (_this.isSlideElement(target) && mousedown) {
1739 if (!_this.outer.hasClass('lg-dragging')) {
1740 _this.closeGallery();
1741 }
1742 }
1743 });
1744 }
1745 };
1746 /**
1747 * Close lightGallery if it is opened.
1748 *
1749 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery
1750 * @return returns the estimated time to close gallery completely including the close animation duration
1751 * @category lGPublicMethods
1752 * @example
1753 * const plugin = lightGallery();
1754 * plugin.closeGallery();
1755 *
1756 */
1757 LightGallery.prototype.closeGallery = function (force) {
1758 var _this = this;
1759 if (!this.lgOpened || (!this.settings.closable && !force)) {
1760 return 0;
1761 }
1762 this.LGel.trigger(lg_events_1.lGEvents.beforeClose);
1763 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) {
1764 lgQuery_1.$LG(window).scrollTop(this.prevScrollTop);
1765 }
1766 var currentItem = this.items[this.index];
1767 var transform;
1768 if (this.zoomFromOrigin && currentItem) {
1769 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom;
1770 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster;
1771 var imageSize = lg_utils_1.default.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize);
1772 transform = lg_utils_1.default.getTransform(currentItem, this.outer, top_4, bottom, imageSize);
1773 }
1774 if (this.zoomFromOrigin && transform) {
1775 this.outer.addClass('lg-closing lg-zoom-from-image');
1776 this.getSlideItem(this.index)
1777 .addClass('lg-start-end-progress')
1778 .css('transition-duration', this.settings.startAnimationDuration + 'ms')
1779 .css('transform', transform);
1780 }
1781 else {
1782 this.outer.addClass('lg-hide-items');
1783 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true
1784 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts
1785 this.outer.removeClass('lg-zoom-from-image');
1786 }
1787 // Unbind all events added by lightGallery
1788 // @todo
1789 //this.$el.off('.lg.tm');
1790 this.destroyModules();
1791 this.lGalleryOn = false;
1792 this.isDummyImageRemoved = false;
1793 this.zoomFromOrigin = this.settings.zoomFromOrigin;
1794 clearTimeout(this.hideBarTimeout);
1795 this.hideBarTimeout = false;
1796 lgQuery_1.$LG('html').removeClass('lg-on');
1797 this.outer.removeClass('lg-visible lg-components-open');
1798 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity.
1799 this.$backdrop.removeClass('in').css('opacity', 0);
1800 var removeTimeout = this.zoomFromOrigin && transform
1801 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration)
1802 : this.settings.backdropDuration;
1803 this.$container.removeClass('lg-show-in');
1804 // Once the closign animation is completed and gallery is invisible
1805 setTimeout(function () {
1806 if (_this.zoomFromOrigin && transform) {
1807 _this.outer.removeClass('lg-zoom-from-image');
1808 }
1809 _this.$container.removeClass('lg-show');
1810 // Reset scrollbar
1811 _this.resetScrollBar();
1812 // Need to remove inline opacity as it is used in the stylesheet as well
1813 _this.$backdrop
1814 .removeAttr('style')
1815 .css('transition-duration', _this.settings.backdropDuration + 'ms');
1816 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
1817 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress');
1818 _this.$inner.empty();
1819 if (_this.lgOpened) {
1820 _this.LGel.trigger(lg_events_1.lGEvents.afterClose, {
1821 instance: _this,
1822 });
1823 }
1824 if (_this.$container.get()) {
1825 _this.$container.get().blur();
1826 }
1827 _this.lgOpened = false;
1828 }, removeTimeout + 100);
1829 return removeTimeout + 100;
1830 };
1831 LightGallery.prototype.initModules = function () {
1832 this.plugins.forEach(function (module) {
1833 try {
1834 module.init();
1835 }
1836 catch (err) {
1837 console.warn("lightGallery:- make sure lightGallery module is properly initiated");
1838 }
1839 });
1840 };
1841 LightGallery.prototype.destroyModules = function (destroy) {
1842 this.plugins.forEach(function (module) {
1843 try {
1844 if (destroy) {
1845 module.destroy();
1846 }
1847 else {
1848 module.closeGallery && module.closeGallery();
1849 }
1850 }
1851 catch (err) {
1852 console.warn("lightGallery:- make sure lightGallery module is properly destroyed");
1853 }
1854 });
1855 };
1856 /**
1857 * Refresh lightGallery with new set of children.
1858 *
1859 * @description This is useful to update the gallery when the child elements are changed without calling destroy method.
1860 *
1861 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery
1862 * @see <a href="/demos/dynamic-mode/">Demo</a>
1863 * @category lGPublicMethods
1864 * @example
1865 * const plugin = lightGallery();
1866 * // Delete or add children, then call
1867 * plugin.refresh();
1868 *
1869 */
1870 LightGallery.prototype.refresh = function (galleryItems) {
1871 if (!this.settings.dynamic) {
1872 this.invalidateItems();
1873 }
1874 if (galleryItems) {
1875 this.galleryItems = galleryItems;
1876 }
1877 else {
1878 this.galleryItems = this.getItems();
1879 }
1880 this.updateControls();
1881 this.openGalleryOnItemClick();
1882 this.LGel.trigger(lg_events_1.lGEvents.updateSlides);
1883 };
1884 LightGallery.prototype.updateControls = function () {
1885 this.addSlideVideoInfo(this.galleryItems);
1886 this.updateCounterTotal();
1887 this.manageSingleSlideClassName();
1888 };
1889 LightGallery.prototype.destroyGallery = function () {
1890 this.destroyModules(true);
1891 if (!this.settings.dynamic) {
1892 this.invalidateItems();
1893 }
1894 lgQuery_1.$LG(window).off(".lg.global" + this.lgId);
1895 this.LGel.off('.lg');
1896 this.$container.remove();
1897 };
1898 /**
1899 * Destroy lightGallery.
1900 * Destroy lightGallery and its plugin instances completely
1901 *
1902 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance.
1903 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed.
1904 * You can use refresh method most of the times.
1905 * @category lGPublicMethods
1906 * @example
1907 * const plugin = lightGallery();
1908 * plugin.destroy();
1909 *
1910 */
1911 LightGallery.prototype.destroy = function () {
1912 var closeTimeout = this.closeGallery(true);
1913 if (closeTimeout) {
1914 setTimeout(this.destroyGallery.bind(this), closeTimeout);
1915 }
1916 else {
1917 this.destroyGallery();
1918 }
1919 return closeTimeout;
1920 };
1921 return LightGallery;
1922}());
1923exports.LightGallery = LightGallery;
1924//# sourceMappingURL=lightgallery.js.map
\No newline at end of file