UNPKG

84 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">' +
759 _this.settings.strings['mediaLoadingFailed'] +
760 '</span>');
761 });
762 };
763 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) {
764 var _this = this;
765 var currentGalleryItem = this.galleryItems[index];
766 // Adding delay for video slides without poster for better performance and user experience
767 // Videos should start playing once once the gallery is completely loaded
768 var _speed = isFirstSlide &&
769 this.getSlideType(currentGalleryItem) === 'video' &&
770 !currentGalleryItem.poster
771 ? speed
772 : 0;
773 setTimeout(function () {
774 $currentSlide.addClass('lg-complete lg-complete_');
775 _this.LGel.trigger(lg_events_1.lGEvents.slideItemLoad, {
776 index: index,
777 delay: delay || 0,
778 isFirstSlide: isFirstSlide,
779 });
780 }, _speed);
781 };
782 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () {
783 return !!(!this.lGalleryOn &&
784 this.zoomFromOrigin &&
785 this.currentImageSize);
786 };
787 // Add video slideInfo
788 LightGallery.prototype.addSlideVideoInfo = function (items) {
789 var _this = this;
790 items.forEach(function (element, index) {
791 element.__slideVideoInfo = lg_utils_1.default.isVideo(element.src, !!element.video, index);
792 if (element.__slideVideoInfo &&
793 _this.settings.loadYouTubePoster &&
794 !element.poster &&
795 element.__slideVideoInfo.youtube) {
796 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg";
797 }
798 });
799 };
800 /**
801 * Load slide content into slide.
802 * This is used to load content into slides that is not visible too
803 * @param {Number} index - index of the slide.
804 * @param {Boolean} rec - if true call loadcontent() function again.
805 */
806 LightGallery.prototype.loadContent = function (index, rec) {
807 var _this = this;
808 var currentGalleryItem = this.galleryItems[index];
809 var $currentSlide = lgQuery_1.$LG(this.getSlideItemId(index));
810 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;
811 var src = currentGalleryItem.src;
812 var video = currentGalleryItem.video;
813 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video;
814 if (currentGalleryItem.responsive) {
815 var srcDyItms = currentGalleryItem.responsive.split(',');
816 src = lg_utils_1.default.getResponsiveSrc(srcDyItms) || src;
817 }
818 var videoInfo = currentGalleryItem.__slideVideoInfo;
819 var lgVideoStyle = '';
820 var iframe = !!currentGalleryItem.iframe;
821 var isFirstSlide = !this.lGalleryOn;
822 // delay for adding complete class. it is 0 except first time.
823 var delay = 0;
824 if (isFirstSlide) {
825 if (this.zoomFromOrigin && this.currentImageSize) {
826 delay = this.settings.startAnimationDuration + 10;
827 }
828 else {
829 delay = this.settings.backdropDuration + 10;
830 }
831 }
832 if (!$currentSlide.hasClass('lg-loaded')) {
833 if (videoInfo) {
834 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom;
835 var videoSize = lg_utils_1.default.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize);
836 lgVideoStyle = this.getVideoContStyle(videoSize);
837 }
838 if (iframe) {
839 var markup = lg_utils_1.default.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle);
840 $currentSlide.prepend(markup);
841 }
842 else if (poster) {
843 var dummyImg = '';
844 var hasStartAnimation = isFirstSlide &&
845 this.zoomFromOrigin &&
846 this.currentImageSize;
847 if (hasStartAnimation) {
848 dummyImg = this.getDummyImageContent($currentSlide, index, '');
849 }
850 var markup = lg_utils_1.default.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo);
851 $currentSlide.prepend(markup);
852 }
853 else if (videoInfo) {
854 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>";
855 $currentSlide.prepend(markup);
856 }
857 else {
858 this.setImgMarkup(src, $currentSlide, index);
859 if (srcset || sources) {
860 var $img = $currentSlide.find('.lg-object');
861 this.initPictureFill($img);
862 }
863 }
864 if (poster || videoInfo) {
865 this.LGel.trigger(lg_events_1.lGEvents.hasVideo, {
866 index: index,
867 src: src,
868 html5Video: _html5Video,
869 hasPoster: !!poster,
870 });
871 }
872 this.LGel.trigger(lg_events_1.lGEvents.afterAppendSlide, { index: index });
873 if (this.lGalleryOn &&
874 this.settings.appendSubHtmlTo === '.lg-item') {
875 this.addHtml(index);
876 }
877 }
878 // For first time add some delay for displaying the start animation.
879 var _speed = 0;
880 // Do not change the delay value because it is required for zoom plugin.
881 // If gallery opened from direct url (hash) speed value should be 0
882 if (delay && !lgQuery_1.$LG(document.body).hasClass('lg-from-hash')) {
883 _speed = delay;
884 }
885 // Only for first slide and zoomFromOrigin is enabled
886 if (this.isFirstSlideWithZoomAnimation()) {
887 setTimeout(function () {
888 $currentSlide
889 .removeClass('lg-start-end-progress lg-start-progress')
890 .removeAttr('style');
891 }, this.settings.startAnimationDuration + 100);
892 if (!$currentSlide.hasClass('lg-loaded')) {
893 setTimeout(function () {
894 if (_this.getSlideType(currentGalleryItem) === 'image') {
895 var alt = currentGalleryItem.alt;
896 var altAttr = alt ? 'alt="' + alt + '"' : '';
897 $currentSlide
898 .find('.lg-img-wrap')
899 .append(lg_utils_1.default.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources));
900 if (srcset || sources) {
901 var $img = $currentSlide.find('.lg-object');
902 _this.initPictureFill($img);
903 }
904 }
905 if (_this.getSlideType(currentGalleryItem) === 'image' ||
906 (_this.getSlideType(currentGalleryItem) === 'video' &&
907 poster)) {
908 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false);
909 // load remaining slides once the slide is completely loaded
910 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () {
911 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
912 }, function () {
913 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
914 });
915 }
916 }, this.settings.startAnimationDuration + 100);
917 }
918 }
919 // SLide content has been added to dom
920 $currentSlide.addClass('lg-loaded');
921 if (!this.isFirstSlideWithZoomAnimation() ||
922 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) {
923 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster));
924 }
925 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling
926 if ((!this.zoomFromOrigin || !this.currentImageSize) &&
927 $currentSlide.hasClass('lg-complete_') &&
928 !this.lGalleryOn) {
929 setTimeout(function () {
930 $currentSlide.addClass('lg-complete');
931 }, this.settings.backdropDuration);
932 }
933 // Content loaded
934 // Need to set lGalleryOn before calling preload function
935 this.lGalleryOn = true;
936 if (rec === true) {
937 if (!$currentSlide.hasClass('lg-complete_')) {
938 $currentSlide
939 .find('.lg-object')
940 .first()
941 .on('load.lg error.lg', function () {
942 _this.preload(index);
943 });
944 }
945 else {
946 this.preload(index);
947 }
948 }
949 };
950 /**
951 * @desc Remove dummy image content and load next slides
952 * Called only for the first time if zoomFromOrigin animation is enabled
953 * @param index
954 * @param $currentSlide
955 * @param speed
956 */
957 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) {
958 var _this = this;
959 setTimeout(function () {
960 $currentSlide.find('.lg-dummy-img').remove();
961 $currentSlide.removeClass('lg-first-slide');
962 _this.outer.removeClass('lg-first-slide-loading');
963 _this.isDummyImageRemoved = true;
964 _this.preload(index);
965 }, speed + 300);
966 };
967 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) {
968 var _this = this;
969 if (numberOfItems === void 0) { numberOfItems = 0; }
970 var itemsToBeInsertedToDom = [];
971 // Minimum 2 items should be there
972 var possibleNumberOfItems = Math.max(numberOfItems, 3);
973 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length);
974 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex;
975 if (this.galleryItems.length <= 3) {
976 this.galleryItems.forEach(function (_element, index) {
977 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index);
978 });
979 return itemsToBeInsertedToDom;
980 }
981 if (index < (this.galleryItems.length - 1) / 2) {
982 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) {
983 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
984 }
985 var numberOfExistingItems = itemsToBeInsertedToDom.length;
986 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
987 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1));
988 }
989 }
990 else {
991 for (var idx = index; idx <= this.galleryItems.length - 1 &&
992 idx < index + possibleNumberOfItems / 2; idx++) {
993 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
994 }
995 var numberOfExistingItems = itemsToBeInsertedToDom.length;
996 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
997 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1));
998 }
999 }
1000 if (this.settings.loop) {
1001 if (index === this.galleryItems.length - 1) {
1002 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0);
1003 }
1004 else if (index === 0) {
1005 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1));
1006 }
1007 }
1008 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) {
1009 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex);
1010 }
1011 return itemsToBeInsertedToDom;
1012 };
1013 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) {
1014 var _this = this;
1015 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom);
1016 itemsToBeInsertedToDom.forEach(function (item) {
1017 if (_this.currentItemsInDom.indexOf(item) === -1) {
1018 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>");
1019 }
1020 });
1021 this.currentItemsInDom.forEach(function (item) {
1022 if (itemsToBeInsertedToDom.indexOf(item) === -1) {
1023 lgQuery_1.$LG("#" + item).remove();
1024 }
1025 });
1026 return itemsToBeInsertedToDom;
1027 };
1028 /**
1029 * Get previous index of the slide
1030 */
1031 LightGallery.prototype.getPreviousSlideIndex = function () {
1032 var prevIndex = 0;
1033 try {
1034 var currentItemId = this.outer
1035 .find('.lg-current')
1036 .first()
1037 .attr('id');
1038 prevIndex = parseInt(currentItemId.split('-')[3]) || 0;
1039 }
1040 catch (error) {
1041 prevIndex = 0;
1042 }
1043 return prevIndex;
1044 };
1045 LightGallery.prototype.setDownloadValue = function (index) {
1046 if (this.settings.download) {
1047 var currentGalleryItem = this.galleryItems[index];
1048 var hideDownloadBtn = currentGalleryItem.downloadUrl === false ||
1049 currentGalleryItem.downloadUrl === 'false';
1050 if (hideDownloadBtn) {
1051 this.outer.addClass('lg-hide-download');
1052 }
1053 else {
1054 var $download = this.getElementById('lg-download');
1055 this.outer.removeClass('lg-hide-download');
1056 $download.attr('href', currentGalleryItem.downloadUrl ||
1057 currentGalleryItem.src);
1058 if (currentGalleryItem.download) {
1059 $download.attr('download', currentGalleryItem.download);
1060 }
1061 }
1062 }
1063 };
1064 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) {
1065 var _this = this;
1066 if (this.lGalleryOn) {
1067 previousSlideItem.addClass('lg-slide-progress');
1068 }
1069 setTimeout(function () {
1070 // remove all transitions
1071 _this.outer.addClass('lg-no-trans');
1072 _this.outer
1073 .find('.lg-item')
1074 .removeClass('lg-prev-slide lg-next-slide');
1075 if (direction === 'prev') {
1076 //prevslide
1077 currentSlideItem.addClass('lg-prev-slide');
1078 previousSlideItem.addClass('lg-next-slide');
1079 }
1080 else {
1081 // next slide
1082 currentSlideItem.addClass('lg-next-slide');
1083 previousSlideItem.addClass('lg-prev-slide');
1084 }
1085 // give 50 ms for browser to add/remove class
1086 setTimeout(function () {
1087 _this.outer.find('.lg-item').removeClass('lg-current');
1088 currentSlideItem.addClass('lg-current');
1089 // reset all transitions
1090 _this.outer.removeClass('lg-no-trans');
1091 }, 50);
1092 }, this.lGalleryOn ? this.settings.slideDelay : 0);
1093 };
1094 /**
1095 * Goto a specific slide.
1096 * @param {Number} index - index of the slide
1097 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag
1098 * @param {Boolean} fromThumb - true if slide function called via thumbnail click
1099 * @param {String} direction - Direction of the slide(next/prev)
1100 * @category lGPublicMethods
1101 * @example
1102 * const plugin = lightGallery();
1103 * // to go to 3rd slide
1104 * plugin.slide(2);
1105 *
1106 */
1107 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) {
1108 var _this = this;
1109 var prevIndex = this.getPreviousSlideIndex();
1110 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex);
1111 // Prevent multiple call, Required for hsh plugin
1112 if (this.lGalleryOn && prevIndex === index) {
1113 return;
1114 }
1115 var numberOfGalleryItems = this.galleryItems.length;
1116 if (!this.lgBusy) {
1117 if (this.settings.counter) {
1118 this.updateCurrentCounter(index);
1119 }
1120 var currentSlideItem = this.getSlideItem(index);
1121 var previousSlideItem_1 = this.getSlideItem(prevIndex);
1122 var currentGalleryItem = this.galleryItems[index];
1123 var videoInfo = currentGalleryItem.__slideVideoInfo;
1124 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem));
1125 this.setDownloadValue(index);
1126 if (videoInfo) {
1127 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom;
1128 var videoSize = lg_utils_1.default.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize);
1129 this.resizeVideoSlide(index, videoSize);
1130 }
1131 this.LGel.trigger(lg_events_1.lGEvents.beforeSlide, {
1132 prevIndex: prevIndex,
1133 index: index,
1134 fromTouch: !!fromTouch,
1135 fromThumb: !!fromThumb,
1136 });
1137 this.lgBusy = true;
1138 clearTimeout(this.hideBarTimeout);
1139 this.arrowDisable(index);
1140 if (!direction) {
1141 if (index < prevIndex) {
1142 direction = 'prev';
1143 }
1144 else if (index > prevIndex) {
1145 direction = 'next';
1146 }
1147 }
1148 if (!fromTouch) {
1149 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1);
1150 }
1151 else {
1152 this.outer
1153 .find('.lg-item')
1154 .removeClass('lg-prev-slide lg-current lg-next-slide');
1155 var touchPrev = void 0;
1156 var touchNext = void 0;
1157 if (numberOfGalleryItems > 2) {
1158 touchPrev = index - 1;
1159 touchNext = index + 1;
1160 if (index === 0 && prevIndex === numberOfGalleryItems - 1) {
1161 // next slide
1162 touchNext = 0;
1163 touchPrev = numberOfGalleryItems - 1;
1164 }
1165 else if (index === numberOfGalleryItems - 1 &&
1166 prevIndex === 0) {
1167 // prev slide
1168 touchNext = 0;
1169 touchPrev = numberOfGalleryItems - 1;
1170 }
1171 }
1172 else {
1173 touchPrev = 0;
1174 touchNext = 1;
1175 }
1176 if (direction === 'prev') {
1177 this.getSlideItem(touchNext).addClass('lg-next-slide');
1178 }
1179 else {
1180 this.getSlideItem(touchPrev).addClass('lg-prev-slide');
1181 }
1182 currentSlideItem.addClass('lg-current');
1183 }
1184 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened
1185 if (!this.lGalleryOn) {
1186 this.loadContent(index, true);
1187 }
1188 else {
1189 setTimeout(function () {
1190 _this.loadContent(index, true);
1191 // Add title if this.settings.appendSubHtmlTo === lg-sub-html
1192 if (_this.settings.appendSubHtmlTo !== '.lg-item') {
1193 _this.addHtml(index);
1194 }
1195 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay));
1196 }
1197 setTimeout(function () {
1198 _this.lgBusy = false;
1199 previousSlideItem_1.removeClass('lg-slide-progress');
1200 _this.LGel.trigger(lg_events_1.lGEvents.afterSlide, {
1201 prevIndex: prevIndex,
1202 index: index,
1203 fromTouch: fromTouch,
1204 fromThumb: fromThumb,
1205 });
1206 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay));
1207 }
1208 this.index = index;
1209 };
1210 LightGallery.prototype.updateCurrentCounter = function (index) {
1211 this.getElementById('lg-counter-current').html(index + 1 + '');
1212 };
1213 LightGallery.prototype.updateCounterTotal = function () {
1214 this.getElementById('lg-counter-all').html(this.galleryItems.length + '');
1215 };
1216 LightGallery.prototype.getSlideType = function (item) {
1217 if (item.__slideVideoInfo) {
1218 return 'video';
1219 }
1220 else if (item.iframe) {
1221 return 'iframe';
1222 }
1223 else {
1224 return 'image';
1225 }
1226 };
1227 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) {
1228 var distanceX = endCoords.pageX - startCoords.pageX;
1229 var distanceY = endCoords.pageY - startCoords.pageY;
1230 var allowSwipe = false;
1231 if (this.swipeDirection) {
1232 allowSwipe = true;
1233 }
1234 else {
1235 if (Math.abs(distanceX) > 15) {
1236 this.swipeDirection = 'horizontal';
1237 allowSwipe = true;
1238 }
1239 else if (Math.abs(distanceY) > 15) {
1240 this.swipeDirection = 'vertical';
1241 allowSwipe = true;
1242 }
1243 }
1244 if (!allowSwipe) {
1245 return;
1246 }
1247 var $currentSlide = this.getSlideItem(this.index);
1248 if (this.swipeDirection === 'horizontal') {
1249 e === null || e === void 0 ? void 0 : e.preventDefault();
1250 // reset opacity and transition duration
1251 this.outer.addClass('lg-dragging');
1252 // move current slide
1253 this.setTranslate($currentSlide, distanceX, 0);
1254 // move next and prev slide with current slide
1255 var width = $currentSlide.get().offsetWidth;
1256 var slideWidthAmount = (width * 15) / 100;
1257 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100);
1258 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0);
1259 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0);
1260 }
1261 else if (this.swipeDirection === 'vertical') {
1262 if (this.settings.swipeToClose) {
1263 e === null || e === void 0 ? void 0 : e.preventDefault();
1264 this.$container.addClass('lg-dragging-vertical');
1265 var opacity = 1 - Math.abs(distanceY) / window.innerHeight;
1266 this.$backdrop.css('opacity', opacity);
1267 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2);
1268 this.setTranslate($currentSlide, 0, distanceY, scale, scale);
1269 if (Math.abs(distanceY) > 100) {
1270 this.outer
1271 .addClass('lg-hide-items')
1272 .removeClass('lg-components-open');
1273 }
1274 }
1275 }
1276 };
1277 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) {
1278 var _this = this;
1279 var distance;
1280 // keep slide animation for any mode while dragg/swipe
1281 if (this.settings.mode !== 'lg-slide') {
1282 this.outer.addClass('lg-slide');
1283 }
1284 // set transition duration
1285 setTimeout(function () {
1286 _this.$container.removeClass('lg-dragging-vertical');
1287 _this.outer
1288 .removeClass('lg-dragging lg-hide-items')
1289 .addClass('lg-components-open');
1290 var triggerClick = true;
1291 if (_this.swipeDirection === 'horizontal') {
1292 distance = endCoords.pageX - startCoords.pageX;
1293 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX);
1294 if (distance < 0 &&
1295 distanceAbs > _this.settings.swipeThreshold) {
1296 _this.goToNextSlide(true);
1297 triggerClick = false;
1298 }
1299 else if (distance > 0 &&
1300 distanceAbs > _this.settings.swipeThreshold) {
1301 _this.goToPrevSlide(true);
1302 triggerClick = false;
1303 }
1304 }
1305 else if (_this.swipeDirection === 'vertical') {
1306 distance = Math.abs(endCoords.pageY - startCoords.pageY);
1307 if (_this.settings.closable &&
1308 _this.settings.swipeToClose &&
1309 distance > 100) {
1310 _this.closeGallery();
1311 return;
1312 }
1313 else {
1314 _this.$backdrop.css('opacity', 1);
1315 }
1316 }
1317 _this.outer.find('.lg-item').removeAttr('style');
1318 if (triggerClick &&
1319 Math.abs(endCoords.pageX - startCoords.pageX) < 5) {
1320 // Trigger click if distance is less than 5 pix
1321 var target = lgQuery_1.$LG(event.target);
1322 if (_this.isPosterElement(target)) {
1323 _this.LGel.trigger(lg_events_1.lGEvents.posterClick);
1324 }
1325 }
1326 _this.swipeDirection = undefined;
1327 });
1328 // remove slide class once drag/swipe is completed if mode is not slide
1329 setTimeout(function () {
1330 if (!_this.outer.hasClass('lg-dragging') &&
1331 _this.settings.mode !== 'lg-slide') {
1332 _this.outer.removeClass('lg-slide');
1333 }
1334 }, this.settings.speed + 100);
1335 };
1336 LightGallery.prototype.enableSwipe = function () {
1337 var _this = this;
1338 var startCoords = {};
1339 var endCoords = {};
1340 var isMoved = false;
1341 var isSwiping = false;
1342 if (this.settings.enableSwipe) {
1343 this.$inner.on('touchstart.lg', function (e) {
1344 _this.dragOrSwipeEnabled = true;
1345 var $item = _this.getSlideItem(_this.index);
1346 if ((lgQuery_1.$LG(e.target).hasClass('lg-item') ||
1347 $item.get().contains(e.target)) &&
1348 !_this.outer.hasClass('lg-zoomed') &&
1349 !_this.lgBusy &&
1350 e.touches.length === 1) {
1351 isSwiping = true;
1352 _this.touchAction = 'swipe';
1353 _this.manageSwipeClass();
1354 startCoords = {
1355 pageX: e.touches[0].pageX,
1356 pageY: e.touches[0].pageY,
1357 };
1358 }
1359 });
1360 this.$inner.on('touchmove.lg', function (e) {
1361 if (isSwiping &&
1362 _this.touchAction === 'swipe' &&
1363 e.touches.length === 1) {
1364 endCoords = {
1365 pageX: e.touches[0].pageX,
1366 pageY: e.touches[0].pageY,
1367 };
1368 _this.touchMove(startCoords, endCoords, e);
1369 isMoved = true;
1370 }
1371 });
1372 this.$inner.on('touchend.lg', function (event) {
1373 if (_this.touchAction === 'swipe') {
1374 if (isMoved) {
1375 isMoved = false;
1376 _this.touchEnd(endCoords, startCoords, event);
1377 }
1378 else if (isSwiping) {
1379 var target = lgQuery_1.$LG(event.target);
1380 if (_this.isPosterElement(target)) {
1381 _this.LGel.trigger(lg_events_1.lGEvents.posterClick);
1382 }
1383 }
1384 _this.touchAction = undefined;
1385 isSwiping = false;
1386 }
1387 });
1388 }
1389 };
1390 LightGallery.prototype.enableDrag = function () {
1391 var _this = this;
1392 var startCoords = {};
1393 var endCoords = {};
1394 var isDraging = false;
1395 var isMoved = false;
1396 if (this.settings.enableDrag) {
1397 this.outer.on('mousedown.lg', function (e) {
1398 _this.dragOrSwipeEnabled = true;
1399 var $item = _this.getSlideItem(_this.index);
1400 if (lgQuery_1.$LG(e.target).hasClass('lg-item') ||
1401 $item.get().contains(e.target)) {
1402 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) {
1403 e.preventDefault();
1404 if (!_this.lgBusy) {
1405 _this.manageSwipeClass();
1406 startCoords = {
1407 pageX: e.pageX,
1408 pageY: e.pageY,
1409 };
1410 isDraging = true;
1411 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
1412 _this.outer.get().scrollLeft += 1;
1413 _this.outer.get().scrollLeft -= 1;
1414 // *
1415 _this.outer
1416 .removeClass('lg-grab')
1417 .addClass('lg-grabbing');
1418 _this.LGel.trigger(lg_events_1.lGEvents.dragStart);
1419 }
1420 }
1421 }
1422 });
1423 lgQuery_1.$LG(window).on("mousemove.lg.global" + this.lgId, function (e) {
1424 if (isDraging && _this.lgOpened) {
1425 isMoved = true;
1426 endCoords = {
1427 pageX: e.pageX,
1428 pageY: e.pageY,
1429 };
1430 _this.touchMove(startCoords, endCoords);
1431 _this.LGel.trigger(lg_events_1.lGEvents.dragMove);
1432 }
1433 });
1434 lgQuery_1.$LG(window).on("mouseup.lg.global" + this.lgId, function (event) {
1435 if (!_this.lgOpened) {
1436 return;
1437 }
1438 var target = lgQuery_1.$LG(event.target);
1439 if (isMoved) {
1440 isMoved = false;
1441 _this.touchEnd(endCoords, startCoords, event);
1442 _this.LGel.trigger(lg_events_1.lGEvents.dragEnd);
1443 }
1444 else if (_this.isPosterElement(target)) {
1445 _this.LGel.trigger(lg_events_1.lGEvents.posterClick);
1446 }
1447 // Prevent execution on click
1448 if (isDraging) {
1449 isDraging = false;
1450 _this.outer.removeClass('lg-grabbing').addClass('lg-grab');
1451 }
1452 });
1453 }
1454 };
1455 LightGallery.prototype.triggerPosterClick = function () {
1456 var _this = this;
1457 this.$inner.on('click.lg', function (event) {
1458 if (!_this.dragOrSwipeEnabled &&
1459 _this.isPosterElement(lgQuery_1.$LG(event.target))) {
1460 _this.LGel.trigger(lg_events_1.lGEvents.posterClick);
1461 }
1462 });
1463 };
1464 LightGallery.prototype.manageSwipeClass = function () {
1465 var _touchNext = this.index + 1;
1466 var _touchPrev = this.index - 1;
1467 if (this.settings.loop && this.galleryItems.length > 2) {
1468 if (this.index === 0) {
1469 _touchPrev = this.galleryItems.length - 1;
1470 }
1471 else if (this.index === this.galleryItems.length - 1) {
1472 _touchNext = 0;
1473 }
1474 }
1475 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide');
1476 if (_touchPrev > -1) {
1477 this.getSlideItem(_touchPrev).addClass('lg-prev-slide');
1478 }
1479 this.getSlideItem(_touchNext).addClass('lg-next-slide');
1480 };
1481 /**
1482 * Go to next slide
1483 * @param {Boolean} fromTouch - true if slide function called via touch event
1484 * @category lGPublicMethods
1485 * @example
1486 * const plugin = lightGallery();
1487 * plugin.goToNextSlide();
1488 * @see <a href="/demos/methods/">Demo</a>
1489 */
1490 LightGallery.prototype.goToNextSlide = function (fromTouch) {
1491 var _this = this;
1492 var _loop = this.settings.loop;
1493 if (fromTouch && this.galleryItems.length < 3) {
1494 _loop = false;
1495 }
1496 if (!this.lgBusy) {
1497 if (this.index + 1 < this.galleryItems.length) {
1498 this.index++;
1499 this.LGel.trigger(lg_events_1.lGEvents.beforeNextSlide, {
1500 index: this.index,
1501 });
1502 this.slide(this.index, !!fromTouch, false, 'next');
1503 }
1504 else {
1505 if (_loop) {
1506 this.index = 0;
1507 this.LGel.trigger(lg_events_1.lGEvents.beforeNextSlide, {
1508 index: this.index,
1509 });
1510 this.slide(this.index, !!fromTouch, false, 'next');
1511 }
1512 else if (this.settings.slideEndAnimation && !fromTouch) {
1513 this.outer.addClass('lg-right-end');
1514 setTimeout(function () {
1515 _this.outer.removeClass('lg-right-end');
1516 }, 400);
1517 }
1518 }
1519 }
1520 };
1521 /**
1522 * Go to previous slides
1523 * @param {Boolean} fromTouch - true if slide function called via touch event
1524 * @category lGPublicMethods
1525 * @example
1526 * const plugin = lightGallery({});
1527 * plugin.goToPrevSlide();
1528 * @see <a href="/demos/methods/">Demo</a>
1529 *
1530 */
1531 LightGallery.prototype.goToPrevSlide = function (fromTouch) {
1532 var _this = this;
1533 var _loop = this.settings.loop;
1534 if (fromTouch && this.galleryItems.length < 3) {
1535 _loop = false;
1536 }
1537 if (!this.lgBusy) {
1538 if (this.index > 0) {
1539 this.index--;
1540 this.LGel.trigger(lg_events_1.lGEvents.beforePrevSlide, {
1541 index: this.index,
1542 fromTouch: fromTouch,
1543 });
1544 this.slide(this.index, !!fromTouch, false, 'prev');
1545 }
1546 else {
1547 if (_loop) {
1548 this.index = this.galleryItems.length - 1;
1549 this.LGel.trigger(lg_events_1.lGEvents.beforePrevSlide, {
1550 index: this.index,
1551 fromTouch: fromTouch,
1552 });
1553 this.slide(this.index, !!fromTouch, false, 'prev');
1554 }
1555 else if (this.settings.slideEndAnimation && !fromTouch) {
1556 this.outer.addClass('lg-left-end');
1557 setTimeout(function () {
1558 _this.outer.removeClass('lg-left-end');
1559 }, 400);
1560 }
1561 }
1562 }
1563 };
1564 LightGallery.prototype.keyPress = function () {
1565 var _this = this;
1566 lgQuery_1.$LG(window).on("keydown.lg.global" + this.lgId, function (e) {
1567 if (_this.lgOpened &&
1568 _this.settings.escKey === true &&
1569 e.keyCode === 27) {
1570 e.preventDefault();
1571 if (_this.settings.allowMediaOverlap &&
1572 _this.outer.hasClass('lg-can-toggle') &&
1573 _this.outer.hasClass('lg-components-open')) {
1574 _this.outer.removeClass('lg-components-open');
1575 }
1576 else {
1577 _this.closeGallery();
1578 }
1579 }
1580 if (_this.lgOpened && _this.galleryItems.length > 1) {
1581 if (e.keyCode === 37) {
1582 e.preventDefault();
1583 _this.goToPrevSlide();
1584 }
1585 if (e.keyCode === 39) {
1586 e.preventDefault();
1587 _this.goToNextSlide();
1588 }
1589 }
1590 });
1591 };
1592 LightGallery.prototype.arrow = function () {
1593 var _this = this;
1594 this.getElementById('lg-prev').on('click.lg', function () {
1595 _this.goToPrevSlide();
1596 });
1597 this.getElementById('lg-next').on('click.lg', function () {
1598 _this.goToNextSlide();
1599 });
1600 };
1601 LightGallery.prototype.arrowDisable = function (index) {
1602 // Disable arrows if settings.hideControlOnEnd is true
1603 if (!this.settings.loop && this.settings.hideControlOnEnd) {
1604 var $prev = this.getElementById('lg-prev');
1605 var $next = this.getElementById('lg-next');
1606 if (index + 1 === this.galleryItems.length) {
1607 $next.attr('disabled', 'disabled').addClass('disabled');
1608 }
1609 else {
1610 $next.removeAttr('disabled').removeClass('disabled');
1611 }
1612 if (index === 0) {
1613 $prev.attr('disabled', 'disabled').addClass('disabled');
1614 }
1615 else {
1616 $prev.removeAttr('disabled').removeClass('disabled');
1617 }
1618 }
1619 };
1620 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) {
1621 if (scaleX === void 0) { scaleX = 1; }
1622 if (scaleY === void 0) { scaleY = 1; }
1623 $el.css('transform', 'translate3d(' +
1624 xValue +
1625 'px, ' +
1626 yValue +
1627 'px, 0px) scale3d(' +
1628 scaleX +
1629 ', ' +
1630 scaleY +
1631 ', 1)');
1632 };
1633 LightGallery.prototype.mousewheel = function () {
1634 var _this = this;
1635 var lastCall = 0;
1636 this.outer.on('wheel.lg', function (e) {
1637 if (!e.deltaY || _this.galleryItems.length < 2) {
1638 return;
1639 }
1640 e.preventDefault();
1641 var now = new Date().getTime();
1642 if (now - lastCall < 1000) {
1643 return;
1644 }
1645 lastCall = now;
1646 if (e.deltaY > 0) {
1647 _this.goToNextSlide();
1648 }
1649 else if (e.deltaY < 0) {
1650 _this.goToPrevSlide();
1651 }
1652 });
1653 };
1654 LightGallery.prototype.isSlideElement = function (target) {
1655 return (target.hasClass('lg-outer') ||
1656 target.hasClass('lg-item') ||
1657 target.hasClass('lg-img-wrap'));
1658 };
1659 LightGallery.prototype.isPosterElement = function (target) {
1660 var playButton = this.getSlideItem(this.index)
1661 .find('.lg-video-play-button')
1662 .get();
1663 return (target.hasClass('lg-video-poster') ||
1664 target.hasClass('lg-video-play-button') ||
1665 (playButton && playButton.contains(target.get())));
1666 };
1667 /**
1668 * Maximize minimize inline gallery.
1669 * @category lGPublicMethods
1670 */
1671 LightGallery.prototype.toggleMaximize = function () {
1672 var _this = this;
1673 this.getElementById('lg-maximize').on('click.lg', function () {
1674 _this.$container.toggleClass('lg-inline');
1675 _this.refreshOnResize();
1676 });
1677 };
1678 LightGallery.prototype.invalidateItems = function () {
1679 for (var index = 0; index < this.items.length; index++) {
1680 var element = this.items[index];
1681 var $element = lgQuery_1.$LG(element);
1682 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id'));
1683 }
1684 };
1685 LightGallery.prototype.trapFocus = function () {
1686 var _this = this;
1687 this.$container.get().focus({
1688 preventScroll: true,
1689 });
1690 lgQuery_1.$LG(window).on("keydown.lg.global" + this.lgId, function (e) {
1691 if (!_this.lgOpened) {
1692 return;
1693 }
1694 var isTabPressed = e.key === 'Tab' || e.keyCode === 9;
1695 if (!isTabPressed) {
1696 return;
1697 }
1698 var focusableEls = lg_utils_1.default.getFocusableElements(_this.$container.get());
1699 var firstFocusableEl = focusableEls[0];
1700 var lastFocusableEl = focusableEls[focusableEls.length - 1];
1701 if (e.shiftKey) {
1702 if (document.activeElement === firstFocusableEl) {
1703 lastFocusableEl.focus();
1704 e.preventDefault();
1705 }
1706 }
1707 else {
1708 if (document.activeElement === lastFocusableEl) {
1709 firstFocusableEl.focus();
1710 e.preventDefault();
1711 }
1712 }
1713 });
1714 };
1715 LightGallery.prototype.manageCloseGallery = function () {
1716 var _this = this;
1717 if (!this.settings.closable)
1718 return;
1719 var mousedown = false;
1720 this.getElementById('lg-close').on('click.lg', function () {
1721 _this.closeGallery();
1722 });
1723 if (this.settings.closeOnTap) {
1724 // If you drag the slide and release outside gallery gets close on chrome
1725 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer
1726 this.outer.on('mousedown.lg', function (e) {
1727 var target = lgQuery_1.$LG(e.target);
1728 if (_this.isSlideElement(target)) {
1729 mousedown = true;
1730 }
1731 else {
1732 mousedown = false;
1733 }
1734 });
1735 this.outer.on('mousemove.lg', function () {
1736 mousedown = false;
1737 });
1738 this.outer.on('mouseup.lg', function (e) {
1739 var target = lgQuery_1.$LG(e.target);
1740 if (_this.isSlideElement(target) && mousedown) {
1741 if (!_this.outer.hasClass('lg-dragging')) {
1742 _this.closeGallery();
1743 }
1744 }
1745 });
1746 }
1747 };
1748 /**
1749 * Close lightGallery if it is opened.
1750 *
1751 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery
1752 * @return returns the estimated time to close gallery completely including the close animation duration
1753 * @category lGPublicMethods
1754 * @example
1755 * const plugin = lightGallery();
1756 * plugin.closeGallery();
1757 *
1758 */
1759 LightGallery.prototype.closeGallery = function (force) {
1760 var _this = this;
1761 if (!this.lgOpened || (!this.settings.closable && !force)) {
1762 return 0;
1763 }
1764 this.LGel.trigger(lg_events_1.lGEvents.beforeClose);
1765 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) {
1766 lgQuery_1.$LG(window).scrollTop(this.prevScrollTop);
1767 }
1768 var currentItem = this.items[this.index];
1769 var transform;
1770 if (this.zoomFromOrigin && currentItem) {
1771 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom;
1772 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster;
1773 var imageSize = lg_utils_1.default.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize);
1774 transform = lg_utils_1.default.getTransform(currentItem, this.outer, top_4, bottom, imageSize);
1775 }
1776 if (this.zoomFromOrigin && transform) {
1777 this.outer.addClass('lg-closing lg-zoom-from-image');
1778 this.getSlideItem(this.index)
1779 .addClass('lg-start-end-progress')
1780 .css('transition-duration', this.settings.startAnimationDuration + 'ms')
1781 .css('transform', transform);
1782 }
1783 else {
1784 this.outer.addClass('lg-hide-items');
1785 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true
1786 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts
1787 this.outer.removeClass('lg-zoom-from-image');
1788 }
1789 // Unbind all events added by lightGallery
1790 // @todo
1791 //this.$el.off('.lg.tm');
1792 this.destroyModules();
1793 this.lGalleryOn = false;
1794 this.isDummyImageRemoved = false;
1795 this.zoomFromOrigin = this.settings.zoomFromOrigin;
1796 clearTimeout(this.hideBarTimeout);
1797 this.hideBarTimeout = false;
1798 lgQuery_1.$LG('html').removeClass('lg-on');
1799 this.outer.removeClass('lg-visible lg-components-open');
1800 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity.
1801 this.$backdrop.removeClass('in').css('opacity', 0);
1802 var removeTimeout = this.zoomFromOrigin && transform
1803 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration)
1804 : this.settings.backdropDuration;
1805 this.$container.removeClass('lg-show-in');
1806 // Once the closign animation is completed and gallery is invisible
1807 setTimeout(function () {
1808 if (_this.zoomFromOrigin && transform) {
1809 _this.outer.removeClass('lg-zoom-from-image');
1810 }
1811 _this.$container.removeClass('lg-show');
1812 // Reset scrollbar
1813 _this.resetScrollBar();
1814 // Need to remove inline opacity as it is used in the stylesheet as well
1815 _this.$backdrop
1816 .removeAttr('style')
1817 .css('transition-duration', _this.settings.backdropDuration + 'ms');
1818 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
1819 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress');
1820 _this.$inner.empty();
1821 if (_this.lgOpened) {
1822 _this.LGel.trigger(lg_events_1.lGEvents.afterClose, {
1823 instance: _this,
1824 });
1825 }
1826 if (_this.$container.get()) {
1827 _this.$container.get().blur();
1828 }
1829 _this.lgOpened = false;
1830 }, removeTimeout + 100);
1831 return removeTimeout + 100;
1832 };
1833 LightGallery.prototype.initModules = function () {
1834 this.plugins.forEach(function (module) {
1835 try {
1836 module.init();
1837 }
1838 catch (err) {
1839 console.warn("lightGallery:- make sure lightGallery module is properly initiated");
1840 }
1841 });
1842 };
1843 LightGallery.prototype.destroyModules = function (destroy) {
1844 this.plugins.forEach(function (module) {
1845 try {
1846 if (destroy) {
1847 module.destroy();
1848 }
1849 else {
1850 module.closeGallery && module.closeGallery();
1851 }
1852 }
1853 catch (err) {
1854 console.warn("lightGallery:- make sure lightGallery module is properly destroyed");
1855 }
1856 });
1857 };
1858 /**
1859 * Refresh lightGallery with new set of children.
1860 *
1861 * @description This is useful to update the gallery when the child elements are changed without calling destroy method.
1862 *
1863 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery
1864 * @see <a href="/demos/dynamic-mode/">Demo</a>
1865 * @category lGPublicMethods
1866 * @example
1867 * const plugin = lightGallery();
1868 * // Delete or add children, then call
1869 * plugin.refresh();
1870 *
1871 */
1872 LightGallery.prototype.refresh = function (galleryItems) {
1873 if (!this.settings.dynamic) {
1874 this.invalidateItems();
1875 }
1876 if (galleryItems) {
1877 this.galleryItems = galleryItems;
1878 }
1879 else {
1880 this.galleryItems = this.getItems();
1881 }
1882 this.updateControls();
1883 this.openGalleryOnItemClick();
1884 this.LGel.trigger(lg_events_1.lGEvents.updateSlides);
1885 };
1886 LightGallery.prototype.updateControls = function () {
1887 this.addSlideVideoInfo(this.galleryItems);
1888 this.updateCounterTotal();
1889 this.manageSingleSlideClassName();
1890 };
1891 LightGallery.prototype.destroyGallery = function () {
1892 this.destroyModules(true);
1893 if (!this.settings.dynamic) {
1894 this.invalidateItems();
1895 }
1896 lgQuery_1.$LG(window).off(".lg.global" + this.lgId);
1897 this.LGel.off('.lg');
1898 this.$container.remove();
1899 };
1900 /**
1901 * Destroy lightGallery.
1902 * Destroy lightGallery and its plugin instances completely
1903 *
1904 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance.
1905 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed.
1906 * You can use refresh method most of the times.
1907 * @category lGPublicMethods
1908 * @example
1909 * const plugin = lightGallery();
1910 * plugin.destroy();
1911 *
1912 */
1913 LightGallery.prototype.destroy = function () {
1914 var closeTimeout = this.closeGallery(true);
1915 if (closeTimeout) {
1916 setTimeout(this.destroyGallery.bind(this), closeTimeout);
1917 }
1918 else {
1919 this.destroyGallery();
1920 }
1921 return closeTimeout;
1922 };
1923 return LightGallery;
1924}());
1925exports.LightGallery = LightGallery;
1926//# sourceMappingURL=lightgallery.js.map
\No newline at end of file