@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.
Files changed (55) hide show
  1. package/es/const/hotkey.js +1 -1
  2. package/es/editor-kernel/kernel.d.ts +4 -4
  3. package/es/editor-kernel/kernel.js +6 -2
  4. package/es/editor-kernel/react/PortalContainer.d.ts +11 -0
  5. package/es/editor-kernel/react/PortalContainer.js +32 -0
  6. package/es/editor-kernel/react/index.d.ts +1 -0
  7. package/es/editor-kernel/react/index.js +1 -0
  8. package/es/editor-kernel/react/useDecorators.js +3 -2
  9. package/es/editor-kernel/utils.d.ts +7 -1
  10. package/es/editor-kernel/utils.js +34 -0
  11. package/es/index.d.ts +1 -0
  12. package/es/index.js +1 -0
  13. package/es/plugins/common/plugin/register.js +37 -2
  14. package/es/plugins/file/node/FileNode.js +12 -2
  15. package/es/plugins/hr/node/HorizontalRuleNode.js +12 -2
  16. package/es/plugins/image/node/block-image-node.js +1 -1
  17. package/es/plugins/image/plugin/index.js +33 -3
  18. package/es/plugins/image/react/components/Image.js +1 -1
  19. package/es/plugins/inode/index.d.ts +3 -0
  20. package/es/plugins/inode/index.js +3 -0
  21. package/es/plugins/inode/plugin/index.d.ts +16 -0
  22. package/es/plugins/inode/plugin/index.js +49 -0
  23. package/es/plugins/inode/react/index.d.ts +3 -0
  24. package/es/plugins/inode/react/index.js +22 -0
  25. package/es/plugins/inode/service/index.d.ts +25 -0
  26. package/es/plugins/inode/service/index.js +49 -0
  27. package/es/plugins/link/node/LinkNode.js +2 -0
  28. package/es/plugins/link-highlight/node/link-highlight.js +1 -0
  29. package/es/plugins/litexml/command/diffCommand.d.ts +10 -0
  30. package/es/plugins/litexml/command/diffCommand.js +47 -0
  31. package/es/plugins/litexml/command/index.d.ts +19 -0
  32. package/es/plugins/litexml/command/index.js +286 -45
  33. package/es/plugins/litexml/data-source/litexml-data-source.d.ts +3 -1
  34. package/es/plugins/litexml/data-source/litexml-data-source.js +10 -3
  35. package/es/plugins/litexml/index.d.ts +1 -1
  36. package/es/plugins/litexml/index.js +1 -1
  37. package/es/plugins/litexml/node/DiffNode.d.ts +26 -0
  38. package/es/plugins/litexml/node/DiffNode.js +164 -0
  39. package/es/plugins/litexml/plugin/index.d.ts +4 -0
  40. package/es/plugins/litexml/plugin/index.js +23 -4
  41. package/es/plugins/litexml/react/DiffNodeToolbar.d.ts +10 -0
  42. package/es/plugins/litexml/react/DiffNodeToolbar.js +47 -0
  43. package/es/plugins/litexml/react/index.js +16 -1
  44. package/es/plugins/litexml/react/style.d.ts +1 -0
  45. package/es/plugins/litexml/react/style.js +8 -0
  46. package/es/plugins/litexml/utils/index.d.ts +3 -0
  47. package/es/plugins/litexml/utils/index.js +47 -0
  48. package/es/plugins/markdown/data-source/markdown-data-source.d.ts +3 -1
  49. package/es/plugins/markdown/data-source/markdown-data-source.js +5 -1
  50. package/es/plugins/markdown/plugin/index.js +3 -2
  51. package/es/plugins/markdown/react/index.js +2 -0
  52. package/es/plugins/math/node/index.js +24 -4
  53. package/es/plugins/mention/node/MentionNode.js +12 -2
  54. package/es/types/kernel.d.ts +8 -3
  55. 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, $isElementNode, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
12
+ import { $getNodeByKey, $insertNodes, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
3
13
  import { $closest } from "../../../editor-kernel";
4
- import { $parseSerializedNodeImpl } from "../utils";
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(LITEXML_APPLY_COMMAND, function (payload) {
10
- var litexml = payload.litexml;
11
- var arrayXml = Array.isArray(litexml) ? litexml : [litexml];
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 oldNode = $getNodeByKey(child.id);
19
- var newNode = $parseSerializedNodeImpl(child, editor);
20
- if (oldNode) {
21
- prevNode = oldNode.replace(newNode, $isElementNode(newNode));
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
- return false;
49
- }, COMMAND_PRIORITY_EDITOR // Priority
50
- ), editor.registerCommand(LITEXML_REMOVE_COMMAND, function (payload) {
51
- var id = payload.id;
52
- editor.update(function () {
53
- var node = $getNodeByKey(id);
54
- if (node) {
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
- return false;
59
- }, COMMAND_PRIORITY_EDITOR // Priority
60
- ), editor.registerCommand(LITEXML_INSERT_COMMAND, function (payload) {
61
- var litexml = payload.litexml;
62
- var isBefore = ('beforeId' in payload);
63
- var inode = dataSource.readLiteXMLToInode(litexml);
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
- } catch (error) {
88
- console.error('Error inserting node:', error);
275
+ return;
89
276
  }
90
- });
91
- return false;
92
- }, COMMAND_PRIORITY_EDITOR // Priority
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 service = arguments.length > 1 ? arguments[1] : undefined;
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
- result.id = xmlElement.getAttribute('id') || undefined;
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;