1/** 2 * Cross-fading image panel for a 50:50 split section. 3 * 4 * Markup comes from ce_page_split_section() â see inc/acf-cornerstones-curriculum.php. 5 * The first <img> has a real src and the alt text; the rest carry data-ce-src 6 * and nothing else, so a page with six slides still loads one image until this 7 * runs. Each is fetched just before its turn, not all at once on load. 8 * 9 * It only runs while the panel is on screen and the tab is in front, so a 10 * slideshow nobody is looking at is not quietly downloading images or keeping 11 * a timer alive. 12 * 13 * Doing nothing is a valid outcome: with one slide, with reduced motion asked 14 * for, or with no IntersectionObserver, the first image simply stays put â 15 * which is the same thing the panel showed before this existed. 16 */ 17( function () { 18 'use strict'; 19 20 var INTERVAL = 4500; // ms each slide holds. The CSS fade is 0.7s of it. 21 22 if ( window.matchMedia && window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches ) { 23 return; 24 } 25 26 document.querySelectorAll( '[data-ce-slideshow]' ).forEach( function ( panel ) { 27 28 var slides = Array.prototype.slice.call( panel.querySelectorAll( 'img' ) ); 29 30 if ( slides.length < 2 ) { 31 return; 32 } 33 34 var index = 0; 35 var timer = null; 36 var onView = false; 37 38 /** 39 * Give a slide its src the first time it is needed. 40 * 41 * Returns once the image is usable, so a slow connection delays the 42 * change rather than fading to an empty box. 43 */ 44 function load( slide ) { 45 46 var src = slide.getAttribute( 'data-ce-src' ); 47 48 if ( ! src ) { 49 return Promise.resolve(); // already has a real src 50 } 51 52 slide.removeAttribute( 'data-ce-src' ); 53 slide.src = src; 54 55 return slide.decode 56 ? slide.decode().catch( function () {} ) 57 : Promise.resolve(); 58 } 59 60 function show( next ) { 61 slides[ index ].classList.remove( 'is-current' ); 62 slides[ next ].classList.add( 'is-current' ); 63 index = next; 64 } 65 66 function advance() { 67 68 var next = ( index + 1 ) % slides.length; 69 70 load( slides[ next ] ).then( function () { 71 72 if ( ! onView ) { 73 return; // scrolled away while loading 74 } 75 76 show( next ); 77 78 // Fetch the one after this during the current slide's turn, so 79 // its own change is instant. 80 load( slides[ ( next + 1 ) % slides.length ] ); 81 } ); 82 } 83 84 function start() { 85 if ( ! timer ) { 86 timer = setInterval( advance, INTERVAL ); 87 } 88 } 89 90 function stop() { 91 clearInterval( timer ); 92 timer = null; 93 } 94 95 // Only while the panel is actually on screen. 96 if ( ! ( 'IntersectionObserver' in window ) ) { 97 return; 98 } 99 100 new IntersectionObserver( function ( entries ) { 101 102 onView = entries[ 0 ].isIntersecting; 103 104 if ( onView && ! document.hidden ) { 105 start(); 106 } else { 107 stop(); 108 } 109 110 }, { threshold: 0.25 } ).observe( panel ); 111 112 // A background tab should not keep cycling. 113 document.addEventListener( 'visibilitychange', function () { 114 if ( document.hidden || ! onView ) { 115 stop(); 116 } else { 117 start(); 118 } 119 } ); 120 } ); 121 122}() );
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.