mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-18 22:36:10 +01:00
🎨
This commit is contained in:
parent
a9b58641ea
commit
3729c16fd6
1 changed files with 110 additions and 110 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import {addScript} from "../util/addScript";
|
||||
import {Constants} from "../../constants";
|
||||
import {hasClosestByClassName} from "../util/hasClosest";
|
||||
import {genIconHTML} from "./util";
|
||||
import { addScript } from "../util/addScript";
|
||||
import { Constants } from "../../constants";
|
||||
import { hasClosestByClassName } from "../util/hasClosest";
|
||||
import { genIconHTML } from "./util";
|
||||
|
||||
export const mindmapRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
|
||||
let mindmapElements: Element[] = [];
|
||||
|
|
@ -19,122 +19,122 @@ export const mindmapRender = (element: Element, cdn = Constants.PROTYLE_CDN) =>
|
|||
.then(() => addScript(`${cdn}/js/markmap/markmap-lib.min.js`, "protyleMarkmapLibScript"))
|
||||
.then(() => addScript(`${cdn}/js/markmap/markmap-view.min.js`, "protyleMarkmapScript"))
|
||||
.then(() => {
|
||||
const wysiswgElement = hasClosestByClassName(element, "protyle-wysiwyg", true);
|
||||
let width: number = undefined;
|
||||
if (wysiswgElement && wysiswgElement.clientWidth > 0 && mindmapElements[0].firstElementChild.clientWidth === 0 && wysiswgElement.firstElementChild) {
|
||||
width = wysiswgElement.firstElementChild.clientWidth;
|
||||
}
|
||||
mindmapElements.forEach((e: HTMLDivElement) => {
|
||||
if (e.getAttribute("data-render") === "true") {
|
||||
return;
|
||||
const wysiswgElement = hasClosestByClassName(element, "protyle-wysiwyg", true);
|
||||
let width: number = undefined;
|
||||
if (wysiswgElement && wysiswgElement.clientWidth > 0 && mindmapElements[0].firstElementChild.clientWidth === 0 && wysiswgElement.firstElementChild) {
|
||||
width = wysiswgElement.firstElementChild.clientWidth;
|
||||
}
|
||||
if (!e.firstElementChild.classList.contains("protyle-icons")) {
|
||||
e.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement));
|
||||
}
|
||||
const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
|
||||
if (!e.getAttribute("data-content")) {
|
||||
renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span>`;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// create or reuse container for markmap
|
||||
if (!renderElement.lastElementChild || renderElement.childElementCount === 1) {
|
||||
renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span><div style="height:${e.style.height || "420px"}" contenteditable="false"></div>`;
|
||||
} else {
|
||||
renderElement.lastElementChild.classList.remove("ft__error");
|
||||
mindmapElements.forEach((e: HTMLDivElement) => {
|
||||
if (e.getAttribute("data-render") === "true") {
|
||||
return;
|
||||
}
|
||||
if (!e.firstElementChild.classList.contains("protyle-icons")) {
|
||||
e.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement));
|
||||
}
|
||||
const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
|
||||
if (!e.getAttribute("data-content")) {
|
||||
renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span>`;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// create or reuse container for markmap
|
||||
if (!renderElement.lastElementChild || renderElement.childElementCount === 1) {
|
||||
renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span><div style="height:${e.style.height || "420px"}" contenteditable="false"></div>`;
|
||||
} else {
|
||||
renderElement.lastElementChild.classList.remove("ft__error");
|
||||
}
|
||||
|
||||
// Convert stored content to markdown using Lute (prefer existing instance), then transform/render with markmap
|
||||
const raw = Lute.UnEscapeHTMLStr(e.getAttribute("data-content"));
|
||||
let md: string = raw;
|
||||
// prefer protyle's lute instance if available
|
||||
if ((window as any).protyle && (window as any).protyle.lute && typeof (window as any).protyle.lute.BlockDOM2Md === "function") {
|
||||
md = (window as any).protyle.lute.BlockDOM2Md(raw);
|
||||
} else if (typeof Lute === "function" && typeof Lute.New === "function") {
|
||||
// Convert stored content to markdown using Lute (prefer existing instance), then transform/render with markmap
|
||||
const raw = Lute.UnEscapeHTMLStr(e.getAttribute("data-content"));
|
||||
let md: string = raw;
|
||||
// prefer protyle's lute instance if available
|
||||
if ((window as any).protyle && (window as any).protyle.lute && typeof (window as any).protyle.lute.BlockDOM2Md === "function") {
|
||||
md = (window as any).protyle.lute.BlockDOM2Md(raw);
|
||||
} else if (typeof Lute === "function" && typeof Lute.New === "function") {
|
||||
try {
|
||||
const luteInst = Lute.New();
|
||||
if (luteInst && typeof luteInst.BlockDOM2Md === "function") {
|
||||
md = luteInst.BlockDOM2Md(raw);
|
||||
} else if (luteInst && typeof luteInst.BlockDOM2HTML === "function") {
|
||||
md = luteInst.BlockDOM2HTML(raw);
|
||||
}
|
||||
} catch (e) {
|
||||
// fallback to raw
|
||||
md = raw;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to obtain markmap entry from loaded bundles (single unified reference)
|
||||
const mm: any = (window as any).markmap;
|
||||
|
||||
// Prefer the new markmap Transformer API when available
|
||||
let data: any = null;
|
||||
let rootData: any = null;
|
||||
try {
|
||||
const luteInst = Lute.New();
|
||||
if (luteInst && typeof luteInst.BlockDOM2Md === "function") {
|
||||
md = luteInst.BlockDOM2Md(raw);
|
||||
} else if (luteInst && typeof luteInst.BlockDOM2HTML === "function") {
|
||||
md = luteInst.BlockDOM2HTML(raw);
|
||||
if (mm && typeof mm.Transformer === "function") {
|
||||
const transformer = new mm.Transformer();
|
||||
const tx = transformer.transform(md);
|
||||
// tx contains { root, features }
|
||||
rootData = tx && tx.root;
|
||||
|
||||
// load assets required by used features
|
||||
const assetsGetter = typeof transformer.getUsedAssets === "function" ? "getUsedAssets" : (typeof transformer.getAssets === "function" ? "getAssets" : null);
|
||||
if (assetsGetter) {
|
||||
const assets = (transformer as any)[assetsGetter](tx.features);
|
||||
const styles = assets && assets.styles;
|
||||
const scripts = assets && assets.scripts;
|
||||
if (styles && typeof mm.loadCSS === "function") {
|
||||
try { mm.loadCSS(styles); } catch (err) { /* ignore */ }
|
||||
}
|
||||
if (scripts && typeof mm.loadJS === "function") {
|
||||
try { mm.loadJS(scripts, { getMarkmap: () => (window as any).markmap }); } catch (err) { /* ignore */ }
|
||||
}
|
||||
}
|
||||
} else if (mm && typeof mm.transform === "function") {
|
||||
data = mm.transform(md);
|
||||
} else if ((window as any).markmap && typeof (window as any).markmap.transform === "function") {
|
||||
data = (window as any).markmap.transform(md);
|
||||
}
|
||||
} catch (e) {
|
||||
// fallback to raw
|
||||
md = raw;
|
||||
// fallback, leave data/rootData null and let downstream handle it
|
||||
data = null;
|
||||
rootData = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to obtain markmap entry from loaded bundles (single unified reference)
|
||||
const mm: any = (window as any).markmap;
|
||||
|
||||
// Prefer the new markmap Transformer API when available
|
||||
let data: any = null;
|
||||
let rootData: any = null;
|
||||
try {
|
||||
if (mm && typeof mm.Transformer === "function") {
|
||||
const transformer = new mm.Transformer();
|
||||
const tx = transformer.transform(md);
|
||||
// tx contains { root, features }
|
||||
rootData = tx && tx.root;
|
||||
|
||||
// load assets required by used features
|
||||
const assetsGetter = typeof transformer.getUsedAssets === "function" ? "getUsedAssets" : (typeof transformer.getAssets === "function" ? "getAssets" : null);
|
||||
if (assetsGetter) {
|
||||
const assets = (transformer as any)[assetsGetter](tx.features);
|
||||
const styles = assets && assets.styles;
|
||||
const scripts = assets && assets.scripts;
|
||||
if (styles && typeof mm.loadCSS === "function") {
|
||||
try { mm.loadCSS(styles); } catch (err) { /* ignore */ }
|
||||
}
|
||||
if (scripts && typeof mm.loadJS === "function") {
|
||||
try { mm.loadJS(scripts, { getMarkmap: () => (window as any).markmap }); } catch (err) { /* ignore */ }
|
||||
}
|
||||
}
|
||||
} else if (mm && typeof mm.transform === "function") {
|
||||
data = mm.transform(md);
|
||||
} else if ((window as any).markmap && typeof (window as any).markmap.transform === "function") {
|
||||
data = (window as any).markmap.transform(md);
|
||||
}
|
||||
} catch (e) {
|
||||
// fallback, leave data/rootData null and let downstream handle it
|
||||
data = null;
|
||||
rootData = null;
|
||||
}
|
||||
|
||||
// container for svg
|
||||
const container = renderElement.lastElementChild as HTMLElement;
|
||||
// clear existing content and append an svg for markmap
|
||||
container.innerHTML = "";
|
||||
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
// use width if calculated earlier
|
||||
if (typeof width === "number" && width > 0) {
|
||||
svg.setAttribute("width", String(width));
|
||||
} else {
|
||||
svg.setAttribute("width", "100%");
|
||||
}
|
||||
svg.setAttribute("height", "100%");
|
||||
container.appendChild(svg);
|
||||
|
||||
// prefer Markmap.create if available
|
||||
const MarkmapCtor = (mm && (mm.Markmap || mm.default || mm)) || (window as any).Markmap;
|
||||
if (MarkmapCtor && typeof MarkmapCtor.create === "function") {
|
||||
if (rootData) {
|
||||
// When Transformer was used we have a `root` structure
|
||||
MarkmapCtor.create(svg, null, rootData);
|
||||
// container for svg
|
||||
const container = renderElement.lastElementChild as HTMLElement;
|
||||
// clear existing content and append an svg for markmap
|
||||
container.innerHTML = "";
|
||||
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
// use width if calculated earlier
|
||||
if (typeof width === "number" && width > 0) {
|
||||
svg.setAttribute("width", String(width));
|
||||
} else {
|
||||
if (!data && typeof MarkmapCtor.transform === "function") {
|
||||
try { data = MarkmapCtor.transform(md); } catch (err) { data = null; }
|
||||
}
|
||||
MarkmapCtor.create(svg, data || { root: { children: [] } }, { embedCSS: true });
|
||||
svg.setAttribute("width", "100%");
|
||||
}
|
||||
} else {
|
||||
throw new Error("Markmap not available");
|
||||
}
|
||||
} catch (error) {
|
||||
svg.setAttribute("height", "100%");
|
||||
container.appendChild(svg);
|
||||
|
||||
renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span><div class="ft__error" style="height:${e.style.height || "420px"}" contenteditable="false">Mindmap render error: <br>${error}</div>`;
|
||||
}
|
||||
e.setAttribute("data-render", "true");
|
||||
// prefer Markmap.create if available
|
||||
const MarkmapCtor = (mm && (mm.Markmap || mm.default || mm)) || (window as any).Markmap;
|
||||
if (MarkmapCtor && typeof MarkmapCtor.create === "function") {
|
||||
if (rootData) {
|
||||
// When Transformer was used we have a `root` structure
|
||||
MarkmapCtor.create(svg, null, rootData);
|
||||
} else {
|
||||
if (!data && typeof MarkmapCtor.transform === "function") {
|
||||
try { data = MarkmapCtor.transform(md); } catch (err) { data = null; }
|
||||
}
|
||||
MarkmapCtor.create(svg, data || { root: { children: [] } }, { embedCSS: true });
|
||||
}
|
||||
} else {
|
||||
throw new Error("Markmap not available");
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span><div class="ft__error" style="height:${e.style.height || "420px"}" contenteditable="false">Mindmap render error: <br>${error}</div>`;
|
||||
}
|
||||
e.setAttribute("data-render", "true");
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue