PageSourceSearch

https://docs.sensu.io/js/toc.js

js sensu.io collected 2026-10-02 06:24:10 UTC 2,266 bytes, 58 lines download raw bytes

1// This is messy, because docs content isn't nested in <section>s. Instead, we:
2//   1. Detect the ToC anchors (links)
3//   2. Query the <article> for these headings
4//   3. Re-format the ToC (in Hugo v0.70.0, the template is not customizable)
5//   4. Split the <article>'s childNodes into <section>s with these headings as boundaries
6//   5. Use the new parent <sections> as IntersectionObserver entries
7(function () {
8  // 1
9  const $toc = document.getElementById('TableOfContents');
10  if (!$toc) return;
11  const $tocElements = Array.from($toc.querySelectorAll('li')).filter($el => $el.innerHTML.trim());
12  const tocLinks = $tocElements.map($li => (
13    `#${CSS.escape($li.querySelector('a').getAttribute('href').replace('#', ''))}`
14  ));
15
16  // 2
17  const $headings = Array.from(document.querySelectorAll(tocLinks.join(',')));
18  // 3
19  $headings.map(($heading, i) => (
20    $tocElements[i].classList.add($heading.tagName.toLowerCase())
21  ));
22  while($toc.firstChild){
23    $toc.removeChild($toc.firstChild);
24  }
25  $tocElements.forEach($el => $toc.appendChild($el));
26
27  // 4
28  const $article = document.querySelector('main article h1').parentElement;
29  const $articleNodes = Array.from($article.childNodes);
30  // Use Set for unique indices
31  const sectionBoundaries = [...new Set([
32      0,
33      ...$headings.map($heading => (
34        // $heading.tagName === 'H2' ? $articleNodes.indexOf($heading) : 0
35        $articleNodes.indexOf($heading)
36      )),
37      $articleNodes.length - 1
38    ])];
39  for (let i=1; i < sectionBoundaries.length; i++) {
40    const $section = document.createElement('section');
41    $article.appendChild($section);
42    $articleNodes.slice(sectionBoundaries[i-1], sectionBoundaries[i]).map($child => $section.appendChild($child));
43  }
44
45  // 5
46  const observer = new IntersectionObserver(entries => {
47    entries.forEach(entry => {
48      const id = CSS.escape(entry.target.firstChild.getAttribute('id'));
49      const $li = $toc.querySelector(`a[href="#${id}"]`).parentElement;
50      if (entry.intersectionRatio > 0) {
51        $li.classList.add('active');
52      } else {
53        $li.classList.remove('active');
54      }
55    });
56  }, { rootMargin: '-125px 0px -60px' });
57  $headings.forEach(heading => observer.observe(heading.parentElement));
58})();

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.