dishui 0.0.76 → 0.0.77

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.
@@ -1,24 +1,25 @@
1
- import { useCallback as e, useEffect as t, useRef as n, useState as r, useSyncExternalStore as i } from "react";
2
- import { jsx as a, jsxs as o } from "react/jsx-runtime";
3
- import { Prism as s } from "react-syntax-highlighter";
4
- import { oneLight as c } from "react-syntax-highlighter/dist/esm/styles/prism";
5
- import l from "react-markdown";
6
- import u from "remark-gfm";
7
- import d from "rehype-katex";
8
- import f from "remark-math";
9
- import p from "mermaid";
1
+ import { normalizeLegacyMermaid as e } from "./legacyMermaid.js";
2
+ import { useCallback as t, useEffect as n, useRef as r, useState as i, useSyncExternalStore as a } from "react";
3
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
+ import { Prism as c } from "react-syntax-highlighter";
5
+ import { oneLight as l } from "react-syntax-highlighter/dist/esm/styles/prism";
6
+ import u from "react-markdown";
7
+ import d from "remark-gfm";
8
+ import f from "rehype-katex";
9
+ import p from "remark-math";
10
+ import m from "mermaid";
10
11
  import "katex/dist/katex.min.css";
11
- import { Node as m, NodeViewWrapper as h, ReactNodeViewRenderer as g, mergeAttributes as _ } from "@tiptap/react";
12
+ import { Node as h, NodeViewWrapper as g, ReactNodeViewRenderer as _, mergeAttributes as v } from "@tiptap/react";
12
13
  //#region src/components/pro/RichTextEditor/extensions/MarkdownBlock.tsx
13
- function v(t) {
14
- let n = e((e) => (t.on("update", e), t.on("transaction", e), t.on("destroy", e), () => {
15
- t.off("update", e), t.off("transaction", e), t.off("destroy", e);
16
- }), [t]);
17
- return i(n, () => !t.isDestroyed && t.isEditable, () => !1);
14
+ function y(e) {
15
+ let n = t((t) => (e.on("update", t), e.on("transaction", t), e.on("destroy", t), () => {
16
+ e.off("update", t), e.off("transaction", t), e.off("destroy", t);
17
+ }), [e]);
18
+ return a(n, () => !e.isDestroyed && e.isEditable, () => !1);
18
19
  }
19
- var y = Promise.resolve();
20
- function b(e, t) {
21
- let n = y.then(() => (p.initialize({
20
+ var b = Promise.resolve();
21
+ function x(e, t) {
22
+ let n = b.then(() => (m.initialize({
22
23
  startOnLoad: !1,
23
24
  theme: "default",
24
25
  securityLevel: "strict",
@@ -28,35 +29,35 @@ function b(e, t) {
28
29
  useMaxWidth: !0,
29
30
  htmlLabels: !1
30
31
  }
31
- }), p.mermaidAPI.render(e, t)));
32
- return y = n.catch(() => void 0), n;
32
+ }), m.mermaidAPI.render(e, t)));
33
+ return b = n.catch(() => void 0), n;
33
34
  }
34
- var x = ({ code: e }) => {
35
- let r = n(null);
36
- return t(() => {
37
- if (!r.current || (r.current.replaceChildren(), !e.trim())) return;
38
- let t = !1;
35
+ var S = ({ code: t }) => {
36
+ let i = r(null);
37
+ return n(() => {
38
+ if (!i.current || (i.current.replaceChildren(), !t.trim())) return;
39
+ let n = !1;
39
40
  return (async () => {
40
41
  try {
41
- let { svg: n } = await b(`mermaid-md-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, e);
42
- !t && r.current && (r.current.innerHTML = n);
42
+ let { svg: r } = await x(`mermaid-md-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`, e(t));
43
+ !n && i.current && (i.current.innerHTML = r);
43
44
  } catch (e) {
44
- !t && r.current && (r.current.textContent = String(e));
45
+ !n && i.current && (i.current.textContent = String(e));
45
46
  }
46
47
  })(), () => {
47
- t = !0;
48
+ n = !0;
48
49
  };
49
- }, [e]), /* @__PURE__ */ a("div", {
50
- ref: r,
50
+ }, [t]), /* @__PURE__ */ o("div", {
51
+ ref: i,
51
52
  className: "rte-mermaid-container"
52
53
  });
53
- }, S = ({ content: e }) => /* @__PURE__ */ a(l, {
54
- remarkPlugins: [u, f],
55
- rehypePlugins: [d],
54
+ }, C = ({ content: e }) => /* @__PURE__ */ o(u, {
55
+ remarkPlugins: [d, p],
56
+ rehypePlugins: [f],
56
57
  components: { code({ className: e, children: t, ...n }) {
57
58
  let r = /language-(\w+)/.exec(e || "")?.[1], i = String(t).replace(/\n$/, "");
58
- return r === "mermaid" ? /* @__PURE__ */ a(x, { code: i }) : r ? /* @__PURE__ */ a(s, {
59
- style: c,
59
+ return r === "mermaid" ? /* @__PURE__ */ o(S, { code: i }) : r ? /* @__PURE__ */ o(c, {
60
+ style: l,
60
61
  language: r,
61
62
  PreTag: "div",
62
63
  customStyle: {
@@ -66,51 +67,51 @@ var x = ({ code: e }) => {
66
67
  margin: "0.5em 0"
67
68
  },
68
69
  children: i
69
- }) : /* @__PURE__ */ a("code", {
70
+ }) : /* @__PURE__ */ o("code", {
70
71
  className: e,
71
72
  ...n,
72
73
  children: t
73
74
  });
74
75
  } },
75
76
  children: e
76
- }), C = ({ node: i, editor: s, updateAttributes: c, selected: l }) => {
77
- let u = v(s), [d, f] = r(!1), [p, m] = r(i.attrs.content || ""), g = n(null);
78
- t(() => {
79
- m(i.attrs.content || ""), f(!1);
80
- }, [i.attrs.content, u]), t(() => {
81
- d && g.current && (g.current.focus(), _(g.current));
77
+ }), w = ({ node: e, editor: a, updateAttributes: c, selected: l }) => {
78
+ let u = y(a), [d, f] = i(!1), [p, m] = i(e.attrs.content || ""), h = r(null);
79
+ n(() => {
80
+ m(e.attrs.content || ""), f(!1);
81
+ }, [e.attrs.content, u]), n(() => {
82
+ d && h.current && (h.current.focus(), _(h.current));
82
83
  }, [d]);
83
84
  let _ = (e) => {
84
85
  e.style.height = "auto", e.style.height = e.scrollHeight + "px";
85
- }, y = e((e) => {
86
+ }, v = t((e) => {
86
87
  m(e.target.value), _(e.target);
87
- }, []), b = e(() => {
88
- !s.isDestroyed && s.isEditable && c({ content: p }), f(!1);
88
+ }, []), b = t(() => {
89
+ !a.isDestroyed && a.isEditable && c({ content: p }), f(!1);
89
90
  }, [
90
- s,
91
+ a,
91
92
  p,
92
93
  c
93
- ]), x = e((e) => {
94
+ ]), x = t((e) => {
94
95
  e.key === "Escape" && b();
95
- }, [b]), C = p || "# Markdown Block\n\nWrite your **markdown** here.\n\n```mermaid\ngraph LR\n A[Start] --> B[End]\n```\n";
96
- return /* @__PURE__ */ o(h, {
96
+ }, [b]), S = p || "# Markdown Block\n\nWrite your **markdown** here.\n\n```mermaid\ngraph LR\n A[Start] --> B[End]\n```\n";
97
+ return /* @__PURE__ */ s(g, {
97
98
  contentEditable: !1,
98
99
  className: `rte-markdown-block ${l ? "rte-markdown-block--selected" : ""}`,
99
- children: [/* @__PURE__ */ o("div", {
100
+ children: [/* @__PURE__ */ s("div", {
100
101
  className: "rte-markdown-block__header",
101
- children: [/* @__PURE__ */ a("span", {
102
+ children: [/* @__PURE__ */ o("span", {
102
103
  className: "rte-markdown-block__label",
103
104
  children: "Markdown"
104
- }), /* @__PURE__ */ o("button", {
105
+ }), /* @__PURE__ */ s("button", {
105
106
  type: "button",
106
107
  className: `rte-markdown-block__toggle ${d ? "rte-markdown-block__toggle--active" : ""}`,
107
108
  disabled: !u,
108
109
  onMouseDown: (e) => e.preventDefault(),
109
110
  onClick: () => {
110
- !s.isDestroyed && s.isEditable && (d && c({ content: p }), f(!d));
111
+ !a.isDestroyed && a.isEditable && (d && c({ content: p }), f(!d));
111
112
  },
112
113
  title: d ? "Preview" : "Edit",
113
- children: [d ? /* @__PURE__ */ o("svg", {
114
+ children: [d ? /* @__PURE__ */ s("svg", {
114
115
  width: "14",
115
116
  height: "14",
116
117
  viewBox: "0 0 24 24",
@@ -119,12 +120,12 @@ var x = ({ code: e }) => {
119
120
  strokeWidth: "2",
120
121
  strokeLinecap: "round",
121
122
  strokeLinejoin: "round",
122
- children: [/* @__PURE__ */ a("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }), /* @__PURE__ */ a("circle", {
123
+ children: [/* @__PURE__ */ o("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }), /* @__PURE__ */ o("circle", {
123
124
  cx: "12",
124
125
  cy: "12",
125
126
  r: "3"
126
127
  })]
127
- }) : /* @__PURE__ */ o("svg", {
128
+ }) : /* @__PURE__ */ s("svg", {
128
129
  width: "14",
129
130
  height: "14",
130
131
  viewBox: "0 0 24 24",
@@ -133,33 +134,33 @@ var x = ({ code: e }) => {
133
134
  strokeWidth: "2",
134
135
  strokeLinecap: "round",
135
136
  strokeLinejoin: "round",
136
- 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" })]
137
- }), /* @__PURE__ */ a("span", { children: d ? "Preview" : "Edit" })]
137
+ children: [/* @__PURE__ */ o("path", { d: "M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7" }), /* @__PURE__ */ o("path", { d: "M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z" })]
138
+ }), /* @__PURE__ */ o("span", { children: d ? "Preview" : "Edit" })]
138
139
  })]
139
- }), /* @__PURE__ */ a("div", {
140
+ }), /* @__PURE__ */ o("div", {
140
141
  className: "rte-markdown-block__body",
141
- children: d && u ? /* @__PURE__ */ a("textarea", {
142
- ref: g,
142
+ children: d && u ? /* @__PURE__ */ o("textarea", {
143
+ ref: h,
143
144
  className: "rte-markdown-block__editor",
144
145
  value: p,
145
- onChange: y,
146
+ onChange: v,
146
147
  onBlur: b,
147
148
  onKeyDown: x,
148
149
  placeholder: "Enter Markdown content...",
149
150
  rows: 5
150
- }) : /* @__PURE__ */ a("div", {
151
+ }) : /* @__PURE__ */ o("div", {
151
152
  className: "rte-markdown-block__preview prose",
152
153
  onDoubleClick: () => {
153
- !s.isDestroyed && s.isEditable && f(!0);
154
+ !a.isDestroyed && a.isEditable && f(!0);
154
155
  },
155
- children: C.trim() ? /* @__PURE__ */ a(S, { content: C }) : /* @__PURE__ */ a("p", {
156
+ children: S.trim() ? /* @__PURE__ */ o(C, { content: S }) : /* @__PURE__ */ o("p", {
156
157
  className: "rte-markdown-block__placeholder",
157
158
  children: "Double-click to edit Markdown content..."
158
159
  })
159
160
  })
160
161
  })]
161
162
  });
162
- }, w = m.create({
163
+ }, T = h.create({
163
164
  name: "markdownBlock",
164
165
  group: "block",
165
166
  atom: !0,
@@ -171,13 +172,13 @@ var x = ({ code: e }) => {
171
172
  return [{ tag: "div[data-type=\"markdown-block\"]" }];
172
173
  },
173
174
  renderHTML({ HTMLAttributes: e }) {
174
- return ["div", _(e, { "data-type": "markdown-block" })];
175
+ return ["div", v(e, { "data-type": "markdown-block" })];
175
176
  },
176
177
  addNodeView() {
177
- return g(C);
178
+ return _(w);
178
179
  }
179
180
  });
180
181
  //#endregion
181
- export { w as MarkdownBlockExtension, w as default, x as MermaidRenderer, v as useNodeEditable };
182
+ export { T as MarkdownBlockExtension, T as default, S as MermaidRenderer, y as useNodeEditable };
182
183
 
183
184
  //# sourceMappingURL=MarkdownBlock.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownBlock.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/extensions/MarkdownBlock.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useSyncExternalStore } from 'react';\nimport { Node, mergeAttributes } from '@tiptap/react';\nimport { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react';\nimport type { NodeViewProps } from '@tiptap/react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\n\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';\nimport mermaid from 'mermaid';\nimport 'katex/dist/katex.min.css';\n\nexport function useNodeEditable(editor: NodeViewProps['editor']) {\n const subscribe = useCallback((notify: () => void) => {\n // setEditable emits update, not transaction, in Tiptap 3.\n editor.on('update', notify);\n editor.on('transaction', notify);\n editor.on('destroy', notify);\n return () => {\n editor.off('update', notify);\n editor.off('transaction', notify);\n editor.off('destroy', notify);\n };\n }, [editor]);\n return useSyncExternalStore(subscribe, () => !editor.isDestroyed && editor.isEditable, () => false);\n}\n\nlet renderQueue: Promise<unknown> = Promise.resolve();\n\nfunction renderMermaid(id: string, code: string) {\n const result = renderQueue.then(() => {\n // Capture strict config when rendering starts, not before Mermaid's global queue runs.\n mermaid.initialize({\n startOnLoad: false,\n theme: 'default',\n securityLevel: 'strict',\n suppressErrorRendering: true,\n fontFamily: 'inherit',\n flowchart: { useMaxWidth: true, htmlLabels: false },\n });\n return mermaid.mermaidAPI.render(id, code);\n });\n renderQueue = result.catch(() => undefined);\n return result;\n}\n\nexport const MermaidRenderer: React.FC<{ code: string }> = ({ code }) => {\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n containerRef.current.replaceChildren();\n if (!code.trim()) return;\n\n let cancelled = false;\n const render = async () => {\n try {\n const id = `mermaid-md-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n const { svg } = await renderMermaid(id, code);\n if (!cancelled && containerRef.current) {\n containerRef.current.innerHTML = svg;\n }\n } catch (err) {\n if (!cancelled && containerRef.current) {\n containerRef.current.textContent = String(err);\n }\n }\n };\n render();\n return () => { cancelled = true; };\n }, [code]);\n\n return <div ref={containerRef} className=\"rte-mermaid-container\" />;\n};\n\nconst MarkdownPreview: React.FC<{ content: string }> = ({ content }) => {\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') {\n return <MermaidRenderer code={text} />;\n }\n\n if (lang) {\n return (\n <SyntaxHighlighter\n style={oneLight as Record<string, React.CSSProperties>}\n language={lang}\n PreTag=\"div\"\n customStyle={{\n borderRadius: '0.5rem',\n fontSize: '0.875em',\n padding: '1em',\n margin: '0.5em 0',\n }}\n >\n {text}\n </SyntaxHighlighter>\n );\n }\n return <code className={className} {...props}>{children}</code>;\n },\n }}\n >\n {content}\n </ReactMarkdown>\n );\n};\n\nconst MarkdownBlockView: React.FC<NodeViewProps> = ({\n node,\n editor,\n updateAttributes,\n selected,\n}) => {\n const editable = useNodeEditable(editor);\n const [isEditing, setIsEditing] = useState(false);\n const [localContent, setLocalContent] = useState(node.attrs.content || '');\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n setLocalContent(node.attrs.content || '');\n setIsEditing(false);\n }, [node.attrs.content, editable]);\n\n useEffect(() => {\n if (isEditing && textareaRef.current) {\n textareaRef.current.focus();\n adjustTextareaHeight(textareaRef.current);\n }\n }, [isEditing]);\n\n const adjustTextareaHeight = (el: HTMLTextAreaElement) => {\n el.style.height = 'auto';\n el.style.height = el.scrollHeight + 'px';\n };\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setLocalContent(e.target.value);\n adjustTextareaHeight(e.target);\n }, []);\n\n const handleBlur = useCallback(() => {\n if (!editor.isDestroyed && editor.isEditable) updateAttributes({ content: localContent });\n setIsEditing(false);\n }, [editor, localContent, updateAttributes]);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'Escape') {\n handleBlur();\n }\n }, [handleBlur]);\n\n const defaultContent = `# Markdown Block\n\nWrite your **markdown** here.\n\n\\`\\`\\`mermaid\ngraph LR\n A[Start] --> B[End]\n\\`\\`\\`\n`;\n\n const displayContent = localContent || defaultContent;\n\n return (\n <NodeViewWrapper contentEditable={false} className={`rte-markdown-block ${selected ? 'rte-markdown-block--selected' : ''}`}>\n <div className=\"rte-markdown-block__header\">\n <span className=\"rte-markdown-block__label\">Markdown</span>\n <button\n type=\"button\"\n className={`rte-markdown-block__toggle ${isEditing ? 'rte-markdown-block__toggle--active' : ''}`}\n disabled={!editable}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (isEditing) {\n updateAttributes({ content: localContent });\n }\n setIsEditing(!isEditing);\n }}\n title={isEditing ? 'Preview' : 'Edit'}\n >\n {isEditing ? (\n <svg width=\"14\" height=\"14\" 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 <svg width=\"14\" height=\"14\" 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 <span>{isEditing ? 'Preview' : 'Edit'}</span>\n </button>\n </div>\n\n <div className=\"rte-markdown-block__body\">\n {isEditing && editable ? (\n <textarea\n ref={textareaRef}\n className=\"rte-markdown-block__editor\"\n value={localContent}\n onChange={handleChange}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n placeholder=\"Enter Markdown content...\"\n rows={5}\n />\n ) : (\n <div\n className=\"rte-markdown-block__preview prose\"\n onDoubleClick={() => { if (!editor.isDestroyed && editor.isEditable) setIsEditing(true); }}\n >\n {displayContent.trim() ? (\n <MarkdownPreview content={displayContent} />\n ) : (\n <p className=\"rte-markdown-block__placeholder\">\n Double-click to edit Markdown content...\n </p>\n )}\n </div>\n )}\n </div>\n </NodeViewWrapper>\n );\n};\n\nexport const MarkdownBlockExtension = Node.create({\n name: 'markdownBlock',\n group: 'block',\n atom: true,\n draggable: true,\n\n addAttributes() {\n return {\n content: {\n default: '',\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-type=\"markdown-block\"]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'markdown-block' })];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(MarkdownBlockView);\n },\n});\n\nexport default MarkdownBlockExtension;\n"],"mappings":"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"}
1
+ {"version":3,"file":"MarkdownBlock.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/extensions/MarkdownBlock.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useSyncExternalStore } from 'react';\nimport { Node, mergeAttributes } from '@tiptap/react';\nimport { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react';\nimport type { NodeViewProps } from '@tiptap/react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport remarkMath from 'remark-math';\nimport rehypeKatex from 'rehype-katex';\n\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';\nimport mermaid from 'mermaid';\nimport { normalizeLegacyMermaid } from './legacyMermaid';\nimport 'katex/dist/katex.min.css';\n\nexport function useNodeEditable(editor: NodeViewProps['editor']) {\n const subscribe = useCallback((notify: () => void) => {\n // setEditable emits update, not transaction, in Tiptap 3.\n editor.on('update', notify);\n editor.on('transaction', notify);\n editor.on('destroy', notify);\n return () => {\n editor.off('update', notify);\n editor.off('transaction', notify);\n editor.off('destroy', notify);\n };\n }, [editor]);\n return useSyncExternalStore(subscribe, () => !editor.isDestroyed && editor.isEditable, () => false);\n}\n\nlet renderQueue: Promise<unknown> = Promise.resolve();\n\nfunction renderMermaid(id: string, code: string) {\n const result = renderQueue.then(() => {\n // Capture strict config when rendering starts, not before Mermaid's global queue runs.\n mermaid.initialize({\n startOnLoad: false,\n theme: 'default',\n securityLevel: 'strict',\n suppressErrorRendering: true,\n fontFamily: 'inherit',\n flowchart: { useMaxWidth: true, htmlLabels: false },\n });\n return mermaid.mermaidAPI.render(id, code);\n });\n renderQueue = result.catch(() => undefined);\n return result;\n}\n\nexport const MermaidRenderer: React.FC<{ code: string }> = ({ code }) => {\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n containerRef.current.replaceChildren();\n if (!code.trim()) return;\n\n let cancelled = false;\n const render = async () => {\n try {\n const id = `mermaid-md-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;\n const { svg } = await renderMermaid(id, normalizeLegacyMermaid(code));\n if (!cancelled && containerRef.current) {\n containerRef.current.innerHTML = svg;\n }\n } catch (err) {\n if (!cancelled && containerRef.current) {\n containerRef.current.textContent = String(err);\n }\n }\n };\n render();\n return () => { cancelled = true; };\n }, [code]);\n\n return <div ref={containerRef} className=\"rte-mermaid-container\" />;\n};\n\nconst MarkdownPreview: React.FC<{ content: string }> = ({ content }) => {\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') {\n return <MermaidRenderer code={text} />;\n }\n\n if (lang) {\n return (\n <SyntaxHighlighter\n style={oneLight as Record<string, React.CSSProperties>}\n language={lang}\n PreTag=\"div\"\n customStyle={{\n borderRadius: '0.5rem',\n fontSize: '0.875em',\n padding: '1em',\n margin: '0.5em 0',\n }}\n >\n {text}\n </SyntaxHighlighter>\n );\n }\n return <code className={className} {...props}>{children}</code>;\n },\n }}\n >\n {content}\n </ReactMarkdown>\n );\n};\n\nconst MarkdownBlockView: React.FC<NodeViewProps> = ({\n node,\n editor,\n updateAttributes,\n selected,\n}) => {\n const editable = useNodeEditable(editor);\n const [isEditing, setIsEditing] = useState(false);\n const [localContent, setLocalContent] = useState(node.attrs.content || '');\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n setLocalContent(node.attrs.content || '');\n setIsEditing(false);\n }, [node.attrs.content, editable]);\n\n useEffect(() => {\n if (isEditing && textareaRef.current) {\n textareaRef.current.focus();\n adjustTextareaHeight(textareaRef.current);\n }\n }, [isEditing]);\n\n const adjustTextareaHeight = (el: HTMLTextAreaElement) => {\n el.style.height = 'auto';\n el.style.height = el.scrollHeight + 'px';\n };\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setLocalContent(e.target.value);\n adjustTextareaHeight(e.target);\n }, []);\n\n const handleBlur = useCallback(() => {\n if (!editor.isDestroyed && editor.isEditable) updateAttributes({ content: localContent });\n setIsEditing(false);\n }, [editor, localContent, updateAttributes]);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'Escape') {\n handleBlur();\n }\n }, [handleBlur]);\n\n const defaultContent = `# Markdown Block\n\nWrite your **markdown** here.\n\n\\`\\`\\`mermaid\ngraph LR\n A[Start] --> B[End]\n\\`\\`\\`\n`;\n\n const displayContent = localContent || defaultContent;\n\n return (\n <NodeViewWrapper contentEditable={false} className={`rte-markdown-block ${selected ? 'rte-markdown-block--selected' : ''}`}>\n <div className=\"rte-markdown-block__header\">\n <span className=\"rte-markdown-block__label\">Markdown</span>\n <button\n type=\"button\"\n className={`rte-markdown-block__toggle ${isEditing ? 'rte-markdown-block__toggle--active' : ''}`}\n disabled={!editable}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (isEditing) {\n updateAttributes({ content: localContent });\n }\n setIsEditing(!isEditing);\n }}\n title={isEditing ? 'Preview' : 'Edit'}\n >\n {isEditing ? (\n <svg width=\"14\" height=\"14\" 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 <svg width=\"14\" height=\"14\" 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 <span>{isEditing ? 'Preview' : 'Edit'}</span>\n </button>\n </div>\n\n <div className=\"rte-markdown-block__body\">\n {isEditing && editable ? (\n <textarea\n ref={textareaRef}\n className=\"rte-markdown-block__editor\"\n value={localContent}\n onChange={handleChange}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n placeholder=\"Enter Markdown content...\"\n rows={5}\n />\n ) : (\n <div\n className=\"rte-markdown-block__preview prose\"\n onDoubleClick={() => { if (!editor.isDestroyed && editor.isEditable) setIsEditing(true); }}\n >\n {displayContent.trim() ? (\n <MarkdownPreview content={displayContent} />\n ) : (\n <p className=\"rte-markdown-block__placeholder\">\n Double-click to edit Markdown content...\n </p>\n )}\n </div>\n )}\n </div>\n </NodeViewWrapper>\n );\n};\n\nexport const MarkdownBlockExtension = Node.create({\n name: 'markdownBlock',\n group: 'block',\n atom: true,\n draggable: true,\n\n addAttributes() {\n return {\n content: {\n default: '',\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'div[data-type=\"markdown-block\"]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'markdown-block' })];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(MarkdownBlockView);\n },\n});\n\nexport default MarkdownBlockExtension;\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ /** Convert only explicit legacy headers. Unsupported syntax fails rather than changing meaning. */
2
+ export declare function normalizeLegacyMermaid(source: string): string;
@@ -0,0 +1,96 @@
1
+ //#region src/components/pro/RichTextEditor/extensions/legacyMermaid.ts
2
+ function e(e) {
3
+ return Array.from(e, (e) => /[\p{L}\p{N} ,.!?_-]/u.test(e) ? e : `#${e.codePointAt(0)};`).join("");
4
+ }
5
+ function t(t) {
6
+ let n = t.split(/\r?\n/), r = n[0].trim();
7
+ if (r !== "flow" && r !== "seq") return t;
8
+ let i = (e, t) => {
9
+ throw Error(`Legacy ${r}, line ${e + 1}: ${t}`);
10
+ }, a = n.map((e, t) => ({
11
+ value: e.trim(),
12
+ line: t
13
+ })).slice(1).filter(({ value: e }) => e && !e.startsWith("#"));
14
+ if (a.length || i(0, "Empty diagram"), r === "seq") {
15
+ let t = /* @__PURE__ */ new Map(), n = (e, n) => (e = e.trim(), (!e || /[\r\n:<>]/.test(e)) && i(n, "Invalid participant name"), t.has(e) || t.set(e, `p${t.size}`), t.get(e)), r = [], o = {
16
+ "->": "->>",
17
+ "-->": "-->>",
18
+ "->>": "->",
19
+ "-->>": "-->"
20
+ };
21
+ for (let { value: t, line: s } of a) {
22
+ let a = /^Note\s+(right of|left of|over)\s+([^:]+):\s*(.*)$/i.exec(t);
23
+ if (a) {
24
+ let t = a[1].toLowerCase(), o = a[2].split(",");
25
+ o.length > (t === "over" ? 2 : 1) && i(s, "Unsupported note participants"), r.push(`Note ${t} ${o.map((e) => n(e, s)).join(",")}: ${e(a[3])}`);
26
+ continue;
27
+ }
28
+ let c = /^([^:<>]+?)(-->>|->>|-->|->)([^:<>]+):\s*(.*)$/.exec(t);
29
+ (!c || /[-]$/.test(c[1].trim())) && i(s, "Unsupported sequence statement or arrow"), r.push(`${n(c[1], s)}${o[c[2]]}${n(c[3], s)}: ${e(c[4])}`);
30
+ }
31
+ return [
32
+ "sequenceDiagram",
33
+ ...Array.from(t, ([t, n]) => `participant ${n} as ${e(t)}`),
34
+ ...r
35
+ ].join("\n");
36
+ }
37
+ let o = /* @__PURE__ */ new Map(), s = [], c = [], l = {
38
+ start: ["([", "])"],
39
+ end: ["([", "])"],
40
+ operation: ["[", "]"],
41
+ condition: ["{", "}"],
42
+ inputoutput: ["[/", "/]"],
43
+ subroutine: ["[[", "]]"]
44
+ };
45
+ for (let { value: t, line: n } of a) {
46
+ if (!t.includes("=>")) continue;
47
+ let r = /^([A-Za-z_][\w]*)=>([a-z]+)(?::\s*(.*))?$/.exec(t);
48
+ (!r || !Object.hasOwn(l, r[2])) && i(n, "Unsupported node declaration/type");
49
+ let [, a, c, u] = r;
50
+ o.has(a) && i(n, `Duplicate node: ${a}`), u && /\||:>/.test(u) && i(n, "Node styles and links are unsupported");
51
+ let d = `n${o.size}`;
52
+ o.set(a, {
53
+ id: d,
54
+ type: c
55
+ });
56
+ let [f, p] = l[c];
57
+ s.push(`${d}${f}"${e(u ?? c)}"${p}`);
58
+ }
59
+ let u, d = {
60
+ right: "LR",
61
+ left: "RL",
62
+ top: "BT",
63
+ bottom: "TD"
64
+ };
65
+ for (let { value: e, line: t } of a) {
66
+ if (e.includes("=>")) continue;
67
+ let n = e.split("->");
68
+ n.length < 2 && i(t, "Unsupported flow statement");
69
+ let r = n.map((e) => {
70
+ let n = /^\s*([A-Za-z_][\w]*)(?:\(([^()]+)\))?\s*$/.exec(e);
71
+ return (!n || !o.has(n[1])) && i(t, "Invalid or undefined node reference"), {
72
+ node: o.get(n[1]),
73
+ options: n[2]?.split(",").map((e) => e.trim()) ?? []
74
+ };
75
+ });
76
+ for (let e = 0; e < r.length; e++) {
77
+ let { node: n, options: a } = r[e];
78
+ if (e === r.length - 1) {
79
+ a.length && i(t, "Options on a terminal reference are unsupported");
80
+ break;
81
+ }
82
+ let o, s;
83
+ for (let e of a) (e === "yes" || e === "no") && n.type === "condition" && !o ? o = e : Object.hasOwn(d, e) && !s ? s = d[e] : i(t, `Unsupported branch/direction: ${e}`);
84
+ s && (u && u !== s && i(t, "Mixed edge directions cannot be represented reliably"), u = s), c.push(`${n.id} -->${o ? `|${o}|` : ""} ${r[e + 1].node.id}`);
85
+ }
86
+ }
87
+ return o.size || i(0, "No node declarations"), [
88
+ `flowchart ${u ?? "TD"}`,
89
+ ...s,
90
+ ...c
91
+ ].join("\n");
92
+ }
93
+ //#endregion
94
+ export { t as normalizeLegacyMermaid };
95
+
96
+ //# sourceMappingURL=legacyMermaid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacyMermaid.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/extensions/legacyMermaid.ts"],"sourcesContent":["// Encode user text before embedding it in Mermaid syntax (including entity-like input).\nfunction text(value: string): string {\n return Array.from(value, char => /[\\p{L}\\p{N} ,.!?_-]/u.test(char)\n ? char : `#${char.codePointAt(0)};`).join('');\n}\n\n/** Convert only explicit legacy headers. Unsupported syntax fails rather than changing meaning. */\nexport function normalizeLegacyMermaid(source: string): string {\n const lines = source.split(/\\r?\\n/);\n const kind = lines[0].trim();\n if (kind !== 'flow' && kind !== 'seq') return source;\n const fail = (line: number, reason: string): never => {\n throw new Error(`Legacy ${kind}, line ${line + 1}: ${reason}`);\n };\n const body = lines.map((value, line) => ({ value: value.trim(), line }))\n .slice(1).filter(({ value }) => value && !value.startsWith('#'));\n if (!body.length) fail(0, 'Empty diagram');\n\n if (kind === 'seq') {\n const actors = new Map<string, string>();\n const actor = (name: string, line: number) => {\n name = name.trim();\n if (!name || /[\\r\\n:<>]/.test(name)) fail(line, 'Invalid participant name');\n if (!actors.has(name)) actors.set(name, `p${actors.size}`);\n return actors.get(name)!;\n };\n const output: string[] = [];\n const arrows: Record<string, string> = { '->': '->>', '-->': '-->>', '->>': '->', '-->>': '-->' };\n for (const { value, line } of body) {\n const note = /^Note\\s+(right of|left of|over)\\s+([^:]+):\\s*(.*)$/i.exec(value);\n if (note) {\n const placement = note[1].toLowerCase();\n const names = note[2].split(',');\n if (names.length > (placement === 'over' ? 2 : 1)) fail(line, 'Unsupported note participants');\n output.push(`Note ${placement} ${names.map(name => actor(name, line)).join(',')}: ${text(note[3])}`);\n continue;\n }\n const message = /^([^:<>]+?)(-->>|->>|-->|->)([^:<>]+):\\s*(.*)$/.exec(value);\n if (!message || /[-]$/.test(message[1].trim())) fail(line, 'Unsupported sequence statement or arrow');\n output.push(`${actor(message![1], line)}${arrows[message![2]]}${actor(message![3], line)}: ${text(message![4])}`);\n }\n return ['sequenceDiagram', ...Array.from(actors, ([name, id]) => `participant ${id} as ${text(name)}`), ...output].join('\\n');\n }\n\n const nodes = new Map<string, { id: string; type: string }>();\n const declarations: string[] = [];\n const edges: string[] = [];\n const shapes: Record<string, [string, string]> = {\n start: ['([', '])'], end: ['([', '])'], operation: ['[', ']'],\n condition: ['{', '}'], inputoutput: ['[/', '/]'], subroutine: ['[[', ']]'],\n };\n for (const { value, line } of body) {\n if (!value.includes('=>')) continue;\n const match = /^([A-Za-z_][\\w]*)=>([a-z]+)(?::\\s*(.*))?$/.exec(value);\n if (!match || !Object.hasOwn(shapes, match[2])) fail(line, 'Unsupported node declaration/type');\n const [, name, type, label] = match!;\n if (nodes.has(name)) fail(line, `Duplicate node: ${name}`);\n // flowchart.js uses these as state/link metadata, not literal label text.\n if (label && /\\||:>/.test(label)) fail(line, 'Node styles and links are unsupported');\n const id = `n${nodes.size}`;\n nodes.set(name, { id, type });\n const [open, close] = shapes[type];\n declarations.push(`${id}${open}\"${text(label ?? type)}\"${close}`);\n }\n let direction: string | undefined;\n const directions: Record<string, string> = { right: 'LR', left: 'RL', top: 'BT', bottom: 'TD' };\n for (const { value, line } of body) {\n if (value.includes('=>')) continue;\n const parts = value.split('->');\n if (parts.length < 2) fail(line, 'Unsupported flow statement');\n const refs = parts.map(part => {\n const match = /^\\s*([A-Za-z_][\\w]*)(?:\\(([^()]+)\\))?\\s*$/.exec(part);\n if (!match || !nodes.has(match[1])) fail(line, 'Invalid or undefined node reference');\n return { node: nodes.get(match![1])!, options: match![2]?.split(',').map(option => option.trim()) ?? [] };\n });\n for (let i = 0; i < refs.length; i++) {\n const { node, options } = refs[i];\n if (i === refs.length - 1) {\n if (options.length) fail(line, 'Options on a terminal reference are unsupported');\n break;\n }\n let branch: string | undefined;\n let hint: string | undefined;\n for (const option of options) {\n if ((option === 'yes' || option === 'no') && node.type === 'condition' && !branch) branch = option;\n else if (Object.hasOwn(directions, option) && !hint) hint = directions[option];\n else fail(line, `Unsupported branch/direction: ${option}`);\n }\n if (hint) {\n if (direction && direction !== hint) fail(line, 'Mixed edge directions cannot be represented reliably');\n direction = hint;\n }\n edges.push(`${node.id} -->${branch ? `|${branch}|` : ''} ${refs[i + 1].node.id}`);\n }\n }\n if (!nodes.size) fail(0, 'No node declarations');\n return [`flowchart ${direction ?? 'TD'}`, ...declarations, ...edges].join('\\n');\n}\n"],"mappings":"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"}