mirror of
https://gitea.tendokyu.moe/eamuse/docs.git
synced 2024-11-28 00:20:52 +01:00
171 lines
4.9 KiB
JavaScript
171 lines
4.9 KiB
JavaScript
const ROOT = document.getElementById("root");
|
|
|
|
const sidebar = document.createElement("div");
|
|
sidebar.classList.add("sidebar");
|
|
|
|
let contentsEl = document.createElement("ul");
|
|
sidebar.appendChild(contentsEl);
|
|
|
|
const contentsHeadings = [];
|
|
|
|
let cDepth = 1;
|
|
for (const el of ROOT.querySelectorAll(["h1", "h2", "h3", "h4"])) {
|
|
if (el.id.length == 0) {
|
|
el.id = el.innerText
|
|
.toLowerCase()
|
|
.replace(/[^a-zA-Z]+/g, " ")
|
|
.trim()
|
|
.replace(/ /g, "-");
|
|
}
|
|
|
|
let newLi = document.createElement("li");
|
|
const newA = document.createElement("a");
|
|
newA.setAttribute("href", "#" + el.id);
|
|
newA.innerHTML = el.innerHTML;
|
|
newLi.appendChild(newA);
|
|
|
|
contentsHeadings.push([el, newLi]);
|
|
|
|
const depth = parseInt(el.tagName[1]);
|
|
// We're in too deep
|
|
while (cDepth > depth) {
|
|
contentsEl = contentsEl.parentElement.parentElement;
|
|
cDepth--;
|
|
}
|
|
|
|
// We're _way_ too shallow
|
|
if (cDepth < depth - 1) {
|
|
while (cDepth < depth) {
|
|
const tempLi = document.createElement("li");
|
|
contentsEl.appendChild(tempLi);
|
|
const newUl = document.createElement("ul");
|
|
tempLi.appendChild(newUl);
|
|
contentsEl = newUl;
|
|
cDepth++;
|
|
}
|
|
}
|
|
// We're only one level too shallow
|
|
else if (cDepth < depth) {
|
|
const newUl = document.createElement("ul");
|
|
|
|
if (depth == 0) {
|
|
newLi.appendChild(newUl);
|
|
} else {
|
|
contentsEl.childNodes[contentsEl.childNodes.length - 1].appendChild(newUl);
|
|
}
|
|
contentsEl = newUl;
|
|
cDepth++;
|
|
}
|
|
contentsEl.appendChild(newLi);
|
|
}
|
|
document.body.appendChild(sidebar);
|
|
|
|
contentsHeadings.reverse();
|
|
const onScroll = () => {
|
|
for (const [hEl, sbLi] of contentsHeadings) {
|
|
sbLi.classList.remove("active");
|
|
}
|
|
let set = false;
|
|
for (const [hEl, sbLi] of contentsHeadings) {
|
|
if (hEl.offsetTop <= window.scrollY + 32) {
|
|
sbLi.classList.add("active");
|
|
set = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!set && contentsHeadings.length != 0) {
|
|
contentsHeadings[contentsHeadings.length - 1][1].classList.add("active");
|
|
}
|
|
};
|
|
document.addEventListener("scroll", onScroll);
|
|
document.addEventListener("resize", onScroll);
|
|
onScroll();
|
|
|
|
for (const el of ROOT.querySelectorAll("[id]")) {
|
|
if (el.tagName === "marker") continue;
|
|
el.classList.add("haspara");
|
|
const pilcrow = document.createElement("a");
|
|
pilcrow.className = "pilcrow";
|
|
pilcrow.href = "#" + el.id;
|
|
pilcrow.innerHTML = "¶";
|
|
el.prepend(pilcrow);
|
|
}
|
|
|
|
const foldable = (root, children) => {
|
|
let state = true;
|
|
root.addEventListener("click", (e) => {
|
|
if (e.target.classList.contains("pilcrow")) state = true;
|
|
else state = !state;
|
|
|
|
if (state) children.classList.remove("closed");
|
|
else children.classList.add("closed");
|
|
if (state) root.classList.remove("closed");
|
|
else root.classList.add("closed");
|
|
});
|
|
root.classList.add("toggle-root");
|
|
};
|
|
|
|
const make_foldable = (root) => {
|
|
const child_stacks = new Array(10).fill(null).map(() => ({ children: [], root: null }));
|
|
|
|
const flush_header = (this_level, sibling) => {
|
|
for (let level = 9; level >= this_level; level--) {
|
|
const stack = child_stacks[level];
|
|
|
|
if (!stack.root) continue;
|
|
|
|
const new_e = document.createElement("div");
|
|
new_e.classList.add("toggle-section");
|
|
for (const old_e of stack.children) {
|
|
old_e.remove();
|
|
new_e.appendChild(old_e);
|
|
}
|
|
|
|
if (stack.root.tagName !== "H1") foldable(stack.root, new_e);
|
|
let parent_level;
|
|
for (parent_level = level - 1; parent_level > 0; parent_level--) if (child_stacks[parent_level].root) break;
|
|
|
|
if (parent_level === -1) {
|
|
if (sibling) root.insertBefore(new_e, sibling);
|
|
else root.appendChild(new_e);
|
|
} else {
|
|
stack.root.remove();
|
|
child_stacks[parent_level].children.push(stack.root);
|
|
child_stacks[parent_level].children.push(new_e);
|
|
}
|
|
|
|
stack.root = null;
|
|
stack.children.length = 0;
|
|
}
|
|
};
|
|
|
|
let end = null;
|
|
for (const child of [...root.children]) {
|
|
if (child.tagName === "FOOTER") {
|
|
end = child;
|
|
break;
|
|
}
|
|
|
|
if (/^H\d$/.test(child.tagName)) {
|
|
const this_level = parseInt(child.tagName[1]) - 1;
|
|
|
|
flush_header(this_level, child);
|
|
|
|
child_stacks[this_level].root = child;
|
|
continue;
|
|
}
|
|
|
|
for (let level = 9; level >= 0; level--) {
|
|
if (child_stacks[level].root) {
|
|
child_stacks[level].children.push(child);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (let level = 9; level >= 0; level--) {
|
|
flush_header(level, end);
|
|
}
|
|
};
|
|
make_foldable(ROOT);
|