@netless/appliance-plugin 1.1.36-beta.4 → 1.1.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/appliance-plugin.js +1 -1
- package/dist/appliance-plugin.mjs +1 -1
- package/dist/assets/{fullWorker-Bji8YEga.js → fullWorker-BnxU9bnt.js} +1 -1
- package/dist/assets/{subWorker-EBGqPf7s.js → subWorker-BsTroxB8.js} +1 -1
- package/dist/bridge-C7tN2qjT.js +1 -0
- package/dist/bridge-DmxbEjIC.mjs +67 -0
- package/dist/bridge.js +1 -1
- package/dist/bridge.mjs +1 -1
- package/dist/component/svg/manager.d.ts +1 -1
- package/dist/component/svg/markmap-runtime.d.ts +39 -0
- package/dist/component/svg/mermaid.d.ts +12 -3
- package/dist/component/svg/snapshot.d.ts +1 -1
- package/dist/component/svg/svgElemt.d.ts +2 -2
- package/dist/core/mainEngine.d.ts +1 -0
- package/dist/fullWorker.js +1 -1
- package/dist/index-09gdXQ2w.js +1 -0
- package/dist/{index-DIUxN_Uj.mjs → index-BCNBmzwR.mjs} +444 -411
- package/dist/index-BW3Xkxk-.js +1 -0
- package/dist/index-Bl1tLXFo.js +1 -0
- package/dist/{index-CXsBcxaO.mjs → index-CNcfXUx4.mjs} +1 -1
- package/dist/index-D-4DoHbs.mjs +769 -0
- package/dist/index-DKbaEDea.js +1 -0
- package/dist/{index-CvW3SdH4.js → index-DqCdgRfA.js} +1 -1
- package/dist/{index-DlGlPREI.mjs → index-TIV0naEi.mjs} +819 -804
- package/dist/index-nxeYRf5P.mjs +771 -0
- package/dist/{index-FpadMsTK.js → index-r9ho55PA.js} +1 -1
- package/dist/{index-dsmRXiK1.mjs → index-rYcPxCxx.mjs} +1 -1
- package/dist/markmap-runtime-Cg3OxuZ2.mjs +25 -0
- package/dist/markmap-runtime-CsBCTpRs.js +1 -0
- package/dist/markmap.d.ts +1 -0
- package/dist/markmap.js +3 -0
- package/dist/markmap.mjs +535 -0
- package/dist/plugin/types.d.ts +1 -1
- package/dist/subWorker.js +1 -1
- package/package.json +23 -4
- package/dist/bridge-CBJiO03C.js +0 -1
- package/dist/bridge-MIUgb_9o.mjs +0 -67
- package/dist/index-BE1zE-eD.js +0 -3
- package/dist/index-C9RblUmt.mjs +0 -1262
- package/dist/index-CaWs6nK1.js +0 -1
- package/dist/index-DXF7au5i.js +0 -3
- package/dist/index-DsFl0A7n.js +0 -1
- package/dist/index-DzTeGttZ.mjs +0 -1263
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var _t = Object.defineProperty;
|
|
2
2
|
var Vt = (T, i, e) => i in T ? _t(T, i, { enumerable: !0, configurable: !0, writable: !0, value: e }) : T[i] = e;
|
|
3
3
|
var y = (T, i, e) => Vt(T, typeof i != "symbol" ? i + "" : i, e);
|
|
4
|
-
import {
|
|
4
|
+
import { e as Je, i as et, _ as Pt, p as Se, f as Te, D as J, h as A, j as Re, k as Ve, l as se, P as E, m as W, c as k, s as qe, n as tt, o as Ne, q as st, r as qt, t as Ht, u as Me, v as U, a as w, b as x, w as O, x as G, y as ee, z as $, A as Ze, B as jt, C as Zt, F as Kt, G as Qt, H as Jt, I as es, J as ts, K as ss, L as X, M as os, N as ht, O as We, Q as Wt, T as Be, R as ye, U as is, W as Lt, X as rs, Y as ns, Z as ce, $ as _, a0 as ue, a1 as as, a2 as cs, a3 as ls, a4 as hs, a5 as be, a6 as ps, E as Y, a7 as pt, V as dt, S as ds } from "./index-BCNBmzwR.mjs";
|
|
5
5
|
import { Group as j, Path as we, Sprite as Ct, Rect as Ke, Polyline as he, Ellipse as us, Label as fs, Scene as ot, Layer as ms } from "spritejs";
|
|
6
6
|
import ie from "clipper-lib";
|
|
7
7
|
import it from "lineclip";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const n = "__netless_appliance_plugin_markmap_runtime__";
|
|
2
|
+
function e() {
|
|
3
|
+
return globalThis;
|
|
4
|
+
}
|
|
5
|
+
function i(r) {
|
|
6
|
+
e()[n] = r;
|
|
7
|
+
}
|
|
8
|
+
function a() {
|
|
9
|
+
return e()[n];
|
|
10
|
+
}
|
|
11
|
+
function t() {
|
|
12
|
+
return new Error(
|
|
13
|
+
'Markmap runtime is not registered. Install "markmap-lib", "markmap-view", and "mermaid", then import "@netless/appliance-plugin/markmap" before using insertMarkmap/updateMarkmap.'
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
function m() {
|
|
17
|
+
const r = a();
|
|
18
|
+
if (!r)
|
|
19
|
+
throw t();
|
|
20
|
+
return r;
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
m as g,
|
|
24
|
+
i as r
|
|
25
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const e="__netless_appliance_plugin_markmap_runtime__";function n(){return globalThis}function t(r){n()[e]=r}function a(){return n()[e]}function i(){return new Error('Markmap runtime is not registered. Install "markmap-lib", "markmap-view", and "mermaid", then import "@netless/appliance-plugin/markmap" before using insertMarkmap/updateMarkmap.')}function m(){const r=a();if(!r)throw i();return r}exports.getMarkmapRuntimeOrThrow=m;exports.registerMarkmapRuntime=t;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./component/svg/markmap";
|
package/dist/markmap.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";var j=Object.create;var F=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var z=Object.getPrototypeOf,U=Object.prototype.hasOwnProperty;var G=(r,t,e)=>t in r?F(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var R=(r,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of D(t))!U.call(r,i)&&i!==e&&F(r,i,{get:()=>t[i],enumerable:!(a=K(t,i))||a.enumerable});return r};var V=(r,t,e)=>(e=r!=null?j(z(r)):{},R(t||!r||!r.__esModule?F(e,"default",{value:r,enumerable:!0}):e,r));var $=(r,t,e)=>G(r,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const X=require("markmap-view"),N=require("markmap-lib"),Y=require("./markmap-runtime-CsBCTpRs.js");function J(r){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const e in r)if(e!=="default"){const a=Object.getOwnPropertyDescriptor(r,e);Object.defineProperty(t,e,a.get?a:{enumerable:!0,get:()=>r[e]})}}return t.default=r,Object.freeze(t)}const W=J(X);let I=null,M=null,O=!1;async function Z(){return I||M||(M=import("mermaid").then(r=>(I=r,M=null,r)).catch(r=>{throw M=null,r}),M)}async function Q(){const r=await Z();return O||(r.default.initialize({startOnLoad:!1,theme:"default"}),O=!0),r}function _(){return(I==null?void 0:I.default)||null}const v=class v{constructor(){$(this,"mermaidCodeBlocksByWorkId",new Map)}static getInstance(){return v.instance||(v.instance=new v),v.instance}generateId(){return`mermaid-${Math.random().toString(36).substr(2,9)}`}createContainer(t,e,a){if(e&&a){let i=this.mermaidCodeBlocksByWorkId.get(a);i||(i=new Map,this.mermaidCodeBlocksByWorkId.set(a,i)),i.set(t,e)}return`<div class="mermaid-container" data-mermaid-id="${t}"><div class="mermaid-placeholder" id="${t}">正在渲染图表...</div></div>`}getCode(t,e){const a=this.mermaidCodeBlocksByWorkId.get(e);return a==null?void 0:a.get(t)}clear(t){t?this.mermaidCodeBlocksByWorkId.delete(t):this.mermaidCodeBlocksByWorkId.clear()}extendMarkdown(t,e){const a=t.md.renderer,i=a.rules.fence,u=this;a.rules.fence=(s,n,m,h,f)=>{const l=s[n];if(l.info.trim()==="mermaid"){const g=u.generateId();return u.createContainer(g,l.content,e)}return i?i(s,n,m,h,f):""}}static generateId(){return v.getInstance().generateId()}static createContainer(t,e,a){return v.getInstance().createContainer(t,e,a)}static getCode(t,e){return v.getInstance().getCode(t,e)}static clear(t){v.getInstance().clear(t)}static extendMarkdown(t,e){v.getInstance().extendMarkdown(t,e)}};$(v,"instance",null);let S=v;class A{static checkNodeHasMermaid(t){if(!t)return!1;if(t.content&&typeof t.content=="string"&&(t.content.includes('class="mermaid-container"')||t.content.includes("class='mermaid-container'")||t.content.includes("data-mermaid-id=")||t.content.includes("mermaid-placeholder")))return!0;if(t.children&&Array.isArray(t.children)){for(const e of t.children)if(A.checkNodeHasMermaid(e))return!0}return!1}static async renderMermaidAfterDOMUpdate(t,e){await A.renderMermaidBlocks(t,e)}static async renderMermaidBlocks(t,e){if(!t)return;try{await Q()}catch(n){console.error("[renderMermaidBlocks] error: ",n);return}const a=_();if(!a)return;let i=null,u=!1;for(let n=0;n<30;n++){const m=t.querySelectorAll("foreignObject");if(i=t.querySelectorAll(".mermaid-container"),i.length>0||(m.length>0&&(u=!0),await new Promise(h=>setTimeout(h,50)),u&&n>=20))break}if(!i||i.length===0)return;const s=Array.from(i).map(async(n,m)=>{const h=n,f=h.getAttribute("data-mermaid-id"),l=f?S.getCode(f,e):void 0,d=h.querySelector(".mermaid-placeholder");if(!(!d||!l))try{const p=`mermaid-${e.replace(/[^a-zA-Z0-9_-]/g,"-")}-${Date.now()}-${m}`,{svg:y}=await a.render(p,l);if(d&&d.parentNode){const w=document.createElement("div");w.innerHTML=y;const o=w.querySelector("svg");if(o){if(!o.getAttribute("viewBox")&&o.getAttribute("width")&&o.getAttribute("height")){const C=o.getAttribute("width"),x=o.getAttribute("height"),b=parseFloat((C==null?void 0:C.replace(/px|%/,""))||"0"),k=parseFloat((x==null?void 0:x.replace(/px|%/,""))||"0");b>0&&k>0&&o.setAttribute("viewBox",`0 0 ${b} ${k}`)}o.style.display="block",o.style.maxWidth="100%",o.style.width="auto",o.style.height="auto",o.style.overflow="visible",o.style.verticalAlign="top",o.style.objectFit="contain";const c=document.createElement("div");c.className="mermaid-wrapper",c.style.width="100%",c.style.height="auto",c.style.overflow="hidden",c.style.display="inline-block",c.style.verticalAlign="top",c.style.margin="0",c.style.padding="0",c.style.boxSizing="border-box",c.style.position="relative",this.isSafari()&&(c.style.clipPath="inset(100% 0 0 0)",c.style.pointerEvents="none"),c.appendChild(o),o.style.width="100%",o.style.height="100%",o.style.maxWidth="100%",o.style.maxHeight="100%",o.style.objectFit="contain",o.setAttribute("data-type","mermaid"),this.isSafari()&&(o.style.opacity="0"),d.parentNode.replaceChild(c,d)}else d.outerHTML=y}}catch(g){const p=g instanceof Error?g.message:String(g);d&&(d.textContent=`Mermaid 渲染失败: ${p}`,d.style.color="red",d.style.fontSize="12px")}});await Promise.all(s)}static isSafari(){const t=navigator.userAgent.toLowerCase(),e=t.indexOf("safari")!==-1&&t.indexOf("chrome")===-1&&t.indexOf("chromium")===-1,a=!!(navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1);return e||a}static async transformMermaidSvgToMarkmapSvg(t){if(!t)return;await new Promise(s=>setTimeout(s,200));const e=t.querySelectorAll('g[data-mermaid-wrapper][data-mermaid-clone="true"]'),a=t.querySelectorAll("foreignObject"),i=new Set;if(a.forEach(s=>{const n=s.querySelector(".mermaid-container"),m=n==null?void 0:n.getAttribute("data-mermaid-id");m&&i.add(m)}),e.forEach(s=>{const n=s.getAttribute("data-mermaid-id");n&&!i.has(n)&&s.remove()}),a.length===0)return;const u=Array.from(a).map(async s=>{let n=s.querySelector('svg[data-type="mermaid"]');if(!n){const f=s.querySelector(".mermaid-wrapper");f&&(n=f.querySelector('svg[data-type="mermaid"]'))}if(!n)return;const m=s.querySelector(".mermaid-container"),h=m==null?void 0:m.getAttribute("data-mermaid-id");if(h)try{const f=parseFloat(s.getAttribute("x")||"0"),l=parseFloat(s.getAttribute("y")||"0"),d=parseFloat(s.getAttribute("width")||"0"),g=parseFloat(s.getAttribute("height")||"0");if(d<=0||g<=0)return;const p=s.parentElement;if(!p||p.tagName!=="g")return;let y=p.getAttribute("transform");if(!y)y=`translate(${f}, ${l})`;else{const x=y.match(/translate\(([^,]+),([^)]+)\)/);if(x){const b=parseFloat(x[1]),k=parseFloat(x[2]),T=b+f,P=k+l;y=y.replace(/translate\([^)]+\)/,`translate(${T}, ${P})`)}else y=`translate(${f}, ${l}) ${y}`}const w=t.querySelector(`g[data-mermaid-wrapper][data-mermaid-id="${h}"][data-mermaid-clone="true"]`);let o;if(w){o=w;const x=o.querySelector('svg[data-type="mermaid"]');x&&o.removeChild(x)}else o=document.createElementNS("http://www.w3.org/2000/svg","g"),o.setAttribute("data-mermaid-wrapper","true"),o.setAttribute("data-mermaid-clone","true"),o.setAttribute("data-mermaid-id",h);o.setAttribute("transform",y);const c=n.cloneNode(!0);if(c.setAttribute("width",d.toString()),c.setAttribute("height",g.toString()),c.setAttribute("data-mermaid-transformed","true"),c.style.width="",c.style.height="",c.style.maxWidth="",c.style.maxHeight="",c.style.transform="",c.style.transformOrigin="",c.style.display="block",c.style.overflow="visible",c.style.opacity="1",!c.getAttribute("viewBox")){const x=c.getAttribute("width"),b=c.getAttribute("height");if(x&&b){const k=parseFloat(x.replace(/px|%/,"")||"0"),T=parseFloat(b.replace(/px|%/,"")||"0");k>0&&T>0&&c.setAttribute("viewBox",`0 0 ${k} ${T}`)}}o.appendChild(c),w||(p&&p.parentNode?p.parentNode.insertBefore(o,p.nextSibling):t.appendChild(o)),m&&(m.style.opacity="0",m.style.pointerEvents="none")}catch(f){console.error("[transformMermaidSvgToMarkmapSvg] error: ",f)}});await Promise.all(u)}static injectMermaidHtml(t,e,a){const i=[],u=e.split(`
|
|
2
|
+
`);let s="",n=!1,m=[],h=-1;for(let l=0;l<u.length;l++){const d=u[l],g=d.match(/^(#{1,6})\s+(.+)$/);if(g&&(s=g[2].trim()),d.trim().startsWith("```mermaid"))n=!0,m=[],h=l;else if(n&&d.trim()==="```"){n=!1;const p=m.join(`
|
|
3
|
+
`);p&&s&&i.push({title:s,content:p,index:h}),m=[]}else n&&m.push(d)}const f=l=>{if(!l)return;const d=l.content||"",g=A.decodeHtmlEntities(d);for(const p of i)if(g.includes(p.title)||d.includes(p.title)){const y=S.generateId(),w=S.createContainer(y,p.content,a);l.content?l.content=l.content+w:l.content=w;break}l.children&&l.children.length>0&&l.children.forEach(p=>{f(p)})};return f(t),t}static decodeHtmlEntities(t){const e=document.createElement("textarea");return e.innerHTML=t,e.value}static hasMermaidSvg(t){return t.querySelectorAll("svg[data-type='mermaid']").length>0}}class q extends N.Transformer{constructor(e){super(e);$(this,"currentWorkId",null)}setWorkId(e){this.currentWorkId=e,e&&S.extendMarkdown(this,e)}transform(e,a){this.currentWorkId?S.clear(this.currentWorkId):S.clear();const i=this.convertKatexToText(e),u=super.transform(i,a);return u.root&&this.processKatexInRoot(u.root),u}convertKatexToText(e){if(!e)return e;let a=e.replace(/\$\$([\s\S]*?)\$\$/g,(i,u)=>u.replace(/\\/g,"").replace(/\{/g,"").replace(/\}/g,"").replace(/\\over/g,"/").replace(/\\pm/g,"±").replace(/\\sqrt/g,"√").replace(/\\frac/g,"/").trim());return a=a.replace(/\$([^$\n]+?)\$/g,(i,u)=>u.replace(/\\/g,"").replace(/\{/g,"").replace(/\}/g,"").replace(/\\over/g,"/").replace(/\\pm/g,"±").replace(/\\sqrt/g,"√").replace(/\\frac/g,"/").trim()),a}processKatexInRoot(e){if(e){if(e.content&&typeof e.content=="string"&&(e.content.includes("katex")||e.content.includes("katex-mathml"))){const a=e.content.match(/<annotation[^>]*encoding="application\/x-tex">([^<]+)<\/annotation>/);if(a){const i=a[1].replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&").replace(/\\/g,"").replace(/\{/g,"").replace(/\}/g,"").replace(/\\over/g,"/").replace(/\\pm/g,"±").replace(/\\sqrt/g,"√").replace(/\\frac/g,"/").trim();e.content=e.content.replace(/<div[^>]*xmlns="http:\/\/www\.w3\.org\/1999\/xhtml"[^>]*>Katex:\s*<span[^>]*class="katex"[^>]*>[\s\S]*?<\/span><\/div>/g,i)}else{const i=document.createElement("div");i.innerHTML=e.content;const u=i.querySelector(".katex");if(u){let s=u.textContent||"";s=s.replace(/^Katex:\s*/i,"").trim(),e.content=e.content.replace(/<div[^>]*xmlns="http:\/\/www\.w3\.org\/1999\/xhtml"[^>]*>Katex:\s*<span[^>]*class="katex"[^>]*>[\s\S]*?<\/span><\/div>/g,s||"公式")}else{const s=e.content.replace(/<[^>]+>/g," ").replace(/\s+/g," ").replace(/^Katex:\s*/i,"").trim();e.content=s||"公式"}}}e.children&&Array.isArray(e.children)&&e.children.forEach(a=>{this.processKatexInRoot(a)})}}static async waitForImagesInForeignObjects(e,a=1e4){if(!e)return;const i=e.querySelectorAll("foreignObject.markmap-foreign img");if(i.length===0)return;const u=[],s=new Set;i.forEach(n=>{const m=n.src||n.getAttribute("src");if(!m||s.has(m)||(s.add(m),n.complete&&n.naturalWidth>0))return;const h=new Promise(f=>{const l=setTimeout(()=>{f()},a);if(n.complete&&n.naturalWidth>0){clearTimeout(l),f();return}const d=()=>{clearTimeout(l),n.removeEventListener("load",d),n.removeEventListener("error",g),f()},g=()=>{clearTimeout(l),n.removeEventListener("load",d),n.removeEventListener("error",g),f()};n.addEventListener("load",d),n.addEventListener("error",g),!n.src&&m&&(n.src=m)});u.push(h)}),u.length>0&&await Promise.all(u)}}const B=new q,{loadCSS:ee,loadJS:te,Markmap:L}=W,{scripts:E,styles:H}=B.getAssets();H&&ee(H);E&&te(E,{getMarkmap:()=>W});Y.registerMarkmapRuntime({createMarkmap(r,t){return L.create(r,t)},transform(r,t){return B.setWorkId(r),B.transform(t)},hasMermaidCodeBlock(r){return/```\s*mermaid[\s\S]*?```/i.test(r)},checkNodeHasMermaid(r){const t=e=>e?e.content&&typeof e.content=="string"&&(e.content.includes('class="mermaid-container"')||e.content.includes("class='mermaid-container'")||e.content.includes("data-mermaid-id=")||e.content.includes("mermaid-placeholder"))?!0:e.children&&Array.isArray(e.children)?e.children.some(t):!1:!1;return t(r)},async renderMermaidAfterDOMUpdate(r,t){await A.renderMermaidAfterDOMUpdate(r,t)},injectMermaidHtml(r,t,e){return A.injectMermaidHtml(r,t,e)},async waitForImagesInForeignObjects(r){await q.waitForImagesInForeignObjects(r)},async transformMermaidSvgToMarkmapSvg(r){await A.transformMermaidSvgToMarkmapSvg(r)},isSafari(){const r=navigator.userAgent.toLowerCase(),t=r.indexOf("safari")!==-1&&r.indexOf("chrome")===-1&&r.indexOf("chromium")===-1,e=!!(navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1);return t||e},hasMermaidSvg(r){return r.querySelectorAll("svg[data-type='mermaid']").length>0}});exports.markmap=W;Object.defineProperty(exports,"Transformer",{enumerable:!0,get:()=>N.Transformer});exports.Markmap=L;exports.MermaidTransformer=q;exports.transformer=B;
|
package/dist/markmap.mjs
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
var L = Object.defineProperty;
|
|
2
|
+
var O = (a, t, e) => t in a ? L(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e;
|
|
3
|
+
var B = (a, t, e) => O(a, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import * as E from "markmap-view";
|
|
5
|
+
import { Transformer as P } from "markmap-lib";
|
|
6
|
+
import { Transformer as Q } from "markmap-lib";
|
|
7
|
+
import { r as K } from "./markmap-runtime-Cg3OxuZ2.mjs";
|
|
8
|
+
let I = null, M = null, W = !1;
|
|
9
|
+
async function j() {
|
|
10
|
+
return I || M || (M = import("mermaid").then((a) => (I = a, M = null, a)).catch((a) => {
|
|
11
|
+
throw M = null, a;
|
|
12
|
+
}), M);
|
|
13
|
+
}
|
|
14
|
+
async function z() {
|
|
15
|
+
const a = await j();
|
|
16
|
+
return W || (a.default.initialize({
|
|
17
|
+
startOnLoad: !1,
|
|
18
|
+
theme: "default"
|
|
19
|
+
}), W = !0), a;
|
|
20
|
+
}
|
|
21
|
+
function D() {
|
|
22
|
+
return (I == null ? void 0 : I.default) || null;
|
|
23
|
+
}
|
|
24
|
+
const w = class w {
|
|
25
|
+
constructor() {
|
|
26
|
+
// 使用 workId 作为 key,存储每个实例的 mermaid 代码块
|
|
27
|
+
B(this, "mermaidCodeBlocksByWorkId", /* @__PURE__ */ new Map());
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 获取 MermaidManager 单例实例
|
|
31
|
+
*/
|
|
32
|
+
static getInstance() {
|
|
33
|
+
return w.instance || (w.instance = new w()), w.instance;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 生成唯一的 mermaid ID
|
|
37
|
+
*/
|
|
38
|
+
generateId() {
|
|
39
|
+
return `mermaid-${Math.random().toString(36).substr(2, 9)}`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 生成 mermaid HTML 容器
|
|
43
|
+
* @param id mermaid ID
|
|
44
|
+
* @param mermaidCode mermaid 代码(可选,如果提供则存储)
|
|
45
|
+
* @param workId 工作 ID(用于命名空间隔离)
|
|
46
|
+
* @returns HTML 字符串
|
|
47
|
+
*/
|
|
48
|
+
createContainer(t, e, n) {
|
|
49
|
+
if (e && n) {
|
|
50
|
+
let c = this.mermaidCodeBlocksByWorkId.get(n);
|
|
51
|
+
c || (c = /* @__PURE__ */ new Map(), this.mermaidCodeBlocksByWorkId.set(n, c)), c.set(t, e);
|
|
52
|
+
}
|
|
53
|
+
return `<div class="mermaid-container" data-mermaid-id="${t}"><div class="mermaid-placeholder" id="${t}">正在渲染图表...</div></div>`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 获取 mermaid 代码块
|
|
57
|
+
* @param id mermaid ID
|
|
58
|
+
* @param workId 工作 ID(用于命名空间隔离)
|
|
59
|
+
* @returns mermaid 代码或 undefined
|
|
60
|
+
*/
|
|
61
|
+
getCode(t, e) {
|
|
62
|
+
const n = this.mermaidCodeBlocksByWorkId.get(e);
|
|
63
|
+
return n == null ? void 0 : n.get(t);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 清空指定 workId 的 mermaid 代码块
|
|
67
|
+
* @param workId 工作 ID(如果未提供,清空所有)
|
|
68
|
+
*/
|
|
69
|
+
clear(t) {
|
|
70
|
+
t ? this.mermaidCodeBlocksByWorkId.delete(t) : this.mermaidCodeBlocksByWorkId.clear();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 扩展 markdown-it 的渲染规则,处理 mermaid 代码块
|
|
74
|
+
* @param transformer Transformer 实例
|
|
75
|
+
* @param workId 工作 ID(用于命名空间隔离)
|
|
76
|
+
*/
|
|
77
|
+
extendMarkdown(t, e) {
|
|
78
|
+
const n = t.md.renderer, c = n.rules.fence, u = this;
|
|
79
|
+
n.rules.fence = (i, r, d, h, f) => {
|
|
80
|
+
const l = i[r];
|
|
81
|
+
if (l.info.trim() === "mermaid") {
|
|
82
|
+
const g = u.generateId();
|
|
83
|
+
return u.createContainer(g, l.content, e);
|
|
84
|
+
}
|
|
85
|
+
return c ? c(i, r, d, h, f) : "";
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// 为了向后兼容,保留静态方法(内部使用单例)
|
|
89
|
+
static generateId() {
|
|
90
|
+
return w.getInstance().generateId();
|
|
91
|
+
}
|
|
92
|
+
static createContainer(t, e, n) {
|
|
93
|
+
return w.getInstance().createContainer(
|
|
94
|
+
t,
|
|
95
|
+
e,
|
|
96
|
+
n
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
static getCode(t, e) {
|
|
100
|
+
return w.getInstance().getCode(t, e);
|
|
101
|
+
}
|
|
102
|
+
static clear(t) {
|
|
103
|
+
w.getInstance().clear(t);
|
|
104
|
+
}
|
|
105
|
+
static extendMarkdown(t, e) {
|
|
106
|
+
w.getInstance().extendMarkdown(t, e);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
B(w, "instance", null);
|
|
110
|
+
let S = w;
|
|
111
|
+
class b {
|
|
112
|
+
/**
|
|
113
|
+
* 检查 markmap 节点及其子节点是否包含 mermaid 代码块
|
|
114
|
+
* @param node markmap 节点数据
|
|
115
|
+
* @returns 如果节点或其子节点包含 mermaid 代码块,返回 true
|
|
116
|
+
*/
|
|
117
|
+
static checkNodeHasMermaid(t) {
|
|
118
|
+
if (!t)
|
|
119
|
+
return !1;
|
|
120
|
+
if (t.content && typeof t.content == "string" && (t.content.includes('class="mermaid-container"') || t.content.includes("class='mermaid-container'") || t.content.includes("data-mermaid-id=") || t.content.includes("mermaid-placeholder")))
|
|
121
|
+
return !0;
|
|
122
|
+
if (t.children && Array.isArray(t.children)) {
|
|
123
|
+
for (const e of t.children)
|
|
124
|
+
if (b.checkNodeHasMermaid(e))
|
|
125
|
+
return !0;
|
|
126
|
+
}
|
|
127
|
+
return !1;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* 等待 DOM 更新后渲染 Mermaid 图表
|
|
131
|
+
* @param svgElement SVG 元素
|
|
132
|
+
* @param workId 工作 ID
|
|
133
|
+
* @returns Promise<void>
|
|
134
|
+
*/
|
|
135
|
+
static async renderMermaidAfterDOMUpdate(t, e) {
|
|
136
|
+
await b.renderMermaidBlocks(t, e);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 渲染所有 mermaid 容器中的图表
|
|
140
|
+
* @param svgElement SVG 元素
|
|
141
|
+
* @param workId 工作 ID
|
|
142
|
+
* @returns Promise<void>
|
|
143
|
+
*/
|
|
144
|
+
static async renderMermaidBlocks(t, e) {
|
|
145
|
+
if (!t)
|
|
146
|
+
return;
|
|
147
|
+
try {
|
|
148
|
+
await z();
|
|
149
|
+
} catch (r) {
|
|
150
|
+
console.error("[renderMermaidBlocks] error: ", r);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const n = D();
|
|
154
|
+
if (!n)
|
|
155
|
+
return;
|
|
156
|
+
let c = null, u = !1;
|
|
157
|
+
for (let r = 0; r < 30; r++) {
|
|
158
|
+
const d = t.querySelectorAll("foreignObject");
|
|
159
|
+
if (c = t.querySelectorAll(".mermaid-container"), c.length > 0 || (d.length > 0 && (u = !0), await new Promise((h) => setTimeout(h, 50)), u && r >= 20))
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
if (!c || c.length === 0)
|
|
163
|
+
return;
|
|
164
|
+
const i = Array.from(c).map(
|
|
165
|
+
async (r, d) => {
|
|
166
|
+
const h = r, f = h.getAttribute("data-mermaid-id"), l = f ? S.getCode(f, e) : void 0, m = h.querySelector(
|
|
167
|
+
".mermaid-placeholder"
|
|
168
|
+
);
|
|
169
|
+
if (!(!m || !l))
|
|
170
|
+
try {
|
|
171
|
+
const p = `mermaid-${e.replace(/[^a-zA-Z0-9_-]/g, "-")}-${Date.now()}-${d}`, { svg: y } = await n.render(p, l);
|
|
172
|
+
if (m && m.parentNode) {
|
|
173
|
+
const v = document.createElement("div");
|
|
174
|
+
v.innerHTML = y;
|
|
175
|
+
const s = v.querySelector("svg");
|
|
176
|
+
if (s) {
|
|
177
|
+
if (!s.getAttribute("viewBox") && s.getAttribute("width") && s.getAttribute("height")) {
|
|
178
|
+
const C = s.getAttribute("width"), x = s.getAttribute("height"), A = parseFloat((C == null ? void 0 : C.replace(/px|%/, "")) || "0"), k = parseFloat(
|
|
179
|
+
(x == null ? void 0 : x.replace(/px|%/, "")) || "0"
|
|
180
|
+
);
|
|
181
|
+
A > 0 && k > 0 && s.setAttribute(
|
|
182
|
+
"viewBox",
|
|
183
|
+
`0 0 ${A} ${k}`
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
s.style.display = "block", s.style.maxWidth = "100%", s.style.width = "auto", s.style.height = "auto", s.style.overflow = "visible", s.style.verticalAlign = "top", s.style.objectFit = "contain";
|
|
187
|
+
const o = document.createElement("div");
|
|
188
|
+
o.className = "mermaid-wrapper", o.style.width = "100%", o.style.height = "auto", o.style.overflow = "hidden", o.style.display = "inline-block", o.style.verticalAlign = "top", o.style.margin = "0", o.style.padding = "0", o.style.boxSizing = "border-box", o.style.position = "relative", this.isSafari() && (o.style.clipPath = "inset(100% 0 0 0)", o.style.pointerEvents = "none"), o.appendChild(s), s.style.width = "100%", s.style.height = "100%", s.style.maxWidth = "100%", s.style.maxHeight = "100%", s.style.objectFit = "contain", s.setAttribute("data-type", "mermaid"), this.isSafari() && (s.style.opacity = "0"), m.parentNode.replaceChild(o, m);
|
|
189
|
+
} else
|
|
190
|
+
m.outerHTML = y;
|
|
191
|
+
}
|
|
192
|
+
} catch (g) {
|
|
193
|
+
const p = g instanceof Error ? g.message : String(g);
|
|
194
|
+
m && (m.textContent = `Mermaid 渲染失败: ${p}`, m.style.color = "red", m.style.fontSize = "12px");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
await Promise.all(i);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* 检测是否是 Safari 浏览器
|
|
202
|
+
* @returns 如果是 Safari 返回 true,否则返回 false
|
|
203
|
+
*/
|
|
204
|
+
static isSafari() {
|
|
205
|
+
const t = navigator.userAgent.toLowerCase(), e = t.indexOf("safari") !== -1 && t.indexOf("chrome") === -1 && t.indexOf("chromium") === -1, n = !!(navigator.vendor && navigator.vendor.indexOf("Apple") !== -1);
|
|
206
|
+
return e || n;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* 将 mermaid SVG 从 foreignObject 移出,直接添加到 markmap SVG 中(Safari 兼容性处理)
|
|
210
|
+
* 克隆 mermaid SVG 元素,设置正确的尺寸和位置,然后将 foreignObject 中的 mermaid-container 透明度设为 0
|
|
211
|
+
* @param svgElement markmap SVG 元素
|
|
212
|
+
* @returns Promise<void>
|
|
213
|
+
*/
|
|
214
|
+
static async transformMermaidSvgToMarkmapSvg(t) {
|
|
215
|
+
if (!t)
|
|
216
|
+
return;
|
|
217
|
+
await new Promise((i) => setTimeout(i, 200));
|
|
218
|
+
const e = t.querySelectorAll(
|
|
219
|
+
'g[data-mermaid-wrapper][data-mermaid-clone="true"]'
|
|
220
|
+
), n = t.querySelectorAll("foreignObject"), c = /* @__PURE__ */ new Set();
|
|
221
|
+
if (n.forEach((i) => {
|
|
222
|
+
const r = i.querySelector(
|
|
223
|
+
".mermaid-container"
|
|
224
|
+
), d = r == null ? void 0 : r.getAttribute("data-mermaid-id");
|
|
225
|
+
d && c.add(d);
|
|
226
|
+
}), e.forEach((i) => {
|
|
227
|
+
const r = i.getAttribute("data-mermaid-id");
|
|
228
|
+
r && !c.has(r) && i.remove();
|
|
229
|
+
}), n.length === 0)
|
|
230
|
+
return;
|
|
231
|
+
const u = Array.from(n).map(
|
|
232
|
+
async (i) => {
|
|
233
|
+
let r = i.querySelector(
|
|
234
|
+
'svg[data-type="mermaid"]'
|
|
235
|
+
);
|
|
236
|
+
if (!r) {
|
|
237
|
+
const f = i.querySelector(".mermaid-wrapper");
|
|
238
|
+
f && (r = f.querySelector(
|
|
239
|
+
'svg[data-type="mermaid"]'
|
|
240
|
+
));
|
|
241
|
+
}
|
|
242
|
+
if (!r)
|
|
243
|
+
return;
|
|
244
|
+
const d = i.querySelector(
|
|
245
|
+
".mermaid-container"
|
|
246
|
+
), h = d == null ? void 0 : d.getAttribute("data-mermaid-id");
|
|
247
|
+
if (h)
|
|
248
|
+
try {
|
|
249
|
+
const f = parseFloat(i.getAttribute("x") || "0"), l = parseFloat(i.getAttribute("y") || "0"), m = parseFloat(
|
|
250
|
+
i.getAttribute("width") || "0"
|
|
251
|
+
), g = parseFloat(
|
|
252
|
+
i.getAttribute("height") || "0"
|
|
253
|
+
);
|
|
254
|
+
if (m <= 0 || g <= 0)
|
|
255
|
+
return;
|
|
256
|
+
const p = i.parentElement;
|
|
257
|
+
if (!p || p.tagName !== "g")
|
|
258
|
+
return;
|
|
259
|
+
let y = p.getAttribute("transform");
|
|
260
|
+
if (!y)
|
|
261
|
+
y = `translate(${f}, ${l})`;
|
|
262
|
+
else {
|
|
263
|
+
const x = y.match(
|
|
264
|
+
/translate\(([^,]+),([^)]+)\)/
|
|
265
|
+
);
|
|
266
|
+
if (x) {
|
|
267
|
+
const A = parseFloat(x[1]), k = parseFloat(x[2]), $ = A + f, N = k + l;
|
|
268
|
+
y = y.replace(
|
|
269
|
+
/translate\([^)]+\)/,
|
|
270
|
+
`translate(${$}, ${N})`
|
|
271
|
+
);
|
|
272
|
+
} else
|
|
273
|
+
y = `translate(${f}, ${l}) ${y}`;
|
|
274
|
+
}
|
|
275
|
+
const v = t.querySelector(
|
|
276
|
+
`g[data-mermaid-wrapper][data-mermaid-id="${h}"][data-mermaid-clone="true"]`
|
|
277
|
+
);
|
|
278
|
+
let s;
|
|
279
|
+
if (v) {
|
|
280
|
+
s = v;
|
|
281
|
+
const x = s.querySelector('svg[data-type="mermaid"]');
|
|
282
|
+
x && s.removeChild(x);
|
|
283
|
+
} else
|
|
284
|
+
s = document.createElementNS(
|
|
285
|
+
"http://www.w3.org/2000/svg",
|
|
286
|
+
"g"
|
|
287
|
+
), s.setAttribute("data-mermaid-wrapper", "true"), s.setAttribute("data-mermaid-clone", "true"), s.setAttribute("data-mermaid-id", h);
|
|
288
|
+
s.setAttribute("transform", y);
|
|
289
|
+
const o = r.cloneNode(!0);
|
|
290
|
+
if (o.setAttribute("width", m.toString()), o.setAttribute("height", g.toString()), o.setAttribute("data-mermaid-transformed", "true"), o.style.width = "", o.style.height = "", o.style.maxWidth = "", o.style.maxHeight = "", o.style.transform = "", o.style.transformOrigin = "", o.style.display = "block", o.style.overflow = "visible", o.style.opacity = "1", !o.getAttribute("viewBox")) {
|
|
291
|
+
const x = o.getAttribute("width"), A = o.getAttribute("height");
|
|
292
|
+
if (x && A) {
|
|
293
|
+
const k = parseFloat(
|
|
294
|
+
x.replace(/px|%/, "") || "0"
|
|
295
|
+
), $ = parseFloat(
|
|
296
|
+
A.replace(/px|%/, "") || "0"
|
|
297
|
+
);
|
|
298
|
+
k > 0 && $ > 0 && o.setAttribute(
|
|
299
|
+
"viewBox",
|
|
300
|
+
`0 0 ${k} ${$}`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
s.appendChild(o), v || (p && p.parentNode ? p.parentNode.insertBefore(s, p.nextSibling) : t.appendChild(s)), d && (d.style.opacity = "0", d.style.pointerEvents = "none");
|
|
305
|
+
} catch (f) {
|
|
306
|
+
console.error("[transformMermaidSvgToMarkmapSvg] error: ", f);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
);
|
|
310
|
+
await Promise.all(u);
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* 在 root 数据中注入 mermaid HTML
|
|
314
|
+
* 找到包含 mermaid 代码块的节点,将 HTML 添加到其 content 中
|
|
315
|
+
* @param root markmap root 数据
|
|
316
|
+
* @param markdown markdown 文本
|
|
317
|
+
* @param workId 工作 ID(用于命名空间隔离)
|
|
318
|
+
* @returns 修改后的 root 数据
|
|
319
|
+
*/
|
|
320
|
+
static injectMermaidHtml(t, e, n) {
|
|
321
|
+
const c = [], u = e.split(`
|
|
322
|
+
`);
|
|
323
|
+
let i = "", r = !1, d = [], h = -1;
|
|
324
|
+
for (let l = 0; l < u.length; l++) {
|
|
325
|
+
const m = u[l], g = m.match(/^(#{1,6})\s+(.+)$/);
|
|
326
|
+
if (g && (i = g[2].trim()), m.trim().startsWith("```mermaid"))
|
|
327
|
+
r = !0, d = [], h = l;
|
|
328
|
+
else if (r && m.trim() === "```") {
|
|
329
|
+
r = !1;
|
|
330
|
+
const p = d.join(`
|
|
331
|
+
`);
|
|
332
|
+
p && i && c.push({
|
|
333
|
+
title: i,
|
|
334
|
+
content: p,
|
|
335
|
+
index: h
|
|
336
|
+
}), d = [];
|
|
337
|
+
} else r && d.push(m);
|
|
338
|
+
}
|
|
339
|
+
const f = (l) => {
|
|
340
|
+
if (!l) return;
|
|
341
|
+
const m = l.content || "", g = b.decodeHtmlEntities(m);
|
|
342
|
+
for (const p of c)
|
|
343
|
+
if (g.includes(p.title) || m.includes(p.title)) {
|
|
344
|
+
const y = S.generateId(), v = S.createContainer(
|
|
345
|
+
y,
|
|
346
|
+
p.content,
|
|
347
|
+
n
|
|
348
|
+
);
|
|
349
|
+
l.content ? l.content = l.content + v : l.content = v;
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
l.children && l.children.length > 0 && l.children.forEach((p) => {
|
|
353
|
+
f(p);
|
|
354
|
+
});
|
|
355
|
+
};
|
|
356
|
+
return f(t), t;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* 解码 HTML 实体
|
|
360
|
+
* @param str HTML 字符串
|
|
361
|
+
* @returns 解码后的字符串
|
|
362
|
+
*/
|
|
363
|
+
static decodeHtmlEntities(t) {
|
|
364
|
+
const e = document.createElement("textarea");
|
|
365
|
+
return e.innerHTML = t, e.value;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* 检查 divElement 中是否包含 mermaid SVG 元素
|
|
369
|
+
* @param divElement HTMLDivElement 或 SVGSVGElement 元素
|
|
370
|
+
* @returns 如果包含 mermaid SVG 元素,返回 true,否则返回 false
|
|
371
|
+
*/
|
|
372
|
+
static hasMermaidSvg(t) {
|
|
373
|
+
return t.querySelectorAll("svg[data-type='mermaid']").length > 0;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
class H extends P {
|
|
377
|
+
constructor(e) {
|
|
378
|
+
super(e);
|
|
379
|
+
B(this, "currentWorkId", null);
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* 设置当前工作 ID(用于命名空间隔离)
|
|
383
|
+
* @param workId 工作 ID
|
|
384
|
+
*/
|
|
385
|
+
setWorkId(e) {
|
|
386
|
+
this.currentWorkId = e, e && S.extendMarkdown(this, e);
|
|
387
|
+
}
|
|
388
|
+
transform(e, n) {
|
|
389
|
+
this.currentWorkId ? S.clear(this.currentWorkId) : S.clear();
|
|
390
|
+
const c = this.convertKatexToText(e), u = super.transform(c, n);
|
|
391
|
+
return u.root && this.processKatexInRoot(u.root), u;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* 将 markdown 内容中的 katex 公式转换为普通文本
|
|
395
|
+
* 处理 $...$ 和 $$...$$ 格式的公式
|
|
396
|
+
* 由于 Safari 对 katex 的兼容性问题,将公式转换为普通文本显示
|
|
397
|
+
* @param content markdown 内容
|
|
398
|
+
* @returns 处理后的内容
|
|
399
|
+
*/
|
|
400
|
+
convertKatexToText(e) {
|
|
401
|
+
if (!e)
|
|
402
|
+
return e;
|
|
403
|
+
let n = e.replace(
|
|
404
|
+
/\$\$([\s\S]*?)\$\$/g,
|
|
405
|
+
(c, u) => u.replace(/\\/g, "").replace(/\{/g, "").replace(/\}/g, "").replace(/\\over/g, "/").replace(/\\pm/g, "±").replace(/\\sqrt/g, "√").replace(/\\frac/g, "/").trim()
|
|
406
|
+
);
|
|
407
|
+
return n = n.replace(
|
|
408
|
+
/\$([^$\n]+?)\$/g,
|
|
409
|
+
(c, u) => u.replace(/\\/g, "").replace(/\{/g, "").replace(/\}/g, "").replace(/\\over/g, "/").replace(/\\pm/g, "±").replace(/\\sqrt/g, "√").replace(/\\frac/g, "/").trim()
|
|
410
|
+
), n;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* 处理转换结果中的 katex HTML,将其转换为普通文本
|
|
414
|
+
* 递归处理节点树,查找包含 katex 的内容并转换
|
|
415
|
+
* 由于 Safari 对 katex 的兼容性问题,将 katex HTML 转换为普通文本显示
|
|
416
|
+
* @param node markmap 节点
|
|
417
|
+
*/
|
|
418
|
+
processKatexInRoot(e) {
|
|
419
|
+
if (e) {
|
|
420
|
+
if (e.content && typeof e.content == "string" && (e.content.includes("katex") || e.content.includes("katex-mathml"))) {
|
|
421
|
+
const n = e.content.match(
|
|
422
|
+
/<annotation[^>]*encoding="application\/x-tex">([^<]+)<\/annotation>/
|
|
423
|
+
);
|
|
424
|
+
if (n) {
|
|
425
|
+
const c = n[1].replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/\\/g, "").replace(/\{/g, "").replace(/\}/g, "").replace(/\\over/g, "/").replace(/\\pm/g, "±").replace(/\\sqrt/g, "√").replace(/\\frac/g, "/").trim();
|
|
426
|
+
e.content = e.content.replace(
|
|
427
|
+
/<div[^>]*xmlns="http:\/\/www\.w3\.org\/1999\/xhtml"[^>]*>Katex:\s*<span[^>]*class="katex"[^>]*>[\s\S]*?<\/span><\/div>/g,
|
|
428
|
+
c
|
|
429
|
+
);
|
|
430
|
+
} else {
|
|
431
|
+
const c = document.createElement("div");
|
|
432
|
+
c.innerHTML = e.content;
|
|
433
|
+
const u = c.querySelector(".katex");
|
|
434
|
+
if (u) {
|
|
435
|
+
let i = u.textContent || "";
|
|
436
|
+
i = i.replace(/^Katex:\s*/i, "").trim(), e.content = e.content.replace(
|
|
437
|
+
/<div[^>]*xmlns="http:\/\/www\.w3\.org\/1999\/xhtml"[^>]*>Katex:\s*<span[^>]*class="katex"[^>]*>[\s\S]*?<\/span><\/div>/g,
|
|
438
|
+
i || "公式"
|
|
439
|
+
);
|
|
440
|
+
} else {
|
|
441
|
+
const i = e.content.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").replace(/^Katex:\s*/i, "").trim();
|
|
442
|
+
e.content = i || "公式";
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
e.children && Array.isArray(e.children) && e.children.forEach((n) => {
|
|
447
|
+
this.processKatexInRoot(n);
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* 等待 markmap foreignObject 内所有图片加载完成
|
|
453
|
+
* 用于在调用 fit() 之前确保所有图片都已加载,以便正确计算尺寸
|
|
454
|
+
* @param svgElement SVG 元素
|
|
455
|
+
* @param timeout 超时时间(毫秒),默认 10 秒
|
|
456
|
+
* @returns Promise<void> 当所有图片加载完成时 resolve
|
|
457
|
+
*/
|
|
458
|
+
static async waitForImagesInForeignObjects(e, n = 1e4) {
|
|
459
|
+
if (!e)
|
|
460
|
+
return;
|
|
461
|
+
const c = e.querySelectorAll(
|
|
462
|
+
"foreignObject.markmap-foreign img"
|
|
463
|
+
);
|
|
464
|
+
if (c.length === 0)
|
|
465
|
+
return;
|
|
466
|
+
const u = [], i = /* @__PURE__ */ new Set();
|
|
467
|
+
c.forEach((r) => {
|
|
468
|
+
const d = r.src || r.getAttribute("src");
|
|
469
|
+
if (!d || i.has(d) || (i.add(d), r.complete && r.naturalWidth > 0))
|
|
470
|
+
return;
|
|
471
|
+
const h = new Promise((f) => {
|
|
472
|
+
const l = setTimeout(() => {
|
|
473
|
+
f();
|
|
474
|
+
}, n);
|
|
475
|
+
if (r.complete && r.naturalWidth > 0) {
|
|
476
|
+
clearTimeout(l), f();
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
const m = () => {
|
|
480
|
+
clearTimeout(l), r.removeEventListener("load", m), r.removeEventListener("error", g), f();
|
|
481
|
+
}, g = () => {
|
|
482
|
+
clearTimeout(l), r.removeEventListener("load", m), r.removeEventListener("error", g), f();
|
|
483
|
+
};
|
|
484
|
+
r.addEventListener("load", m), r.addEventListener("error", g), !r.src && d && (r.src = d);
|
|
485
|
+
});
|
|
486
|
+
u.push(h);
|
|
487
|
+
}), u.length > 0 && await Promise.all(u);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
const F = new H(), { loadCSS: U, loadJS: G, Markmap: V } = E, { scripts: T, styles: q } = F.getAssets();
|
|
491
|
+
q && U(q);
|
|
492
|
+
T && G(T, {
|
|
493
|
+
getMarkmap: () => E
|
|
494
|
+
});
|
|
495
|
+
K({
|
|
496
|
+
createMarkmap(a, t) {
|
|
497
|
+
return V.create(a, t);
|
|
498
|
+
},
|
|
499
|
+
transform(a, t) {
|
|
500
|
+
return F.setWorkId(a), F.transform(t);
|
|
501
|
+
},
|
|
502
|
+
hasMermaidCodeBlock(a) {
|
|
503
|
+
return /```\s*mermaid[\s\S]*?```/i.test(a);
|
|
504
|
+
},
|
|
505
|
+
checkNodeHasMermaid(a) {
|
|
506
|
+
const t = (e) => e ? e.content && typeof e.content == "string" && (e.content.includes('class="mermaid-container"') || e.content.includes("class='mermaid-container'") || e.content.includes("data-mermaid-id=") || e.content.includes("mermaid-placeholder")) ? !0 : e.children && Array.isArray(e.children) ? e.children.some(t) : !1 : !1;
|
|
507
|
+
return t(a);
|
|
508
|
+
},
|
|
509
|
+
async renderMermaidAfterDOMUpdate(a, t) {
|
|
510
|
+
await b.renderMermaidAfterDOMUpdate(a, t);
|
|
511
|
+
},
|
|
512
|
+
injectMermaidHtml(a, t, e) {
|
|
513
|
+
return b.injectMermaidHtml(a, t, e);
|
|
514
|
+
},
|
|
515
|
+
async waitForImagesInForeignObjects(a) {
|
|
516
|
+
await H.waitForImagesInForeignObjects(a);
|
|
517
|
+
},
|
|
518
|
+
async transformMermaidSvgToMarkmapSvg(a) {
|
|
519
|
+
await b.transformMermaidSvgToMarkmapSvg(a);
|
|
520
|
+
},
|
|
521
|
+
isSafari() {
|
|
522
|
+
const a = navigator.userAgent.toLowerCase(), t = a.indexOf("safari") !== -1 && a.indexOf("chrome") === -1 && a.indexOf("chromium") === -1, e = !!(navigator.vendor && navigator.vendor.indexOf("Apple") !== -1);
|
|
523
|
+
return t || e;
|
|
524
|
+
},
|
|
525
|
+
hasMermaidSvg(a) {
|
|
526
|
+
return a.querySelectorAll("svg[data-type='mermaid']").length > 0;
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
export {
|
|
530
|
+
V as Markmap,
|
|
531
|
+
H as MermaidTransformer,
|
|
532
|
+
Q as Transformer,
|
|
533
|
+
E as markmap,
|
|
534
|
+
F as transformer
|
|
535
|
+
};
|
package/dist/plugin/types.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { ECanvasContextType, EToolsKey, EventWorkState, EScaleType, ElayerT
|
|
|
12
12
|
import type { AuthRenderScenesData } from "../core/renderCotrol";
|
|
13
13
|
import type { Plugin } from "../core/plugin";
|
|
14
14
|
import type { TextEditorInfo, FontWeightType, FontStyleType, TextAlignType, VerticalAlignType, TextOptions } from "../component/textEditor/types";
|
|
15
|
-
import type { IMarkmapOptions } from "../component/svg/markmap";
|
|
15
|
+
import type { IMarkmapOptions } from "../component/svg/markmap-runtime";
|
|
16
16
|
import type { AutoShapeKind, AutoShapeMetrics } from "../core/autoShape/types";
|
|
17
17
|
import type { ShapeOptType } from "../displayer/types";
|
|
18
18
|
export type { Room, ImageInformation, Point, Size, Rectangle, RoomMember, RoomState, Player, HotKeys, Camera, Displayer, DisplayerCallbacks, CameraState, View, Cursor, CursorAdapter, RenderEngine, _MemberState, };
|