PageSourceSearch

https://eideford.com/js/plugins/lity.js?v=12.1.255

js eideford.com collected 2026-10-07 15:18:51 UTC 17,458 bytes, 626 lines download raw bytes

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

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.