Implement approved specification #32 and tickets #33-#37. Keep host authentication server-verified and pin session interaction language. Compile scoped base selectors for browser compatibility and retain full gutters during CSS pruning.
31 lines
1.2 KiB
TypeScript
31 lines
1.2 KiB
TypeScript
let initializedTheme: "light" | "dark" | undefined;
|
|
let rendering: Promise<unknown> = Promise.resolve();
|
|
|
|
export function renderMermaid(def: string, theme: "light" | "dark" = "light"): Promise<string> {
|
|
// Mermaid configuration is global: serialize renders so a theme change cannot
|
|
// recolor another diagram midway through its asynchronous rendering.
|
|
const result = rendering.then(() => renderDiagram(def, theme));
|
|
rendering = result.catch(() => undefined);
|
|
return result;
|
|
}
|
|
|
|
async function renderDiagram(def: string, theme: "light" | "dark"): Promise<string> {
|
|
const mermaid = (await import("mermaid")).default;
|
|
if (initializedTheme !== theme) {
|
|
mermaid.initialize({ startOnLoad: false, theme: theme === "dark" ? "dark" : "default" });
|
|
initializedTheme = theme;
|
|
}
|
|
const id = `mermaid-${Math.random().toString(36).slice(2)}`;
|
|
const container = document.createElement("div");
|
|
container.style.position = "absolute";
|
|
container.style.left = "-9999px";
|
|
document.body.appendChild(container);
|
|
try {
|
|
const { svg } = await mermaid.render(id, def, container);
|
|
return svg;
|
|
} finally {
|
|
container.remove();
|
|
document.getElementById(id)?.remove();
|
|
}
|
|
}
|