PageSourceSearch

https://www.fareedarmaly.net/site/templates/lib/lazysizes/lazysizes.js?rand=212

js fareedarmaly.net collected 2026-09-24 10:18:33 UTC 17,332 bytes, 697 lines download raw bytes

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.