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