1/** 2 * DW App Splash â lp_hero rotator 3 * 4 * Cross-fades through all uploaded screenshots inside each .lp-device 5 * frame. Each tick advances that frame's active screenshot by one. The 6 * loop is per-frame and generic, so it works for the single LP hero 7 * phone (the only caller today) or any number of frames. 8 * 9 * Runs on every viewport size (mobile included â the user explicitly 10 * wants the rotation everywhere). Skipped only when the device 11 * indicates prefers-reduced-motion. 12 */ 13(function () { 14 'use strict'; 15 16 if (typeof window === 'undefined') return; 17 18 // Honour reduced-motion preference. 19 try { 20 if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) { 21 return; 22 } 23 } catch (e) {} 24 25 function ready(fn) { 26 if (document.readyState !== 'loading') fn(); 27 else document.addEventListener('DOMContentLoaded', fn); 28 } 29 30 // Promote a deferred shot's data-src/data-srcset to real src/srcset so it 31 // actually downloads. Shots after the first render WITHOUT a URL (PHP holds 32 // it back so the initial load pays for one image only); this is what streams 33 // the rest in, one just-ahead of the fade. Idempotent per <img>. 34 function loadShot(img) { 35 if (!img || img.dataset.lpLoaded) return; 36 img.dataset.lpLoaded = '1'; 37 var pic = img.parentElement; 38 if (pic && pic.tagName === 'PICTURE') { 39 pic.querySelectorAll('source[data-srcset]').forEach(function (s) { 40 s.srcset = s.dataset.srcset; 41 }); 42 } 43 if (img.dataset.src) img.src = img.dataset.src; 44 } 45 46 ready(function () { 47 document.querySelectorAll('.lp-devices[data-rotate-interval]').forEach(function (group) { 48 var intervalSec = parseInt(group.getAttribute('data-rotate-interval'), 10) || 5; 49 var devices = group.querySelectorAll('.lp-device'); 50 if (!devices.length) return; 51 52 // Per-device current index â initialised from the active slide 53 // PHP placed. 54 var indices = Array.prototype.map.call(devices, function (d) { 55 var slides = d.querySelectorAll('.lp-device__shot'); 56 for (var i = 0; i < slides.length; i++) { 57 if (slides[i].classList.contains('lp-device__shot--active')) return i; 58 } 59 return 0; 60 }); 61 62 // Warm the shot after the active one on each device, so it has finished 63 // (or nearly) by the time the first tick fades it in. The active shot is 64 // already loaded eagerly by the browser. 65 devices.forEach(function (d, idx) { 66 var slides = d.querySelectorAll('.lp-device__shot'); 67 loadShot(slides[indices[idx]]); 68 if (slides.length > 1) loadShot(slides[(indices[idx] + 1) % slides.length]); 69 }); 70 71 function tick() { 72 devices.forEach(function (d, idx) { 73 var slides = d.querySelectorAll('.lp-device__shot'); 74 if (slides.length < 2) return; 75 var prev = indices[idx]; 76 var next = (prev + 1) % slides.length; 77 slides[prev].classList.remove('lp-device__shot--active'); 78 slides[next].classList.add('lp-device__shot--active'); 79 indices[idx] = next; 80 // Prefetch one ahead so the NEXT fade always has its image ready. 81 loadShot(slides[(next + 1) % slides.length]); 82 }); 83 } 84 85 // Pause when the page is hidden so we don't spin uselessly. 86 var timer = null; 87 function start() { 88 if (timer) return; 89 timer = window.setInterval(tick, intervalSec * 1000); 90 } 91 function stop() { 92 if (!timer) return; 93 clearInterval(timer); 94 timer = null; 95 } 96 start(); 97 document.addEventListener('visibilitychange', function () { 98 if (document.hidden) stop(); else start(); 99 }); 100 }); 101 }); 102})();
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.