siyuan/app/src/protyle/render/mermaidRender.ts
Yingyi / 颖逸 b2a27bb54c
Refactor code language and ts types (#9300)
* 🎨 Code block language list adds custom languages

* Update index.d.ts

* 🎨 Improve global variable type definition

* 🎨 Improve global variable type definition

* 🎨 Add constant `EXTRA_CODE_LANGUAGES`
2023-09-28 22:38:49 +08:00

81 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {addScript} from "../util/addScript";
import {Constants} from "../../constants";
import {hasClosestByAttribute} from "../util/hasClosest";
export const mermaidRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
let mermaidElements: Element[] = [];
if (element.getAttribute("data-subtype") === "mermaid") {
// 编辑器内代码块编辑渲染
mermaidElements = [element];
} else {
mermaidElements = Array.from(element.querySelectorAll('[data-subtype="mermaid"]'));
}
if (mermaidElements.length === 0) {
return;
}
addScript(`${cdn}/js/mermaid/mermaid.min.js?v=10.3.0`, "protyleMermaidScript").then(() => {
const config: any = {
securityLevel: "loose", // 升级后无 https://github.com/siyuan-note/siyuan/issues/3587可使用该选项
altFontFamily: "sans-serif",
fontFamily: "sans-serif",
startOnLoad: false,
flowchart: {
htmlLabels: true,
useMaxWidth: !0
},
sequence: {
useMaxWidth: true,
diagramMarginX: 8,
diagramMarginY: 8,
boxMargin: 8,
showSequenceNumbers: true // Mermaid 时序图增加序号 https://github.com/siyuan-note/siyuan/pull/6992 https://mermaid.js.org/syntax/sequenceDiagram.html#sequencenumbers
},
gantt: {
leftPadding: 75,
rightPadding: 20
}
};
if (window.siyuan.config.appearance.mode === 1) {
config.theme = "dark";
}
window.mermaid.initialize(config);
if (mermaidElements[0].firstElementChild.clientWidth === 0) {
const hideElement = hasClosestByAttribute(mermaidElements[0], "fold", "1");
if (!hideElement) {
return;
}
const observer = new MutationObserver(() => {
initMermaid(mermaidElements);
observer.disconnect();
});
observer.observe(hideElement, {attributeFilter: ["fold"]});
} else {
initMermaid(mermaidElements);
}
});
};
const initMermaid = (mermaidElements: Element[]) => {
mermaidElements.forEach((item, index) => {
if (item.getAttribute("data-render") === "true") {
return;
}
if (!item.firstElementChild.classList.contains("protyle-icons")) {
item.insertAdjacentHTML("afterbegin", `<div class="protyle-icons">
<span aria-label="${window.siyuan.languages.edit}" class="b3-tooltips__sw b3-tooltips protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span>
<span aria-label="${window.siyuan.languages.more}" class="b3-tooltips__sw b3-tooltips protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span>
</div>`);
}
const renderElement = item.firstElementChild.nextElementSibling as HTMLElement;
renderElement.removeAttribute("data-processed");
renderElement.textContent = Lute.UnEscapeHTMLStr(item.getAttribute("data-content"));
setTimeout(() => {
window.mermaid.init(undefined, renderElement);
}, Constants.TIMEOUT_LOAD * index);
item.setAttribute("data-render", "true");
renderElement.setAttribute("contenteditable", "false");
if (!item.textContent.endsWith(Constants.ZWSP)) {
item.insertAdjacentHTML("beforeend", `<span style="position: absolute">${Constants.ZWSP}</span>`);
}
});
};