1/* Site header behaviour. The header's markup is rendered at build time (src/redesign/header.html); this is the 2 behaviour half of the redesign's inline header script, copied verbatim (scripts/redesign/port.mjs warns when the 3 redesign changes it). */ 4(function () { 5 document.documentElement.setAttribute('data-hdr', 'evolve'); 6 const el = document.querySelector('[data-nav]'); 7 const b = el && el.querySelector('.hx-burger'); 8 if (b) b.addEventListener('click', function () { el.classList.toggle('open'); }); 9 10 function scrolled() { const n = document.querySelector('[data-nav]'); if (n) n.classList.toggle('scrolled', window.scrollY > 24); } 11 window.addEventListener('scroll', scrolled, { passive: true }); 12 13 /* menus open on hover and keyboard focus (CSS); a click or tap pins one open (.x), which is what touch 14 screens and the mobile menu use. Escape or a click elsewhere closes; siblings close each other. */ 15 function closeAll(except) { 16 document.querySelectorAll('[data-nav] .x').forEach(function (n) { 17 if (except && n.contains(except)) return; 18 n.classList.remove('x'); 19 const b = n.querySelector(':scope > button, :scope > .cm-st'); if (b) b.setAttribute('aria-expanded', 'false'); 20 }); 21 } 22 document.addEventListener('click', function (e) { 23 const nav = e.target.closest('[data-nav]'); 24 if (!nav) { closeAll(); return; } 25 const b = e.target.closest('.hx-dd > button, .cm-sub > .cm-st'); 26 if (!b) { if (e.target.closest('a[href]')) closeAll(); return; } 27 e.preventDefault(); 28 const n = b.parentNode, open = !n.classList.contains('x'); 29 n.parentNode.querySelectorAll(':scope > .x').forEach(function (s) { if (s !== n) { s.classList.remove('x'); s.querySelector(':scope > button, :scope > .cm-st').setAttribute('aria-expanded', 'false'); } }); 30 n.classList.toggle('x', open); b.setAttribute('aria-expanded', String(open)); 31 }); 32 document.addEventListener('keydown', function (e) { 33 if (e.key !== 'Escape') return; 34 const open = document.querySelector('[data-nav] .x, [data-nav] :focus'); 35 closeAll(); 36 if (open && document.activeElement && document.activeElement.closest('[data-nav]')) document.activeElement.blur(); 37 }); 38 /* with a mouse, leaving a pinned menu closes it again (hover takes over) */ 39 document.addEventListener('mouseout', function (e) { 40 if (!window.matchMedia('(hover: hover)').matches || window.innerWidth <= 1100) return; 41 let n = e.target.closest && e.target.closest('[data-nav] .x'); 42 while (n) { 43 if (!n.contains(e.relatedTarget)) { n.classList.remove('x'); n.querySelector(':scope > button, :scope > .cm-st').setAttribute('aria-expanded', 'false'); } 44 n = n.parentElement.closest('[data-nav] .x'); 45 } 46 }); 47})();
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.