@lexical/react 0.1.10 → 0.1.13

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 (86) hide show
  1. package/DEPRECATED_useLexical.dev.js +3 -7
  2. package/DEPRECATED_useLexical.prod.js +1 -1
  3. package/DEPRECATED_useLexicalAutoFormatter.dev.js +83 -37
  4. package/DEPRECATED_useLexicalAutoFormatter.prod.js +20 -19
  5. package/DEPRECATED_useLexicalCharacterLimit.dev.js +20 -17
  6. package/DEPRECATED_useLexicalCharacterLimit.prod.js +8 -8
  7. package/DEPRECATED_useLexicalList.dev.js +6 -0
  8. package/DEPRECATED_useLexicalList.prod.js +1 -1
  9. package/DEPRECATED_useLexicalPlainText.dev.js +84 -75
  10. package/DEPRECATED_useLexicalPlainText.prod.js +15 -15
  11. package/DEPRECATED_useLexicalRichText.dev.js +96 -438
  12. package/DEPRECATED_useLexicalRichText.prod.js +17 -26
  13. package/LexicalAutoFormatterPlugin.d.ts +9 -0
  14. package/LexicalAutoFormatterPlugin.dev.js +83 -37
  15. package/LexicalAutoFormatterPlugin.js.flow +10 -0
  16. package/LexicalAutoFormatterPlugin.prod.js +21 -20
  17. package/LexicalAutoLinkPlugin.d.ts +20 -0
  18. package/LexicalAutoLinkPlugin.js.flow +23 -0
  19. package/LexicalCharacterLimitPlugin.d.ts +11 -0
  20. package/LexicalCharacterLimitPlugin.dev.js +20 -17
  21. package/LexicalCharacterLimitPlugin.js.flow +12 -0
  22. package/LexicalCharacterLimitPlugin.prod.js +9 -8
  23. package/LexicalClearEditorPlugin.d.ts +14 -0
  24. package/LexicalClearEditorPlugin.dev.js +73 -0
  25. package/LexicalClearEditorPlugin.js +9 -0
  26. package/LexicalClearEditorPlugin.js.flow +14 -0
  27. package/LexicalClearEditorPlugin.prod.js +8 -0
  28. package/LexicalCollaborationPlugin.d.ts +49 -0
  29. package/LexicalCollaborationPlugin.dev.js +21 -13
  30. package/LexicalCollaborationPlugin.js.flow +55 -0
  31. package/LexicalCollaborationPlugin.prod.js +7 -7
  32. package/LexicalComposer.d.ts +22 -0
  33. package/LexicalComposer.dev.js +32 -3
  34. package/LexicalComposer.js.flow +24 -0
  35. package/LexicalComposer.prod.js +3 -2
  36. package/LexicalComposerContext.d.ts +24 -0
  37. package/LexicalComposerContext.js.flow +27 -0
  38. package/LexicalContentEditable.d.ts +32 -0
  39. package/LexicalContentEditable.dev.js +35 -8
  40. package/LexicalContentEditable.js.flow +35 -0
  41. package/LexicalContentEditable.prod.js +3 -3
  42. package/LexicalHashtagPlugin.d.ts +9 -0
  43. package/LexicalHashtagPlugin.js.flow +10 -0
  44. package/LexicalHistoryPlugin.d.ts +29 -0
  45. package/LexicalHistoryPlugin.js.flow +34 -0
  46. package/LexicalHorizontalRuleNode.d.ts +23 -0
  47. package/LexicalHorizontalRuleNode.js.flow +25 -0
  48. package/LexicalLinkPlugin.d.ts +9 -0
  49. package/LexicalLinkPlugin.js.flow +10 -0
  50. package/LexicalListPlugin.d.ts +9 -0
  51. package/LexicalListPlugin.dev.js +6 -0
  52. package/LexicalListPlugin.js.flow +10 -0
  53. package/LexicalListPlugin.prod.js +2 -2
  54. package/LexicalNestedComposer.d.ts +17 -0
  55. package/LexicalNestedComposer.dev.js +21 -11
  56. package/LexicalNestedComposer.js.flow +18 -0
  57. package/LexicalNestedComposer.prod.js +3 -2
  58. package/LexicalOnChangePlugin.d.ts +12 -0
  59. package/LexicalOnChangePlugin.js.flow +14 -0
  60. package/LexicalPlainTextPlugin.d.ts +15 -0
  61. package/LexicalPlainTextPlugin.dev.js +73 -84
  62. package/LexicalPlainTextPlugin.js.flow +18 -0
  63. package/LexicalPlainTextPlugin.prod.js +12 -12
  64. package/LexicalRichTextPlugin.d.ts +15 -0
  65. package/LexicalRichTextPlugin.dev.js +85 -447
  66. package/LexicalRichTextPlugin.js.flow +18 -0
  67. package/LexicalRichTextPlugin.prod.js +13 -22
  68. package/LexicalTablePlugin.d.ts +9 -0
  69. package/LexicalTablePlugin.dev.js +22 -0
  70. package/LexicalTablePlugin.js.flow +10 -0
  71. package/LexicalTablePlugin.prod.js +4 -3
  72. package/LexicalTreeView.d.ts +17 -0
  73. package/LexicalTreeView.js.flow +19 -0
  74. package/README.md +0 -1
  75. package/package.json +9 -5
  76. package/useLexicalDecoratorMap.d.ts +14 -0
  77. package/useLexicalDecoratorMap.js.flow +16 -0
  78. package/useLexicalIsTextContentEmpty.d.ts +13 -0
  79. package/useLexicalIsTextContentEmpty.js.flow +15 -0
  80. package/useLexicalNodeSelection.d.ts +12 -0
  81. package/useLexicalNodeSelection.js.flow +14 -0
  82. package/withSubscriptions.d.ts +12 -0
  83. package/withSubscriptions.js.flow +13 -0
  84. package/LexicalBootstrapPlugin.dev.js +0 -122
  85. package/LexicalBootstrapPlugin.js +0 -9
  86. package/LexicalBootstrapPlugin.prod.js +0 -8
@@ -9,6 +9,7 @@
9
9
  var withSubscriptions = require('@lexical/react/withSubscriptions');
10
10
  var lexical = require('lexical');
11
11
  var react = require('react');
12
+ var clipboard = require('@lexical/clipboard');
12
13
 
13
14
  /**
14
15
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -347,188 +348,6 @@ function useLexicalHistory(editor, externalHistoryState, delay = 1000) {
347
348
  *
348
349
  */
349
350
 
350
- function $cloneWithProperties(node) {
351
- const latest = node.getLatest();
352
- const constructor = latest.constructor;
353
- const clone = constructor.clone(latest);
354
- clone.__parent = latest.__parent;
355
-
356
- if (lexical.$isElementNode(latest) && lexical.$isElementNode(clone)) {
357
- clone.__children = Array.from(latest.__children);
358
- clone.__format = latest.__format;
359
- clone.__indent = latest.__indent;
360
- clone.__dir = latest.__dir;
361
- } else if (lexical.$isTextNode(latest) && lexical.$isTextNode(clone)) {
362
- clone.__format = latest.__format;
363
- clone.__style = latest.__style;
364
- clone.__mode = latest.__mode;
365
- clone.__detail = latest.__detail;
366
- } else if (lexical.$isDecoratorNode(latest) && lexical.$isDecoratorNode(clone)) {
367
- clone.__state = latest.__state;
368
- } // $FlowFixMe
369
-
370
-
371
- return clone;
372
- }
373
-
374
- function $getIndexFromPossibleClone(node, parent, nodeMap) {
375
- const parentClone = nodeMap.get(parent.getKey());
376
-
377
- if (lexical.$isElementNode(parentClone)) {
378
- return parentClone.__children.indexOf(node.getKey());
379
- }
380
-
381
- return node.getIndexWithinParent();
382
- }
383
-
384
- function $getParentAvoidingExcludedElements(node) {
385
- let parent = node.getParent();
386
-
387
- while (parent !== null && parent.excludeFromCopy()) {
388
- parent = parent.getParent();
389
- }
390
-
391
- return parent;
392
- }
393
-
394
- function $copyLeafNodeBranchToRoot(leaf, startingOffset, isLeftSide, range, nodeMap) {
395
- let node = leaf;
396
- let offset = startingOffset;
397
-
398
- while (node !== null) {
399
- const parent = $getParentAvoidingExcludedElements(node);
400
-
401
- if (parent === null) {
402
- break;
403
- }
404
-
405
- if (!lexical.$isElementNode(node) || !node.excludeFromCopy()) {
406
- const key = node.getKey();
407
- let clone = nodeMap.get(key);
408
- const needsClone = clone === undefined;
409
-
410
- if (needsClone) {
411
- clone = $cloneWithProperties(node);
412
- nodeMap.set(key, clone);
413
- }
414
-
415
- if (lexical.$isTextNode(clone) && !clone.isSegmented() && !clone.isToken()) {
416
- clone.__text = clone.__text.slice(isLeftSide ? offset : 0, isLeftSide ? undefined : offset);
417
- } else if (lexical.$isElementNode(clone)) {
418
- clone.__children = clone.__children.slice(isLeftSide ? offset : 0, isLeftSide ? undefined : offset + 1);
419
- }
420
-
421
- if (lexical.$isRootNode(parent)) {
422
- if (needsClone) {
423
- // We only want to collect a range of top level nodes.
424
- // So if the parent is the root, we know this is a top level.
425
- range.push(key);
426
- }
427
-
428
- break;
429
- }
430
- }
431
-
432
- offset = $getIndexFromPossibleClone(node, parent, nodeMap);
433
- node = parent;
434
- }
435
- }
436
-
437
- function $cloneContents(selection) {
438
- if (!lexical.$isRangeSelection(selection)) {
439
- {
440
- throw Error(`TODO`);
441
- }
442
- }
443
-
444
- const anchor = selection.anchor;
445
- const focus = selection.focus;
446
- const anchorOffset = anchor.getCharacterOffset();
447
- const focusOffset = focus.getCharacterOffset();
448
- const anchorNode = anchor.getNode();
449
- const focusNode = focus.getNode();
450
- const anchorNodeParent = anchorNode.getParentOrThrow(); // Handle a single text node extraction
451
-
452
- if (anchorNode === focusNode && lexical.$isTextNode(anchorNode) && (anchorNodeParent.canBeEmpty() || anchorNodeParent.getChildrenSize() > 1)) {
453
- const clonedFirstNode = $cloneWithProperties(anchorNode);
454
- const isBefore = focusOffset > anchorOffset;
455
- const startOffset = isBefore ? anchorOffset : focusOffset;
456
- const endOffset = isBefore ? focusOffset : anchorOffset;
457
- clonedFirstNode.__text = clonedFirstNode.__text.slice(startOffset, endOffset);
458
- const key = clonedFirstNode.getKey();
459
- return {
460
- nodeMap: [[key, clonedFirstNode]],
461
- range: [key]
462
- };
463
- }
464
-
465
- const nodes = selection.getNodes();
466
-
467
- if (nodes.length === 0) {
468
- return {
469
- nodeMap: [],
470
- range: []
471
- };
472
- } // Check if we can use the parent of the nodes, if the
473
- // parent can't be empty, then it's important that we
474
- // also copy that element node along with its children.
475
-
476
-
477
- let nodesLength = nodes.length;
478
- const firstNode = nodes[0];
479
- const firstNodeParent = firstNode.getParent();
480
-
481
- if (firstNodeParent !== null && (!firstNodeParent.canBeEmpty() || lexical.$isRootNode(firstNodeParent))) {
482
- const parentChildren = firstNodeParent.__children;
483
- const parentChildrenLength = parentChildren.length;
484
-
485
- if (parentChildrenLength === nodesLength) {
486
- let areTheSame = true;
487
-
488
- for (let i = 0; i < parentChildren.length; i++) {
489
- if (parentChildren[i] !== nodes[i].__key) {
490
- areTheSame = false;
491
- break;
492
- }
493
- }
494
-
495
- if (areTheSame) {
496
- nodesLength++;
497
- nodes.push(firstNodeParent);
498
- }
499
- }
500
- }
501
-
502
- const lastNode = nodes[nodesLength - 1];
503
- const isBefore = anchor.isBefore(focus);
504
- const nodeMap = new Map();
505
- const range = []; // Do first node to root
506
-
507
- $copyLeafNodeBranchToRoot(firstNode, isBefore ? anchorOffset : focusOffset, true, range, nodeMap); // Copy all nodes between
508
-
509
- for (let i = 0; i < nodesLength; i++) {
510
- const node = nodes[i];
511
- const key = node.getKey();
512
-
513
- if (!nodeMap.has(key) && (!lexical.$isElementNode(node) || !node.excludeFromCopy())) {
514
- const clone = $cloneWithProperties(node);
515
-
516
- if (lexical.$isRootNode(node.getParent())) {
517
- range.push(node.getKey());
518
- }
519
-
520
- nodeMap.set(key, clone);
521
- }
522
- } // Do last node to root
523
-
524
-
525
- $copyLeafNodeBranchToRoot(lastNode, isBefore ? focusOffset : anchorOffset, false, range, nodeMap);
526
- return {
527
- nodeMap: Array.from(nodeMap.entries()),
528
- range
529
- };
530
- }
531
-
532
351
  function $moveCaretSelection(selection, isHoldingShift, isBackward, granularity) {
533
352
  selection.modify(isHoldingShift ? 'extend' : 'move', isBackward, granularity);
534
353
  }
@@ -541,6 +360,10 @@ function $moveCharacter(selection, isHoldingShift, isBackward) {
541
360
  const isRTL = $isParentElementRTL(selection);
542
361
  $moveCaretSelection(selection, isHoldingShift, isBackward ? !isRTL : isRTL, 'character');
543
362
  }
363
+ function $shouldOverrideDefaultCharacterSelection(selection, isBackward) {
364
+ const possibleNode = lexical.$getDecoratorNode(selection.focus, isBackward);
365
+ return lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated();
366
+ }
544
367
 
545
368
  /**
546
369
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -550,46 +373,7 @@ function $moveCharacter(selection, isHoldingShift, isBackward) {
550
373
  *
551
374
  *
552
375
  */
553
- function resolveElement(element, isBackward, focusOffset) {
554
- const parent = element.getParent();
555
- let offset = focusOffset;
556
- let block = element;
557
-
558
- if (parent !== null) {
559
- if (isBackward && focusOffset === 0) {
560
- offset = block.getIndexWithinParent();
561
- block = parent;
562
- } else if (!isBackward && focusOffset === block.getChildrenSize()) {
563
- offset = block.getIndexWithinParent() + 1;
564
- block = parent;
565
- }
566
- }
567
-
568
- return block.getChildAtIndex(isBackward ? offset - 1 : offset);
569
- }
570
-
571
- function getPossibleDecoratorNode(focus, isBackward) {
572
- const focusOffset = focus.offset;
573
-
574
- if (focus.type === 'element') {
575
- const block = focus.getNode();
576
- return resolveElement(block, isBackward, focusOffset);
577
- } else {
578
- const focusNode = focus.getNode();
579
-
580
- if (isBackward && focusOffset === 0 || !isBackward && focusOffset === focusNode.getTextContentSize()) {
581
- const possibleNode = isBackward ? focusNode.getPreviousSibling() : focusNode.getNextSibling();
582
-
583
- if (possibleNode === null) {
584
- return resolveElement(focusNode.getParentOrThrow(), isBackward, focusNode.getIndexWithinParent() + (isBackward ? 0 : 1));
585
- }
586
-
587
- return possibleNode;
588
- }
589
- }
590
-
591
- return null;
592
- }
376
+ const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
593
377
 
594
378
  /**
595
379
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -599,185 +383,50 @@ function getPossibleDecoratorNode(focus, isBackward) {
599
383
  *
600
384
  *
601
385
  */
386
+ const useLayoutEffectImpl = CAN_USE_DOM ? react.useLayoutEffect : react.useEffect;
387
+ var useLayoutEffect = useLayoutEffectImpl;
602
388
 
603
- function $generateNodes(nodeRange) {
604
- const {
605
- range,
606
- nodeMap
607
- } = nodeRange;
608
- const parsedNodeMap = new Map(nodeMap);
609
- const nodes = [];
610
-
611
- for (let i = 0; i < range.length; i++) {
612
- const key = range[i];
613
- const parsedNode = parsedNodeMap.get(key);
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();
614
401
 
615
- if (parsedNode !== undefined) {
616
- const node = lexical.$createNodeFromParse(parsedNode, parsedNodeMap);
617
- nodes.push(node);
402
+ if (lexical.$isRangeSelection(selection)) {
403
+ selection.removeText();
618
404
  }
619
- }
620
-
621
- return nodes;
405
+ });
622
406
  }
407
+ function onCopyForRichText(event, editor) {
408
+ event.preventDefault();
409
+ editor.update(() => {
410
+ const clipboardData = event.clipboardData;
411
+ const selection = lexical.$getSelection();
623
412
 
624
- function getConversionFunction(domNode, editor) {
625
- const {
626
- nodeName
627
- } = domNode;
628
-
629
- const cachedConversions = editor._htmlConversions.get(nodeName.toLowerCase());
630
-
631
- let currentConversion = null;
632
-
633
- if (cachedConversions !== undefined) {
634
- cachedConversions.forEach(cachedConversion => {
635
- const domConversion = cachedConversion(domNode);
413
+ if (selection !== null) {
414
+ if (clipboardData != null) {
415
+ const htmlString = clipboard.getHtmlContent(editor);
416
+ const lexicalString = clipboard.$getLexicalContent(editor);
636
417
 
637
- if (domConversion !== null) {
638
- if (currentConversion === null || currentConversion.priority < domConversion.priority) {
639
- currentConversion = domConversion;
418
+ if (htmlString !== null) {
419
+ clipboardData.setData('text/html', htmlString);
640
420
  }
641
- }
642
- });
643
- }
644
-
645
- return currentConversion !== null ? currentConversion.conversion : null;
646
- }
647
-
648
- function $createNodesFromDOM(node, editor, forChildMap = new Map()) {
649
- let lexicalNodes = [];
650
- let currentLexicalNode = null;
651
- const transformFunction = getConversionFunction(node, editor);
652
- const transformOutput = transformFunction ? transformFunction(node) : null;
653
- let postTransform = null;
654
-
655
- if (transformOutput !== null) {
656
- postTransform = transformOutput.after;
657
- currentLexicalNode = transformOutput.node;
658
-
659
- if (currentLexicalNode !== null) {
660
- lexicalNodes.push(currentLexicalNode);
661
- const forChildFunctions = Array.from(forChildMap.values());
662
-
663
- for (let i = 0; i < forChildFunctions.length; i++) {
664
- forChildFunctions[i](currentLexicalNode);
665
- }
666
- }
667
-
668
- if (transformOutput.forChild != null) {
669
- forChildMap.set(node.nodeName, transformOutput.forChild);
670
- }
671
- } // If the DOM node doesn't have a transformer, we don't know what
672
- // to do with it but we still need to process any childNodes.
673
-
674
-
675
- const children = node.childNodes;
676
- let childLexicalNodes = [];
677
-
678
- for (let i = 0; i < children.length; i++) {
679
- childLexicalNodes.push(...$createNodesFromDOM(children[i], editor, forChildMap));
680
- }
681
-
682
- if (postTransform != null) {
683
- childLexicalNodes = postTransform(childLexicalNodes);
684
- }
685
-
686
- if (currentLexicalNode == null) {
687
- // If it hasn't been converted to a LexicalNode, we hoist its children
688
- // up to the same level as it.
689
- lexicalNodes = lexicalNodes.concat(childLexicalNodes);
690
- } else {
691
- if (lexical.$isElementNode(currentLexicalNode)) {
692
- // If the current node is a ElementNode after conversion,
693
- // we can append all the children to it.
694
- currentLexicalNode.append(...childLexicalNodes);
695
- }
696
- }
697
-
698
- return lexicalNodes;
699
- }
700
-
701
- function $generateNodesFromDOM(dom, editor) {
702
- let lexicalNodes = [];
703
- const elements = dom.body ? Array.from(dom.body.childNodes) : [];
704
- const elementsLength = elements.length;
705
-
706
- for (let i = 0; i < elementsLength; i++) {
707
- const lexicalNode = $createNodesFromDOM(elements[i], editor);
708
-
709
- if (lexicalNode !== null) {
710
- lexicalNodes = lexicalNodes.concat(lexicalNode);
711
- }
712
- }
713
-
714
- return lexicalNodes;
715
- }
716
-
717
- function $insertDataTransferForRichText(dataTransfer, selection, editor) {
718
- const lexicalNodesString = dataTransfer.getData('application/x-lexical-editor');
719
-
720
- if (lexicalNodesString) {
721
- const namespace = editor._config.namespace;
722
-
723
- try {
724
- const lexicalClipboardData = JSON.parse(lexicalNodesString);
725
421
 
726
- if (lexicalClipboardData.namespace === namespace) {
727
- const nodeRange = lexicalClipboardData.state;
728
- const nodes = $generateNodes(nodeRange);
729
- selection.insertNodes(nodes);
730
- return;
731
- }
732
- } catch (e) {// Malformed, missing nodes..
733
- }
734
- }
735
-
736
- const textHtmlMimeType = 'text/html';
737
- const htmlString = dataTransfer.getData(textHtmlMimeType);
738
-
739
- if (htmlString) {
740
- const parser = new DOMParser();
741
- const dom = parser.parseFromString(htmlString, textHtmlMimeType);
742
- const nodes = $generateNodesFromDOM(dom, editor); // Wrap text and inline nodes in paragraph nodes so we have all blocks at the top-level
743
-
744
- const topLevelBlocks = [];
745
- let currentBlock = null;
746
-
747
- for (let i = 0; i < nodes.length; i++) {
748
- const node = nodes[i];
749
-
750
- if (!lexical.$isElementNode(node) || node.isInline()) {
751
- if (currentBlock === null) {
752
- currentBlock = lexical.$createParagraphNode();
753
- topLevelBlocks.push(currentBlock);
422
+ if (lexicalString !== null) {
423
+ clipboardData.setData('application/x-lexical-editor', lexicalString);
754
424
  }
755
425
 
756
- if (currentBlock !== null) {
757
- currentBlock.append(node);
758
- }
759
- } else {
760
- topLevelBlocks.push(node);
761
- currentBlock = null;
426
+ clipboardData.setData('text/plain', selection.getTextContent());
762
427
  }
763
428
  }
764
-
765
- selection.insertNodes(topLevelBlocks);
766
- return;
767
- }
768
-
769
- $insertDataTransferForPlainText(dataTransfer, selection);
770
- }
771
- function $insertDataTransferForPlainText(dataTransfer, selection) {
772
- const text = dataTransfer.getData('text/plain');
773
-
774
- if (text != null) {
775
- selection.insertRawText(text);
776
- }
777
- }
778
- function $shouldOverrideDefaultCharacterSelection(selection, isBackward) {
779
- const possibleNode = getPossibleDecoratorNode(selection.focus, isBackward);
780
- return lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated();
429
+ });
781
430
  }
782
431
  function onPasteForRichText(event, editor) {
783
432
  event.preventDefault();
@@ -786,52 +435,65 @@ function onPasteForRichText(event, editor) {
786
435
  const clipboardData = event.clipboardData;
787
436
 
788
437
  if (clipboardData != null && lexical.$isRangeSelection(selection)) {
789
- $insertDataTransferForRichText(clipboardData, selection, editor);
790
- }
791
- });
792
- }
793
- function onCutForRichText(event, editor) {
794
- onCopyForRichText(event, editor);
795
- editor.update(() => {
796
- const selection = lexical.$getSelection();
797
-
798
- if (lexical.$isRangeSelection(selection)) {
799
- selection.removeText();
438
+ clipboard.$insertDataTransferForRichText(clipboardData, selection, editor);
800
439
  }
801
440
  });
802
441
  }
803
- function onCopyForRichText(event, editor) {
804
- event.preventDefault();
805
- editor.update(() => {
806
- const clipboardData = event.clipboardData;
807
- const selection = lexical.$getSelection();
808
-
809
- if (selection !== null) {
810
- if (clipboardData != null) {
811
- const domSelection = window.getSelection(); // If we haven't selected a range, then don't copy anything
812
442
 
813
- if (domSelection.isCollapsed) {
814
- return;
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;
815
482
  }
816
483
 
817
- const range = domSelection.getRangeAt(0);
818
-
819
- if (range) {
820
- const container = document.createElement('div');
821
- const frag = range.cloneContents();
822
- container.appendChild(frag);
823
- clipboardData.setData('text/html', container.innerHTML);
484
+ case 'object':
485
+ {
486
+ editor.setEditorState(initialEditorState, setEditorOptions);
487
+ break;
824
488
  }
825
489
 
826
- clipboardData.setData('text/plain', selection.getTextContent());
827
- const namespace = editor._config.namespace;
828
- clipboardData.setData('application/x-lexical-editor', JSON.stringify({
829
- namespace,
830
- state: $cloneContents(selection)
831
- }));
832
- }
490
+ case 'function':
491
+ {
492
+ editor.update(initialEditorState, updateOptions);
493
+ break;
494
+ }
833
495
  }
834
- });
496
+ }
835
497
  }
836
498
 
837
499
  /**
@@ -930,8 +592,8 @@ function useLexicalDragonSupport(editor) {
930
592
  *
931
593
  *
932
594
  */
933
- function useRichTextSetup(editor) {
934
- react.useEffect(() => {
595
+ function useRichTextSetup(editor, initialEditorState) {
596
+ useLayoutEffect(() => {
935
597
  const removeListener = editor.addListener('command', (type, payload) => {
936
598
  const selection = lexical.$getSelection();
937
599
 
@@ -976,7 +638,7 @@ function useRichTextSetup(editor) {
976
638
  const dataTransfer = eventOrText.dataTransfer;
977
639
 
978
640
  if (dataTransfer != null) {
979
- $insertDataTransferForRichText(dataTransfer, selection, editor);
641
+ clipboard.$insertDataTransferForRichText(dataTransfer, selection, editor);
980
642
  } else {
981
643
  const data = eventOrText.data;
982
644
 
@@ -1170,13 +832,9 @@ function useRichTextSetup(editor) {
1170
832
 
1171
833
  return false;
1172
834
  }, 0);
1173
- const bootstrapCommandHandled = editor.execCommand('bootstrapEditor');
1174
-
1175
- if (!bootstrapCommandHandled) {
1176
- console.warn('bootstrapEditor command was not handled. Did you forget to add <BootstrapPlugin />?');
1177
- }
1178
-
1179
- return removeListener;
835
+ initializeEditor(editor, initialEditorState);
836
+ return removeListener; // We only do this for init
837
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1180
838
  }, [editor]);
1181
839
  useLexicalDragonSupport(editor);
1182
840
  }
@@ -1189,8 +847,8 @@ function useRichTextSetup(editor) {
1189
847
  *
1190
848
  *
1191
849
  */
1192
- function useLexicalRichText(editor, externalHistoryState) {
1193
- useRichTextSetup(editor);
850
+ function useLexicalRichText(editor, externalHistoryState, initialEditorState) {
851
+ useRichTextSetup(editor, initialEditorState);
1194
852
  useLexicalHistory(editor, externalHistoryState);
1195
853
  }
1196
854