Files
cairnquire/apps/server/internal/httpserver/static/render.js
Tim Bendt 780ff3a02c feat: miller column browser, offline cache, search, breadcrumbs
- 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
2026-04-30 11:55:03 -04:00

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();
}
})();