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