@lexical/react 0.1.6 → 0.1.10

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 (105) hide show
  1. package/DEPRECATED_useLexical.dev.js +49 -0
  2. package/DEPRECATED_useLexical.js +9 -2
  3. package/DEPRECATED_useLexical.prod.js +7 -0
  4. package/DEPRECATED_useLexicalAutoFormatter.dev.js +729 -0
  5. package/DEPRECATED_useLexicalAutoFormatter.js +9 -11
  6. package/DEPRECATED_useLexicalAutoFormatter.prod.js +26 -0
  7. package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +136 -0
  8. package/DEPRECATED_useLexicalCanShowPlaceholder.js +9 -3
  9. package/DEPRECATED_useLexicalCanShowPlaceholder.prod.js +8 -0
  10. package/DEPRECATED_useLexicalCharacterLimit.dev.js +293 -0
  11. package/DEPRECATED_useLexicalCharacterLimit.js +9 -9
  12. package/DEPRECATED_useLexicalCharacterLimit.prod.js +14 -0
  13. package/DEPRECATED_useLexicalDecorators.dev.js +82 -0
  14. package/DEPRECATED_useLexicalDecorators.js +9 -2
  15. package/DEPRECATED_useLexicalDecorators.prod.js +8 -0
  16. package/DEPRECATED_useLexicalEditor.dev.js +28 -0
  17. package/DEPRECATED_useLexicalEditor.js +9 -1
  18. package/DEPRECATED_useLexicalEditor.prod.js +7 -0
  19. package/DEPRECATED_useLexicalEditorEvents.dev.js +96 -0
  20. package/DEPRECATED_useLexicalEditorEvents.js +9 -2
  21. package/DEPRECATED_useLexicalEditorEvents.prod.js +8 -0
  22. package/DEPRECATED_useLexicalHistory.dev.js +342 -0
  23. package/DEPRECATED_useLexicalHistory.js +9 -7
  24. package/DEPRECATED_useLexicalHistory.prod.js +13 -0
  25. package/DEPRECATED_useLexicalList.dev.js +64 -0
  26. package/DEPRECATED_useLexicalList.js +9 -12
  27. package/DEPRECATED_useLexicalList.prod.js +7 -0
  28. package/DEPRECATED_useLexicalPlainText.dev.js +761 -0
  29. package/DEPRECATED_useLexicalPlainText.js +9 -17
  30. package/DEPRECATED_useLexicalPlainText.prod.js +21 -0
  31. package/DEPRECATED_useLexicalRichText.dev.js +1197 -0
  32. package/DEPRECATED_useLexicalRichText.js +9 -31
  33. package/DEPRECATED_useLexicalRichText.prod.js +32 -0
  34. package/LexicalAutoFormatterPlugin.dev.js +732 -0
  35. package/LexicalAutoFormatterPlugin.js +9 -12
  36. package/LexicalAutoFormatterPlugin.prod.js +26 -0
  37. package/LexicalAutoLinkPlugin.dev.js +227 -0
  38. package/LexicalAutoLinkPlugin.js +9 -5
  39. package/LexicalAutoLinkPlugin.prod.js +12 -0
  40. package/LexicalBootstrapPlugin.dev.js +122 -0
  41. package/LexicalBootstrapPlugin.js +9 -0
  42. package/LexicalBootstrapPlugin.prod.js +8 -0
  43. package/LexicalCharacterLimitPlugin.dev.js +351 -0
  44. package/LexicalCharacterLimitPlugin.js +9 -10
  45. package/LexicalCharacterLimitPlugin.prod.js +14 -0
  46. package/LexicalCollaborationPlugin.dev.js +220 -0
  47. package/LexicalCollaborationPlugin.js +9 -8
  48. package/LexicalCollaborationPlugin.prod.js +13 -0
  49. package/LexicalComposer.dev.js +71 -0
  50. package/LexicalComposer.js +9 -2
  51. package/LexicalComposer.prod.js +8 -0
  52. package/LexicalComposerContext.dev.js +53 -0
  53. package/LexicalComposerContext.js +9 -1
  54. package/LexicalComposerContext.prod.js +7 -0
  55. package/LexicalContentEditable.dev.js +71 -0
  56. package/LexicalContentEditable.js +9 -3
  57. package/LexicalContentEditable.prod.js +9 -0
  58. package/LexicalHashtagPlugin.dev.js +152 -0
  59. package/LexicalHashtagPlugin.js +9 -4
  60. package/LexicalHashtagPlugin.prod.js +10 -0
  61. package/LexicalHistoryPlugin.dev.js +347 -0
  62. package/LexicalHistoryPlugin.js +9 -7
  63. package/LexicalHistoryPlugin.prod.js +13 -0
  64. package/LexicalHorizontalRuleNode.dev.js +66 -0
  65. package/LexicalHorizontalRuleNode.js +9 -0
  66. package/LexicalHorizontalRuleNode.prod.js +8 -0
  67. package/LexicalLinkPlugin.dev.js +136 -0
  68. package/LexicalLinkPlugin.js +9 -3
  69. package/LexicalLinkPlugin.prod.js +9 -0
  70. package/LexicalListPlugin.dev.js +67 -0
  71. package/LexicalListPlugin.js +9 -12
  72. package/LexicalListPlugin.prod.js +8 -0
  73. package/LexicalNestedComposer.dev.js +60 -0
  74. package/LexicalNestedComposer.js +9 -1
  75. package/LexicalNestedComposer.prod.js +8 -0
  76. package/LexicalOnChangePlugin.dev.js +57 -0
  77. package/LexicalOnChangePlugin.js +9 -1
  78. package/LexicalOnChangePlugin.prod.js +7 -0
  79. package/LexicalPlainTextPlugin.dev.js +589 -0
  80. package/LexicalPlainTextPlugin.js +9 -13
  81. package/LexicalPlainTextPlugin.prod.js +18 -0
  82. package/LexicalRichTextPlugin.dev.js +1025 -0
  83. package/LexicalRichTextPlugin.js +9 -27
  84. package/LexicalRichTextPlugin.prod.js +28 -0
  85. package/LexicalTablePlugin.dev.js +77 -0
  86. package/LexicalTablePlugin.js +9 -3
  87. package/LexicalTablePlugin.prod.js +9 -0
  88. package/LexicalTreeView.dev.js +348 -0
  89. package/LexicalTreeView.js +9 -12
  90. package/LexicalTreeView.prod.js +20 -0
  91. package/README.md +10 -5
  92. package/package.json +5 -4
  93. package/useLexicalDecoratorMap.dev.js +83 -0
  94. package/useLexicalDecoratorMap.js +9 -2
  95. package/useLexicalDecoratorMap.prod.js +8 -0
  96. package/useLexicalIsTextContentEmpty.dev.js +84 -0
  97. package/useLexicalIsTextContentEmpty.js +9 -2
  98. package/useLexicalIsTextContentEmpty.prod.js +8 -0
  99. package/useLexicalNodeSelection.dev.js +70 -0
  100. package/useLexicalNodeSelection.js +9 -0
  101. package/useLexicalNodeSelection.prod.js +8 -0
  102. package/withSubscriptions.dev.js +23 -0
  103. package/withSubscriptions.js +9 -1
  104. package/withSubscriptions.prod.js +7 -0
  105. package/LexicalHorizontalRulePlugin.js +0 -1
@@ -0,0 +1,761 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ 'use strict';
8
+
9
+ var withSubscriptions = require('@lexical/react/withSubscriptions');
10
+ var lexical = require('lexical');
11
+ var react = require('react');
12
+
13
+ /**
14
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
15
+ *
16
+ * This source code is licensed under the MIT license found in the
17
+ * LICENSE file in the root directory of this source tree.
18
+ *
19
+ *
20
+ */
21
+ const HISTORY_MERGE = 0;
22
+ const HISTORY_PUSH = 1;
23
+ const DISCARD_HISTORY_CANDIDATE = 2;
24
+ const OTHER = 0;
25
+ const COMPOSING_CHARACTER = 1;
26
+ const INSERT_CHARACTER_AFTER_SELECTION = 2;
27
+ const DELETE_CHARACTER_BEFORE_SELECTION = 3;
28
+ const DELETE_CHARACTER_AFTER_SELECTION = 4;
29
+ const EditorPriority = 0;
30
+
31
+ function getDirtyNodes(editorState, dirtyLeavesSet, dirtyElementsSet) {
32
+ const dirtyLeaves = Array.from(dirtyLeavesSet);
33
+ const dirtyElements = Array.from(dirtyElementsSet);
34
+ const nodeMap = editorState._nodeMap;
35
+ const nodes = [];
36
+
37
+ for (let i = 0; i < dirtyLeaves.length; i++) {
38
+ const dirtyLeafKey = dirtyLeaves[i];
39
+ const dirtyLeaf = nodeMap.get(dirtyLeafKey);
40
+
41
+ if (dirtyLeaf !== undefined) {
42
+ nodes.push(dirtyLeaf);
43
+ }
44
+ }
45
+
46
+ for (let i = 0; i < dirtyElements.length; i++) {
47
+ const intentionallyMarkedAsDirty = dirtyElements[i][1];
48
+
49
+ if (!intentionallyMarkedAsDirty) {
50
+ continue;
51
+ }
52
+
53
+ const dirtyElementKey = dirtyElements[i][0];
54
+ const dirtyElement = nodeMap.get(dirtyElementKey);
55
+
56
+ if (dirtyElement !== undefined && !lexical.$isRootNode(dirtyElement)) {
57
+ nodes.push(dirtyElement);
58
+ }
59
+ }
60
+
61
+ return nodes;
62
+ }
63
+
64
+ function getChangeType(prevEditorState, nextEditorState, dirtyLeavesSet, dirtyElementsSet, isComposing) {
65
+ if (prevEditorState === null || dirtyLeavesSet.size === 0 && dirtyElementsSet.size === 0) {
66
+ return OTHER;
67
+ }
68
+
69
+ const nextSelection = nextEditorState._selection;
70
+ const prevSelection = prevEditorState._selection;
71
+
72
+ if (isComposing) {
73
+ return COMPOSING_CHARACTER;
74
+ }
75
+
76
+ if (!lexical.$isRangeSelection(nextSelection) || !lexical.$isRangeSelection(prevSelection) || !prevSelection.isCollapsed() || !nextSelection.isCollapsed()) {
77
+ return OTHER;
78
+ }
79
+
80
+ const dirtyNodes = getDirtyNodes(nextEditorState, dirtyLeavesSet, dirtyElementsSet);
81
+
82
+ if (dirtyNodes.length === 0) {
83
+ return OTHER;
84
+ } // Catching the case when inserting new text node into an element (e.g. first char in paragraph/list),
85
+ // or after existing node.
86
+
87
+
88
+ if (dirtyNodes.length > 1) {
89
+ const nextNodeMap = nextEditorState._nodeMap;
90
+ const nextAnchorNode = nextNodeMap.get(nextSelection.anchor.key);
91
+ const prevAnchorNode = nextNodeMap.get(prevSelection.anchor.key);
92
+
93
+ if (nextAnchorNode && prevAnchorNode && !prevEditorState._nodeMap.has(nextAnchorNode.__key) && lexical.$isTextNode(nextAnchorNode) && nextAnchorNode.__text.length === 1 && nextSelection.anchor.offset === 1) {
94
+ return INSERT_CHARACTER_AFTER_SELECTION;
95
+ }
96
+
97
+ return OTHER;
98
+ }
99
+
100
+ const nextDirtyNode = dirtyNodes[0];
101
+
102
+ const prevDirtyNode = prevEditorState._nodeMap.get(nextDirtyNode.__key);
103
+
104
+ if (!lexical.$isTextNode(prevDirtyNode) || !lexical.$isTextNode(nextDirtyNode) || prevDirtyNode.__mode !== nextDirtyNode.__mode) {
105
+ return OTHER;
106
+ }
107
+
108
+ const prevText = prevDirtyNode.__text;
109
+ const nextText = nextDirtyNode.__text;
110
+
111
+ if (prevText === nextText) {
112
+ return OTHER;
113
+ }
114
+
115
+ const nextAnchor = nextSelection.anchor;
116
+ const prevAnchor = prevSelection.anchor;
117
+
118
+ if (nextAnchor.key !== prevAnchor.key || nextAnchor.type !== 'text') {
119
+ return OTHER;
120
+ }
121
+
122
+ const nextAnchorOffset = nextAnchor.offset;
123
+ const prevAnchorOffset = prevAnchor.offset;
124
+ const textDiff = nextText.length - prevText.length;
125
+
126
+ if (textDiff === 1 && prevAnchorOffset === nextAnchorOffset - 1) {
127
+ return INSERT_CHARACTER_AFTER_SELECTION;
128
+ }
129
+
130
+ if (textDiff === -1 && prevAnchorOffset === nextAnchorOffset + 1) {
131
+ return DELETE_CHARACTER_BEFORE_SELECTION;
132
+ }
133
+
134
+ if (textDiff === -1 && prevAnchorOffset === nextAnchorOffset) {
135
+ return DELETE_CHARACTER_AFTER_SELECTION;
136
+ }
137
+
138
+ return OTHER;
139
+ }
140
+
141
+ function createMergeActionGetter(editor, delay) {
142
+ let prevChangeTime = Date.now();
143
+ let prevChangeType = OTHER;
144
+ return (prevEditorState, nextEditorState, currentHistoryEntry, dirtyLeaves, dirtyElements, tags) => {
145
+ const changeTime = Date.now(); // If applying changes from history stack there's no need
146
+ // to run history logic again, as history entries already calculated
147
+
148
+ if (tags.has('historic')) {
149
+ prevChangeType = OTHER;
150
+ prevChangeTime = changeTime;
151
+ return DISCARD_HISTORY_CANDIDATE;
152
+ }
153
+
154
+ const changeType = getChangeType(prevEditorState, nextEditorState, dirtyLeaves, dirtyElements, editor.isComposing());
155
+
156
+ const mergeAction = (() => {
157
+ const shouldPushHistory = tags.has('history-push');
158
+ const shouldMergeHistory = !shouldPushHistory && tags.has('history-merge');
159
+
160
+ if (shouldMergeHistory) {
161
+ return HISTORY_MERGE;
162
+ }
163
+
164
+ if (prevEditorState === null) {
165
+ return HISTORY_PUSH;
166
+ }
167
+
168
+ const selection = nextEditorState._selection;
169
+ const prevSelection = prevEditorState._selection;
170
+ const hasDirtyNodes = dirtyLeaves.size > 0 || dirtyElements.size > 0;
171
+
172
+ if (!hasDirtyNodes) {
173
+ if (prevSelection === null && selection !== null) {
174
+ return HISTORY_MERGE;
175
+ }
176
+
177
+ return DISCARD_HISTORY_CANDIDATE;
178
+ }
179
+
180
+ const isSameEditor = currentHistoryEntry === null || currentHistoryEntry.editor === editor;
181
+
182
+ if (shouldPushHistory === false && changeType !== OTHER && changeType === prevChangeType && changeTime < prevChangeTime + delay && isSameEditor) {
183
+ return HISTORY_MERGE;
184
+ }
185
+
186
+ return HISTORY_PUSH;
187
+ })();
188
+
189
+ prevChangeTime = changeTime;
190
+ prevChangeType = changeType;
191
+ return mergeAction;
192
+ };
193
+ }
194
+
195
+ function useHistory(editor, externalHistoryState, delay = 1000) {
196
+ const historyState = react.useMemo(() => externalHistoryState || createEmptyHistoryState(), [externalHistoryState]);
197
+ const clearHistory = react.useCallback(() => {
198
+ historyState.undoStack = [];
199
+ historyState.redoStack = [];
200
+ historyState.current = null;
201
+ }, [historyState]);
202
+ react.useEffect(() => {
203
+ const getMergeAction = createMergeActionGetter(editor, delay);
204
+
205
+ const applyChange = ({
206
+ editorState,
207
+ prevEditorState,
208
+ dirtyLeaves,
209
+ dirtyElements,
210
+ tags
211
+ }) => {
212
+ const current = historyState.current;
213
+ const redoStack = historyState.redoStack;
214
+ const undoStack = historyState.undoStack;
215
+ const currentEditorState = current === null ? null : current.editorState;
216
+
217
+ if (current !== null && editorState === currentEditorState) {
218
+ return;
219
+ }
220
+
221
+ const mergeAction = getMergeAction(prevEditorState, editorState, current, dirtyLeaves, dirtyElements, tags);
222
+
223
+ if (mergeAction === HISTORY_PUSH) {
224
+ if (redoStack.length !== 0) {
225
+ historyState.redoStack = [];
226
+ }
227
+
228
+ if (current !== null) {
229
+ undoStack.push({ ...current,
230
+ undoSelection: prevEditorState.read(lexical.$getSelection)
231
+ });
232
+ editor.execCommand('canUndo', true);
233
+ }
234
+ } else if (mergeAction === DISCARD_HISTORY_CANDIDATE) {
235
+ return;
236
+ } // Else we merge
237
+
238
+
239
+ historyState.current = {
240
+ editor,
241
+ editorState
242
+ };
243
+ };
244
+
245
+ const undo = () => {
246
+ const redoStack = historyState.redoStack;
247
+ const undoStack = historyState.undoStack;
248
+ const undoStackLength = undoStack.length;
249
+
250
+ if (undoStackLength !== 0) {
251
+ const current = historyState.current;
252
+ const historyStateEntry = undoStack.pop();
253
+
254
+ if (current !== null) {
255
+ redoStack.push(current);
256
+ editor.execCommand('canRedo', true);
257
+ }
258
+
259
+ if (undoStack.length === 0) {
260
+ editor.execCommand('canUndo', false);
261
+ }
262
+
263
+ historyState.current = historyStateEntry;
264
+ historyStateEntry.editor.setEditorState(historyStateEntry.editorState.clone(historyStateEntry.undoSelection), {
265
+ tag: 'historic'
266
+ });
267
+ }
268
+ };
269
+
270
+ const redo = () => {
271
+ const redoStack = historyState.redoStack;
272
+ const undoStack = historyState.undoStack;
273
+
274
+ if (redoStack.length !== 0) {
275
+ const current = historyState.current;
276
+
277
+ if (current !== null) {
278
+ undoStack.push(current);
279
+ editor.execCommand('canUndo', true);
280
+ }
281
+
282
+ const historyStateEntry = redoStack.pop();
283
+
284
+ if (redoStack.length === 0) {
285
+ editor.execCommand('canRedo', false);
286
+ }
287
+
288
+ historyState.current = historyStateEntry;
289
+ historyStateEntry.editor.setEditorState(historyStateEntry.editorState, {
290
+ tag: 'historic'
291
+ });
292
+ }
293
+ };
294
+
295
+ const applyCommand = type => {
296
+ switch (type) {
297
+ case 'undo':
298
+ undo();
299
+ return true;
300
+
301
+ case 'redo':
302
+ redo();
303
+ return true;
304
+
305
+ case 'clearEditor':
306
+ clearHistory();
307
+ return false;
308
+
309
+ case 'clearHistory':
310
+ clearHistory();
311
+ return true;
312
+
313
+ default:
314
+ return false;
315
+ }
316
+ };
317
+
318
+ return withSubscriptions(editor.addListener('command', applyCommand, EditorPriority), editor.addListener('update', applyChange));
319
+ }, [clearHistory, delay, editor, historyState]);
320
+ }
321
+ function createEmptyHistoryState() {
322
+ return {
323
+ current: null,
324
+ redoStack: [],
325
+ undoStack: []
326
+ };
327
+ }
328
+
329
+ /**
330
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
331
+ *
332
+ * This source code is licensed under the MIT license found in the
333
+ * LICENSE file in the root directory of this source tree.
334
+ *
335
+ *
336
+ */
337
+ function useLexicalHistory(editor, externalHistoryState, delay = 1000) {
338
+ return useHistory(editor, externalHistoryState, delay);
339
+ }
340
+
341
+ /**
342
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
343
+ *
344
+ * This source code is licensed under the MIT license found in the
345
+ * LICENSE file in the root directory of this source tree.
346
+ *
347
+ *
348
+ */
349
+
350
+ function $moveCaretSelection(selection, isHoldingShift, isBackward, granularity) {
351
+ selection.modify(isHoldingShift ? 'extend' : 'move', isBackward, granularity);
352
+ }
353
+ function $isParentElementRTL(selection) {
354
+ const anchorNode = selection.anchor.getNode();
355
+ const parent = lexical.$isRootNode(anchorNode) ? anchorNode : anchorNode.getParentOrThrow();
356
+ return parent.getDirection() === 'rtl';
357
+ }
358
+ function $moveCharacter(selection, isHoldingShift, isBackward) {
359
+ const isRTL = $isParentElementRTL(selection);
360
+ $moveCaretSelection(selection, isHoldingShift, isBackward ? !isRTL : isRTL, 'character');
361
+ }
362
+
363
+ /**
364
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
365
+ *
366
+ * This source code is licensed under the MIT license found in the
367
+ * LICENSE file in the root directory of this source tree.
368
+ *
369
+ *
370
+ */
371
+ function resolveElement(element, isBackward, focusOffset) {
372
+ const parent = element.getParent();
373
+ let offset = focusOffset;
374
+ let block = element;
375
+
376
+ if (parent !== null) {
377
+ if (isBackward && focusOffset === 0) {
378
+ offset = block.getIndexWithinParent();
379
+ block = parent;
380
+ } else if (!isBackward && focusOffset === block.getChildrenSize()) {
381
+ offset = block.getIndexWithinParent() + 1;
382
+ block = parent;
383
+ }
384
+ }
385
+
386
+ return block.getChildAtIndex(isBackward ? offset - 1 : offset);
387
+ }
388
+
389
+ function getPossibleDecoratorNode(focus, isBackward) {
390
+ const focusOffset = focus.offset;
391
+
392
+ if (focus.type === 'element') {
393
+ const block = focus.getNode();
394
+ return resolveElement(block, isBackward, focusOffset);
395
+ } else {
396
+ const focusNode = focus.getNode();
397
+
398
+ if (isBackward && focusOffset === 0 || !isBackward && focusOffset === focusNode.getTextContentSize()) {
399
+ const possibleNode = isBackward ? focusNode.getPreviousSibling() : focusNode.getNextSibling();
400
+
401
+ if (possibleNode === null) {
402
+ return resolveElement(focusNode.getParentOrThrow(), isBackward, focusNode.getIndexWithinParent() + (isBackward ? 0 : 1));
403
+ }
404
+
405
+ return possibleNode;
406
+ }
407
+ }
408
+
409
+ return null;
410
+ }
411
+
412
+ /**
413
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
414
+ *
415
+ * This source code is licensed under the MIT license found in the
416
+ * LICENSE file in the root directory of this source tree.
417
+ *
418
+ *
419
+ */
420
+ function $insertDataTransferForPlainText(dataTransfer, selection) {
421
+ const text = dataTransfer.getData('text/plain');
422
+
423
+ if (text != null) {
424
+ selection.insertRawText(text);
425
+ }
426
+ }
427
+ function $shouldOverrideDefaultCharacterSelection(selection, isBackward) {
428
+ const possibleNode = getPossibleDecoratorNode(selection.focus, isBackward);
429
+ return lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated();
430
+ }
431
+ function onPasteForPlainText(event, editor) {
432
+ event.preventDefault();
433
+ editor.update(() => {
434
+ const selection = lexical.$getSelection();
435
+ const clipboardData = event.clipboardData;
436
+
437
+ if (clipboardData != null && lexical.$isRangeSelection(selection)) {
438
+ $insertDataTransferForPlainText(clipboardData, selection);
439
+ }
440
+ });
441
+ }
442
+ function onCutForPlainText(event, editor) {
443
+ onCopyForPlainText(event, editor);
444
+ editor.update(() => {
445
+ const selection = lexical.$getSelection();
446
+
447
+ if (lexical.$isRangeSelection(selection)) {
448
+ selection.removeText();
449
+ }
450
+ });
451
+ }
452
+ function onCopyForPlainText(event, editor) {
453
+ event.preventDefault();
454
+ editor.update(() => {
455
+ const clipboardData = event.clipboardData;
456
+ const selection = lexical.$getSelection();
457
+
458
+ if (selection !== null) {
459
+ if (clipboardData != null) {
460
+ const domSelection = window.getSelection(); // If we haven't selected a range, then don't copy anything
461
+
462
+ if (domSelection.isCollapsed) {
463
+ return;
464
+ }
465
+
466
+ const range = domSelection.getRangeAt(0);
467
+
468
+ if (range) {
469
+ const container = document.createElement('div');
470
+ const frag = range.cloneContents();
471
+ container.appendChild(frag);
472
+ clipboardData.setData('text/html', container.innerHTML);
473
+ }
474
+
475
+ clipboardData.setData('text/plain', selection.getTextContent());
476
+ }
477
+ }
478
+ });
479
+ }
480
+
481
+ /**
482
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
483
+ *
484
+ * This source code is licensed under the MIT license found in the
485
+ * LICENSE file in the root directory of this source tree.
486
+ *
487
+ *
488
+ */
489
+ function useLexicalDragonSupport(editor) {
490
+ react.useEffect(() => {
491
+ const handler = event => {
492
+ const rootElement = editor.getRootElement();
493
+
494
+ if (document.activeElement !== rootElement) {
495
+ return;
496
+ }
497
+
498
+ const data = event.data;
499
+
500
+ if (typeof data === 'string') {
501
+ let parsedData;
502
+
503
+ try {
504
+ parsedData = JSON.parse(data);
505
+ } catch (e) {
506
+ return;
507
+ }
508
+
509
+ if (parsedData && parsedData.protocol === 'nuanria_messaging' && parsedData.type === 'request') {
510
+ const payload = parsedData.payload;
511
+
512
+ if (payload && payload.functionId === 'makeChanges') {
513
+ const args = payload.args;
514
+
515
+ if (args) {
516
+ const [elementStart, elementLength, text, selStart, selLength, formatCommand] = args; // TODO: we should probably handle formatCommand somehow?
517
+ editor.update(() => {
518
+ const selection = lexical.$getSelection();
519
+
520
+ if (lexical.$isRangeSelection(selection)) {
521
+ const anchor = selection.anchor;
522
+ let anchorNode = anchor.getNode();
523
+ let setSelStart = 0;
524
+ let setSelEnd = 0;
525
+
526
+ if (lexical.$isTextNode(anchorNode)) {
527
+ // set initial selection
528
+ if (elementStart >= 0 && elementLength >= 0) {
529
+ setSelStart = elementStart;
530
+ setSelEnd = elementStart + elementLength; // If the offset is more than the end, make it the end
531
+
532
+ selection.setTextNodeRange(anchorNode, setSelStart, anchorNode, setSelEnd);
533
+ }
534
+ }
535
+
536
+ if (setSelStart !== setSelEnd || text !== '') {
537
+ selection.insertRawText(text);
538
+ anchorNode = anchor.getNode();
539
+ }
540
+
541
+ if (lexical.$isTextNode(anchorNode)) {
542
+ // set final selection
543
+ setSelStart = selStart;
544
+ setSelEnd = selStart + selLength;
545
+ const anchorNodeTextLength = anchorNode.getTextContentSize(); // If the offset is more than the end, make it the end
546
+
547
+ setSelStart = setSelStart > anchorNodeTextLength ? anchorNodeTextLength : setSelStart;
548
+ setSelEnd = setSelEnd > anchorNodeTextLength ? anchorNodeTextLength : setSelEnd;
549
+ selection.setTextNodeRange(anchorNode, setSelStart, anchorNode, setSelEnd);
550
+ } // block the chrome extension from handling this event
551
+
552
+
553
+ event.stopImmediatePropagation();
554
+ }
555
+ });
556
+ }
557
+ }
558
+ }
559
+ }
560
+ };
561
+
562
+ window.addEventListener('message', handler, true);
563
+ return () => {
564
+ window.removeEventListener('message', handler, true);
565
+ };
566
+ }, [editor]);
567
+ }
568
+
569
+ /**
570
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
571
+ *
572
+ * This source code is licensed under the MIT license found in the
573
+ * LICENSE file in the root directory of this source tree.
574
+ *
575
+ *
576
+ */
577
+ function usePlainTextSetup(editor) {
578
+ react.useEffect(() => {
579
+ const removeListener = editor.addListener('command', (type, payload) => {
580
+ const selection = lexical.$getSelection();
581
+
582
+ if (!lexical.$isRangeSelection(selection)) {
583
+ return false;
584
+ }
585
+
586
+ switch (type) {
587
+ case 'deleteCharacter':
588
+ {
589
+ const isBackward = payload;
590
+ selection.deleteCharacter(isBackward);
591
+ return true;
592
+ }
593
+
594
+ case 'deleteWord':
595
+ {
596
+ const isBackward = payload;
597
+ selection.deleteWord(isBackward);
598
+ return true;
599
+ }
600
+
601
+ case 'deleteLine':
602
+ {
603
+ const isBackward = payload;
604
+ selection.deleteLine(isBackward);
605
+ return true;
606
+ }
607
+
608
+ case 'insertText':
609
+ {
610
+ const eventOrText = payload;
611
+
612
+ if (typeof eventOrText === 'string') {
613
+ selection.insertText(eventOrText);
614
+ } else {
615
+ const dataTransfer = eventOrText.dataTransfer;
616
+
617
+ if (dataTransfer != null) {
618
+ $insertDataTransferForPlainText(dataTransfer, selection);
619
+ } else {
620
+ const data = eventOrText.data;
621
+
622
+ if (data) {
623
+ selection.insertText(data);
624
+ }
625
+ }
626
+ }
627
+
628
+ return true;
629
+ }
630
+
631
+ case 'removeText':
632
+ selection.removeText();
633
+ return true;
634
+
635
+ case 'insertLineBreak':
636
+ const selectStart = payload;
637
+ selection.insertLineBreak(selectStart);
638
+ return true;
639
+
640
+ case 'insertParagraph':
641
+ selection.insertLineBreak();
642
+ return true;
643
+
644
+ case 'indentContent':
645
+ case 'outdentContent':
646
+ case 'insertHorizontalRule':
647
+ case 'insertImage':
648
+ case 'insertTable':
649
+ case 'formatElement':
650
+ case 'formatText':
651
+ {
652
+ return true;
653
+ }
654
+
655
+ case 'keyArrowLeft':
656
+ {
657
+ const event = payload;
658
+ const isHoldingShift = event.shiftKey;
659
+
660
+ if ($shouldOverrideDefaultCharacterSelection(selection, true)) {
661
+ event.preventDefault();
662
+ $moveCharacter(selection, isHoldingShift, true);
663
+ return true;
664
+ }
665
+
666
+ return false;
667
+ }
668
+
669
+ case 'keyArrowRight':
670
+ {
671
+ const event = payload;
672
+ const isHoldingShift = event.shiftKey;
673
+
674
+ if ($shouldOverrideDefaultCharacterSelection(selection, false)) {
675
+ event.preventDefault();
676
+ $moveCharacter(selection, isHoldingShift, false);
677
+ return true;
678
+ }
679
+
680
+ return false;
681
+ }
682
+
683
+ case 'keyBackspace':
684
+ {
685
+ const event = payload;
686
+ event.preventDefault();
687
+ return editor.execCommand('deleteCharacter', true);
688
+ }
689
+
690
+ case 'keyDelete':
691
+ {
692
+ const event = payload;
693
+ event.preventDefault();
694
+ return editor.execCommand('deleteCharacter', false);
695
+ }
696
+
697
+ case 'keyEnter':
698
+ {
699
+ const event = payload;
700
+ event.preventDefault();
701
+ return editor.execCommand('insertLineBreak');
702
+ }
703
+
704
+ case 'copy':
705
+ {
706
+ const event = payload;
707
+ onCopyForPlainText(event, editor);
708
+ return true;
709
+ }
710
+
711
+ case 'cut':
712
+ {
713
+ const event = payload;
714
+ onCutForPlainText(event, editor);
715
+ return true;
716
+ }
717
+
718
+ case 'paste':
719
+ {
720
+ const event = payload;
721
+ onPasteForPlainText(event, editor);
722
+ return true;
723
+ }
724
+
725
+ case 'drop':
726
+ case 'dragstart':
727
+ {
728
+ // TODO: Make drag and drop work at some point.
729
+ const event = payload;
730
+ event.preventDefault();
731
+ return true;
732
+ }
733
+ }
734
+
735
+ return false;
736
+ }, 0);
737
+ const bootstrapCommandHandled = editor.execCommand('bootstrapEditor');
738
+
739
+ if (!bootstrapCommandHandled) {
740
+ console.warn('bootstrapEditor command was not handled. Did you forget to add <BootstrapPlugin />?');
741
+ }
742
+
743
+ return removeListener;
744
+ }, [editor]);
745
+ useLexicalDragonSupport(editor);
746
+ }
747
+
748
+ /**
749
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
750
+ *
751
+ * This source code is licensed under the MIT license found in the
752
+ * LICENSE file in the root directory of this source tree.
753
+ *
754
+ *
755
+ */
756
+ function useLexicalPlainText(editor, externalHistoryState) {
757
+ usePlainTextSetup(editor);
758
+ useLexicalHistory(editor, externalHistoryState);
759
+ }
760
+
761
+ module.exports = useLexicalPlainText;