PageSourceSearch

https://netsecurity.com/site/header.js

js netsecurity.com collected 2026-10-02 05:28:01 UTC 2,748 bytes, 47 lines download raw bytes

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.