All files / mobile.init lazyLoadedImages.js

11.11% Statements 2/18
0% Branches 0/6
0% Functions 0/6
11.11% Lines 2/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 651x                                                                                                                         1x      
const lazyImageLoader = require( '../mobile.startup/lazyImages/lazyImageLoader' );
 
/**
 * Initialise lazy loading images to supplement the HTML changes inside the
 * MobileFormatter.
 *
 * @param {jQuery} $container
 */
function init( $container ) {
 
	// T360781 - since this is invoked via hook, the value of $container is not guaranteed.
	// If undefined, return early since no further work can be done on $container.
	if ( !( $container[ 0 ] instanceof HTMLElement ) ) {
		return;
	}
 
	const imagePlaceholders = lazyImageLoader.queryPlaceholders( $container[ 0 ] );
 
	// Regardless of whether or not lazy load is turned on
	// We need to load in all images before print
	window.addEventListener( 'beforeprint', function () {
		lazyImageLoader.loadImages( imagePlaceholders );
	} );
 
	if ( !mw.config.get( 'wgMFLazyLoadImages' ) ) {
		return;
	}
 
	// eslint-disable-next-line compat/compat
	const observer = new IntersectionObserver(
		( entries ) => {
			entries.forEach( ( entry ) => {
				const placeholder = entry.target;
				// If intersecting load image and stop observing it to free up resources.
				if ( entry.isIntersecting ) {
					lazyImageLoader.loadImage( placeholder );
					observer.unobserve( placeholder );
				}
			} );
		},
		// See https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
		{
			// Setup the area for observing.
			// By default the root is the viewport.
			// We want the detection area to be as tall as 150% of the viewport height,
			// allowing elements to be detected before they reach the viewport.
			// This is achieved with a 50% bottom margin.
			rootMargin: '0px 0px 50% 0px',
			// The default is 0 (meaning as soon as even one pixel is visible,
			// the callback will be run), however we explicitly set this so that
			// it is clear we have made this choice in case we want to revisit later.
			threshold: 0
		}
	);
 
	// observe all the placeholders
	imagePlaceholders.forEach( ( placeholder ) => {
		observer.observe( placeholder );
	} );
}
 
module.exports = function () {
	mw.hook( 'wikipage.content' ).add( init );
};