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