PageSourceSearch

https://e123.hk/themes/inv/e123_enar_sub/assets/lity-2.3.1/dist/lity.js?v=1

js e123.hk collected 2026-09-24 09:59:52 UTC 18,029 bytes, 639 lines download raw bytes

vendor: 18,029 bytes, lines 1-639
1/*! Lity - v2.3.1 - 2018-04-20
2* http://sorgalla.com/lity/
3* Copyright (c) 2015-2018 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"/>').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 img = $('<img src="' + target + '" alt="' + desc + '"/><div class="lity_desc_after_image">' + desc + '</div>');
144        var deferred = _deferred();
145        var failed = function() {
146            deferred.reject(error('Failed loading image'));
147        };
148
149        img
150            .on('load', function() {
151                if (this.naturalWidth === 0) {
152                    return failed();
153                }
154
155                deferred.resolve(img);
156            })
157            .on('error', failed)
158        ;
159
160        return deferred.promise();
161    }
162
163    imageHandler.test = function(target) {
164        return _imageRegexp.test(target);
165    };
166
167    function inlineHandler(target, instance) {
168        var el, placeholder, hasHideClass;
169
170        try {
171            el = $(target);
172        } catch (e) {
173            return false;
174        }
175
176        if (!el.length) {
177            return false;
178        }
179
180        placeholder = $('<i style="display:none !important"/>');
181        hasHideClass = el.hasClass('lity-hide');
182
183        instance
184            .element()
185            .one('lity:remove', function() {
186                placeholder
187                    .before(el)
188                    .remove()
189                ;
190
191                if (hasHideClass && !el.closest('.lity-content').length) {
192                    el.addClass('lity-hide');
193                }
194            })
195        ;
196
197        return el
198            .removeClass('lity-hide')
199            .after(placeholder)
200        ;
201    }
202
203    function youtubeHandler(target) {
204        var matches = _youtubeRegex.exec(target);
205
206        if (!matches) {
207            return false;
208        }
209
210        return iframeHandler(
211            transferHash(
212                target,
213                appendQueryParams(
214                    'https://www.youtube' + (matches[2] || '') + '.com/embed/' + matches[4],
215                    $.extend(
216                        {
217                            autoplay: 1
218                        },
219                        parseQueryParams(matches[5] || '')
220                    )
221                )
222            )
223        );
224    }
225
226    function vimeoHandler(target) {
227        var matches = _vimeoRegex.exec(target);
228
229        if (!matches) {
230            return false;
231        }
232
233        return iframeHandler(
234            transferHash(
235                target,
236                appendQueryParams(
237                    'https://player.vimeo.com/video/' + matches[3],
238                    $.extend(
239                        {
240                            autoplay: 1
241                        },
242                        parseQueryParams(matches[4] || '')
243                    )
244                )
245            )
246        );
247    }
248
249    function facebookvideoHandler(target) {
250        var matches = _facebookvideoRegex.exec(target);
251
252        if (!matches) {
253            return false;
254        }
255
256        if (0 !== target.indexOf('http')) {
257            target = 'https:' + target;
258        }
259
260        return iframeHandler(
261            transferHash(
262                target,
263                appendQueryParams(
264                    'https://www.facebook.com/plugins/video.php?href=' + target,
265                    $.extend(
266                        {
267                            autoplay: 1
268                        },
269                        parseQueryParams(matches[4] || '')
270                    )
271                )
272            )
273        );
274    }
275
276    function googlemapsHandler(target) {
277        var matches = _googlemapsRegex.exec(target);
278
279        if (!matches) {
280            return false;
281        }
282
283        return iframeHandler(
284            transferHash(
285                target,
286                appendQueryParams(
287                    'https://www.google.' + matches[3] + '/maps?' + matches[6],
288                    {
289                        output: matches[6].indexOf('layer=c') > 0 ? 'svembed' : 'embed'
290                    }
291                )
292            )
293        );
294    }
295
296    function iframeHandler(target) {
297        return '<div class="lity-iframe-container"><iframe frameborder="0" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen src="' + target + '"/></div>';
298    }
299
300    function winHeight() {
301        return document.documentElement.clientHeight
302            ? document.documentElement.clientHeight
303            : Math.round(_win.height());
304    }
305
306    function keydown(e) {
307        var current = currentInstance();
308
309        if (!current) {
310            return;
311        }
312
313        // ESC key
314        if (e.keyCode === 27 && !!current.options('esc')) {
315            current.close();
316        }
317
318        // TAB key
319        if (e.keyCode === 9) {
320            handleTabKey(e, current);
321        }
322    }
323
324    function handleTabKey(e, instance) {
325        var focusableElements = instance.element().find(_focusableElementsSelector);
326        var focusedIndex = focusableElements.index(document.activeElement);
327
328        if (e.shiftKey && focusedIndex <= 0) {
329            focusableElements.get(focusableElements.length - 1).focus();
330            e.preventDefault();
331        } else if (!e.shiftKey && focusedIndex === focusableElements.length - 1) {
332            focusableElements.get(0).focus();
333            e.preventDefault();
334        }
335    }
336
337    function resize() {
338        $.each(_instances, function(i, instance) {
339            instance.resize();
340        });
341    }
342
343    function registerInstance(instanceToRegister) {
344        if (1 === _instances.unshift(instanceToRegister)) {
345            _html.addClass('lity-active');
346
347            _win
348                .on({
349                    resize: resize,
350                    keydown: keydown
351                })
352            ;
353        }
354
355        $('body > *').not(instanceToRegister.element())
356            .addClass('lity-hidden')
357            .each(function() {
358                var el = $(this);
359
360                if (undefined !== el.data(_dataAriaHidden)) {
361                    return;
362                }
363
364                el.data(_dataAriaHidden, el.attr(_attrAriaHidden) || null);
365            })
366            .attr(_attrAriaHidden, 'true')
367        ;
368    }
369
370    function removeInstance(instanceToRemove) {
371        var show;
372
373        instanceToRemove
374            .element()
375            .attr(_attrAriaHidden, 'true')
376        ;
377
378        if (1 === _instances.length) {
379            _html.removeClass('lity-active');
380
381            _win
382                .off({
383                    resize: resize,
384                    keydown: keydown
385                })
386            ;
387        }
388
389        _instances = $.grep(_instances, function(instance) {
390            return instanceToRemove !== instance;
391        });
392
393        if (!!_instances.length) {
394            show = _instances[0].element();
395        } else {
396            show = $('.lity-hidden');
397        }
398
399        show
400            .removeClass('lity-hidden')
401            .each(function() {
402                var el = $(this), oldAttr = el.data(_dataAriaHidden);
403
404                if (!oldAttr) {
405                    el.removeAttr(_attrAriaHidden);
406                } else {
407                    el.attr(_attrAriaHidden, oldAttr);
408                }
409
410                el.removeData(_dataAriaHidden);
411            })
412        ;
413    }
414
415    function currentInstance() {
416        if (0 === _instances.length) {
417            return null;
418        }
419
420        return _instances[0];
421    }
422
423    function factory(target, instance, handlers, preferredHandler) {
424        var handler = 'inline', content;
425
426        var currentHandlers = $.extend({}, handlers);
427
428        if (preferredHandler && currentHandlers[preferredHandler]) {
429            content = currentHandlers[preferredHandler](target, instance);
430            handler = preferredHandler;
431        } else {
432            // Run inline and iframe handlers after all other handlers
433            $.each(['inline', 'iframe'], function(i, name) {
434                delete currentHandlers[name];
435
436                currentHandlers[name] = handlers[name];
437            });
438
439            $.each(currentHandlers, function(name, currentHandler) {
440                // Handler might be "removed" by setting callback to null
441                if (!currentHandler) {
442                    return true;
443                }
444
445                if (
446                    currentHandler.test &&
447                    !currentHandler.test(target, instance)
448                ) {
449                    return true;
450                }
451
452                content = currentHandler(target, instance);
453
454                if (false !== content) {
455                    handler = name;
456                    return false;
457                }
458            });
459        }
460
461        return {handler: handler, content: content || ''};
462    }
463
464    function Lity(target, options, opener, activeElement) {
465        var self = this;
466        var result;
467        var isReady = false;
468        var isClosed = false;
469        var element;
470        var content;
471
472        options = $.extend(
473            {},
474            _defaultOptions,
475            options
476        );
477
478        element = $(options.template);
479
480        // -- API --
481
482        self.element = function() {
483            return element;
484        };
485
486        self.opener = function() {
487            return opener;
488        };
489
490        self.options  = $.proxy(settings, self, options);
491        self.handlers = $.proxy(settings, self, options.handlers);
492
493        self.resize = function() {
494            if (!isReady || isClosed) {
495                return;
496            }
497
498            content
499                .css('max-height', winHeight() + 'px')
500                .trigger('lity:resize', [self])
501            ;
502        };
503
504        self.close = function() {
505            if (!isReady || isClosed) {
506                return;
507            }
508
509            isClosed = true;
510
511            removeInstance(self);
512
513            var deferred = _deferred();
514
515            // We return focus only if the current focus is inside this instance
516            if (
517                activeElement &&
518                (
519                    document.activeElement === element[0] ||
520                    $.contains(element[0], document.activeElement)
521                )
522            ) {
523                try {
524                    activeElement.focus();
525                } catch (e) {
526                    // Ignore exceptions, eg. for SVG elements which can't be
527                    // focused in IE11
528                }
529            }
530
531            content.trigger('lity:close', [self]);
532
533            element
534                .removeClass('lity-opened')
535                .addClass('lity-closed')
536            ;
537
538            transitionEnd(content.add(element))
539                .always(function() {
540                    content.trigger('lity:remove', [self]);
541                    element.remove();
542                    element = undefined;
543                    deferred.resolve();
544                })
545            ;
546
547            return deferred.promise();
548        };
549
550        // -- Initialization --
551
552        result = factory(target, self, options.handlers, options.handler);
553
554        element
555            .attr(_attrAriaHidden, 'false')
556            .addClass('lity-loading lity-opened lity-' + result.handler)
557            .appendTo('body')
558            .focus()
559            .on('click', '[data-lity-close]', function(e) {
560                if ($(e.target).is('[data-lity-close]')) {
561                    self.close();
562                }
563            })
564            .trigger('lity:open', [self])
565        ;
566
567        registerInstance(self);
568
569        $.when(result.content)
570            .always(ready)
571        ;
572
573        function ready(result) {
574            content = $(result)
575                .css('max-height', winHeight() + 'px')
576            ;
577
578            element
579                .find('.lity-loader')
580                .each(function() {
581                    var loader = $(this);
582
583                    transitionEnd(loader)
584                        .always(function() {
585                            loader.remove();
586                        })
587                    ;
588                })
589            ;
590
591            element
592                .removeClass('lity-loading')
593                .find('.lity-content')
594                .empty()
595                .append(content)
596            ;
597
598            isReady = true;
599
600            content
601                .trigger('lity:ready', [self])
602            ;
603        }
604    }
605
606    function lity(target, options, opener) {
607        if (!target.preventDefault) {
608            opener = $(opener);
609        } else {
610            target.preventDefault();
611            opener = $(this);
612            target = opener.data('lity-target') || opener.attr('href') || opener.attr('src');
613        }
614
615        var instance = new Lity(
616            target,
617            $.extend(
618                {},
619                opener.data('lity-options') || opener.data('lity'),
620                options
621            ),
622            opener,
623            document.activeElement
624        );
625
626        if (!target.preventDefault) {
627            return instance;
628        }
629    }
630
631    lity.version  = '2.3.1';
632    lity.options  = $.proxy(settings, lity, _defaultOptions);
633    lity.handlers = $.proxy(settings, lity, _defaultOptions.handlers);
634    lity.current  = currentInstance;
635
636    $(document).on('click.lity', '[data-lity]', lity);
637
638    return lity;
639}));

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.