PageSourceSearch

https://www.perfectdraft.com/static/version0.0.0.1228/frontend/Bee…/en_BE/Magento_Theme/js/lazysizes.js

js perfectdraft.com collected 2026-10-09 22:39:33 UTC 17,588 bytes, 698 lines download raw bytes

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.