1/** 2 * Breaking ribbon: rotates the server-rendered items every 6 s (fade-up, count badge) and 3 * refreshes the list from the REST API every 60 s when the backend plugin is active. 4 */ 5export default function breaking(data) { 6 const bar = document.querySelector('[data-breaking]'); 7 if (!bar) return; 8 const wrap = bar.querySelector('[data-breaking-items]'); 9 const count = bar.querySelector('[data-breaking-count]'); 10 let i = 0; let timer = 0; 11 12 const rotate = () => { 13 const items = [...wrap.querySelectorAll('.breaking__t')]; 14 if (items.length < 2) return; 15 i = (i + 1) % items.length; 16 items.forEach((el, k) => el.classList.toggle('is-on', k === i)); 17 if (count) count.textContent = `${i + 1}/${items.length}`; 18 }; 19 let paused = false; 20 const arm = () => { 21 clearInterval(timer); 22 if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; 23 if (wrap.querySelectorAll('.breaking__t').length > 1) timer = setInterval(() => { if (!paused) rotate(); }, 6000); 24 }; 25 bar.addEventListener('mouseenter', () => { paused = true; }); 26 bar.addEventListener('mouseleave', () => { paused = false; }); 27 /* motion budget: hold the rotation while the shows hero (its own autoplay) is on screen */ 28 const hero = document.querySelector('.hero-band'); 29 if (hero && 'IntersectionObserver' in window) { 30 new IntersectionObserver((es) => es.forEach((e) => { if (e.isIntersecting) paused = true; else if (!bar.matches(':hover')) paused = false; }), { threshold: 0.3 }).observe(hero); 31 } 32 arm(); 33 34 if (data.restUrl) { 35 const time = bar.querySelector('[data-breaking-time]'); 36 setInterval(() => fetch(data.restUrl + 'breaking', { credentials: 'omit' }).then((r) => (r.ok ? r.json() : null)).then((items) => { 37 if (!Array.isArray(items)) return; 38 bar.hidden = !items.length; 39 if (!items.length) return; 40 wrap.innerHTML = items.map((it, k) => `<a class="breaking__t${k === 0 ? ' is-on' : ''}" href="${it.url}">${it.title.replace(/</g, '<')}</a>`).join(''); 41 i = 0; 42 if (time) time.textContent = ''; 43 arm(); 44 }).catch(() => {}), 60000); 45 } 46}
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.