@lobehub/editor 4.15.2 → 4.16.1
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/react/useDecorators.js +14 -8
- package/es/headless/index.d.ts +1 -1
- package/es/headless/index.js +1 -1
- package/es/headless.d.ts +3 -18
- package/es/headless.js +711 -52
- package/es/index.d.ts +5 -5
- package/es/index.js +5 -5
- package/es/locale/index.d.ts +2 -0
- package/es/locale/index.js +5 -1
- package/es/plugins/auto-complete/plugin/index.js +3 -3
- package/es/plugins/block/index.d.ts +1 -1
- package/es/plugins/block/plugin/index.js +78 -2
- package/es/plugins/block/react/ReactBlockPlugin.js +172 -16
- package/es/plugins/block/react/drag/drag-utils.js +37 -10
- package/es/plugins/block/service/i-block-menu-service.d.ts +18 -1
- package/es/plugins/block/service/i-block-menu-service.js +24 -0
- package/es/plugins/block/service/index.d.ts +1 -1
- package/es/plugins/codeblock/plugin/index.js +25 -1
- package/es/plugins/common/plugin/register.js +2 -2
- package/es/plugins/litexml/command/diffCommand.d.ts +2 -17
- package/es/plugins/litexml/command/diffCommand.js +3 -9
- package/es/plugins/litexml/command/index.d.ts +2 -38
- package/es/plugins/litexml/command/index.js +3 -6
- package/es/plugins/litexml/command/symbols.d.ts +67 -0
- package/es/plugins/litexml/command/symbols.js +34 -0
- package/es/plugins/litexml/index.d.ts +1 -2
- package/es/plugins/litexml/plugin/index.js +8 -2
- package/es/plugins/litexml/react/DiffNodeToolbar/index.js +1 -1
- package/es/plugins/slash/plugin/index.js +1 -1
- package/es/plugins/slash/react/ReactSlashPlugin.js +4 -4
- package/es/plugins/table/command/index.d.ts +13 -1
- package/es/plugins/table/command/index.js +220 -39
- package/es/plugins/table/index.d.ts +3 -2
- package/es/plugins/table/node/index.d.ts +2 -0
- package/es/plugins/table/node/index.js +130 -2
- package/es/plugins/table/plugin/index.d.ts +6 -0
- package/es/plugins/table/plugin/index.js +193 -4
- package/es/plugins/table/react/TableActionMenu/ActionMenu.js +82 -6
- package/es/plugins/table/react/TableActionMenu/index.js +9 -4
- package/es/plugins/table/react/TableColController.js +354 -0
- package/es/plugins/table/react/TableController/hooks.js +201 -0
- package/es/plugins/table/react/TableController/style.js +264 -0
- package/es/plugins/table/react/TableController/utils.js +25 -0
- package/es/plugins/table/react/TableControllerButton.js +81 -0
- package/es/plugins/table/react/TableControllerMenu.js +123 -0
- package/es/plugins/table/react/TableInsertButton.js +25 -0
- package/es/plugins/table/react/TableResize/index.js +153 -78
- package/es/plugins/table/react/TableRowController.js +349 -0
- package/es/plugins/table/react/hooks.js +77 -0
- package/es/plugins/table/react/index.js +139 -16
- package/es/plugins/table/react/style.js +89 -8
- package/es/plugins/table/react/type.d.ts +2 -0
- package/es/plugins/table/react/useAutoFitPastedTable.js +189 -0
- package/es/plugins/table/service/i-table-controller-menu-service.d.ts +44 -0
- package/es/plugins/table/service/i-table-controller-menu-service.js +31 -0
- package/es/plugins/table/service/index.d.ts +1 -0
- package/es/plugins/table/utils/autoFitColumnWidth.js +87 -0
- package/es/plugins/table/utils/distributeColumnWidth.js +37 -0
- package/es/plugins/table/utils/index.js +102 -2
- package/es/react/EditorProvider/index.d.ts +2 -2
- package/es/renderer/LexicalDiff.d.ts +2 -2
- package/es/symbols-DEEvsKq4.d.ts +67 -0
- package/package.json +5 -1
|
@@ -1,21 +1,48 @@
|
|
|
1
1
|
//#region src/plugins/block/react/drag/drag-utils.ts
|
|
2
|
+
const toRectSnapshot = (rect) => ({
|
|
3
|
+
bottom: rect.bottom,
|
|
4
|
+
height: rect.height,
|
|
5
|
+
left: rect.left,
|
|
6
|
+
top: rect.top,
|
|
7
|
+
width: rect.width
|
|
8
|
+
});
|
|
9
|
+
const isTableBlockElement = (element) => {
|
|
10
|
+
return element instanceof HTMLTableElement || Boolean(element.querySelector("table.editor_table, table"));
|
|
11
|
+
};
|
|
12
|
+
const getTableBlockRect = (element) => {
|
|
13
|
+
const table = element instanceof HTMLTableElement ? element : element.querySelector("table.editor_table, table");
|
|
14
|
+
if (!(table instanceof HTMLElement)) return null;
|
|
15
|
+
const tableRect = table.getBoundingClientRect();
|
|
16
|
+
const firstCell = table.querySelector("th, td");
|
|
17
|
+
if (firstCell instanceof HTMLElement) {
|
|
18
|
+
const cellRect = firstCell.getBoundingClientRect();
|
|
19
|
+
if (cellRect.width > 0 && cellRect.height > 0) return {
|
|
20
|
+
bottom: tableRect.height > 0 ? tableRect.bottom : cellRect.bottom,
|
|
21
|
+
height: tableRect.height > 0 ? tableRect.height : cellRect.height,
|
|
22
|
+
left: cellRect.left,
|
|
23
|
+
top: tableRect.height > 0 ? tableRect.top : cellRect.top,
|
|
24
|
+
width: tableRect.width > 0 ? tableRect.width : cellRect.width
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (tableRect.height <= 0) return null;
|
|
28
|
+
return toRectSnapshot(tableRect);
|
|
29
|
+
};
|
|
30
|
+
const getBlockMeasureRect = (block) => {
|
|
31
|
+
const rect = isTableBlockElement(block) ? getTableBlockRect(block) : toRectSnapshot(block.getBoundingClientRect());
|
|
32
|
+
if (!rect || rect.height <= 0) return null;
|
|
33
|
+
return rect;
|
|
34
|
+
};
|
|
2
35
|
const collectDragBlocks = (root) => {
|
|
3
36
|
if (!root) return [];
|
|
4
37
|
return Array.from(root.querySelectorAll("[data-block-id]")).reduce((acc, block) => {
|
|
5
38
|
const blockId = block.dataset.blockId;
|
|
6
39
|
if (!blockId) return acc;
|
|
7
|
-
const rect = block
|
|
8
|
-
if (rect
|
|
40
|
+
const rect = getBlockMeasureRect(block);
|
|
41
|
+
if (!rect) return acc;
|
|
9
42
|
acc.push({
|
|
10
43
|
block,
|
|
11
44
|
blockId,
|
|
12
|
-
rect
|
|
13
|
-
bottom: rect.bottom,
|
|
14
|
-
height: rect.height,
|
|
15
|
-
left: rect.left,
|
|
16
|
-
top: rect.top,
|
|
17
|
-
width: rect.width
|
|
18
|
-
}
|
|
45
|
+
rect
|
|
19
46
|
});
|
|
20
47
|
return acc;
|
|
21
48
|
}, []).sort((a, b) => a.rect.top - b.rect.top);
|
|
@@ -92,4 +119,4 @@ const resolveNearestInsertionSlot = (sourceBlockId, blocks, y) => {
|
|
|
92
119
|
return bestSlot;
|
|
93
120
|
};
|
|
94
121
|
//#endregion
|
|
95
|
-
export { collectDragBlocks, getAutoScrollDelta, resolveNearestInsertionSlot, resolveScrollContainers };
|
|
122
|
+
export { collectDragBlocks, getAutoScrollDelta, getBlockMeasureRect, getTableBlockRect, isTableBlockElement, resolveNearestInsertionSlot, resolveScrollContainers };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { IEditor, IServiceID } from "../../../types/kernel.js";
|
|
2
|
+
import { LexicalNode } from "lexical";
|
|
3
|
+
|
|
2
4
|
//#region src/plugins/block/service/i-block-menu-service.d.ts
|
|
3
5
|
interface IBlockMenuRenderContext {
|
|
4
6
|
blockElement: HTMLElement;
|
|
@@ -21,11 +23,20 @@ interface IBlockActionButton {
|
|
|
21
23
|
title: string | ((context: IBlockMenuRenderContext) => string);
|
|
22
24
|
when?: (context: IBlockMenuRenderContext) => boolean;
|
|
23
25
|
}
|
|
26
|
+
interface IBlockSelectHandler {
|
|
27
|
+
key: string;
|
|
28
|
+
onSelect: (node: LexicalNode) => boolean | void;
|
|
29
|
+
order?: number;
|
|
30
|
+
}
|
|
24
31
|
interface IBlockMenuService {
|
|
25
32
|
getActionButtons(context: IBlockMenuRenderContext): IBlockActionButton[];
|
|
26
33
|
getMenus(context: IBlockMenuRenderContext): IBlockMenuItem[];
|
|
34
|
+
isMenuSuppressed(): boolean;
|
|
27
35
|
registerActionButton(item: IBlockActionButton): () => void;
|
|
28
36
|
registerMenu(item: IBlockMenuItem): () => void;
|
|
37
|
+
registerSelectHandler(item: IBlockSelectHandler): () => void;
|
|
38
|
+
selectNode(node: LexicalNode): boolean;
|
|
39
|
+
setMenuSuppressed(key: string, suppressed: boolean): void;
|
|
29
40
|
subscribe(listener: () => void): () => void;
|
|
30
41
|
}
|
|
31
42
|
declare const IBlockMenuService: IServiceID<IBlockMenuService>;
|
|
@@ -33,12 +44,18 @@ declare class BlockMenuService implements IBlockMenuService {
|
|
|
33
44
|
private actionButtons;
|
|
34
45
|
private items;
|
|
35
46
|
private listeners;
|
|
47
|
+
private selectHandlers;
|
|
48
|
+
private suppressors;
|
|
36
49
|
getActionButtons(context: IBlockMenuRenderContext): IBlockActionButton[];
|
|
37
50
|
getMenus(context: IBlockMenuRenderContext): IBlockMenuItem[];
|
|
51
|
+
isMenuSuppressed(): boolean;
|
|
38
52
|
registerActionButton(item: IBlockActionButton): () => void;
|
|
39
53
|
registerMenu(item: IBlockMenuItem): () => void;
|
|
54
|
+
registerSelectHandler(item: IBlockSelectHandler): () => void;
|
|
55
|
+
selectNode(node: LexicalNode): boolean;
|
|
56
|
+
setMenuSuppressed(key: string, suppressed: boolean): void;
|
|
40
57
|
subscribe(listener: () => void): () => void;
|
|
41
58
|
private notify;
|
|
42
59
|
}
|
|
43
60
|
//#endregion
|
|
44
|
-
export { BlockMenuService, IBlockActionButton, IBlockActionButtonIcon, IBlockMenuItem, IBlockMenuRenderContext, IBlockMenuService };
|
|
61
|
+
export { BlockMenuService, IBlockActionButton, IBlockActionButtonIcon, IBlockMenuItem, IBlockMenuRenderContext, IBlockMenuService, IBlockSelectHandler };
|
|
@@ -6,6 +6,8 @@ var BlockMenuService = class {
|
|
|
6
6
|
this.actionButtons = /* @__PURE__ */ new Map();
|
|
7
7
|
this.items = /* @__PURE__ */ new Map();
|
|
8
8
|
this.listeners = /* @__PURE__ */ new Set();
|
|
9
|
+
this.selectHandlers = /* @__PURE__ */ new Map();
|
|
10
|
+
this.suppressors = /* @__PURE__ */ new Set();
|
|
9
11
|
}
|
|
10
12
|
getActionButtons(context) {
|
|
11
13
|
return Array.from(this.actionButtons.values()).filter((item) => item.when ? item.when(context) : true).sort((a, b) => (a.order || 0) - (b.order || 0));
|
|
@@ -13,6 +15,9 @@ var BlockMenuService = class {
|
|
|
13
15
|
getMenus(context) {
|
|
14
16
|
return Array.from(this.items.values()).filter((item) => item.when ? item.when(context) : true).sort((a, b) => (a.order || 0) - (b.order || 0));
|
|
15
17
|
}
|
|
18
|
+
isMenuSuppressed() {
|
|
19
|
+
return this.suppressors.size > 0;
|
|
20
|
+
}
|
|
16
21
|
registerActionButton(item) {
|
|
17
22
|
this.actionButtons.set(item.key, item);
|
|
18
23
|
this.notify();
|
|
@@ -29,6 +34,25 @@ var BlockMenuService = class {
|
|
|
29
34
|
this.notify();
|
|
30
35
|
};
|
|
31
36
|
}
|
|
37
|
+
registerSelectHandler(item) {
|
|
38
|
+
this.selectHandlers.set(item.key, item);
|
|
39
|
+
this.notify();
|
|
40
|
+
return () => {
|
|
41
|
+
this.selectHandlers.delete(item.key);
|
|
42
|
+
this.notify();
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
selectNode(node) {
|
|
46
|
+
const handlers = Array.from(this.selectHandlers.values()).sort((a, b) => (a.order || 0) - (b.order || 0));
|
|
47
|
+
for (const handler of handlers) if (handler.onSelect(node)) return true;
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
setMenuSuppressed(key, suppressed) {
|
|
51
|
+
const size = this.suppressors.size;
|
|
52
|
+
if (suppressed) this.suppressors.add(key);
|
|
53
|
+
else this.suppressors.delete(key);
|
|
54
|
+
if (this.suppressors.size !== size) this.notify();
|
|
55
|
+
}
|
|
32
56
|
subscribe(listener) {
|
|
33
57
|
this.listeners.add(listener);
|
|
34
58
|
return () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import { BlockMenuService, IBlockActionButton, IBlockActionButtonIcon, IBlockMenuItem, IBlockMenuRenderContext, IBlockMenuService } from "./i-block-menu-service.js";
|
|
1
|
+
import { BlockMenuService, IBlockActionButton, IBlockActionButtonIcon, IBlockMenuItem, IBlockMenuRenderContext, IBlockMenuService, IBlockSelectHandler } from "./i-block-menu-service.js";
|
|
@@ -2,10 +2,11 @@ import { INodeHelper, init_helper } from "../../../editor-kernel/inode/helper.js
|
|
|
2
2
|
import { KernelPlugin, init_plugin } from "../../../editor-kernel/plugin.js";
|
|
3
3
|
import { ILitexmlService } from "../../litexml/service/litexml-service.js";
|
|
4
4
|
import { IMarkdownShortCutService } from "../../markdown/service/shortcut.js";
|
|
5
|
+
import { IBlockMenuService } from "../../block/service/i-block-menu-service.js";
|
|
5
6
|
import { getCodeLanguageByInput } from "../utils/language.js";
|
|
6
7
|
import { registerCodeHighlighting, toCodeTheme } from "./CodeHighlighterShiki.js";
|
|
7
8
|
import { CustomShikiTokenizer, registerCodeCommand } from "../command/index.js";
|
|
8
|
-
import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, PASTE_COMMAND, TabNode } from "lexical";
|
|
9
|
+
import { $createRangeSelection, $getSelection, $isRangeSelection, $setSelection, COMMAND_PRIORITY_EDITOR, PASTE_COMMAND, TabNode } from "lexical";
|
|
9
10
|
import { $createCodeNode, $isCodeHighlightNode, $isCodeNode, CodeHighlightNode, CodeNode } from "@lexical/code-core";
|
|
10
11
|
//#region src/plugins/codeblock/plugin/index.ts
|
|
11
12
|
init_helper();
|
|
@@ -75,6 +76,29 @@ const CodeblockPlugin = class extends KernelPlugin {
|
|
|
75
76
|
}, COMMAND_PRIORITY_EDITOR));
|
|
76
77
|
this.registerMarkdown();
|
|
77
78
|
this.registerLiteXml();
|
|
79
|
+
this.registerBlockSelect();
|
|
80
|
+
}
|
|
81
|
+
registerBlockSelect() {
|
|
82
|
+
const blockMenuService = this.kernel.requireService(IBlockMenuService);
|
|
83
|
+
if (!blockMenuService) return;
|
|
84
|
+
this.register(blockMenuService.registerSelectHandler({
|
|
85
|
+
key: "__codeblock_block_select_handler",
|
|
86
|
+
onSelect: (node) => {
|
|
87
|
+
if (!$isCodeNode(node)) return false;
|
|
88
|
+
const textNodes = node.getAllTextNodes();
|
|
89
|
+
const firstTextNode = textNodes[0];
|
|
90
|
+
const lastTextNode = textNodes.at(-1);
|
|
91
|
+
if (!firstTextNode || !lastTextNode) {
|
|
92
|
+
node.select(0, node.getChildrenSize());
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
const selection = $createRangeSelection();
|
|
96
|
+
selection.setTextNodeRange(firstTextNode, 0, lastTextNode, lastTextNode.getTextContentSize());
|
|
97
|
+
$setSelection(selection);
|
|
98
|
+
return true;
|
|
99
|
+
},
|
|
100
|
+
order: 100
|
|
101
|
+
}));
|
|
78
102
|
}
|
|
79
103
|
registerLiteXml() {
|
|
80
104
|
const litexmlService = this.kernel.requireService(ILitexmlService);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createDebugLogger, init_debug } from "../../../utils/debug.js";
|
|
2
2
|
import { HotkeyEnum, init_hotkey } from "../../../types/hotkey.js";
|
|
3
3
|
import { $closest } from "../../../editor-kernel/utils.js";
|
|
4
|
-
import { $createNodeSelection, $createParagraphNode, $getRoot, $getSelection, $isDecoratorNode, $isElementNode, $isLineBreakNode, $isNodeSelection, $isRangeSelection, $isRootOrShadowRoot, $isTextNode, $setSelection, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_LOW, COMMAND_PRIORITY_NORMAL, FORMAT_TEXT_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_BACKSPACE_COMMAND, REDO_COMMAND, UNDO_COMMAND } from "lexical";
|
|
4
|
+
import { $createNodeSelection, $createParagraphNode, $getRoot, $getSelection, $isDecoratorNode, $isElementNode, $isLineBreakNode, $isNodeSelection, $isRangeSelection, $isRootOrShadowRoot, $isTextNode, $setSelection, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_LOW, COMMAND_PRIORITY_NORMAL, FORMAT_TEXT_COMMAND, HISTORIC_TAG, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_BACKSPACE_COMMAND, REDO_COMMAND, UNDO_COMMAND } from "lexical";
|
|
5
5
|
import { $isHeadingNode, QuoteNode } from "@lexical/rich-text";
|
|
6
6
|
import { mergeRegister } from "@lexical/utils";
|
|
7
7
|
import { $isCodeHighlightNode, $isCodeNode } from "@lexical/code-core";
|
|
@@ -297,7 +297,7 @@ function registerLastElement(editor) {
|
|
|
297
297
|
root.append(paragraph);
|
|
298
298
|
}
|
|
299
299
|
isProcessing = false;
|
|
300
|
-
});
|
|
300
|
+
}, { tag: HISTORIC_TAG });
|
|
301
301
|
});
|
|
302
302
|
}
|
|
303
303
|
});
|
|
@@ -1,17 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { LexicalEditor } from "lexical";
|
|
3
|
-
|
|
4
|
-
//#region src/plugins/litexml/command/diffCommand.d.ts
|
|
5
|
-
declare enum DiffAction {
|
|
6
|
-
Reject = 0,
|
|
7
|
-
Accept = 1
|
|
8
|
-
}
|
|
9
|
-
declare const LITEXML_DIFFNODE_COMMAND: _$lexical.LexicalCommand<{
|
|
10
|
-
action: DiffAction;
|
|
11
|
-
nodeKey: string;
|
|
12
|
-
}>;
|
|
13
|
-
declare const LITEXML_DIFFNODE_ALL_COMMAND: _$lexical.LexicalCommand<{
|
|
14
|
-
action: DiffAction;
|
|
15
|
-
}>;
|
|
16
|
-
//#endregion
|
|
17
|
-
export { DiffAction, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND };
|
|
1
|
+
import { DiffAction, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND } from "./symbols.js";
|
|
2
|
+
import { LexicalEditor } from "lexical";
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import { DiffNode } from "../node/DiffNode.js";
|
|
2
|
-
import {
|
|
2
|
+
import { LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND } from "./symbols.js";
|
|
3
|
+
import { $getNodeByKey, $isElementNode, COMMAND_PRIORITY_EDITOR } from "lexical";
|
|
3
4
|
import { mergeRegister } from "@lexical/utils";
|
|
4
5
|
//#region src/plugins/litexml/command/diffCommand.ts
|
|
5
|
-
let DiffAction = /* @__PURE__ */ function(DiffAction) {
|
|
6
|
-
DiffAction[DiffAction["Reject"] = 0] = "Reject";
|
|
7
|
-
DiffAction[DiffAction["Accept"] = 1] = "Accept";
|
|
8
|
-
return DiffAction;
|
|
9
|
-
}({});
|
|
10
|
-
const LITEXML_DIFFNODE_COMMAND = createCommand("LITEXML_DIFFNODE_COMMAND");
|
|
11
|
-
const LITEXML_DIFFNODE_ALL_COMMAND = createCommand("LITEXML_DIFFNODE_ALL_COMMAND");
|
|
12
6
|
function doAction(node, action) {
|
|
13
7
|
if (node.diffType === "modify") {
|
|
14
8
|
const children = node.getChildren();
|
|
@@ -94,4 +88,4 @@ function registerLiteXMLDiffCommand(editor) {
|
|
|
94
88
|
}, COMMAND_PRIORITY_EDITOR));
|
|
95
89
|
}
|
|
96
90
|
//#endregion
|
|
97
|
-
export {
|
|
91
|
+
export { registerLiteXMLDiffCommand };
|
|
@@ -1,38 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { LexicalEditor } from "lexical";
|
|
3
|
-
|
|
4
|
-
//#region src/plugins/litexml/command/index.d.ts
|
|
5
|
-
declare const LITEXML_MODIFY_COMMAND: _$lexical.LexicalCommand<({
|
|
6
|
-
action: "insert";
|
|
7
|
-
beforeId: string;
|
|
8
|
-
litexml: string;
|
|
9
|
-
} | {
|
|
10
|
-
action: "insert";
|
|
11
|
-
afterId: string;
|
|
12
|
-
litexml: string;
|
|
13
|
-
} | {
|
|
14
|
-
action: "remove";
|
|
15
|
-
id: string;
|
|
16
|
-
} | {
|
|
17
|
-
action: "modify";
|
|
18
|
-
litexml: string | string[];
|
|
19
|
-
})[]>;
|
|
20
|
-
declare const LITEXML_APPLY_COMMAND: _$lexical.LexicalCommand<{
|
|
21
|
-
delay?: boolean;
|
|
22
|
-
litexml: string | string[];
|
|
23
|
-
}>;
|
|
24
|
-
declare const LITEXML_REMOVE_COMMAND: _$lexical.LexicalCommand<{
|
|
25
|
-
delay?: boolean;
|
|
26
|
-
id: string;
|
|
27
|
-
}>;
|
|
28
|
-
declare const LITEXML_INSERT_COMMAND: _$lexical.LexicalCommand<{
|
|
29
|
-
beforeId: string;
|
|
30
|
-
delay?: boolean;
|
|
31
|
-
litexml: string;
|
|
32
|
-
} | {
|
|
33
|
-
afterId: string;
|
|
34
|
-
delay?: boolean;
|
|
35
|
-
litexml: string;
|
|
36
|
-
}>;
|
|
37
|
-
//#endregion
|
|
38
|
-
export { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND };
|
|
1
|
+
import { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND } from "./symbols.js";
|
|
2
|
+
import { LexicalEditor } from "lexical";
|
|
@@ -2,7 +2,8 @@ import { createDebugLogger, init_debug } from "../../../utils/debug.js";
|
|
|
2
2
|
import { $closest } from "../../../editor-kernel/utils.js";
|
|
3
3
|
import { $createDiffNode, DiffNode } from "../node/DiffNode.js";
|
|
4
4
|
import { $cloneNode, $parseSerializedNodeImpl, charToId } from "../utils/index.js";
|
|
5
|
-
import {
|
|
5
|
+
import { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND } from "./symbols.js";
|
|
6
|
+
import { $createParagraphNode, $getNodeByKey, $getRoot, $insertNodes, $isElementNode, COMMAND_PRIORITY_EDITOR } from "lexical";
|
|
6
7
|
import { mergeRegister } from "@lexical/utils";
|
|
7
8
|
import { $isListItemNode } from "@lexical/list";
|
|
8
9
|
//#region src/plugins/litexml/command/index.ts
|
|
@@ -101,10 +102,6 @@ function wrapBlockModify(oldBlock, editor, changeFn) {
|
|
|
101
102
|
diffNode.append($cloneNode(newBlock, editor));
|
|
102
103
|
newBlock.replace(diffNode, false);
|
|
103
104
|
}
|
|
104
|
-
const LITEXML_MODIFY_COMMAND = createCommand("LITEXML_MODIFY_COMMAND");
|
|
105
|
-
const LITEXML_APPLY_COMMAND = createCommand("LITEXML_APPLY_COMMAND");
|
|
106
|
-
const LITEXML_REMOVE_COMMAND = createCommand("LITEXML_REMOVE_COMMAND");
|
|
107
|
-
const LITEXML_INSERT_COMMAND = createCommand("LITEXML_INSERT_COMMAND");
|
|
108
105
|
function registerLiteXMLCommand(editor, dataSource) {
|
|
109
106
|
return mergeRegister(editor.registerCommand(LITEXML_MODIFY_COMMAND, (payload) => {
|
|
110
107
|
const resultPayload = payload.reduce((acc, cur) => {
|
|
@@ -330,4 +327,4 @@ function handleInsert(editor, payload, dataSource) {
|
|
|
330
327
|
});
|
|
331
328
|
}
|
|
332
329
|
//#endregion
|
|
333
|
-
export {
|
|
330
|
+
export { registerLiteXMLCommand };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as _$lexical from "lexical";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/litexml/command/symbols.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* LiteXML command identities.
|
|
6
|
+
*
|
|
7
|
+
* These symbols are intentionally isolated in a side-effect-free module so they
|
|
8
|
+
* keep a SINGLE runtime identity across every entry of this package.
|
|
9
|
+
*
|
|
10
|
+
* Lexical's `dispatchCommand` matches command listeners by object reference, not
|
|
11
|
+
* by the string label. The package ships two independently-bundled entries — the
|
|
12
|
+
* browser build (`index` / `react` / `renderer`) and the node build (`headless`)
|
|
13
|
+
* — and if each entry inlined its own `createCommand(...)` call, dispatching a
|
|
14
|
+
* command obtained from one entry onto an editor registered by the other would
|
|
15
|
+
* silently no-op (different object identities, same label).
|
|
16
|
+
*
|
|
17
|
+
* By keeping every command in this one module — exposed verbatim through
|
|
18
|
+
* `@lobehub/editor/litexml-commands` and emitted as a shared chunk by both
|
|
19
|
+
* builds — a single object backs the command in any runtime, and the module is
|
|
20
|
+
* pure enough to be imported on the server without pulling in the DOM-dependent
|
|
21
|
+
* editor bundle.
|
|
22
|
+
*/
|
|
23
|
+
declare enum DiffAction {
|
|
24
|
+
Reject = 0,
|
|
25
|
+
Accept = 1
|
|
26
|
+
}
|
|
27
|
+
declare const LITEXML_MODIFY_COMMAND: _$lexical.LexicalCommand<({
|
|
28
|
+
action: "insert";
|
|
29
|
+
beforeId: string;
|
|
30
|
+
litexml: string;
|
|
31
|
+
} | {
|
|
32
|
+
action: "insert";
|
|
33
|
+
afterId: string;
|
|
34
|
+
litexml: string;
|
|
35
|
+
} | {
|
|
36
|
+
action: "remove";
|
|
37
|
+
id: string;
|
|
38
|
+
} | {
|
|
39
|
+
action: "modify";
|
|
40
|
+
litexml: string | string[];
|
|
41
|
+
})[]>;
|
|
42
|
+
declare const LITEXML_APPLY_COMMAND: _$lexical.LexicalCommand<{
|
|
43
|
+
delay?: boolean;
|
|
44
|
+
litexml: string | string[];
|
|
45
|
+
}>;
|
|
46
|
+
declare const LITEXML_REMOVE_COMMAND: _$lexical.LexicalCommand<{
|
|
47
|
+
delay?: boolean;
|
|
48
|
+
id: string;
|
|
49
|
+
}>;
|
|
50
|
+
declare const LITEXML_INSERT_COMMAND: _$lexical.LexicalCommand<{
|
|
51
|
+
beforeId: string;
|
|
52
|
+
delay?: boolean;
|
|
53
|
+
litexml: string;
|
|
54
|
+
} | {
|
|
55
|
+
afterId: string;
|
|
56
|
+
delay?: boolean;
|
|
57
|
+
litexml: string;
|
|
58
|
+
}>;
|
|
59
|
+
declare const LITEXML_DIFFNODE_COMMAND: _$lexical.LexicalCommand<{
|
|
60
|
+
action: DiffAction;
|
|
61
|
+
nodeKey: string;
|
|
62
|
+
}>;
|
|
63
|
+
declare const LITEXML_DIFFNODE_ALL_COMMAND: _$lexical.LexicalCommand<{
|
|
64
|
+
action: DiffAction;
|
|
65
|
+
}>;
|
|
66
|
+
//#endregion
|
|
67
|
+
export { DiffAction, LITEXML_APPLY_COMMAND, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createCommand } from "lexical";
|
|
2
|
+
//#region src/plugins/litexml/command/symbols.ts
|
|
3
|
+
/**
|
|
4
|
+
* LiteXML command identities.
|
|
5
|
+
*
|
|
6
|
+
* These symbols are intentionally isolated in a side-effect-free module so they
|
|
7
|
+
* keep a SINGLE runtime identity across every entry of this package.
|
|
8
|
+
*
|
|
9
|
+
* Lexical's `dispatchCommand` matches command listeners by object reference, not
|
|
10
|
+
* by the string label. The package ships two independently-bundled entries — the
|
|
11
|
+
* browser build (`index` / `react` / `renderer`) and the node build (`headless`)
|
|
12
|
+
* — and if each entry inlined its own `createCommand(...)` call, dispatching a
|
|
13
|
+
* command obtained from one entry onto an editor registered by the other would
|
|
14
|
+
* silently no-op (different object identities, same label).
|
|
15
|
+
*
|
|
16
|
+
* By keeping every command in this one module — exposed verbatim through
|
|
17
|
+
* `@lobehub/editor/litexml-commands` and emitted as a shared chunk by both
|
|
18
|
+
* builds — a single object backs the command in any runtime, and the module is
|
|
19
|
+
* pure enough to be imported on the server without pulling in the DOM-dependent
|
|
20
|
+
* editor bundle.
|
|
21
|
+
*/
|
|
22
|
+
let DiffAction = /* @__PURE__ */ function(DiffAction) {
|
|
23
|
+
DiffAction[DiffAction["Reject"] = 0] = "Reject";
|
|
24
|
+
DiffAction[DiffAction["Accept"] = 1] = "Accept";
|
|
25
|
+
return DiffAction;
|
|
26
|
+
}({});
|
|
27
|
+
const LITEXML_MODIFY_COMMAND = createCommand("LITEXML_MODIFY_COMMAND");
|
|
28
|
+
const LITEXML_APPLY_COMMAND = createCommand("LITEXML_APPLY_COMMAND");
|
|
29
|
+
const LITEXML_REMOVE_COMMAND = createCommand("LITEXML_REMOVE_COMMAND");
|
|
30
|
+
const LITEXML_INSERT_COMMAND = createCommand("LITEXML_INSERT_COMMAND");
|
|
31
|
+
const LITEXML_DIFFNODE_COMMAND = createCommand("LITEXML_DIFFNODE_COMMAND");
|
|
32
|
+
const LITEXML_DIFFNODE_ALL_COMMAND = createCommand("LITEXML_DIFFNODE_ALL_COMMAND");
|
|
33
|
+
//#endregion
|
|
34
|
+
export { DiffAction, LITEXML_APPLY_COMMAND, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ILitexmlService, LitexmlService, XMLReaderFunc, XMLReaderRecord, XMLWriterFunc, XMLWriterRecord } from "./service/litexml-service.js";
|
|
2
2
|
import { LitexmlDataSource } from "./data-source/litexml-data-source.js";
|
|
3
|
-
import { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND } from "./command/
|
|
4
|
-
import { DiffAction, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND } from "./command/diffCommand.js";
|
|
3
|
+
import { DiffAction, LITEXML_APPLY_COMMAND, LITEXML_DIFFNODE_ALL_COMMAND, LITEXML_DIFFNODE_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND } from "./command/symbols.js";
|
|
5
4
|
import { LitexmlPlugin, LitexmlPluginOptions } from "./plugin/index.js";
|
|
6
5
|
import { ReactLiteXmlPlugin } from "./react/index.js";
|
|
7
6
|
import { useHasDiffNode } from "./react/hooks/useHasDiffNode.js";
|
|
@@ -5,7 +5,7 @@ import { registerLiteXMLDiffCommand } from "../command/diffCommand.js";
|
|
|
5
5
|
import { ILitexmlService, LitexmlService } from "../service/litexml-service.js";
|
|
6
6
|
import LitexmlDataSource from "../data-source/litexml-data-source.js";
|
|
7
7
|
import { IMarkdownShortCutService } from "../../markdown/service/shortcut.js";
|
|
8
|
-
import { $nodesOfType } from "lexical";
|
|
8
|
+
import { $nodesOfType, HISTORIC_TAG } from "lexical";
|
|
9
9
|
//#region src/plugins/litexml/plugin/index.ts
|
|
10
10
|
init_plugin();
|
|
11
11
|
/**
|
|
@@ -42,8 +42,14 @@ const LitexmlPlugin = class extends KernelPlugin {
|
|
|
42
42
|
this.register(editor.registerNodeTransform(DiffNode, (node) => {
|
|
43
43
|
if (node.diffType === "modify" && node.getChildrenSize() === 1) node.setDiffType("remove");
|
|
44
44
|
}));
|
|
45
|
-
this.register(editor.registerUpdateListener(({ editorState, prevEditorState }) => {
|
|
45
|
+
this.register(editor.registerUpdateListener(({ editorState, prevEditorState, tags }) => {
|
|
46
46
|
if (editorState === prevEditorState) return;
|
|
47
|
+
if (tags.has(HISTORIC_TAG)) return;
|
|
48
|
+
let shouldNormalize = false;
|
|
49
|
+
editorState.read(() => {
|
|
50
|
+
shouldNormalize = $nodesOfType(DiffNode).some((node) => node.diffType === "modify" && node.getChildrenSize() === 1);
|
|
51
|
+
});
|
|
52
|
+
if (!shouldNormalize) return;
|
|
47
53
|
editor.update(() => {
|
|
48
54
|
const diffNodes = $nodesOfType(DiffNode);
|
|
49
55
|
for (const node of diffNodes) if (node.diffType === "modify" && node.getChildrenSize() === 1) node.setDiffType("remove");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import LexicalPortalContainer from "../../../../editor-kernel/react/PortalContainer.js";
|
|
2
|
-
import { LITEXML_DIFFNODE_COMMAND } from "../../command/
|
|
2
|
+
import { LITEXML_DIFFNODE_COMMAND } from "../../command/symbols.js";
|
|
3
3
|
import { useTranslation } from "../../../../editor-kernel/react/useTranslation.js";
|
|
4
4
|
import { styles } from "./style.js";
|
|
5
5
|
import { ActionIcon, Block } from "@lobehub/ui";
|
|
@@ -26,7 +26,7 @@ const SlashPlugin = class extends KernelPlugin {
|
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
triggerClose() {
|
|
29
|
-
this.config?.triggerClose?.();
|
|
29
|
+
if (this.currentSlashTrigger !== null || this.manualOpen || !this.suppressOpen) this.config?.triggerClose?.();
|
|
30
30
|
this.currentSlashTrigger = null;
|
|
31
31
|
this.currentSlashTriggerIndex = -1;
|
|
32
32
|
this.manualOpen = false;
|
|
@@ -26,10 +26,10 @@ const ReactSlashPlugin = ({ children, anchorClassName, getPopupContainer, placem
|
|
|
26
26
|
const cancelRef = useRef({ cancel: noop });
|
|
27
27
|
const triggerMapRef = useRef(/* @__PURE__ */ new Map());
|
|
28
28
|
const close = useCallback(() => {
|
|
29
|
-
setIsOpen(false);
|
|
30
|
-
setOptions([]);
|
|
31
|
-
setResolution(null);
|
|
32
|
-
setActiveKey(null);
|
|
29
|
+
setIsOpen((open) => open ? false : open);
|
|
30
|
+
setOptions((currentOptions) => currentOptions.length > 0 ? [] : currentOptions);
|
|
31
|
+
setResolution((currentResolution) => currentResolution ? null : currentResolution);
|
|
32
|
+
setActiveKey((currentActiveKey) => currentActiveKey ? null : currentActiveKey);
|
|
33
33
|
}, []);
|
|
34
34
|
useEffect(() => close, [close]);
|
|
35
35
|
const handleActiveKeyChange = useCallback((key) => {
|
|
@@ -9,9 +9,21 @@ declare const INSERT_TABLE_COMMAND: _$lexical.LexicalCommand<{
|
|
|
9
9
|
rows: string;
|
|
10
10
|
}>;
|
|
11
11
|
declare const SELECT_TABLE_COMMAND: _$lexical.LexicalCommand<{
|
|
12
|
+
anchorIndex?: number;
|
|
12
13
|
columnIndex?: number;
|
|
14
|
+
extend?: boolean;
|
|
13
15
|
rowIndex?: number;
|
|
14
16
|
table: string;
|
|
15
17
|
}>;
|
|
18
|
+
declare const INSERT_TABLE_COLUMN_COMMAND: _$lexical.LexicalCommand<{
|
|
19
|
+
columnIndex: number;
|
|
20
|
+
insertAfter?: boolean;
|
|
21
|
+
table: string;
|
|
22
|
+
}>;
|
|
23
|
+
declare const INSERT_TABLE_ROW_COMMAND: _$lexical.LexicalCommand<{
|
|
24
|
+
insertAfter?: boolean;
|
|
25
|
+
rowIndex: number;
|
|
26
|
+
table: string;
|
|
27
|
+
}>;
|
|
16
28
|
//#endregion
|
|
17
|
-
export { INSERT_TABLE_COMMAND, SELECT_TABLE_COMMAND };
|
|
29
|
+
export { INSERT_TABLE_COLUMN_COMMAND, INSERT_TABLE_COMMAND, INSERT_TABLE_ROW_COMMAND, SELECT_TABLE_COMMAND };
|