repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/strata/assets/diagram.js
Raw(() => {
const MAX_SOURCE_LENGTH = 12000;
const MAX_HEIGHT = 4000;
const expectedOrigin = document.documentElement.dataset.parentOrigin;
const root = document.querySelector("#diagram");
let generation = 0;
let running = false;
let pending = null;
function send(message) {
window.parent.postMessage(message, expectedOrigin);
}
function reportSize() {
const height = Math.max(
80,
Math.min(MAX_HEIGHT, Math.ceil(document.documentElement.scrollHeight)),
);
send({ type: "strata.diagram.size", height });
}
function sanitize(svg) {
const documentNode = new DOMParser().parseFromString(svg, "image/svg+xml");
const svgNode = documentNode.documentElement;
if (
svgNode.localName !== "svg" ||
documentNode.querySelector("parsererror")
)
return null;
for (const node of svgNode.querySelectorAll(
"script, foreignObject, iframe, object, embed, audio, video, image, animate, animateMotion, animateTransform, set, a",
))
node.remove();
for (const element of [svgNode, ...svgNode.querySelectorAll("*")]) {
if (element.namespaceURI !== "http://www.w3.org/2000/svg") return null;
if (
element.localName === "style" &&
/@(?!keyframes\b)|url\s*\(|expression\s*\(|\\/iu.test(
element.textContent,
)
)
return null;
for (const attribute of [...element.attributes]) {
const name = attribute.name.toLowerCase();
const value = attribute.value.trim().toLowerCase();
if (
name.startsWith("on") ||
name === "xml:base" ||
(name.endsWith("href") && !/^#[\w.-]+$/u.test(value))
)
return null;
const withoutLocalReferences = value.replace(
/url\(\s*["']?#[\w.-]+["']?\s*\)/giu,
"",
);
if (/url\s*\(|expression\s*\(|\\/iu.test(withoutLocalReferences))
return null;
}
}
return svgNode.outerHTML;
}
async function render(source, dark, requestGeneration) {
try {
mermaid.initialize({
startOnLoad: false,
securityLevel: "strict",
htmlLabels: false,
maxTextSize: MAX_SOURCE_LENGTH,
maxEdges: 500,
theme: dark ? "dark" : "default",
});
const rendered = await mermaid.render(
`strata-diagram-${requestGeneration}`,
source,
);
if (requestGeneration !== generation) return;
const svg = sanitize(rendered.svg);
if (!svg) throw new Error("unsafe diagram output");
root.innerHTML = svg;
reportSize();
} catch {
if (requestGeneration !== generation) return;
root.textContent = "Diagram unavailable.";
send({ type: "strata.diagram.error" });
reportSize();
}
}
async function drain() {
if (running) return;
running = true;
try {
while (pending) {
const next = pending;
pending = null;
await render(next.source, next.dark, next.generation);
}
} finally {
running = false;
}
}
window.addEventListener("message", (event) => {
if (event.source !== window.parent || event.origin !== expectedOrigin)
return;
const data = event.data;
if (
!data ||
typeof data !== "object" ||
data.type !== "strata.diagram.render" ||
typeof data.source !== "string" ||
typeof data.dark !== "boolean" ||
Object.keys(data).length !== 3
)
return;
try {
const source = validateDiagram(data.source);
generation += 1;
pending = { source, dark: data.dark, generation };
void drain();
} catch {
generation += 1;
pending = null;
root.textContent = "Diagram unavailable.";
send({ type: "strata.diagram.error" });
reportSize();
}
});
send({ type: "strata.diagram.ready" });
})();