- Dynamic miller column sizing with flexbox layout - Root column (160px), middle slices (48px), active column (flex) - Auto-scroll browser to rightmost column on navigation - Offline indicator UI and IndexedDB cache integration - /api/documents endpoint for client-side document caching - Breadcrumb navigation in document content area - FTS5 search with SQLite virtual table - Client-side Mermaid and KaTeX rendering via CDN - Deep sample content (advanced-topics/raft-deep-dive) - Border removal (only search button keeps radius) - Full viewport layout with proper borders between sidebar/content
82 lines
2.1 KiB
JavaScript
82 lines
2.1 KiB
JavaScript
(function () {
|
|
function renderMermaid() {
|
|
if (typeof mermaid === "undefined") return;
|
|
const blocks = document.querySelectorAll("pre code.language-mermaid");
|
|
blocks.forEach(function (block) {
|
|
const pre = block.parentElement;
|
|
const container = document.createElement("div");
|
|
container.className = "mermaid";
|
|
container.textContent = block.textContent;
|
|
pre.replaceWith(container);
|
|
});
|
|
mermaid.initialize({ startOnLoad: false });
|
|
mermaid.run({ querySelector: ".mermaid" });
|
|
}
|
|
|
|
function renderMath() {
|
|
if (typeof katex === "undefined") return;
|
|
|
|
const blocks = document.querySelectorAll("pre code.language-math");
|
|
blocks.forEach(function (block) {
|
|
const pre = block.parentElement;
|
|
const container = document.createElement("div");
|
|
container.className = "katex-block";
|
|
try {
|
|
katex.render(block.textContent.trim(), container, {
|
|
displayMode: true,
|
|
throwOnError: false,
|
|
});
|
|
pre.replaceWith(container);
|
|
} catch (e) {
|
|
console.warn("KaTeX render failed:", e);
|
|
}
|
|
});
|
|
|
|
const markdownBody = document.querySelector(".markdown-body");
|
|
if (!markdownBody) return;
|
|
|
|
const html = markdownBody.innerHTML;
|
|
let newHtml = html;
|
|
|
|
newHtml = newHtml.replace(/\$\$([\s\S]+?)\$\$/g, function (match, tex) {
|
|
try {
|
|
return katex.renderToString(tex.trim(), {
|
|
displayMode: true,
|
|
throwOnError: false,
|
|
});
|
|
} catch (e) {
|
|
return match;
|
|
}
|
|
});
|
|
|
|
newHtml = newHtml.replace(/\$([^\s$][^$]*?)\$/g, function (match, tex) {
|
|
try {
|
|
return katex.renderToString(tex.trim(), {
|
|
displayMode: false,
|
|
throwOnError: false,
|
|
});
|
|
} catch (e) {
|
|
return match;
|
|
}
|
|
});
|
|
|
|
if (newHtml !== html) {
|
|
markdownBody.innerHTML = newHtml;
|
|
}
|
|
}
|
|
|
|
function init() {
|
|
renderMermaid();
|
|
renderMath();
|
|
}
|
|
|
|
window.renderMermaid = renderMermaid;
|
|
window.renderMath = renderMath;
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", init);
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|