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>×</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.