@lexical/react 0.1.14 → 0.1.17

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