Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T01:48:18.702Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

page-toc.js

113 lines · 2.9 KB · javascript
1let scrollTimeout;
2
3const listenActive = () => {
4  const elems = document.querySelector(".pagetoc").children;
5  [...elems].forEach((el) => {
6    el.addEventListener("click", (_) => {
7      clearTimeout(scrollTimeout);
8      [...elems].forEach((el) => el.classList.remove("active"));
9      el.classList.add("active");
10
11      scrollTimeout = setTimeout(() => {
12        scrollTimeout = null;
13      }, 100);
14    });
15  });
16};
17
18const autoCreatePagetoc = () => {
19  const main = document.querySelector("#content > main");
20  const content = Object.assign(document.createElement("div"), {
21    className: "content-wrap",
22  });
23  content.append(...main.childNodes);
24  main.prepend(content);
25  main.insertAdjacentHTML(
26    "afterbegin",
27    '<div class="toc-container"><nav class="pagetoc"></nav></div>',
28  );
29  return document.querySelector(".pagetoc");
30};
31
32const getPagetoc = () =>
33  document.querySelector(".pagetoc") || autoCreatePagetoc();
34
35const updateFunction = () => {
36  if (scrollTimeout) return;
37
38  const headers = [...document.getElementsByClassName("header")];
39  if (headers.length === 0) return;
40
41  const threshold = 100;
42  let activeHeader = null;
43
44  for (const header of headers) {
45    const rect = header.getBoundingClientRect();
46
47    if (rect.top <= threshold) {
48      activeHeader = header;
49    }
50  }
51
52  if (!activeHeader && headers.length > 0) {
53    activeHeader = headers[0];
54  }
55
56  const pagetocLinks = [...document.querySelector(".pagetoc").children];
57  pagetocLinks.forEach((link) => link.classList.remove("active"));
58
59  if (activeHeader) {
60    const activeLink = pagetocLinks.find(
61      (link) => activeHeader.href === link.href,
62    );
63    if (activeLink) activeLink.classList.add("active");
64  }
65};
66
67document.addEventListener("DOMContentLoaded", () => {
68  const pagetoc = getPagetoc();
69  const headers = [...document.getElementsByClassName("header")];
70
71  const nonH1Headers = headers.filter(
72    (header) => !header.parentElement.tagName.toLowerCase().startsWith("h1"),
73  );
74  const tocContainer = document.querySelector(".toc-container");
75
76  if (nonH1Headers.length === 0) {
77    if (tocContainer) {
78      tocContainer.classList.add("no-toc");
79    }
80    return;
81  }
82
83  if (tocContainer) {
84    tocContainer.classList.add("has-toc");
85  }
86
87  const tocTitle = Object.assign(document.createElement("p"), {
88    className: "toc-title",
89    textContent: "On This Page",
90  });
91
92  pagetoc.appendChild(tocTitle);
93
94  headers.forEach((header) => {
95    const link = Object.assign(document.createElement("a"), {
96      textContent: header.text,
97      href: header.href,
98      className: `pagetoc-${header.parentElement.tagName}`,
99    });
100    pagetoc.appendChild(link);
101  });
102
103  updateFunction();
104  listenActive();
105
106  const pageElement = document.querySelector(".page");
107  if (pageElement) {
108    pageElement.addEventListener("scroll", updateFunction);
109  } else {
110    window.addEventListener("scroll", updateFunction);
111  }
112});
113
Served at tenant.openagents/omega Member data and write actions are omitted.