PageSourceSearch

https://ourfuturesinstitute.org.au/wp-content/themes/salient-child/js/lity.js

js ourfuturesinstitute.org.au collected 2026-10-04 13:23:50 UTC 17,699 bytes, 634 lines download raw bytes

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

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.