md-editor-v3
Version:
Markdown editor for vue3, developed in jsx and typescript, dark theme、beautify content by prettier、render articles directly、paste or clip the picture and upload it...
2,055 lines (2,054 loc) • 51 kB
JavaScript
import { useId as Fe, provide as T, computed as R, reactive as re, watch as E, onMounted as H, ref as G, inject as w, nextTick as U, shallowRef as ee, onBeforeUnmount as te, toRef as Re, defineComponent as ce, createVNode as N, Fragment as Ae, h as He } from "vue";
import { deepMerge as Me, deepClone as Pe, randomId as le, debounce as Le } from "@vavt/util";
import { p as f, g as P, f as ue, s as me, b as Oe, a as _e } from "./config.mjs";
import { b as y, U as je, C as Ee, B as X, O as ke, E as Q, P as fe, F as he, f as pe, g as ge, H as ve, h as ye, R as ie, e as Ne, i as de, d as Be, j as oe, k as De, T as Ve } from "./event-bus.mjs";
import { a as O, u as Ge, S as Ue, c as ze, z as We } from "./dom.mjs";
import qe from "@vavt/copy2clipboard";
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 { g as Ye } from "./index5.mjs";
import { LRUCache as Qe } from "lru-cache";
import et 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`
}, Jt = (e, t, r) => {
const { editorId: n } = r, o = re({
// 是否已编译成html
buildFinished: !1,
// 存储当前最新的html
html: ""
});
E(
() => e.modelValue,
() => {
o.buildFinished = !1;
}
), H(() => {
y.on(n, {
name: X,
callback(u) {
o.buildFinished = !0, o.html = u;
}
}), y.on(n, {
name: ke,
callback() {
const u = new Promise((c) => {
if (o.buildFinished)
c(o.html);
else {
const m = (s) => {
c(s), y.remove(n, X, m);
};
y.on(n, {
name: X,
callback: m
});
}
});
e.onSave ? e.onSave(e.modelValue, u) : t.emit("onSave", e.modelValue, u);
}
});
});
}, Te = (e, {
editorId: t,
rootRef: r,
setting: n
}) => {
const o = P.editorExtensions.highlight, u = P.editorExtensionsAttrs.highlight;
T("editorId", t), T("rootRef", r), T(
"theme",
R(() => e.theme)
), T(
"language",
R(() => e.language)
), T(
"highlight",
R(() => {
const { js: m } = o, s = {
...ue,
...o.css
}, { js: l, css: i = {} } = u || {}, a = e.codeStyleReverse && e.codeStyleReverseList.includes(e.previewTheme) ? "dark" : e.theme, d = s[e.codeTheme] ? s[e.codeTheme][a] : ue.atom[a], $ = s[e.codeTheme] && i[e.codeTheme] ? i[e.codeTheme][a] : i.atom ? i.atom[a] : {};
return {
js: {
src: m,
...l
},
css: {
href: d,
...$
}
};
})
), T("showCodeRowNumber", e.showCodeRowNumber);
const c = R(() => {
const m = {
...me,
...P.editorConfig.languageUserDefined
};
return Me(
Pe(me["en-US"]),
m[e.language] || {}
);
});
return T("usedLanguageText", c), T(
"previewTheme",
R(() => e.previewTheme)
), T(
"customIcon",
R(() => e.customIcon)
), T(
"setting",
R(() => n ? {
// setting是reactive,不转化是可以直接赋值的
...n
} : {
preview: !0,
htmlPreview: !1,
previewOnly: !1,
pageFullscreen: !1,
fullscreen: !1
})
), { editorId: t };
}, Xt = (e, t) => (T("tabWidth", e.tabWidth), T(
"disabled",
R(() => e.disabled)
), T(
"showToolbarName",
R(() => e.showToolbarName)
), T("noUploadImg", e.noUploadImg), T(
"tableShape",
R(() => e.tableShape)
), T("noPrettier", e.noPrettier), T(
"codeTheme",
R(() => e.codeTheme)
), T("updateSetting", t.updateSetting), T(
"catalogVisible",
R(() => t.catalogVisible.value)
), T("defToolbars", t.defToolbars), T(
"floatingToolbars",
R(() => e.floatingToolbars)
), Te(e, t)), Yt = (e) => {
const { noPrettier: t, noUploadImg: r } = e, { editorExtensions: n, editorExtensionsAttrs: o } = P, u = t || n.prettier.prettierInstance, c = t || n.prettier.parserMarkdownInstance, m = r || n.cropper.instance;
H(() => {
if (!m) {
const { js: s = {}, css: l = {} } = o.cropper || {};
O("link", {
...l,
rel: "stylesheet",
href: n.cropper.css,
id: M.croppercss
}), O("script", {
...s,
src: n.cropper.js,
id: M.cropperjs
});
}
if (!u) {
const { standaloneJs: s = {} } = o.prettier || {};
O("script", {
...s,
src: n.prettier.standaloneJs,
id: M.prettier
});
}
if (!c) {
const { parserMarkdownJs: s = {} } = o.prettier || {};
O("script", {
...s,
src: n.prettier.parserMarkdownJs,
id: M.prettierMD
});
}
});
}, Qt = (e, t, r) => {
const { editorId: n } = r;
H(() => {
y.on(n, {
name: Q,
callback: (o) => {
e.onError?.(o), t.emit("onError", o);
}
});
});
}, en = (e, t, r) => {
const { editorId: n } = r, o = re({
pageFullscreen: e.pageFullscreen,
fullscreen: !1,
preview: e.preview,
htmlPreview: e.preview ? !1 : e.htmlPreview,
previewOnly: !1
}), u = re({ ...o }), c = (l, i) => {
const a = i === void 0 ? !o[l] : i;
switch (l) {
case "preview": {
o.htmlPreview = !1, o.previewOnly = !1;
break;
}
case "htmlPreview": {
o.preview = !1, o.previewOnly = !1;
break;
}
case "previewOnly": {
a ? !o.preview && !o.htmlPreview && (o.preview = !0) : (u.preview || (o.preview = !1), u.htmlPreview || (o.htmlPreview = !1));
break;
}
}
u[l] = a, o[l] = a;
};
let m = "";
const s = () => {
o.pageFullscreen || o.fullscreen ? document.body.style.overflow = "hidden" : document.body.style.overflow = m;
};
return E(() => [o.pageFullscreen, o.fullscreen], s), H(() => {
y.on(n, {
name: je,
callback(l, i) {
const a = (d) => {
y.emit(n, ie, "image", {
desc: "",
urls: d
}), i?.();
};
e.onUploadImg ? e.onUploadImg(l, a) : t.emit("onUploadImg", l, a);
}
}), m = document.body.style.overflow, s();
}), [o, c];
}, tn = (e, t) => {
const { editorId: r } = t, n = G(!1);
return H(() => {
y.on(r, {
name: Ee,
callback: (o) => {
o === void 0 ? n.value = !n.value : n.value = o;
}
});
}), n;
}, nn = (e, t, r) => {
const { editorId: n, catalogVisible: o, setting: u, updateSetting: c, codeRef: m } = r;
E(
() => u.pageFullscreen,
(l) => {
y.emit(n, fe, l);
}
), E(
() => u.fullscreen,
(l) => {
y.emit(n, he, l);
}
), E(
() => u.preview,
(l) => {
y.emit(n, pe, l);
}
), E(
() => u.previewOnly,
(l) => {
y.emit(n, ge, l);
}
), E(
() => u.htmlPreview,
(l) => {
y.emit(n, ve, l);
}
), E(o, (l) => {
y.emit(n, ye, l);
});
const s = {
on(l, i) {
switch (l) {
case "pageFullscreen": {
y.on(n, {
name: fe,
callback(a) {
i(a);
}
});
break;
}
case "fullscreen": {
y.on(n, {
name: he,
callback(a) {
i(a);
}
});
break;
}
case "preview": {
y.on(n, {
name: pe,
callback(a) {
i(a);
}
});
break;
}
case "previewOnly": {
y.on(n, {
name: ge,
callback(a) {
i(a);
}
});
break;
}
case "htmlPreview": {
y.on(n, {
name: ve,
callback(a) {
i(a);
}
});
break;
}
case "catalog": {
y.on(n, {
name: ye,
callback(a) {
i(a);
}
});
break;
}
}
},
togglePageFullscreen(l) {
c("pageFullscreen", l);
},
toggleFullscreen(l) {
y.emit(n, Be, l);
},
togglePreview(l) {
c("preview", l);
},
togglePreviewOnly(l) {
c("previewOnly", l);
},
toggleHtmlPreview(l) {
c("htmlPreview", l);
},
toggleCatalog(l) {
y.emit(n, Ee, l);
},
triggerSave() {
y.emit(n, ke);
},
insert(l) {
y.emit(n, ie, "universal", { generate: l });
},
focus(l) {
m.value?.focus(l);
},
rerender() {
y.emit(n, de);
},
getSelectedText() {
return m.value?.getSelectedText();
},
resetHistory() {
m.value?.resetHistory();
},
domEventHandlers(l) {
y.emit(n, Ne, l);
},
execCommand(l) {
y.emit(n, ie, l);
},
getEditorView() {
return m.value?.getEditorView();
}
};
t.expose(s);
}, tt = (e) => {
const t = Fe();
return e.id || e.editorId || `${f}-${t}`;
}, nt = (e, t, r) => {
const n = w("editorId"), o = w("rootRef"), u = w("usedLanguageText"), c = w("setting"), m = () => {
o.value.querySelectorAll(`#${n} .${f}-preview .${f}-code`).forEach((i) => {
let a = -1;
const d = i.querySelector(
`.${f}-copy-button:not([data-processed])`
);
d && (d.onclick = ($) => {
$.preventDefault(), clearTimeout(a);
const p = (i.querySelector("input:checked + pre code") || i.querySelector("pre code")).textContent, { text: g, successTips: I, failTips: v } = u.value.copyCode;
let C = I;
qe(e.formatCopiedText(p || "")).catch(() => {
C = v;
}).finally(() => {
d.dataset.isIcon ? d.dataset.tips = C : d.innerHTML = C, a = window.setTimeout(() => {
d.dataset.isIcon ? d.dataset.tips = g : d.innerHTML = g;
}, 1500);
});
}, d.setAttribute("data-processed", "true"));
});
}, s = () => {
U(m);
}, l = (i) => {
i && U(m);
};
E([t, r], s), E(() => c.value.preview, l), E(() => c.value.htmlPreview, l), H(m);
}, ot = (e) => {
const t = w("editorId"), r = w("theme"), n = w("rootRef"), { editorExtensions: o, editorExtensionsAttrs: u } = P;
let c = o.echarts.instance;
const m = ee(-1), s = () => {
!e.noEcharts && c && (m.value = m.value + 1);
};
E(
() => r.value,
() => {
s();
}
), H(() => {
if (e.noEcharts || c)
return;
const h = o.echarts.js;
O(
"script",
{
...u.echarts?.js,
src: h,
id: M.echarts,
onload() {
c = window.echarts, s();
}
},
"echarts"
);
});
let l = [], i = [], a = [];
const d = (h = !1) => {
if (!l.length) {
h && (i.forEach((v) => {
v.dispose?.();
}), a.forEach((v) => {
v.disconnect?.();
}), i = [], a = []);
return;
}
const p = [], g = [], I = [];
l.forEach((v, C) => {
const x = i[C], b = a[C];
if (h || !v || !v.isConnected || (n?.value ? !n.value.contains(v) : !1)) {
x?.dispose?.(), b?.disconnect?.();
return;
}
p.push(v), x && g.push(x), b && I.push(b);
}), l = p, i = g, a = I;
}, $ = () => {
d(), !e.noEcharts && c && Array.from(
n.value.querySelectorAll(
`#${t} div.${f}-echarts:not([data-processed])`
)
).forEach((p) => {
if (p.dataset.closed === "false")
return !1;
try {
const g = new Function(`return ${p.innerText}`)(), I = c.init(p, r.value);
I.setOption(g), p.setAttribute("data-processed", ""), l.push(p), i.push(I);
const v = new ResizeObserver(() => {
I.resize();
});
v.observe(p), a.push(v);
} catch (g) {
y.emit(t, Q, {
name: "echarts",
message: g?.message,
error: g
});
}
});
};
return te(() => {
d(!0);
}), { reRenderEcharts: m, replaceEcharts: $ };
}, at = (e) => {
const t = w("highlight"), r = ee(P.editorExtensions.highlight.instance);
return H(() => {
e.noHighlight || r.value || (O("link", {
...t.value.css,
rel: "stylesheet",
id: M.hlcss
}), O(
"script",
{
...t.value.js,
id: M.hljs,
onload() {
r.value = window.hljs;
}
},
"hljs"
));
}), E(
() => t.value.css,
() => {
e.noHighlight || P.editorExtensions.highlight.instance || Ge("link", {
...t.value.css,
rel: "stylesheet",
id: M.hlcss
});
}
), r;
}, rt = (e) => {
const t = ee(P.editorExtensions.katex.instance);
return H(() => {
if (e.noKatex || t.value)
return;
const { editorExtensions: r, editorExtensionsAttrs: n } = P;
O(
"script",
{
...n.katex?.js,
src: r.katex.js,
id: M.katexjs,
onload() {
t.value = window.katex;
}
},
"katex"
), O("link", {
...n.katex?.css,
rel: "stylesheet",
href: r.katex.css,
id: M.katexcss
});
}), t;
}, Y = new Qe({
max: 1e3,
// 缓存10分钟
ttl: 6e5
}), lt = (e) => {
const t = w("editorId"), r = w("theme"), n = w("rootRef"), { editorExtensions: o, editorExtensionsAttrs: u, mermaidConfig: c } = P;
let m = o.mermaid.instance;
const s = ee(-1), l = () => {
!e.noMermaid && m && (m.initialize(
c({
startOnLoad: !1,
theme: r.value === "dark" ? "dark" : "default"
})
), s.value = s.value + 1);
};
return E(
() => r.value,
() => {
Y.clear(), l();
}
), H(() => {
if (e.noMermaid || m)
return;
const a = o.mermaid.js;
/\.mjs/.test(a) ? (O("link", {
...u.mermaid?.js,
rel: "modulepreload",
href: a,
id: M.mermaidM
}), import(
/* @vite-ignore */
/* webpackIgnore: true */
a
).then((d) => {
m = d.default, l();
}).catch((d) => {
y.emit(t, Q, {
name: "mermaid",
message: `Failed to load mermaid module: ${d.message}`,
error: d
});
})) : O(
"script",
{
...u.mermaid?.js,
src: a,
id: M.mermaid,
onload() {
m = window.mermaid, l();
}
},
"mermaid"
);
}), { reRenderRef: s, replaceMermaid: async () => {
if (!e.noMermaid && m) {
const a = n.value.querySelectorAll(
`div.${f}-mermaid`
), d = document.createElement("div"), $ = document.body.offsetWidth > 1366 ? document.body.offsetWidth : 1366, h = document.body.offsetHeight > 768 ? document.body.offsetHeight : 768;
d.style.width = $ + "px", d.style.height = h + "px", d.style.position = "fixed", d.style.zIndex = "-10000", d.style.top = "-10000";
let p = a.length;
p > 0 && document.body.appendChild(d), await Promise.allSettled(
Array.from(a).map((g) => (async (v) => {
if (v.dataset.closed === "false")
return !1;
const C = v.innerText;
let x = Y.get(C);
if (!x) {
const b = le();
let F = { svg: "" };
try {
F = await m.render(b, C, d), x = await e.sanitizeMermaid(F.svg);
const S = document.createElement("p");
S.className = `${f}-mermaid`, S.setAttribute("data-processed", ""), S.setAttribute("data-content", C), S.innerHTML = x, S.children[0]?.removeAttribute("height"), Y.set(C, S.innerHTML), v.dataset.line !== void 0 && (S.dataset.line = v.dataset.line), v.replaceWith(S);
} catch (S) {
y.emit(t, Q, {
name: "mermaid",
message: S.message,
error: S
});
}
--p === 0 && d.remove();
}
})(g))
);
}
} };
}, it = (e, t) => {
t = t || {};
const r = 3, n = t.marker || "!", o = n.charCodeAt(0), u = n.length;
let c = "", m = "";
const s = (i, a, d, $, h) => {
const p = i[a];
return p.type === "admonition_open" ? i[a].attrPush([
"class",
`${f}-admonition ${f}-admonition-${p.info}`
]) : p.type === "admonition_title_open" && i[a].attrPush(["class", `${f}-admonition-title`]), h.renderToken(i, a, d);
}, l = (i) => {
const a = i.trim().split(" ", 2);
m = "", c = a[0], a.length > 1 && (m = i.substring(c.length + 2));
};
e.block.ruler.before(
"code",
"admonition",
(i, a, d, $) => {
let h, p, g, I = !1, v = i.bMarks[a] + i.tShift[a], C = i.eMarks[a];
if (o !== i.src.charCodeAt(v))
return !1;
for (h = v + 1; h <= C && n[(h - v) % u] === i.src[h]; h++)
;
const x = Math.floor((h - v) / u);
if (x !== r)
return !1;
h -= (h - v) % u;
const b = i.src.slice(v, h), F = i.src.slice(h, C);
if (l(F), $)
return !0;
for (p = a; p++, !(p >= d || (v = i.bMarks[p] + i.tShift[p], C = i.eMarks[p], v < C && i.sCount[p] < i.blkIndent)); )
if (o === i.src.charCodeAt(v) && !(i.sCount[p] - i.blkIndent >= 4)) {
for (h = v + 1; h <= C && n[(h - v) % u] === i.src[h]; h++)
;
if (!(Math.floor((h - v) / u) < x) && (h -= (h - v) % u, h = i.skipSpaces(h), !(h < C))) {
I = !0;
break;
}
}
const S = i.parentType, L = i.lineMax;
return i.parentType = "root", i.lineMax = p, g = i.push("admonition_open", "div", 1), g.markup = b, g.block = !0, g.info = c, g.map = [a, p], m && (g = i.push("admonition_title_open", "p", 1), g.markup = b + " " + c, g.map = [a, p], 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 = b + " " + c), i.md.block.tokenize(i, a + 1, p), g = i.push("admonition_close", "div", -1), g.markup = i.src.slice(v, h), g.block = !0, i.parentType = S, i.lineMax = L, i.line = p + (I ? 1 : 0), !0;
},
{
alt: ["paragraph", "reference", "blockquote", "list"]
}
), e.renderer.rules.admonition_open = s, e.renderer.rules.admonition_title_open = s, e.renderer.rules.admonition_title_close = s, e.renderer.rules.admonition_close = s;
}, se = (e, t) => {
const r = e.attrs ? e.attrs.slice() : [];
return t.forEach((n) => {
const o = e.attrIndex(n[0]);
o < 0 ? r.push(n) : (r[o] = r[o].slice(), r[o][1] += ` ${n[1]}`);
}), r;
}, st = (e, t) => {
const r = e.renderer.rules.fence, n = e.utils.unescapeAll, o = /\[(\w*)(?::([\w ]*))?\]/, u = /::(open|close)/, c = (a) => a.info ? n(a.info).trim() : "", m = (a) => {
const d = c(a), [$ = null, h = ""] = (o.exec(d) || []).slice(1);
return [$, h];
}, s = (a) => {
const d = c(a);
return d ? d.split(/(\s+)/g)[0] : "";
}, l = (a) => {
const d = a.info.match(u) || [], $ = d[1] === "open" || d[1] !== "close" && t.codeFoldable && a.content.trim().split(`
`).length < t.autoFoldThreshold, h = d[1] || t.codeFoldable ? "details" : "div", p = d[1] || t.codeFoldable ? "summary" : "div";
return { open: $, tagContainer: h, tagHeader: p };
}, i = (a, d, $, h, p) => {
if (a[d].hidden)
return "";
const g = t.usedLanguageTextRef.value?.copyCode.text, I = t.customIconRef.value.copy || g, v = !!t.customIconRef.value.copy, C = `<span class="${f}-collapse-tips">${Ue("collapse-tips", t.customIconRef.value)}</span>`, [x] = m(a[d]);
if (x === null) {
const { open: k, tagContainer: A, tagHeader: J } = l(a[d]), j = [["class", `${f}-code`]];
k && j.push(["open", ""]);
const ne = {
attrs: se(a[d], j)
};
a[d].info = a[d].info.replace(u, "");
const W = r(a, d, $, h, p);
return `
<${A} ${p.renderAttrs(ne)}>
<${J} 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[d].info.trim())}</span>
<span class="${f}-copy-button" data-tips="${g}"${v ? " data-is-icon=true" : ""}>${I}</span>
${t.extraTools instanceof Function ? t.extraTools({ lang: a[d].info.trim() }) : t.extraTools || ""}
${A === "details" ? C : ""}
</div>
</${J}>
${W}
</${A}>
`;
}
let b, F, S, L, _ = "", B = "", D = "";
const { open: q, tagContainer: V, tagHeader: z } = l(a[d]), K = [["class", `${f}-code`]];
q && K.push(["open", ""]);
const Z = {
attrs: se(a[d], K)
};
for (let k = d; k < a.length && (b = a[k], [F, S] = m(b), F === x); k++) {
b.info = b.info.replace(o, "").replace(u, ""), b.hidden = !0;
const A = `${f}-codetab-${t.editorId}-${d}-${k - d}`;
L = k - d > 0 ? "" : "checked", _ += `
<li>
<input
type="radio"
id="label-${f}-codetab-label-1-${t.editorId}-${d}-${k - d}"
name="${f}-codetab-label-${t.editorId}-${d}"
class="${A}"
${L}
>
<label
for="label-${f}-codetab-label-1-${t.editorId}-${d}-${k - d}"
onclick="this.getRootNode().querySelectorAll('.${A}').forEach(e => e.click())"
>
${e.utils.escapeHtml(S || s(b))}
</label>
</li>`, B += `
<div role="tabpanel">
<input
type="radio"
name="${f}-codetab-pre-${t.editorId}-${d}"
class="${A}"
${L}
role="presentation">
${r(a, k, $, h, p)}
</div>`, D += `
<input
type="radio"
name="${f}-codetab-lang-${t.editorId}-${d}"
class="${A}"
${L}
role="presentation">
<span class=${f}-code-lang role="note">${e.utils.escapeHtml(s(b))}</span>`;
}
return `
<${V} ${p.renderAttrs(Z)}>
<${z} class="${f}-code-head">
<div class="${f}-code-flag">
<ul class="${f}-codetab-label" role="tablist">${_}</ul>
</div>
<div class="${f}-code-action">
<span class="${f}-codetab-lang">${D}</span>
<span class="${f}-copy-button" data-tips="${g}"${v ? " data-is-icon=true" : ""}>${I}</span>
${t.extraTools instanceof Function ? t.extraTools({ lang: a[d].info.trim() }) : t.extraTools || ""}
${V === "details" ? C : ""}
</div>
</${z}>
${B}
</${V}>
`;
};
e.renderer.rules.fence = i, e.renderer.rules.code_block = i;
}, ct = (e, t) => {
const r = e.renderer.rules.fence.bind(e.renderer.rules);
e.renderer.rules.fence = (n, o, u, c, m) => {
const s = n[o], l = s.content.trim();
if (s.info === "echarts") {
if (s.attrSet("class", `${f}-echarts`), s.attrSet("data-echarts-theme", t.themeRef.value), s.map && s.level === 0) {
const i = s.map[1] - 1, d = !!c.srcLines[i]?.trim()?.startsWith("```");
s.attrSet("data-closed", `${d}`), s.attrSet("data-line", String(s.map[0]));
}
return `<div ${m.renderAttrs(s)} style="width: 100%; aspect-ratio: 4 / 3;">${e.utils.escapeHtml(l)}</div>`;
}
return r(n, o, u, c, m);
};
}, dt = (e, t) => {
e.renderer.rules.heading_open = (r, n) => {
const o = r[n], u = r[n + 1].children?.reduce((m, s) => m + (["text", "code_inline", "math_inline"].includes(s.type) && s.content || ""), "") || "", c = o.markup.length;
return t.headsRef.value.push({
text: u,
level: c,
line: o.map[0],
currentToken: o,
nextToken: r[n + 1]
}), o.map && o.level === 0 && o.attrSet(
"id",
t.mdHeadingId({
text: u,
level: c,
index: t.headsRef.value.length,
currentToken: o,
nextToken: r[n + 1]
})
), e.renderer.renderToken(r, n, t);
}, e.renderer.rules.heading_close = (r, n, o, u, c) => c.renderToken(r, n, o);
}, be = {
block: [
{ open: "$$", close: "$$" },
{ open: "\\[", close: "\\]" }
],
inline: [
{ open: "$$", close: "$$" },
{ open: "$", close: "$" },
{ open: "\\[", close: "\\]" },
{ open: "\\(", close: "\\)" }
]
}, ut = (e) => (t, r) => {
const n = e.delimiters;
for (const o of n) {
if (!t.src.startsWith(o.open, t.pos))
continue;
const u = t.pos + o.open.length;
let c = u;
for (; (c = t.src.indexOf(o.close, c)) !== -1; ) {
let m = 0, s = c - 1;
for (; s >= 0 && t.src[s] === "\\"; )
m++, s--;
if (m % 2 === 0)
break;
c += o.close.length;
}
if (c !== -1) {
if (c - u === 0)
return r || (t.pending += o.open + o.close), t.pos = c + o.close.length, !0;
if (!r) {
const m = t.push("math_inline", "math", 0);
m.markup = o.open, m.content = t.src.slice(u, c);
}
return t.pos = c + o.close.length, !0;
}
}
return !1;
}, mt = (e) => (t, r, n, o) => {
const u = e.delimiters, c = t.bMarks[r] + t.tShift[r], m = t.eMarks[r], s = (l, i, a) => {
t.line = i;
const d = t.push("math_block", "math", 0);
return d.block = !0, d.content = l, d.map = [r, t.line], d.markup = a, !0;
};
for (const l of u) {
const i = c;
if (t.src.slice(i, i + l.open.length) !== l.open)
continue;
const a = i + l.open.length, d = t.src.slice(a, m).trim(), $ = d === "", h = d === l.close, p = d.endsWith(l.close);
if (!$ && !h && !p)
continue;
if (o)
return !0;
if (h)
return s("", r + 1, l.open);
if (!$ && p) {
const b = d.slice(0, -l.close.length);
return s(b, r + 1, l.open);
}
let g = r + 1, I = !1, v = "";
for (; g < n; g++) {
const b = t.bMarks[g] + t.tShift[g], F = t.eMarks[g];
if (b < F && t.tShift[g] < t.blkIndent)
break;
if (t.src.slice(b, F).trim().endsWith(l.close)) {
const L = t.src.slice(0, F).lastIndexOf(l.close);
v = t.src.slice(b, L), I = !0;
break;
}
}
if (!I)
continue;
const x = t.getLines(r + 1, g, t.tShift[r], !0) + (v.trim() ? v : "");
return s(x, g + 1, l.open);
}
return !1;
}, ft = (e, { katexRef: t, inlineDelimiters: r, blockDelimiters: n }) => {
const o = (m, s, l, i, a = !1) => {
const d = {
attrs: se(m, [["class", s]])
}, $ = i.renderAttrs(d);
if (!t.value)
return `<${l} ${$}>${m.content}</${l}>`;
const h = t.value.renderToString(
m.content,
P.katexConfig({
throwOnError: !1,
displayMode: a
})
);
return `<${l} ${$} data-processed>${h}</${l}>`;
}, u = (m, s, l, i, a) => o(m[s], `${f}-katex-inline`, "span", a), c = (m, s, l, i, a) => o(m[s], `${f}-katex-block`, "p", a, !0);
e.inline.ruler.before(
"escape",
"math_inline",
ut({
delimiters: r || be.inline
})
), e.block.ruler.after(
"blockquote",
"math_block",
mt({
delimiters: n || be.block
}),
{
alt: ["paragraph", "reference", "blockquote", "list"]
}
), e.renderer.rules.math_inline = u, e.renderer.rules.math_block = c;
}, ht = (e, t) => {
const r = e.renderer.rules.fence.bind(e.renderer.rules);
e.renderer.rules.fence = (n, o, u, c, m) => {
const s = n[o], l = s.content.trim();
if (s.info === "mermaid") {
if (s.attrSet("class", `${f}-mermaid`), s.attrSet("data-mermaid-theme", t.themeRef.value), s.map && s.level === 0) {
const a = s.map[1] - 1, $ = !!c.srcLines[a]?.trim()?.startsWith("```");
s.attrSet("data-closed", `${$}`), s.attrSet("data-line", String(s.map[0]));
}
const i = Y.get(l);
return i ? (s.attrSet("data-processed", ""), s.attrSet("data-content", l), `<p ${m.renderAttrs(s)}>${i}</p>`) : `<div ${m.renderAttrs(s)}>${e.utils.escapeHtml(l)}</div>`;
}
return r(n, o, u, c, m);
};
}, $e = (e, t, r) => {
const n = e.attrIndex(t), o = [t, r];
n < 0 ? e.attrPush(o) : (e.attrs = e.attrs || [], e.attrs[n] = o);
}, pt = (e) => e.type === "inline", gt = (e) => e.type === "paragraph_open", vt = (e) => e.type === "list_item_open", yt = (e) => e.content.indexOf("[ ] ") === 0 || e.content.indexOf("[x] ") === 0 || e.content.indexOf("[X] ") === 0, bt = (e, t) => pt(e[t]) && gt(e[t - 1]) && vt(e[t - 2]) && yt(e[t]), $t = (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;
}, wt = (e) => {
const t = new e("html_inline", "", 0);
return t.content = "<label>", t;
}, Ct = (e) => {
const t = new e("html_inline", "", 0);
return t.content = "</label>", t;
}, Et = (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;
}, kt = (e, t, r) => {
const n = new t("html_inline", "", 0), o = r.enabled ? " " : ' disabled="" ';
return e.content.indexOf("[ ] ") === 0 ? n.content = '<input class="task-list-item-checkbox"' + o + 'type="checkbox">' : (e.content.indexOf("[x] ") === 0 || e.content.indexOf("[X] ") === 0) && (n.content = '<input class="task-list-item-checkbox" checked=""' + o + 'type="checkbox">'), n;
}, Tt = (e, t, r) => {
if (e.children = e.children || [], e.children.unshift(kt(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(Et(e.content, n, t));
} else
e.children.unshift(wt(t)), e.children.push(Ct(t));
}, It = (e, t = {}) => {
e.core.ruler.after("inline", "github-task-lists", (r) => {
const n = r.tokens;
for (let o = 2; o < n.length; o++)
bt(n, o) && (Tt(n[o], r.Token, t), $e(
n[o - 2],
"class",
"task-list-item" + (t.enabled ? " enabled" : " ")
), $e(n[$t(n, o - 2)], "class", "contains-task-list"));
});
}, St = (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));
}, xt = (e, t) => {
const { editorConfig: r, markdownItConfig: n, markdownItPlugins: o, editorExtensions: u } = P, c = w("editorId"), m = w("language"), s = w(
"usedLanguageText"
), l = w("showCodeRowNumber"), i = w("theme"), a = w("customIcon"), d = w("rootRef"), $ = w("setting"), h = G([]), p = at(e), g = rt(e), { reRenderRef: I, replaceMermaid: v } = lt(e), { reRenderEcharts: C, replaceEcharts: x } = ot(e), b = Ke({
html: !0,
breaks: !0,
linkify: !0
});
n(b, {
editorId: c
});
const F = [
{
type: "image",
plugin: Ze,
options: { figcaption: !0, classes: "md-zoom" }
},
{
type: "admonition",
plugin: it,
options: {}
},
{
type: "taskList",
plugin: It,
options: {}
},
{
type: "heading",
plugin: dt,
options: { mdHeadingId: e.mdHeadingId, headsRef: h }
},
{
type: "code",
plugin: st,
options: {
editorId: c,
usedLanguageTextRef: s,
// showCodeRowNumber,
codeFoldable: e.codeFoldable,
autoFoldThreshold: e.autoFoldThreshold,
customIconRef: a
}
},
{
type: "sub",
plugin: Je,
options: {}
},
{
type: "sup",
plugin: Xe,
options: {}
}
];
e.noKatex || F.push({
type: "katex",
plugin: ft,
options: { katexRef: g }
}), e.noMermaid || F.push({
type: "mermaid",
plugin: ht,
options: { themeRef: i }
}), e.noEcharts || F.push({
type: "echarts",
plugin: ct,
options: { themeRef: i }
}), o(F, {
editorId: c
}).forEach((k) => {
b.use(k.plugin, k.options);
});
const S = b.options.highlight;
b.set({
highlight: (k, A, J) => {
if (S) {
const W = S(k, A, J);
if (W)
return W;
}
let j;
!e.noHighlight && p.value ? p.value.getLanguage(A) ? j = p.value.highlight(k, {
language: A,
ignoreIllegals: !0
}).value : j = p.value.highlightAuto(k).value : j = b.utils.escapeHtml(k);
const ne = l ? Ye(
j.replace(/^\n+|\n+$/g, ""),
k.replace(/^\n+|\n+$/g, "")
) : `<span class="${f}-code-block">${j.replace(/^\n+|\n+$/g, "")}</span>`;
return `<pre><code class="language-${A}" language=${A}>${ne}</code></pre>`;
}
}), St(b);
const L = G(`_article-key_${le()}`), _ = G(
e.sanitize(
b.render(e.modelValue, {
srcLines: e.modelValue.split(`
`)
})
)
);
let B = () => {
}, D = () => {
};
const q = () => {
const k = d.value?.querySelectorAll(
`#${c} p.${f}-mermaid:not([data-closed=false])`
);
D(), D = ze(k, {
customIcon: a.value
}), u.mermaid?.enableZoom && (B(), B = We(k, {
customIcon: a.value
}));
}, V = () => {
y.emit(c, X, _.value), e.onHtmlChanged(_.value), e.onGetCatalog(h.value), y.emit(c, oe, h.value), U(() => {
v().then(q), x();
});
}, z = () => {
h.value = [], _.value = e.sanitize(
b.render(e.modelValue, {
srcLines: e.modelValue.split(`
`)
})
);
}, K = R(() => (e.noKatex || !!g.value) && (e.noHighlight || !!p.value));
let Z = -1;
return E([Re(e, "modelValue"), K, I, m], () => {
Z = window.setTimeout(
() => {
z();
},
t ? 0 : r.renderDelay
);
}), E(
() => $.value.preview,
() => {
$.value.preview && U(() => {
v().then(q), x(), y.emit(c, oe, h.value);
});
}
), E([_, C], () => {
V();
}), H(V), H(() => {
y.on(c, {
name: De,
callback() {
y.emit(c, oe, h.value);
}
}), y.on(c, {
name: de,
callback: () => {
L.value = `_article-key_${le()}`, z();
}
});
}), te(() => {
B(), D(), clearTimeout(Z);
}), { html: _, key: L };
}, Ft = (e, t) => {
const r = w("editorId"), n = w("setting"), { noImgZoomIn: o } = e, u = Le(() => {
const c = document.querySelectorAll(
`#${r}-preview img:not(.not-zoom):not(.medium-zoom-image)`
);
c.length !== 0 && et(c, {
background: "#00000073"
});
});
H(async () => {
!o && n.value.preview && await u();
}), E([t, () => n.value.preview], async () => {
!o && n.value.preview && await u();
});
}, we = {
checked: {
regexp: /- \[x\]/,
value: "- [ ]"
},
unChecked: {
regexp: /- \[\s\]/,
value: "- [x]"
}
}, Rt = (e, t) => {
const r = w("editorId"), n = w("rootRef");
let o = () => {
};
const u = () => {
if (!n.value)
return !1;
const c = n.value.querySelectorAll(".task-list-item.enabled"), m = (s) => {
s.preventDefault();
const l = s.target.checked ? "unChecked" : "checked", i = s.target.parentElement?.dataset.line;
if (!i)
return;
const a = Number(i), d = e.modelValue.split(`
`), $ = d[Number(a)].replace(
we[l].regexp,
we[l].value
);
e.previewOnly ? (d[Number(a)] = $, e.onChange(d.join(`
`))) : y.emit(r, Ve, a + 1, $);
};
c.forEach((s) => {
s.addEventListener("click", m);
}), o = () => {
c.forEach((s) => {
s.removeEventListener("click", m);
});
};
};
te(() => {
o();
}), E(
[t],
() => {
o(), U(u);
},
{
immediate: !0
}
);
}, At = (e, t, r) => {
const n = w("setting"), o = () => {
U(() => {
e.onRemount?.();
});
}, u = (c) => {
c && o();
};
E([t, r], o), E(() => n.value.preview, u), E(() => n.value.htmlPreview, u), H(o);
}, Ie = {
modelValue: {
type: String,
default: ""
},
onChange: {
type: Function,
default: () => {
}
},
onHtmlChanged: {
type: Function,
default: () => {
}
},
onGetCatalog: {
type: Function,
default: () => {
}
},
mdHeadingId: {
type: Function,
default: () => ""
},
noMermaid: {
type: Boolean,
default: !1
},
sanitize: {
type: Function,
default: (e) => e
},
// 不使用该函数功能
noKatex: {
type: Boolean,
default: !1
},
formatCopiedText: {
type: Function,
default: (e) => e
},
noHighlight: {
type: Boolean,
default: !1
},
previewOnly: {
type: Boolean,
default: !1
},
noImgZoomIn: {
type: Boolean
},
sanitizeMermaid: {
type: Function
},
codeFoldable: {
type: Boolean
},
autoFoldThreshold: {
type: Number
},
onRemount: {
type: Function
},
noEcharts: {
type: Boolean
},
previewComponent: {
type: [Object, Function],
default: void 0
}
}, on = {
...Ie,
updateModelValue: {
type: Function,
default: () => {
}
},
placeholder: {
type: String,
default: ""
},
scrollAuto: {
type: Boolean
},
autofocus: {
type: Boolean
},
readonly: {
type: Boolean
},
maxlength: {
type: Number
},
autoDetectCode: {
type: Boolean
},
/**
* 输入框失去焦点时触发事件
*/
onBlur: {
type: Function,
default: () => {
}
},
/**
* 输入框获得焦点时触发事件
*/
onFocus: {
type: Function,
default: () => {
}
},
completions: {
type: Array
},
onInput: {
type: Function
},
onDrop: {
type: Function,
default: () => {
}
},
inputBoxWidth: {
type: String
},
oninputBoxWidthChange: {
type: Function
},
transformImgUrl: {
type: Function,
default: (e) => e
},
catalogLayout: {
type: String
},
catalogMaxDepth: {
type: Number
}
}, Ce = (e) => {
const r = new DOMParser().parseFromString(e, "text/html");
return Array.from(r.body.childNodes);
}, Ht = (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, Mt = /* @__PURE__ */ ce({
name: "UpdateOnDemand",
props: {
id: {
type: String,
required: !0
},
class: {
type: [String, Array, Object],
required: !0
},
html: {
type: String,
required: !0
}
},
setup(e) {
const t = G(), r = e.html, n = (o, u) => {
if (!t.value) return;
const c = t.value, m = Array.from(c.childNodes), s = Math.min(o.length, u.length);
let l = -1;
for (let a = 0; a < s; a++)
if (!Ht(o[a], u[a])) {
l = a;
break;
}
if (l === -1)
if (u.length > o.length)
l = o.length;
else if (o.length > u.length)
l = u.length;
else
return;
const i = Math.min(l, m.length);
for (let a = m.length - 1; a >= i; a--)
m[a].remove();
for (let a = l; a < o.length; a++)
c.appendChild(o[a].cloneNode(!0));
};
return E(() => e.html, (o, u) => {
const c = Ce(o), m = Ce(u || "");
n(c, m);
}), () => N("div", {
id: e.id,
class: e.class,
innerHTML: r,
ref: t
}, null);
}
}), Pt = /* @__PURE__ */ ce({
name: "ContentPreview",
props: Ie,
setup(e) {
const t = w("editorId"), r = w("setting"), n = w("previewTheme"), o = w("showCodeRowNumber"), {
html: u,
key: c
} = xt(e, e.previewOnly);
nt(e, u, c), Ft(e, u), Rt(e, u), At(e, u, c);
const m = R(() => [`${f}-preview`, `${n?.value}-theme`, o && `${f}-scrn`].filter(Boolean)), s = () => {
const l = `${t}-preview`;
return e.previewComponent ? He(e.previewComponent, {
key: c.value,
html: u.value,
id: l,
class: m.value
}) : N(Mt, {
key: c.value,
html: u.value,
id: l,
class: m.value
}, null);
};
return () => N(Ae, null, [r.value.preview && (e.previewOnly ? s() : N("div", {
id: `${t}-preview-wrapper`,
class: `${f}-preview-wrapper`,
key: "content-preview-wrapper"
}, [s()])), r.value.htmlPreview && N("div", {
id: `${t}-html-wrapper`,
class: `${f}-preview-wrapper`,
key: "html-preview-wrapper"
}, [N("div", {
class: `${f}-html`
}, [u.value])])]);
}
}), Lt = ({ text: e }) => e, Se = {
/**
* markdown content.
*
* @default ''
*/
modelValue: {
type: String,
default: ""
},
/**
* input回调事件
*/
onChange: {
type: Function,
default: void 0
},
/**
* 主题,支持light和dark
*
* @default 'light'
*/
theme: {
type: String,
default: "light"
},
/**
* 外层类名
*
* @default ''
*/
class: {
type: String,
default: ""
},
/**
* 预设语言名称
*
* @default 'zh-CN'
*/
language: {
type: String,
default: "zh-CN"
},
/**
* html变化事件
*/
onHtmlChanged: {
type: Function,
default: void 0
},
/**
* 获取目录结构
*/
onGetCatalog: {
type: Function,
default: void 0
},
/**
* 编辑器唯一标识
*
* @default 'md-editor-v3'
* @deprecated 5.x版本开始使用 id 替换
*/
editorId: {
type: String,
default: void 0
},
/**
* 5.x版本开始 editorId 的替换
*
* @default 'md-editor-v3'
*/
id: {
type: String,
default: void 0
},
/**
* 预览中代码是否显示行号
*
* @default true
*/
showCodeRowNumber: {
type: Boolean,
default: !0
},
/**
* 预览内容样式
*
* @default 'default'
*/
previewTheme: {
type: String,
default: "default"
},
/**
* 编辑器样式
*/
style: {
type: Object,
default: () => ({})
},
/**
* 标题的id生成方式
*
* @default (text: string) => text
*/
mdHeadingId: {
type: Function,
default: Lt
},
/**
*
* 不能保证文本正确的情况,在marked编译md文本后通过该方法处理
* 推荐DOMPurify、sanitize-html
*
* @default (text: string) => text
*/
sanitize: {
type: Function,
default: (e) => e
},
/**
* 不使用该mermaid
*
* @default false
*/
noMermaid: {
type: Boolean,
default: !1
},
/**
* 不使用katex
*
* @default false
*/
noKatex: {
type: Boolean,
default: !1
},
/**
* 代码主题
*
* @default 'atom'
*/
codeTheme: {
type: String,
default: "atom"
},
/**
* 复制代码格式化方法
*
* @default (text) => text
*/
formatCopiedText: {
type: Function,
default: (e) => e
},
/**
* 某些预览主题的代码模块背景是暗色系
* 将这个属性设置为true,会自动在该主题下的light模式下使用暗色系的代码风格
*
* @default true
*/
codeStyleReverse: {
type: Boolean,
default: !0
},
/**
* 需要自动调整的预览主题
*
* @default ['default', 'mk-cute']
*/
codeStyleReverseList: {
type: Array,
default: ["default", "mk-cute"]
},
noHighlight: {
type: Boolean,
default: !1
},
/**
* 是否关闭编辑器默认的放大缩小功能
*/
noImgZoomIn: {
type: Boolean,
default: !1
},
/**
* 自定义的图标
*/
customIcon: {
type: Object,
default: {}
},
sanitizeMermaid: {
type: Function,
default: (e) => Promise.resolve(e)
},
/**
* 是否开启折叠代码功能
* 不开启会使用div标签替代details标签
*
* @default true
*/
codeFoldable: {
type: Boolean,
default: !0
},
/**
* 触发自动折叠代码的行数阈值
*
* @default 30
*/
autoFoldThreshold: {
type: Number,
default: 30
},
/**
* 内容重新挂载事件
*
* 相比起onHtmlChanged,onRemount会在重新挂载后触发
*/
onRemount: {
type: Function,
default: void 0
},
/**
* 不使用 echarts
*/
noEcharts: {
type: Boolean,
default: !1
},
previewComponent: {
type: [Object, Function],
default: void 0
}
}, an = {
...Se,
/**
* input回调事件
*/
onSave: {
type: Function,
default: void 0
},
/**
* 上传图片事件
*/
onUploadImg: {
type: Function,
default: void 0
},
/**
* 是否页面内全屏
*
* @default false
*/
pageFullscreen: {
type: Boolean,
default: !1
},
/**
* 是否展开预览
*
* @default true
*/
preview: {
type: Boolean,
default: !0
},
/**
* 是否展开html预览
*
* @default false
*/
htmlPreview: {
type: Boolean,
default: !1
},
/**
* 仅预览模式,不显示toolbar和编辑框
*
* @4.0.0开始移除该设置,使用组件MdPreview替换
*
* @default false
*/
// previewOnly: {
// type: Boolean as PropType<boolean>,
// default: false
// },
/**
* 工具栏选择显示
*
* @default allToolbar
*/
toolbars: {
type: Array,
default: _e
},
/**
* 浮动工具栏
*
* @version 6.0.0
* @default []
*/
floatingToolbars: {
type: Array,
default: []
},
/**
* 工具栏选择不显示
*
* @default []
*/
toolbarsExclude: {
type: Array,
default: []
},
/**
* 格式化md
*
* @default true
*/
noPrettier: {
type: Boolean,
default: !1
},
/**
* 一个tab等于空格数
*
* @default 2
*/
tabWidth: {
type: Number,
default: 2
},
/**
* 表格预设格子数
*
* 也可以是[6, 4, 10, 8]
*
* @default [6, 4]
*/
tableShape: {
type: Array,
default: [6, 4]
},
/**
* 空提示
*
* @default ''
*/
placeholder: {
type: String,
default: ""
},
/**
* 自定义的工具栏列表
*/
defToolbars: {
type: [String, Object],
default: void 0
},
/**
* 内部错误捕获
*/
onError: {
type: Function,
default: void 0
},
/**
* 页脚列表显示顺序
*/
footers: {
type: Array,
default: Oe
},
/**
* 是否默认激活输入框和预览框同步滚动
*
* @default true
*/
scrollAuto: {
type: Boolean,
default: !0
},
/**
* 自定义的也叫工具组件列表
*/
defFooters: {
type: [String, Object],
default: void 0
},
/**
* 是否禁用上传图片
*
* @default false
*/
noUploadImg: {
type: Boolean,
default: !1
},
/**
* 文本区域自动获得焦点
*
* @default false
*/
autoFocus: {
type: Boolean,
default: !1
},
/**
* 禁用文本区域
*
* @default false
*/
disabled: {
type: Boolean,
default: !1
},
/**
* 文本区域为只读
*
* @default false
*/
readOnly: {
type: Boolean,
default: !1
},
/**
* 文本区域允许的最大字符数
*/
maxLength: {
type: Number,
default: void 0
},
/**
* 是否启用自动识别粘贴代码类别
* 目前支持 vscode 复制的代码识别
*
* @default false
*/
autoDetectCode: {
type: Boolean,
default: !1
},
/**
* 输入框失去焦点时触发事件
*/
onBlur: {
type: Function,
default: void 0
},
/**
* 输入框获得焦点时触发事件
*/
onFocus: {
type: Function,
default: void 0
},
/**
* @codemirror/autocomplete匹配关键词的方法列表
*
* 它会被像下面这样嵌入编辑器
*
* import { autocompletion } from '@codemirror/autocomplete';
* autocompletion({
* override: [...completions]
* })
*/
completions: {
type: Array,
default: void 0
},
/**
* 是否在工具栏下面显示对应的文字名称
*
* @default false
*/
showToolbarName: {
type: Boolean,
default: !1
},
/**
* 字符输入事件
*/
onInput: {
type: Function,
default: void 0
},
onDrop: {
type: Function,
default: void 0
},
/**
* 输入框的默认宽度
*
* @example '100px'/'50%'
* @default '50%
*/
inputBoxWidth: {
type: String,
default: "50%"
},
/**
* 输入框宽度变化事件
*/
oninputBoxWidthChange: {
type: Function,
default: void 0
},
/**
* 替换粘贴的图片链接
*
* @param t 图片链接
* @returns
*/
transformImgUrl: {
type: Function,
default: (e) => e
},
/**
* 内置的目录显示的状态
*
* 'fixed': 悬浮在内容上方
* 'flat': 展示在右侧
*
* \>=5.3.0
*
* @default 'fixed'
*/
catalogLayout: {
type: String,
default: "fixed"
},
/**
* 控制最大显示的目录层级
*/
catalogMaxDepth: {
type: Number,
default: void 0
}
}, xe = [
"onHtmlChanged",
"onGetCatalog",
"onChange",
"onRemount",
"update:modelValue"
], rn = [
...xe,
"onSave",
"onUploadImg",
"onError",
"onBlur",
"onFocus",
"onInput",
"onDrop",
"oninputBoxWidthChange"
], Ot = (e, t, r) => {
const { editorId: n } = r, o = {
rerender() {
y.emit(n, de);
}
};
t.expose(o);
}, ae = /* @__PURE__ */ ce({
name: "MdPreview",
props: Se,
emits: xe,
setup(e, t) {
const {
noKatex: r,
noMermaid: n,
noHighlight: o
} = e, u = G(), c = tt(e);
Te(e, {
rootRef: u,
editorId: c
}), Ot(e, t, {
editorId: c
}), te(() => {
y.clear(c);
});
const m = (a) => {
e.onChange?.(a), t.emit("onChange", a), t.emit("update:modelValue", a);
}, s = (a) => {
e.onHtmlChanged?.(a), t.emit("onHtmlChanged", a);
}, l = (a) => {
e.onGetCatalog?.(a), t.emit("onGetCatalog", a);
}, i = () => {
e.onRemount?.(), t.emit("onRemount");
};
return () => N("div", {
id: c,
class: [f, e.class, e.theme === "dark" && `${f}-dark`, `${f}-previewOnly`],
style: e.style,
ref: u
}, [N(Pt, {
modelValue: e.modelValue,
onChange: m,
onHtmlChanged: s,
onGetCatalog: l,
mdHeadingId: e.mdHeadingId,
noMermaid: n,
sanitize: e.sanitize,
noKatex: r,
formatCopiedText: e.formatCopiedText,
noHighlight: o,
noImgZoomIn: e.noImgZoomIn,
previewOnly: !0,
sanitizeMermaid: e.sanitizeMermaid,
codeFoldable: e.codeFoldable,
autoFoldThreshold: e.autoFoldThreshold,
onRemount: i,
noEcharts: e.noEcharts,
previewComponent: e.previewComponent
}, null)]);
}
});
ae.install = (e) => (e.component(ae.name, ae), e);
export {
M as C,
ae as M,
Pt as a,
an as b,
on as c,
en as d,
rn as e,
tn as f,
Jt as g,
Yt as h,
Qt as i,
nn as j,
Xt as k,
tt as u
};