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