A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
at lambda-fork/main 64 lines 3.0 kB view raw
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};