A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1import {addScript} from "../util/addScript";
2import {Constants} from "../../constants";
3import {hasClosestByAttribute, hasClosestByClassName} from "../util/hasClosest";
4import {genIconHTML} from "./util";
5
6declare const flowchart: {
7 parse(text: string): { drawSVG: (type: Element) => void };
8};
9
10export const flowchartRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
11 let flowchartElements: Element[] = [];
12 if (element.getAttribute("data-subtype") === "flowchart") {
13 // 编辑器内代码块编辑渲染
14 flowchartElements = [element];
15 } else {
16 flowchartElements = Array.from(element.querySelectorAll('[data-subtype="flowchart"]'));
17 }
18 if (flowchartElements.length === 0) {
19 return;
20 }
21 addScript(`${cdn}/js/flowchart.js/flowchart.min.js?v=1.18.0`, "protyleFlowchartScript").then(() => {
22 if (flowchartElements[0].firstElementChild.clientWidth === 0) {
23 const observer = new MutationObserver(() => {
24 initFlowchart(flowchartElements);
25 observer.disconnect();
26 });
27 const hideElement = hasClosestByAttribute(flowchartElements[0], "fold", "1");
28 if (hideElement) {
29 observer.observe(hideElement, {attributeFilter: ["fold"]});
30 } else {
31 const cardElement = hasClosestByClassName(flowchartElements[0], "card__block", true);
32 if (cardElement) {
33 observer.observe(cardElement, {attributeFilter: ["class"]});
34 }
35 }
36 } else {
37 initFlowchart(flowchartElements);
38 }
39 });
40};
41
42const initFlowchart = (flowchartElements: Element[]) => {
43 const wysiswgElement = hasClosestByClassName(flowchartElements[0], "protyle-wysiwyg", true);
44 flowchartElements.forEach((item: HTMLElement) => {
45 if (item.getAttribute("data-render") === "true") {
46 return;
47 }
48 if (!item.firstElementChild.classList.contains("protyle-icons")) {
49 item.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement));
50 }
51 const renderElement = item.firstElementChild.nextElementSibling;
52 if (!item.getAttribute("data-content")) {
53 renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span>`;
54 return;
55 }
56 try {
57 renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span><div contenteditable="false"></div>`;
58 flowchart.parse(Lute.UnEscapeHTMLStr(item.getAttribute("data-content"))).drawSVG(renderElement.lastElementChild);
59 } catch (error) {
60 renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span><div class="ft__error" contenteditable="false">Flow Chart render error: <br>${error}</div>`;
61 }
62 item.setAttribute("data-render", "true");
63 });
64};