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,889 lines (1,888 loc) 96.1 kB
import { jsxs as $, jsx as a, Fragment as rt } from "react/jsx-runtime"; import { memo as N, useRef as R, useCallback as A, useEffect as D, useContext as y, useState as O, useMemo as V, cloneElement as nt, createContext as wt, useSyncExternalStore as $t, forwardRef as at, useImperativeHandle as Ct } from "react"; import { p as n, g as ee, a as xt, M as ce, b as yt, d as S } from "./config.mjs"; import { linkTo as kt, createSmoothScroll as lt, draggingScroll as Nt } from "@vavt/util"; import { c as E, b as St } from "./index2.mjs"; import { E as C, d as Et } from "./context.mjs"; import { s as It, a as Lt, M as At } from "./index3.mjs"; import { C as Dt, a as Rt, u as Mt, b as Ft, c as Ht, d as Pt, e as Ot, f as Vt, g as Bt, h as zt } from "./hooks.mjs"; import { deleteLine as _t, defaultKeymap as Wt, historyKeymap as qt, indentWithTab as Kt, history as He, undo as Ut, redo as Gt } from "@codemirror/commands"; import { markdown as jt } from "@codemirror/lang-markdown"; import { languages as Yt } from "@codemirror/language-data"; import { EditorState as fe, EditorSelection as Q, Compartment as J, StateEffect as ue, StateField as it, RangeSetBuilder as Zt } from "@codemirror/state"; import { placeholder as Xt, EditorView as K, showTooltip as Jt, Decoration as Qt, WidgetType as eo, keymap as to, drawSelection as oo } from "@codemirror/view"; import { b as f, E as re, R as w, U as ye, O as st, C as ro, a as $e, c as Ce, d as Pe, e as Oe, T as Ve, S as Be, G as ze } from "./event-bus.mjs"; import { indentUnit as no, syntaxHighlighting as ct, HighlightStyle as dt } from "@codemirror/language"; import { autocompletion as ao } from "@codemirror/autocomplete"; import { searchKeymap as lo } from "@codemirror/search"; import { createRoot as io } from "react-dom/client"; import { a as so } from "./dom.mjs"; import { I as L, M as co } from "./index.mjs"; import { D as ie } from "./index4.mjs"; import { tags as m } from "@lezer/highlight"; const uo = (e) => { const t = R(null), r = R(null), o = R(null), l = R(null), i = R(!1), s = R(0), d = R(0), b = A(() => { if (!r.current || !t.current || !o.current || !l.current) return; const v = t.current.clientHeight, k = r.current.scrollHeight, I = r.current.scrollTop; if (k <= 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 H = v / k, z = Math.max(v * H, 20), B = v - z, P = Math.min(I * H, B); o.current.style.height = `${z}px`, o.current.style.top = `${P}px`; }, [e.alwaysShowTrack]), c = b, u = A((v) => { i.current = !0, s.current = v.clientY, d.current = r.current.scrollTop, document.body.style.userSelect = "none"; }, []), g = A( (v) => { if (!i.current || !r.current || !t.current) return; const k = v.clientY - s.current, I = r.current.scrollHeight / t.current.clientHeight; r.current.scrollTop = d.current + k * I; }, [d, s] ), h = A(() => { i.current = !1, document.body.style.userSelect = ""; }, []), p = A( (v) => { r.current && r.current.removeEventListener("scroll", c), r.current = v, r.current ? (r.current.addEventListener("scroll", c), b()) : l.current && !e.alwaysShowTrack && (l.current.style.display = "none"); }, [c, e.alwaysShowTrack, b] ), T = A(() => { if (!t.current) return; const v = e.scrollTarget ? t.current.querySelector(e.scrollTarget) : t.current.firstElementChild; p(v); }, [p, e.scrollTarget]); return D(() => { T(); const v = o.current; let k = null; const I = new MutationObserver(() => { k && cancelAnimationFrame(k), k = requestAnimationFrame(() => { T(); }); }); return I.observe(t.current, { childList: !0, subtree: !0 }), window.addEventListener("resize", b), v?.addEventListener("mousedown", u), document.addEventListener("mousemove", g), document.addEventListener("mouseup", h), () => { I?.disconnect(), r.current && r.current.removeEventListener("scroll", c), window.removeEventListener("resize", b), v?.removeEventListener("mousedown", u), document.removeEventListener("mousemove", g), document.removeEventListener("mouseup", h); }; }, [T, u, g, h, c, b]), /* @__PURE__ */ $( "div", { id: e.id, className: E([`${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 }) }) ] } ); }, pe = N(uo), mo = (e, t, r) => { const { editorId: o, setting: l } = y(C), [i, s] = O({ clear() { }, init() { } }); D(() => { const d = r.current?.view.contentDOM.getRootNode(), b = d?.querySelector( `#${o} .cm-scroller` ), c = d?.querySelector( `[id="${o}-preview-wrapper"]` ), u = d?.querySelector( `[id="${o}-html-wrapper"]` ); if (c || u) { const g = c ? It : Lt, h = c || u, [p, T] = g(b, h, r.current); s({ init: p, clear: T }); } }, [ t, l.fullscreen, l.pageFullscreen, l.preview, l.htmlPreview, o, r ]), D(() => (e.scrollAuto && !l.previewOnly && (l.preview || l.htmlPreview) ? i.init() : i.clear(), () => { i.clear(); }), [ i, e.scrollAuto, l.preview, l.htmlPreview, l.previewOnly ]); }, Te = async (e, t, r) => { if (/^h[1-6]$/.test(e)) return bo(e, t); if (e === "prettier") return await ho(t, r); switch (e) { case "bold": case "underline": case "italic": case "strikeThrough": case "sub": case "sup": case "codeRow": case "katexInline": case "katexBlock": return fo(e, t); case "quote": case "orderedList": case "unorderedList": case "task": return To(e, t); case "code": return vo(r, t); case "table": return Co(r); case "link": { const o = t.getSelectedText(), { desc: l = o, url: i = "" } = r, s = `[${l}](${i})`; return { text: s, options: { select: i === "", deviationStart: s.length - i.length - 1, deviationEnd: -1 } }; } case "image": return $o(r, t); case "flow": case "sequence": case "gantt": case "class": case "state": case "pie": case "relationship": case "journey": return wo(e); case "universal": return xo(t.getSelectedText(), r); default: return { text: "", options: {} }; } }, bo = (e, t) => { const r = e.slice(1), o = "#".repeat(Number(r)), [l, i, s] = ke(t, { wholeLine: !0 }); return { text: `${o} ${l}`, options: { deviationStart: o.length + 1, replaceStart: i, replaceEnd: s } }; }, ho = async (e, t) => { const r = window.prettier || ee.editorExtensions.prettier?.prettierInstance, o = [ window.prettierPlugins?.markdown || ee.editorExtensions.prettier?.parserMarkdownInstance ]; return !r || !o[0] ? (f.emit(t.editorId, re, { 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 } }; }, go = { 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] }, fo = (e, t) => { const r = t.getSelectedText(), [o, l, i, s] = go[e]; return { text: `${o}${r}${l}`, options: { deviationStart: i, deviationEnd: s // replaceStart, replaceEnd } }; }, po = { quote: "> ", unorderedList: "- ", orderedList: 1, task: "- [ ] " }, To = (e, t) => { const [r, o, l] = ke(t, { wholeLine: !0 }), i = r.split(` `), s = po[e], d = e === "orderedList" ? i.map((u, g) => `${s + g}. ${u}`) : i.map((u) => `${s}${u}`), b = e === "orderedList" ? "1. " : s.toString(), c = i.length === 1 ? b.length : 0; return { text: d.join(` `), options: { deviationStart: c, replaceStart: o, replaceEnd: l } }; }, vo = (e, t) => { const [r, o, l] = ke(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 } }; }, wo = (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`, ...ee.editorConfig.mermaidTemplate }[e]} \`\`\` `, options: { deviationStart: 12, deviationEnd: -5 } }), $o = (e, t) => { const r = t.getSelectedText(), { desc: o = r, url: l = "", urls: i } = e; let s = ""; const d = l === "" && (!i || i instanceof Array && i.length === 0); return i instanceof Array ? s = i.reduce((b, c) => { const { url: u = "", alt: g = "", title: h = "" } = typeof c == "object" ? c : { url: c }; return b + `![${g}](${u}${h ? " '" + h + "'" : ""}) `; }, "") : s = `![${o}](${l}) `, { text: s, options: { select: l === "", deviationStart: d ? s.length - l.length - 2 : s.length, deviationEnd: d ? -2 : 0 } }; }, Co = (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 } }; }, xo = (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 } }; }, ke = (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 ]; }, oe = (e) => { const t = new J(); return (o) => (t.get(e.state) ? e.dispatch({ effects: t.reconfigure(o) }) : e.dispatch({ effects: ue.appendConfig.of(t.of(o)) }), !0); }; class yo { 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") f.emit(o, re, { name: "overlength", message: i.message, data: t }); else throw i; } } constructor(t) { this.view = t, this.toggleTabSize = oe(this.view), this.togglePlaceholder = oe(this.view), this.setExtensions = oe(this.view), this.toggleDisabled = oe(this.view), this.toggleReadOnly = oe(this.view), this.toggleMaxlength = oe(this.view); } /** * 设置tabSize * * @param tabSize 需要切换的大小 */ setTabSize(t) { this.toggleTabSize([ fe.tabSize.of(t), no.of(" ".repeat(t)) ]); } /** * 设置placeholder * * @param t 目标内容 */ setPlaceholder(t) { this.togglePlaceholder(Xt(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: Q.create( [Q.range(r, o), Q.cursor(l)], 1 ) }); } setDisabled(t) { this.toggleDisabled([K.editable.of(!t)]); } setReadOnly(t) { this.toggleReadOnly([fe.readOnly.of(t)]); } setMaxLength(t) { this.maxLength = t, this.toggleMaxlength([ fe.changeFilter.of((r) => r.newDoc.length <= t) ]); } } const ko = (e, t) => { const { editorId: r } = y(C), o = A( (i) => { i instanceof Promise ? i.then((s) => { f.emit(r, w, "universal", { generate() { return { targetValue: s }; } }); }).catch((s) => { console.error(s); }) : f.emit(r, w, "universal", { generate() { return { targetValue: i }; } }); }, [r] ); return A( (i) => { if (!i.clipboardData) return; if (i.clipboardData.files.length > 0) { const { files: h } = i.clipboardData; f.emit( r, ye, Array.from(h).filter((p) => /image\/.*/.test(p.type)) ), i.preventDefault(); return; } const s = i.clipboardData.getData("text/plain"), d = t.current?.view.state.selection.main.to || 0, b = t.current?.view.state.doc.lineAt(d).from || 0, c = t.current?.view.state.doc.sliceString(b, d) || "", u = /!\[.*\]\(\s*$/.test(c), g = /!\[.*\]\((.*)\s?.*\)/.test(s); if (u) { const h = e.transformImgUrl(s); o(h), i.preventDefault(); return; } else if (g) { const h = s.match( new RegExp(`(?<=!\\[.*\\]\\()([^)\\s]+)(?=\\s?["']?.*["']?\\))`, "g") ); h ? Promise.all( h.map((p) => e.transformImgUrl(p)) ).then((p) => { o( p.reduce((T, v, k) => T.replace(h[k], v), s) ); }).catch((p) => { console.error(p); }) : o(s), i.preventDefault(); return; } if (e.autoDetectCode && i.clipboardData.types.includes("vscode-editor-data")) { const h = JSON.parse(i.clipboardData.getData("vscode-editor-data")); f.emit(r, w, "code", { mode: h.mode, text: i.clipboardData.getData("text/plain") }), i.preventDefault(); return; } e.maxLength && s.length + e.modelValue.length > e.maxLength && f.emit(r, re, { name: "overlength", message: "The input text is too long", data: s }); }, [t, r, o, e] ); }, de = (e, t, r, o, l) => (i, s, d, b) => { const c = `${e}${t}${r}${o}`, u = d + s.label.length + (l === "title" ? r.length : 0); i.dispatch({ changes: { from: d, to: b, insert: c }, selection: Q.create( [ Q.range( d + s.label.length + (l === "title" ? 1 : -t.length), u ), Q.cursor(u) ], 1 ) }), i.focus(); }, _e = (e) => (t, r, o, l) => { const i = e.slice(l - o); t.dispatch(t.state.replaceSelection(`${i} `)); }, We = (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: _e(s) }; }), // 任务列表 ...["unchecked", "checked"].map((l) => { const i = l === "checked" ? "- [x]" : "- [ ]"; return { label: i, type: "text", apply: _e(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 ao({ override: e ? [t, ...e] : [t] }); }, No = (e, t) => [ { key: "Ctrl-b", mac: "Cmd-b", run: () => (f.emit(e, w, "bold"), !0) }, { key: "Ctrl-d", mac: "Cmd-d", run: _t, preventDefault: !0 }, { key: "Ctrl-s", mac: "Cmd-s", run: (B) => (f.emit(e, st, B.state.doc.toString()), !0), shift: () => (f.emit(e, w, "strikeThrough"), !0) }, { key: "Ctrl-u", mac: "Cmd-u", preventDefault: !0, run: () => (f.emit(e, w, "underline"), !0), shift: () => (f.emit(e, w, "unorderedList"), !0) }, { key: "Ctrl-i", mac: "Cmd-i", preventDefault: !0, run: () => (f.emit(e, w, "italic"), !0), shift: () => (f.emit(e, w, "image"), !0) }, { key: "Ctrl-1", mac: "Cmd-1", run: () => (f.emit(e, w, "h1"), !0) }, { key: "Ctrl-2", mac: "Cmd-2", run: () => (f.emit(e, w, "h2"), !0) }, { key: "Ctrl-3", mac: "Cmd-3", run: () => (f.emit(e, w, "h3"), !0) }, { key: "Ctrl-4", mac: "Cmd-4", run: () => (f.emit(e, w, "h4"), !0) }, { key: "Ctrl-5", mac: "Cmd-5", run: () => (f.emit(e, w, "h5"), !0) }, { key: "Ctrl-6", mac: "Cmd-6", run: () => (f.emit(e, w, "h6"), !0) }, { key: "Ctrl-ArrowUp", mac: "Cmd-ArrowUp", run: () => (f.emit(e, w, "sup"), !0) }, { key: "Ctrl-ArrowDown", mac: "Cmd-ArrowDown", run: () => (f.emit(e, w, "sub"), !0) }, { key: "Ctrl-o", mac: "Cmd-o", run: () => (f.emit(e, w, "orderedList"), !0) }, { key: "Ctrl-c", mac: "Cmd-c", shift: () => (f.emit(e, w, "code"), !0), any(B, P) { return (P.ctrlKey || P.metaKey) && P.altKey && P.code === "KeyC" ? (f.emit(e, w, "codeRow"), !0) : !1; } }, { key: "Ctrl-l", mac: "Cmd-l", run: () => (f.emit(e, w, "link"), !0) }, { key: "Ctrl-f", mac: "Cmd-f", shift: () => t.noPrettier ? !1 : (f.emit(e, w, "prettier"), !0) }, { any: (B, P) => (P.ctrlKey || P.metaKey) && P.altKey && P.shiftKey && P.code === "KeyT" ? (f.emit(e, w, "table"), !0) : !1 }, ...lo ], So = () => /* @__PURE__ */ a("div", { className: `${n}-divider` }), Eo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.bold, "aria-label": t.toolbarTips?.bold, disabled: o, onClick: () => { f.emit(e, w, "bold"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "bold" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.bold }) ] } ); }, Io = N(Eo), Lo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o, catalogVisible: l } = y(C); return /* @__PURE__ */ $( "button", { className: E([ `${n}-toolbar-item`, l && `${n}-toolbar-active`, o && `${n}-disabled` ]), title: t.toolbarTips?.catalog, "aria-label": t.toolbarTips?.catalog, disabled: o, onClick: () => { f.emit(e, ro); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "catalog" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.catalog }) ] }, "bar-catalog" ); }, Ao = N(Lo), Do = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.code, "aria-label": t.toolbarTips?.code, disabled: o, onClick: () => { f.emit(e, w, "code"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "code" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.code }) ] } ); }, Ro = N(Do), Mo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.codeRow, "aria-label": t.toolbarTips?.codeRow, disabled: o, onClick: () => { f.emit(e, w, "codeRow"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "code-row" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.codeRow }) ] } ); }, Fo = N(Mo), Ho = () => { const { setting: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C), { fullscreenHandler: l } = Br(); return /* @__PURE__ */ $( "button", { className: E([ `${n}-toolbar-item`, e.fullscreen && `${n}-toolbar-active`, o && `${n}-disabled` ]), title: t.toolbarTips?.fullscreen, "aria-label": t.toolbarTips?.fullscreen, disabled: o, onClick: () => { l(); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: e.fullscreen ? "fullscreen-exit" : "fullscreen" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.fullscreen }) ] } ); }, Po = N(Ho), Oo = () => { const { usedLanguageText: e, showToolbarName: t, disabled: r } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, r && `${n}-disabled`]), title: e.toolbarTips?.github, "aria-label": e.toolbarTips?.github, disabled: r, onClick: () => { kt("https://github.com/imzbf/md-editor-rt"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "github" }), t && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: e.toolbarTips?.github }) ] } ); }, Vo = N(Oo), Bo = () => { const { usedLanguageText: e, setting: t, updateSetting: r, showToolbarName: o, disabled: l } = y(C); return /* @__PURE__ */ $( "button", { className: E([ `${n}-toolbar-item`, t.htmlPreview && `${n}-toolbar-active`, l && `${n}-disabled` ]), title: e.toolbarTips?.htmlPreview, "aria-label": e.toolbarTips?.htmlPreview, disabled: l, onClick: () => { r("htmlPreview"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "preview-html" }), o && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: e.toolbarTips?.htmlPreview }) ] } ); }, zo = N(Bo), _o = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.image, "aria-label": t.toolbarTips?.image, disabled: o, onClick: () => { f.emit(e, w, "image"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "image" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.image }) ] } ); }, Wo = N(_o); let X = null; const qo = (e) => { const t = y(C), { editorId: r, usedLanguageText: o, rootRef: l } = t, i = ee.editorExtensions.cropper.instance, s = R(null), d = R(null), b = R(null), [c, u] = O({ cropperInited: !1, imgSelected: !1, imgSrc: "", // 是否全屏 isFullscreen: !1 }); D(() => { e.visible && !c.cropperInited && (window.Cropper = i || window.Cropper, s.current.onchange = () => { if (!window.Cropper) { f.emit(r, re, { name: "Cropper", message: "Cropper is undefined" }); return; } const T = s.current.files || []; if (T?.length > 0) { const v = new FileReader(); v.onload = (k) => { u((I) => ({ ...I, imgSelected: !0, imgSrc: k.target.result })); }, v.readAsDataURL(T[0]); } }); }, [e.visible, c.cropperInited, i, r]), D(() => { b.current?.setAttribute("style", ""); }, [c.imgSelected]), D(() => { X?.destroy(), b.current?.setAttribute("style", ""), d.current && c.imgSrc && (X = new window.Cropper(d.current, { viewMode: 2, preview: (l.current?.getRootNode()).querySelector( `.${n}-clip-preview-target` ) })); }, [c.imgSrc, c.isFullscreen, l]); const g = V(() => c.isFullscreen ? { width: "100%", height: "100%" } : { width: "668px", height: "392px" }, [c.isFullscreen]), h = () => { X.clear(), X.destroy(), X = null, s.current.value = "", u((T) => ({ ...T, imgSrc: "", imgSelected: !1 })); }, p = A((T) => { u((v) => ({ ...v, isFullscreen: T })); }, []); return V(() => /* @__PURE__ */ $( co, { className: `${n}-modal-clip`, title: o.clipModalTips?.title, visible: e.visible, onClose: e.onCancel, showAdjust: !0, isFullscreen: c.isFullscreen, onAdjust: p, ...g, children: [ /* @__PURE__ */ $("div", { className: `${n}-form-item ${n}-clip`, children: [ /* @__PURE__ */ a("div", { className: `${n}-clip-main`, children: c.imgSelected ? /* @__PURE__ */ $("div", { className: `${n}-clip-cropper`, children: [ /* @__PURE__ */ a( "img", { src: c.imgSrc, ref: d, style: { display: "none" }, alt: "" } ), /* @__PURE__ */ a("div", { className: `${n}-clip-delete`, onClick: h, children: /* @__PURE__ */ a(L, { 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(L, { name: "upload" }) } ) }), /* @__PURE__ */ a("div", { className: `${n}-clip-preview`, children: /* @__PURE__ */ a("div", { className: `${n}-clip-preview-target`, ref: b }) }) ] }), /* @__PURE__ */ a("div", { className: `${n}-form-item`, children: /* @__PURE__ */ a( "button", { className: `${n}-btn`, type: "button", onClick: () => { if (X) { const T = X.getCroppedCanvas(); f.emit( r, ye, [St(T.toDataURL("image/png"))], e.onOk ), h(); } }, 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, c.isFullscreen, c.imgSelected, c.imgSrc, p, g, r ]); }, Ko = N(qo), Uo = (e) => /* @__PURE__ */ a(Ko, { visible: e.clipVisible, onOk: e.onOk, onCancel: e.onCancel }), Go = N(Uo), jo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C), l = `${e}-toolbar-wrapper`, [i, s] = O(!1), [d, b] = O(!1), c = R(null), u = A(() => { f.emit(e, ye, Array.from(c.current?.files || [])), c.current.value = ""; }, [e]), g = A( (k, I) => { o || f.emit(e, w, k, I); }, [e, o] ), h = A(() => { b(!1); }, []), p = A( (k) => { k && g("image", { desc: k.desc, url: k.url, transform: !0 }), b(!1); }, [g] ), T = V(() => { const k = [ { key: "link", label: t.imgTitleItem?.link, onClick: () => g("image") }, { key: "upload", label: t.imgTitleItem?.upload, onClick: () => c.current?.click() }, { key: "clip", label: t.imgTitleItem?.clip2upload, onClick: () => b(!0) } ]; return /* @__PURE__ */ a( "ul", { className: `${n}-menu`, onClick: () => { s(!1); }, role: "menu", children: k.map((I) => /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-image`, onClick: I.onClick, role: "menuitem", tabIndex: 0, children: I.label }, I.key )) } ); }, [g, t.imgTitleItem]), v = V(() => /* @__PURE__ */ $( "button", { className: E([ `${n}-toolbar-item`, o && `${n}-disabled` ]), title: t.toolbarTips?.image, "aria-label": t.toolbarTips?.image, disabled: o, type: "button", children: [ /* @__PURE__ */ a(L, { name: "image" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.image }) ] } ), [o, r, t.toolbarTips?.image]); return D(() => { const k = c.current; return k?.addEventListener("change", u), () => { k?.removeEventListener("change", u); }; }, [u]), /* @__PURE__ */ $(rt, { children: [ /* @__PURE__ */ a( "label", { htmlFor: `${l}_label`, style: { display: "none" }, "aria-label": t.imgTitleItem?.upload } ), /* @__PURE__ */ a( "input", { id: `${l}_label`, ref: c, accept: "image/*", type: "file", multiple: !0, style: { display: "none" } } ), /* @__PURE__ */ a(Go, { clipVisible: d, onCancel: h, onOk: p }), /* @__PURE__ */ a( ie, { relative: `#${l}`, visible: i, onChange: s, disabled: o, overlay: T, children: v } ) ] }); }, Yo = N(jo), Zo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.italic, "aria-label": t.toolbarTips?.italic, disabled: o, onClick: () => { f.emit(e, w, "italic"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "italic" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.italic }) ] } ); }, Xo = N(Zo), Jo = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C), l = `${e}-toolbar-wrapper`, [i, s] = O(!1), d = A( (u) => { o || f.emit(e, w, u); }, [o, e] ), b = V(() => /* @__PURE__ */ $( "ul", { className: `${n}-menu`, onClick: () => { s(!1); }, role: "menu", children: [ /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-katex`, onClick: () => { d("katexInline"); }, role: "menuitem", tabIndex: 0, children: t.katex?.inline } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-katex`, onClick: () => { d("katexBlock"); }, role: "menuitem", tabIndex: 0, children: t.katex?.block } ) ] } ), [d, t.katex?.block, t.katex?.inline]), c = V(() => /* @__PURE__ */ $( "button", { className: E([ `${n}-toolbar-item`, o && `${n}-disabled` ]), title: t.toolbarTips?.katex, "aria-label": t.toolbarTips?.katex, disabled: o, type: "button", children: [ /* @__PURE__ */ a(L, { 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: b, children: c }, "bar-katex" ); }, Qo = N(Jo), er = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.link, "aria-label": t.toolbarTips?.link, disabled: o, onClick: () => { f.emit(e, w, "link"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "link" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.link }) ] } ); }, tr = N(er), or = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C), l = `${e}-toolbar-wrapper`, [i, s] = O(!1), d = A( (u) => { o || f.emit(e, w, u); }, [o, e] ), b = V(() => /* @__PURE__ */ $( "ul", { className: `${n}-menu`, onClick: () => { s(!1); }, role: "menu", children: [ /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { d("flow"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.flow } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { d("sequence"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.sequence } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { d("gantt"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.gantt } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { d("class"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.class } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { d("state"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.state } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { d("pie"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.pie } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { d("relationship"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.relationship } ), /* @__PURE__ */ a( "li", { className: `${n}-menu-item ${n}-menu-item-mermaid`, onClick: () => { d("journey"); }, role: "menuitem", tabIndex: 0, children: t.mermaid?.journey } ) ] } ), [ d, t.mermaid?.class, t.mermaid?.flow, t.mermaid?.gantt, t.mermaid?.journey, t.mermaid?.pie, t.mermaid?.relationship, t.mermaid?.sequence, t.mermaid?.state ]), c = V(() => /* @__PURE__ */ $( "button", { className: E([ `${n}-toolbar-item`, o && `${n}-disabled` ]), title: t.toolbarTips?.mermaid, "aria-label": t.toolbarTips?.mermaid, disabled: o, type: "button", children: [ /* @__PURE__ */ a(L, { 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: b, children: c }, "bar-mermaid" ); }, rr = N(or), nr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.next, "aria-label": t.toolbarTips?.next, disabled: o, onClick: () => { f.emit(e, $e); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "next" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.next }) ] } ); }, ar = N(nr), lr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.orderedList, "aria-label": t.toolbarTips?.orderedList, disabled: o, onClick: () => { f.emit(e, w, "orderedList"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "ordered-list" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.orderedList }) ] } ); }, ir = N(lr), sr = () => { const { setting: e, usedLanguageText: t, updateSetting: r, showToolbarName: o, disabled: l } = y(C); return /* @__PURE__ */ $( "button", { className: E([ `${n}-toolbar-item`, e.pageFullscreen && `${n}-toolbar-active`, l && `${n}-disabled` ]), title: t.toolbarTips?.pageFullscreen, "aria-label": t.toolbarTips?.pageFullscreen, disabled: l, onClick: () => { r("pageFullscreen"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: e.pageFullscreen ? "minimize" : "maximize" }), o && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.pageFullscreen }) ] } ); }, cr = N(sr), dr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.prettier, "aria-label": t.toolbarTips?.prettier, disabled: o, onClick: () => { f.emit(e, w, "prettier"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "prettier" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.prettier }) ] } ); }, ur = N(dr), mr = () => { const { usedLanguageText: e, showToolbarName: t, disabled: r, setting: o, updateSetting: l } = y(C); return /* @__PURE__ */ $( "button", { className: E([ `${n}-toolbar-item`, o.preview && `${n}-toolbar-active`, r && `${n}-disabled` ]), title: e.toolbarTips?.preview, "aria-label": e.toolbarTips?.preview, disabled: r, onClick: () => { l("preview"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "preview" }), t && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: e.toolbarTips?.preview }) ] } ); }, br = N(mr), hr = () => { const { usedLanguageText: e, showToolbarName: t, disabled: r, setting: o, updateSetting: l } = y(C); return /* @__PURE__ */ $( "button", { className: E([ `${n}-toolbar-item`, o.previewOnly && `${n}-toolbar-active`, r && `${n}-disabled` ]), title: e.toolbarTips?.previewOnly, "aria-label": e.toolbarTips?.previewOnly, disabled: r, onClick: () => { l("previewOnly"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "preview-only" }), t && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: e.toolbarTips?.previewOnly }) ] } ); }, gr = N(hr), fr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.quote, "aria-label": t.toolbarTips?.quote, disabled: o, onClick: () => { f.emit(e, w, "quote"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "quote" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.quote }) ] } ); }, pr = N(fr), Tr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.revoke, "aria-label": t.toolbarTips?.revoke, disabled: o, onClick: () => { f.emit(e, Ce); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "revoke" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.revoke }) ] } ); }, vr = N(Tr), wr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.save, "aria-label": t.toolbarTips?.save, disabled: o, onClick: () => { f.emit(e, st); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "save" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.save }) ] } ); }, $r = N(wr), Cr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.strikeThrough, "aria-label": t.toolbarTips?.strikeThrough, disabled: o, onClick: () => { f.emit(e, w, "strikeThrough"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "strike-through" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.strikeThrough }) ] } ); }, xr = N(Cr), yr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.sub, "aria-label": t.toolbarTips?.sub, disabled: o, onClick: () => { f.emit(e, w, "sub"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "sub" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.sub }) ] } ); }, kr = N(yr), Nr = () => { const { editorId: e, usedLanguageText: t, showToolbarName: r, disabled: o } = y(C); return /* @__PURE__ */ $( "button", { className: E([`${n}-toolbar-item`, o && `${n}-disabled`]), title: t.toolbarTips?.sup, "aria-label": t.toolbarTips?.sup, disabled: o, onClick: () => { f.emit(e, w, "sup"); }, type: "button", children: [ /* @__PURE__ */ a(L, { name: "sup" }), r && /* @__PURE__ */ a("div", { className: `${n}-toolbar-item-name`, children: t.toolbarTips?.sup }) ] } ); }, Sr = N(Nr), Er = (e) => { const [t, r] = O({ x: -1, y: -1 }), o = V(() => JSON.stringify(e.tableShape), [e.tableShape]), l = A(() => { const d = [...JSON.parse(o)]; return (!d[2] || d[2] < d[0]) && (d[2] = d[0]), (!d[3] || d[3] < d[3]) && (d[3] = d[1]), d; }, [o]), [i, s] = O(l); return D(() => { 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((d, b) => /* @__PURE__ */ a("div", { className: `${n}-table-shape-row`, children: new Array(i[0]).fill("").map((c, u) => /* @__PURE__ */ a( "div", { className: `${n}-table-shape-col`, onMouseEnter: () => { r({ x: b, y: u }), u + 1 === i[0] && u + 1 < i[2] ? s((g) => { const h = [...g]; return h[0] = g[0] + 1, h; })