md-editor-rt
Version:
Markdown editor for react, developed in jsx and typescript, dark theme、beautify content by prettier、render articles directly、paste or clip the picture and upload it...
1,244 lines (1,243 loc) • 38.4 kB
JavaScript
import { jsx as K, jsxs as Ne, Fragment as De } from "react/jsx-runtime";
import { useContext as j, useEffect as v, useRef as T, useState as M, useCallback as U, useMemo as ue, useId as Ge, useImperativeHandle as ze } from "react";
import { p as f, g as C, d as O, f as ve, s as ke } from "./config.mjs";
import { E as F } from "./context.mjs";
import Ue from "@vavt/copy2clipboard";
import { randomId as me } from "@vavt/util";
import qe from "markdown-it";
import Ve from "markdown-it-image-figures";
import We from "markdown-it-sub";
import Ke from "markdown-it-sup";
import { b as $, E as te, B as ee, g as de, P as ye, f as pe, T as Ze, O as he, U as we, C as fe, h as Ee, F as xe, i as Ce, j as Ie, H as Te, k as Se, R as ge, e as Je, d as Xe } from "./event-bus.mjs";
import { g as Be, c as Ye } from "./index2.mjs";
import { a as _, u as Qe, S as et, z as Ae } from "./dom.mjs";
import { LRUCache as tt } from "lru-cache";
import rt from "medium-zoom";
const L = {
hljs: `${f}-hljs`,
hlcss: `${f}-hlCss`,
prettier: `${f}-prettier`,
prettierMD: `${f}-prettierMD`,
cropperjs: `${f}-cropper`,
croppercss: `${f}-cropperCss`,
screenfull: `${f}-screenfull`,
mermaidM: `${f}-mermaid-m`,
mermaid: `${f}-mermaid`,
katexjs: `${f}-katex`,
katexcss: `${f}-katexCss`,
echarts: `${f}-echarts`
}, nt = (e, t, s) => {
const { editorId: n, usedLanguageText: r, customIcon: d, rootRef: o, setting: m } = j(F), { formatCopiedText: c = (p) => p } = e;
v(() => {
m.preview && o.current?.querySelectorAll(`#${n} .${f}-preview .${f}-code`).forEach((p) => {
let i = -1;
const a = p.querySelector(
`.${f}-copy-button`
);
a && (a.onclick = (l) => {
l.preventDefault(), clearTimeout(i);
const u = (p.querySelector("input:checked + pre code") || p.querySelector("pre code")).textContent || "", { text: b, successTips: g, failTips: H } = r.copyCode;
let k = g;
Ue(c(u)).catch(() => {
k = H;
}).finally(() => {
a.dataset.isIcon ? a.dataset.tips = k : a.innerHTML = k, i = window.setTimeout(() => {
a.dataset.isIcon ? a.dataset.tips = b : a.innerHTML = b;
}, 1500);
});
});
});
}, [
d,
n,
c,
t,
s,
m.preview,
o,
r.copyCode
]);
}, st = (e) => {
const { editorId: t, theme: s, rootRef: n } = j(F), r = T(C.editorExtensions.echarts?.instance), [d, o] = M(0), m = T([]), c = T([]), p = T([]), i = U(() => {
!e.noEcharts && r.current && o((h) => h + 1);
}, [e.noEcharts]);
v(() => {
i();
}, [s, i]), v(() => {
if (e.noEcharts || r.current) return;
const { editorExtensions: h, editorExtensionsAttrs: u } = C, b = h.echarts.js;
_(
"script",
{
...u.echarts?.js,
src: b,
id: L.echarts,
onload() {
r.current = window.echarts, i();
}
},
"echarts"
);
}, [e.noEcharts, i]);
const a = U(() => {
m.current.forEach((h) => h.dispose()), c.current.forEach((h) => h.disconnect()), m.current = [], p.current = [], c.current = [];
}, []), l = U(() => {
a(), !e.noEcharts && r.current && n.current && (p.current = Array.from(
n.current.querySelectorAll(
`#${t} div.${f}-echarts:not([data-processed])`
)
), p.current.forEach((h) => {
if (h.dataset.closed !== "false")
try {
const u = new Function(`return ${h.innerText}`)(), b = r.current.init(h, s);
b.setOption(u), h.setAttribute("data-processed", ""), m.current.push(b);
const g = new ResizeObserver(() => {
b.resize();
});
g.observe(h), c.current.push(g);
} catch (u) {
$.emit(t, te, {
name: "echarts",
message: u?.message,
error: u
});
}
}));
}, [e.noEcharts, n, t, s, a]);
return v(() => () => {
a();
}, [a]), { reRenderEcharts: d, replaceEcharts: l };
}, ot = (e) => {
const { highlight: t } = j(F), s = T(C.editorExtensions.highlight.instance), [n, r] = M(!!s.current);
return v(() => {
e.noHighlight || C.editorExtensions.highlight.instance || Qe("link", {
...t.css,
rel: "stylesheet",
id: L.hlcss
});
}, [t.css, e.noHighlight]), v(() => {
e.noHighlight || s.current || _(
"script",
{
...t.js,
id: L.hljs,
onload() {
s.current = window.hljs, r(!0);
}
},
"hljs"
);
}, []), { hljsRef: s, hljsInited: n };
}, ct = (e) => {
const t = T(C.editorExtensions.katex.instance), [s, n] = M(!!t.current);
return v(() => {
if (e.noKatex || t.current)
return;
const { editorExtensions: r, editorExtensionsAttrs: d } = C;
_(
"script",
{
...d.katex?.js,
src: r.katex.js,
id: L.katexjs,
onload() {
t.current = window.katex, n(!0);
}
},
"katex"
), _("link", {
...d.katex?.css,
rel: "stylesheet",
href: r.katex.css,
id: L.katexcss
});
}, [e.noKatex]), { katexRef: t, katexInited: s };
}, oe = new tt({
max: 1e3,
// 缓存10分钟
ttl: 6e5
}), it = (e) => {
const { editorId: t, theme: s, rootRef: n } = j(F), { noMermaid: r, sanitizeMermaid: d } = e, o = T(C.editorExtensions.mermaid.instance), [m, c] = M(-1), p = U(() => {
oe.clear();
const a = o.current;
!r && a && (a.initialize(
C.mermaidConfig({
startOnLoad: !1,
theme: s === "dark" ? "dark" : "default"
})
), c((l) => l + 1));
}, [r, s]);
v(p, [p]), v(() => {
const { editorExtensions: a, editorExtensionsAttrs: l } = C;
if (r || o.current)
return;
const h = a.mermaid.js;
/\.mjs/.test(h) ? (_("link", {
...l.mermaid?.js,
rel: "modulepreload",
href: h,
id: L.mermaidM
}), import(
/* @vite-ignore */
/* webpackIgnore: true */
h
).then((u) => {
o.current = u.default, p();
}).catch((u) => {
$.emit(t, te, {
name: "mermaid",
message: `Failed to load mermaid module: ${u.message}`,
error: u
});
})) : _(
"script",
{
...l.mermaid?.js,
src: h,
id: L.mermaid,
onload() {
o.current = window.mermaid, p();
}
},
"mermaid"
);
}, [p, t, r]);
const i = U(async () => {
if (!r && o.current) {
const a = n.current?.querySelectorAll(`div.${f}-mermaid`) || [], l = document.createElement("div"), h = document.body.offsetWidth > 1366 ? document.body.offsetWidth : 1366, u = document.body.offsetHeight > 768 ? document.body.offsetHeight : 768;
l.style.width = h + "px", l.style.height = u + "px", l.style.position = "fixed", l.style.zIndex = "-10000", l.style.top = "-10000";
let b = a.length;
b > 0 && document.body.appendChild(l), await Promise.allSettled(
Array.from(a).map((g) => (async (k) => {
if (k.dataset.closed === "false")
return !1;
const w = k.innerText;
let A = oe.get(w);
if (!A) {
const x = me();
let R = { svg: "" };
try {
R = await o.current.render(
x,
w,
l
), A = await d(R.svg);
const E = document.createElement("p");
E.className = `${f}-mermaid`, E.setAttribute("data-processed", ""), E.innerHTML = A, E.children[0]?.removeAttribute("height"), oe.set(w, E.innerHTML), k.dataset.line !== void 0 && (E.dataset.line = k.dataset.line), k.replaceWith(E);
} catch (E) {
$.emit(t, te, {
name: "mermaid",
message: E.message,
error: E
});
}
--b === 0 && l.remove();
}
})(g))
);
}
}, [t, r, n, d]);
return { reRender: m, replaceMermaid: i };
}, at = (e, t) => {
t = t || {};
const s = 3, n = t.marker || "!", r = n.charCodeAt(0), d = n.length;
let o = "", m = "";
const c = (i, a, l, h, u) => {
const b = i[a];
return b.type === "admonition_open" ? i[a].attrPush([
"class",
`${f}-admonition ${f}-admonition-${b.info}`
]) : b.type === "admonition_title_open" && i[a].attrPush(["class", `${f}-admonition-title`]), u.renderToken(i, a, l);
}, p = (i) => {
const a = i.trim().split(" ", 2);
m = "", o = a[0], a.length > 1 && (m = i.substring(o.length + 2));
};
e.block.ruler.before(
"code",
"admonition",
(i, a, l, h) => {
let u, b, g, H = !1, k = i.bMarks[a] + i.tShift[a], w = i.eMarks[a];
if (r !== i.src.charCodeAt(k))
return !1;
for (u = k + 1; u <= w && n[(u - k) % d] === i.src[u]; u++)
;
const A = Math.floor((u - k) / d);
if (A !== s)
return !1;
u -= (u - k) % d;
const x = i.src.slice(k, u), R = i.src.slice(u, w);
if (p(R), h)
return !0;
for (b = a; b++, !(b >= l || (k = i.bMarks[b] + i.tShift[b], w = i.eMarks[b], k < w && i.sCount[b] < i.blkIndent)); )
if (r === i.src.charCodeAt(k) && !(i.sCount[b] - i.blkIndent >= 4)) {
for (u = k + 1; u <= w && n[(u - k) % d] === i.src[u]; u++)
;
if (!(Math.floor((u - k) / d) < A) && (u -= (u - k) % d, u = i.skipSpaces(u), !(u < w))) {
H = !0;
break;
}
}
const E = i.parentType, S = i.lineMax;
return i.parentType = "root", i.lineMax = b, g = i.push("admonition_open", "div", 1), g.markup = x, g.block = !0, g.info = o, g.map = [a, b], m && (g = i.push("admonition_title_open", "p", 1), g.markup = x + " " + o, g.map = [a, b], g = i.push("inline", "", 0), g.content = m, g.map = [a, i.line - 1], g.children = [], g = i.push("admonition_title_close", "p", -1), g.markup = x + " " + o), i.md.block.tokenize(i, a + 1, b), g = i.push("admonition_close", "div", -1), g.markup = i.src.slice(k, u), g.block = !0, i.parentType = E, i.lineMax = S, i.line = b + (H ? 1 : 0), !0;
},
{
alt: ["paragraph", "reference", "blockquote", "list"]
}
), e.renderer.rules.admonition_open = c, e.renderer.rules.admonition_title_open = c, e.renderer.rules.admonition_title_close = c, e.renderer.rules.admonition_close = c;
}, ce = (e, t) => {
const s = e.attrs ? e.attrs.slice() : [];
return t.forEach((n) => {
const r = e.attrIndex(n[0]);
r < 0 ? s.push(n) : (s[r] = s[r].slice(), s[r][1] += ` ${n[1]}`);
}), s;
}, lt = (e, t) => {
const s = e.renderer.rules.fence, n = e.utils.unescapeAll, r = /\[(\w*)(?::([\w ]*))?\]/, d = /::(open|close)/, o = (a) => a.info ? n(a.info).trim() : "", m = (a) => {
const l = o(a), [h = null, u = ""] = (r.exec(l) || []).slice(1);
return [h, u];
}, c = (a) => {
const l = o(a);
return l ? l.split(/(\s+)/g)[0] : "";
}, p = (a) => {
const l = a.info.match(d) || [], h = l[1] === "open" || l[1] !== "close" && t.codeFoldable && a.content.trim().split(`
`).length < t.autoFoldThreshold, u = l[1] || t.codeFoldable ? "details" : "div", b = l[1] || t.codeFoldable ? "summary" : "div";
return { open: h, tagContainer: u, tagHeader: b };
}, i = (a, l, h, u, b) => {
if (a[l].hidden)
return "";
const g = t.usedLanguageTextRef.current.copyCode.text, H = t.customIconRef.current.copy || g, k = !!t.customIconRef.current.copy, w = `<span class="${f}-collapse-tips">${et("collapse-tips", t.customIconRef.current)}</span>`, [A] = m(a[l]);
if (A === null) {
const { open: I, tagContainer: P, tagHeader: G } = p(a[l]), z = [["class", `${f}-code`]];
I && z.push(["open", ""]);
const X = {
attrs: ce(a[l], z)
};
a[l].info = a[l].info.replace(d, "");
const ae = s(a, l, h, u, b);
return `
<${P} ${b.renderAttrs(X)}>
<${G} class="${f}-code-head">
<div class="${f}-code-flag"><span></span><span></span><span></span></div>
<div class="${f}-code-action">
<span class="${f}-code-lang">${e.utils.escapeHtml(a[l].info.trim())}</span>
<span class="${f}-copy-button" data-tips="${g}"${k ? " data-is-icon=true" : ""}>${H}</span>
${t.extraTools instanceof Function ? t.extraTools({ lang: a[l].info.trim() }) : t.extraTools || ""}
${P === "details" ? w : ""}
</div>
</${G}>
${ae}
</${P}>
`;
}
let x, R, E, S, q = "", Z = "", D = "";
const { open: V, tagContainer: W, tagHeader: re } = p(a[l]), J = [["class", `${f}-code`]];
V && J.push(["open", ""]);
const ie = {
attrs: ce(a[l], J)
};
for (let I = l; I < a.length && (x = a[I], [R, E] = m(x), R === A); I++) {
x.info = x.info.replace(r, "").replace(d, ""), x.hidden = !0;
const P = `${f}-codetab-${t.editorId}-${l}-${I - l}`;
S = I - l > 0 ? "" : "checked", q += `
<li>
<input
type="radio"
id="label-${f}-codetab-label-1-${t.editorId}-${l}-${I - l}"
name="${f}-codetab-label-${t.editorId}-${l}"
class="${P}"
${S}
>
<label
for="label-${f}-codetab-label-1-${t.editorId}-${l}-${I - l}"
onclick="this.getRootNode().querySelectorAll('.${P}').forEach(e => e.click())"
>
${e.utils.escapeHtml(E || c(x))}
</label>
</li>`, Z += `
<div role="tabpanel">
<input
type="radio"
name="${f}-codetab-pre-${t.editorId}-${l}"
class="${P}"
${S}
role="presentation">
${s(a, I, h, u, b)}
</div>`, D += `
<input
type="radio"
name="${f}-codetab-lang-${t.editorId}-${l}"
class="${P}"
${S}
role="presentation">
<span class=${f}-code-lang role="note">${e.utils.escapeHtml(c(x))}</span>`;
}
return `
<${W} ${b.renderAttrs(ie)}>
<${re} class="${f}-code-head">
<div class="${f}-code-flag">
<ul class="${f}-codetab-label" role="tablist">${q}</ul>
</div>
<div class="${f}-code-action">
<span class="${f}-codetab-lang">${D}</span>
<span class="${f}-copy-button" data-tips="${g}"${k ? " data-is-icon=true" : ""}>${H}</span>
${t.extraTools instanceof Function ? t.extraTools({ lang: a[l].info.trim() }) : t.extraTools || ""}
${W === "details" ? w : ""}
</div>
</${re}>
${Z}
</${W}>
`;
};
e.renderer.rules.fence = i, e.renderer.rules.code_block = i;
}, dt = (e, t) => {
const s = e.renderer.rules.fence.bind(e.renderer.rules);
e.renderer.rules.fence = (n, r, d, o, m) => {
const c = n[r], p = c.content.trim();
if (c.info === "echarts") {
if (c.attrSet("class", `${f}-echarts`), c.attrSet("data-echarts-theme", t.themeRef.current), c.map && c.level === 0) {
const i = c.map[1] - 1, l = !!o.srcLines[i]?.trim()?.startsWith("```");
c.attrSet("data-closed", `${l}`), c.attrSet("data-line", String(c.map[0]));
}
return `<div ${m.renderAttrs(c)} style="width: 100%; aspect-ratio: 4 / 3;">${e.utils.escapeHtml(p)}</div>`;
}
return s(n, r, d, o, m);
};
}, ut = (e, t) => {
e.renderer.rules.heading_open = (s, n) => {
const r = s[n], d = s[n + 1].children?.reduce((m, c) => m + (["text", "code_inline", "math_inline"].includes(c.type) && c.content || ""), "") || "", o = r.markup.length;
return t.headsRef.current.push({
text: d,
level: o,
line: r.map[0],
currentToken: r,
nextToken: s[n + 1]
}), r.map && r.level === 0 && r.attrSet(
"id",
t.mdHeadingId({
text: d,
level: o,
index: t.headsRef.current.length,
currentToken: r,
nextToken: s[n + 1]
})
), e.renderer.renderToken(s, n, t);
}, e.renderer.rules.heading_close = (s, n, r, d, o) => o.renderToken(s, n, r);
}, He = {
block: [
{ open: "$$", close: "$$" },
{ open: "\\[", close: "\\]" }
],
inline: [
{ open: "$$", close: "$$" },
{ open: "$", close: "$" },
{ open: "\\[", close: "\\]" },
{ open: "\\(", close: "\\)" }
]
}, mt = (e) => (t, s) => {
const n = e.delimiters;
let r, d, o;
for (const m of n)
if (t.src.startsWith(m.open, t.pos)) {
const c = t.pos + m.open.length;
for (r = c; (r = t.src.indexOf(m.close, r)) !== -1; ) {
for (o = r - 1; t.src[o] === "\\"; )
o -= 1;
if ((r - o) % 2 === 1)
break;
r += m.close.length;
}
if (r === -1)
return s || (t.pending += m.open), t.pos = c, !0;
if (r - c === 0)
return s || (t.pending += m.open + m.close), t.pos = c + m.close.length, !0;
if (!s) {
const p = t.src.slice(c, r);
d = t.push("math_inline", "math", 0), d.markup = m.open, d.content = p;
}
return t.pos = r + m.close.length, !0;
}
return !1;
}, pt = (e) => (t, s, n, r) => {
const d = e.delimiters;
let o, m, c, p, i = !1, a = t.bMarks[s] + t.tShift[s], l = t.eMarks[s];
for (const h of d)
if (t.src.slice(a, a + h.open.length) === h.open && t.src.slice(l - h.close.length, l) === h.close) {
if (a += h.open.length, o = t.src.slice(a, l), r)
return !0;
for (o.trim().slice(-h.close.length) === h.close && (o = o.trim().slice(0, -h.close.length), i = !0), c = s; !i && (c++, !(c >= n || (a = t.bMarks[c] + t.tShift[c], l = t.eMarks[c], a < l && t.tShift[c] < t.blkIndent))); )
t.src.slice(a, l).trim().slice(-h.close.length) === h.close && (p = t.src.slice(0, l).lastIndexOf(h.close), m = t.src.slice(a, p), i = !0);
t.line = c + 1;
const u = t.push("math_block", "math", 0);
return u.block = !0, u.content = (o && o.trim() ? o + `
` : "") + t.getLines(s + 1, c, t.tShift[s], !0) + (m && m.trim() ? m : ""), u.map = [s, t.line], u.markup = h.open, !0;
}
return !1;
}, ht = (e, { katexRef: t, inlineDelimiters: s, blockDelimiters: n }) => {
const r = (o, m, c, p, i) => {
const a = o[m], l = {
attrs: ce(a, [["class", `${f}-katex-inline`]])
};
if (t.current) {
const h = t.current.renderToString(
a.content,
C.katexConfig({
throwOnError: !1
})
);
return `<span ${i.renderAttrs(l)} data-processed>${h}</span>`;
} else
return `<span ${i.renderAttrs(l)}>${a.content}</span>`;
}, d = (o, m, c, p, i) => {
const a = o[m], l = {
attrs: ce(a, [["class", `${f}-katex-block`]])
};
if (t.current) {
const h = t.current.renderToString(
a.content,
C.katexConfig({
throwOnError: !1,
displayMode: !0
})
);
return `<p ${i.renderAttrs(l)} data-processed>${h}</p>`;
} else
return `<p ${i.renderAttrs(l)}>${a.content}</p>`;
};
e.inline.ruler.before(
"escape",
"math_inline",
mt({
delimiters: s || He.inline
})
), e.block.ruler.after(
"blockquote",
"math_block",
pt({
delimiters: n || He.block
}),
{
alt: ["paragraph", "reference", "blockquote", "list"]
}
), e.renderer.rules.math_inline = r, e.renderer.rules.math_block = d;
}, ft = (e, t) => {
const s = e.renderer.rules.fence.bind(e.renderer.rules);
e.renderer.rules.fence = (n, r, d, o, m) => {
const c = n[r], p = c.content.trim();
if (c.info === "mermaid") {
if (c.attrSet("class", `${f}-mermaid`), c.attrSet("data-mermaid-theme", t.themeRef.current), c.map && c.level === 0) {
const a = c.map[1] - 1, h = !!o.srcLines[a]?.trim()?.startsWith("```");
c.attrSet("data-closed", `${h}`), c.attrSet("data-line", String(c.map[0]));
}
const i = oe.get(p);
return i ? (c.attrSet("data-processed", ""), `<p ${m.renderAttrs(c)}>${i}</p>`) : `<div ${m.renderAttrs(c)}>${e.utils.escapeHtml(p)}</div>`;
}
return s(n, r, d, o, m);
};
}, Re = (e, t, s) => {
const n = e.attrIndex(t), r = [t, s];
n < 0 ? e.attrPush(r) : (e.attrs = e.attrs || [], e.attrs[n] = r);
}, gt = (e) => e.type === "inline", bt = (e) => e.type === "paragraph_open", $t = (e) => e.type === "list_item_open", vt = (e) => e.content.indexOf("[ ] ") === 0 || e.content.indexOf("[x] ") === 0 || e.content.indexOf("[X] ") === 0, kt = (e, t) => gt(e[t]) && bt(e[t - 1]) && $t(e[t - 2]) && vt(e[t]), yt = (e, t) => {
const s = e[t].level - 1;
for (let n = t - 1; n >= 0; n--)
if (e[n].level === s)
return n;
return -1;
}, wt = (e) => {
const t = new e("html_inline", "", 0);
return t.content = "<label>", t;
}, Et = (e) => {
const t = new e("html_inline", "", 0);
return t.content = "</label>", t;
}, xt = (e, t, s) => {
const n = new s("html_inline", "", 0);
return n.content = '<label class="task-list-item-label" for="' + t + '">' + e + "</label>", n.attrs = [{ for: t }], n;
}, Ct = (e, t, s) => {
const n = new t("html_inline", "", 0), r = s.enabled ? " " : ' disabled="" ';
return e.content.indexOf("[ ] ") === 0 ? n.content = '<input class="task-list-item-checkbox"' + r + 'type="checkbox">' : (e.content.indexOf("[x] ") === 0 || e.content.indexOf("[X] ") === 0) && (n.content = '<input class="task-list-item-checkbox" checked=""' + r + 'type="checkbox">'), n;
}, It = (e, t, s) => {
if (e.children = e.children || [], e.children.unshift(Ct(e, t, s)), e.children[1].content = e.children[1].content.slice(3), e.content = e.content.slice(3), s.label)
if (s.labelAfter) {
e.children.pop();
const n = "task-item-" + Math.ceil(Math.random() * (1e4 * 1e3) - 1e3);
e.children[0].content = e.children[0].content.slice(0, -1) + ' id="' + n + '">', e.children.push(xt(e.content, n, t));
} else
e.children.unshift(wt(t)), e.children.push(Et(t));
}, Tt = (e, t = {}) => {
e.core.ruler.after("inline", "github-task-lists", (s) => {
const n = s.tokens;
for (let r = 2; r < n.length; r++)
kt(n, r) && (It(n[r], s.Token, t), Re(
n[r - 2],
"class",
"task-list-item" + (t.enabled ? " enabled" : " ")
), Re(n[yt(n, r - 2)], "class", "contains-task-list"));
});
}, St = (e) => {
e.core.ruler.push("init-line-number", (t) => (t.tokens.forEach((s) => {
s.map && (s.attrs || (s.attrs = []), s.attrs.push(["data-line", s.map[0].toString()]));
}), !0));
}, At = (e, t) => {
const {
modelValue: s,
sanitize: n,
mdHeadingId: r,
codeFoldable: d,
autoFoldThreshold: o,
noKatex: m,
noMermaid: c,
noHighlight: p,
onHtmlChanged: i,
onGetCatalog: a
} = e, { editorConfig: l, markdownItConfig: h, markdownItPlugins: u, editorExtensions: b } = C, {
editorId: g,
language: H,
showCodeRowNumber: k,
theme: w,
usedLanguageText: A,
customIcon: x,
rootRef: R,
setting: E
} = j(F), S = T([]), q = T(w);
v(() => {
q.current = w;
}, [w]);
const Z = T(A);
v(() => {
Z.current = A;
}, [A]);
const D = T(x);
v(() => {
D.current = x;
}, [x]);
const { hljsRef: V, hljsInited: W } = ot(e), { katexRef: re, katexInited: J } = ct(e), { reRender: ie, replaceMermaid: I } = it(e), { reRenderEcharts: P, replaceEcharts: G } = st(e), [z] = M(() => {
const y = qe({
html: !0,
breaks: !0,
linkify: !0
});
h(y, {
editorId: g
});
const se = [
{
type: "image",
plugin: Ve,
options: { figcaption: !0, classes: "md-zoom" }
},
{
type: "admonition",
plugin: at,
options: {}
},
{
type: "taskList",
plugin: Tt,
options: {}
},
{
type: "heading",
plugin: ut,
options: { mdHeadingId: r, headsRef: S }
},
{
type: "code",
plugin: lt,
options: {
editorId: g,
usedLanguageTextRef: Z,
// showCodeRowNumber,
codeFoldable: d,
autoFoldThreshold: o,
customIconRef: D
}
},
{
type: "sub",
plugin: We,
options: {}
},
{
type: "sup",
plugin: Ke,
options: {}
}
];
m || se.push({
type: "katex",
plugin: ht,
options: { katexRef: re }
}), c || se.push({
type: "mermaid",
plugin: ft,
options: { themeRef: q }
}), e.noEcharts || se.push({
type: "echarts",
plugin: dt,
options: { themeRef: q }
}), u(se, {
editorId: g
}).forEach((N) => {
y.use(N.plugin, N.options);
});
const $e = y.options.highlight;
return y.set({
highlight: (N, Y, Fe) => {
if ($e) {
const le = $e(N, Y, Fe);
if (le)
return le;
}
let Q;
!p && V.current ? V.current.getLanguage(Y) ? Q = V.current.highlight(N, {
language: Y,
ignoreIllegals: !0
}).value : Q = V.current.highlightAuto(N).value : Q = z.utils.escapeHtml(N);
const Oe = k ? Be(
Q.replace(/^\n+|\n+$/g, ""),
N.replace(/^\n+|\n+$/g, "")
) : `<span class="${f}-code-block">${Q.replace(/^\n+|\n+$/g, "")}</span>`;
return `<pre><code class="language-${Y}" language=${Y}>${Oe}</code></pre>`;
}
}), St(y), y;
}), [X, ae] = M(`_article-key_${me()}`), [B, Me] = M(() => (S.current = [], n(
z.render(s, {
srcLines: s.split(`
`)
})
))), je = ue(() => (p || W) && (m || J), [W, J, p, m]), be = T(!0), ne = U(() => {
S.current = [];
const y = n(
z.render(s, {
srcLines: s.split(`
`)
})
);
Me(y);
}, [z, s, n]);
return v(() => {
$.emit(g, ee, B), i?.(B), a?.(S.current), $.emit(g, de, S.current);
}, [g, B, X, a, i]), v(() => {
let y = () => {
};
return E.preview && (I().then(() => {
b.mermaid?.enableZoom && (y(), y = Ae(
R.current?.querySelectorAll(
`#${g} .${f}-mermaid:not([data-closed=false])`
),
{
customIcon: D.current
}
));
}), G(), $.emit(g, de, S.current)), () => {
y();
};
}, [
b.mermaid?.enableZoom,
g,
G,
I,
R,
E.preview
]), v(() => {
if (be.current) {
be.current = !1;
return;
}
const y = setTimeout(
() => {
ne();
},
t ? 0 : l.renderDelay
);
return () => {
clearTimeout(y);
};
}, [je, w, ne, H, t, l.renderDelay]), v(() => {
let y = () => {
};
return I().then(() => {
b.mermaid?.enableZoom && (y(), y = Ae(
R.current?.querySelectorAll(
`#${g} p.${f}-mermaid:not([data-closed=false])`
),
{
customIcon: D.current
}
));
}), G(), () => {
y();
};
}, [
b.mermaid?.enableZoom,
g,
B,
X,
ie,
I,
P,
G,
R
]), v(() => {
const y = () => {
$.emit(g, de, S.current);
};
return $.on(g, {
name: ye,
callback: y
}), () => {
$.remove(g, ye, y);
};
}, [g]), v(() => {
const y = () => {
ae(`_article-key_${me()}`), ne();
};
return $.on(g, {
name: pe,
callback: y
}), () => {
$.remove(g, pe, y);
};
}, [g, ne]), { html: B, key: X };
}, Ht = (e, t) => {
const { editorId: s, setting: n } = j(F);
v(() => e.noImgZoomIn ? void 0 : (() => {
const d = document.querySelectorAll(
`#${s}-preview img:not(.not-zoom):not(.medium-zoom-image)`
), o = rt(d, {
background: "#00000073"
});
return () => {
o.detach();
};
})(), [s, t, e.noImgZoomIn, n]);
}, Le = {
checked: {
regexp: /- \[x\]/,
value: "- [ ]"
},
unChecked: {
regexp: /- \[\s\]/,
value: "- [x]"
}
}, Rt = (e, t) => {
const { editorId: s, rootRef: n } = j(F);
v(() => {
const r = n.current?.querySelectorAll(".task-list-item.enabled") || [], d = (o) => {
o.preventDefault();
const m = o.target.checked ? "unChecked" : "checked", c = o.target.parentElement?.dataset.line;
if (!c)
return;
const p = Number(c), i = e.modelValue.split(`
`), a = i[Number(p)].replace(
Le[m].regexp,
Le[m].value
);
e.previewOnly ? (i[Number(p)] = a, e.onChange(i.join(`
`))) : $.emit(s, Ze, p + 1, a);
};
return r.forEach((o) => {
o.addEventListener("click", d);
}), () => {
r.forEach((o) => {
o.removeEventListener("click", d);
});
};
}, [s, t, e, n]);
}, Lt = (e, t, s) => {
const { onRemount: n } = e, { setting: r } = j(F);
v(() => {
n?.();
}, [t, s, n]), v(() => {
(r.preview || r.htmlPreview) && n?.();
}, [r.preview, r.htmlPreview, n]);
}, Pt = (e) => {
const s = new DOMParser().parseFromString(e, "text/html");
return Array.from(s.body.childNodes);
}, _t = (e, t) => {
const s = [], n = [];
if (e.forEach((r, d) => {
const o = t[d];
if (!o) {
s.push({ index: d, newNode: r });
return;
}
(r.nodeType !== o.nodeType || r.textContent !== o.textContent || r.nodeType === 1 && r.outerHTML !== o.outerHTML) && s.push({ index: d, newNode: r });
}), t.length > e.length)
for (let r = e.length; r < t.length; r++)
n.push(t[r]);
return { updates: s, deletes: n };
}, Pe = ({ html: e }) => {
const { editorId: t, previewTheme: s, showCodeRowNumber: n } = j(F), r = T({ __html: e }), d = T(null);
return v(() => {
if (!d.current) return;
const o = Pt(e), m = Array.from(d.current.childNodes || []), { updates: c, deletes: p } = _t(o, m);
p.forEach((i) => {
i.remove();
}), c.forEach(({ index: i, newNode: a }) => {
const l = d.current.childNodes[i];
l ? d.current.replaceChild(a.cloneNode(!0), l) : d.current.appendChild(a.cloneNode(!0));
});
}, [e]), /* @__PURE__ */ K(
"div",
{
id: `${t}-preview`,
className: Ye([
`${f}-preview`,
`${s}-theme`,
n && `${f}-scrn`
]),
dangerouslySetInnerHTML: r.current,
ref: d
}
);
}, Bt = (e) => {
const { previewOnly: t = !1, setting: s = { preview: !0 } } = e, { editorId: n } = j(F), { html: r, key: d } = At(e, !!t);
return nt(e, r, d), Ht(e, r), Rt(e, r), Lt(e, r, d), /* @__PURE__ */ Ne(De, { children: [
s.preview && (e.previewOnly ? /* @__PURE__ */ K(Pe, { html: r }, d) : /* @__PURE__ */ K(
"div",
{
id: `${n}-preview-wrapper`,
className: `${f}-preview-wrapper`,
children: /* @__PURE__ */ K(Pe, { html: r }, d)
},
"content-preview-wrapper"
)),
s.htmlPreview && /* @__PURE__ */ K(
"div",
{
id: `${n}-html-wrapper`,
className: `${f}-preview-wrapper`,
children: /* @__PURE__ */ K("div", { className: `${f}-html`, children: r })
},
"html-preview-wrapper"
)
] });
}, Yt = (e, t) => {
const { value: s, modelValue: n, onSave: r } = e, { editorId: d } = t, [o, m] = M({
// 是否已编译成html
buildFinished: !1,
// 存储当前最新的html
html: ""
});
v(() => {
const c = (p) => {
m(() => ({
buildFinished: !0,
html: p
}));
};
return $.on(d, {
name: ee,
callback: c
}), () => {
$.remove(d, ee, c);
};
}, [d]), v(() => {
const c = () => {
if (r) {
const p = new Promise((i) => {
if (o.buildFinished)
i(o.html);
else {
const a = (l) => {
i(l), $.remove(d, ee, a);
};
$.on(d, {
name: ee,
callback: a
});
}
});
r(s || n || "", p);
}
};
return $.on(d, {
name: he,
callback: c
}), () => {
$.remove(d, he, c);
};
}, [d, n, r, o.buildFinished, o.html, s]), v(() => {
m((c) => ({
...c,
buildFinished: !1
}));
}, [s, n]);
}, Qt = (e) => {
const { noPrettier: t, noUploadImg: s } = e;
v(() => {
const { editorExtensions: n, editorExtensionsAttrs: r } = C, d = t || !!n.prettier.prettierInstance, o = t || !!n.prettier.parserMarkdownInstance;
if (!(s || !!n.cropper.instance)) {
const { js: c = {}, css: p = {} } = r.cropper || {};
_("link", {
...p,
rel: "stylesheet",
href: n.cropper.css,
id: L.croppercss
}), _("script", {
...c,
src: n.cropper.js,
id: L.cropperjs
});
}
if (!d) {
const { standaloneJs: c = {} } = r.prettier || {};
_("script", {
...c,
src: n.prettier.standaloneJs,
id: L.prettier
});
}
if (!o) {
const { parserMarkdownJs: c = {} } = r.prettier || {};
_("script", {
...c,
src: n.prettier.parserMarkdownJs,
id: L.prettierMD
});
}
}, [t, s]);
}, er = (e, t) => {
v(() => ($.on(e, {
name: te,
callback: t
}), () => {
$.remove(e, te, t);
}), [e, t]);
}, tr = (e, t) => {
const { editorId: s } = t, { onUploadImg: n } = e;
v(() => {
const r = (d, o) => {
n?.(d, (c) => {
$.emit(s, ge, "image", {
desc: "",
urls: c
}), o?.();
});
};
return $.on(s, {
name: we,
callback: r
}), () => {
$.remove(s, we, r);
};
}, [s, n]);
}, rr = (e, t) => {
const { editorId: s } = t, [n, r] = M(!1);
return v(() => {
const d = (o) => {
r(o === void 0 ? (m) => !m : o);
};
return $.on(s, {
name: fe,
callback: d
}), () => {
$.remove(s, fe, d);
};
}, [s]), n;
};
let _e = "";
const Mt = (e) => {
const {
theme: t = O.theme,
previewTheme: s = O.previewTheme,
codeTheme: n = O.codeTheme,
language: r = O.language,
codeStyleReverse: d = O.codeStyleReverse,
codeStyleReverseList: o = O.codeStyleReverseList
} = e, m = ue(() => {
const p = C.editorExtensions.highlight, i = C.editorExtensionsAttrs.highlight, { js: a } = p, l = {
...ve,
...p.css
}, { js: h, css: u = {} } = i || {}, b = d && o.includes(s) ? "dark" : t, g = l[n] ? l[n][b] : ve.atom[b], H = l[n] && u[n] ? u[n][b] : u.atom ? u.atom[b] : {};
return {
js: {
src: a,
...h
},
css: {
href: g,
...H
}
};
}, [d, o, s, t, n]), c = ue(() => {
const p = {
...ke,
...C.editorConfig.languageUserDefined
};
return p[r] ? p[r] : ke["zh-CN"];
}, [r]);
return [m, c];
}, nr = (e) => {
const {
preview: t = O.preview,
htmlPreview: s = O.htmlPreview,
pageFullscreen: n = O.pageFullscreen
} = e, [r, d] = Mt(e), [o, m] = M({
pageFullscreen: n,
fullscreen: !1,
preview: t,
htmlPreview: t ? !1 : s,
previewOnly: !1
}), c = T(o), p = U((i, a) => {
m((l) => {
const h = a === void 0 ? !l[i] : a, u = {
...l
};
switch (i) {
case "preview": {
u.htmlPreview = !1, u.previewOnly = !1;
break;
}
case "htmlPreview": {
u.preview = !1, u.previewOnly = !1;
break;
}
case "previewOnly": {
h ? !u.preview && !u.htmlPreview && (u.preview = !0) : (c.current.preview || (u.preview = !1), c.current.htmlPreview || (u.htmlPreview = !1));
break;
}
}
return c.current[i] = h, u[i] = h, u;
});
}, []);
return v(() => {
_e = document.body.style.overflow;
}, []), v(() => {
o.pageFullscreen || o.fullscreen ? document.body.style.overflow = "hidden" : document.body.style.overflow = _e;
}, [o.pageFullscreen, o.fullscreen]), [r, d, o, p];
}, sr = (e, t, s, n, r, d) => {
const { editorId: o } = t;
v(() => {
$.emit(o, Ee, n.pageFullscreen);
}, [o, n.pageFullscreen]), v(() => {
$.emit(o, xe, n.fullscreen);
}, [o, n.fullscreen]), v(() => {
$.emit(o, Ce, n.preview);
}, [o, n.preview]), v(() => {
$.emit(o, Ie, n.previewOnly);
}, [o, n.previewOnly]), v(() => {
$.emit(o, Te, n.htmlPreview);
}, [o, n.htmlPreview]), v(() => {
$.emit(o, Se, s);
}, [s, o]), ze(e, () => ({
on(c, p) {
switch (c) {
case "pageFullscreen": {
$.on(o, {
name: Ee,
callback(i) {
p(i);
}
});
break;
}
case "fullscreen": {
$.on(o, {
name: xe,
callback(i) {
p(i);
}
});
break;
}
case "preview": {
$.on(o, {
name: Ce,
callback(i) {
p(i);
}
});
break;
}
case "previewOnly": {
$.on(o, {
name: Ie,
callback(i) {
p(i);
}
});
break;
}
case "htmlPreview": {
$.on(o, {
name: Te,
callback(i) {
p(i);
}
});
break;
}
case "catalog": {
$.on(o, {
name: Se,
callback(i) {
p(i);
}
});
break;
}
}
},
togglePageFullscreen(c) {
r("pageFullscreen", c);
},
toggleFullscreen(c) {
$.emit(o, Xe, c);
},
togglePreview(c) {
r("preview", c);
},
togglePreviewOnly(c) {
r("previewOnly", c);
},
toggleHtmlPreview(c) {
r("htmlPreview", c);
},
toggleCatalog(c) {
$.emit(o, fe, c);
},
triggerSave() {
$.emit(o, he);
},
insert(c) {
$.emit(o, ge, "universal", { generate: c });
},
focus(c) {
d.current?.focus(c);
},
rerender() {
$.emit(o, pe);
},
getSelectedText() {
return d.current?.getSelectedText();
},
resetHistory() {
d.current?.resetHistory();
},
domEventHandlers(c) {
$.emit(o, Je, c);
},
execCommand(c) {
$.emit(o, ge, c);
},
getEditorView() {
return d.current?.getEditorView();
}
}), [d, o, r]);
}, or = (e) => {
const t = Ge();
return e.id || e.editorId || f + "-" + t.replaceAll(":", "");
};
export {
L as C,
Bt as a,
Yt as b,
Qt as c,
tr as d,
er as e,
rr as f,
nr as g,
sr as h,
Mt as i,
or as u
};