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