socktop-webterm/docs/theme/catppuccin-themes.js

227 lines
6.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Replace default mdBook themes with Catppuccin themes
(function () {
"use strict";
// Wait for DOM to be ready
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
function init() {
addSidebarLogo();
replaceThemeList();
setupGhosttyStyleSidebar();
// Watch for sidebar changes and re-run setup
const sidebarScrollbox = document.querySelector(".sidebar-scrollbox");
if (sidebarScrollbox) {
const observer = new MutationObserver(() => {
// Wait a bit for mdBook to finish updating
setTimeout(setupGhosttyStyleSidebar, 50);
});
observer.observe(sidebarScrollbox, {
childList: true,
subtree: true,
});
}
// Also re-run on page navigation
window.addEventListener("hashchange", () => {
setTimeout(setupGhosttyStyleSidebar, 100);
});
}
function addSidebarLogo() {
const scrollbox = document.querySelector(".sidebar-scrollbox");
if (!scrollbox) {
return;
}
// Check if logo already exists
if (document.querySelector(".sidebar-logo")) {
return;
}
// Create logo container
const logoContainer = document.createElement("div");
logoContainer.className = "sidebar-logo";
// Create clickable link wrapper
const logoLink = document.createElement("a");
logoLink.href = "https://socktop.io";
logoLink.style.display = "block";
logoLink.style.textAlign = "center";
// Create logo image
const logoImg = document.createElement("img");
// Use root-relative path that works from any page depth
logoImg.src = window.location.pathname.includes("/assets/docs/")
? "/assets/docs/logo.png"
: "logo.png";
logoImg.alt = "socktop";
logoImg.style.display = "inline-block";
logoImg.style.maxWidth = "80%";
logoLink.appendChild(logoImg);
logoContainer.appendChild(logoLink);
// Insert as the very first child inside the scrollbox
scrollbox.insertBefore(logoContainer, scrollbox.firstChild);
}
function replaceThemeList() {
const themeList = document.getElementById("mdbook-theme-list");
if (!themeList) {
console.warn("Theme list not found");
return;
}
// Clear existing themes
themeList.innerHTML = "";
// Catppuccin themes
const catppuccinThemes = [
{ id: "latte", name: "Latte" },
{ id: "frappe", name: "Frappé" },
{ id: "macchiato", name: "Macchiato" },
{ id: "mocha", name: "Mocha" },
];
// Add Catppuccin themes
catppuccinThemes.forEach((theme) => {
const li = document.createElement("li");
li.setAttribute("role", "none");
const button = document.createElement("button");
button.setAttribute("role", "menuitem");
button.className = "theme";
button.id = "mdbook-theme-" + theme.id;
button.textContent = theme.name;
li.appendChild(button);
themeList.appendChild(li);
});
}
function setupGhosttyStyleSidebar() {
// Hide mdBook's default fold toggles
const defaultToggles = document.querySelectorAll(".chapter-fold-toggle");
defaultToggles.forEach((toggle) => {
toggle.style.display = "none";
});
// Get current page path to determine active item
const currentPath = window.location.pathname;
// Find all chapter items
const allChapterItems = document.querySelectorAll(
"ol.chapter > li.chapter-item",
);
allChapterItems.forEach((li) => {
// Check if this item has a nested section list
const nestedList = li.querySelector("ol.section");
// Skip if no nested list (like Introduction)
if (!nestedList) {
return;
}
const linkWrapper = li.querySelector("span.chapter-link-wrapper");
const link = linkWrapper ? linkWrapper.querySelector("a") : null;
if (!linkWrapper) {
return;
}
// Check if any child link matches current page
let hasActivePage = false;
const childLinks = nestedList.querySelectorAll("a");
childLinks.forEach((childLink) => {
const href = childLink.getAttribute("href");
if (
href &&
currentPath.includes(href.replace("../", "").replace("./", ""))
) {
childLink.closest("li.chapter-item").classList.add("active");
hasActivePage = true;
}
});
// Skip if we already added a chevron - just update state
const existingChevron = linkWrapper.querySelector(".chapter-chevron");
if (existingChevron) {
if (hasActivePage) {
nestedList.style.display = "block";
li.classList.add("expanded");
li.classList.remove("collapsed");
existingChevron.style.transform = "rotate(90deg)";
}
return;
}
// Create custom chevron
const chevron = document.createElement("span");
chevron.className = "chapter-chevron";
chevron.textContent = "";
chevron.style.cssText =
"float: right; transition: transform 0.2s ease; display: inline-block; opacity: 0.6; font-size: 1.2em; line-height: 1; user-select: none; cursor: pointer;";
// Insert chevron into the link wrapper
linkWrapper.appendChild(chevron);
// Start expanded if it contains the active page, collapsed otherwise
if (hasActivePage) {
nestedList.style.display = "block";
li.classList.add("expanded");
li.classList.remove("collapsed");
chevron.style.transform = "rotate(90deg)";
} else {
nestedList.style.display = "none";
li.classList.add("collapsed");
li.classList.remove("expanded");
chevron.style.transform = "rotate(0deg)";
}
// Add click handler to toggle
const toggleSection = function (e) {
e.preventDefault();
e.stopPropagation();
const isCollapsed = li.classList.contains("collapsed");
if (isCollapsed) {
// Expand
nestedList.style.display = "block";
li.classList.remove("collapsed");
li.classList.add("expanded");
chevron.style.transform = "rotate(90deg)";
} else {
// Collapse
nestedList.style.display = "none";
li.classList.add("collapsed");
li.classList.remove("expanded");
chevron.style.transform = "rotate(0deg)";
}
};
// Click on chevron toggles
chevron.addEventListener("click", toggleSection);
// Click on parent link also toggles if it's a dummy link
if (link) {
const href = link.getAttribute("href");
if (!href || href === "" || href === "#") {
link.addEventListener("click", toggleSection);
link.style.cursor = "pointer";
}
} else {
linkWrapper.addEventListener("click", toggleSection);
linkWrapper.style.cursor = "pointer";
}
});
}
})();