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,244 lines (1,243 loc) 38.4 kB
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 };