Files
pghrt/export/pghrtjs.js
2025-11-02 00:57:10 -07:00

178 lines
5.2 KiB
JavaScript

// this function adds the + and functionality to the toc so that it is less scary
// it's still pretty scary ngl it's a giant toc but at least it starts hidden
function initTocOnClick() {
const colls = document.querySelectorAll(".ltx_tocentry.ltx_tocentry_section > .ltx_ref");
for (const coll of colls) {
coll.addEventListener("click", (event) => {
coll.classList.toggle("active");
const content = coll.nextElementSibling;
if (content) {
event.preventDefault(); // don't jump
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
}
});
// don't add the + if there's nothing to expand
if (!coll.nextElementSibling) {
coll.classList.add("del");
}
}
}
// copy on click for section permalinks
function copyURI(event) {
event.preventDefault();
try {
navigator.clipboard.writeText(
// ensures url is without hash, then add on correct hash
window.location.href.replace(window.location.hash, "") + event.target.getAttribute("href")
);
} catch (e) {
console.error(e);
}
// toast that i ripped from w3schools. does not nicely handle being spam clicked. w/e
// OKAY understanding more later. why is this replace and not remove? so ugly wow...
// you're telling me that chatgpt and copilot were trained on obtuse garbage like this!?
const snackbar = document.getElementById("snackbar");
snackbar.className = "show";
setTimeout(() => {
snackbar.className = snackbar.className.replace("show", "");
}, 2000);
}
// source: https://stackoverflow.com/questions/56300132/how-to-override-css-prefers-color-scheme-setting
// ty jimmy banks
// determines if the user has a set theme or a stored theme on load
function detectColorScheme() {
// check if already saved dark
if (localStorage.getItem("theme")) {
if (localStorage.getItem("theme") === "dark") {
document.documentElement.setAttribute("data-theme", "dark");
}
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
// set to dark if OS preferred
document.documentElement.setAttribute("data-theme", "dark");
localStorage.setItem("theme", "dark");
} else {
// default light otherwise
document.documentElement.setAttribute("data-theme", "light");
localStorage.setItem("theme", "light");
}
}
function detectFont() {
// check if user wants sans
if (localStorage.getItem("font") === "sans") {
document.documentElement.setAttribute("data-font", "sans");
localStorage.setItem("font", "sans");
}
else {
// otherwise give avec
document.documentElement.setAttribute("data-font", "avec");
localStorage.setItem("font", "avec");
}
}
// source: https://www.accessibilityfirst.at/posts/dark-and-light-mode-a-simple-guide-for-web-design-and-development
// add onClick to toggle theme between light and dark
function initThemeToggle() {
document.getElementById("theme-toggle").addEventListener("click", () => {
document.documentElement.setAttribute(
"data-theme",
document.documentElement.getAttribute("data-theme") === "dark"
? "light"
: "dark"
);
localStorage.setItem(
"theme",
document.documentElement.getAttribute("data-theme")
);
});
}
// the same function except it's for font toggle
// btw i think i'm a little funny for the var naming
// funny status redacted for the var naming
function initFontToggle() {
document.getElementById("font-toggle").addEventListener("click", () => {
document.documentElement.setAttribute(
"data-font",
document.documentElement.getAttribute("data-font") === "avec"
? "sans"
: "avec"
);
localStorage.setItem(
"font",
document.documentElement.getAttribute("data-font")
);
});
}
// saving the scroll position for clicking references or toc
function saveScroll() {
const colls = document.querySelectorAll(".ltx_ref");
for (const coll of colls) {
coll.addEventListener("click", () => {
document.getElementById("return").classList.add("show"); // only fires once
const pos = window.scrollY;
const scrollArray = JSON.parse(sessionStorage.getItem("scrollPos") ?? "[]");
scrollArray.unshift(pos);
sessionStorage.setItem("scrollPos", JSON.stringify(scrollArray));
});
}
}
// it returns to scroll positions stored in the array "scrollPos"
function returnScroll() {
document.getElementById("return").addEventListener("click", () => {
const scrollArray = JSON.parse(sessionStorage.getItem("scrollPos") ?? "[]").map(num => Number(num));
// check if saved, otherwise goto top and remove back arrow
if (scrollArray.length > 1) {
pos = scrollArray.shift();
sessionStorage.setItem("scrollPos", JSON.stringify(scrollArray));
window.scroll(0, pos);
}
else if (scrollArray.length === 1) {
this.classList.remove("show");
let pos = scrollArray.shift();
sessionStorage.setItem("scrollPos", JSON.stringify(scrollArray));
// scroll to top
window.scroll(0, pos);
} else {
this.classList.remove("show");
// scroll to top
window.scroll(0, 0);
}
});
}
// run da functions
function main() {
const funcs = [
initTocOnClick,
detectColorScheme,
detectFont,
initThemeToggle,
initFontToggle,
saveScroll,
returnScroll
];
for (const func of funcs) {
try {
func();
} catch (e) {
console.error(e);
}
}
}
main();