dishui 0.0.74 → 0.0.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js +80 -64
- package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js +44 -69
- package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/package.json +1 -1
|
@@ -42,25 +42,25 @@ var x = ({ code: e }) => {
|
|
|
42
42
|
} },
|
|
43
43
|
children: t
|
|
44
44
|
}), C = [
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
], w = /* @__PURE__ */ ".javascript.typescript.python.rust.go.java.c.cpp.csharp.ruby.php.swift.kotlin.sql.bash.shell.html.css.json.yaml.toml.xml.
|
|
49
|
-
[...w, ...C];
|
|
45
|
+
"markdown",
|
|
46
|
+
"mermaid",
|
|
47
|
+
"math"
|
|
48
|
+
], w = /* @__PURE__ */ ".javascript.typescript.python.rust.go.java.c.cpp.csharp.ruby.php.swift.kotlin.sql.bash.shell.html.css.json.yaml.toml.xml.docker.graphql.latex.tex".split(".");
|
|
50
49
|
function T(e) {
|
|
51
|
-
|
|
50
|
+
let t = e.startsWith("r-") ? e.slice(2) : e;
|
|
51
|
+
return C.includes(t) ? t : "";
|
|
52
52
|
}
|
|
53
53
|
function E(e) {
|
|
54
54
|
return e === "math" || e === "latex" || e === "tex" ? "latex" : e;
|
|
55
55
|
}
|
|
56
56
|
var D = ({ node: l, editor: u, updateAttributes: d }) => {
|
|
57
|
-
let f = t(u), p = l.attrs.language || "", g = l.textContent, _ = !!p, v = T(p),
|
|
57
|
+
let f = t(u), p = l.attrs.language || "", g = l.textContent, _ = !!p, v = T(p), y = !!v, [b, D] = r(!0);
|
|
58
58
|
n(() => {
|
|
59
|
-
_ ||
|
|
59
|
+
_ || D(!0);
|
|
60
60
|
}, [p, _]), n(() => {
|
|
61
|
-
f ||
|
|
61
|
+
f || D(!1);
|
|
62
62
|
}, [f]);
|
|
63
|
-
let
|
|
63
|
+
let O = b && f, k = /* @__PURE__ */ o("svg", {
|
|
64
64
|
width: "12",
|
|
65
65
|
height: "12",
|
|
66
66
|
viewBox: "0 0 24 24",
|
|
@@ -70,7 +70,7 @@ var D = ({ node: l, editor: u, updateAttributes: d }) => {
|
|
|
70
70
|
strokeLinecap: "round",
|
|
71
71
|
strokeLinejoin: "round",
|
|
72
72
|
children: [/* @__PURE__ */ a("path", { d: "M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7" }), /* @__PURE__ */ a("path", { d: "M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z" })]
|
|
73
|
-
}),
|
|
73
|
+
}), A = /* @__PURE__ */ o("svg", {
|
|
74
74
|
width: "12",
|
|
75
75
|
height: "12",
|
|
76
76
|
viewBox: "0 0 24 24",
|
|
@@ -84,26 +84,26 @@ var D = ({ node: l, editor: u, updateAttributes: d }) => {
|
|
|
84
84
|
cy: "12",
|
|
85
85
|
r: "3"
|
|
86
86
|
})]
|
|
87
|
-
}),
|
|
87
|
+
}), j = () => v === "mermaid" ? g.trim() ? /* @__PURE__ */ a(e, { code: g }) : /* @__PURE__ */ a("p", {
|
|
88
88
|
className: "rte-codeblock__placeholder",
|
|
89
89
|
children: "Enter mermaid diagram code..."
|
|
90
|
-
}) :
|
|
90
|
+
}) : v === "math" ? g.trim() ? /* @__PURE__ */ a(x, { code: g }) : /* @__PURE__ */ a("p", {
|
|
91
91
|
className: "rte-codeblock__placeholder",
|
|
92
92
|
children: "Enter KaTeX math formula..."
|
|
93
|
-
}) :
|
|
93
|
+
}) : v === "markdown" ? g.trim() ? /* @__PURE__ */ a(S, { code: g }) : /* @__PURE__ */ a("p", {
|
|
94
94
|
className: "rte-codeblock__placeholder",
|
|
95
95
|
children: "Enter Markdown content..."
|
|
96
|
-
}) : null,
|
|
96
|
+
}) : null, M = v ? v + " (render)" : p || "plain text";
|
|
97
97
|
return /* @__PURE__ */ a(h, {
|
|
98
|
-
className: `rte-codeblock-wrapper ${!
|
|
99
|
-
children:
|
|
98
|
+
className: `rte-codeblock-wrapper ${!b && _ ? "rte-codeblock-wrapper--preview" : ""}`,
|
|
99
|
+
children: O ? /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ o("div", {
|
|
100
100
|
className: "rte-codeblock__header",
|
|
101
101
|
children: [/* @__PURE__ */ o("select", {
|
|
102
102
|
className: "rte-codeblock__lang-select",
|
|
103
|
-
value: p,
|
|
103
|
+
value: v || p,
|
|
104
104
|
disabled: !f,
|
|
105
105
|
onChange: (e) => {
|
|
106
|
-
!u.isDestroyed && u.isEditable && (d({ language: e.target.value }), e.target.value ||
|
|
106
|
+
!u.isDestroyed && u.isEditable && (d({ language: e.target.value }), e.target.value || D(!0));
|
|
107
107
|
},
|
|
108
108
|
contentEditable: !1,
|
|
109
109
|
children: [
|
|
@@ -129,65 +129,81 @@ var D = ({ node: l, editor: u, updateAttributes: d }) => {
|
|
|
129
129
|
}), _ && /* @__PURE__ */ o("button", {
|
|
130
130
|
type: "button",
|
|
131
131
|
className: "rte-codeblock__preview-btn",
|
|
132
|
-
onClick: () =>
|
|
132
|
+
onClick: () => D(!1),
|
|
133
133
|
contentEditable: !1,
|
|
134
|
-
children: [
|
|
134
|
+
children: [A, " Preview"]
|
|
135
135
|
})]
|
|
136
136
|
}), /* @__PURE__ */ a("pre", {
|
|
137
137
|
className: "rte-codeblock__editable-pre",
|
|
138
138
|
children: /* @__PURE__ */ a(m, { as: "code" })
|
|
139
|
-
})] }) :
|
|
139
|
+
})] }) : y ? /* @__PURE__ */ o("div", {
|
|
140
140
|
className: "rte-codeblock__render-preview",
|
|
141
141
|
contentEditable: !1,
|
|
142
142
|
onDoubleClick: () => {
|
|
143
|
-
f &&
|
|
143
|
+
f && D(!0);
|
|
144
144
|
},
|
|
145
|
-
children: [
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
145
|
+
children: [
|
|
146
|
+
/* @__PURE__ */ o("div", {
|
|
147
|
+
className: "rte-codeblock__preview-toolbar",
|
|
148
|
+
contentEditable: !1,
|
|
149
|
+
children: [/* @__PURE__ */ a("span", {
|
|
150
|
+
className: "rte-codeblock__preview-label",
|
|
151
|
+
children: M
|
|
152
|
+
}), f && /* @__PURE__ */ o("button", {
|
|
153
|
+
type: "button",
|
|
154
|
+
className: "rte-codeblock__preview-edit-btn",
|
|
155
|
+
onClick: () => D(!0),
|
|
156
|
+
children: [k, " Edit"]
|
|
157
|
+
})]
|
|
158
|
+
}),
|
|
159
|
+
/* @__PURE__ */ a("div", {
|
|
160
|
+
className: "rte-codeblock__render-body",
|
|
161
|
+
children: j()
|
|
162
|
+
}),
|
|
163
|
+
/* @__PURE__ */ a("div", {
|
|
164
|
+
style: { display: "none" },
|
|
165
|
+
"aria-hidden": "true",
|
|
166
|
+
children: /* @__PURE__ */ a(m, { as: "code" })
|
|
167
|
+
})
|
|
168
|
+
]
|
|
161
169
|
}) : /* @__PURE__ */ o("div", {
|
|
162
170
|
className: "rte-codeblock__syntax-preview",
|
|
163
171
|
contentEditable: !1,
|
|
164
172
|
onDoubleClick: () => {
|
|
165
|
-
f &&
|
|
173
|
+
f && D(!0);
|
|
166
174
|
},
|
|
167
|
-
children: [
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
175
|
+
children: [
|
|
176
|
+
/* @__PURE__ */ o("div", {
|
|
177
|
+
className: "rte-codeblock__preview-toolbar",
|
|
178
|
+
contentEditable: !1,
|
|
179
|
+
children: [/* @__PURE__ */ a("span", {
|
|
180
|
+
className: "rte-codeblock__preview-label",
|
|
181
|
+
children: M
|
|
182
|
+
}), f && /* @__PURE__ */ o("button", {
|
|
183
|
+
type: "button",
|
|
184
|
+
className: "rte-codeblock__preview-edit-btn",
|
|
185
|
+
onClick: () => D(!0),
|
|
186
|
+
children: [k, " Edit"]
|
|
187
|
+
})]
|
|
188
|
+
}),
|
|
189
|
+
/* @__PURE__ */ a(s, {
|
|
190
|
+
style: c,
|
|
191
|
+
language: E(p),
|
|
192
|
+
PreTag: "div",
|
|
193
|
+
customStyle: {
|
|
194
|
+
borderRadius: "0 0 0.5rem 0.5rem",
|
|
195
|
+
fontSize: "0.875em",
|
|
196
|
+
padding: "1em",
|
|
197
|
+
margin: "0"
|
|
198
|
+
},
|
|
199
|
+
children: g || " "
|
|
200
|
+
}),
|
|
201
|
+
/* @__PURE__ */ a("div", {
|
|
202
|
+
style: { display: "none" },
|
|
203
|
+
"aria-hidden": "true",
|
|
204
|
+
children: /* @__PURE__ */ a(m, { as: "code" })
|
|
205
|
+
})
|
|
206
|
+
]
|
|
191
207
|
})
|
|
192
208
|
});
|
|
193
209
|
}, O = /^```([a-z-]*)[\s\n]$/, k = /^~~~([a-z-]*)[\s\n]$/, A = /^(?:```|~~~)table(?:(\d+)[x×X*](\d+))?\s?$/, j = p.create({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockView.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/extensions/CodeBlockView.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { Node, mergeAttributes, textblockTypeInputRule } from '@tiptap/react';\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\nimport { NodeViewWrapper, NodeViewContent, ReactNodeViewRenderer } from '@tiptap/react';\nimport type { NodeViewProps } from '@tiptap/react';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\nimport { MermaidRenderer, useNodeEditable } from './MarkdownBlock';\nimport 'katex/dist/katex.min.css';\n\n\nconst KatexRenderer: React.FC<{ code: string }> = ({ code }) => {\n const wrapped = code.includes('$$') ? code : `$$\\n${code}\\n$$`;\n return (\n <ReactMarkdown\n remarkPlugins={[remarkMath]}\n rehypePlugins={[rehypeKatex]}\n >\n {wrapped}\n </ReactMarkdown>\n );\n};\n\nconst MarkdownRenderer: React.FC<{ code: string }> = ({ code }) => {\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm, remarkMath]}\n rehypePlugins={[rehypeKatex]}\n components={{\n code({ className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || '');\n const lang = match?.[1];\n const text = String(children).replace(/\\n$/, '');\n\n if (lang === 'mermaid') return <MermaidRenderer code={text} />;\n\n if (lang) {\n return (\n <SyntaxHighlighter\n style={oneLight as Record<string, React.CSSProperties>}\n language={lang}\n PreTag=\"div\"\n customStyle={{ borderRadius: '0.5rem', fontSize: '0.875em', padding: '1em', margin: '0.5em 0' }}\n >\n {text}\n </SyntaxHighlighter>\n );\n }\n return <code className={className} {...props}>{children}</code>;\n },\n }}\n >\n {code}\n </ReactMarkdown>\n );\n};\n\nconst RENDER_LANGUAGES = ['r-markdown', 'r-mermaid', 'r-math'];\n\nconst HIGHLIGHT_LANGUAGES = [\n '', 'javascript', 'typescript', 'python', 'rust', 'go', 'java', 'c', 'cpp',\n 'csharp', 'ruby', 'php', 'swift', 'kotlin', 'sql', 'bash', 'shell',\n 'html', 'css', 'json', 'yaml', 'toml', 'xml', 'markdown', 'mermaid', 'math',\n 'docker', 'graphql', 'latex', 'tex',\n];\n\nconst ALL_LANGUAGES = [...HIGHLIGHT_LANGUAGES, ...RENDER_LANGUAGES];\n\nfunction isRenderLang(lang: string): boolean {\n return RENDER_LANGUAGES.includes(lang);\n}\n\nfunction highlightLang(lang: string): string {\n if (lang === 'math' || lang === 'latex' || lang === 'tex') return 'latex';\n return lang;\n}\n\nconst CodeBlockNodeView: React.FC<NodeViewProps> = ({\n node,\n editor,\n updateAttributes,\n}) => {\n const editable = useNodeEditable(editor);\n const language = node.attrs.language || '';\n const textContent = node.textContent;\n const hasLanguage = !!language;\n const isRenderable = isRenderLang(language);\n\n const [isEditing, setIsEditing] = useState(true);\n\n useEffect(() => {\n if (!hasLanguage) setIsEditing(true);\n }, [language, hasLanguage]);\n\n // Read-only viewers always get the rendered/preview state, never the editor chrome.\n useEffect(() => {\n if (!editable) setIsEditing(false);\n }, [editable]);\n\n const showEditing = isEditing && editable;\n\n const editIcon = (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n );\n const previewIcon = (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n );\n\n const renderPreview = () => {\n if (language === 'r-mermaid') {\n return textContent.trim()\n ? <MermaidRenderer code={textContent} />\n : <p className=\"rte-codeblock__placeholder\">Enter mermaid diagram code...</p>;\n }\n if (language === 'r-math') {\n return textContent.trim()\n ? <KatexRenderer code={textContent} />\n : <p className=\"rte-codeblock__placeholder\">Enter KaTeX math formula...</p>;\n }\n if (language === 'r-markdown') {\n return textContent.trim()\n ? <MarkdownRenderer code={textContent} />\n : <p className=\"rte-codeblock__placeholder\">Enter Markdown content...</p>;\n }\n return null;\n };\n\n const displayLabel = language.startsWith('r-') ? language.slice(2) + ' (render)' : language || 'plain text';\n\n return (\n <NodeViewWrapper className={`rte-codeblock-wrapper ${!isEditing && hasLanguage ? 'rte-codeblock-wrapper--preview' : ''}`}>\n {showEditing ? (\n <>\n <div className=\"rte-codeblock__header\">\n <select\n className=\"rte-codeblock__lang-select\"\n value={language}\n disabled={!editable}\n onChange={(e) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n updateAttributes({ language: e.target.value });\n if (!e.target.value) setIsEditing(true);\n }}\n contentEditable={false}\n >\n <option value=\"\">Plain text</option>\n <optgroup label=\"Syntax Highlight\">\n {HIGHLIGHT_LANGUAGES.filter(Boolean).map((lang) => (\n <option key={lang} value={lang}>{lang}</option>\n ))}\n </optgroup>\n <optgroup label=\"Live Render\">\n {RENDER_LANGUAGES.map((lang) => (\n <option key={lang} value={lang}>{lang}</option>\n ))}\n </optgroup>\n </select>\n {hasLanguage && (\n <button\n type=\"button\"\n className=\"rte-codeblock__preview-btn\"\n onClick={() => setIsEditing(false)}\n contentEditable={false}\n >\n {previewIcon} Preview\n </button>\n )}\n </div>\n <pre className=\"rte-codeblock__editable-pre\">\n <NodeViewContent as={'code' as any} />\n </pre>\n </>\n ) : isRenderable ? (\n <div\n className=\"rte-codeblock__render-preview\"\n contentEditable={false}\n onDoubleClick={() => { if (editable) setIsEditing(true); }}\n >\n <div className=\"rte-codeblock__preview-toolbar\" contentEditable={false}>\n <span className=\"rte-codeblock__preview-label\">{displayLabel}</span>\n {editable && (\n <button\n type=\"button\"\n className=\"rte-codeblock__preview-edit-btn\"\n onClick={() => setIsEditing(true)}\n >\n {editIcon} Edit\n </button>\n )}\n </div>\n <div className=\"rte-codeblock__render-body\">\n {renderPreview()}\n </div>\n </div>\n ) : (\n <div\n className=\"rte-codeblock__syntax-preview\"\n contentEditable={false}\n onDoubleClick={() => { if (editable) setIsEditing(true); }}\n >\n <div className=\"rte-codeblock__preview-toolbar\" contentEditable={false}>\n <span className=\"rte-codeblock__preview-label\">{displayLabel}</span>\n {editable && (\n <button\n type=\"button\"\n className=\"rte-codeblock__preview-edit-btn\"\n onClick={() => setIsEditing(true)}\n >\n {editIcon} Edit\n </button>\n )}\n </div>\n <SyntaxHighlighter\n style={oneLight as Record<string, React.CSSProperties>}\n language={highlightLang(language)}\n PreTag=\"div\"\n customStyle={{\n borderRadius: '0 0 0.5rem 0.5rem',\n fontSize: '0.875em',\n padding: '1em',\n margin: '0',\n }}\n >\n {textContent || ' '}\n </SyntaxHighlighter>\n </div>\n )}\n </NodeViewWrapper>\n );\n};\n\nconst backtickInputRegex = /^```([a-z-]*)[\\s\\n]$/;\nconst tildeInputRegex = /^~~~([a-z-]*)[\\s\\n]$/;\nconst tableShortcutRegex = /^(?:```|~~~)table(?:(\\d+)[x×X*](\\d+))?\\s?$/;\n\nexport const CodeBlockExtension = Node.create({\n name: 'codeBlock',\n group: 'block',\n content: 'text*',\n marks: '',\n code: true,\n defining: true,\n\n addAttributes() {\n return {\n language: {\n default: null,\n parseHTML: (element) => {\n const classAttr = element.querySelector('code')?.className ||\n element.className || '';\n const match = /language-([\\w-]+)/.exec(classAttr);\n return match?.[1] || element.getAttribute('data-language') || null;\n },\n renderHTML: (attributes) => {\n if (!attributes.language) return {};\n return { 'data-language': attributes.language };\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'pre',\n preserveWhitespace: 'full',\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'pre',\n mergeAttributes(HTMLAttributes, { 'data-language': node.attrs.language }),\n ['code', { class: node.attrs.language ? `language-${node.attrs.language}` : undefined }, 0],\n ];\n },\n\n addInputRules() {\n return [\n textblockTypeInputRule({\n find: backtickInputRegex,\n type: this.type,\n getAttributes: (match) => {\n if (match[1]?.startsWith('table')) return false;\n return { language: match[1] || null };\n },\n }),\n textblockTypeInputRule({\n find: tildeInputRegex,\n type: this.type,\n getAttributes: (match) => {\n if (match[1]?.startsWith('table')) return false;\n return { language: match[1] || null };\n },\n }),\n ];\n },\n\n addProseMirrorPlugins() {\n const editorRef = this.editor;\n return [\n new Plugin({\n key: new PluginKey('tableShortcut'),\n props: {\n handleTextInput(view, from, to, text) {\n if (!editorRef.isEditable || text !== ' ') return false;\n const { state } = view;\n const $from = state.doc.resolve(from);\n const blockStart = $from.start();\n const textBefore = state.doc.textBetween(blockStart, from, '\\0');\n const full = textBefore + ' ';\n const m = tableShortcutRegex.exec(full);\n if (!m) return false;\n\n const rows = Math.min(Math.max(parseInt(m[1], 10) || 3, 1), 20);\n const cols = Math.min(Math.max(parseInt(m[2], 10) || 3, 1), 20);\n dispatchTable(view, blockStart, to, rows, cols);\n return true;\n },\n handleKeyDown(view, event) {\n if (!editorRef.isEditable || event.key !== 'Enter') return false;\n const { state } = view;\n const { $from } = state.selection;\n if (!$from.parent.isTextblock) return false;\n const blockStart = $from.start();\n const textBefore = state.doc.textBetween(blockStart, $from.pos, '\\0');\n const m = tableShortcutRegex.exec(textBefore);\n if (!m) return false;\n\n event.preventDefault();\n const rows = Math.min(Math.max(parseInt(m[1], 10) || 3, 1), 20);\n const cols = Math.min(Math.max(parseInt(m[2], 10) || 3, 1), 20);\n dispatchTable(view, blockStart, $from.pos, rows, cols);\n return true;\n },\n },\n }),\n ];\n\n function dispatchTable(view: typeof editorRef.view, from: number, to: number, rows: number, cols: number) {\n const { state } = view;\n const $from = state.doc.resolve(from);\n const blockNode = $from.parent;\n const blockPos = $from.before();\n\n const tableType = state.schema.nodes.table;\n const rowType = state.schema.nodes.tableRow;\n const headerType = state.schema.nodes.tableHeader;\n const cellType = state.schema.nodes.tableCell;\n if (!tableType || !rowType || !cellType) return;\n\n const emptyParagraph = state.schema.nodes.paragraph.create();\n const buildRow = (isHeader: boolean) => {\n const type = isHeader && headerType ? headerType : cellType;\n const cells = Array.from({ length: cols }, () => type.create(null, emptyParagraph));\n return rowType.create(null, cells);\n };\n\n const tableRows = [\n buildRow(true),\n ...Array.from({ length: rows - 1 }, () => buildRow(false)),\n ];\n const table = tableType.create(null, tableRows);\n const tr = state.tr.replaceWith(blockPos, blockPos + blockNode.nodeSize, table);\n view.dispatch(tr);\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Alt-c': () => this.editor.isEditable && this.editor.commands.toggleNode('codeBlock', 'paragraph'),\n Tab: ({ editor }) => {\n if (!editor.isEditable) return false;\n if (editor.isActive('codeBlock')) {\n editor.commands.insertContent('\\t');\n return true;\n }\n return false;\n },\n Enter: ({ editor }) => {\n if (!editor.isEditable) return false;\n if (!editor.isActive('codeBlock')) return false;\n editor.commands.newlineInCode();\n return true;\n },\n ArrowDown: ({ editor }) => {\n if (!editor.isEditable) return false;\n if (!editor.isActive('codeBlock')) return false;\n const { $from } = editor.state.selection;\n const isAtEnd = $from.parentOffset === $from.parent.content.size;\n if (!isAtEnd) return false;\n const after = $from.after();\n if (after === undefined) return false;\n const nodeAfter = editor.state.doc.nodeAt(after);\n if (nodeAfter) return false;\n editor.commands.exitCode();\n return true;\n },\n };\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(CodeBlockNodeView);\n },\n});\n\nexport default CodeBlockExtension;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeBlockView.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/extensions/CodeBlockView.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { Node, mergeAttributes, textblockTypeInputRule } from '@tiptap/react';\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\nimport { NodeViewWrapper, NodeViewContent, ReactNodeViewRenderer } from '@tiptap/react';\nimport type { NodeViewProps } from '@tiptap/react';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\nimport { MermaidRenderer, useNodeEditable } from './MarkdownBlock';\nimport 'katex/dist/katex.min.css';\n\n\nconst KatexRenderer: React.FC<{ code: string }> = ({ code }) => {\n const wrapped = code.includes('$$') ? code : `$$\\n${code}\\n$$`;\n return (\n <ReactMarkdown\n remarkPlugins={[remarkMath]}\n rehypePlugins={[rehypeKatex]}\n >\n {wrapped}\n </ReactMarkdown>\n );\n};\n\nconst MarkdownRenderer: React.FC<{ code: string }> = ({ code }) => {\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm, remarkMath]}\n rehypePlugins={[rehypeKatex]}\n components={{\n code({ className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || '');\n const lang = match?.[1];\n const text = String(children).replace(/\\n$/, '');\n\n if (lang === 'mermaid') return <MermaidRenderer code={text} />;\n\n if (lang) {\n return (\n <SyntaxHighlighter\n style={oneLight as Record<string, React.CSSProperties>}\n language={lang}\n PreTag=\"div\"\n customStyle={{ borderRadius: '0.5rem', fontSize: '0.875em', padding: '1em', margin: '0.5em 0' }}\n >\n {text}\n </SyntaxHighlighter>\n );\n }\n return <code className={className} {...props}>{children}</code>;\n },\n }}\n >\n {code}\n </ReactMarkdown>\n );\n};\n\nconst RENDER_LANGUAGES = ['markdown', 'mermaid', 'math'];\n\nconst HIGHLIGHT_LANGUAGES = [\n '', 'javascript', 'typescript', 'python', 'rust', 'go', 'java', 'c', 'cpp',\n 'csharp', 'ruby', 'php', 'swift', 'kotlin', 'sql', 'bash', 'shell',\n 'html', 'css', 'json', 'yaml', 'toml', 'xml',\n 'docker', 'graphql', 'latex', 'tex',\n];\n\nfunction renderLang(lang: string): string {\n // Legacy documents keep their r- attributes; the selector uses canonical names.\n const canonical = lang.startsWith('r-') ? lang.slice(2) : lang;\n return RENDER_LANGUAGES.includes(canonical) ? canonical : '';\n}\n\nfunction highlightLang(lang: string): string {\n if (lang === 'math' || lang === 'latex' || lang === 'tex') return 'latex';\n return lang;\n}\n\nconst CodeBlockNodeView: React.FC<NodeViewProps> = ({\n node,\n editor,\n updateAttributes,\n}) => {\n const editable = useNodeEditable(editor);\n const language = node.attrs.language || '';\n const textContent = node.textContent;\n const hasLanguage = !!language;\n const renderLanguage = renderLang(language);\n const isRenderable = !!renderLanguage;\n\n const [isEditing, setIsEditing] = useState(true);\n\n useEffect(() => {\n if (!hasLanguage) setIsEditing(true);\n }, [language, hasLanguage]);\n\n // Read-only viewers always get the rendered/preview state, never the editor chrome.\n useEffect(() => {\n if (!editable) setIsEditing(false);\n }, [editable]);\n\n const showEditing = isEditing && editable;\n\n const editIcon = (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n );\n const previewIcon = (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n );\n\n const renderPreview = () => {\n if (renderLanguage === 'mermaid') {\n return textContent.trim()\n ? <MermaidRenderer code={textContent} />\n : <p className=\"rte-codeblock__placeholder\">Enter mermaid diagram code...</p>;\n }\n if (renderLanguage === 'math') {\n return textContent.trim()\n ? <KatexRenderer code={textContent} />\n : <p className=\"rte-codeblock__placeholder\">Enter KaTeX math formula...</p>;\n }\n if (renderLanguage === 'markdown') {\n return textContent.trim()\n ? <MarkdownRenderer code={textContent} />\n : <p className=\"rte-codeblock__placeholder\">Enter Markdown content...</p>;\n }\n return null;\n };\n\n const displayLabel = renderLanguage ? renderLanguage + ' (render)' : language || 'plain text';\n\n return (\n <NodeViewWrapper className={`rte-codeblock-wrapper ${!isEditing && hasLanguage ? 'rte-codeblock-wrapper--preview' : ''}`}>\n {showEditing ? (\n <>\n <div className=\"rte-codeblock__header\">\n <select\n className=\"rte-codeblock__lang-select\"\n value={renderLanguage || language}\n disabled={!editable}\n onChange={(e) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n updateAttributes({ language: e.target.value });\n if (!e.target.value) setIsEditing(true);\n }}\n contentEditable={false}\n >\n <option value=\"\">Plain text</option>\n <optgroup label=\"Syntax Highlight\">\n {HIGHLIGHT_LANGUAGES.filter(Boolean).map((lang) => (\n <option key={lang} value={lang}>{lang}</option>\n ))}\n </optgroup>\n <optgroup label=\"Live Render\">\n {RENDER_LANGUAGES.map((lang) => (\n <option key={lang} value={lang}>{lang}</option>\n ))}\n </optgroup>\n </select>\n {hasLanguage && (\n <button\n type=\"button\"\n className=\"rte-codeblock__preview-btn\"\n onClick={() => setIsEditing(false)}\n contentEditable={false}\n >\n {previewIcon} Preview\n </button>\n )}\n </div>\n <pre className=\"rte-codeblock__editable-pre\">\n <NodeViewContent as={'code' as any} />\n </pre>\n </>\n ) : isRenderable ? (\n <div\n className=\"rte-codeblock__render-preview\"\n contentEditable={false}\n onDoubleClick={() => { if (editable) setIsEditing(true); }}\n >\n <div className=\"rte-codeblock__preview-toolbar\" contentEditable={false}>\n <span className=\"rte-codeblock__preview-label\">{displayLabel}</span>\n {editable && (\n <button\n type=\"button\"\n className=\"rte-codeblock__preview-edit-btn\"\n onClick={() => setIsEditing(true)}\n >\n {editIcon} Edit\n </button>\n )}\n </div>\n <div className=\"rte-codeblock__render-body\">\n {renderPreview()}\n </div>\n {/* 预览分支也必须挂载 contentDOM(隐藏):不渲染 NodeViewContent 时\n tiptap 会把代码文本以 data-node-view-content-react 形式再渲染\n 一份裸露副本,只读 / 预览下出现重复的原始代码。 */}\n <div style={{ display: 'none' }} aria-hidden=\"true\">\n <NodeViewContent as={'code' as any} />\n </div>\n </div>\n ) : (\n <div\n className=\"rte-codeblock__syntax-preview\"\n contentEditable={false}\n onDoubleClick={() => { if (editable) setIsEditing(true); }}\n >\n <div className=\"rte-codeblock__preview-toolbar\" contentEditable={false}>\n <span className=\"rte-codeblock__preview-label\">{displayLabel}</span>\n {editable && (\n <button\n type=\"button\"\n className=\"rte-codeblock__preview-edit-btn\"\n onClick={() => setIsEditing(true)}\n >\n {editIcon} Edit\n </button>\n )}\n </div>\n <SyntaxHighlighter\n style={oneLight as Record<string, React.CSSProperties>}\n language={highlightLang(language)}\n PreTag=\"div\"\n customStyle={{\n borderRadius: '0 0 0.5rem 0.5rem',\n fontSize: '0.875em',\n padding: '1em',\n margin: '0',\n }}\n >\n {textContent || ' '}\n </SyntaxHighlighter>\n <div style={{ display: 'none' }} aria-hidden=\"true\">\n <NodeViewContent as={'code' as any} />\n </div>\n </div>\n )}\n </NodeViewWrapper>\n );\n};\n\nconst backtickInputRegex = /^```([a-z-]*)[\\s\\n]$/;\nconst tildeInputRegex = /^~~~([a-z-]*)[\\s\\n]$/;\nconst tableShortcutRegex = /^(?:```|~~~)table(?:(\\d+)[x×X*](\\d+))?\\s?$/;\n\nexport const CodeBlockExtension = Node.create({\n name: 'codeBlock',\n group: 'block',\n content: 'text*',\n marks: '',\n code: true,\n defining: true,\n\n addAttributes() {\n return {\n language: {\n default: null,\n parseHTML: (element) => {\n const classAttr = element.querySelector('code')?.className ||\n element.className || '';\n const match = /language-([\\w-]+)/.exec(classAttr);\n return match?.[1] || element.getAttribute('data-language') || null;\n },\n renderHTML: (attributes) => {\n if (!attributes.language) return {};\n return { 'data-language': attributes.language };\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'pre',\n preserveWhitespace: 'full',\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'pre',\n mergeAttributes(HTMLAttributes, { 'data-language': node.attrs.language }),\n ['code', { class: node.attrs.language ? `language-${node.attrs.language}` : undefined }, 0],\n ];\n },\n\n addInputRules() {\n return [\n textblockTypeInputRule({\n find: backtickInputRegex,\n type: this.type,\n getAttributes: (match) => {\n if (match[1]?.startsWith('table')) return false;\n return { language: match[1] || null };\n },\n }),\n textblockTypeInputRule({\n find: tildeInputRegex,\n type: this.type,\n getAttributes: (match) => {\n if (match[1]?.startsWith('table')) return false;\n return { language: match[1] || null };\n },\n }),\n ];\n },\n\n addProseMirrorPlugins() {\n const editorRef = this.editor;\n return [\n new Plugin({\n key: new PluginKey('tableShortcut'),\n props: {\n handleTextInput(view, from, to, text) {\n if (!editorRef.isEditable || text !== ' ') return false;\n const { state } = view;\n const $from = state.doc.resolve(from);\n const blockStart = $from.start();\n const textBefore = state.doc.textBetween(blockStart, from, '\\0');\n const full = textBefore + ' ';\n const m = tableShortcutRegex.exec(full);\n if (!m) return false;\n\n const rows = Math.min(Math.max(parseInt(m[1], 10) || 3, 1), 20);\n const cols = Math.min(Math.max(parseInt(m[2], 10) || 3, 1), 20);\n dispatchTable(view, blockStart, to, rows, cols);\n return true;\n },\n handleKeyDown(view, event) {\n if (!editorRef.isEditable || event.key !== 'Enter') return false;\n const { state } = view;\n const { $from } = state.selection;\n if (!$from.parent.isTextblock) return false;\n const blockStart = $from.start();\n const textBefore = state.doc.textBetween(blockStart, $from.pos, '\\0');\n const m = tableShortcutRegex.exec(textBefore);\n if (!m) return false;\n\n event.preventDefault();\n const rows = Math.min(Math.max(parseInt(m[1], 10) || 3, 1), 20);\n const cols = Math.min(Math.max(parseInt(m[2], 10) || 3, 1), 20);\n dispatchTable(view, blockStart, $from.pos, rows, cols);\n return true;\n },\n },\n }),\n ];\n\n function dispatchTable(view: typeof editorRef.view, from: number, to: number, rows: number, cols: number) {\n const { state } = view;\n const $from = state.doc.resolve(from);\n const blockNode = $from.parent;\n const blockPos = $from.before();\n\n const tableType = state.schema.nodes.table;\n const rowType = state.schema.nodes.tableRow;\n const headerType = state.schema.nodes.tableHeader;\n const cellType = state.schema.nodes.tableCell;\n if (!tableType || !rowType || !cellType) return;\n\n const emptyParagraph = state.schema.nodes.paragraph.create();\n const buildRow = (isHeader: boolean) => {\n const type = isHeader && headerType ? headerType : cellType;\n const cells = Array.from({ length: cols }, () => type.create(null, emptyParagraph));\n return rowType.create(null, cells);\n };\n\n const tableRows = [\n buildRow(true),\n ...Array.from({ length: rows - 1 }, () => buildRow(false)),\n ];\n const table = tableType.create(null, tableRows);\n const tr = state.tr.replaceWith(blockPos, blockPos + blockNode.nodeSize, table);\n view.dispatch(tr);\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Alt-c': () => this.editor.isEditable && this.editor.commands.toggleNode('codeBlock', 'paragraph'),\n Tab: ({ editor }) => {\n if (!editor.isEditable) return false;\n if (editor.isActive('codeBlock')) {\n editor.commands.insertContent('\\t');\n return true;\n }\n return false;\n },\n Enter: ({ editor }) => {\n if (!editor.isEditable) return false;\n if (!editor.isActive('codeBlock')) return false;\n editor.commands.newlineInCode();\n return true;\n },\n ArrowDown: ({ editor }) => {\n if (!editor.isEditable) return false;\n if (!editor.isActive('codeBlock')) return false;\n const { $from } = editor.state.selection;\n const isAtEnd = $from.parentOffset === $from.parent.content.size;\n if (!isAtEnd) return false;\n const after = $from.after();\n if (after === undefined) return false;\n const nodeAfter = editor.state.doc.nodeAt(after);\n if (nodeAfter) return false;\n editor.commands.exitCode();\n return true;\n },\n };\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(CodeBlockNodeView);\n },\n});\n\nexport default CodeBlockExtension;\n"],"mappings":"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"}
|
|
@@ -220,17 +220,7 @@ function h(e) {
|
|
|
220
220
|
var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }) => {
|
|
221
221
|
let v = t(d), y = n((e) => {
|
|
222
222
|
!d.isDestroyed && d.isEditable && f(e);
|
|
223
|
-
}, [d, f]), b = i(null), x = c.attrs, S = x.layout || "block", C = S === "float", w = x.zIndex ?? 10, [T, E] = a(!1), [D, O] = a(x.title), [k, A] = a(!1), [j, M] = a(!1), N = i(
|
|
224
|
-
mx: 0,
|
|
225
|
-
my: 0,
|
|
226
|
-
x: 0,
|
|
227
|
-
y: 0
|
|
228
|
-
}), P = i({
|
|
229
|
-
mx: 0,
|
|
230
|
-
my: 0,
|
|
231
|
-
w: 0,
|
|
232
|
-
h: 0
|
|
233
|
-
}), F = i(null), I = i(null);
|
|
223
|
+
}, [d, f]), b = i(null), x = c.attrs, S = x.layout || "block", C = S === "float", w = x.zIndex ?? 10, [T, E] = a(!1), [D, O] = a(x.title), [k, A] = a(!1), [j, M] = a(!1), N = i(null), P = i(null);
|
|
234
224
|
r(() => {
|
|
235
225
|
O(x.title);
|
|
236
226
|
}, [x.title]), r(() => {
|
|
@@ -242,95 +232,78 @@ var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }
|
|
|
242
232
|
};
|
|
243
233
|
}, [d]), r(() => {
|
|
244
234
|
let e = (e) => {
|
|
245
|
-
|
|
235
|
+
N.current && !N.current.contains(e.target) && A(!1), P.current && !P.current.contains(e.target) && M(!1);
|
|
246
236
|
};
|
|
247
237
|
return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
|
|
248
238
|
}, []);
|
|
249
|
-
let
|
|
250
|
-
if (
|
|
251
|
-
b.current?.(), e.preventDefault(), e.stopPropagation()
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
y
|
|
239
|
+
let F = n((e, t) => {
|
|
240
|
+
if (d.isDestroyed || !d.isEditable || !e.isPrimary || e.button !== 0 || !t && (!C || e.target.closest("button, input"))) return;
|
|
241
|
+
b.current?.(), e.preventDefault(), e.stopPropagation();
|
|
242
|
+
let n = e.currentTarget, r = n.ownerDocument, i = e.pointerId, { clientX: a, clientY: o } = e, s = t ? x.width : x.x, c = t ? x.height : x.y, l = s, u = c, f = (e) => {
|
|
243
|
+
if (e.pointerId !== i) return;
|
|
244
|
+
let n = t ? Math.max(160, l + e.clientX - a) : l + e.clientX - a, r = t ? Math.max(80, u + e.clientY - o) : u + e.clientY - o;
|
|
245
|
+
(n !== s || r !== c) && (s = n, c = r, y(t ? {
|
|
246
|
+
width: n,
|
|
247
|
+
height: r
|
|
248
|
+
} : {
|
|
249
|
+
x: n,
|
|
250
|
+
y: r
|
|
251
|
+
}));
|
|
252
|
+
}, p = () => {
|
|
253
|
+
r.removeEventListener("pointermove", f), r.removeEventListener("pointerup", m), r.removeEventListener("pointercancel", m), n.removeEventListener("lostpointercapture", m), b.current = null, n.hasPointerCapture(i) && n.releasePointerCapture(i);
|
|
254
|
+
}, m = (e) => {
|
|
255
|
+
e.pointerId === i && p();
|
|
256
256
|
};
|
|
257
|
-
|
|
258
|
-
let t = e.clientX - N.current.mx, n = e.clientY - N.current.my;
|
|
259
|
-
y({
|
|
260
|
-
x: N.current.x + t,
|
|
261
|
-
y: N.current.y + n
|
|
262
|
-
});
|
|
263
|
-
}, n = () => {
|
|
264
|
-
document.removeEventListener("mousemove", t), document.removeEventListener("mouseup", n);
|
|
265
|
-
};
|
|
266
|
-
document.addEventListener("mousemove", t), document.addEventListener("mouseup", n), b.current = n;
|
|
257
|
+
n.setPointerCapture(i), r.addEventListener("pointermove", f), r.addEventListener("pointerup", m), r.addEventListener("pointercancel", m), n.addEventListener("lostpointercapture", m), b.current = p;
|
|
267
258
|
}, [
|
|
268
259
|
d,
|
|
269
260
|
C,
|
|
270
261
|
x.x,
|
|
271
262
|
x.y,
|
|
272
|
-
y
|
|
273
|
-
]), R = n((e) => {
|
|
274
|
-
if (d.isDestroyed || !d.isEditable || e.button !== 0) return;
|
|
275
|
-
b.current?.(), e.preventDefault(), e.stopPropagation(), P.current = {
|
|
276
|
-
mx: e.clientX,
|
|
277
|
-
my: e.clientY,
|
|
278
|
-
w: x.width,
|
|
279
|
-
h: x.height
|
|
280
|
-
};
|
|
281
|
-
let t = (e) => {
|
|
282
|
-
let t = e.clientX - P.current.mx, n = e.clientY - P.current.my;
|
|
283
|
-
y({
|
|
284
|
-
width: Math.max(160, P.current.w + t),
|
|
285
|
-
height: Math.max(80, P.current.h + n)
|
|
286
|
-
});
|
|
287
|
-
}, n = () => {
|
|
288
|
-
document.removeEventListener("mousemove", t), document.removeEventListener("mouseup", n);
|
|
289
|
-
};
|
|
290
|
-
document.addEventListener("mousemove", t), document.addEventListener("mouseup", n), b.current = n;
|
|
291
|
-
}, [
|
|
292
|
-
d,
|
|
293
263
|
x.width,
|
|
294
264
|
x.height,
|
|
295
265
|
y
|
|
296
|
-
]),
|
|
266
|
+
]), I = n(() => {
|
|
297
267
|
y({ title: D }), E(!1);
|
|
298
|
-
}, [D, y]),
|
|
268
|
+
}, [D, y]), L = n(() => {
|
|
299
269
|
let e = h(d), t = Math.max(...e);
|
|
300
270
|
w < t && y({ zIndex: t + 1 });
|
|
301
271
|
}, [
|
|
302
272
|
d,
|
|
303
273
|
w,
|
|
304
274
|
y
|
|
305
|
-
]),
|
|
275
|
+
]), R = n(() => {
|
|
306
276
|
let e = h(d), t = Math.min(...e);
|
|
307
277
|
w > t ? y({ zIndex: t - 1 }) : w > 1 && y({ zIndex: w - 1 });
|
|
308
278
|
}, [
|
|
309
279
|
d,
|
|
310
280
|
w,
|
|
311
281
|
y
|
|
312
|
-
]),
|
|
282
|
+
]), z = e("rte-float-dialog", `rte-float-dialog--${S}`, _ && "rte-float-dialog--selected"), B = C ? {
|
|
313
283
|
position: "absolute",
|
|
314
284
|
left: x.x,
|
|
315
285
|
top: x.y,
|
|
316
286
|
zIndex: w
|
|
317
|
-
} : {},
|
|
287
|
+
} : {}, V = {
|
|
318
288
|
width: S === "block" ? "100%" : x.width,
|
|
319
289
|
minHeight: x.height,
|
|
320
290
|
borderColor: x.borderColor,
|
|
321
291
|
backgroundColor: x.bgColor
|
|
322
|
-
},
|
|
292
|
+
}, H = m.find((e) => e.key === S)?.icon;
|
|
323
293
|
return /* @__PURE__ */ o(u, {
|
|
324
|
-
className:
|
|
325
|
-
style:
|
|
294
|
+
className: z,
|
|
295
|
+
style: B,
|
|
326
296
|
children: /* @__PURE__ */ s("div", {
|
|
327
297
|
className: "rte-float-dialog__box",
|
|
328
|
-
style:
|
|
298
|
+
style: V,
|
|
329
299
|
children: [
|
|
330
300
|
/* @__PURE__ */ s("div", {
|
|
331
301
|
className: "rte-float-dialog__titlebar",
|
|
332
|
-
style: {
|
|
333
|
-
|
|
302
|
+
style: {
|
|
303
|
+
borderBottomColor: x.borderColor,
|
|
304
|
+
touchAction: C && v ? "none" : void 0
|
|
305
|
+
},
|
|
306
|
+
onPointerDown: (e) => F(e, !1),
|
|
334
307
|
contentEditable: !1,
|
|
335
308
|
children: [
|
|
336
309
|
C && /* @__PURE__ */ o("span", {
|
|
@@ -382,9 +355,10 @@ var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }
|
|
|
382
355
|
onChange: (e) => O(e.target.value),
|
|
383
356
|
placeholder: "Title...",
|
|
384
357
|
onMouseDown: (e) => e.stopPropagation(),
|
|
385
|
-
|
|
358
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
359
|
+
onBlur: I,
|
|
386
360
|
onKeyDown: (e) => {
|
|
387
|
-
(e.key === "Enter" || e.key === "Escape") &&
|
|
361
|
+
(e.key === "Enter" || e.key === "Escape") && I();
|
|
388
362
|
},
|
|
389
363
|
autoFocus: !0
|
|
390
364
|
}) : /* @__PURE__ */ o("span", {
|
|
@@ -396,6 +370,7 @@ var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }
|
|
|
396
370
|
}),
|
|
397
371
|
v && /* @__PURE__ */ s("div", {
|
|
398
372
|
className: "rte-float-dialog__actions",
|
|
373
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
399
374
|
children: [
|
|
400
375
|
C && /* @__PURE__ */ s("div", {
|
|
401
376
|
className: "rte-float-dialog__zorder",
|
|
@@ -403,7 +378,7 @@ var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }
|
|
|
403
378
|
type: "button",
|
|
404
379
|
className: "rte-float-dialog__action-btn",
|
|
405
380
|
onClick: (e) => {
|
|
406
|
-
e.stopPropagation(),
|
|
381
|
+
e.stopPropagation(), L();
|
|
407
382
|
},
|
|
408
383
|
title: "Bring to Front",
|
|
409
384
|
onMouseDown: (e) => e.stopPropagation(),
|
|
@@ -433,7 +408,7 @@ var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }
|
|
|
433
408
|
type: "button",
|
|
434
409
|
className: "rte-float-dialog__action-btn",
|
|
435
410
|
onClick: (e) => {
|
|
436
|
-
e.stopPropagation(),
|
|
411
|
+
e.stopPropagation(), R();
|
|
437
412
|
},
|
|
438
413
|
title: "Send to Back",
|
|
439
414
|
onMouseDown: (e) => e.stopPropagation(),
|
|
@@ -462,7 +437,7 @@ var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }
|
|
|
462
437
|
})]
|
|
463
438
|
}),
|
|
464
439
|
/* @__PURE__ */ s("div", {
|
|
465
|
-
ref:
|
|
440
|
+
ref: P,
|
|
466
441
|
style: { position: "relative" },
|
|
467
442
|
children: [/* @__PURE__ */ o("button", {
|
|
468
443
|
type: "button",
|
|
@@ -472,7 +447,7 @@ var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }
|
|
|
472
447
|
},
|
|
473
448
|
title: `Layout: ${S}`,
|
|
474
449
|
onMouseDown: (e) => e.stopPropagation(),
|
|
475
|
-
children:
|
|
450
|
+
children: H
|
|
476
451
|
}), j && /* @__PURE__ */ o("div", {
|
|
477
452
|
className: "rte-float-dialog__layout-dropdown",
|
|
478
453
|
onMouseDown: (e) => e.stopPropagation(),
|
|
@@ -488,7 +463,7 @@ var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }
|
|
|
488
463
|
})]
|
|
489
464
|
}),
|
|
490
465
|
/* @__PURE__ */ s("div", {
|
|
491
|
-
ref:
|
|
466
|
+
ref: N,
|
|
492
467
|
style: { position: "relative" },
|
|
493
468
|
children: [/* @__PURE__ */ o("button", {
|
|
494
469
|
type: "button",
|
|
@@ -563,7 +538,7 @@ var g = ({ node: c, editor: d, updateAttributes: f, deleteNode: g, selected: _ }
|
|
|
563
538
|
/* @__PURE__ */ o(l, { className: "rte-float-dialog__body" }),
|
|
564
539
|
v && /* @__PURE__ */ o("div", {
|
|
565
540
|
className: "rte-float-dialog__resize-handle",
|
|
566
|
-
|
|
541
|
+
onPointerDown: (e) => F(e, !0),
|
|
567
542
|
contentEditable: !1,
|
|
568
543
|
children: /* @__PURE__ */ s("svg", {
|
|
569
544
|
width: "10",
|