PageSourceSearch

https://www.xyner.ai/assets/js/main.js?v=9.12

js xyner.ai collected 2026-10-05 14:03:21 UTC 3,175 bytes, 71 lines download raw bytes

1// Mobile nav drawer behavior + year stamp.
2// The burger button uses an inline onclick (see layout.js template).
3// The top-level nav-link <a> uses inline onclick to toggle .is-open on its parent <li>.
4(function () {
5  // When the user expands a top-level item, scroll the open header to the
6  // top of the drawer so the sub-items have maximum vertical room.
7  // (We watch for class mutations on the parent <ul> rather than wiring
8  // a separate click handler so we don't double-fire with the inline onclick.)
9  function watchDrawer() {
10    var drawer = document.getElementById('navLinks') || document.querySelector('.nav-links');
11    if (!drawer || drawer.__watched) return;
12    drawer.__watched = true;
13    var obs = new MutationObserver(function (mutations) {
14      mutations.forEach(function (m) {
15        if (m.type !== 'attributes' || m.attributeName !== 'class') return;
16        var li = m.target;
17        if (!li.classList.contains('is-open')) return;
18        if (!drawer.classList.contains('open')) return;
19        // Scroll the opened header to the top of the drawer.
20        // Wait a tick so the .mega has rendered before measuring.
21        setTimeout(function () {
22          var link = li.querySelector(':scope > .nav-link');
23          if (!link) return;
24          var offset = link.offsetTop - drawer.scrollTop;
25          drawer.scrollBy({ top: offset - 4, left: 0, behavior: 'smooth' });
26        }, 30);
27      });
28    });
29    // Observe every .nav-item child for class changes
30    drawer.querySelectorAll('.nav-item').forEach(function (li) {
31      obs.observe(li, { attributes: true, attributeFilter: ['class'] });
32    });
33  }
34
35  // Wire up after DOM is ready (and again on first burger tap, in case the
36  // drawer markup is injected late).
37  if (document.readyState === 'loading') {
38    document.addEventListener('DOMContentLoaded', watchDrawer);
39  } else { watchDrawer(); }
40  // Re-arm whenever the burger opens the drawer
41  document.addEventListener('click', function (e) {
42    if (e.target.closest && e.target.closest('.nav-toggle')) {
43      setTimeout(watchDrawer, 20);
44    }
45  });
46
47  // Close the entire drawer when a real link (menu-item) inside it is tapped.
48  document.addEventListener('click', function (e) {
49    var link = e.target.closest && e.target.closest('#navLinks .menu-item, .nav-links .menu-item');
50    if (!link) return;
51    var links = document.getElementById('navLinks') || document.querySelector('.nav-links');
52    if (links && links.classList.contains('open')) {
53      links.classList.remove('open');
54      document.body.classList.remove('nav-open');
55      links.querySelectorAll('.nav-item.is-open').forEach(function (n) { n.classList.remove('is-open'); });
56      var btn = document.querySelector('.nav-toggle');
57      if (btn) btn.setAttribute('aria-expanded', 'false');
58    }
59  });
60
61  // Year stamp
62  document.querySelectorAll('[data-year]').forEach(function (el) {
63    el.textContent = new Date().getFullYear();
64  });
65
66  // Make sure no element stays invisible from old reveal styles
67  document.querySelectorAll('[data-reveal]').forEach(function (el) {
68    el.style.opacity = '1';
69    el.style.transform = 'none';
70  });
71})();

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.