PageSourceSearch

https://prensa.unicach.mx/plugins/lightgallery/js/lightgallery.js

js unicach.mx collected 2026-09-24 09:47:36 UTC 44,527 bytes, 1,361 lines download raw bytes

1/*! lightgallery - v1.6.12 - 2019-02-19
2* http://sachinchoolur.github.io/lightGallery/
3* Copyright (c) 2019 Sachin N; Licensed GPLv3 */
4(function (root, factory) {
5  if (typeof define === 'function' && define.amd) {
6    // AMD. Register as an anonymous module unless amdModuleId is set
7    define(['jquery'], function (a0) {
8      return (factory(a0));
9    });
10  } else if (typeof module === 'object' && module.exports) {
11    // Node. Does not work with strict CommonJS, but
12    // only CommonJS-like environments that support module.exports,
13    // like Node.
14    module.exports = factory(require('jquery'));
15  } else {
16    factory(root["jQuery"]);
17  }
18}(this, function ($) {
19
20(function() {
21    'use strict';
22
23    var defaults = {
24
25        mode: 'lg-slide',
26
27        // Ex : 'ease'
28        cssEasing: 'ease',
29
30        //'for jquery animation'
31        easing: 'linear',
32        speed: 600,
33        height: '100%',
34        width: '100%',
35        addClass: '',
36        startClass: 'lg-start-zoom',
37        backdropDuration: 150,
38        hideBarsDelay: 6000,
39
40        useLeft: false,
41
42        closable: true,
43        loop: true,
44        escKey: true,
45        keyPress: true,
46        controls: true,
47        slideEndAnimatoin: true,
48        hideControlOnEnd: false,
49        mousewheel: true,
50
51        getCaptionFromTitleOrAlt: true,
52
53        // .lg-item || '.lg-sub-html'
54        appendSubHtmlTo: '.lg-sub-html',
55
56        subHtmlSelectorRelative: false,
57
58        /**
59         * @desc number of preload slides
60         * will exicute only after the current slide is fully loaded.
61         *
62         * @ex you clicked on 4th image and if preload = 1 then 3rd slide and 5th
63         * slide will be loaded in the background after the 4th slide is fully loaded..
64         * if preload is 2 then 2nd 3rd 5th 6th slides will be preloaded.. ... ...
65         *
66         */
67        preload: 1,
68        showAfterLoad: true,
69        selector: '',
70        selectWithin: '',
71        nextHtml: '',
72        prevHtml: '',
73
74        // 0, 1
75        index: false,
76
77        iframeMaxWidth: '100%',
78
79        download: true,
80        counter: true,
81        appendCounterTo: '.lg-toolbar',
82
83        swipeThreshold: 50,
84        enableSwipe: true,
85        enableDrag: true,
86
87        dynamic: false,
88        dynamicEl: [],
89        galleryId: 1
90    };
91
92    function Plugin(element, options) {
93
94        // Current lightGallery element
95        this.el = element;
96
97        // Current jquery element
98        this.$el = $(element);
99
100        // lightGallery settings
101        this.s = $.extend({}, defaults, options);
102
103        // When using dynamic mode, ensure dynamicEl is an array
104        if (this.s.dynamic && this.s.dynamicEl !== 'undefined' && this.s.dynamicEl.constructor === Array && !this.s.dynamicEl.length) {
105            throw ('When using dynamic mode, you must also define dynamicEl as an Array.');
106        }
107
108        // lightGallery modules
109        this.modules = {};
110
111        // false when lightgallery complete first slide;
112        this.lGalleryOn = false;
113
114        this.lgBusy = false;
115
116        // Timeout function for hiding controls;
117        this.hideBartimeout = false;
118
119        // To determine browser supports for touch events;
120        this.isTouch = ('ontouchstart' in document.documentElement);
121
122        // Disable hideControlOnEnd if sildeEndAnimation is true
123        if (this.s.slideEndAnimatoin) {
124            this.s.hideControlOnEnd = false;
125        }
126
127        // Gallery items
128        if (this.s.dynamic) {
129            this.$items = this.s.dynamicEl;
130        } else {
131            if (this.s.selector === 'this') {
132                this.$items = this.$el;
133            } else if (this.s.selector !== '') {
134                if (this.s.selectWithin) {
135                    this.$items = $(this.s.selectWithin).find(this.s.selector);
136                } else {
137                    this.$items = this.$el.find($(this.s.selector));
138                }
139            } else {
140                this.$items = this.$el.children();
141            }
142        }
143
144        // .lg-item
145        this.$slide = '';
146
147        // .lg-outer
148        this.$outer = '';
149
150        this.init();
151
152        return this;
153    }
154
155    Plugin.prototype.init = function() {
156
157        var _this = this;
158
159        // s.preload should not be more than $item.length
160        if (_this.s.preload > _this.$items.length) {
161            _this.s.preload = _this.$items.length;
162        }
163
164        // if dynamic option is enabled execute immediately
165        var _hash = window.location.hash;
166        if (_hash.indexOf('lg=' + this.s.galleryId) > 0) {
167
168            _this.index = parseInt(_hash.split('&slide=')[1], 10);
169
170            $('body').addClass('lg-from-hash');
171            if (!$('body').hasClass('lg-on')) {
172                setTimeout(function() {
173                    _this.build(_this.index);
174                });
175
176                $('body').addClass('lg-on');
177            }
178        }
179
180        if (_this.s.dynamic) {
181
182            _this.$el.trigger('onBeforeOpen.lg');
183
184            _this.index = _this.s.index || 0;
185
186            // prevent accidental double execution
187            if (!$('body').hasClass('lg-on')) {
188                setTimeout(function() {
189                    _this.build(_this.index);
190                    $('body').addClass('lg-on');
191                });
192            }
193        } else {
194
195            // Using different namespace for click because click event should not unbind if selector is same object('this')
196            _this.$items.on('click.lgcustom', function(event) {
197
198                // For IE8
199                try {
200                    event.preventDefault();
201                    event.preventDefault();
202                } catch (er) {
203                    event.returnValue = false;
204                }
205
206                _this.$el.trigger('onBeforeOpen.lg');
207
208                _this.index = _this.s.index || _this.$items.index(this);
209
210                // prevent accidental double execution
211                if (!$('body').hasClass('lg-on')) {
212                    _this.build(_this.index);
213                    $('body').addClass('lg-on');
214                }
215            });
216        }
217
218    };
219
220    Plugin.prototype.build = function(index) {
221
222        var _this = this;
223
224        _this.structure();
225
226        // module constructor
227        $.each($.fn.lightGallery.modules, function(key) {
228            _this.modules[key] = new $.fn.lightGallery.modules[key](_this.el);
229        });
230
231        // initiate slide function
232        _this.slide(index, false, false, false);
233
234        if (_this.s.keyPress) {
235            _this.keyPress();
236        }
237
238        if (_this.$items.length > 1) {
239
240            _this.arrow();
241
242            setTimeout(function() {
243                _this.enableDrag();
244                _this.enableSwipe();
245            }, 50);
246
247            if (_this.s.mousewheel) {
248                _this.mousewheel();
249            }
250        } else {
251            _this.$slide.on('click.lg', function() {
252                _this.$el.trigger('onSlideClick.lg');
253            });
254        }
255
256        _this.counter();
257
258        _this.closeGallery();
259
260        _this.$el.trigger('onAfterOpen.lg');
261
262        // Hide controllers if mouse doesn't move for some period
263        _this.$outer.on('mousemove.lg click.lg touchstart.lg', function() {
264
265            _this.$outer.removeClass('lg-hide-items');
266
267            clearTimeout(_this.hideBartimeout);
268
269            // Timeout will be cleared on each slide movement also
270            _this.hideBartimeout = setTimeout(function() {
271                _this.$outer.addClass('lg-hide-items');
272            }, _this.s.hideBarsDelay);
273
274        });
275
276        _this.$outer.trigger('mousemove.lg');
277
278    };
279
280    Plugin.prototype.structure = function() {
281        var list = '';
282        var controls = '';
283        var i = 0;
284        var subHtmlCont = '';
285        var template;
286        var _this = this;
287
288        $('body').append('<div class="lg-backdrop"></div>');
289        $('.lg-backdrop').css('transition-duration', this.s.backdropDuration + 'ms');
290
291        // Create gallery items
292        for (i = 0; i < this.$items.length; i++) {
293            list += '<div class="lg-item"></div>';
294        }
295
296        // Create controlls
297        if (this.s.controls && this.$items.length > 1) {
298            controls = '<div class="lg-actions">' +
299                '<button class="lg-prev lg-icon">' + this.s.prevHtml + '</button>' +
300                '<button class="lg-next lg-icon">' + this.s.nextHtml + '</button>' +
301                '</div>';
302        }
303
304        if (this.s.appendSubHtmlTo === '.lg-sub-html') {
305            subHtmlCont = '<div class="lg-sub-html"></div>';
306        }
307
308        template = '<div class="lg-outer ' + this.s.addClass + ' ' + this.s.startClass + '">' +
309            '<div class="lg" style="width:' + this.s.width + '; height:' + this.s.height + '">' +
310            '<div class="lg-inner">' + list + '</div>' +
311            '<div class="lg-toolbar lg-group">' +
312            '<span class="lg-close lg-icon"></span>' +
313            '</div>' +
314            controls +
315            subHtmlCont +
316            '</div>' +
317            '</div>';
318
319        $('body').append(template);
320        this.$outer = $('.lg-outer');
321        this.$slide = this.$outer.find('.lg-item');
322
323        if (this.s.useLeft) {
324            this.$outer.addClass('lg-use-left');
325
326            // Set mode lg-slide if use left is true;
327            this.s.mode = 'lg-slide';
328        } else {
329            this.$outer.addClass('lg-use-css3');
330        }
331
332        // For fixed height gallery
333        _this.setTop();
334        $(window).on('resize.lg orientationchange.lg', function() {
335            setTimeout(function() {
336                _this.setTop();
337            }, 100);
338        });
339
340        // add class lg-current to remove initial transition
341        this.$slide.eq(this.index).addClass('lg-current');
342
343        // add Class for css support and transition mode
344        if (this.doCss()) {
345            this.$outer.addClass('lg-css3');
346        } else {
347            this.$outer.addClass('lg-css');
348
349            // Set speed 0 because no animation will happen if browser doesn't support css3
350            this.s.speed = 0;
351        }
352
353        this.$outer.addClass(this.s.mode);
354
355        if (this.s.enableDrag && this.$items.length > 1) {
356            this.$outer.addClass('lg-grab');
357        }
358
359        if (this.s.showAfterLoad) {
360            this.$outer.addClass('lg-show-after-load');
361        }
362
363        if (this.doCss()) {
364            var $inner = this.$outer.find('.lg-inner');
365            $inner.css('transition-timing-function', this.s.cssEasing);
366            $inner.css('transition-duration', this.s.speed + 'ms');
367        }
368
369        setTimeout(function() {
370            $('.lg-backdrop').addClass('in');
371        });
372
373        setTimeout(function() {
374            _this.$outer.addClass('lg-visible');
375        }, this.s.backdropDuration);
376
377        if (this.s.download) {
378            this.$outer.find('.lg-toolbar').append('<a id="lg-download" target="_blank" download class="lg-download lg-icon"></a>');
379        }
380
381        // Store the current scroll top value to scroll back after closing the gallery..
382        this.prevScrollTop = $(window).scrollTop();
383
384    };
385
386    // For fixed height gallery
387    Plugin.prototype.setTop = function() {
388        if (this.s.height !== '100%') {
389            var wH = $(window).height();
390            var top = (wH - parseInt(this.s.height, 10)) / 2;
391            var $lGallery = this.$outer.find('.lg');
392            if (wH >= parseInt(this.s.height, 10)) {
393                $lGallery.css('top', top + 'px');
394            } else {
395                $lGallery.css('top', '0px');
396            }
397        }
398    };
399
400    // Find css3 support
401    Plugin.prototype.doCss = function() {
402        // check for css animation support
403        var support = function() {
404            var transition = ['transition', 'MozTransition', 'WebkitTransition', 'OTransition', 'msTransition', 'KhtmlTransition'];
405            var root = document.documentElement;
406            var i = 0;
407            for (i = 0; i < transition.length; i++) {
408                if (transition[i] in root.style) {
409                    return true;
410                }
411            }
412        };
413
414        if (support()) {
415            return true;
416        }
417
418        return false;
419    };
420
421    /**
422     *  @desc Check the given src is video
423     *  @param {String} src
424     *  @return {Object} video type
425     *  Ex:{ youtube  :  ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] }
426     */
427    Plugin.prototype.isVideo = function(src, index) {
428
429        var html;
430        if (this.s.dynamic) {
431            html = this.s.dynamicEl[index].html;
432        } else {
433            html = this.$items.eq(index).attr('data-html');
434        }
435
436        if (!src) {
437            if(html) {
438                return {
439                    html5: true
440                };
441            } else {
442                console.error('lightGallery :- data-src is not pvovided on slide item ' + (index + 1) + '. Please make sure the selector property is properly configured. More info - http://sachinchoolur.github.io/lightGallery/demos/html-markup.html');
443                return false;
444            }
445        }
446
447        var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)/i);
448        var vimeo = src.match(/\/\/(?:www\.)?vimeo.com\/([0-9a-z\-_]+)/i);
449        var dailymotion = src.match(/\/\/(?:www\.)?dai.ly\/([0-9a-z\-_]+)/i);
450        var vk = src.match(/\/\/(?:www\.)?(?:vk\.com|vkontakte\.ru)\/(?:video_ext\.php\?)(.*)/i);
451
452        if (youtube) {
453            return {
454                youtube: youtube
455            };
456        } else if (vimeo) {
457            return {
458                vimeo: vimeo
459            };
460        } else if (dailymotion) {
461            return {
462                dailymotion: dailymotion
463            };
464        } else if (vk) {
465            return {
466                vk: vk
467            };
468        }
469    };
470
471    /**
472     *  @desc Create image counter
473     *  Ex: 1/10
474     */
475    Plugin.prototype.counter = function() {
476        if (this.s.counter) {
477            $(this.s.appendCounterTo).append('<div id="lg-counter"><span id="lg-counter-current">' + (parseInt(this.index, 10) + 1) + '</span> / <span id="lg-counter-all">' + this.$items.length + '</span></div>');
478        }
479    };
480
481    /**
482     *  @desc add sub-html into the slide
483     *  @param {Number} index - index of the slide
484     */
485    Plugin.prototype.addHtml = function(index) {
486        var subHtml = null;
487        var subHtmlUrl;
488        var $currentEle;
489        if (this.s.dynamic) {
490            if (this.s.dynamicEl[index].subHtmlUrl) {
491                subHtmlUrl = this.s.dynamicEl[index].subHtmlUrl;
492            } else {
493                subHtml = this.s.dynamicEl[index].subHtml;
494            }
495        } else {
496            $currentEle = this.$items.eq(index);
497            if ($currentEle.attr('data-sub-html-url')) {
498                subHtmlUrl = $currentEle.attr('data-sub-html-url');
499            } else {
500                subHtml = $currentEle.attr('data-sub-html');
501                if (this.s.getCaptionFromTitleOrAlt && !subHtml) {
502                    subHtml = $currentEle.attr('title') || $currentEle.find('img').first().attr('alt');
503                }
504            }
505        }
506
507        if (!subHtmlUrl) {
508            if (typeof subHtml !== 'undefined' && subHtml !== null) {
509
510                // get first letter of subhtml
511                // if first letter starts with . or # get the html form the jQuery object
512                var fL = subHtml.substring(0, 1);
513                if (fL === '.' || fL === '#') {
514                    if (this.s.subHtmlSelectorRelative && !this.s.dynamic) {
515                        subHtml = $currentEle.find(subHtml).html();
516                    } else {
517                        subHtml = $(subHtml).html();
518                    }
519                }
520            } else {
521                subHtml = '';
522            }
523        }
524
525        if (this.s.appendSubHtmlTo === '.lg-sub-html') {
526
527            if (subHtmlUrl) {
528                this.$outer.find(this.s.appendSubHtmlTo).load(subHtmlUrl);
529            } else {
530                this.$outer.find(this.s.appendSubHtmlTo).html(subHtml);
531            }
532
533        } else {
534
535            if (subHtmlUrl) {
536                this.$slide.eq(index).load(subHtmlUrl);
537            } else {
538                this.$slide.eq(index).append(subHtml);
539            }
540        }
541
542        // Add lg-empty-html class if title doesn't exist
543        if (typeof subHtml !== 'undefined' && subHtml !== null) {
544            if (subHtml === '') {
545                this.$outer.find(this.s.appendSubHtmlTo).addClass('lg-empty-html');
546            } else {
547                this.$outer.find(this.s.appendSubHtmlTo).removeClass('lg-empty-html');
548            }
549        }
550
551        this.$el.trigger('onAfterAppendSubHtml.lg', [index]);
552    };
553
554    /**
555     *  @desc Preload slides
556     *  @param {Number} index - index of the slide
557     */
558    Plugin.prototype.preload = function(index) {
559        var i = 1;
560        var j = 1;
561        for (i = 1; i <= this.s.preload; i++) {
562            if (i >= this.$items.length - index) {
563                break;
564            }
565
566            this.loadContent(index + i, false, 0);
567        }
568
569        for (j = 1; j <= this.s.preload; j++) {
570            if (index - j < 0) {
571                break;
572            }
573
574            this.loadContent(index - j, false, 0);
575        }
576    };
577
578    /**
579     *  @desc Load slide content into slide.
580     *  @param {Number} index - index of the slide.
581     *  @param {Boolean} rec - if true call loadcontent() function again.
582     *  @param {Boolean} delay - delay for adding complete class. it is 0 except first time.
583     */
584    Plugin.prototype.loadContent = function(index, rec, delay) {
585
586        var _this = this;
587        var _hasPoster = false;
588        var _$img;
589        var _src;
590        var _poster;
591        var _srcset;
592        var _sizes;
593        var _html;
594        var getResponsiveSrc = function(srcItms) {
595            var rsWidth = [];
596            var rsSrc = [];
597            for (var i = 0; i < srcItms.length; i++) {
598                var __src = srcItms[i].split(' ');
599
600                // Manage empty space
601                if (__src[0] === '') {
602                    __src.splice(0, 1);
603                }
604
605                rsSrc.push(__src[0]);
606                rsWidth.push(__src[1]);
607            }
608
609            var wWidth = $(window).width();
610            for (var j = 0; j < rsWidth.length; j++) {
611                if (parseInt(rsWidth[j], 10) > wWidth) {
612                    _src = rsSrc[j];
613                    break;
614                }
615            }
616        };
617
618        if (_this.s.dynamic) {
619
620            if (_this.s.dynamicEl[index].poster) {
621                _hasPoster = true;
622                _poster = _this.s.dynamicEl[index].poster;
623            }
624
625            _html = _this.s.dynamicEl[index].html;
626            _src = _this.s.dynamicEl[index].src;
627
628            if (_this.s.dynamicEl[index].responsive) {
629                var srcDyItms = _this.s.dynamicEl[index].responsive.split(',');
630                getResponsiveSrc(srcDyItms);
631            }
632
633            _srcset = _this.s.dynamicEl[index].srcset;
634            _sizes = _this.s.dynamicEl[index].sizes;
635
636        } else {
637
638            if (_this.$items.eq(index).attr('data-poster')) {
639                _hasPoster = true;
640                _poster = _this.$items.eq(index).attr('data-poster');
641            }
642
643            _html = _this.$items.eq(index).attr('data-html');
644            _src = _this.$items.eq(index).attr('href') || _this.$items.eq(index).attr('data-src');
645
646            if (_this.$items.eq(index).attr('data-responsive')) {
647                var srcItms = _this.$items.eq(index).attr('data-responsive').split(',');
648                getResponsiveSrc(srcItms);
649            }
650
651            _srcset = _this.$items.eq(index).attr('data-srcset');
652            _sizes = _this.$items.eq(index).attr('data-sizes');
653
654        }
655
656        //if (_src || _srcset || _sizes || _poster) {
657
658        var iframe = false;
659        if (_this.s.dynamic) {
660            if (_this.s.dynamicEl[index].iframe) {
661                iframe = true;
662            }
663        } else {
664            if (_this.$items.eq(index).attr('data-iframe') === 'true') {
665                iframe = true;
666            }
667        }
668
669        var _isVideo = _this.isVideo(_src, index);
670        if (!_this.$slide.eq(index).hasClass('lg-loaded')) {
671            if (iframe) {
672                _this.$slide.eq(index).prepend('<div class="lg-video-cont lg-has-iframe" style="max-width:' + _this.s.iframeMaxWidth + '"><div class="lg-video"><iframe class="lg-object" frameborder="0" src="' + _src + '"  allowfullscreen="true"></iframe></div></div>');
673            } else if (_hasPoster) {
674                var videoClass = '';
675                if (_isVideo && _isVideo.youtube) {
676                    videoClass = 'lg-has-youtube';
677                } else if (_isVideo && _isVideo.vimeo) {
678                    videoClass = 'lg-has-vimeo';
679                } else {
680                    videoClass = 'lg-has-html5';
681                }
682
683                _this.$slide.eq(index).prepend('<div class="lg-video-cont ' + videoClass + ' "><div class="lg-video"><span class="lg-video-play"></span><img class="lg-object lg-has-poster" src="' + _poster + '" /></div></div>');
684
685            } else if (_isVideo) {
686                _this.$slide.eq(index).prepend('<div class="lg-video-cont "><div class="lg-video"></div></div>');
687                _this.$el.trigger('hasVideo.lg', [index, _src, _html]);
688            } else {
689                _this.$slide.eq(index).prepend('<div class="lg-img-wrap"><img class="lg-object lg-image" src="' + _src + '" /></div>');
690            }
691
692            _this.$el.trigger('onAferAppendSlide.lg', [index]);
693
694            _$img = _this.$slide.eq(index).find('.lg-object');
695            if (_sizes) {
696                _$img.attr('sizes', _sizes);
697            }
698
699            if (_srcset) {
700                _$img.attr('srcset', _srcset);
701                try {
702                    picturefill({
703                        elements: [_$img[0]]
704                    });
705                } catch (e) {
706                    console.warn('lightGallery :- If you want srcset to be supported for older browser please include picturefil version 2 javascript library in your document.');
707                }
708            }
709
710            if (this.s.appendSubHtmlTo !== '.lg-sub-html') {
711                _this.addHtml(index);
712            }
713
714            _this.$slide.eq(index).addClass('lg-loaded');
715        }
716
717        _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() {
718
719            // For first time add some delay for displaying the start animation.
720            var _speed = 0;
721
722            // Do not change the delay value because it is required for zoom plugin.
723            // If gallery opened from direct url (hash) speed value should be 0
724            if (delay && !$('body').hasClass('lg-from-hash')) {
725                _speed = delay;
726            }
727
728            setTimeout(function() {
729                _this.$slide.eq(index).addClass('lg-complete');
730                _this.$el.trigger('onSlideItemLoad.lg', [index, delay || 0]);
731            }, _speed);
732
733        });
734
735        // @todo check load state for html5 videos
736        if (_isVideo && _isVideo.html5 && !_hasPoster) {
737            _this.$slide.eq(index).addClass('lg-complete');
738        }
739
740        if (rec === true) {
741            if (!_this.$slide.eq(index).hasClass('lg-complete')) {
742                _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() {
743                    _this.preload(index);
744                });
745            } else {
746                _this.preload(index);
747            }
748        }
749
750        //}
751    };
752
753    /**
754    *   @desc slide function for lightgallery
755        ** Slide() gets call on start
756        ** ** Set lg.on true once slide() function gets called.
757        ** Call loadContent() on slide() function inside setTimeout
758        ** ** On first slide we do not want any animation like slide of fade
759        ** ** So on first slide( if lg.on if false that is first slide) loadContent() should start loading immediately
760        ** ** Else loadContent() should wait for the transition to complete.
761        ** ** So set timeout s.speed + 50
762    <=> ** loadContent() will load slide content in to the particular slide
763        ** ** It has recursion (rec) parameter. if rec === true loadContent() will call preload() function.
764        ** ** preload will execute only when the previous slide is fully loaded (images iframe)
765        ** ** avoid simultaneous image load
766    <=> ** Preload() will check for s.preload value and call loadContent() again accoring to preload value
767        ** loadContent()  <====> Preload();
768
769    *   @param {Number} index - index of the slide
770    *   @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag
771    *   @param {Boolean} fromThumb - true if slide function called via thumbnail click
772    *   @param {String} direction - Direction of the slide(next/prev)
773    */
774    Plugin.prototype.slide = function(index, fromTouch, fromThumb, direction) {
775
776        var _prevIndex = this.$outer.find('.lg-current').index();
777        var _this = this;
778
779        // Prevent if multiple call
780        // Required for hsh plugin
781        if (_this.lGalleryOn && (_prevIndex === index)) {
782            return;
783        }
784
785        var _length = this.$slide.length;
786        var _time = _this.lGalleryOn ? this.s.speed : 0;
787
788        if (!_this.lgBusy) {
789
790            if (this.s.download) {
791                var _src;
792                if (_this.s.dynamic) {
793                    _src = _this.s.dynamicEl[index].downloadUrl !== false && (_this.s.dynamicEl[index].downloadUrl || _this.s.dynamicEl[index].src);
794                } else {
795                    _src = _this.$items.eq(index).attr('data-download-url') !== 'false' && (_this.$items.eq(index).attr('data-download-url') || _this.$items.eq(index).attr('href') || _this.$items.eq(index).attr('data-src'));
796
797                }
798
799                if (_src) {
800                    $('#lg-download').attr('href', _src);
801                    _this.$outer.removeClass('lg-hide-download');
802                } else {
803                    _this.$outer.addClass('lg-hide-download');
804                }
805            }
806
807            this.$el.trigger('onBeforeSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
808
809            _this.lgBusy = true;
810
811            clearTimeout(_this.hideBartimeout);
812
813            // Add title if this.s.appendSubHtmlTo === lg-sub-html
814            if (this.s.appendSubHtmlTo === '.lg-sub-html') {
815
816                // wait for slide animation to complete
817                setTimeout(function() {
818                    _this.addHtml(index);
819                }, _time);
820            }
821
822            this.arrowDisable(index);
823
824            if (!direction) {
825                if (index < _prevIndex) {
826                    direction = 'prev';
827                } else if (index > _prevIndex) {
828                    direction = 'next';
829                }
830            }
831
832            if (!fromTouch) {
833
834                // remove all transitions
835                _this.$outer.addClass('lg-no-trans');
836
837                this.$slide.removeClass('lg-prev-slide lg-next-slide');
838
839                if (direction === 'prev') {
840
841                    //prevslide
842                    this.$slide.eq(index).addClass('lg-prev-slide');
843                    this.$slide.eq(_prevIndex).addClass('lg-next-slide');
844                } else {
845
846                    // next slide
847                    this.$slide.eq(index).addClass('lg-next-slide');
848                    this.$slide.eq(_prevIndex).addClass('lg-prev-slide');
849                }
850
851                // give 50 ms for browser to add/remove class
852                setTimeout(function() {
853                    _this.$slide.removeClass('lg-current');
854
855                    //_this.$slide.eq(_prevIndex).removeClass('lg-current');
856                    _this.$slide.eq(index).addClass('lg-current');
857
858                    // reset all transitions
859                    _this.$outer.removeClass('lg-no-trans');
860                }, 50);
861            } else {
862
863                this.$slide.removeClass('lg-prev-slide lg-current lg-next-slide');
864                var touchPrev;
865                var touchNext;
866                if (_length > 2) {
867                    touchPrev = index - 1;
868                    touchNext = index + 1;
869
870                    if ((index === 0) && (_prevIndex === _length - 1)) {
871
872                        // next slide
873                        touchNext = 0;
874                        touchPrev = _length - 1;
875                    } else if ((index === _length - 1) && (_prevIndex === 0)) {
876
877                        // prev slide
878                        touchNext = 0;
879                        touchPrev = _length - 1;
880                    }
881
882                } else {
883                    touchPrev = 0;
884                    touchNext = 1;
885                }
886
887                if (direction === 'prev') {
888                    _this.$slide.eq(touchNext).addClass('lg-next-slide');
889                } else {
890                    _this.$slide.eq(touchPrev).addClass('lg-prev-slide');
891                }
892
893                _this.$slide.eq(index).addClass('lg-current');
894            }
895
896            if (_this.lGalleryOn) {
897                setTimeout(function() {
898                    _this.loadContent(index, true, 0);
899                }, this.s.speed + 50);
900
901                setTimeout(function() {
902                    _this.lgBusy = false;
903                    _this.$el.trigger('onAfterSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
904                }, this.s.speed);
905
906            } else {
907                _this.loadContent(index, true, _this.s.backdropDuration);
908
909                _this.lgBusy = false;
910                _this.$el.trigger('onAfterSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
911            }
912
913            _this.lGalleryOn = true;
914
915            if (this.s.counter) {
916                $('#lg-counter-current').text(index + 1);
917            }
918
919        }
920        _this.index = index;
921
922    };
923
924    /**
925     *  @desc Go to next slide
926     *  @param {Boolean} fromTouch - true if slide function called via touch event
927     */
928    Plugin.prototype.goToNextSlide = function(fromTouch) {
929        var _this = this;
930        var _loop = _this.s.loop;
931        if (fromTouch && _this.$slide.length < 3) {
932            _loop = false;
933        }
934
935        if (!_this.lgBusy) {
936            if ((_this.index + 1) < _this.$slide.length) {
937                _this.index++;
938                _this.$el.trigger('onBeforeNextSlide.lg', [_this.index]);
939                _this.slide(_this.index, fromTouch, false, 'next');
940            } else {
941                if (_loop) {
942                    _this.index = 0;
943                    _this.$el.trigger('onBeforeNextSlide.lg', [_this.index]);
944                    _this.slide(_this.index, fromTouch, false, 'next');
945                } else if (_this.s.slideEndAnimatoin && !fromTouch) {
946                    _this.$outer.addClass('lg-right-end');
947                    setTimeout(function() {
948                        _this.$outer.removeClass('lg-right-end');
949                    }, 400);
950                }
951            }
952        }
953    };
954
955    /**
956     *  @desc Go to previous slide
957     *  @param {Boolean} fromTouch - true if slide function called via touch event
958     */
959    Plugin.prototype.goToPrevSlide = function(fromTouch) {
960        var _this = this;
961        var _loop = _this.s.loop;
962        if (fromTouch && _this.$slide.length < 3) {
963            _loop = false;
964        }
965
966        if (!_this.lgBusy) {
967            if (_this.index > 0) {
968                _this.index--;
969                _this.$el.trigger('onBeforePrevSlide.lg', [_this.index, fromTouch]);
970                _this.slide(_this.index, fromTouch, false, 'prev');
971            } else {
972                if (_loop) {
973                    _this.index = _this.$items.length - 1;
974                    _this.$el.trigger('onBeforePrevSlide.lg', [_this.index, fromTouch]);
975                    _this.slide(_this.index, fromTouch, false, 'prev');
976                } else if (_this.s.slideEndAnimatoin && !fromTouch) {
977                    _this.$outer.addClass('lg-left-end');
978                    setTimeout(function() {
979                        _this.$outer.removeClass('lg-left-end');
980                    }, 400);
981                }
982            }
983        }
984    };
985
986    Plugin.prototype.keyPress = function() {
987        var _this = this;
988        if (this.$items.length > 1) {
989            $(window).on('keyup.lg', function(e) {
990                if (_this.$items.length > 1) {
991                    if (e.keyCode === 37) {
992                        e.preventDefault();
993                        _this.goToPrevSlide();
994                    }
995
996                    if (e.keyCode === 39) {
997                        e.preventDefault();
998                        _this.goToNextSlide();
999                    }
1000                }
1001            });
1002        }
1003
1004        $(window).on('keydown.lg', function(e) {
1005            if (_this.s.escKey === true && e.keyCode === 27) {
1006                e.preventDefault();
1007                if (!_this.$outer.hasClass('lg-thumb-open')) {
1008                    _this.destroy();
1009                } else {
1010                    _this.$outer.removeClass('lg-thumb-open');
1011                }
1012            }
1013        });
1014    };
1015
1016    Plugin.prototype.arrow = function() {
1017        var _this = this;
1018        this.$outer.find('.lg-prev').on('click.lg', function() {
1019            _this.goToPrevSlide();
1020        });
1021
1022        this.$outer.find('.lg-next').on('click.lg', function() {
1023            _this.goToNextSlide();
1024        });
1025    };
1026
1027    Plugin.prototype.arrowDisable = function(index) {
1028
1029        // Disable arrows if s.hideControlOnEnd is true
1030        if (!this.s.loop && this.s.hideControlOnEnd) {
1031            if ((index + 1) < this.$slide.length) {
1032                this.$outer.find('.lg-next').removeAttr('disabled').removeClass('disabled');
1033            } else {
1034                this.$outer.find('.lg-next').attr('disabled', 'disabled').addClass('disabled');
1035            }
1036
1037            if (index > 0) {
1038                this.$outer.find('.lg-prev').removeAttr('disabled').removeClass('disabled');
1039            } else {
1040                this.$outer.find('.lg-prev').attr('disabled', 'disabled').addClass('disabled');
1041            }
1042        }
1043    };
1044
1045    Plugin.prototype.setTranslate = function($el, xValue, yValue) {
1046        // jQuery supports Automatic CSS prefixing since jQuery 1.8.0
1047        if (this.s.useLeft) {
1048            $el.css('left', xValue);
1049        } else {
1050            $el.css({
1051                transform: 'translate3d(' + (xValue) + 'px, ' + yValue + 'px, 0px)'
1052            });
1053        }
1054    };
1055
1056    Plugin.prototype.touchMove = function(startCoords, endCoords) {
1057
1058        var distance = endCoords - startCoords;
1059
1060        if (Math.abs(distance) > 15) {
1061            // reset opacity and transition duration
1062            this.$outer.addClass('lg-dragging');
1063
1064            // move current slide
1065            this.setTranslate(this.$slide.eq(this.index), distance, 0);
1066
1067            // move next and prev slide with current slide
1068            this.setTranslate($('.lg-prev-slide'), -this.$slide.eq(this.index).width() + distance, 0);
1069            this.setTranslate($('.lg-next-slide'), this.$slide.eq(this.index).width() + distance, 0);
1070        }
1071    };
1072
1073    Plugin.prototype.touchEnd = function(distance) {
1074        var _this = this;
1075
1076        // keep slide animation for any mode while dragg/swipe
1077        if (_this.s.mode !== 'lg-slide') {
1078            _this.$outer.addClass('lg-slide');
1079        }
1080
1081        this.$slide.not('.lg-current, .lg-prev-slide, .lg-next-slide').css('opacity', '0');
1082
1083        // set transition duration
1084        setTimeout(function() {
1085            _this.$outer.removeClass('lg-dragging');
1086            if ((distance < 0) && (Math.abs(distance) > _this.s.swipeThreshold)) {
1087                _this.goToNextSlide(true);
1088            } else if ((distance > 0) && (Math.abs(distance) > _this.s.swipeThreshold)) {
1089                _this.goToPrevSlide(true);
1090            } else if (Math.abs(distance) < 5) {
1091
1092                // Trigger click if distance is less than 5 pix
1093                _this.$el.trigger('onSlideClick.lg');
1094            }
1095
1096            _this.$slide.removeAttr('style');
1097        });
1098
1099        // remove slide class once drag/swipe is completed if mode is not slide
1100        setTimeout(function() {
1101            if (!_this.$outer.hasClass('lg-dragging') && _this.s.mode !== 'lg-slide') {
1102                _this.$outer.removeClass('lg-slide');
1103            }
1104        }, _this.s.speed + 100);
1105
1106    };
1107
1108    Plugin.prototype.enableSwipe = function() {
1109        var _this = this;
1110        var startCoords = 0;
1111        var endCoords = 0;
1112        var isMoved = false;
1113
1114        if (_this.s.enableSwipe && _this.doCss()) {
1115
1116            _this.$slide.on('touchstart.lg', function(e) {
1117                if (!_this.$outer.hasClass('lg-zoomed') && !_this.lgBusy) {
1118                    e.preventDefault();
1119                    _this.manageSwipeClass();
1120                    startCoords = e.originalEvent.targetTouches[0].pageX;
1121                }
1122            });
1123
1124            _this.$slide.on('touchmove.lg', function(e) {
1125                if (!_this.$outer.hasClass('lg-zoomed')) {
1126                    e.preventDefault();
1127                    endCoords = e.originalEvent.targetTouches[0].pageX;
1128                    _this.touchMove(startCoords, endCoords);
1129                    isMoved = true;
1130                }
1131            });
1132
1133            _this.$slide.on('touchend.lg', function() {
1134                if (!_this.$outer.hasClass('lg-zoomed')) {
1135                    if (isMoved) {
1136                        isMoved = false;
1137                        _this.touchEnd(endCoords - startCoords);
1138                    } else {
1139                        _this.$el.trigger('onSlideClick.lg');
1140                    }
1141                }
1142            });
1143        }
1144
1145    };
1146
1147    Plugin.prototype.enableDrag = function() {
1148        var _this = this;
1149        var startCoords = 0;
1150        var endCoords = 0;
1151        var isDraging = false;
1152        var isMoved = false;
1153        if (_this.s.enableDrag && _this.doCss()) {
1154            _this.$slide.on('mousedown.lg', function(e) {
1155                if (!_this.$outer.hasClass('lg-zoomed') && !_this.lgBusy && !$(e.target).text().trim()) {
1156                    e.preventDefault();
1157                    _this.manageSwipeClass();
1158                    startCoords = e.pageX;
1159                    isDraging = true;
1160
1161                    // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
1162                    _this.$outer.scrollLeft += 1;
1163                    _this.$outer.scrollLeft -= 1;
1164
1165                    // *
1166
1167                    _this.$outer.removeClass('lg-grab').addClass('lg-grabbing');
1168
1169                    _this.$el.trigger('onDragstart.lg');
1170                }
1171            });
1172
1173            $(window).on('mousemove.lg', function(e) {
1174                if (isDraging) {
1175                    isMoved = true;
1176                    endCoords = e.pageX;
1177                    _this.touchMove(startCoords, endCoords);
1178                    _this.$el.trigger('onDragmove.lg');
1179                }
1180            });
1181
1182            $(window).on('mouseup.lg', function(e) {
1183                if (isMoved) {
1184                    isMoved = false;
1185                    _this.touchEnd(endCoords - startCoords);
1186                    _this.$el.trigger('onDragend.lg');
1187                } else if ($(e.target).hasClass('lg-object') || $(e.target).hasClass('lg-video-play')) {
1188                    _this.$el.trigger('onSlideClick.lg');
1189                }
1190
1191                // Prevent execution on click
1192                if (isDraging) {
1193                    isDraging = false;
1194                    _this.$outer.removeClass('lg-grabbing').addClass('lg-grab');
1195                }
1196            });
1197
1198        }
1199    };
1200
1201    Plugin.prototype.manageSwipeClass = function() {
1202        var _touchNext = this.index + 1;
1203        var _touchPrev = this.index - 1;
1204        if (this.s.loop && this.$slide.length > 2) {
1205            if (this.index === 0) {
1206                _touchPrev = this.$slide.length - 1;
1207            } else if (this.index === this.$slide.length - 1) {
1208                _touchNext = 0;
1209            }
1210        }
1211
1212        this.$slide.removeClass('lg-next-slide lg-prev-slide');
1213        if (_touchPrev > -1) {
1214            this.$slide.eq(_touchPrev).addClass('lg-prev-slide');
1215        }
1216
1217        this.$slide.eq(_touchNext).addClass('lg-next-slide');
1218    };
1219
1220    Plugin.prototype.mousewheel = function() {
1221        var _this = this;
1222        _this.$outer.on('mousewheel.lg', function(e) {
1223
1224            if (!e.deltaY) {
1225                return;
1226            }
1227
1228            if (e.deltaY > 0) {
1229                _this.goToPrevSlide();
1230            } else {
1231                _this.goToNextSlide();
1232            }
1233
1234            e.preventDefault();
1235        });
1236
1237    };
1238
1239    Plugin.prototype.closeGallery = function() {
1240
1241        var _this = this;
1242        var mousedown = false;
1243        this.$outer.find('.lg-close').on('click.lg', function() {
1244            _this.destroy();
1245        });
1246
1247        if (_this.s.closable) {
1248
1249            // If you drag the slide and release outside gallery gets close on chrome
1250            // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer
1251            _this.$outer.on('mousedown.lg', function(e) {
1252
1253                if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap')) {
1254                    mousedown = true;
1255                } else {
1256                    mousedown = false;
1257                }
1258
1259            });
1260            
1261            _this.$outer.on('mousemove.lg', function() {
1262                mousedown = false;
1263            });
1264
1265            _this.$outer.on('mouseup.lg', function(e) {
1266
1267                if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap') && mousedown) {
1268                    if (!_this.$outer.hasClass('lg-dragging')) {
1269                        _this.destroy();
1270                    }
1271                }
1272
1273            });
1274
1275        }
1276
1277    };
1278
1279    Plugin.prototype.destroy = function(d) {
1280
1281        var _this = this;
1282
1283        if (!d) {
1284            _this.$el.trigger('onBeforeClose.lg');
1285            $(window).scrollTop(_this.prevScrollTop);
1286        }
1287
1288
1289        /**
1290         * if d is false or undefined destroy will only close the gallery
1291         * plugins instance remains with the element
1292         *
1293         * if d is true destroy will completely remove the plugin
1294         */
1295
1296        if (d) {
1297            if (!_this.s.dynamic) {
1298                // only when not using dynamic mode is $items a jquery collection
1299                this.$items.off('click.lg click.lgcustom');
1300            }
1301
1302            $.removeData(_this.el, 'lightGallery');
1303        }
1304
1305        // Unbind all events added by lightGallery
1306        this.$el.off('.lg.tm');
1307
1308        // Distroy all lightGallery modules
1309        $.each($.fn.lightGallery.modules, function(key) {
1310            if (_this.modules[key]) {
1311                _this.modules[key].destroy();
1312            }
1313        });
1314
1315        this.lGalleryOn = false;
1316
1317        clearTimeout(_this.hideBartimeout);
1318        this.hideBartimeout = false;
1319        $(window).off('.lg');
1320        $('body').removeClass('lg-on lg-from-hash');
1321
1322        if (_this.$outer) {
1323            _this.$outer.removeClass('lg-visible');
1324        }
1325
1326        $('.lg-backdrop').removeClass('in');
1327
1328        setTimeout(function() {
1329            if (_this.$outer) {
1330                _this.$outer.remove();
1331            }
1332
1333            $('.lg-backdrop').remove();
1334
1335            if (!d) {
1336                _this.$el.trigger('onCloseAfter.lg');
1337            }
1338
1339        }, _this.s.backdropDuration + 50);
1340    };
1341
1342    $.fn.lightGallery = function(options) {
1343        return this.each(function() {
1344            if (!$.data(this, 'lightGallery')) {
1345                $.data(this, 'lightGallery', new Plugin(this, options));
1346            } else {
1347                try {
1348                    $(this).data('lightGallery').init();
1349                } catch (err) {
1350                    console.error('lightGallery has not initiated properly');
1351                }
1352            }
1353        });
1354    };
1355
1356    $.fn.lightGallery.modules = {};
1357
1358})();
1359
1360
1361}));

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.