68 lines
2.5 KiB
JavaScript
68 lines
2.5 KiB
JavaScript
(function (root, factory) {
|
|
"use strict";
|
|
|
|
const api = factory(root);
|
|
if (typeof module === "object" && module.exports) module.exports = api;
|
|
else root.RacketWikiMermaid = api;
|
|
})(typeof window === "object" ? window : globalThis, function (root) {
|
|
"use strict";
|
|
|
|
const selector = "pre > code.language-mermaid, pre > code.lang-mermaid";
|
|
let initialized = false;
|
|
let renderSequence = 0;
|
|
let hydrationTimer = null;
|
|
|
|
function initialize(mermaidApi = root.mermaid) {
|
|
if (initialized) return;
|
|
if (!mermaidApi || typeof mermaidApi.initialize !== "function") {
|
|
throw new Error("Mermaid is not installed. Open /setup to repair the frontend setup.");
|
|
}
|
|
mermaidApi.initialize({
|
|
startOnLoad: false,
|
|
securityLevel: "strict",
|
|
suppressErrorRendering: true
|
|
});
|
|
initialized = true;
|
|
}
|
|
|
|
async function hydrate(container = root.document, mermaidApi = root.mermaid) {
|
|
initialize(mermaidApi);
|
|
const blocks = Array.from(container.querySelectorAll(selector));
|
|
for (const code of blocks) {
|
|
const source = code.parentElement;
|
|
if (!source || source.dataset.mermaidState) continue;
|
|
source.dataset.mermaidState = "rendering";
|
|
try {
|
|
const id = `racket-wiki-mermaid-${++renderSequence}`;
|
|
const rendered = await mermaidApi.render(id, code.textContent || "");
|
|
const diagram = source.ownerDocument.createElement("div");
|
|
diagram.className = "rw-mermaid";
|
|
diagram.setAttribute("role", "img");
|
|
diagram.setAttribute("aria-label", "Mermaid diagram");
|
|
diagram.innerHTML = rendered.svg;
|
|
source.replaceWith(diagram);
|
|
if (typeof rendered.bindFunctions === "function") rendered.bindFunctions(diagram);
|
|
} catch (error) {
|
|
source.dataset.mermaidState = "error";
|
|
source.classList.add("rw-mermaid-error");
|
|
source.title = error && error.message ? error.message : "Mermaid diagram could not be rendered";
|
|
if (root.console && typeof root.console.error === "function") {
|
|
root.console.error("Mermaid diagram could not be rendered", error);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function queue(container = root.document) {
|
|
if (hydrationTimer !== null) root.clearTimeout(hydrationTimer);
|
|
hydrationTimer = root.setTimeout(() => {
|
|
hydrationTimer = null;
|
|
hydrate(container).catch((error) => {
|
|
if (root.console && typeof root.console.error === "function") root.console.error(error);
|
|
});
|
|
}, 0);
|
|
}
|
|
|
|
return { hydrate, initialize, queue, selector };
|
|
});
|