@lobehub/editor 1.31.2 → 1.33.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/const/hotkey.js +1 -1
- package/es/editor-kernel/kernel.d.ts +4 -4
- package/es/editor-kernel/kernel.js +6 -2
- package/es/editor-kernel/react/PortalContainer.d.ts +11 -0
- package/es/editor-kernel/react/PortalContainer.js +32 -0
- package/es/editor-kernel/react/index.d.ts +1 -0
- package/es/editor-kernel/react/index.js +1 -0
- package/es/editor-kernel/react/useDecorators.js +3 -2
- package/es/editor-kernel/utils.d.ts +7 -1
- package/es/editor-kernel/utils.js +34 -0
- package/es/index.d.ts +1 -0
- package/es/index.js +1 -0
- package/es/plugins/common/plugin/register.js +37 -2
- package/es/plugins/file/node/FileNode.js +12 -2
- package/es/plugins/hr/node/HorizontalRuleNode.js +12 -2
- package/es/plugins/image/node/block-image-node.js +1 -1
- package/es/plugins/image/plugin/index.js +33 -3
- package/es/plugins/image/react/components/Image.js +1 -1
- package/es/plugins/inode/index.d.ts +3 -0
- package/es/plugins/inode/index.js +3 -0
- package/es/plugins/inode/plugin/index.d.ts +16 -0
- package/es/plugins/inode/plugin/index.js +49 -0
- package/es/plugins/inode/react/index.d.ts +3 -0
- package/es/plugins/inode/react/index.js +22 -0
- package/es/plugins/inode/service/index.d.ts +25 -0
- package/es/plugins/inode/service/index.js +49 -0
- package/es/plugins/link/node/LinkNode.js +2 -0
- package/es/plugins/link-highlight/node/link-highlight.js +1 -0
- package/es/plugins/litexml/command/diffCommand.d.ts +10 -0
- package/es/plugins/litexml/command/diffCommand.js +47 -0
- package/es/plugins/litexml/command/index.d.ts +19 -0
- package/es/plugins/litexml/command/index.js +286 -45
- package/es/plugins/litexml/data-source/litexml-data-source.d.ts +3 -1
- package/es/plugins/litexml/data-source/litexml-data-source.js +10 -3
- package/es/plugins/litexml/index.d.ts +1 -1
- package/es/plugins/litexml/index.js +1 -1
- package/es/plugins/litexml/node/DiffNode.d.ts +26 -0
- package/es/plugins/litexml/node/DiffNode.js +164 -0
- package/es/plugins/litexml/plugin/index.d.ts +4 -0
- package/es/plugins/litexml/plugin/index.js +23 -4
- package/es/plugins/litexml/react/DiffNodeToolbar.d.ts +10 -0
- package/es/plugins/litexml/react/DiffNodeToolbar.js +47 -0
- package/es/plugins/litexml/react/index.js +16 -1
- package/es/plugins/litexml/react/style.d.ts +1 -0
- package/es/plugins/litexml/react/style.js +8 -0
- package/es/plugins/litexml/utils/index.d.ts +3 -0
- package/es/plugins/litexml/utils/index.js +47 -0
- package/es/plugins/markdown/data-source/markdown-data-source.d.ts +3 -1
- package/es/plugins/markdown/data-source/markdown-data-source.js +5 -1
- package/es/plugins/markdown/plugin/index.js +3 -2
- package/es/plugins/markdown/react/index.js +2 -0
- package/es/plugins/math/node/index.js +24 -4
- package/es/plugins/mention/node/MentionNode.js +12 -2
- package/es/types/kernel.d.ts +8 -3
- package/package.json +2 -2
|
@@ -62,6 +62,7 @@ export var LinkNode = /*#__PURE__*/function (_ElementNode) {
|
|
|
62
62
|
key: "createDOM",
|
|
63
63
|
value: function createDOM(config, editor) {
|
|
64
64
|
var _this2 = this;
|
|
65
|
+
console.info('config', config);
|
|
65
66
|
var element = document.createElement('a');
|
|
66
67
|
this.updateLinkDOM(null, element, config);
|
|
67
68
|
addClassNamesToElement(element, config.theme.link);
|
|
@@ -356,6 +357,7 @@ export var AutoLinkNode = /*#__PURE__*/function (_LinkNode) {
|
|
|
356
357
|
}, {
|
|
357
358
|
key: "createDOM",
|
|
358
359
|
value: function createDOM(config, editor) {
|
|
360
|
+
console.info('config', config);
|
|
359
361
|
if (this.__isUnlinked) {
|
|
360
362
|
return document.createElement('span');
|
|
361
363
|
} else {
|
|
@@ -24,6 +24,7 @@ export var LinkHighlightNode = /*#__PURE__*/function (_ElementNode) {
|
|
|
24
24
|
_createClass(LinkHighlightNode, [{
|
|
25
25
|
key: "createDOM",
|
|
26
26
|
value: function createDOM(config) {
|
|
27
|
+
console.info('config', config);
|
|
27
28
|
var element = document.createElement('a');
|
|
28
29
|
|
|
29
30
|
// Set link attributes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LexicalEditor } from 'lexical';
|
|
2
|
+
export declare enum DiffAction {
|
|
3
|
+
Reject = 0,
|
|
4
|
+
Accept = 1
|
|
5
|
+
}
|
|
6
|
+
export declare const LITEXML_DIFFNODE_COMMAND: import("lexical").LexicalCommand<{
|
|
7
|
+
action: DiffAction;
|
|
8
|
+
nodeKey: string;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function registerLiteXMLDiffCommand(editor: LexicalEditor): () => void;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { mergeRegister } from '@lexical/utils';
|
|
2
|
+
import { $getNodeByKey, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
|
|
3
|
+
export var DiffAction = /*#__PURE__*/function (DiffAction) {
|
|
4
|
+
DiffAction[DiffAction["Reject"] = 0] = "Reject";
|
|
5
|
+
DiffAction[DiffAction["Accept"] = 1] = "Accept";
|
|
6
|
+
return DiffAction;
|
|
7
|
+
}({});
|
|
8
|
+
export var LITEXML_DIFFNODE_COMMAND = createCommand('LITEXML_DIFFNODE_COMMAND');
|
|
9
|
+
export function registerLiteXMLDiffCommand(editor) {
|
|
10
|
+
return mergeRegister(editor.registerCommand(LITEXML_DIFFNODE_COMMAND, function (payload) {
|
|
11
|
+
var action = payload.action,
|
|
12
|
+
nodeKey = payload.nodeKey;
|
|
13
|
+
var node = editor.read(function () {
|
|
14
|
+
return $getNodeByKey(nodeKey);
|
|
15
|
+
});
|
|
16
|
+
if (!node) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
editor.update(function () {
|
|
20
|
+
if (node.diffType === 'modify') {
|
|
21
|
+
var children = node.getChildren();
|
|
22
|
+
if (action === DiffAction.Accept) {
|
|
23
|
+
node.replace(children[1], false).selectEnd();
|
|
24
|
+
} else if (action === DiffAction.Reject) {
|
|
25
|
+
node.replace(children[0], false).selectEnd();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (node.diffType === 'remove') {
|
|
29
|
+
if (action === DiffAction.Accept) {
|
|
30
|
+
node.remove();
|
|
31
|
+
} else if (action === DiffAction.Reject) {
|
|
32
|
+
var _children = node.getChildren();
|
|
33
|
+
node.replace(_children[0], false).selectEnd();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (node.diffType === 'add') {
|
|
37
|
+
if (action === DiffAction.Accept) {
|
|
38
|
+
var _children2 = node.getChildren();
|
|
39
|
+
node.replace(_children2[0], false).selectEnd();
|
|
40
|
+
} else if (action === DiffAction.Reject) {
|
|
41
|
+
node.remove();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
return false;
|
|
46
|
+
}, COMMAND_PRIORITY_EDITOR));
|
|
47
|
+
}
|
|
@@ -1,16 +1,35 @@
|
|
|
1
1
|
import { LexicalEditor } from 'lexical';
|
|
2
2
|
import type LitexmlDataSource from '../data-source/litexml-data-source';
|
|
3
|
+
export declare const LITEXML_MODIFY_COMMAND: import("lexical").LexicalCommand<({
|
|
4
|
+
action: 'insert';
|
|
5
|
+
beforeId: string;
|
|
6
|
+
litexml: string;
|
|
7
|
+
} | {
|
|
8
|
+
action: 'insert';
|
|
9
|
+
afterId: string;
|
|
10
|
+
litexml: string;
|
|
11
|
+
} | {
|
|
12
|
+
action: 'remove';
|
|
13
|
+
id: string;
|
|
14
|
+
} | {
|
|
15
|
+
action: 'modify';
|
|
16
|
+
litexml: string | string[];
|
|
17
|
+
})[]>;
|
|
3
18
|
export declare const LITEXML_APPLY_COMMAND: import("lexical").LexicalCommand<{
|
|
19
|
+
delay?: boolean | undefined;
|
|
4
20
|
litexml: string | string[];
|
|
5
21
|
}>;
|
|
6
22
|
export declare const LITEXML_REMOVE_COMMAND: import("lexical").LexicalCommand<{
|
|
23
|
+
delay?: boolean | undefined;
|
|
7
24
|
id: string;
|
|
8
25
|
}>;
|
|
9
26
|
export declare const LITEXML_INSERT_COMMAND: import("lexical").LexicalCommand<{
|
|
10
27
|
beforeId: string;
|
|
28
|
+
delay?: boolean | undefined;
|
|
11
29
|
litexml: string;
|
|
12
30
|
} | {
|
|
13
31
|
afterId: string;
|
|
32
|
+
delay?: boolean | undefined;
|
|
14
33
|
litexml: string;
|
|
15
34
|
}>;
|
|
16
35
|
export declare function registerLiteXMLCommand(editor: LexicalEditor, dataSource: LitexmlDataSource): () => void;
|
|
@@ -1,25 +1,194 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
6
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
8
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
9
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
10
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
1
11
|
import { mergeRegister } from '@lexical/utils';
|
|
2
|
-
import { $getNodeByKey, $insertNodes,
|
|
12
|
+
import { $getNodeByKey, $insertNodes, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
|
|
3
13
|
import { $closest } from "../../../editor-kernel";
|
|
4
|
-
import { $
|
|
14
|
+
import { $createDiffNode } from "../node/DiffNode";
|
|
15
|
+
import { $cloneNode, $parseSerializedNodeImpl, charToId } from "../utils";
|
|
16
|
+
|
|
17
|
+
// Helpers to reduce duplication and improve readability
|
|
18
|
+
function toArrayXml(litexml) {
|
|
19
|
+
return Array.isArray(litexml) ? litexml : [litexml];
|
|
20
|
+
}
|
|
21
|
+
function tryParseChild(child, editor) {
|
|
22
|
+
try {
|
|
23
|
+
var oldNode = $getNodeByKey(child.id);
|
|
24
|
+
var newNode = $parseSerializedNodeImpl(child, editor);
|
|
25
|
+
return {
|
|
26
|
+
newNode: newNode,
|
|
27
|
+
oldNode: oldNode
|
|
28
|
+
};
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error('Error parsing child node:', error);
|
|
31
|
+
return {
|
|
32
|
+
newNode: null,
|
|
33
|
+
oldNode: null
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function handleReplaceForApplyDelay(oldNode, newNode, modifyBlockNodes, diffNodeMap, editor) {
|
|
38
|
+
var oldBlock = $closest(oldNode, function (node) {
|
|
39
|
+
return node.isInline() === false;
|
|
40
|
+
});
|
|
41
|
+
if (!oldBlock) {
|
|
42
|
+
throw new Error('Old block node not found for diffing.');
|
|
43
|
+
}
|
|
44
|
+
if (oldNode === oldBlock) {
|
|
45
|
+
var diffNode = $createDiffNode('modify');
|
|
46
|
+
diffNode.append($cloneNode(oldBlock, editor), newNode);
|
|
47
|
+
oldNode.replace(diffNode, false);
|
|
48
|
+
} else {
|
|
49
|
+
if (!modifyBlockNodes.has(oldBlock.getKey())) {
|
|
50
|
+
modifyBlockNodes.add(oldBlock.getKey());
|
|
51
|
+
var _diffNode = $createDiffNode('modify');
|
|
52
|
+
_diffNode.append($cloneNode(oldBlock, editor));
|
|
53
|
+
diffNodeMap.set(oldBlock.getKey(), _diffNode);
|
|
54
|
+
}
|
|
55
|
+
oldNode.replace(newNode, false);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function finalizeModifyBlocks(modifyBlockNodes, diffNodeMap, editor) {
|
|
59
|
+
var _iterator = _createForOfIteratorHelper(modifyBlockNodes),
|
|
60
|
+
_step;
|
|
61
|
+
try {
|
|
62
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
63
|
+
var blockNodeKey = _step.value;
|
|
64
|
+
var blockNode = $getNodeByKey(blockNodeKey);
|
|
65
|
+
var diffNode = diffNodeMap.get(blockNodeKey);
|
|
66
|
+
if (diffNode && blockNode) {
|
|
67
|
+
diffNode.append($cloneNode(blockNode, editor));
|
|
68
|
+
blockNode.replace(diffNode, false);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
} catch (err) {
|
|
72
|
+
_iterator.e(err);
|
|
73
|
+
} finally {
|
|
74
|
+
_iterator.f();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Wrap a block-level change with a `modify` diff: clone the old block, run the
|
|
80
|
+
* provided changeFn (which should mutate nodes inside the block), then clone
|
|
81
|
+
* the new block and replace it with the diff node. Useful for inline->block
|
|
82
|
+
* transitions where we want to show a modify diff.
|
|
83
|
+
*/
|
|
84
|
+
function wrapBlockModify(oldBlock, editor, changeFn) {
|
|
85
|
+
var diffNode = $createDiffNode('modify');
|
|
86
|
+
diffNode.append($cloneNode(oldBlock, editor));
|
|
87
|
+
changeFn();
|
|
88
|
+
var newBlock = $getNodeByKey(oldBlock.getKey());
|
|
89
|
+
if (!newBlock) {
|
|
90
|
+
throw new Error('New block node not found for modify wrapper.');
|
|
91
|
+
}
|
|
92
|
+
diffNode.append($cloneNode(newBlock, editor));
|
|
93
|
+
newBlock.replace(diffNode, false);
|
|
94
|
+
}
|
|
95
|
+
export var LITEXML_MODIFY_COMMAND = createCommand('LITEXML_MODIFY_COMMAND');
|
|
5
96
|
export var LITEXML_APPLY_COMMAND = createCommand('LITEXML_APPLY_COMMAND');
|
|
6
97
|
export var LITEXML_REMOVE_COMMAND = createCommand('LITEXML_REMOVE_COMMAND');
|
|
7
98
|
export var LITEXML_INSERT_COMMAND = createCommand('LITEXML_INSERT_COMMAND');
|
|
8
99
|
export function registerLiteXMLCommand(editor, dataSource) {
|
|
9
|
-
return mergeRegister(editor.registerCommand(
|
|
10
|
-
|
|
11
|
-
|
|
100
|
+
return mergeRegister(editor.registerCommand(LITEXML_MODIFY_COMMAND, function (payload) {
|
|
101
|
+
payload.forEach(function (item) {
|
|
102
|
+
var action = item.action;
|
|
103
|
+
switch (action) {
|
|
104
|
+
case 'modify':
|
|
105
|
+
{
|
|
106
|
+
var litexml = item.litexml;
|
|
107
|
+
var arrayXml = toArrayXml(litexml);
|
|
108
|
+
// handle modfy action
|
|
109
|
+
handleModify(editor, dataSource, arrayXml, true);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case 'remove':
|
|
113
|
+
{
|
|
114
|
+
var id = item.id;
|
|
115
|
+
var key = charToId(id);
|
|
116
|
+
// handle remove action
|
|
117
|
+
handleRemove(editor, key, true);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case 'insert':
|
|
121
|
+
{
|
|
122
|
+
handleInsert(editor, _objectSpread(_objectSpread({}, item), {}, {
|
|
123
|
+
delay: true
|
|
124
|
+
}), dataSource);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
default:
|
|
128
|
+
{
|
|
129
|
+
console.warn("Unknown action type: ".concat(action));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
return false;
|
|
134
|
+
}, COMMAND_PRIORITY_EDITOR), editor.registerCommand(LITEXML_APPLY_COMMAND, function (payload) {
|
|
135
|
+
var litexml = payload.litexml,
|
|
136
|
+
delay = payload.delay;
|
|
137
|
+
var arrayXml = toArrayXml(litexml);
|
|
138
|
+
handleModify(editor, dataSource, arrayXml, delay);
|
|
139
|
+
return false;
|
|
140
|
+
}, COMMAND_PRIORITY_EDITOR // Priority
|
|
141
|
+
), editor.registerCommand(LITEXML_REMOVE_COMMAND, function (payload) {
|
|
142
|
+
var id = payload.id,
|
|
143
|
+
delay = payload.delay;
|
|
144
|
+
var key = charToId(id);
|
|
145
|
+
handleRemove(editor, key, delay);
|
|
146
|
+
return false;
|
|
147
|
+
}, COMMAND_PRIORITY_EDITOR // Priority
|
|
148
|
+
), editor.registerCommand(LITEXML_INSERT_COMMAND, function (payload) {
|
|
149
|
+
handleInsert(editor, payload, dataSource);
|
|
150
|
+
return false;
|
|
151
|
+
}, COMMAND_PRIORITY_EDITOR // Priority
|
|
152
|
+
));
|
|
153
|
+
}
|
|
154
|
+
function handleModify(editor, dataSource, arrayXml, delay) {
|
|
155
|
+
if (delay) {
|
|
12
156
|
editor.update(function () {
|
|
157
|
+
var modifyBlockNodes = new Set();
|
|
158
|
+
var diffNodeMap = new Map();
|
|
13
159
|
arrayXml.forEach(function (xml) {
|
|
14
160
|
var inode = dataSource.readLiteXMLToInode(xml);
|
|
15
|
-
var prevNode = null;
|
|
16
161
|
inode.root.children.forEach(function (child) {
|
|
17
162
|
try {
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
163
|
+
var _tryParseChild = tryParseChild(child, editor),
|
|
164
|
+
oldNode = _tryParseChild.oldNode,
|
|
165
|
+
newNode = _tryParseChild.newNode;
|
|
166
|
+
if (oldNode && newNode) {
|
|
167
|
+
handleReplaceForApplyDelay(oldNode, newNode, modifyBlockNodes, diffNodeMap, editor);
|
|
22
168
|
} else {
|
|
169
|
+
console.warn("Node with key ".concat(child.id, " not found for diffing."));
|
|
170
|
+
}
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.error('Error replacing node:', error);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
// replace modified block nodes with diff nodes
|
|
177
|
+
finalizeModifyBlocks(modifyBlockNodes, diffNodeMap, editor);
|
|
178
|
+
});
|
|
179
|
+
} else {
|
|
180
|
+
editor.update(function () {
|
|
181
|
+
arrayXml.forEach(function (xml) {
|
|
182
|
+
var inode = dataSource.readLiteXMLToInode(xml);
|
|
183
|
+
var prevNode = null;
|
|
184
|
+
inode.root.children.forEach(function (child) {
|
|
185
|
+
try {
|
|
186
|
+
var _tryParseChild2 = tryParseChild(child, editor),
|
|
187
|
+
oldNode = _tryParseChild2.oldNode,
|
|
188
|
+
newNode = _tryParseChild2.newNode;
|
|
189
|
+
if (oldNode && newNode) {
|
|
190
|
+
prevNode = oldNode.replace(newNode, false);
|
|
191
|
+
} else if (newNode) {
|
|
23
192
|
if (prevNode) {
|
|
24
193
|
if (!newNode.isInline()) {
|
|
25
194
|
var prevBlock = $closest(prevNode, function (node) {
|
|
@@ -36,7 +205,6 @@ export function registerLiteXMLCommand(editor, dataSource) {
|
|
|
36
205
|
}
|
|
37
206
|
} else {
|
|
38
207
|
$insertNodes([newNode]);
|
|
39
|
-
prevNode = newNode;
|
|
40
208
|
}
|
|
41
209
|
}
|
|
42
210
|
} catch (error) {
|
|
@@ -45,36 +213,56 @@ export function registerLiteXMLCommand(editor, dataSource) {
|
|
|
45
213
|
});
|
|
46
214
|
});
|
|
47
215
|
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function handleRemove(editor, key, delay) {
|
|
219
|
+
editor.update(function () {
|
|
220
|
+
var node = $getNodeByKey(key);
|
|
221
|
+
if (!node) return;
|
|
222
|
+
if (!delay) {
|
|
223
|
+
node.remove();
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// delay removal: show a diff
|
|
228
|
+
if (node.isInline() === false) {
|
|
229
|
+
var diffNode = $createDiffNode('remove');
|
|
230
|
+
diffNode.append($cloneNode(node, editor));
|
|
231
|
+
node.replace(diffNode, false);
|
|
232
|
+
} else {
|
|
233
|
+
var oldBlock = $closest(node, function (node) {
|
|
234
|
+
return node.isInline() === false;
|
|
235
|
+
});
|
|
236
|
+
if (!oldBlock) {
|
|
237
|
+
throw new Error('Old block node not found for removal.');
|
|
238
|
+
}
|
|
239
|
+
// wrap changes inside a modify diff
|
|
240
|
+
wrapBlockModify(oldBlock, editor, function () {
|
|
55
241
|
node.remove();
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
function handleInsert(editor, payload, dataSource) {
|
|
247
|
+
var litexml = payload.litexml,
|
|
248
|
+
delay = payload.delay;
|
|
249
|
+
var isBefore = ('beforeId' in payload);
|
|
250
|
+
var inode = dataSource.readLiteXMLToInode(litexml);
|
|
251
|
+
editor.update(function () {
|
|
252
|
+
try {
|
|
253
|
+
var referenceNode = null;
|
|
254
|
+
if (isBefore) {
|
|
255
|
+
referenceNode = $getNodeByKey(charToId(payload.beforeId));
|
|
256
|
+
} else {
|
|
257
|
+
referenceNode = $getNodeByKey(charToId(payload.afterId));
|
|
56
258
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
editor.update(function () {
|
|
65
|
-
try {
|
|
66
|
-
var referenceNode = null;
|
|
67
|
-
if (isBefore) {
|
|
68
|
-
referenceNode = $getNodeByKey(payload.beforeId);
|
|
69
|
-
} else {
|
|
70
|
-
referenceNode = $getNodeByKey(payload.afterId);
|
|
71
|
-
}
|
|
72
|
-
if (!referenceNode) {
|
|
73
|
-
throw new Error('Reference node not found for insertion.');
|
|
74
|
-
}
|
|
75
|
-
var newNodes = inode.root.children.map(function (child) {
|
|
76
|
-
return $parseSerializedNodeImpl(child, editor);
|
|
77
|
-
});
|
|
259
|
+
if (!referenceNode) {
|
|
260
|
+
throw new Error('Reference node not found for insertion.');
|
|
261
|
+
}
|
|
262
|
+
var newNodes = inode.root.children.map(function (child) {
|
|
263
|
+
return $parseSerializedNodeImpl(child, editor);
|
|
264
|
+
});
|
|
265
|
+
if (!delay) {
|
|
78
266
|
if (isBefore) {
|
|
79
267
|
referenceNode = referenceNode.insertBefore(newNodes);
|
|
80
268
|
} else {
|
|
@@ -84,11 +272,64 @@ export function registerLiteXMLCommand(editor, dataSource) {
|
|
|
84
272
|
}
|
|
85
273
|
});
|
|
86
274
|
}
|
|
87
|
-
|
|
88
|
-
console.error('Error inserting node:', error);
|
|
275
|
+
return;
|
|
89
276
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
277
|
+
|
|
278
|
+
// delay insertion: show diffs or wrap block modifications
|
|
279
|
+
if (isBefore) {
|
|
280
|
+
if (referenceNode.isInline() === false) {
|
|
281
|
+
var diffNodes = newNodes.map(function (node) {
|
|
282
|
+
var diffNode = $createDiffNode('add');
|
|
283
|
+
diffNode.append(node);
|
|
284
|
+
return diffNode;
|
|
285
|
+
});
|
|
286
|
+
diffNodes.forEach(function (diffNode) {
|
|
287
|
+
if (referenceNode) {
|
|
288
|
+
referenceNode = referenceNode.insertBefore(diffNode);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
} else {
|
|
292
|
+
var refBlock = $closest(referenceNode, function (node) {
|
|
293
|
+
return node.isInline() === false;
|
|
294
|
+
});
|
|
295
|
+
if (!refBlock) {
|
|
296
|
+
throw new Error('Reference block node not found for insertion.');
|
|
297
|
+
}
|
|
298
|
+
wrapBlockModify(refBlock, editor, function () {
|
|
299
|
+
newNodes.forEach(function (node) {
|
|
300
|
+
if (referenceNode) {
|
|
301
|
+
referenceNode = referenceNode.insertBefore(node);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
307
|
+
if (referenceNode.isInline() === false) {
|
|
308
|
+
newNodes.forEach(function (node) {
|
|
309
|
+
if (referenceNode) {
|
|
310
|
+
var diffNode = $createDiffNode('add');
|
|
311
|
+
diffNode.append(node);
|
|
312
|
+
referenceNode = referenceNode.insertAfter(diffNode);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
} else {
|
|
316
|
+
var _refBlock = $closest(referenceNode, function (node) {
|
|
317
|
+
return node.isInline() === false;
|
|
318
|
+
});
|
|
319
|
+
if (!_refBlock) {
|
|
320
|
+
throw new Error('Reference block node not found for insertion.');
|
|
321
|
+
}
|
|
322
|
+
wrapBlockModify(_refBlock, editor, function () {
|
|
323
|
+
newNodes.forEach(function (node) {
|
|
324
|
+
if (referenceNode) {
|
|
325
|
+
referenceNode = referenceNode.insertAfter(node);
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
} catch (error) {
|
|
332
|
+
console.error('Error inserting node:', error);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
94
335
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { LexicalEditor } from 'lexical';
|
|
2
2
|
import { DataSource } from "../../../editor-kernel";
|
|
3
3
|
import type { IWriteOptions } from "../../../editor-kernel/data-source";
|
|
4
|
+
import { IServiceID } from "../../../types";
|
|
4
5
|
import type { ILitexmlService } from '../service/litexml-service';
|
|
5
6
|
/**
|
|
6
7
|
* LitexmlDataSource - Handles conversion between Lexical editor state and XML format
|
|
@@ -8,9 +9,10 @@ import type { ILitexmlService } from '../service/litexml-service';
|
|
|
8
9
|
*/
|
|
9
10
|
export default class LitexmlDataSource extends DataSource {
|
|
10
11
|
protected dataType: string;
|
|
12
|
+
protected getService?: (<T>(serviceId: IServiceID<T>) => T | null) | undefined;
|
|
11
13
|
private litexmlService;
|
|
12
14
|
private ctx;
|
|
13
|
-
constructor(dataType?: string, service?: ILitexmlService);
|
|
15
|
+
constructor(dataType?: string, getService?: (<T>(serviceId: IServiceID<T>) => T | null) | undefined, service?: ILitexmlService);
|
|
14
16
|
readLiteXMLToInode(litexml: string): any;
|
|
15
17
|
/**
|
|
16
18
|
* Parse XML string and set it to the editor
|
|
@@ -30,8 +30,10 @@ import { DOMParser } from '@xmldom/xmldom';
|
|
|
30
30
|
import { $getRoot, $getSelection, $isElementNode, $isRangeSelection } from 'lexical';
|
|
31
31
|
import { DataSource } from "../../../editor-kernel";
|
|
32
32
|
import { INodeHelper } from "../../../editor-kernel/inode/helper";
|
|
33
|
+
import { INodeService } from "../../inode";
|
|
33
34
|
import { createDebugLogger } from "../../../utils/debug";
|
|
34
35
|
import { LitexmlService } from "../service/litexml-service";
|
|
36
|
+
import { charToId, idToChar } from "../utils";
|
|
35
37
|
var logger = createDebugLogger('plugin', 'litexml');
|
|
36
38
|
var IXmlWriterContext = /*#__PURE__*/function () {
|
|
37
39
|
function IXmlWriterContext() {
|
|
@@ -60,23 +62,27 @@ var LitexmlDataSource = /*#__PURE__*/function (_DataSource) {
|
|
|
60
62
|
function LitexmlDataSource() {
|
|
61
63
|
var _this;
|
|
62
64
|
var dataType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'litexml';
|
|
63
|
-
var
|
|
65
|
+
var getService = arguments.length > 1 ? arguments[1] : undefined;
|
|
66
|
+
var service = arguments.length > 2 ? arguments[2] : undefined;
|
|
64
67
|
_classCallCheck(this, LitexmlDataSource);
|
|
65
68
|
_this = _super.call(this, dataType);
|
|
66
69
|
_defineProperty(_assertThisInitialized(_this), "litexmlService", void 0);
|
|
67
70
|
_defineProperty(_assertThisInitialized(_this), "ctx", new IXmlWriterContext());
|
|
68
71
|
_this.dataType = dataType;
|
|
72
|
+
_this.getService = getService;
|
|
69
73
|
_this.litexmlService = service || new LitexmlService();
|
|
70
74
|
return _this;
|
|
71
75
|
}
|
|
72
76
|
_createClass(LitexmlDataSource, [{
|
|
73
77
|
key: "readLiteXMLToInode",
|
|
74
78
|
value: function readLiteXMLToInode(litexml) {
|
|
79
|
+
var _this$getService;
|
|
75
80
|
if (typeof litexml !== 'string') {
|
|
76
81
|
throw new Error('Invalid data type. Expected string, got ' + _typeof(litexml));
|
|
77
82
|
}
|
|
78
83
|
var xml = this.parseXMLString(litexml);
|
|
79
84
|
var inode = this.xmlToLexical(xml);
|
|
85
|
+
(_this$getService = this.getService) === null || _this$getService === void 0 || (_this$getService = _this$getService.call(this, INodeService)) === null || _this$getService === void 0 || _this$getService.processNodeTree(inode);
|
|
80
86
|
logger.debug('Parsed XML to Lexical State:', inode);
|
|
81
87
|
return inode;
|
|
82
88
|
}
|
|
@@ -214,7 +220,8 @@ var LitexmlDataSource = /*#__PURE__*/function (_DataSource) {
|
|
|
214
220
|
if (Array.isArray(result)) {
|
|
215
221
|
INodeHelper.appendChild.apply(INodeHelper, [parentNode].concat(_toConsumableArray(result)));
|
|
216
222
|
} else if (result) {
|
|
217
|
-
|
|
223
|
+
var attrId = xmlElement.getAttribute('id');
|
|
224
|
+
result.id = attrId ? charToId(attrId) : undefined;
|
|
218
225
|
INodeHelper.appendChild(parentNode, result);
|
|
219
226
|
}
|
|
220
227
|
return; // Custom reader handled it
|
|
@@ -364,7 +371,7 @@ var LitexmlDataSource = /*#__PURE__*/function (_DataSource) {
|
|
|
364
371
|
var handled = writer(node, this.ctx, indent);
|
|
365
372
|
if (handled) {
|
|
366
373
|
var attrs = this.buildXMLAttributes(_objectSpread({
|
|
367
|
-
id: node.getKey()
|
|
374
|
+
id: idToChar(node.getKey())
|
|
368
375
|
}, handled.attributes));
|
|
369
376
|
var openTag = "".concat(indentStr, "<").concat(handled.tagName).concat(attrs, ">");
|
|
370
377
|
var closeTag = "</".concat(handled.tagName, ">");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_REMOVE_COMMAND } from './command';
|
|
1
|
+
export { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND, } from './command';
|
|
2
2
|
export { default as LitexmlDataSource } from './data-source/litexml-data-source';
|
|
3
3
|
export type { LitexmlPluginOptions } from './plugin';
|
|
4
4
|
export { LitexmlPlugin } from './plugin';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_REMOVE_COMMAND } from "./command";
|
|
1
|
+
export { LITEXML_APPLY_COMMAND, LITEXML_INSERT_COMMAND, LITEXML_MODIFY_COMMAND, LITEXML_REMOVE_COMMAND } from "./command";
|
|
2
2
|
export { default as LitexmlDataSource } from "./data-source/litexml-data-source";
|
|
3
3
|
export { LitexmlPlugin } from "./plugin";
|
|
4
4
|
export { ReactLiteXmlPlugin } from "./react";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DOMExportOutput, EditorConfig, ElementDOMSlot, LexicalEditor, LexicalUpdateJSON, SerializedElementNode, Spread } from 'lexical';
|
|
2
|
+
import { CardLikeElementNode } from "../../common/node/cursor";
|
|
3
|
+
export type SerializedDiffNode = Spread<{
|
|
4
|
+
diffType: 'add' | 'remove' | 'modify' | 'unchanged';
|
|
5
|
+
}, SerializedElementNode>;
|
|
6
|
+
/** DiffNode - contains two block children: original and modified */
|
|
7
|
+
export declare class DiffNode extends CardLikeElementNode {
|
|
8
|
+
static getType(): string;
|
|
9
|
+
static clone(node: DiffNode): DiffNode;
|
|
10
|
+
static importJSON(serializedNode: SerializedDiffNode): DiffNode;
|
|
11
|
+
static importDOM(): null;
|
|
12
|
+
private __diffType;
|
|
13
|
+
constructor(type: 'add' | 'remove' | 'modify' | 'unchanged', key?: string);
|
|
14
|
+
get diffType(): 'add' | 'remove' | 'modify' | 'unchanged';
|
|
15
|
+
setDiffType(type: 'add' | 'remove' | 'modify' | 'unchanged'): this;
|
|
16
|
+
updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedDiffNode>): this;
|
|
17
|
+
exportJSON(): SerializedDiffNode;
|
|
18
|
+
exportDOM(editor: LexicalEditor): DOMExportOutput;
|
|
19
|
+
createDOM(config: EditorConfig, editor: LexicalEditor): HTMLDivElement;
|
|
20
|
+
updateDOM(_prevNode: unknown, _dom: HTMLElement, _config: EditorConfig): boolean;
|
|
21
|
+
getDOMSlot(element: HTMLElement): ElementDOMSlot<HTMLElement>;
|
|
22
|
+
isInline(): boolean;
|
|
23
|
+
isCardLike(): boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function $createDiffNode(diffType?: 'add' | 'remove' | 'modify' | 'unchanged'): DiffNode;
|
|
26
|
+
export declare function $isDiffNode(node: unknown): node is DiffNode;
|