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.