mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-11-14 08:17:26 +01:00
71 lines
3.1 KiB
JavaScript
71 lines
3.1 KiB
JavaScript
import { renderMarkdown } from "../../src/markdown";
|
|
import { stlPaths } from "../../src/markdown-diagrams";
|
|
// htmlparser2 uses this ES2022 builtin; retain the viewer's older-browser support.
|
|
if (!Object.hasOwn) Object.defineProperty(Object, "hasOwn", {
|
|
value: (object, key) => Object.prototype.hasOwnProperty.call(object, key),
|
|
configurable: true, writable: true,
|
|
});
|
|
window.MarkdownRenderer = { render: renderMarkdown };
|
|
|
|
// Delegation also covers documents inserted by Vue after this lazy bundle loads.
|
|
document.addEventListener("click", event => {
|
|
const button = event.target.closest?.("button[data-diagram-action]");
|
|
const figure = button?.closest("figure.markdown-diagram");
|
|
if (!figure) return;
|
|
const group = figure.querySelector("svg g");
|
|
const action = button.dataset.diagramAction;
|
|
let zoom = Number(figure.dataset.zoom || 1);
|
|
if (action === "rotate") {
|
|
try {
|
|
const vertices = JSON.parse(figure.dataset.vertices);
|
|
if (!Array.isArray(vertices) || vertices.length > 60000 || vertices.length % 3 || vertices.some(v => !Array.isArray(v) || v.length !== 3 || v.some(n => typeof n !== "number" || !Number.isFinite(n)))) return;
|
|
const angle = Number(figure.dataset.angle || 0.6) + 0.3;
|
|
figure.dataset.angle = angle;
|
|
group.innerHTML = stlPaths(vertices, angle);
|
|
} catch { return; }
|
|
} else {
|
|
if (action === "reset" && figure.dataset.vertices) {
|
|
// Reuse the validated rotation path, then restore the initial view angle.
|
|
figure.dataset.angle = 0.3;
|
|
figure.querySelector('[data-diagram-action="rotate"]')?.click();
|
|
}
|
|
zoom = action === "reset" ? 1 : Math.max(0.25, Math.min(8, zoom * (action === "in" ? 1.25 : 0.8)));
|
|
figure.dataset.zoom = zoom;
|
|
group.setAttribute("transform", `translate(320 160) scale(${zoom}) translate(-320 -160)`);
|
|
}
|
|
});
|
|
|
|
let pending = false;
|
|
async function enhance() {
|
|
if (pending) return;
|
|
const diagrams = [...document.querySelectorAll("pre.mermaid:not([data-processed])")];
|
|
if (!diagrams.length) return;
|
|
pending = true;
|
|
try {
|
|
if (!window.mermaid) {
|
|
await new Promise((resolve, reject) => {
|
|
const script = document.createElement("script");
|
|
script.src = "/script/mermaid.min.js";
|
|
script.onload = resolve;
|
|
script.onerror = reject;
|
|
document.head.appendChild(script);
|
|
});
|
|
}
|
|
if (!window.mermaidInitialized) {
|
|
window.mermaid.initialize({ startOnLoad: false, securityLevel: "strict", theme: "default" });
|
|
window.mermaidInitialized = true;
|
|
}
|
|
for (const element of diagrams) {
|
|
const source = element.textContent;
|
|
try { await window.mermaid.run({ nodes: [element] }); }
|
|
catch { element.textContent = source; element.dataset.processed = "true"; }
|
|
}
|
|
} finally {
|
|
pending = false;
|
|
if ([...document.querySelectorAll("pre.mermaid:not([data-processed])")].some(node => !diagrams.includes(node))) enhance().catch(() => {});
|
|
}
|
|
}
|
|
const observer = new MutationObserver(() => { enhance().catch(() => {}); });
|
|
observer.observe(document.documentElement, { childList: true, subtree: true });
|
|
enhance().catch(() => {});
|