vendor: 1,797 bytes, lines 1-78
1(function(window, factory) { 2 var lazySizes = factory(window, window.document, Date); 3 window.lazySizes = lazySizes; 4 if(typeof module == 'object' && module.exports){ 5 module.exports = lazySizes; 6 } 7}(typeof window != 'undefined' ? 8 window : {}, function l(window, document, Date) { 9 'use strict'; 10 /*jshint eqnull:true */ 11 12 var lazysizes, lazySizesCfg; 13 14 (function(){ 15 var prop; 16 17 var lazySizesDefaults = { 18 lazyClass: 'lazyload', 19 loadedClass: 'lazyloaded', 20 loadingClass: 'lazyloading', 21 preloadClass: 'lazypreload', 22 errorClass: 'lazyerror', 23 //strictClass: 'lazystrict', 24 autosizesClass: 'lazyautosizes', 25 srcAttr: 'data-src', 26 srcsetAttr: 'data-srcset', 27 sizesAttr: 'data-sizes', 28 //preloadAfterLoad: false, 29 minSize: 40, 30 customMedia: {}, 31 init: true, 32 expFactor: 1.5, 33 hFac: 0.8, 34 loadMode: 2, 35 loadHidden: true, 36 ricTimeout: 0, 37 throttleDelay: 125, 38 }; 39 40 lazySizesCfg = window.lazySizesConfig || window.lazysizesConfig || {}; 41 42 for(prop in lazySizesDefaults){ 43 if(!(prop in lazySizesCfg)){ 44 lazySizesCfg[prop] = lazySizesDefaults[prop]; 45 } 46 } 47 })(); 48 49 if (!document || !document.getElementsByClassName) { 50 return { 51 init: function () {}, 52 cfg: lazySizesCfg, 53 noSupport: true, 54 }; 55 } 56 57 var docElem = document.documentElement; 58 59 var supportPicture = window.HTMLPictureElement; 60 61 var _addEventListener = 'addEventListener'; 62 63 var _getAttribute = 'getAttribute'; 64 65 var addEventListener = window[_addEventListener].bind(window); 66 67 var setTimeout = window.setTimeout; 68 69 var requestAnimationFrame = window.requestAnimationFrame || setTimeout; 70 71 var requestIdleCallback = window.requestIdleCallback; 72 73 var regPicture = /^picture$/i; 74 75 var loadEvents = ['load', 'error', 'lazyincluded', '_lazyloaded']; 76 77 var regClassCache = {}; 78
vendor: 16,835 bytes, lines 79-750
79 var forEach = Array.prototype.forEach; 80 81 var hasClass = function(ele, cls) { 82 if(!regClassCache[cls]){ 83 regClassCache[cls] = new RegExp('(\\s|^)'+cls+'(\\s|$)'); 84 } 85 return regClassCache[cls].test(ele[_getAttribute]('class') || '') && regClassCache[cls]; 86 }; 87 88 var addClass = function(ele, cls) { 89 if (!hasClass(ele, cls)){ 90 ele.setAttribute('class', (ele[_getAttribute]('class') || '').trim() + ' ' + cls); 91 } 92 }; 93 94 var removeClass = function(ele, cls) { 95 var reg; 96 if ((reg = hasClass(ele,cls))) { 97 ele.setAttribute('class', (ele[_getAttribute]('class') || '').replace(reg, ' ')); 98 } 99 }; 100 101 var addRemoveLoadEvents = function(dom, fn, add){ 102 var action = add ? _addEventListener : 'removeEventListener'; 103 if(add){ 104 addRemoveLoadEvents(dom, fn); 105 } 106 loadEvents.forEach(function(evt){ 107 dom[action](evt, fn); 108 }); 109 }; 110 111 var triggerEvent = function(elem, name, detail, noBubbles, noCancelable){ 112 var event = document.createEvent('Event'); 113 114 if(!detail){ 115 detail = {}; 116 } 117 118 detail.instance = lazysizes; 119 120 event.initEvent(name, !noBubbles, !noCancelable); 121 122 event.detail = detail; 123 124 elem.dispatchEvent(event); 125 return event; 126 }; 127 128 var updatePolyfill = function (el, full){ 129 var polyfill; 130 if( !supportPicture && ( polyfill = (window.picturefill || lazySizesCfg.pf) ) ){ 131 if(full && full.src && !el[_getAttribute]('srcset')){ 132 el.setAttribute('srcset', full.src); 133 } 134 polyfill({reevaluate: true, elements: [el]}); 135 } else if(full && full.src){ 136 el.src = full.src; 137 } 138 }; 139 140 var getCSS = function (elem, style){ 141 return (getComputedStyle(elem, null) || {})[style]; 142 }; 143 144 var getWidth = function(elem, parent, width){ 145 width = width || elem.offsetWidth; 146 147 while(width < lazySizesCfg.minSize && parent && !elem._lazysizesWidth){ 148 width = parent.offsetWidth; 149 parent = parent.parentNode; 150 } 151 152 return width; 153 }; 154 155 var rAF = (function(){ 156 var running, waiting; 157 var firstFns = []; 158 var secondFns = []; 159 var fns = firstFns; 160 161 var run = function(){ 162 var runFns = fns; 163 164 fns = firstFns.length ? secondFns : firstFns; 165 166 running = true; 167 waiting = false; 168 169 while(runFns.length){ 170 runFns.shift()(); 171 } 172 173 running = false; 174 }; 175 176 var rafBatch = function(fn, queue){ 177 if(running && !queue){ 178 fn.apply(this, arguments); 179 } else { 180 fns.push(fn); 181 182 if(!waiting){ 183 waiting = true; 184 (document.hidden ? setTimeout : requestAnimationFrame)(run); 185 } 186 } 187 }; 188 189 rafBatch._lsFlush = run; 190 191 return rafBatch; 192 })(); 193 194 var rAFIt = function(fn, simple){ 195 return simple ? 196 function() { 197 rAF(fn); 198 } : 199 function(){ 200 var that = this; 201 var args = arguments; 202 rAF(function(){ 203 fn.apply(that, args); 204 }); 205 } 206 ; 207 }; 208 209 var throttle = function(fn){ 210 var running; 211 var lastTime = 0; 212 var gDelay = lazySizesCfg.throttleDelay; 213 var rICTimeout = lazySizesCfg.ricTimeout; 214 var run = function(){ 215 running = false; 216 lastTime = Date.now(); 217 fn(); 218 }; 219 var idleCallback = requestIdleCallback && rICTimeout > 49 ? 220 function(){ 221 requestIdleCallback(run, {timeout: rICTimeout}); 222 223 if(rICTimeout !== lazySizesCfg.ricTimeout){ 224 rICTimeout = lazySizesCfg.ricTimeout; 225 } 226 } : 227 rAFIt(function(){ 228 setTimeout(run); 229 }, true) 230 ; 231 232 return function(isPriority){ 233 var delay; 234 235 if((isPriority = isPriority === true)){ 236 rICTimeout = 33; 237 } 238 239 if(running){ 240 return; 241 } 242 243 running = true; 244 245 delay = gDelay - (Date.now() - lastTime); 246 247 if(delay < 0){ 248 delay = 0; 249 } 250 251 if(isPriority || delay < 9){ 252 idleCallback(); 253 } else { 254 setTimeout(idleCallback, delay); 255 } 256 }; 257 }; 258 259 //based on http://modernjavascript.blogspot.de/2013/08/building-better-debounce.html 260 var debounce = function(func) { 261 var timeout, timestamp; 262 var wait = 99; 263 var run = function(){ 264 timeout = null; 265 func(); 266 }; 267 var later = function() { 268 var last = Date.now() - timestamp; 269 270 if (last < wait) { 271 setTimeout(later, wait - last); 272 } else { 273 (requestIdleCallback || run)(run); 274 } 275 }; 276 277 return function() { 278 timestamp = Date.now(); 279 280 if (!timeout) { 281 timeout = setTimeout(later, wait); 282 } 283 }; 284 }; 285 286 var loader = (function(){ 287 var preloadElems, isCompleted, resetPreloadingTimer, loadMode, started; 288 289 var eLvW, elvH, eLtop, eLleft, eLright, eLbottom, isBodyHidden; 290 291 var regImg = /^img$/i; 292 var regIframe = /^iframe$/i; 293 294 var supportScroll = ('onscroll' in window) && !(/(gle|ing)bot/.test(navigator.userAgent)); 295 296 var shrinkExpand = 0; 297 var currentExpand = 0; 298 299 var isLoading = 0; 300 var lowRuns = -1; 301 302 var resetPreloading = function(e){ 303 isLoading--; 304 if(!e || isLoading < 0 || !e.target){ 305 isLoading = 0; 306 } 307 }; 308 309 var isVisible = function (elem) { 310 if (isBodyHidden == null) { 311 isBodyHidden = getCSS(document.body, 'visibility') == 'hidden'; 312 } 313 314 return isBodyHidden || !(getCSS(elem.parentNode, 'visibility') == 'hidden' && getCSS(elem, 'visibility') == 'hidden'); 315 }; 316 317 var isNestedVisible = function(elem, elemExpand){ 318 var outerRect; 319 var parent = elem; 320 var visible = isVisible(elem); 321 322 eLtop -= elemExpand; 323 eLbottom += elemExpand; 324 eLleft -= elemExpand; 325 eLright += elemExpand; 326 327 while(visible && (parent = parent.offsetParent) && parent != document.body && parent != docElem){ 328 visible = ((getCSS(parent, 'opacity') || 1) > 0); 329 330 if(visible && getCSS(parent, 'overflow') != 'visible'){ 331 outerRect = parent.getBoundingClientRect(); 332 visible = eLright > outerRect.left && 333 eLleft < outerRect.right && 334 eLbottom > outerRect.top - 1 && 335 eLtop < outerRect.bottom + 1 336 ; 337 } 338 } 339 340 return visible; 341 }; 342 343 var checkElements = function() { 344 var eLlen, i, rect, autoLoadElem, loadedSomething, elemExpand, elemNegativeExpand, elemExpandVal, 345 beforeExpandVal, defaultExpand, preloadExpand, hFac; 346 var lazyloadElems = lazysizes.elements; 347 348 if((loadMode = lazySizesCfg.loadMode) && isLoading < 8 && (eLlen = lazyloadElems.length)){ 349 350 i = 0; 351 352 lowRuns++; 353 354 for(; i < eLlen; i++){ 355 356 if(!lazyloadElems[i] || lazyloadElems[i]._lazyRace){continue;} 357 358 if(!supportScroll || (lazysizes.prematureUnveil && lazysizes.prematureUnveil(lazyloadElems[i]))){unveilElement(lazyloadElems[i]);continue;} 359 360 if(!(elemExpandVal = lazyloadElems[i][_getAttribute]('data-expand')) || !(elemExpand = elemExpandVal * 1)){ 361 elemExpand = currentExpand; 362 } 363 364 if (!defaultExpand) { 365 defaultExpand = (!lazySizesCfg.expand || lazySizesCfg.expand < 1) ? 366 docElem.clientHeight > 500 && docElem.clientWidth > 500 ? 500 : 370 : 367 lazySizesCfg.expand; 368 369 lazysizes._defEx = defaultExpand; 370 371 preloadExpand = defaultExpand * lazySizesCfg.expFactor; 372 hFac = lazySizesCfg.hFac; 373 isBodyHidden = null; 374 375 if(currentExpand < preloadExpand && isLoading < 1 && lowRuns > 2 && loadMode > 2 && !document.hidden){ 376 currentExpand = preloadExpand; 377 lowRuns = 0; 378 } else if(loadMode > 1 && lowRuns > 1 && isLoading < 6){ 379 currentExpand = defaultExpand; 380 } else { 381 currentExpand = shrinkExpand; 382 } 383 } 384 385 if(beforeExpandVal !== elemExpand){ 386 eLvW = innerWidth + (elemExpand * hFac); 387 elvH = innerHeight + elemExpand; 388 elemNegativeExpand = elemExpand * -1; 389 beforeExpandVal = elemExpand; 390 } 391 392 rect = lazyloadElems[i].getBoundingClientRect(); 393 394 if ((eLbottom = rect.bottom) >= elemNegativeExpand && 395 (eLtop = rect.top) <= elvH && 396 (eLright = rect.right) >= elemNegativeExpand * hFac && 397 (eLleft = rect.left) <= eLvW && 398 (eLbottom || eLright || eLleft || eLtop) && 399 (lazySizesCfg.loadHidden || isVisible(lazyloadElems[i])) && 400 ((isCompleted && isLoading < 3 && !elemExpandVal && (loadMode < 3 || lowRuns < 4)) || isNestedVisible(lazyloadElems[i], elemExpand))){ 401 unveilElement(lazyloadElems[i]); 402 loadedSomething = true; 403 if(isLoading > 9){break;} 404 } else if(!loadedSomething && isCompleted && !autoLoadElem && 405 isLoading < 4 && lowRuns < 4 && loadMode > 2 && 406 (preloadElems[0] || lazySizesCfg.preloadAfterLoad) && 407 (preloadElems[0] || (!elemExpandVal && ((eLbottom || eLright || eLleft || eLtop) || lazyloadElems[i][_getAttribute](lazySizesCfg.sizesAttr) != 'auto')))){ 408 autoLoadElem = preloadElems[0] || lazyloadElems[i]; 409 } 410 } 411 412 if(autoLoadElem && !loadedSomething){ 413 unveilElement(autoLoadElem); 414 } 415 } 416 }; 417 418 var throttledCheckElements = throttle(checkElements); 419 420 var switchLoadingClass = function(e){ 421 var elem = e.target; 422 423 if (elem._lazyCache) { 424 delete elem._lazyCache; 425 return; 426 } 427 428 resetPreloading(e); 429 addClass(elem, lazySizesCfg.loadedClass); 430 removeClass(elem, lazySizesCfg.loadingClass); 431 addRemoveLoadEvents(elem, rafSwitchLoadingClass); 432 triggerEvent(elem, 'lazyloaded'); 433 }; 434 var rafedSwitchLoadingClass = rAFIt(switchLoadingClass); 435 var rafSwitchLoadingClass = function(e){ 436 rafedSwitchLoadingClass({target: e.target}); 437 }; 438 439 var changeIframeSrc = function(elem, src){ 440 try { 441 elem.contentWindow.location.replace(src); 442 } catch(e){ 443 elem.src = src; 444 } 445 }; 446 447 var handleSources = function(source){ 448 var customMedia; 449 450 var sourceSrcset = source[_getAttribute](lazySizesCfg.srcsetAttr); 451 452 if( (customMedia = lazySizesCfg.customMedia[source[_getAttribute]('data-media') || source[_getAttribute]('media')]) ){ 453 source.setAttribute('media', customMedia); 454 } 455 456 if(sourceSrcset){ 457 source.setAttribute('srcset', sourceSrcset); 458 } 459 }; 460 461 var lazyUnveil = rAFIt(function (elem, detail, isAuto, sizes, isImg){ 462 var src, srcset, parent, isPicture, event, firesLoad; 463 464 if(!(event = triggerEvent(elem, 'lazybeforeunveil', detail)).defaultPrevented){ 465 466 if(sizes){ 467 if(isAuto){ 468 addClass(elem, lazySizesCfg.autosizesClass); 469 } else { 470 elem.setAttribute('sizes', sizes); 471 } 472 } 473 474 srcset = elem[_getAttribute](lazySizesCfg.srcsetAttr); 475 src = elem[_getAttribute](lazySizesCfg.srcAttr); 476 477 if(isImg) { 478 parent = elem.parentNode; 479 isPicture = parent && regPicture.test(parent.nodeName || ''); 480 } 481 482 firesLoad = detail.firesLoad || (('src' in elem) && (srcset || src || isPicture)); 483 484 event = {target: elem}; 485 486 addClass(elem, lazySizesCfg.loadingClass); 487 488 if(firesLoad){ 489 clearTimeout(resetPreloadingTimer); 490 resetPreloadingTimer = setTimeout(resetPreloading, 2500); 491 addRemoveLoadEvents(elem, rafSwitchLoadingClass, true); 492 } 493 494 if(isPicture){ 495 forEach.call(parent.getElementsByTagName('source'), handleSources); 496 } 497 498 if(srcset){ 499 elem.setAttribute('srcset', srcset); 500 } else if(src && !isPicture){ 501 if(regIframe.test(elem.nodeName)){ 502 changeIframeSrc(elem, src); 503 } else { 504 elem.src = src; 505 } 506 } 507 508 if(isImg && (srcset || isPicture)){ 509 updatePolyfill(elem, {src: src}); 510 } 511 } 512 513 if(elem._lazyRace){ 514 delete elem._lazyRace; 515 } 516 removeClass(elem, lazySizesCfg.lazyClass); 517 518 rAF(function(){ 519 // Part of this can be removed as soon as this fix is older: https://bugs.chromium.org/p/chromium/issues/detail?id=7731 (2015) 520 var isLoaded = elem.complete && elem.naturalWidth > 1; 521 522 if( !firesLoad || isLoaded){ 523 if (isLoaded) { 524 addClass(elem, 'ls-is-cached'); 525 } 526 switchLoadingClass(event); 527 elem._lazyCache = true; 528 setTimeout(function(){ 529 if ('_lazyCache' in elem) { 530 delete elem._lazyCache; 531 } 532 }, 9); 533 } 534 if (elem.loading == 'lazy') { 535 isLoading--; 536 } 537 }, true); 538 }); 539 540 var unveilElement = function (elem){ 541 if (elem._lazyRace) {return;} 542 var detail; 543 544 var isImg = regImg.test(elem.nodeName); 545 546 //allow using sizes="auto", but don't use. it's invalid. Use data-sizes="auto" or a valid value for sizes instead (i.e.: sizes="80vw") 547 var sizes = isImg && (elem[_getAttribute](lazySizesCfg.sizesAttr) || elem[_getAttribute]('sizes')); 548 var isAuto = sizes == 'auto'; 549 550 if( (isAuto || !isCompleted) && isImg && (elem[_getAttribute]('src') || elem.srcset) && !elem.complete && !hasClass(elem, lazySizesCfg.errorClass) && hasClass(elem, lazySizesCfg.lazyClass)){return;} 551 552 detail = triggerEvent(elem, 'lazyunveilread').detail; 553 554 if(isAuto){ 555 autoSizer.updateElem(elem, true, elem.offsetWidth); 556 } 557 558 elem._lazyRace = true; 559 isLoading++; 560 561 lazyUnveil(elem, detail, isAuto, sizes, isImg); 562 }; 563 564 var afterScroll = debounce(function(){ 565 lazySizesCfg.loadMode = 3; 566 throttledCheckElements(); 567 }); 568 569 var altLoadmodeScrollListner = function(){ 570 if(lazySizesCfg.loadMode == 3){ 571 lazySizesCfg.loadMode = 2; 572 } 573 afterScroll(); 574 }; 575 576 var onload = function(){ 577 if(isCompleted){return;} 578 if(Date.now() - started < 999){ 579 setTimeout(onload, 999); 580 return; 581 } 582 583 584 isCompleted = true; 585 586 lazySizesCfg.loadMode = 3; 587 588 throttledCheckElements(); 589 590 addEventListener('scroll', altLoadmodeScrollListner, true); 591 }; 592 593 return { 594 _: function(){ 595 started = Date.now(); 596 597 lazysizes.elements = document.getElementsByClassName(lazySizesCfg.lazyClass); 598 preloadElems = document.getElementsByClassName(lazySizesCfg.lazyClass + ' ' + lazySizesCfg.preloadClass); 599 600 addEventListener('scroll', throttledCheckElements, true); 601 602 addEventListener('resize', throttledCheckElements, true); 603 604 addEventListener('pageshow', function (e) { 605 if (e.persisted) { 606 var loadingElements = document.querySelectorAll('.' + lazySizesCfg.loadingClass); 607 608 if (loadingElements.length && loadingElements.forEach) { 609 requestAnimationFrame(function () { 610 loadingElements.forEach( function (img) { 611 if (img.complete) { 612 unveilElement(img); 613 } 614 }); 615 }); 616 } 617 } 618 }); 619 620 if(window.MutationObserver){ 621 new MutationObserver( throttledCheckElements ).observe( docElem, {childList: true, subtree: true, attributes: true} ); 622 } else { 623 docElem[_addEventListener]('DOMNodeInserted', throttledCheckElements, true); 624 docElem[_addEventListener]('DOMAttrModified', throttledCheckElements, true); 625 setInterval(throttledCheckElements, 999); 626 } 627 628 addEventListener('hashchange', throttledCheckElements, true); 629 630 //, 'fullscreenchange' 631 ['focus', 'mouseover', 'click', 'load', 'transitionend', 'animationend'].forEach(function(name){ 632 document[_addEventListener](name, throttledCheckElements, true); 633 }); 634 635 if((/d$|^c/.test(document.readyState))){ 636 onload(); 637 } else { 638 addEventListener('load', onload); 639 document[_addEventListener]('DOMContentLoaded', throttledCheckElements); 640 setTimeout(onload, 20000); 641 } 642 643 if(lazysizes.elements.length){ 644 checkElements(); 645 rAF._lsFlush(); 646 } else { 647 throttledCheckElements(); 648 } 649 }, 650 checkElems: throttledCheckElements, 651 unveil: unveilElement, 652 _aLSL: altLoadmodeScrollListner, 653 }; 654 })(); 655 656 657 var autoSizer = (function(){ 658 var autosizesElems; 659 660 var sizeElement = rAFIt(function(elem, parent, event, width){ 661 var sources, i, len; 662 elem._lazysizesWidth = width; 663 width += 'px'; 664 665 elem.setAttribute('sizes', width); 666 667 if(regPicture.test(parent.nodeName || '')){ 668 sources = parent.getElementsByTagName('source'); 669 for(i = 0, len = sources.length; i < len; i++){ 670 sources[i].setAttribute('sizes', width); 671 } 672 } 673 674 if(!event.detail.dataAttr){ 675 updatePolyfill(elem, event.detail); 676 } 677 }); 678 var getSizeElement = function (elem, dataAttr, width){ 679 var event; 680 var parent = elem.parentNode; 681 682 if(parent){ 683 width = getWidth(elem, parent, width); 684 event = triggerEvent(elem, 'lazybeforesizes', {width: width, dataAttr: !!dataAttr}); 685 686 if(!event.defaultPrevented){ 687 width = event.detail.width; 688 689 if(width && width !== elem._lazysizesWidth){ 690 sizeElement(elem, parent, event, width); 691 } 692 } 693 } 694 }; 695 696 var updateElementsSizes = function(){ 697 var i; 698 var len = autosizesElems.length; 699 if(len){ 700 i = 0; 701 702 for(; i < len; i++){ 703 getSizeElement(autosizesElems[i]); 704 } 705 } 706 }; 707 708 var debouncedUpdateElementsSizes = debounce(updateElementsSizes); 709 710 return { 711 _: function(){ 712 autosizesElems = document.getElementsByClassName(lazySizesCfg.autosizesClass); 713 addEventListener('resize', debouncedUpdateElementsSizes); 714 }, 715 checkElems: debouncedUpdateElementsSizes, 716 updateElem: getSizeElement 717 }; 718 })(); 719 720 var init = function(){ 721 if(!init.i && document.getElementsByClassName){ 722 init.i = true; 723 autoSizer._(); 724 loader._(); 725 } 726 }; 727 728 setTimeout(function(){ 729 if(lazySizesCfg.init){ 730 init(); 731 } 732 }); 733 734 lazysizes = { 735 cfg: lazySizesCfg, 736 autoSizer: autoSizer, 737 loader: loader, 738 init: init, 739 uP: updatePolyfill, 740 aC: addClass, 741 rC: removeClass, 742 hC: hasClass, 743 fire: triggerEvent, 744 gW: getWidth, 745 rAF: rAF, 746 }; 747 748 return lazysizes; 749} 750));
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.