PageSourceSearch

https://skynet.am/assets/js/lib/lity.js

js skynet.am collected 2026-09-24 14:07:49 UTC 17,885 bytes, 638 lines download raw bytes

vendor: 17,885 bytes, lines 1-638
1/*! Lity - v2.4.1 - 2020-04-26
2* http://sorgalla.com/lity/
3* Copyright (c) 2015-2020 Jan Sorgalla; Licensed MIT */
4(function(window, factory) {
5    if (typeof define === 'function' && define.amd) {
6        define(['jquery'], function($) {
7            return factory(window, $);
8        });
9    } else if (typeof module === 'object' && typeof module.exports === 'object') {
10        module.exports = factory(window, require('jquery'));
11    } else {
12        window.lity = factory(window, window.jQuery || window.Zepto);
13    }
14}(typeof window !== "undefined" ? window : this, function(window, $) {
15    'use strict';
16
17    var document = window.document;
18
19    var _win = $(window);
20    var _deferred = $.Deferred;
21    var _html = $('html');
22    var _instances = [];
23
24    var _attrAriaHidden = 'aria-hidden';
25    var _dataAriaHidden = 'lity-' + _attrAriaHidden;
26
27    var _focusableElementsSelector = 'a[href],area[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),button:not([disabled]),iframe,object,embed,[contenteditable],[tabindex]:not([tabindex^="-"])';
28
29    var _defaultOptions = {
30        esc: true,
31        handler: null,
32        handlers: {
33            image: imageHandler,
34            inline: inlineHandler,
35            youtube: youtubeHandler,
36            vimeo: vimeoHandler,
37            googlemaps: googlemapsHandler,
38            facebookvideo: facebookvideoHandler,
39            iframe: iframeHandler
40        },
41        template: '<div class="lity" role="dialog" aria-label="Dialog Window (Press escape to close)" tabindex="-1"><div class="lity-wrap" data-lity-close role="document"><div class="lity-loader" aria-hidden="true">Loading...</div><div class="lity-container"><div class="lity-content"></div><button class="lity-close" type="button" aria-label="Close (Press escape to close)" data-lity-close>&times;</button></div></div></div>'
42    };
43
44    var _imageRegexp = /(^data:image\/)|(\.(png|jpe?g|gif|svg|webp|bmp|ico|tiff?)(\?\S*)?$)/i;
45    var _youtubeRegex = /(youtube(-nocookie)?\.com|youtu\.be)\/(watch\?v=|v\/|u\/|embed\/?)?([\w-]{11})(.*)?/i;
46    var _vimeoRegex =  /(vimeo(pro)?.com)\/(?:[^\d]+)?(\d+)\??(.*)?$/;
47    var _googlemapsRegex = /((maps|www)\.)?google\.([^\/\?]+)\/?((maps\/?)?\?)(.*)/i;
48    var _facebookvideoRegex = /(facebook\.com)\/([a-z0-9_-]*)\/videos\/([0-9]*)(.*)?$/i;
49
50    var _transitionEndEvent = (function() {
51        var el = document.createElement('div');
52
53        var transEndEventNames = {
54            WebkitTransition: 'webkitTransitionEnd',
55            MozTransition: 'transitionend',
56            OTransition: 'oTransitionEnd otransitionend',
57            transition: 'transitionend'
58        };
59
60        for (var name in transEndEventNames) {
61            if (el.style[name] !== undefined) {
62                return transEndEventNames[name];
63            }
64        }
65
66        return false;
67    })();
68
69    function transitionEnd(element) {
70        var deferred = _deferred();
71
72        if (!_transitionEndEvent || !element.length) {
73            deferred.resolve();
74        } else {
75            element.one(_transitionEndEvent, deferred.resolve);
76            setTimeout(deferred.resolve, 500);
77        }
78
79        return deferred.promise();
80    }
81
82    function settings(currSettings, key, value) {
83        if (arguments.length === 1) {
84            return $.extend({}, currSettings);
85        }
86
87        if (typeof key === 'string') {
88            if (typeof value === 'undefined') {
89                return typeof currSettings[key] === 'undefined'
90                    ? null
91                    : currSettings[key];
92            }
93
94            currSettings[key] = value;
95        } else {
96            $.extend(currSettings, key);
97        }
98
99        return this;
100    }
101
102    function parseQueryParams(params) {
103        var pairs = decodeURI(params.split('#')[0]).split('&');
104        var obj = {}, p;
105
106        for (var i = 0, n = pairs.length; i < n; i++) {
107            if (!pairs[i]) {
108                continue;
109            }
110
111            p = pairs[i].split('=');
112            obj[p[0]] = p[1];
113        }
114
115        return obj;
116    }
117
118    function appendQueryParams(url, params) {
119        return url + (url.indexOf('?') > -1 ? '&' : '?') + $.param(params);
120    }
121
122    function transferHash(originalUrl, newUrl) {
123        var pos = originalUrl.indexOf('#');
124
125        if (-1 === pos) {
126            return newUrl;
127        }
128
129        if (pos > 0) {
130            originalUrl = originalUrl.substr(pos);
131        }
132
133        return newUrl + originalUrl;
134    }
135
136    function error(msg) {
137        return $('<span class="lity-error"></span>').append(msg);
138    }
139
140    function imageHandler(target, instance) {
141        var desc = (instance.opener() && instance.opener().data('lity-desc')) || 'Image with no description';
142        var img = $('<img src="' + target + '" alt="' + desc + '"/>');
143        var deferred = _deferred();
144        var failed = function() {
145            deferred.reject(error('Failed loading image'));
146        };
147
148        img
149            .on('load', function() {
150                if (this.naturalWidth === 0) {
151                    return failed();
152                }
153
154                deferred.resolve(img);
155            })
156            .on('error', failed)
157        ;
158
159        return deferred.promise();
160    }
161
162    imageHandler.test = function(target) {
163        return _imageRegexp.test(target);
164    };
165
166    function inlineHandler(target, instance) {
167        var el, placeholder, hasHideClass;
168
169        try {
170            el = $(target);
171        } catch (e) {
172            return false;
173        }
174
175        if (!el.length) {
176            return false;
177        }
178
179        placeholder = $('<i style="display:none !important"></i>');
180        hasHideClass = el.hasClass('lity-hide');
181
182        instance
183            .element()
184            .one('lity:remove', function() {
185                placeholder
186                    .before(el)
187                    .remove()
188                ;
189
190                if (hasHideClass && !el.closest('.lity-content').length) {
191                    el.addClass('lity-hide');
192                }
193            })
194        ;
195
196        return el
197            .removeClass('lity-hide')
198            .after(placeholder)
199        ;
200    }
201
202    function youtubeHandler(target) {
203        var matches = _youtubeRegex.exec(target);
204
205        if (!matches) {
206            return false;
207        }
208
209        return iframeHandler(
210            transferHash(
211                target,
212                appendQueryParams(
213                    'https://www.youtube' + (matches[2] || '') + '.com/embed/' + matches[4],
214                    $.extend(
215                        {
216                            autoplay: 1
217                        },
218                        parseQueryParams(matches[5] || '')
219                    )
220                )
221            )
222        );
223    }
224
225    function vimeoHandler(target) {
226        var matches = _vimeoRegex.exec(target);
227
228        if (!matches) {
229            return false;
230        }
231
232        return iframeHandler(
233            transferHash(
234                target,
235                appendQueryParams(
236                    'https://player.vimeo.com/video/' + matches[3],
237                    $.extend(
238                        {
239                            autoplay: 1
240                        },
241                        parseQueryParams(matches[4] || '')
242                    )
243                )
244            )
245        );
246    }
247
248    function facebookvideoHandler(target) {
249        var matches = _facebookvideoRegex.exec(target);
250
251        if (!matches) {
252            return false;
253        }
254
255        if (0 !== target.indexOf('http')) {
256            target = 'https:' + target;
257        }
258
259        return iframeHandler(
260            transferHash(
261                target,
262                appendQueryParams(
263                    'https://www.facebook.com/plugins/video.php?href=' + target,
264                    $.extend(
265                        {
266                            autoplay: 1
267                        },
268                        parseQueryParams(matches[4] || '')
269                    )
270                )
271            )
272        );
273    }
274
275    function googlemapsHandler(target) {
276        var matches = _googlemapsRegex.exec(target);
277
278        if (!matches) {
279            return false;
280        }
281
282        return iframeHandler(
283            transferHash(
284                target,
285                appendQueryParams(
286                    'https://www.google.' + matches[3] + '/maps?' + matches[6],
287                    {
288                        output: matches[6].indexOf('layer=c') > 0 ? 'svembed' : 'embed'
289                    }
290                )
291            )
292        );
293    }
294
295    function iframeHandler(target) {
296        return '<div class="lity-iframe-container"><iframe frameborder="0" allowfullscreen allow="autoplay; fullscreen" src="' + target + '"/></div>';
297    }
298
299    function winHeight() {
300        return document.documentElement.clientHeight
301            ? document.documentElement.clientHeight
302            : Math.round(_win.height());
303    }
304
305    function keydown(e) {
306        var current = currentInstance();
307
308        if (!current) {
309            return;
310        }
311
312        // ESC key
313        if (e.keyCode === 27 && !!current.options('esc')) {
314            current.close();
315        }
316
317        // TAB key
318        if (e.keyCode === 9) {
319            handleTabKey(e, current);
320        }
321    }
322
323    function handleTabKey(e, instance) {
324        var focusableElements = instance.element().find(_focusableElementsSelector);
325        var focusedIndex = focusableElements.index(document.activeElement);
326
327        if (e.shiftKey && focusedIndex <= 0) {
328            focusableElements.get(focusableElements.length - 1).focus();
329            e.preventDefault();
330        } else if (!e.shiftKey && focusedIndex === focusableElements.length - 1) {
331            focusableElements.get(0).focus();
332            e.preventDefault();
333        }
334    }
335
336    function resize() {
337        $.each(_instances, function(i, instance) {
338            instance.resize();
339        });
340    }
341
342    function registerInstance(instanceToRegister) {
343        if (1 === _instances.unshift(instanceToRegister)) {
344            _html.addClass('lity-active');
345
346            _win
347                .on({
348                    resize: resize,
349                    keydown: keydown
350                })
351            ;
352        }
353
354        $('body > *').not(instanceToRegister.element())
355            .addClass('lity-hidden')
356            .each(function() {
357                var el = $(this);
358
359                if (undefined !== el.data(_dataAriaHidden)) {
360                    return;
361                }
362
363                el.data(_dataAriaHidden, el.attr(_attrAriaHidden) || null);
364            })
365            .attr(_attrAriaHidden, 'true')
366        ;
367    }
368
369    function removeInstance(instanceToRemove) {
370        var show;
371
372        instanceToRemove
373            .element()
374            .attr(_attrAriaHidden, 'true')
375        ;
376
377        if (1 === _instances.length) {
378            _html.removeClass('lity-active');
379
380            _win
381                .off({
382                    resize: resize,
383                    keydown: keydown
384                })
385            ;
386        }
387
388        _instances = $.grep(_instances, function(instance) {
389            return instanceToRemove !== instance;
390        });
391
392        if (!!_instances.length) {
393            show = _instances[0].element();
394        } else {
395            show = $('.lity-hidden');
396        }
397
398        show
399            .removeClass('lity-hidden')
400            .each(function() {
401                var el = $(this), oldAttr = el.data(_dataAriaHidden);
402
403                if (!oldAttr) {
404                    el.removeAttr(_attrAriaHidden);
405                } else {
406                    el.attr(_attrAriaHidden, oldAttr);
407                }
408
409                el.removeData(_dataAriaHidden);
410            })
411        ;
412    }
413
414    function currentInstance() {
415        if (0 === _instances.length) {
416            return null;
417        }
418
419        return _instances[0];
420    }
421
422    function factory(target, instance, handlers, preferredHandler) {
423        var handler = 'inline', content;
424
425        var currentHandlers = $.extend({}, handlers);
426
427        if (preferredHandler && currentHandlers[preferredHandler]) {
428            content = currentHandlers[preferredHandler](target, instance);
429            handler = preferredHandler;
430        } else {
431            // Run inline and iframe handlers after all other handlers
432            $.each(['inline', 'iframe'], function(i, name) {
433                delete currentHandlers[name];
434
435                currentHandlers[name] = handlers[name];
436            });
437
438            $.each(currentHandlers, function(name, currentHandler) {
439                // Handler might be "removed" by setting callback to null
440                if (!currentHandler) {
441                    return true;
442                }
443
444                if (
445                    currentHandler.test &&
446                    !currentHandler.test(target, instance)
447                ) {
448                    return true;
449                }
450
451                content = currentHandler(target, instance);
452
453                if (false !== content) {
454                    handler = name;
455                    return false;
456                }
457            });
458        }
459
460        return {handler: handler, content: content || ''};
461    }
462
463    function Lity(target, options, opener, activeElement) {
464        var self = this;
465        var result;
466        var isReady = false;
467        var isClosed = false;
468        var element;
469        var content;
470
471        options = $.extend(
472            {},
473            _defaultOptions,
474            options
475        );
476
477        element = $(options.template);
478
479        // -- API --
480
481        self.element = function() {
482            return element;
483        };
484
485        self.opener = function() {
486            return opener;
487        };
488
489        self.options  = $.proxy(settings, self, options);
490        self.handlers = $.proxy(settings, self, options.handlers);
491
492        self.resize = function() {
493            if (!isReady || isClosed) {
494                return;
495            }
496
497            content
498                .css('max-height', winHeight() + 'px')
499                .trigger('lity:resize', [self])
500            ;
501        };
502
503        self.close = function() {
504            if (!isReady || isClosed) {
505                return;
506            }
507
508            isClosed = true;
509
510            removeInstance(self);
511
512            var deferred = _deferred();
513
514            // We return focus only if the current focus is inside this instance
515            if (
516                activeElement &&
517                (
518                    document.activeElement === element[0] ||
519                    $.contains(element[0], document.activeElement)
520                )
521            ) {
522                try {
523                    activeElement.focus();
524                } catch (e) {
525                    // Ignore exceptions, eg. for SVG elements which can't be
526                    // focused in IE11
527                }
528            }
529
530            content.trigger('lity:close', [self]);
531
532            element
533                .removeClass('lity-opened')
534                .addClass('lity-closed')
535            ;
536
537            transitionEnd(content.add(element))
538                .always(function() {
539                    content.trigger('lity:remove', [self]);
540                    element.remove();
541                    element = undefined;
542                    deferred.resolve();
543                })
544            ;
545
546            return deferred.promise();
547        };
548
549        // -- Initialization --
550
551        result = factory(target, self, options.handlers, options.handler);
552
553        element
554            .attr(_attrAriaHidden, 'false')
555            .addClass('lity-loading lity-opened lity-' + result.handler)
556            .appendTo('body')
557            .focus()
558            .on('click', '[data-lity-close]', function(e) {
559                if ($(e.target).is('[data-lity-close]')) {
560                    self.close();
561                }
562            })
563            .trigger('lity:open', [self])
564        ;
565
566        registerInstance(self);
567
568        $.when(result.content)
569            .always(ready)
570        ;
571
572        function ready(result) {
573            content = $(result)
574                .css('max-height', winHeight() + 'px')
575            ;
576
577            element
578                .find('.lity-loader')
579                .each(function() {
580                    var loader = $(this);
581
582                    transitionEnd(loader)
583                        .always(function() {
584                            loader.remove();
585                        })
586                    ;
587                })
588            ;
589
590            element
591                .removeClass('lity-loading')
592                .find('.lity-content')
593                .empty()
594                .append(content)
595            ;
596
597            isReady = true;
598
599            content
600                .trigger('lity:ready', [self])
601            ;
602        }
603    }
604
605    function lity(target, options, opener) {
606        if (!target.preventDefault) {
607            opener = $(opener);
608        } else {
609            target.preventDefault();
610            opener = $(this);
611            target = opener.data('lity-target') || opener.attr('href') || opener.attr('src');
612        }
613
614        var instance = new Lity(
615            target,
616            $.extend(
617                {},
618                opener.data('lity-options') || opener.data('lity'),
619                options
620            ),
621            opener,
622            document.activeElement
623        );
624
625        if (!target.preventDefault) {
626            return instance;
627        }
628    }
629
630    lity.version  = '2.4.1';
631    lity.options  = $.proxy(settings, lity, _defaultOptions);
632    lity.handlers = $.proxy(settings, lity, _defaultOptions.handlers);
633    lity.current  = currentInstance;
634
635    $(document).on('click.lity', '[data-lity]', lity);
636
637    return lity;
638}));

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.