Last active
June 21, 2024 01:37
-
-
Save lostfictions/8b4ba08742811fcc53106df4c6fb6c63 to your computer and use it in GitHub Desktop.
godot docs table of contents
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==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