Skip to content

Instantly share code, notes, and snippets.

@lostfictions
Last active June 21, 2024 01:37
Show Gist options
  • Save lostfictions/8b4ba08742811fcc53106df4c6fb6c63 to your computer and use it in GitHub Desktop.
Save lostfictions/8b4ba08742811fcc53106df4c6fb6c63 to your computer and use it in GitHub Desktop.
godot docs table of contents
// ==UserScript==
// @name Godot Docs TOC
// @namespace lostfictions's useful little things
// @match https://docs.godotengine.org/en/*
// @grant GM.addStyle
// @version 1.0
// @author https://github.com/lostfictions
// @description Add a table of contents to Godot's Read The Docs-based documentation pages
// ==/UserScript==
const TOC_TITLE = "Table of Contents"
// Fix browser getting confused, seemingly by multiple scroll containers (sidebar and main content)
window.addEventListener("popstate", (event) => {
const target = location.hash.slice(1);
if (target) {
document.getElementById(target).scrollIntoView();
} else {
document.getElementById("custom-toc").scrollIntoView();
}
});
const body = document.querySelector('div[itemprop="articleBody"]');
const headers = [...body.querySelectorAll("a.headerlink")].map(a => {
const aa = a.parentNode.cloneNode(true);
aa.removeChild(aa.querySelector("a.headerlink"));
return [aa.innerHTML, aa.tagName, a.href]
});
const top = document.querySelector('div.rst-content div[role="navigation"]');
const container = document.createElement("div");
container.className = "custom-toc";
container.id = "custom-toc";
top.appendChild(container);
const containerTitle = document.createElement("div");
containerTitle.className = "custom-toc-title"
container.appendChild(containerTitle);
containerTitle.textContent = TOC_TITLE;
const inner = document.createElement("div");
inner.className = "custom-toc-inner";
container.appendChild(inner);
const ul = document.createElement("ul");
inner.appendChild(ul);
for (const [html, tagName, link] of headers) {
const isHeader = /h[1-5]/i.test(tagName);
if(!isHeader) continue; // skip image captions, etc.
const li = document.createElement("li");
li.className = `custom-toc-${tagName.toLowerCase()}`;
ul.appendChild(li);
const a = document.createElement("a");
li.appendChild(a);
a.innerHTML = html;
a.href = link;
}
GM.addStyle(`
.custom-toc {
padding: 1em;
margin: 1em 0;
border-radius: 8px;
border: 2px solid black;
}
.custom-toc-inner {
margin-top: 1em;
margin-left: 1em; /* unpull bullet */
}
.custom-toc-title {
font-size: larger;
}
.custom-toc ul, .custom-toc li {
list-style: unset !important;
}
/* unstyle automatic "doc" icon for class reference links */
.rst-content .custom-toc a[href*="classes/"]::after {
content: unset;
}
/* style links to other pages (possibly only found on "GDScript Reference" page) */
.custom-toc a:not([href^="${document.location.origin}${document.location.pathname}"])::after {
/* mirrors the definition for .rst-content a[href*="classes/"]::after */
content: "" !important; /* re-set the icon! */
background-image: var(--class-reference-icon);
display: inline-block;
height: 16px;
width: 16px;
padding: 0.125rem 0.375rem;
margin-left: 0.25rem;
}
.custom-toc-h2 {
margin-left: 1em;
}
.custom-toc-h3 {
margin-left: 2em;
}
.custom-toc-h4 {
margin-left: 3em;
}
.custom-toc-h5 {
margin-left: 4em;
}
`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment