vendor: 4,302 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 = lazySizesConfig.throttleDelay; 167 var rICTimeout = lazySizesConfig.ricTimeout; 168 var run = function () { 169 running = false; 170 lastTime = Date.now(); 171 fn(); 172 }; 173 var idleCallback = requestIdleCallback && rICTimeout > 49 ? 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
vendor: 13,286 bytes, lines 199-698
199 delay = gDelay - (Date.now() - lastTime); 200 201 if (delay < 0) { 202 delay = 0; 203 } 204 205 if (isPriority || delay < 9) { 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: 0, 263 throttleDelay: 125, 264 }; 265 266 lazySizesConfig = window.lazySizesConfig || window.lazysizesConfig || {}; 267 268 for (prop in lazySizesDefaults) { 269 if (!(prop in lazySizesConfig)) { 270 lazySizesConfig[prop] = lazySizesDefaults[prop]; 271 } 272 } 273 274 window.lazySizesConfig = lazySizesConfig; 275 276 setTimeout(function () { 277 if (lazySizesConfig.init) { 278 init(); 279 } 280 }); 281 })(); 282 283 var loader = (function () { 284 var preloadElems, isCompleted, resetPreloadingTimer, loadMode, started; 285 286 var eLvW, elvH, eLtop, eLleft, eLright, eLbottom; 287 288 var defaultExpand, preloadExpand, hFac; 289 290 var regImg = /^img$/i; 291 var regIframe = /^iframe$/i; 292 293 var supportScroll = ('onscroll' in window) && !(/glebot/.test(navigator.userAgent)); 294 295 var shrinkExpand = 0; 296 var currentExpand = 0; 297 298 var isLoading = 0; 299 var lowRuns = -1; 300 301 var resetPreloading = function (e) { 302 isLoading--; 303 if (e && e.target) { 304 addRemoveLoadEvents(e.target, resetPreloading); 305 } 306 307 if (!e || isLoading < 0 || !e.target) { 308 isLoading = 0; 309 } 310 }; 311 312 var isNestedVisible = function (elem, elemExpand) { 313 var outerRect; 314 var parent = elem; 315 var visible = getCSS(document.body, 'visibility') == 'hidden' || getCSS(elem, 'visibility') != 'hidden'; 316 317 eLtop -= elemExpand; 318 eLbottom += elemExpand; 319 eLleft -= elemExpand; 320 eLright += elemExpand; 321 322 while (visible && (parent = parent.offsetParent) && parent != document.body && parent != docElem) { 323 visible = ((getCSS(parent, 'opacity') || 1) > 0); 324 325 if (visible && getCSS(parent, 'overflow') != 'visible') { 326 outerRect = parent.getBoundingClientRect(); 327 visible = eLright > outerRect.left && 328 eLleft < outerRect.right && 329 eLbottom > outerRect.top - 1 && 330 eLtop < outerRect.bottom + 1 331 ; 332 } 333 } 334 335 return visible; 336 }; 337 338 var checkElements = function () { 339 var eLlen, i, rect, autoLoadElem, loadedSomething, elemExpand, elemNegativeExpand, elemExpandVal, beforeExpandVal; 340 341 var lazyloadElems = lazysizes.elements; 342 343 if ((loadMode = lazySizesConfig.loadMode) && isLoading < 8 && (eLlen = lazyloadElems.length)) { 344 345 i = 0; 346 347 lowRuns++; 348 349 if (preloadExpand == null) { 350 if (!('expand' in lazySizesConfig)) { 351 lazySizesConfig.expand = docElem.clientHeight > 500 && docElem.clientWidth > 500 ? 500 : 370; 352 } 353 354 defaultExpand = lazySizesConfig.expand; 355 preloadExpand = defaultExpand * lazySizesConfig.expFactor; 356 } 357 358 if (currentExpand < preloadExpand && isLoading < 1 && lowRuns > 2 && loadMode > 2 && !document.hidden) { 359 currentExpand = preloadExpand; 360 lowRuns = 0; 361 } else if (loadMode > 1 && lowRuns > 1 && isLoading < 6) { 362 currentExpand = defaultExpand; 363 } else { 364 currentExpand = shrinkExpand; 365 } 366 367 for (; i < eLlen; i++) { 368 369 if (!lazyloadElems[i] || lazyloadElems[i]._lazyRace) { continue; } 370 371 if (!supportScroll) { unveilElement(lazyloadElems[i]); continue; } 372 373 if (!(elemExpandVal = lazyloadElems[i][_getAttribute]('data-expand')) || !(elemExpand = elemExpandVal * 1)) { 374 elemExpand = currentExpand; 375 } 376 377 if (beforeExpandVal !== elemExpand) { 378 eLvW = innerWidth + (elemExpand * hFac); 379 elvH = innerHeight + elemExpand; 380 elemNegativeExpand = elemExpand * -1; 381 beforeExpandVal = elemExpand; 382 } 383 384 rect = lazyloadElems[i].getBoundingClientRect(); 385 386 if ((eLbottom = rect.bottom) >= elemNegativeExpand && 387 (eLtop = rect.top) <= elvH && 388 (eLright = rect.right) >= elemNegativeExpand * hFac && 389 (eLleft = rect.left) <= eLvW && 390 (eLbottom || eLright || eLleft || eLtop) && 391 (lazySizesConfig.loadHidden || getCSS(lazyloadElems[i], 'visibility') != 'hidden') && 392 ((isCompleted && isLoading < 3 && !elemExpandVal && (loadMode < 3 || lowRuns < 4)) || isNestedVisible(lazyloadElems[i], elemExpand))) { 393 unveilElement(lazyloadElems[i]); 394 loadedSomething = true; 395 if (isLoading > 9) { break; } 396 } else if (!loadedSomething && isCompleted && !autoLoadElem && 397 isLoading < 4 && lowRuns < 4 && loadMode > 2 && 398 (preloadElems[0] || lazySizesConfig.preloadAfterLoad) && 399 (preloadElems[0] || (!elemExpandVal && ((eLbottom || eLright || eLleft || eLtop) || lazyloadElems[i][_getAttribute](lazySizesConfig.sizesAttr) != 'auto')))) { 400 autoLoadElem = preloadElems[0] || lazyloadElems[i]; 401 } 402 } 403 404 if (autoLoadElem && !loadedSomething) { 405 unveilElement(autoLoadElem); 406 } 407 } 408 }; 409 410 var throttledCheckElements = throttle(checkElements); 411 412 var switchLoadingClass = function (e) { 413 addClass(e.target, lazySizesConfig.loadedClass); 414 removeClass(e.target, lazySizesConfig.loadingClass); 415 addRemoveLoadEvents(e.target, rafSwitchLoadingClass); 416 triggerEvent(e.target, 'lazyloaded'); 417 }; 418 var rafedSwitchLoadingClass = rAFIt(switchLoadingClass); 419 var rafSwitchLoadingClass = function (e) { 420 rafedSwitchLoadingClass({ target: e.target }); 421 }; 422 423 var changeIframeSrc = function (elem, src) { 424 try { 425 elem.contentWindow.location.replace(src); 426 } catch (e) { 427 elem.src = src; 428 } 429 }; 430 431 var handleSources = function (source) { 432 var customMedia; 433 434 var sourceSrcset = source[_getAttribute](lazySizesConfig.srcsetAttr); 435 436 if ((customMedia = lazySizesConfig.customMedia[source[_getAttribute]('data-media') || source[_getAttribute]('media')])) { 437 source.setAttribute('media', customMedia); 438 } 439 440 if (sourceSrcset) { 441 source.setAttribute('srcset', sourceSrcset); 442 } 443 }; 444 445 var lazyUnveil = rAFIt(function (elem, detail, isAuto, sizes, isImg) { 446 var src, srcset, parent, isPicture, event, firesLoad; 447 448 if (!(event = triggerEvent(elem, 'lazybeforeunveil', detail)).defaultPrevented) { 449 450 if (sizes) { 451 if (isAuto) { 452 addClass(elem, lazySizesConfig.autosizesClass); 453 } else { 454 elem.setAttribute('sizes', sizes); 455 } 456 } 457 458 srcset = elem[_getAttribute](lazySizesConfig.srcsetAttr); 459 src = elem[_getAttribute](lazySizesConfig.srcAttr); 460 461 if (isImg) { 462 parent = elem.parentNode; 463 isPicture = parent && regPicture.test(parent.nodeName || ''); 464 } 465 466 firesLoad = detail.firesLoad || (('src' in elem) && (srcset || src || isPicture)); 467 468 event = { target: elem }; 469 470 if (firesLoad) { 471 addRemoveLoadEvents(elem, resetPreloading, true); 472 clearTimeout(resetPreloadingTimer); 473 resetPreloadingTimer = setTimeout(resetPreloading, 2500); 474 475 addClass(elem, lazySizesConfig.loadingClass); 476 addRemoveLoadEvents(elem, rafSwitchLoadingClass, true); 477 } 478 479 if (isPicture) { 480 forEach.call(parent.getElementsByTagName('source'), handleSources); 481 } 482 483 if (srcset) { 484 elem.setAttribute('srcset', srcset); 485 } else if (src && !isPicture) { 486 if (regIframe.test(elem.nodeName)) { 487 changeIframeSrc(elem, src); 488 } else { 489 elem.src = src; 490 } 491 } 492 493 if (isImg && (srcset || isPicture)) { 494 updatePolyfill(elem, { src: src }); 495 } 496 } 497 498 if (elem._lazyRace) { 499 delete elem._lazyRace; 500 } 501 removeClass(elem, lazySizesConfig.lazyClass); 502 503 rAF(function () { 504 if (!firesLoad || (elem.complete && elem.naturalWidth > 1)) { 505 if (firesLoad) { 506 resetPreloading(event); 507 } else { 508 isLoading--; 509 } 510 switchLoadingClass(event); 511 } 512 }, true); 513 }); 514 515 var unveilElement = function (elem) { 516 var detail; 517 518 var isImg = regImg.test(elem.nodeName); 519 520 //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") 521 var sizes = isImg && (elem[_getAttribute](lazySizesConfig.sizesAttr) || elem[_getAttribute]('sizes')); 522 var isAuto = sizes == 'auto'; 523 524 if ((isAuto || !isCompleted) && isImg && (elem[_getAttribute]('src') || elem.srcset) && !elem.complete && !hasClass(elem, lazySizesConfig.errorClass) && hasClass(elem, lazySizesConfig.lazyClass)) { return; } 525 526 detail = triggerEvent(elem, 'lazyunveilread').detail; 527 528 if (isAuto) { 529 autoSizer.updateElem(elem, true, elem.offsetWidth); 530 } 531 532 elem._lazyRace = true; 533 isLoading++; 534 535 lazyUnveil(elem, detail, isAuto, sizes, isImg); 536 }; 537 538 var onload = function () { 539 if (isCompleted) { return; } 540 if (Date.now() - started < 999) { 541 setTimeout(onload, 999); 542 return; 543 } 544 var afterScroll = debounce(function () { 545 lazySizesConfig.loadMode = 3; 546 throttledCheckElements(); 547 }); 548 549 isCompleted = true; 550 551 lazySizesConfig.loadMode = 3; 552 553 throttledCheckElements(); 554 555 addEventListener('scroll', function () { 556 if (lazySizesConfig.loadMode == 3) { 557 lazySizesConfig.loadMode = 2; 558 } 559 afterScroll(); 560 }, true); 561 }; 562 563 return { 564 _: function () { 565 started = Date.now(); 566 567 lazysizes.elements = document.getElementsByClassName(lazySizesConfig.lazyClass); 568 preloadElems = document.getElementsByClassName(lazySizesConfig.lazyClass + ' ' + lazySizesConfig.preloadClass); 569 hFac = lazySizesConfig.hFac; 570 571 addEventListener('scroll', throttledCheckElements, true); 572 573 addEventListener('resize', throttledCheckElements, true); 574 575 if (window.MutationObserver) { 576 new MutationObserver(throttledCheckElements).observe(docElem, { childList: true, subtree: true, attributes: true }); 577 } else { 578 docElem[_addEventListener]('DOMNodeInserted', throttledCheckElements, true); 579 docElem[_addEventListener]('DOMAttrModified', throttledCheckElements, true); 580 setInterval(throttledCheckElements, 999); 581 } 582 583 addEventListener('hashchange', throttledCheckElements, true); 584 585 //, 'fullscreenchange' 586 ['focus', 'mouseover', 'click', 'load', 'transitionend', 'animationend', 'webkitAnimationEnd'].forEach(function (name) { 587 document[_addEventListener](name, throttledCheckElements, true); 588 }); 589 590 if ((/d$|^c/.test(document.readyState))) { 591 onload(); 592 } else { 593 addEventListener('load', onload); 594 document[_addEventListener]('DOMContentLoaded', throttledCheckElements); 595 setTimeout(onload, 20000); 596 } 597 598 if (lazysizes.elements.length) { 599 checkElements(); 600 rAF._lsFlush(); 601 } else { 602 throttledCheckElements(); 603 } 604 }, 605 checkElems: throttledCheckElements, 606 unveil: unveilElement 607 }; 608 })(); 609 610 611 var autoSizer = (function () { 612 var autosizesElems; 613 614 var sizeElement = rAFIt(function (elem, parent, event, width) { 615 var sources, i, len; 616 elem._lazysizesWidth = width; 617 width += 'px'; 618 619 elem.setAttribute('sizes', width); 620 621 if (regPicture.test(parent.nodeName || '')) { 622 sources = parent.getElementsByTagName('source'); 623 for (i = 0, len = sources.length; i < len; i++) { 624 sources[i].setAttribute('sizes', width); 625 } 626 } 627 628 if (!event.detail.dataAttr) { 629 updatePolyfill(elem, event.detail); 630 } 631 }); 632 var getSizeElement = function (elem, dataAttr, width) { 633 var event; 634 var parent = elem.parentNode; 635 636 if (parent) { 637 width = getWidth(elem, parent, width); 638 event = triggerEvent(elem, 'lazybeforesizes', { width: width, dataAttr: !!dataAttr }); 639 640 if (!event.defaultPrevented) { 641 width = event.detail.width; 642 643 if (width && width !== elem._lazysizesWidth) { 644 sizeElement(elem, parent, event, width); 645 } 646 } 647 } 648 }; 649 650 var updateElementsSizes = function () { 651 var i; 652 var len = autosizesElems.length; 653 if (len) { 654 i = 0; 655 656 for (; i < len; i++) { 657 getSizeElement(autosizesElems[i]); 658 } 659 } 660 }; 661 662 var debouncedUpdateElementsSizes = debounce(updateElementsSizes); 663 664 return { 665 _: function () { 666 autosizesElems = document.getElementsByClassName(lazySizesConfig.autosizesClass); 667 addEventListener('resize', debouncedUpdateElementsSizes); 668 }, 669 checkElems: debouncedUpdateElementsSizes, 670 updateElem: getSizeElement 671 }; 672 })(); 673 674 var init = function () { 675 if (!init.i) { 676 init.i = true; 677 autoSizer._(); 678 loader._(); 679 } 680 }; 681 682 lazysizes = { 683 cfg: lazySizesConfig, 684 autoSizer: autoSizer, 685 loader: loader, 686 init: init, 687 uP: updatePolyfill, 688 aC: addClass, 689 rC: removeClass, 690 hC: hasClass, 691 fire: triggerEvent, 692 gW: getWidth, 693 rAF: rAF, 694 }; 695 696 return lazysizes; 697} 698));
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.