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