UNPKG

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
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 };