@lobehub/editor 4.23.1 → 4.23.2
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/es/editor-kernel/index.js +1 -0
- package/es/editor-kernel/kernel.js +47 -40
- package/es/editor-kernel/react/useLexicalNodeSelection.js +4 -2
- package/es/headless.js +201 -175
- package/es/index.js +5 -2
- package/es/plugins/auto-complete/plugin/index.js +4 -2
- package/es/plugins/block/react/ReactBlockPlugin.js +5 -4
- package/es/plugins/codeblock/command/index.js +8 -6
- package/es/plugins/codeblock/plugin/index.js +4 -2
- package/es/plugins/codeblock/react/ReactCodeblockPlugin.js +2 -1
- package/es/plugins/codemirror-block/command/index.js +8 -6
- package/es/plugins/common/data-source/json-data-source.js +5 -4
- package/es/plugins/common/plugin/index.js +1 -3
- package/es/plugins/common/plugin/paste-handler.js +2 -1
- package/es/plugins/hr/command/index.js +2 -1
- package/es/plugins/image/react/components/BrokenImage.js +2 -1
- package/es/plugins/image/react/components/Image.js +18 -15
- package/es/plugins/image/react/components/ImageEditPopover.js +42 -41
- package/es/plugins/image/react/components/ResizeHandle.js +1 -3
- package/es/plugins/link/node/LinkNode.js +4 -2
- package/es/plugins/link/plugin/registry.js +17 -12
- package/es/plugins/link/react/components/LinkEdit.js +9 -8
- package/es/plugins/list/plugin/index.js +1 -4
- package/es/plugins/list/utils/index.js +4 -2
- package/es/plugins/litexml/command/index.js +69 -62
- package/es/plugins/litexml/node/DiffNode.js +14 -10
- package/es/plugins/litexml/plugin/index.js +6 -12
- package/es/plugins/markdown/data-source/markdown-data-source.js +5 -4
- package/es/plugins/markdown/plugin/index.js +2 -1
- package/es/plugins/markdown/service/transformers.js +4 -2
- package/es/plugins/markdown/utils/index.js +10 -8
- package/es/plugins/math/command/index.js +4 -2
- package/es/plugins/math/react/components/MathInline.js +14 -13
- package/es/plugins/slash/plugin/index.js +13 -4
- package/es/plugins/slash/react/components/DefaultSlashMenu.js +2 -1
- package/es/plugins/slash/react/components/menuLoading.js +4 -0
- package/es/plugins/slash/service/i-slash-service.d.ts +6 -1
- package/es/plugins/slash/service/i-slash-service.js +16 -2
- package/es/plugins/slash/utils/utils.js +1 -1
- package/es/plugins/table/react/TableActionMenu/ActionMenu.js +69 -67
- package/es/plugins/table/react/TableColController.js +29 -26
- package/es/plugins/table/react/TableHoverActions/index.js +0 -2
- package/es/plugins/table/react/TableRowController.js +29 -26
- package/es/plugins/table/utils/index.js +4 -2
- package/es/react/Editor/Editor.js +24 -23
- package/es/react/hooks/useEditorState/index.js +28 -21
- package/es/react/hooks/useEditorState/utils.js +2 -1
- package/es/renderer/engine/render-builtin-node.js +26 -18
- package/es/renderer/engine/render-tree.js +4 -1
- package/es/renderer/renderers/mermaid.js +2 -1
- package/package.json +1 -1
|
@@ -47,35 +47,36 @@ const Editor = memo(({ content, style, className, collaboration, debounceWait =
|
|
|
47
47
|
markdownWriter,
|
|
48
48
|
className
|
|
49
49
|
]);
|
|
50
|
+
const memoSlash = useMemo(() => {
|
|
51
|
+
if (!enableSlash && !enableMention) return null;
|
|
52
|
+
return /* @__PURE__ */ jsxs(ReactSlashPlugin, {
|
|
53
|
+
getPopupContainer,
|
|
54
|
+
placement: slashPlacement,
|
|
55
|
+
children: [enableSlash ? /* @__PURE__ */ jsx(ReactSlashOption, {
|
|
56
|
+
maxLength: 8,
|
|
57
|
+
trigger: "/",
|
|
58
|
+
...slashOption
|
|
59
|
+
}) : void 0, enableMention ? /* @__PURE__ */ jsx(ReactSlashOption, {
|
|
60
|
+
maxLength: 8,
|
|
61
|
+
trigger: "@",
|
|
62
|
+
...restMentionOption
|
|
63
|
+
}) : void 0]
|
|
64
|
+
});
|
|
65
|
+
}, [
|
|
66
|
+
enableSlash,
|
|
67
|
+
enableMention,
|
|
68
|
+
slashOption,
|
|
69
|
+
slashPlacement,
|
|
70
|
+
getPopupContainer,
|
|
71
|
+
restMentionOption
|
|
72
|
+
]);
|
|
50
73
|
return /* @__PURE__ */ jsxs(ReactEditor, {
|
|
51
74
|
config,
|
|
52
75
|
editor,
|
|
53
76
|
onInit,
|
|
54
77
|
children: [
|
|
55
78
|
memoPlugins,
|
|
56
|
-
|
|
57
|
-
if (!enableSlash && !enableMention) return null;
|
|
58
|
-
return /* @__PURE__ */ jsxs(ReactSlashPlugin, {
|
|
59
|
-
getPopupContainer,
|
|
60
|
-
placement: slashPlacement,
|
|
61
|
-
children: [enableSlash ? /* @__PURE__ */ jsx(ReactSlashOption, {
|
|
62
|
-
maxLength: 8,
|
|
63
|
-
trigger: "/",
|
|
64
|
-
...slashOption
|
|
65
|
-
}) : void 0, enableMention ? /* @__PURE__ */ jsx(ReactSlashOption, {
|
|
66
|
-
maxLength: 8,
|
|
67
|
-
trigger: "@",
|
|
68
|
-
...restMentionOption
|
|
69
|
-
}) : void 0]
|
|
70
|
-
});
|
|
71
|
-
}, [
|
|
72
|
-
enableSlash,
|
|
73
|
-
enableMention,
|
|
74
|
-
slashOption,
|
|
75
|
-
slashPlacement,
|
|
76
|
-
getPopupContainer,
|
|
77
|
-
restMentionOption
|
|
78
|
-
]),
|
|
79
|
+
memoSlash,
|
|
79
80
|
memoMention,
|
|
80
81
|
/* @__PURE__ */ jsx(ReactPlainText, {
|
|
81
82
|
autoFocus,
|
|
@@ -81,11 +81,13 @@ function useEditorState(editor) {
|
|
|
81
81
|
else setCodeblockLang("");
|
|
82
82
|
const isBlockquote = $isQuoteNode(element) && $isQuoteNode(focusElement) && elementKey === focusElement.getKey();
|
|
83
83
|
setIsInBlockquote(isBlockquote);
|
|
84
|
-
if (elementDOM !== null)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
if (elementDOM !== null) {
|
|
85
|
+
if ($isListNode(element)) {
|
|
86
|
+
const parentList = $getNearestNodeOfType(anchorNode, ListNode);
|
|
87
|
+
const type = parentList ? parentList.getListType() : element.getListType();
|
|
88
|
+
setBlockType(type);
|
|
89
|
+
} else $handleHeadingNode(element);
|
|
90
|
+
}
|
|
89
91
|
} else if (!selection) {
|
|
90
92
|
setIsSelected(false);
|
|
91
93
|
setIsBold(false);
|
|
@@ -149,20 +151,23 @@ function useEditorState(editor) {
|
|
|
149
151
|
let selection = $getSelection();
|
|
150
152
|
if (!selection) return;
|
|
151
153
|
const lexicalEditor = editor?.getLexicalEditor();
|
|
152
|
-
if (lexicalEditor ? lexicalEditor._nodes.has("code") && lexicalEditor._nodes.get("code")?.klass.name === "CodeMirrorNode" : false)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
154
|
+
if (lexicalEditor ? lexicalEditor._nodes.has("code") && lexicalEditor._nodes.get("code")?.klass.name === "CodeMirrorNode" : false) {
|
|
155
|
+
if (!$isRangeSelection(selection) || selection.isCollapsed()) {
|
|
156
|
+
const textContent = selection.getTextContent();
|
|
157
|
+
const codeMirrorNode = $createCodeMirrorNode("plain", textContent);
|
|
158
|
+
const nodeSelection = $createNodeSelection();
|
|
159
|
+
nodeSelection.add(codeMirrorNode.getKey());
|
|
160
|
+
selection.insertNodes([codeMirrorNode]);
|
|
161
|
+
$setSelection(nodeSelection);
|
|
162
|
+
} else {
|
|
163
|
+
const textContent = selection.getTextContent();
|
|
164
|
+
const codeMirrorNode = $createCodeMirrorNode("plain", textContent);
|
|
165
|
+
selection.insertNodes([codeMirrorNode]);
|
|
166
|
+
const nodeSelection = $createNodeSelection();
|
|
167
|
+
nodeSelection.add(codeMirrorNode.getKey());
|
|
168
|
+
$setSelection(nodeSelection);
|
|
169
|
+
}
|
|
170
|
+
} else if (!$isRangeSelection(selection) || selection.isCollapsed()) $setBlocksType(selection, () => $createCodeNode());
|
|
166
171
|
else {
|
|
167
172
|
const textContent = selection.getTextContent();
|
|
168
173
|
const codeNode = $createCodeNode();
|
|
@@ -223,7 +228,8 @@ function useEditorState(editor) {
|
|
|
223
228
|
const maybeUrl = formatUrl(text.trim());
|
|
224
229
|
if (validateUrl(maybeUrl)) nextUrl = maybeUrl;
|
|
225
230
|
} else {
|
|
226
|
-
const
|
|
231
|
+
const lineText = selection.anchor.getNode().getTextContent();
|
|
232
|
+
const found = extractUrlFromText(lineText);
|
|
227
233
|
if (found && validateUrl(formatUrl(found.url))) expandTo = {
|
|
228
234
|
index: found.index,
|
|
229
235
|
length: found.length
|
|
@@ -249,7 +255,8 @@ function useEditorState(editor) {
|
|
|
249
255
|
editor?.getLexicalEditor()?.update(() => {
|
|
250
256
|
const selection = $getSelection();
|
|
251
257
|
if ($isRangeSelection(selection)) {
|
|
252
|
-
const
|
|
258
|
+
const anchorNode = selection.anchor.getNode();
|
|
259
|
+
const element = $findTopLevelElement(anchorNode);
|
|
253
260
|
const mathNode = $isParagraphNode(element) && selection.isCollapsed() && selection.anchor.offset === 0 && element.getTextContentSize() === 0 || !selection.isCollapsed() && selection.anchor.offset === 0 && selection.focus.offset === element.getTextContentSize() ? $createMathBlockNode("") : $createMathInlineNode("");
|
|
254
261
|
selection.insertNodes([mathNode]);
|
|
255
262
|
const nodeSelection = $createNodeSelection();
|
|
@@ -12,7 +12,8 @@ const $findTopLevelElement = (node) => {
|
|
|
12
12
|
};
|
|
13
13
|
const formatParagraph = (editor) => {
|
|
14
14
|
editor?.update(() => {
|
|
15
|
-
|
|
15
|
+
const selection = $getSelection();
|
|
16
|
+
$setBlocksType(selection, () => $createParagraphNode());
|
|
16
17
|
});
|
|
17
18
|
};
|
|
18
19
|
const getSelectedNode = (selection) => {
|
|
@@ -75,9 +75,7 @@ function renderDiffNode(node, key, children) {
|
|
|
75
75
|
case "listItemModify":
|
|
76
76
|
content = [wrapChild(renderedChildren[0], `${key}-old`, DIFF_DELETED_STYLE), wrapChild(renderedChildren[1], `${key}-new`)];
|
|
77
77
|
break;
|
|
78
|
-
default:
|
|
79
|
-
content = renderedChildren;
|
|
80
|
-
break;
|
|
78
|
+
default: content = renderedChildren;
|
|
81
79
|
}
|
|
82
80
|
return /* @__PURE__ */ jsx("div", {
|
|
83
81
|
className: "ne-diff",
|
|
@@ -93,10 +91,13 @@ function renderDiffNode(node, key, children) {
|
|
|
93
91
|
function renderBuiltinNode(node, key, children, headingSlugs, textContent) {
|
|
94
92
|
switch (node.type) {
|
|
95
93
|
case "root": return children;
|
|
96
|
-
case "paragraph":
|
|
97
|
-
style
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
case "paragraph": {
|
|
95
|
+
const style = node.format ? { textAlign: node.format } : void 0;
|
|
96
|
+
return /* @__PURE__ */ jsx("p", {
|
|
97
|
+
style,
|
|
98
|
+
children
|
|
99
|
+
}, key);
|
|
100
|
+
}
|
|
100
101
|
case "heading": {
|
|
101
102
|
const tag = node.tag;
|
|
102
103
|
const baseSlug = textToSlug(textContent || "");
|
|
@@ -117,11 +118,15 @@ function renderBuiltinNode(node, key, children, headingSlugs, textContent) {
|
|
|
117
118
|
className: "editor_quote",
|
|
118
119
|
children
|
|
119
120
|
}, key);
|
|
120
|
-
case "list":
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
case "list": {
|
|
122
|
+
const Tag = node.listType === "number" ? "ol" : "ul";
|
|
123
|
+
const listClass = getListClassName(node.listType);
|
|
124
|
+
return /* @__PURE__ */ jsx(Tag, {
|
|
125
|
+
className: listClass,
|
|
126
|
+
start: node.start !== 1 ? node.start : void 0,
|
|
127
|
+
children
|
|
128
|
+
}, key);
|
|
129
|
+
}
|
|
125
130
|
case "listitem": {
|
|
126
131
|
const isChecklist = node.checked !== void 0;
|
|
127
132
|
const hasNestedList = node.children?.some((c) => c.type === "list");
|
|
@@ -143,12 +148,15 @@ function renderBuiltinNode(node, key, children, headingSlugs, textContent) {
|
|
|
143
148
|
target: node.target || void 0,
|
|
144
149
|
children
|
|
145
150
|
}, key);
|
|
146
|
-
case "linkHighlight":
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
case "linkHighlight": {
|
|
152
|
+
const url = textContent ? sanitizeUrl(formatLinkHighlightUrl(textContent)) : void 0;
|
|
153
|
+
return /* @__PURE__ */ jsx("a", {
|
|
154
|
+
href: url,
|
|
155
|
+
rel: "noopener noreferrer",
|
|
156
|
+
target: "_blank",
|
|
157
|
+
children
|
|
158
|
+
}, key);
|
|
159
|
+
}
|
|
152
160
|
case "table": return /* @__PURE__ */ jsx("div", {
|
|
153
161
|
className: getTableWrapperClassName(),
|
|
154
162
|
children: /* @__PURE__ */ jsx("table", {
|
|
@@ -8,7 +8,10 @@ function isHeadlessRenderableNode(node) {
|
|
|
8
8
|
function renderNode(node, registry, headingSlugs, overrides, key, renderContext) {
|
|
9
9
|
const type = node.getType();
|
|
10
10
|
if (type === "cursor") return null;
|
|
11
|
-
if ($isTextNode(node))
|
|
11
|
+
if ($isTextNode(node)) {
|
|
12
|
+
const serialized = node.exportJSON();
|
|
13
|
+
return renderTextNode(serialized, key);
|
|
14
|
+
}
|
|
12
15
|
const serialized = node.exportJSON();
|
|
13
16
|
let children = null;
|
|
14
17
|
if ($isElementNode(node)) {
|
|
@@ -3,6 +3,7 @@ import { Mermaid } from "@lobehub/ui";
|
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
//#region src/renderer/renderers/mermaid.tsx
|
|
5
5
|
function renderMermaidBlock(node, key) {
|
|
6
|
+
const code = node.code || "";
|
|
6
7
|
return /* @__PURE__ */ jsx(Mermaid, {
|
|
7
8
|
animated: false,
|
|
8
9
|
defaultExpand: true,
|
|
@@ -10,7 +11,7 @@ function renderMermaidBlock(node, key) {
|
|
|
10
11
|
style: { width: "100%" },
|
|
11
12
|
theme: "lobe-theme",
|
|
12
13
|
variant: "filled",
|
|
13
|
-
children:
|
|
14
|
+
children: code
|
|
14
15
|
}, key);
|
|
15
16
|
}
|
|
16
17
|
//#endregion
|
package/package.json
CHANGED