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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | 1x 1x 2x 4x 5x 8x 8x 8x 8x 8x 1x 8x 1x 8x 8x 8x 8x 8x 5x 5x 5x 8x 2x 2x 8x 8x 8x 1x | const util = require( '../util' ), placeholderClass = 'lazy-image-placeholder'; /** * @ignore * @param {HTMLElement} root * @return {HTMLElement[]} */ function queryPlaceholders( root ) { return Array.prototype.slice.call( root.getElementsByClassName( placeholderClass ) ); } /** * Load an image on demand * * @ignore * @param {HTMLElement[]} placeholders a list of images that have not been loaded. * @return {jQuery.Deferred} */ function loadImages( placeholders ) { return util.Promise.all( placeholders.map( ( placeholder ) => module.exports.loadImage( placeholder ).promise ) ); } /** * Load an image on demand * * @ignore * @param {HTMLElement} placeholder * @return {{promise: jQuery.Deferred<'load'|'error'>, image: HTMLImageElement}} */ function loadImage( placeholder ) { const deferred = util.Deferred(), // data-width and height are attributes and do not specify dimension. width = placeholder.dataset.width, height = placeholder.dataset.height, image = new Image(); if ( width ) { image.setAttribute( 'width', parseInt( width, 10 ) ); } if ( height ) { image.setAttribute( 'height', parseInt( height, 10 ) ); } // eslint-disable-next-line mediawiki/class-doc image.className = placeholder.dataset.class || ''; image.alt = placeholder.dataset.alt || ''; image.useMap = placeholder.dataset.usemap; image.style.cssText = placeholder.style.cssText || ''; // When the image has loaded image.addEventListener( 'load', () => { // Swap the HTML inside the placeholder (to keep the layout and // dimensions the same and not trigger layouts image.classList.add( 'image-lazy-loaded' ); Iif ( placeholder.parentNode ) { placeholder.parentNode.replaceChild( image, placeholder ); } deferred.resolve( 'load' ); }, { once: true } ); image.addEventListener( 'error', () => { // Swap the HTML and let the browser decide what to do with the broken image. Iif ( placeholder.parentNode ) { placeholder.parentNode.replaceChild( image, placeholder ); } // Never reject. Quietly resolve so that Promise.all() awaits for all Deferreds to complete. // Reevaluate using Deferred.reject in T136693. deferred.resolve( 'error' ); }, { once: true } ); // Trigger image download after binding the load handler image.src = placeholder.dataset.src || ''; image.srcset = placeholder.dataset.srcset || ''; return { promise: deferred, image }; } module.exports = { placeholderClass, queryPlaceholders, loadImages, loadImage, test: { placeholderClass } }; |