@lobehub/editor 4.24.1 → 4.25.0
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/codemirror/style.js +42 -0
- package/es/editor-kernel/kernel.js +3 -0
- package/es/editor-kernel/react/useDecorators.js +2 -4
- package/es/headless/collapsible-plugin.js +74 -0
- package/es/headless/index.js +2 -0
- package/es/headless.d.ts +18 -0
- package/es/headless.js +2479 -71
- package/es/index.d.ts +26 -3
- package/es/index.js +17 -2
- package/es/locale/index.d.ts +14 -0
- package/es/locale/index.js +14 -0
- package/es/plugins/block/command/index.js +24 -0
- package/es/plugins/block/plugin/index.js +7 -5
- package/es/plugins/block/react/ReactBlockPlugin.js +43 -1
- package/es/plugins/block/react/core/menu-position.js +20 -0
- package/es/plugins/block/react/drag/drag-session.js +3 -2
- package/es/plugins/block/react/drag/drag-utils.js +13 -1
- package/es/plugins/codemirror-block/index.d.ts +2 -1
- package/es/plugins/codemirror-block/plugin/index.js +2 -0
- package/es/plugins/codemirror-block/react/CodemirrorNode.js +95 -5
- package/es/plugins/codemirror-block/react/useCodemirrorEditLock.js +33 -0
- package/es/plugins/codemirror-block/service/index.d.ts +40 -0
- package/es/plugins/codemirror-block/service/index.js +59 -0
- package/es/plugins/collapsible/command/index.d.ts +17 -0
- package/es/plugins/collapsible/command/index.js +72 -0
- package/es/plugins/collapsible/index.d.ts +7 -0
- package/es/plugins/collapsible/node/CollapsibleNode.d.ts +30 -0
- package/es/plugins/collapsible/node/CollapsibleNode.js +138 -0
- package/es/plugins/collapsible/plugin/index.d.ts +11 -0
- package/es/plugins/collapsible/plugin/index.js +535 -0
- package/es/plugins/collapsible/react/ReactCollapsiblePlugin.d.ts +6 -0
- package/es/plugins/collapsible/react/ReactCollapsiblePlugin.js +19 -0
- package/es/plugins/collapsible/react/index.d.ts +3 -0
- package/es/plugins/collapsible/react/style.js +67 -0
- package/es/plugins/collapsible/react/type.d.ts +6 -0
- package/es/plugins/common/plugin/index.js +3 -2
- package/es/plugins/common/plugin/progressive-select-all.js +81 -0
- package/es/plugins/common/plugin/register.js +73 -4
- package/es/plugins/link/command/index.js +26 -3
- package/es/plugins/link/conversion/index.js +237 -0
- package/es/plugins/link/index.d.ts +5 -3
- package/es/plugins/link/node/LinkBlockCardNode.d.ts +16 -0
- package/es/plugins/link/node/LinkBlockCardNode.js +66 -0
- package/es/plugins/link/node/LinkCardNode.d.ts +42 -0
- package/es/plugins/link/node/LinkCardNode.js +161 -0
- package/es/plugins/link/node/LinkIframeNode.d.ts +33 -0
- package/es/plugins/link/node/LinkIframeNode.js +131 -0
- package/es/plugins/link/node/LinkNode.d.ts +48 -2
- package/es/plugins/link/node/LinkNode.js +14 -6
- package/es/plugins/link/node/SchemaNode.d.ts +36 -0
- package/es/plugins/link/node/SchemaNode.js +149 -0
- package/es/plugins/link/normalization/index.d.ts +7 -0
- package/es/plugins/link/normalization/index.js +38 -0
- package/es/plugins/link/plugin/index.d.ts +26 -1
- package/es/plugins/link/plugin/index.js +124 -4
- package/es/plugins/link/react/ReactLinkPlugin.js +165 -7
- package/es/plugins/link/react/components/LinkCard.js +235 -0
- package/es/plugins/link/react/components/LinkEdit.js +93 -14
- package/es/plugins/link/react/components/LinkIframe.js +128 -0
- package/es/plugins/link/react/components/LinkToolbar.js +440 -111
- package/es/plugins/link/react/components/SchemaLink.js +49 -0
- package/es/plugins/link/react/index.d.ts +2 -2
- package/es/plugins/link/react/renderer-registry.d.ts +81 -0
- package/es/plugins/link/react/renderer-registry.js +80 -0
- package/es/plugins/link/react/style.js +63 -1
- package/es/plugins/link/react/type.d.ts +24 -1
- package/es/plugins/link/service/i-link-service.d.ts +156 -1
- package/es/plugins/link/service/i-link-service.js +258 -5
- package/es/plugins/list/plugin/index.js +9 -2
- package/es/plugins/litexml/command/diffCommand.js +94 -14
- package/es/plugins/litexml/command/index.js +187 -6
- package/es/plugins/litexml/diff-validation.js +237 -0
- package/es/plugins/litexml/node/DiffContentNode.js +67 -0
- package/es/plugins/litexml/node/DiffNode.d.ts +1 -1
- package/es/plugins/litexml/node/DiffNode.js +5 -2
- package/es/plugins/litexml/node/TableCellDiffNode.js +77 -0
- package/es/plugins/litexml/node/TableRowDiffNode.js +73 -0
- package/es/plugins/litexml/plugin/index.d.ts +2 -0
- package/es/plugins/litexml/plugin/index.js +62 -9
- package/es/plugins/litexml/react/DiffNodeToolbar/index.js +10 -12
- package/es/plugins/litexml/react/TableRowDiffToolbar.js +123 -0
- package/es/plugins/litexml/react/hooks/useHasDiffNode.js +5 -2
- package/es/plugins/litexml/react/index.js +6 -2
- package/es/plugins/litexml/react/style.js +18 -5
- package/es/plugins/litexml/table-cell-diff.js +153 -0
- package/es/plugins/litexml/table-row-diff.js +82 -0
- package/es/plugins/markdown/data-source/markdown/parse.js +25 -1
- package/es/plugins/markdown/plugin/index.js +5 -3
- package/es/plugins/slash/react/ReactSlashPlugin.js +22 -43
- package/es/plugins/slash/react/components/DefaultSlashMenu.js +76 -16
- package/es/plugins/slash/react/menu-utils.js +84 -0
- package/es/plugins/slash/service/i-slash-service.d.ts +3 -0
- package/es/plugins/table/plugin/index.js +4 -1
- package/es/plugins/table/plugin/single-cell-paste.js +79 -0
- package/es/plugins/table/react/TableController/hooks.js +7 -4
- package/es/plugins/table/react/hooks.js +2 -2
- package/es/plugins/table/react/index.js +2 -0
- package/es/plugins/table/react/style.js +15 -5
- package/es/plugins/table/react/useScrollFocusedTableCellIntoView.js +46 -0
- package/es/plugins/toc/index.d.ts +10 -0
- package/es/plugins/toc/plugin/index.d.ts +8 -0
- package/es/plugins/toc/plugin/index.js +56 -0
- package/es/plugins/toc/react/ReactTocPlugin.d.ts +6 -0
- package/es/plugins/toc/react/ReactTocPlugin.js +36 -0
- package/es/plugins/toc/react/getNearestScrollContainer.d.ts +6 -0
- package/es/plugins/toc/react/getNearestScrollContainer.js +18 -0
- package/es/plugins/toc/react/hooks/useActiveHeading.js +59 -0
- package/es/plugins/toc/react/hooks/useTocItems.js +50 -0
- package/es/plugins/toc/react/index.d.ts +5 -0
- package/es/plugins/toc/react/type.d.ts +30 -0
- package/es/plugins/toc/react/useToc.d.ts +5 -0
- package/es/plugins/toc/react/useToc.js +41 -0
- package/es/plugins/toc/service/i-toc-service.d.ts +39 -0
- package/es/plugins/toc/service/i-toc-service.js +125 -0
- package/es/plugins/toc/service/index.d.ts +3 -0
- package/es/plugins/toc/types.d.ts +23 -0
- package/es/plugins/toc/utils/index.d.ts +6 -0
- package/es/plugins/toc/utils/index.js +30 -0
- package/es/plugins/toolbar/react/index.js +26 -12
- package/es/plugins/toolbar/react/style.js +3 -2
- package/es/plugins/virtual-block/plugin/register.js +34 -12
- package/es/plugins/yjs/index.d.ts +6 -0
- package/es/plugins/yjs/plugin/index.d.ts +7 -0
- package/es/plugins/yjs/plugin/index.js +191 -0
- package/es/plugins/yjs/plugin/types.d.ts +16 -0
- package/es/plugins/yjs/plugin/utils/awareness.js +9 -0
- package/es/plugins/yjs/plugin/utils/editor-state.js +47 -0
- package/es/plugins/yjs/plugin/utils/history.js +31 -0
- package/es/plugins/yjs/plugin/utils/node-properties.js +39 -0
- package/es/plugins/yjs/plugin/utils/sync.js +24 -0
- package/es/plugins/yjs/react/codemirrorEditLockProvider.js +59 -0
- package/es/plugins/yjs/react/index.d.ts +23 -0
- package/es/plugins/yjs/react/index.js +200 -0
- package/es/plugins/yjs/service/index.d.ts +47 -0
- package/es/plugins/yjs/service/index.js +84 -0
- package/es/plugins/yjs/websocket-provider.d.ts +78 -0
- package/es/plugins/yjs/websocket-provider.js +263 -0
- package/es/renderer/LexicalRenderer.js +9 -2
- package/es/types/kernel.d.ts +4 -0
- package/es/utils/updatePosition.js +5 -2
- package/package.json +3 -1
- package/patches/@lexical__yjs@0.42.0.patch +42 -0
- package/scripts/postinstall-lexical-patch.cjs +62 -36
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { $isTableRowDiffNode } from "../node/TableRowDiffNode.js";
|
|
2
|
+
import { LITEXML_DIFFNODE_COMMAND } from "../command/symbols.js";
|
|
3
|
+
import { useTranslation } from "../../../editor-kernel/react/useTranslation.js";
|
|
4
|
+
import { styles } from "./DiffNodeToolbar/style.js";
|
|
5
|
+
import { ActionIcon, Block } from "@lobehub/ui";
|
|
6
|
+
import { Check, X } from "lucide-react";
|
|
7
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { useThemeMode } from "antd-style";
|
|
10
|
+
import { $getNearestNodeFromDOMNode } from "lexical";
|
|
11
|
+
import { createPortal } from "react-dom";
|
|
12
|
+
//#region src/plugins/litexml/react/TableRowDiffToolbar.tsx
|
|
13
|
+
const TableRowDiffToolbar = ({ editor }) => {
|
|
14
|
+
const [activeRow, setActiveRow] = useState(null);
|
|
15
|
+
const hideTimerRef = useRef(void 0);
|
|
16
|
+
const toolbarRef = useRef(null);
|
|
17
|
+
const t = useTranslation();
|
|
18
|
+
const { isDarkMode } = useThemeMode();
|
|
19
|
+
const clearHideTimer = useCallback(() => {
|
|
20
|
+
if (hideTimerRef.current) clearTimeout(hideTimerRef.current);
|
|
21
|
+
}, []);
|
|
22
|
+
const scheduleHide = useCallback(() => {
|
|
23
|
+
clearHideTimer();
|
|
24
|
+
hideTimerRef.current = setTimeout(() => setActiveRow(null), 120);
|
|
25
|
+
}, [clearHideTimer]);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const root = editor.getRootElement();
|
|
28
|
+
if (!root) return;
|
|
29
|
+
const onPointerOver = (event) => {
|
|
30
|
+
const target = event.target;
|
|
31
|
+
if (!(target instanceof Element)) return;
|
|
32
|
+
const row = target.closest("tr[data-diff-type]");
|
|
33
|
+
if (!row || !root.contains(row)) return;
|
|
34
|
+
const nodeKey = editor.read(() => {
|
|
35
|
+
const node = $getNearestNodeFromDOMNode(row);
|
|
36
|
+
return $isTableRowDiffNode(node) ? node.getKey() : null;
|
|
37
|
+
});
|
|
38
|
+
if (!nodeKey) return;
|
|
39
|
+
clearHideTimer();
|
|
40
|
+
const rect = row.getBoundingClientRect();
|
|
41
|
+
setActiveRow({
|
|
42
|
+
left: Math.max(8, rect.right - 72),
|
|
43
|
+
nodeKey,
|
|
44
|
+
top: Math.max(8, rect.top + 4)
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
const onPointerOut = (event) => {
|
|
48
|
+
const related = event.relatedTarget;
|
|
49
|
+
if (related instanceof Element && (related.closest("tr[data-diff-type]") || toolbarRef.current?.contains(related))) return;
|
|
50
|
+
scheduleHide();
|
|
51
|
+
};
|
|
52
|
+
root.addEventListener("pointerover", onPointerOver);
|
|
53
|
+
root.addEventListener("pointerout", onPointerOut);
|
|
54
|
+
return () => {
|
|
55
|
+
clearHideTimer();
|
|
56
|
+
root.removeEventListener("pointerover", onPointerOver);
|
|
57
|
+
root.removeEventListener("pointerout", onPointerOut);
|
|
58
|
+
};
|
|
59
|
+
}, [
|
|
60
|
+
clearHideTimer,
|
|
61
|
+
editor,
|
|
62
|
+
scheduleHide
|
|
63
|
+
]);
|
|
64
|
+
if (!activeRow || typeof document === "undefined") return null;
|
|
65
|
+
const dispatch = (action) => {
|
|
66
|
+
editor.dispatchCommand(LITEXML_DIFFNODE_COMMAND, {
|
|
67
|
+
action,
|
|
68
|
+
nodeKey: activeRow.nodeKey
|
|
69
|
+
});
|
|
70
|
+
setActiveRow(null);
|
|
71
|
+
};
|
|
72
|
+
const handleActionPointerDown = (event, action) => {
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
event.stopPropagation();
|
|
75
|
+
dispatch(action);
|
|
76
|
+
};
|
|
77
|
+
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
78
|
+
contentEditable: false,
|
|
79
|
+
onPointerEnter: clearHideTimer,
|
|
80
|
+
onPointerLeave: scheduleHide,
|
|
81
|
+
ref: toolbarRef,
|
|
82
|
+
style: {
|
|
83
|
+
left: activeRow.left,
|
|
84
|
+
pointerEvents: "auto",
|
|
85
|
+
position: "fixed",
|
|
86
|
+
top: activeRow.top,
|
|
87
|
+
zIndex: 10002
|
|
88
|
+
},
|
|
89
|
+
children: /* @__PURE__ */ jsxs(Block, {
|
|
90
|
+
className: isDarkMode ? styles.toolbarDark : styles.toolbarLight,
|
|
91
|
+
gap: 2,
|
|
92
|
+
horizontal: true,
|
|
93
|
+
padding: 2,
|
|
94
|
+
shadow: true,
|
|
95
|
+
variant: "outlined",
|
|
96
|
+
children: [/* @__PURE__ */ jsx(ActionIcon, {
|
|
97
|
+
"aria-label": "Reject row change",
|
|
98
|
+
className: styles.reject,
|
|
99
|
+
danger: true,
|
|
100
|
+
icon: X,
|
|
101
|
+
onPointerDown: (event) => handleActionPointerDown(event, 0),
|
|
102
|
+
size: {
|
|
103
|
+
blockSize: 28,
|
|
104
|
+
size: 16
|
|
105
|
+
},
|
|
106
|
+
title: t("modifier.reject")
|
|
107
|
+
}), /* @__PURE__ */ jsx(ActionIcon, {
|
|
108
|
+
"aria-label": "Accept row change",
|
|
109
|
+
className: styles.accept,
|
|
110
|
+
icon: Check,
|
|
111
|
+
onPointerDown: (event) => handleActionPointerDown(event, 1),
|
|
112
|
+
size: {
|
|
113
|
+
blockSize: 28,
|
|
114
|
+
size: 16
|
|
115
|
+
},
|
|
116
|
+
title: t("modifier.accept")
|
|
117
|
+
})]
|
|
118
|
+
})
|
|
119
|
+
}), document.body);
|
|
120
|
+
};
|
|
121
|
+
TableRowDiffToolbar.displayName = "TableRowDiffToolbar";
|
|
122
|
+
//#endregion
|
|
123
|
+
export { TableRowDiffToolbar as default };
|
|
@@ -4,7 +4,10 @@ function hasDiffNode(editor) {
|
|
|
4
4
|
if (!editor) return false;
|
|
5
5
|
const values = editor.getLexicalEditor()?.getEditorState()._nodeMap.values();
|
|
6
6
|
if (!values) return false;
|
|
7
|
-
for (const node of values)
|
|
7
|
+
for (const node of values) {
|
|
8
|
+
const nodeType = node.getType();
|
|
9
|
+
if (nodeType === "diff" || nodeType === "table-row-diff") return true;
|
|
10
|
+
}
|
|
8
11
|
return false;
|
|
9
12
|
}
|
|
10
13
|
function useHasDiffNode(editor) {
|
|
@@ -32,4 +35,4 @@ function useHasDiffNode(editor) {
|
|
|
32
35
|
return { hasDiff };
|
|
33
36
|
}
|
|
34
37
|
//#endregion
|
|
35
|
-
export { useHasDiffNode };
|
|
38
|
+
export { hasDiffNode, useHasDiffNode };
|
|
@@ -3,12 +3,14 @@ import { useLexicalComposerContext } from "../../../editor-kernel/react/react-co
|
|
|
3
3
|
import { INodePlugin } from "../../inode/plugin/index.js";
|
|
4
4
|
import { LitexmlPlugin } from "../plugin/index.js";
|
|
5
5
|
import ReactDiffNodeToolbar from "./DiffNodeToolbar/index.js";
|
|
6
|
-
import { styles } from "./style.js";
|
|
6
|
+
import { styles, tableCellDiffStyles, tableRowDiffStyles } from "./style.js";
|
|
7
|
+
import TableRowDiffToolbar from "./TableRowDiffToolbar.js";
|
|
7
8
|
import { useLayoutEffect } from "react";
|
|
8
9
|
import { jsx } from "react/jsx-runtime";
|
|
9
10
|
//#region src/plugins/litexml/react/index.tsx
|
|
10
11
|
const ReactLiteXmlPlugin = () => {
|
|
11
12
|
const [editor] = useLexicalComposerContext();
|
|
13
|
+
const lexicalEditor = editor.getLexicalEditor();
|
|
12
14
|
useLayoutEffect(() => {
|
|
13
15
|
editor.registerPlugin(INodePlugin);
|
|
14
16
|
editor.registerPlugin(LitexmlPlugin, {
|
|
@@ -16,10 +18,12 @@ const ReactLiteXmlPlugin = () => {
|
|
|
16
18
|
editor,
|
|
17
19
|
node
|
|
18
20
|
}),
|
|
21
|
+
tableRowDiffTheme: tableRowDiffStyles,
|
|
22
|
+
tableCellDiffTheme: tableCellDiffStyles,
|
|
19
23
|
theme: styles
|
|
20
24
|
});
|
|
21
25
|
}, [editor]);
|
|
22
|
-
return null;
|
|
26
|
+
return lexicalEditor ? /* @__PURE__ */ jsx(TableRowDiffToolbar, { editor: lexicalEditor }) : null;
|
|
23
27
|
};
|
|
24
28
|
ReactLiteXmlPlugin.displayName = "ReactLiteXmlPlugin";
|
|
25
29
|
//#endregion
|
|
@@ -3,17 +3,17 @@ import { createStaticStyles } from "antd-style";
|
|
|
3
3
|
const styles = createStaticStyles(({ css, cssVar }) => css`
|
|
4
4
|
position: relative;
|
|
5
5
|
|
|
6
|
-
.toolbar {
|
|
6
|
+
> .toolbar {
|
|
7
7
|
position: absolute;
|
|
8
8
|
z-index: 10;
|
|
9
|
-
inset-block-
|
|
10
|
-
inset-inline-
|
|
9
|
+
inset-block-start: 0;
|
|
10
|
+
inset-inline-start: 8px;
|
|
11
11
|
|
|
12
12
|
opacity: 0;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
&:hover {
|
|
16
|
-
.toolbar {
|
|
16
|
+
> .toolbar {
|
|
17
17
|
opacity: 1;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -120,5 +120,18 @@ const styles = createStaticStyles(({ css, cssVar }) => css`
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
`);
|
|
123
|
+
const tableRowDiffStyles = createStaticStyles(({ css, cssVar }) => css`
|
|
124
|
+
&[data-diff-type='remove'] {
|
|
125
|
+
color: ${cssVar.colorTextQuaternary};
|
|
126
|
+
text-decoration: line-through;
|
|
127
|
+
background: ${cssVar.colorErrorBg};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
&[data-diff-type='add'] {
|
|
131
|
+
background: ${cssVar.colorSuccessBg};
|
|
132
|
+
box-shadow: inset 3px 0 0 ${cssVar.colorSuccess};
|
|
133
|
+
}
|
|
134
|
+
`);
|
|
135
|
+
const tableCellDiffStyles = tableRowDiffStyles;
|
|
123
136
|
//#endregion
|
|
124
|
-
export { styles };
|
|
137
|
+
export { styles, tableCellDiffStyles, tableRowDiffStyles };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { $createDiffNode, DiffNode } from "./node/DiffNode.js";
|
|
2
|
+
import { $createTableCellDiffNode, TableCellDiffNode } from "./node/TableCellDiffNode.js";
|
|
3
|
+
import { $cloneNode } from "./utils/index.js";
|
|
4
|
+
import { $createTableCellNode, $isTableCellNode, $isTableNode, $isTableRowNode, TableNode } from "@lexical/table";
|
|
5
|
+
import { $nodesOfType } from "lexical";
|
|
6
|
+
//#region src/plugins/litexml/table-cell-diff.ts
|
|
7
|
+
function copyCellStructure(source, target) {
|
|
8
|
+
target.setRowSpan(source.getRowSpan());
|
|
9
|
+
target.setBackgroundColor(source.getBackgroundColor());
|
|
10
|
+
target.setVerticalAlign(source.getVerticalAlign());
|
|
11
|
+
}
|
|
12
|
+
function $createTableCellDiffFromCell(editor, cell, diffType, changeId) {
|
|
13
|
+
const diffCell = $createTableCellDiffNode(diffType, changeId, cell.getHeaderStyles(), cell.getColSpan(), cell.getWidth());
|
|
14
|
+
copyCellStructure(cell, diffCell);
|
|
15
|
+
const diff = $createDiffNode(diffType);
|
|
16
|
+
diff.append(...cell.getChildren().map((child) => $cloneNode(child, editor)));
|
|
17
|
+
diffCell.append(diff);
|
|
18
|
+
return diffCell;
|
|
19
|
+
}
|
|
20
|
+
function $createPlainTableCellFromDiff(editor, cell) {
|
|
21
|
+
const plainCell = $createTableCellNode(cell.getHeaderStyles(), cell.getColSpan(), cell.getWidth());
|
|
22
|
+
copyCellStructure(cell, plainCell);
|
|
23
|
+
const diff = cell.getFirstChild();
|
|
24
|
+
if (diff instanceof DiffNode) plainCell.append(...diff.getChildren().map((child) => $cloneNode(child, editor)));
|
|
25
|
+
else plainCell.append(...cell.getChildren().map((child) => $cloneNode(child, editor)));
|
|
26
|
+
return plainCell;
|
|
27
|
+
}
|
|
28
|
+
function $getTableForCell(cell) {
|
|
29
|
+
const row = cell.getParent();
|
|
30
|
+
if (!$isTableRowNode(row)) return null;
|
|
31
|
+
const table = row.getParent();
|
|
32
|
+
return $isTableNode(table) ? table : null;
|
|
33
|
+
}
|
|
34
|
+
function $getTableCellColumnIndex(cell) {
|
|
35
|
+
const row = cell.getParent();
|
|
36
|
+
if (!$isTableRowNode(row)) return -1;
|
|
37
|
+
let index = 0;
|
|
38
|
+
for (const sibling of row.getChildren()) {
|
|
39
|
+
if (sibling === cell) return index;
|
|
40
|
+
if ($isTableCellNode(sibling)) index += sibling.getColSpan();
|
|
41
|
+
}
|
|
42
|
+
return -1;
|
|
43
|
+
}
|
|
44
|
+
function $getLogicalRowWidth(cell) {
|
|
45
|
+
const row = cell.getParent();
|
|
46
|
+
if (!$isTableRowNode(row)) return 0;
|
|
47
|
+
return row.getChildren().reduce((total, child) => total + ($isTableCellNode(child) ? child.getColSpan() : 0), 0);
|
|
48
|
+
}
|
|
49
|
+
function $getTableCellDiffGroup(cell) {
|
|
50
|
+
const changeId = cell.getChangeId();
|
|
51
|
+
const table = $getTableForCell(cell);
|
|
52
|
+
if (!changeId || !table) return [cell];
|
|
53
|
+
return $nodesOfType(TableCellDiffNode).filter((candidate) => candidate.getChangeId() === changeId && candidate.getDiffType() === cell.getDiffType() && $getTableForCell(candidate) === table);
|
|
54
|
+
}
|
|
55
|
+
function $updateTableWidthsForCellInsertion(table, rowWidthBefore, columnIndex, insertedSpan) {
|
|
56
|
+
const currentWidths = table.getColWidths() || Array.from({ length: rowWidthBefore }, () => 250);
|
|
57
|
+
if (rowWidthBefore < currentWidths.length) return;
|
|
58
|
+
const fallback = currentWidths[Math.max(0, columnIndex - 1)] || 250;
|
|
59
|
+
const next = [...currentWidths];
|
|
60
|
+
next.splice(columnIndex, 0, ...Array.from({ length: insertedSpan }, () => fallback));
|
|
61
|
+
table.setColWidths(next);
|
|
62
|
+
}
|
|
63
|
+
function $removeTableWidthsForCompleteCellGroup(table, group, columnIndex, span) {
|
|
64
|
+
const rows = table.getChildren().filter($isTableRowNode);
|
|
65
|
+
const rowKeys = new Set(group.map((cell) => cell.getParent()?.getKey()));
|
|
66
|
+
if (rows.length !== rowKeys.size) return;
|
|
67
|
+
const widths = table.getColWidths();
|
|
68
|
+
if (!widths) return;
|
|
69
|
+
const next = [...widths];
|
|
70
|
+
next.splice(columnIndex, span);
|
|
71
|
+
table.setColWidths(next);
|
|
72
|
+
}
|
|
73
|
+
function $shrinkTableWidthsAfterCellRemoval(table, columnIndex, span) {
|
|
74
|
+
const widths = table.getColWidths();
|
|
75
|
+
if (!widths) return;
|
|
76
|
+
if (table.getChildren().reduce((max, row) => {
|
|
77
|
+
if (!$isTableRowNode(row)) return max;
|
|
78
|
+
return Math.max(max, row.getChildren().reduce((total, cell) => total + ($isTableCellNode(cell) ? cell.getColSpan() : 0), 0));
|
|
79
|
+
}, 0) > widths.length - span) return;
|
|
80
|
+
const next = [...widths];
|
|
81
|
+
next.splice(columnIndex, span);
|
|
82
|
+
table.setColWidths(next);
|
|
83
|
+
}
|
|
84
|
+
function $getMaximumLogicalColumnCount(table) {
|
|
85
|
+
return table.getChildren().reduce((maximum, row) => {
|
|
86
|
+
if (!$isTableRowNode(row)) return maximum;
|
|
87
|
+
const columnCount = row.getChildren().reduce((total, cell) => {
|
|
88
|
+
return total + ($isTableCellNode(cell) ? cell.getColSpan() : 0);
|
|
89
|
+
}, 0);
|
|
90
|
+
return Math.max(maximum, columnCount);
|
|
91
|
+
}, 0);
|
|
92
|
+
}
|
|
93
|
+
function $hasLegacyTableCellDiffs() {
|
|
94
|
+
return $nodesOfType(DiffNode).some((diff) => {
|
|
95
|
+
return (diff.diffType === "add" || diff.diffType === "remove") && $isTableRowNode(diff.getParent()) && diff.getChildren().some($isTableCellNode);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function $hasIncompleteTableWidths() {
|
|
99
|
+
return $nodesOfType(TableNode).some((table) => {
|
|
100
|
+
return (table.getColWidths()?.length || 0) < $getMaximumLogicalColumnCount(table);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Migrates the old `TableRow > DiffNode > TableCellNode` representation into
|
|
105
|
+
* cell-shaped diff nodes and makes sure the table has a width for every
|
|
106
|
+
* logical column. Safe to call repeatedly.
|
|
107
|
+
*/
|
|
108
|
+
function $normalizeLegacyTableCellDiffs(editor) {
|
|
109
|
+
let changed = false;
|
|
110
|
+
$nodesOfType(DiffNode).forEach((legacyDiff) => {
|
|
111
|
+
const diffType = legacyDiff.diffType;
|
|
112
|
+
if (diffType !== "add" && diffType !== "remove" || !$isTableRowNode(legacyDiff.getParent())) return;
|
|
113
|
+
const cells = legacyDiff.getChildren().filter($isTableCellNode);
|
|
114
|
+
if (cells.length === 0) return;
|
|
115
|
+
const changeId = `legacy-table-cell-${legacyDiff.getKey()}`;
|
|
116
|
+
cells.forEach((cell) => {
|
|
117
|
+
legacyDiff.insertBefore($createTableCellDiffFromCell(editor, cell, diffType, changeId));
|
|
118
|
+
});
|
|
119
|
+
legacyDiff.remove();
|
|
120
|
+
changed = true;
|
|
121
|
+
});
|
|
122
|
+
$nodesOfType(TableNode).forEach((table) => {
|
|
123
|
+
const requiredWidthCount = $getMaximumLogicalColumnCount(table);
|
|
124
|
+
const currentWidths = table.getColWidths() || [];
|
|
125
|
+
if (currentWidths.length >= requiredWidthCount) return;
|
|
126
|
+
const fallback = currentWidths.at(-1) || 250;
|
|
127
|
+
table.setColWidths([...currentWidths, ...Array.from({ length: requiredWidthCount - currentWidths.length }, () => fallback)]);
|
|
128
|
+
changed = true;
|
|
129
|
+
});
|
|
130
|
+
return changed;
|
|
131
|
+
}
|
|
132
|
+
function registerLegacyTableCellDiffNormalization(editor) {
|
|
133
|
+
let destroyed = false;
|
|
134
|
+
let scheduled = false;
|
|
135
|
+
const unregister = editor.registerUpdateListener(() => {
|
|
136
|
+
if (scheduled || destroyed) return;
|
|
137
|
+
scheduled = true;
|
|
138
|
+
queueMicrotask(() => {
|
|
139
|
+
scheduled = false;
|
|
140
|
+
if (destroyed) return;
|
|
141
|
+
if (!editor.getEditorState().read(() => $hasLegacyTableCellDiffs() || $hasIncompleteTableWidths())) return;
|
|
142
|
+
editor.update(() => {
|
|
143
|
+
$normalizeLegacyTableCellDiffs(editor);
|
|
144
|
+
}, { discrete: true });
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
return () => {
|
|
148
|
+
destroyed = true;
|
|
149
|
+
unregister();
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
153
|
+
export { $createPlainTableCellFromDiff, $createTableCellDiffFromCell, $getLogicalRowWidth, $getTableCellColumnIndex, $getTableCellDiffGroup, $getTableForCell, $normalizeLegacyTableCellDiffs, $removeTableWidthsForCompleteCellGroup, $shrinkTableWidthsAfterCellRemoval, $updateTableWidthsForCellInsertion, registerLegacyTableCellDiffNormalization };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { $cloneNode } from "./utils/index.js";
|
|
2
|
+
import { $createTableRowDiffNode, TableRowDiffNode } from "./node/TableRowDiffNode.js";
|
|
3
|
+
import { $createTableRowNode, $isTableCellNode, $isTableNode } from "@lexical/table";
|
|
4
|
+
import { $nodesOfType } from "lexical";
|
|
5
|
+
//#region src/plugins/litexml/table-row-diff.ts
|
|
6
|
+
function $areTableRowStructuresCompatible(previousRow, nextRow) {
|
|
7
|
+
const previousCells = previousRow.getChildren();
|
|
8
|
+
const nextCells = nextRow.getChildren();
|
|
9
|
+
if (previousCells.length !== nextCells.length || !previousCells.every($isTableCellNode) || !nextCells.every($isTableCellNode)) return false;
|
|
10
|
+
return previousCells.every((previousCell, index) => {
|
|
11
|
+
const nextCell = nextCells[index];
|
|
12
|
+
return $isTableCellNode(nextCell) && previousCell.getColSpan() === nextCell.getColSpan() && previousCell.getRowSpan() === nextCell.getRowSpan();
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function $createTableRowDiffFromRow(editor, row, diffType, changeId) {
|
|
16
|
+
const source = $cloneNode(row, editor);
|
|
17
|
+
const diffRow = $createTableRowDiffNode(diffType, changeId, row.getHeight());
|
|
18
|
+
diffRow.append(...source.getChildren());
|
|
19
|
+
return diffRow;
|
|
20
|
+
}
|
|
21
|
+
function $createPlainTableRowFromDiff(editor, row) {
|
|
22
|
+
const plainRow = $createTableRowNode(row.getHeight());
|
|
23
|
+
plainRow.append(...row.getChildren().map((child) => $cloneNode(child, editor)));
|
|
24
|
+
return plainRow;
|
|
25
|
+
}
|
|
26
|
+
function $getTableRowDiffPair(node) {
|
|
27
|
+
const changeId = node.getChangeId();
|
|
28
|
+
if (!changeId) return null;
|
|
29
|
+
const matchingRows = $nodesOfType(TableRowDiffNode).filter((candidate) => candidate.getChangeId() === changeId);
|
|
30
|
+
if (matchingRows.length !== 2) return null;
|
|
31
|
+
const remove = matchingRows.find((candidate) => candidate.getDiffType() === "remove");
|
|
32
|
+
const add = matchingRows.find((candidate) => candidate.getDiffType() === "add");
|
|
33
|
+
if (!remove || !add) return null;
|
|
34
|
+
const parent = remove.getParent();
|
|
35
|
+
if (!$isTableNode(parent) || add.getParent() !== parent || remove.getNextSibling() !== add || !$areTableRowStructuresCompatible(remove, add)) return null;
|
|
36
|
+
return {
|
|
37
|
+
add,
|
|
38
|
+
remove
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function $normalizeTableRowDiffPairs() {
|
|
42
|
+
const rows = $nodesOfType(TableRowDiffNode);
|
|
43
|
+
const groups = /* @__PURE__ */ new Map();
|
|
44
|
+
rows.forEach((row) => {
|
|
45
|
+
const changeId = row.getChangeId();
|
|
46
|
+
if (!changeId) return;
|
|
47
|
+
const group = groups.get(changeId) || [];
|
|
48
|
+
group.push(row);
|
|
49
|
+
groups.set(changeId, group);
|
|
50
|
+
});
|
|
51
|
+
let changed = false;
|
|
52
|
+
groups.forEach((group) => {
|
|
53
|
+
if (group.length === 2 ? $getTableRowDiffPair(group[0]) : null) return;
|
|
54
|
+
group.forEach((row) => row.setChangeId());
|
|
55
|
+
changed = true;
|
|
56
|
+
});
|
|
57
|
+
return changed;
|
|
58
|
+
}
|
|
59
|
+
function registerTableRowDiffNormalization(editor) {
|
|
60
|
+
let destroyed = false;
|
|
61
|
+
let scheduled = false;
|
|
62
|
+
const unregister = editor.registerUpdateListener(() => {
|
|
63
|
+
if (scheduled || destroyed) return;
|
|
64
|
+
scheduled = true;
|
|
65
|
+
queueMicrotask(() => {
|
|
66
|
+
scheduled = false;
|
|
67
|
+
if (destroyed) return;
|
|
68
|
+
if (!editor.getEditorState().read(() => {
|
|
69
|
+
return $nodesOfType(TableRowDiffNode).some((row) => row.getChangeId() && !$getTableRowDiffPair(row));
|
|
70
|
+
})) return;
|
|
71
|
+
editor.update(() => {
|
|
72
|
+
$normalizeTableRowDiffPairs();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
return () => {
|
|
77
|
+
destroyed = true;
|
|
78
|
+
unregister();
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { $areTableRowStructuresCompatible, $createPlainTableRowFromDiff, $createTableRowDiffFromRow, $getTableRowDiffPair, $normalizeTableRowDiffPairs, registerTableRowDiffNormalization };
|
|
@@ -72,8 +72,29 @@ function convertMdastToLexical(node, index, ctx, markdownReaders = {}, parentTyp
|
|
|
72
72
|
return ret;
|
|
73
73
|
}
|
|
74
74
|
if (child.value.startsWith("<!--") && child.value.endsWith("-->")) return ret;
|
|
75
|
-
const tag = child.value
|
|
75
|
+
const tag = getHtmlTagName(child.value);
|
|
76
76
|
const isEndTag = child.value.startsWith("</");
|
|
77
|
+
const pairedTag = child.value.match(/^<\s*([a-z0-9-]+)\b[^>]*>([\s\S]*)<\/\s*\1\s*>$/i);
|
|
78
|
+
if (!isEndTag && pairedTag) {
|
|
79
|
+
const reader = markdownReaders["html"];
|
|
80
|
+
const htmlChildren = pairedTag[2] ? [INodeHelper.createTextNode(pairedTag[2])] : [];
|
|
81
|
+
if (Array.isArray(reader)) for (const element of reader) {
|
|
82
|
+
const inode = element(child, htmlChildren, index);
|
|
83
|
+
if (inode) {
|
|
84
|
+
ret.push(inode);
|
|
85
|
+
return ret;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else if (typeof reader === "function") {
|
|
89
|
+
const inode = reader(child, htmlChildren, index);
|
|
90
|
+
if (inode) {
|
|
91
|
+
ret.push(inode);
|
|
92
|
+
return ret;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
ret.push(INodeHelper.createTextNode(child.value));
|
|
96
|
+
return ret;
|
|
97
|
+
}
|
|
77
98
|
if (selfClosingHtmlTags.has(tag)) {
|
|
78
99
|
const reader = markdownReaders["html"];
|
|
79
100
|
if (Array.isArray(reader)) for (const element of reader) {
|
|
@@ -160,6 +181,9 @@ function convertMdastToLexical(node, index, ctx, markdownReaders = {}, parentTyp
|
|
|
160
181
|
}
|
|
161
182
|
}
|
|
162
183
|
}
|
|
184
|
+
function getHtmlTagName(value) {
|
|
185
|
+
return value.match(/^<\/?\s*([a-z0-9-]+)/i)?.[1]?.toLowerCase() || value.replaceAll(/^<\/?|>$/g, "");
|
|
186
|
+
}
|
|
163
187
|
function registerDefaultReaders(markdownReaders) {
|
|
164
188
|
if (!markdownReaders["root"]) markdownReaders["root"] = (node, children) => {
|
|
165
189
|
return {
|
|
@@ -13,6 +13,7 @@ init_plugin();
|
|
|
13
13
|
init_debug();
|
|
14
14
|
const DEFAULT_PASTE_MARKDOWN_AUTO_CONVERT_THRESHOLD = 5;
|
|
15
15
|
const RICH_HTML_SELECTOR = "strong,em,b,i,h1,h2,h3,h4,h5,h6,ul,ol,table,img,blockquote,pre>code,a[href]";
|
|
16
|
+
const normalizeMarkdownForClipboard = (markdown) => markdown.replace(/\r?\n$/, "");
|
|
16
17
|
const MARKDOWN_DETECTION_RULES = [
|
|
17
18
|
{
|
|
18
19
|
name: "headers",
|
|
@@ -209,8 +210,9 @@ const MarkdownPlugin = class extends KernelPlugin {
|
|
|
209
210
|
if (!clipboardData) return false;
|
|
210
211
|
const selection = $getSelection();
|
|
211
212
|
if (!selection || selection.isCollapsed()) return false;
|
|
212
|
-
const
|
|
213
|
-
if (!
|
|
213
|
+
const rawMarkdown = this.markdownDataSource.write(editor, { selection: true });
|
|
214
|
+
if (!rawMarkdown) return false;
|
|
215
|
+
const markdown = normalizeMarkdownForClipboard(rawMarkdown);
|
|
214
216
|
event.preventDefault();
|
|
215
217
|
const data = $getClipboardDataFromSelection(selection);
|
|
216
218
|
setLexicalClipboardDataTransfer(clipboardData, data);
|
|
@@ -283,4 +285,4 @@ const MarkdownPlugin = class extends KernelPlugin {
|
|
|
283
285
|
}
|
|
284
286
|
};
|
|
285
287
|
//#endregion
|
|
286
|
-
export { MarkdownPlugin };
|
|
288
|
+
export { MarkdownPlugin, normalizeMarkdownForClipboard };
|
|
@@ -3,13 +3,14 @@ import { init_utils, noop } from "../../../editor-kernel/utils.js";
|
|
|
3
3
|
import { useLexicalComposerContext } from "../../../editor-kernel/react/react-context.js";
|
|
4
4
|
import { useLexicalEditor } from "../../../editor-kernel/react/useLexicalEditor.js";
|
|
5
5
|
import { $splitNodeContainingQuery } from "../utils/utils.js";
|
|
6
|
-
import { ISlashService
|
|
6
|
+
import { ISlashService } from "../service/i-slash-service.js";
|
|
7
7
|
import { SlashPlugin } from "../plugin/index.js";
|
|
8
8
|
import SlashMenu from "./components/SlashMenu.js";
|
|
9
|
+
import { findSlashOptionByKey, getNextSlashActiveKey, getNextSlashSpatialActiveKey } from "./menu-utils.js";
|
|
9
10
|
import { setCancelablePromise } from "./utils.js";
|
|
10
11
|
import { Children, useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
11
12
|
import { jsx } from "react/jsx-runtime";
|
|
12
|
-
import { COMMAND_PRIORITY_CRITICAL, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_DOWN_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND } from "lexical";
|
|
13
|
+
import { COMMAND_PRIORITY_CRITICAL, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_LEFT_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_DOWN_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND } from "lexical";
|
|
13
14
|
import { mergeRegister } from "@lexical/utils";
|
|
14
15
|
//#region src/plugins/slash/react/ReactSlashPlugin.tsx
|
|
15
16
|
init_utils();
|
|
@@ -36,12 +37,10 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
|
|
|
36
37
|
const handleActiveKeyChange = useCallback((key) => {
|
|
37
38
|
setActiveKey(key);
|
|
38
39
|
}, []);
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
}, [activeKey]);
|
|
40
|
+
const updateMenuOptions = useCallback((items) => {
|
|
41
|
+
setOptions(items);
|
|
42
|
+
setActiveKey(getNextSlashActiveKey(items, null, "forward"));
|
|
43
|
+
}, []);
|
|
45
44
|
useLayoutEffect(() => {
|
|
46
45
|
const options = Children.map(children, (child) => {
|
|
47
46
|
if (!child) return null;
|
|
@@ -58,18 +57,14 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
|
|
|
58
57
|
triggerOpen: (ctx) => {
|
|
59
58
|
setResolution(ctx);
|
|
60
59
|
cancelRef.current.cancel();
|
|
61
|
-
if (Array.isArray(ctx.items))
|
|
62
|
-
|
|
63
|
-
setInitialActiveKey(ctx.items);
|
|
64
|
-
} else {
|
|
60
|
+
if (Array.isArray(ctx.items)) updateMenuOptions(ctx.items);
|
|
61
|
+
else {
|
|
65
62
|
setLoading(true);
|
|
66
63
|
const pr = setCancelablePromise((resolve, reject) => {
|
|
67
64
|
ctx.items(ctx.match || null).then(resolve, reject).finally(() => setLoading(false));
|
|
68
65
|
});
|
|
69
66
|
pr.promise.then((items) => {
|
|
70
|
-
|
|
71
|
-
setOptions(typedItems);
|
|
72
|
-
setInitialActiveKey(typedItems);
|
|
67
|
+
updateMenuOptions(items);
|
|
73
68
|
});
|
|
74
69
|
cancelRef.current.cancel = () => {
|
|
75
70
|
pr.cancel();
|
|
@@ -89,7 +84,7 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
|
|
|
89
84
|
}, [
|
|
90
85
|
editor,
|
|
91
86
|
close,
|
|
92
|
-
|
|
87
|
+
updateMenuOptions
|
|
93
88
|
]);
|
|
94
89
|
useLayoutEffect(() => {
|
|
95
90
|
const slash = editor.requireService(ISlashService);
|
|
@@ -118,30 +113,15 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
|
|
|
118
113
|
close
|
|
119
114
|
]);
|
|
120
115
|
useLexicalEditor(() => {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return true;
|
|
131
|
-
}
|
|
132
|
-
return false;
|
|
133
|
-
}, COMMAND_PRIORITY_CRITICAL), editor.registerHighCommand(KEY_ARROW_UP_COMMAND, (payload) => {
|
|
134
|
-
const event = payload;
|
|
135
|
-
if (pureOptions !== null && pureOptions.length) {
|
|
136
|
-
const currentIndex = activeKey ? pureOptions.findIndex((opt) => opt.key === activeKey) : -1;
|
|
137
|
-
const newIndex = currentIndex === -1 ? pureOptions.length - 1 : (currentIndex - 1 + pureOptions.length) % pureOptions.length;
|
|
138
|
-
setActiveKey(String(pureOptions[newIndex].key));
|
|
139
|
-
event.preventDefault();
|
|
140
|
-
event.stopImmediatePropagation();
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
143
|
-
return false;
|
|
144
|
-
}, COMMAND_PRIORITY_CRITICAL), editor.registerHighCommand(KEY_ESCAPE_COMMAND, (payload) => {
|
|
116
|
+
const activateSpatialSibling = (event, direction) => {
|
|
117
|
+
const nextKey = getNextSlashSpatialActiveKey(options, activeKey, direction);
|
|
118
|
+
if (!nextKey) return false;
|
|
119
|
+
setActiveKey(nextKey);
|
|
120
|
+
event.preventDefault();
|
|
121
|
+
event.stopImmediatePropagation();
|
|
122
|
+
return true;
|
|
123
|
+
};
|
|
124
|
+
return mergeRegister(editor.registerHighCommand(KEY_ARROW_DOWN_COMMAND, (payload) => activateSpatialSibling(payload, "down"), COMMAND_PRIORITY_CRITICAL), editor.registerHighCommand(KEY_ARROW_UP_COMMAND, (payload) => activateSpatialSibling(payload, "up"), COMMAND_PRIORITY_CRITICAL), editor.registerHighCommand(KEY_ARROW_RIGHT_COMMAND, (payload) => activateSpatialSibling(payload, "right"), COMMAND_PRIORITY_CRITICAL), editor.registerHighCommand(KEY_ARROW_LEFT_COMMAND, (payload) => activateSpatialSibling(payload, "left"), COMMAND_PRIORITY_CRITICAL), editor.registerHighCommand(KEY_ESCAPE_COMMAND, (payload) => {
|
|
145
125
|
const event = payload;
|
|
146
126
|
event.preventDefault();
|
|
147
127
|
event.stopImmediatePropagation();
|
|
@@ -150,7 +130,7 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
|
|
|
150
130
|
}, COMMAND_PRIORITY_CRITICAL), editor.registerHighCommand(KEY_TAB_COMMAND, (payload) => {
|
|
151
131
|
const event = payload;
|
|
152
132
|
if (options === null || activeKey === null) return false;
|
|
153
|
-
const selectedOption =
|
|
133
|
+
const selectedOption = findSlashOptionByKey(options, activeKey);
|
|
154
134
|
if (!selectedOption) return false;
|
|
155
135
|
event.preventDefault();
|
|
156
136
|
event.stopImmediatePropagation();
|
|
@@ -161,7 +141,7 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
|
|
|
161
141
|
event.preventDefault();
|
|
162
142
|
event.stopImmediatePropagation();
|
|
163
143
|
if (options !== null && activeKey !== null) {
|
|
164
|
-
const selectedOption =
|
|
144
|
+
const selectedOption = findSlashOptionByKey(options, activeKey);
|
|
165
145
|
if (selectedOption) handleMenuSelect(selectedOption);
|
|
166
146
|
}
|
|
167
147
|
return true;
|
|
@@ -171,7 +151,6 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
|
|
|
171
151
|
}, [
|
|
172
152
|
options,
|
|
173
153
|
activeKey,
|
|
174
|
-
handleActiveKeyChange,
|
|
175
154
|
handleMenuSelect,
|
|
176
155
|
isOpen
|
|
177
156
|
]);
|