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,901 lines (1,900 loc) 91.7 kB
import { jsxs as $, jsx as a, Fragment as tt } from "react/jsx-runtime"; import { memo as I, useRef as D, useCallback as L, useEffect as A, useContext as x, useState as F, useMemo as M, cloneElement as ot, createContext as vt, useSyncExternalStore as Tt, forwardRef as rt, useImperativeHandle as wt } from "react"; import { p as n, g as X, a as $t, M as ce, b as Ct, d as N } from "./config.mjs"; import { linkTo as xt, createSmoothScroll as nt, draggingScroll as yt } from "@vavt/util"; import { c as S, b as kt } from "./index2.mjs"; import { E as C, d as Nt } from "./context.mjs"; import { s as St, a as It, M as Et } from "./index3.mjs"; import { C as Lt, a as At, u as Dt, b as Rt, c as Mt, d as Ft, e as Ht, f as Pt, g as Ot, h as Vt } from "./hooks.mjs"; import { deleteLine as Bt, defaultKeymap as zt, historyKeymap as Wt, indentWithTab as _t, history as Me, undo as qt, redo as Kt } from "@codemirror/commands"; import { markdown as Ut } from "@codemirror/lang-markdown"; import { languages as Gt } from "@codemirror/language-data"; import { EditorState as he, EditorSelection as te, Compartment as Y, StateEffect as at, StateField as lt, RangeSetBuilder as jt } from "@codemirror/state"; import { placeholder as Zt, EditorView as U, showTooltip as Yt, Decoration as Xt, WidgetType as Jt, keymap as Qt, drawSelection as eo } from "@codemirror/view"; import { b as h, E as oe, R as w, U as Ce, O as it, C as to, a as Te, c as we, d as Fe, e as He, T as Pe, S as Oe, G as Ve } from "./event-bus.mjs"; import { indentUnit as oo, syntaxHighlighting as st, HighlightStyle as ct } from "@codemirror/language"; import { autocompletion as ro } from "@codemirror/autocomplete"; import { searchKeymap as no } from "@codemirror/search"; import { createRoot as ao } from "react-dom/client"; import { a as lo } from "./dom.mjs"; import { I as E, M as io } from "./index.mjs"; import { D as ie } from "./index4.mjs"; import { tags as u } from "@lezer/highlight"; const so = (e) => { const t = D(null), r = D(null), o = D(null), l = D(null), i = D(!1), s = D(0), c = D(0), m = L(() => { if (!r.current || !t.current || !o.current || !l.current) return; const v = t.current.clientHeight, y = r.current.scrollHeight, H = r.current.scrollTop; if (y <= v) { o.current.style.display = "none", e.alwaysShowTrack || (l.current.style.display = "none"); return; } else o.current.style.display = "block", l.current.style.display = "block"; const B = v / y, _ = Math.max(v * B, 20), W = v - _, O = Math.min(H * B, W); o.current.style.height = `${_}px`, o.current.style.top = `${O}px`; }, [e.alwaysShowTrack]), d = m, b = L((v) => { i.current = !0, s.current = v.clientY, c.current = r.current.scrollTop, document.body.style.userSelect = "none"; }, []), g = L( (v) => { if (!i.current || !r.current || !t.current) return; const y = v.clientY - s.current, H = r.current.scrollHeight / t.current.clientHeight; r.current.scrollTop = c.current + y * H; }, [c, s] ), f = L(() => { i.current = !1, document.body.style.userSelect = ""; }, []), p = L( (v) => { r.current && r.current.removeEventListener("scroll", d), r.current = v, r.current ? (r.current.addEventListener("scroll", d), m()) : l.current && !e.alwaysShowTrack && (l.current.style.display = "none"); }, [d, e.alwaysShowTrack, m] ), k = L(() => { if (!t.current) return; const v = e.scrollTarget ? t.current.querySelector(e.scrollTarget) : t.current.firstElementChild; p(v); }, [p, e.scrollTarget]); return A(() => { k(); const v = o.current; let y = null; const H = new MutationObserver(() => { y && cancelAnimationFrame(y), y = requestAnimationFrame(() => { k(); }); }); return H.observe(t.current, { childList: !0, subtree: !0 }), window.addEventListener("resize", m), v?.addEventListener("mousedown", b), document.addEventListener("mousemove", g), document.addEventListener("mouseup", f), () => { H?.disconnect(), r.current && r.current.removeEventListener("scroll", d), window.removeEventListener("resize", m), v?.removeEventListener("mousedown", b), document.removeEventListener("mousemove", g), document.removeEventListener("mouseup", f); }; }, [k, b, g, f, d, m]), /* @__PURE__ */ $( "div", { id: e.id, className: S([`${n}-custom-scrollbar`, e.className]), style: e.style, ref: t, onMouseEnter: e.onMouseEnter, onMouseLeave: e.onMouseLeave, children: [ e.children, /* @__PURE__ */ a("div", { className: `${n}-custom-scrollbar__track`, ref: l, children: /* @__PURE__ */ a("div", { className: `${n}-custom-scrollbar__thumb`, ref: o }) }) ] } ); }, ge = I(so), co = (e, t, r) => { const { editorId: o, setting: l } = x(C), [i, s] = F({ clear() { }, init() { } }); A(() => { const c = r.current?.view.contentDOM.getRootNode(), m = c?.querySelector( `#${o} .cm-scroller` ), d = c?.querySelector( `[id="${o}-preview-wrapper"]` ), b = c?.querySelector( `[id="${o}-html-wrapper"]` ); if (d || b) { const g = d ? St : It, f = d || b, [p, k] = g(m, f, r.current); s({ init: p, clear: k }); } }, [ t, l.fullscreen, l.pageFullscreen, l.preview, l.htmlPreview, o, r ]), A(() => (e.scrollAuto && !l.previewOnly && (l.preview || l.htmlPreview) ? i.init() : i.clear(), () => { i.clear(); }), [ i, e.scrollAuto, l.preview, l.htmlPreview, l.previewOnly ]); }, fe = async (e, t, r) => { if (/^h[1-6]$/.test(e)) return uo(e, t); if (e === "prettier") return await mo(t, r); switch (e) { case "bold": case "underline": case "italic": case "strikeThrough": case "sub": case "sup": case "codeRow": case "katexInline": case "katexBlock": return ho(e, t); case "quote": case "orderedList": case "unorderedList": case "task": return fo(e, t); case "code": return po(r, t); case "table": return wo(r); case "link": { const { desc: o = "", url: l = "" } = r, i = `[${o}](${l})`; return { text: i, options: { select: l === "", deviationStart: i.length - l.length - 1, deviationEnd: -1 } }; } case "image": return To(r); case "flow": case "sequence": case "gantt": case "class": case "state": case "pie": case "relationship": case "journey": return vo(e); case "universal": return $o(t.getSelectedText(), r); default: return { text: "", options: {} }; } }, uo = (e, t) => { const r = e.slice(1), o = "#".repeat(Number(r)), [l, i, s] = xe(t, { wholeLine: !0 }); return { text: `${o} ${l}`, options: { deviationStart: o.length + 1, replaceStart: i, replaceEnd: s } }; }, mo = async (e, t) => { const r = window.prettier || X.editorExtensions.prettier?.prettierInstance, o = [ window.prettierPlugins?.markdown || X.editorExtensions.prettier?.parserMarkdownInstance ]; return !r || !o[0] ? (h.emit(t.editorId, oe, { name: "prettier", message: "prettier is undefined" }), { text: e.getValue(), options: { select: !1, replaceAll: !0 } }) : { text: await r.format(e.getValue(), { parser: "markdown", plugins: o }), options: { select: !1, replaceAll: !0 } }; }, bo = { bold: ["**", "**", 2, -2], underline: ["<u>", "</u>", 3, -4], italic: ["*", "*", 1, -1], strikeThrough: ["~~", "~~", 2, -2], sub: ["~", "~", 1, -1], sup: ["^", "^", 1, -1], codeRow: ["`", "`", 1, -1], katexInline: ["$", "$", 1, -1], katexBlock: [` $$ `, ` $$ `, 4, -4] }, ho = (e, t) => { const r = t.getSelectedText(), [o, l, i, s] = bo[e]; return { text: `${o}${r}${l}`, options: { deviationStart: i, deviationEnd: s // replaceStart, replaceEnd } }; }, go = { quote: "> ", unorderedList: "- ", orderedList: 1, task: "- [ ] " }, fo = (e, t) => { const [r, o, l] = xe(t, { wholeLine: !0 }), i = r.split(` `), s = go[e], c = e === "orderedList" ? i.map((b, g) => `${s + g}. ${b}`) : i.map((b) => `${s}${b}`), m = e === "orderedList" ? "1. " : s.toString(), d = i.length === 1 ? m.length : 0; return { text: c.join(` `), options: { deviationStart: d, replaceStart: o, replaceEnd: l } }; }, po = (e, t) => { const [r, o, l] = xe(t), i = e.mode || "language", s = ` \`\`\`${i} ${e.text || r || ""} \`\`\` `; return { text: s, options: { deviationStart: 4, deviationEnd: 4 + i.length - s.length, replaceStart: o, replaceEnd: l } }; }, vo = (e) => ({ text: ` \`\`\`mermaid ${{ flow: `flowchart TD Start --> Stop`, sequence: `sequenceDiagram A->>B: hello! B-->>A: hi!`, gantt: `gantt title Gantt Chart dateFormat YYYY-MM-DD`, class: `classDiagram class Animal`, state: `stateDiagram-v2 s1 --> s2`, pie: `pie "Dogs" : 386 "Cats" : 85 "Rats" : 15`, relationship: `erDiagram CAR ||--o{ NAMED-DRIVER : allows`, journey: `journey title My Journey`, ...X.editorConfig.mermaidTemplate }[e]} \`\`\` `, options: { deviationStart: 12, deviationEnd: -5 } }), To = (e) => { const { desc: t = "", url: r = "", urls: o } = e; let l = ""; const i = r === "" && (!o || o instanceof Array && o.length === 0); return o instanceof Array ? l = o.reduce((s, c) => { const { url: m = "", alt: d = "", title: b = "" } = typeof c == "object" ? c : { url: c }; return s + `![${d}](${m}${b ? " '" + b + "'" : ""}) `; }, "") : l = `![${t}](${r}) `, { text: l, options: { select: r === "", deviationStart: i ? l.length - r.length - 2 : l.length, deviationEnd: i ? -2 : 0 } }; }, wo = (e) => { const { selectedShape: t = { x: 1, y: 1 } } = e, { x: r, y: o } = t; let l = ` | Column`; for (let i = 0; i <= o; i++) l += " |"; l += ` |`; for (let i = 0; i <= o; i++) l += " - |"; for (let i = 0; i <= r; i++) { l += ` |`; for (let s = 0; s <= o; s++) l += " |"; } return l += ` `, { text: l, options: { deviationStart: 3, deviationEnd: 10 - l.length } }; }, $o = (e, t) => { const { generate: r } = t, o = r(e); return { text: o.targetValue, options: { select: o.select ?? !0, deviationStart: o.deviationStart || 0, deviationEnd: o.deviationEnd || 0 } }; }, xe = (e, t = { wholeLine: !1 }) => { const r = e.view.state, o = r.selection.main; if (o.empty) { const l = r.doc.lineAt(o.from); return [r.doc.lineAt(o.from).text, l.from, l.to]; } else if (t.wholeLine) { const l = r.doc.lineAt(o.from), i = r.doc.lineAt(o.to); return [ r.doc.sliceString(l.from, i.to), l.from, i.to ]; } return [ r.doc.sliceString(o.from, o.to), o.from, o.to ]; }, ee = (e) => { const t = new Y(); return (o) => (t.get(e.state) ? e.dispatch({ effects: t.reconfigure(o) }) : e.dispatch({ effects: at.appendConfig.of(t.of(o)) }), !0); }; class Co { view; maxLength = Number.MAX_SAFE_INTEGER; // 切换tabSize的执行方法。切换时,Compartment实例需要相同 toggleTabSize; togglePlaceholder; /** * 设置全部的扩展 */ setExtensions; toggleDisabled; toggleReadOnly; toggleMaxlength; getValue() { return this.view.state.doc.toString(); } /** * 设置内容 * * @param insert 待插入内容 * @param from 插入开始位置 * @param to 插入结束位置 */ setValue(t, r = 0, o = this.view.state.doc.length) { this.view.dispatch({ changes: { from: r, to: o, insert: t } }); } /** * 获取选中的文本 */ getSelectedText() { const { from: t, to: r } = this.view.state.selection.main; return this.view.state.sliceDoc(t, r); } /** * 使用新的内容替换选中的内容 * * @param text 待替换内容 * @param options 替换后是否选中 */ replaceSelectedText(t, r, o) { const l = { // 是否选中 select: !0, // 选中时,开始位置的偏移量 deviationStart: 0, // 结束的偏移量 deviationEnd: 0, // 直接替换所有文本 replaceAll: !1, // 替换旧文本的开始位置 replaceStart: -1, // 替换旧文本的结束位置 replaceEnd: -1, ...r }; try { if (l.replaceAll) { if (this.setValue(t), t.length > this.maxLength) throw new Error("The input text is too long"); return; } if (this.view.state.doc.length - this.getSelectedText().length + t.length > this.maxLength) throw new Error("The input text is too long"); const { from: i } = this.view.state.selection.main; l.replaceStart !== -1 ? this.view.dispatch({ changes: { from: l.replaceStart, to: l.replaceEnd, insert: t } }) : this.view.dispatch(this.view.state.replaceSelection(t)), l.select && this.view.dispatch({ selection: { anchor: l.replaceStart === -1 ? i + l.deviationStart : l.replaceStart + l.deviationStart, head: l.replaceStart === -1 ? i + t.length + l.deviationEnd : l.replaceStart + t.length + l.deviationEnd } }), this.view.focus(); } catch (i) { if (i.message === "The input text is too long") h.emit(o, oe, { name: "overlength", message: i.message, data: t }); else throw i; } } constructor(t) { this.view = t, this.toggleTabSize = ee(this.view), this.togglePlaceholder = ee(this.view), this.setExtensions = ee(this.view), this.toggleDisabled = ee(this.view), this.toggleReadOnly = ee(this.view), this.toggleMaxlength = ee(this.view); } /** * 设置tabSize * * @param tabSize 需要切换的大小 */ setTabSize(t) { this.toggleTabSize([ he.tabSize.of(t), oo.of(" ".repeat(t)) ]); } /** * 设置placeholder * * @param t 目标内容 */ setPlaceholder(t) { this.togglePlaceholder(Zt(t)); } focus(t) { if (this.view.focus(), !t) return; let r = 0, o = 0, l = 0; switch (t) { case "start": break; case "end": { r = o = l = this.getValue().length; break; } default: r = t.rangeAnchor || t.cursorPos, o = t.rangeHead || t.cursorPos, l = t.cursorPos; } this.view.dispatch({ scrollIntoView: !0, selection: te.create( [te.range(r, o), te.cursor(l)], 1 ) }); } setDisabled(t) { this.toggleDisabled([U.editable.of(!t)]); } setReadOnly(t) { this.toggleReadOnly([he.readOnly.of(t)]); } setMaxLength(t) { this.maxLength = t, this.toggleMaxlength([ he.changeFilter.of((r) => r.newDoc.length <= t) ]); } } const xo = (e, t) => { const { editorId: r } = x(C), o = L( (i) => { i instanceof Promise ? i.then((s) => { h.emit(r, w, "universal", { generate() { return { targetValue: s }; } }); }).catch((s) => { console.error(s); }) : h.emit(r, w, "universal", { generate() { return { targetValue: i }; } }); }, [r] ); return L( (i) => { if (!i.clipboardData) return; if (i.clipboardData.files.length > 0) { const { files: f } = i.clipboardData; h.emit( r, Ce, Array.from(f).filter((p) => /image\/.*/.test(p.type)) ), i.preventDefault(); return; } const s = i.clipboardData.getData("text/plain"), c = t.current?.view.state.selection.main.to || 0, m = t.current?.view.state.doc.lineAt(c).from || 0, d = t.current?.view.state.doc.sliceString(m, c) || "", b = /!\[.*\]\(\s*$/.test(d), g = /!\[.*\]\((.*)\s?.*\)/.test(s); if (b) { const f = e.transformImgUrl(s); o(f), i.preventDefault(); return; } else if (g) { const f = s.match( new RegExp(`(?<=!\\[.*\\]\\()([^)\\s]+)(?=\\s?["']?.*["']?\\))`, "g") ); f ? Promise.all( f.map((p) => e.transformImgUrl(p)) ).then((p) => { o( p.reduce((k, v, y) => k.replace(f[y], v), s) ); }).catch((p) => { console.error(p); }) : o(s), i.preventDefault(); return; } if (e.autoDetectCode && i.clipboardData.types.includes("vscode-editor-data")) { const f = JSON.parse(i.clipboardData.getData("vscode-editor-data")); h.emit(r, w, "code", { mode: f.mode, text: i.clipboardData.getData("text/plain") }), i.preventDefault(); return; } e.maxLength && s.length + e.modelValue.length > e.maxLength && h.emit(r, oe, { name: "overlength", message: "The input text is too long", data: s }); }, [t, r, o, e] ); }, de = (e, t, r, o, l) => (i, s, c, m) => { const d = `${e}${t}${r}${o}`, b = c + s.label.length + (l === "title" ? r.length : 0); i.dispatch({ changes: { from: c, to: m, insert: d }, selection: te.create( [ te.range( c + s.label.length + (l === "title" ? 1 : -t.length), b ), te.cursor(b) ], 1 ) }), i.focus(); }, Be = (e) => (t, r, o, l) => { const i = e.slice(l - o); t.dispatch(t.state.replaceSelection(`${i} `)); }, ze = (e) => { const t = (r) => { const o = r.matchBefore( /^#+|^-\s*\[*\s*\]*|`+|\[|!\[*|^\|\s?\|?|\$\$?|!+\s*\w*/ ); return o === null || o.from == o.to && r.explicit ? null : { from: o.from, options: [ // 标题 ...["h2", "h3", "h4", "h5", "h6"].map((l, i) => { const s = new Array(i + 2).fill("#").join(""); return { label: s, type: "text", apply: Be(s) }; }), // 任务列表 ...["unchecked", "checked"].map((l) => { const i = l === "checked" ? "- [x]" : "- [ ]"; return { label: i, type: "text", apply: Be(i) }; }), // 代码 ...[ ["`", ""], ["```", "language"], ["```mermaid\n", ""], ["```echarts\n", ""] ].map((l) => ({ label: `${l[0]}${l[1]}`, type: "text", apply: de(l[0], l[1], "", l[0] === "`" ? "`" : "\n```", "type") })), // 链接 { label: "[]()", type: "text" }, { label: "![]()", type: "text" }, // 表格 { label: "| |", type: "text", detail: "table", apply: `| col | col | col | | - | - | - | | content | content | content | | content | content | content |` }, // 公式 { label: "$", type: "text", apply: de("$", "", "", "$", "type") }, { label: "$$", type: "text", apply: de("$$", "", ` `, ` $$`, "title") }, // 那啥? ...[ "note", "abstract", "info", "tip", "success", "question", "warning", "failure", "danger", "bug", "example", "quote", "hint", "caution", "error", "attention" ].map((l) => ({ label: `!!! ${l}`, type: "text", apply: de("!!!", ` ${l}`, " Title", ` !!!`, "title") })) ] }; }; return ro({ override: e ? [t, ...e] : [t] }); }, yo = (e, t) => [ { key: "Ctrl-b", mac: "Cmd-b", run: () => (h.emit(e, w, "bold"), !0) }, { key: "Ctrl-d", mac: "Cmd-d", run: Bt, preventDefault: !0 }, { key: "Ctrl-s", mac: "Cmd-s", run: (W) => (h.emit(e, it, W.state.doc.toString()), !0), shift: () => (h.emit(e, w, "strikeThrough"), !0) }, { key: "Ctrl-u", mac: "Cmd-u", preventDefault: !0, run: () => (h.emit(e, w, "underline"), !0), shift: () => (h.emit(e, w, "unorderedList"), !0) }, { key: "Ctrl-i", mac: "Cmd-i", preventDefault: !0, run: () => (h.emit(e, w, "italic"), !0), shift: () => (h.emit(e, w, "image"), !0) }, { key: "Ctrl-1", mac: "Cmd-1", run: () => (h.emit(e, w, "h1"), !0) }, { key: "Ctrl-2", mac: "Cmd-2", run: () => (h.emit(e, w, "h2"), !0) }, { key: "Ctrl-3", mac: "Cmd-3", run: () => (h.emit(e, w, "h3"), !0) }, { key: "Ctrl-4", mac: "Cmd-4", run: () => (h.emit(e, w, "h4"), !0) }, { key: "Ctrl-5", mac: "Cmd-5", run: () => (h.emit(e, w, "h5"), !0) }, { key: "Ctrl-6", mac: "Cmd-6", run: () => (h.emit(e, w, "h6"), !0) }, { key: "Ctrl-ArrowUp", mac: "Cmd-ArrowUp", run: () => (h.emit(e, w, "sup"), !0) }, { key: "Ctrl-ArrowDown", mac: "Cmd-ArrowDown", run: () => (h.emit(e, w, "sub"), !0) }, { key: "Ctrl-o", mac: "Cmd-o", run: () => (h.emit(e, w, "orderedList"), !0) }, { key: "Ctrl-c", mac: "Cmd-c", shift: () => (h.emit(e, w, "code"), !0), any(W, O) { return (O.ctrlKey || O.metaKey) && O.altKey && O.code === "KeyC" ? (h.emit(e, w, "codeRow"), !0) : !1; } }, { key: "Ctrl-l", mac: "Cmd-l", run: () => (h.emit(e, w, "link"), !0) }, { key: "Ctrl-f", mac: "Cmd-f", shift: () => t.noPrettier ? !1 : (h.emit(e, w, "prettier"), !0) }, { any: (W, O) => (O.ctrlKey || O.metaKey) && O.altKey && O.shiftKey && O.code === "KeyT" ? (h.emit(e, w, "table"), !0) : !1 }, ...no ], ko = () => /* @__PURE__ */ a("div", { className: `${n}-divider` }), No = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.bold, disabled: o, onClick: () => { h.emit(e, w, "bold"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "bold" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.bold }) ] } ); }, So = I(No), Io = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o, catalogVisible: l } = x(C); return /* @__PURE__ */ $( "button", { className: S([ `${n}-toolbar-item`, l && `${n}-toolbar-active`, o && `${n}-disabled` ]), title: t.toolbarTips?.catalog, disabled: o, onClick: () => { h.emit(e, to); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "catalog" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.catalog }) ] }, "bar-catalog" ); }, Eo = I(Io), Lo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.code, disabled: o, onClick: () => { h.emit(e, w, "code"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "code" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.code }) ] } ); }, Ao = I(Lo), Do = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.codeRow, disabled: o, onClick: () => { h.emit(e, w, "codeRow"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "code-row" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.codeRow }) ] } ); }, Ro = I(Do), Mo = () => { const { setting: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C), { fullscreenHandler: l } = Fr(); return /* @__PURE__ */ $( "button", { className: S([ `${n}-toolbar-item`, e.fullscreen && `${n}-toolbar-active`, o && `${n}-disabled` ]), title: t.toolbarTips?.fullscreen, disabled: o, onClick: () => { l(); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: e.fullscreen ? "fullscreen-exit" : "fullscreen" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.fullscreen }) ] } ); }, Fo = I(Mo), Ho = () => { const { usedLanguageText: e, showToolbarName: t, disabled: r } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, r && `${n}-disabled`]), title: e.toolbarTips?.github, disabled: r, onClick: () => { xt("https://github.com/imzbf/md-editor-v3"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "github" }), t && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: e.toolbarTips?.github }) ] } ); }, Po = I(Ho), Oo = () => { const { usedLanguageText: e, setting: t, updateSetting: r, showToolbarName: o, disabled: l } = x(C); return /* @__PURE__ */ $( "button", { className: S([ `${n}-toolbar-item`, t.htmlPreview && `${n}-toolbar-active`, l && `${n}-disabled` ]), title: e.toolbarTips?.htmlPreview, disabled: l, onClick: () => { r("htmlPreview"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "preview-html" }), o && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: e.toolbarTips?.htmlPreview }) ] } ); }, Vo = I(Oo), Bo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.image, disabled: o, onClick: () => { h.emit(e, w, "image"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "image" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.image }) ] } ); }, zo = I(Bo); let Z = null; const Wo = (e) => { const t = x(C), { editorId: r, usedLanguageText: o, rootRef: l } = t, i = X.editorExtensions.cropper.instance, s = D(null), c = D(null), m = D(null), [d, b] = F({ cropperInited: !1, imgSelected: !1, imgSrc: "", // 是否全屏 isFullscreen: !1 }); A(() => { e.visible && !d.cropperInited && (window.Cropper = i || window.Cropper, s.current.onchange = () => { if (!window.Cropper) { h.emit(r, oe, { name: "Cropper", message: "Cropper is undefined" }); return; } const k = s.current.files || []; if (k?.length > 0) { const v = new FileReader(); v.onload = (y) => { b((H) => ({ ...H, imgSelected: !0, imgSrc: y.target.result })); }, v.readAsDataURL(k[0]); } }); }, [e.visible, d.cropperInited, i, r]), A(() => { m.current?.setAttribute("style", ""); }, [d.imgSelected]), A(() => { Z?.destroy(), m.current?.setAttribute("style", ""), c.current && d.imgSrc && (Z = new window.Cropper(c.current, { viewMode: 2, preview: (l.current?.getRootNode()).querySelector( `.${n}-clip-preview-target` ) })); }, [d.imgSrc, d.isFullscreen, l]); const g = M(() => d.isFullscreen ? { width: "100%", height: "100%" } : { width: "668px", height: "392px" }, [d.isFullscreen]), f = () => { Z.clear(), Z.destroy(), Z = null, s.current.value = "", b((k) => ({ ...k, imgSrc: "", imgSelected: !1 })); }, p = L((k) => { b((v) => ({ ...v, isFullscreen: k })); }, []); return M(() => /* @__PURE__ */ $( io, { className: `${n}-modal-clip`, title: o.clipModalTips?.title, visible: e.visible, onClose: e.onCancel, showAdjust: !0, isFullscreen: d.isFullscreen, onAdjust: p, ...g, children: [ /* @__PURE__ */ $("div", { className: `${n}-form-item ${n}-clip`, children: [ /* @__PURE__ */ a("div", { className: `${n}-clip-main`, children: d.imgSelected ? /* @__PURE__ */ $("div", { className: `${n}-clip-cropper`, children: [ /* @__PURE__ */ a( "img", { src: d.imgSrc, ref: c, style: { display: "none" }, alt: "" } ), /* @__PURE__ */ a("div", { className: `${n}-clip-delete`, onClick: f, children: /* @__PURE__ */ a(E, { name: "delete" }) }) ] }) : /* @__PURE__ */ a( "div", { className: `${n}-clip-upload`, onClick: () => { s.current.click(); }, role: "button", tabIndex: 0, "aria-label": o.imgTitleItem?.upload, children: /* @__PURE__ */ a(E, { name: "upload" }) } ) }), /* @__PURE__ */ a("div", { className: `${n}-clip-preview`, children: /* @__PURE__ */ a("div", { className: `${n}-clip-preview-target`, ref: m }) }) ] }), /* @__PURE__ */ a("div", { className: `${n}-form-item`, children: /* @__PURE__ */ a( "button", { className: `${n}-btn`, type: "button", onClick: () => { if (Z) { const k = Z.getCroppedCanvas(); h.emit( r, Ce, [kt(k.toDataURL("image/png"))], e.onOk ), f(); } }, children: o.linkModalTips?.buttonOK } ) }), /* @__PURE__ */ a( "input", { ref: s, accept: "image/*", type: "file", multiple: !1, style: { display: "none" }, "aria-hidden": "true" } ) ] } ), [ o.clipModalTips?.title, o.linkModalTips?.buttonOK, o.imgTitleItem?.upload, e.visible, e.onCancel, e.onOk, d.isFullscreen, d.imgSelected, d.imgSrc, p, g, r ]); }, _o = (e) => /* @__PURE__ */ a(Wo, { visible: e.clipVisible, onOk: e.onOk, onCancel: e.onCancel }), qo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C), l = `${e}-toolbar-wrapper`, [i, s] = F(!1), [c, m] = F(!1), d = D(null), b = L(() => { h.emit(e, Ce, Array.from(d.current?.files || [])), d.current.value = ""; }, [e]), g = L( (y, H) => { o || h.emit(e, w, y, H); }, [e, o] ), f = L(() => { s(!1); }, []), p = L( (y) => { y && g("image", { desc: y.desc, url: y.url, transform: !0 }), m(!1); }, [g] ), k = M(() => /* @__PURE__ */ $( "ul", { className: `${n}-menu`, onClick: () => { s(!1); }, role: "menu", children: [ /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-image`, onClick: () => { g("image"); }, role: "menuitem", tabIndex: 0, children: t.imgTitleItem?.link } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-image`, onClick: () => { d.current?.click(); }, role: "menuitem", tabIndex: 0, children: t.imgTitleItem?.upload } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-image`, onClick: () => { m(!0); }, role: "menuitem", tabIndex: 0, children: t.imgTitleItem?.clip2upload } ) ] } ), [ g, t.imgTitleItem?.clip2upload, t.imgTitleItem?.link, t.imgTitleItem?.upload ]), v = M(() => /* @__PURE__ */ $( "button", { className: S([ `${n}-toolbar-item`, o && `${n}-disabled` ]), title: t.toolbarTips?.image, disabled: o, type: "button", children: [ /* @__PURE__ */ a(E, { name: "image" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.image }) ] } ), [o, r, t.toolbarTips?.image]); return A(() => { const y = d.current; return y?.addEventListener("change", b), () => { y?.removeEventListener("change", b); }; }, [b]), /* @__PURE__ */ $(tt, { children: [ /* @__PURE__ */ a( "label", { htmlFor: `${l}_label`, style: { display: "none" }, "aria-label": t.imgTitleItem?.upload } ), /* @__PURE__ */ a( "input", { id: `${l}_label`, ref: d, accept: "image/*", type: "file", multiple: !0, style: { display: "none" } } ), /* @__PURE__ */ a(_o, { clipVisible: c, onCancel: f, onOk: p }), /* @__PURE__ */ a( ie, { relative: `#${l}`, visible: i, onChange: s, disabled: o, overlay: k, children: v } ) ] }); }, Ko = I(qo), Uo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.italic, disabled: o, onClick: () => { h.emit(e, w, "italic"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "italic" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.italic }) ] } ); }, Go = I(Uo), jo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C), l = `${e}-toolbar-wrapper`, [i, s] = F(!1), c = L( (b) => { o || h.emit(e, w, b); }, [o, e] ), m = M(() => /* @__PURE__ */ $( "ul", { className: `${n}-menu`, onClick: () => { s(!1); }, role: "menu", children: [ /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-katex`, onClick: () => { c("katexInline"); }, role: "menuitem", tabIndex: 0, children: t.katex?.inline } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-katex`, onClick: () => { c("katexBlock"); }, role: "menuitem", tabIndex: 0, children: t.katex?.block } ) ] } ), [c, t.katex?.block, t.katex?.inline]), d = M(() => /* @__PURE__ */ $( "button", { className: S([ `${n}-toolbar-item`, o && `${n}-disabled` ]), title: t.toolbarTips?.katex, disabled: o, type: "button", children: [ /* @__PURE__ */ a(E, { name: "formula" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.katex }) ] } ), [o, r, t.toolbarTips?.katex]); return /* @__PURE__ */ a( ie, { relative: `#${l}`, visible: i, onChange: s, disabled: o, overlay: m, children: d }, "bar-katex" ); }, Zo = I(jo), Yo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.link, disabled: o, onClick: () => { h.emit(e, w, "link"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "link" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.link }) ] } ); }, Xo = I(Yo), Jo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C), l = `${e}-toolbar-wrapper`, [i, s] = F(!1), c = L( (b) => { o || h.emit(e, w, b); }, [o, e] ), m = M(() => /* @__PURE__ */ $( "ul", { className: `${n}-menu`, onClick: () => { s(!1); }, role: "menu", children: [ /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { c("flow"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.flow } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { c("sequence"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.sequence } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { c("gantt"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.gantt } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { c("class"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.class } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { c("state"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.state } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { c("pie"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.pie } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { c("relationship"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.relationship } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { c("journey"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.journey } ) ] } ), [ c, t.mermaid?.class, t.mermaid?.flow, t.mermaid?.gantt, t.mermaid?.journey, t.mermaid?.pie, t.mermaid?.relationship, t.mermaid?.sequence, t.mermaid?.state ]), d = M(() => /* @__PURE__ */ $( "button", { className: S([ `${n}-toolbar-item`, o && `${n}-disabled` ]), title: t.toolbarTips?.mermaid, disabled: o, type: "button", children: [ /* @__PURE__ */ a(E, { name: "mermaid" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.mermaid }) ] } ), [o, r, t.toolbarTips?.mermaid]); return /* @__PURE__ */ a( ie, { relative: `#${l}`, visible: i, onChange: s, disabled: o, overlay: m, children: d }, "bar-mermaid" ); }, Qo = I(Jo), er = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.next, disabled: o, onClick: () => { h.emit(e, Te); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "next" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.next }) ] } ); }, tr = I(er), or = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.orderedList, disabled: o, onClick: () => { h.emit(e, w, "orderedList"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "ordered-list" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.orderedList }) ] } ); }, rr = I(or), nr = () => { const { setting: e, usedLanguageText: t, updateSetting: r, showToolbarName: o, disabled: l } = x(C); return /* @__PURE__ */ $( "button", { className: S([ `${n}-toolbar-item`, e.pageFullscreen && `${n}-toolbar-active`, l && `${n}-disabled` ]), title: t.toolbarTips?.pageFullscreen, disabled: l, onClick: () => { r("pageFullscreen"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: e.pageFullscreen ? "minimize" : "maximize" }), o && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.pageFullscreen }) ] } ); }, ar = I(nr), lr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.prettier, disabled: o, onClick: () => { h.emit(e, w, "prettier"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "prettier" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.prettier }) ] } ); }, ir = I(lr), sr = () => { const { usedLanguageText: e, showToolbarName: t, disabled: r, setting: o, updateSetting: l } = x(C); return /* @__PURE__ */ $( "button", { className: S([ `${n}-toolbar-item`, o.preview && `${n}-toolbar-active`, r && `${n}-disabled` ]), title: e.toolbarTips?.preview, disabled: r, onClick: () => { l("preview"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "preview" }), t && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: e.toolbarTips?.preview }) ] } ); }, cr = I(sr), dr = () => { const { usedLanguageText: e, showToolbarName: t, disabled: r, setting: o, updateSetting: l } = x(C); return /* @__PURE__ */ $( "button", { className: S([ `${n}-toolbar-item`, o.previewOnly && `${n}-toolbar-active`, r && `${n}-disabled` ]), title: e.toolbarTips?.previewOnly, disabled: r, onClick: () => { l("previewOnly"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "preview-only" }), t && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: e.toolbarTips?.previewOnly }) ] } ); }, ur = I(dr), mr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.quote, disabled: o, onClick: () => { h.emit(e, w, "quote"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "quote" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.quote }) ] } ); }, br = I(mr), hr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.revoke, disabled: o, onClick: () => { h.emit(e, we); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "revoke" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.revoke }) ] } ); }, gr = I(hr), fr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.save, disabled: o, onClick: () => { h.emit(e, it); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "save" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.save }) ] } ); }, pr = I(fr), vr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.strikeThrough, disabled: o, onClick: () => { h.emit(e, w, "strikeThrough"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "strike-through" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.strikeThrough }) ] } ); }, Tr = I(vr), wr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.sub, disabled: o, onClick: () => { h.emit(e, w, "sub"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "sub" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.sub }) ] } ); }, $r = I(wr), Cr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = x(C); return /* @__PURE__ */ $( "button", { className: S([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.sup, disabled: o, onClick: () => { h.emit(e, w, "sup"); }, type: "button", children: [ /* @__PURE__ */ a(E, { name: "sup" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.sup }) ] } ); }, xr = I(Cr), yr = (e) => { const [t, r] = F({ x: -1, y: -1 }), o = M(() => JSON.stringify(e.tableShape), [e.tableShape]), l = L(() => { const c = [...JSON.parse(o)]; return (!c[2] || c[2] < c[0]) && (c[2] = c[0]), (!c[3] || c[3] < c[3]) && (c[3] = c[1]), c; }, [o]), [i, s] = F(l); return A(() => { s(l), r({ x: -1, y: -1 }); }, [l]), /* @__PURE__ */ a( "div", { className: `${n}-table-shape`, onMouseLeave: () => { s(l), r({ x: -1, y: -1 }); }, children: new Array(i[1]).fill("").map((c, m) => /* @__PURE__ */ a("div", { className: `${n}-table-shape-row`, children: new Array(i[0]).fill("").map((d, b) => /* @__PURE__ */ a( "div", { className: `${n}-table-shape-col`, onMouseEnter: () => { r({ x: m, y: b }), b + 1 === i[0] && b + 1 < i[2] ? s((g) => { const f = [...g]; return f[0] = g[0] + 1, f; }) : b + 2 < i[0] && i[0] > e.tableShape[0] && s((g) => { const f = [...g]; return f[0] = g[0] - 1, f; }), m + 1 === i[1] && m + 1 < i[3] ? s((g) => { const f = [...g]; return f[1] = g[1] + 1, f; }) : m + 2 < i[1] && i[1] > e.tableShape[1] && s((g) => { const f = [...g]; return f[1] = g[1] - 1, f; }); }, onClick: () => { e.onSelected(t); }, children: /* @__PURE__ */ a( "div", { className: [ `${n}-table-shape-col-default`, m <= t.x && b <= t.y && `${n}-table-shape-col-include` ].filter((g) => !!g).join(" ") } ) }, `table-shape-col-