lexical 0.12.4 → 0.12.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Lexical.dev.js +211 -102
- package/Lexical.js.flow +58 -30
- package/Lexical.prod.js +162 -158
- package/LexicalEditorState.d.ts +4 -4
- package/LexicalNode.d.ts +12 -2
- package/LexicalSelection.d.ts +60 -37
- package/LexicalUtils.d.ts +4 -4
- package/index.d.ts +2 -2
- package/nodes/LexicalDecoratorNode.d.ts +3 -0
- package/nodes/LexicalElementNode.d.ts +2 -2
- package/nodes/LexicalTextNode.d.ts +6 -3
- package/package.json +1 -1
package/Lexical.dev.js
CHANGED
|
@@ -583,16 +583,16 @@ function getDOMTextNode(element) {
|
|
|
583
583
|
}
|
|
584
584
|
function toggleTextFormatType(format, type, alignWithFormat) {
|
|
585
585
|
const activeFormat = TEXT_TYPE_TO_FORMAT[type];
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
// Remove the state flag.
|
|
589
|
-
return format ^ activeFormat;
|
|
586
|
+
if (alignWithFormat !== null && (format & activeFormat) === (alignWithFormat & activeFormat)) {
|
|
587
|
+
return format;
|
|
590
588
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
589
|
+
let newFormat = format ^ activeFormat;
|
|
590
|
+
if (type === 'subscript') {
|
|
591
|
+
newFormat &= ~TEXT_TYPE_TO_FORMAT.superscript;
|
|
592
|
+
} else if (type === 'superscript') {
|
|
593
|
+
newFormat &= ~TEXT_TYPE_TO_FORMAT.subscript;
|
|
594
594
|
}
|
|
595
|
-
return
|
|
595
|
+
return newFormat;
|
|
596
596
|
}
|
|
597
597
|
function $isLeafNode(node) {
|
|
598
598
|
return $isTextNode(node) || $isLineBreakNode(node) || $isDecoratorNode(node);
|
|
@@ -816,7 +816,7 @@ function $setSelection(selection) {
|
|
|
816
816
|
}
|
|
817
817
|
}
|
|
818
818
|
selection.dirty = true;
|
|
819
|
-
selection.
|
|
819
|
+
selection.setCachedNodes(null);
|
|
820
820
|
}
|
|
821
821
|
editorState._selection = selection;
|
|
822
822
|
}
|
|
@@ -2357,6 +2357,8 @@ function onSelectionChange(domSelection, editor, isActive) {
|
|
|
2357
2357
|
const windowEvent = getWindow(editor).event;
|
|
2358
2358
|
const currentTimeStamp = windowEvent ? windowEvent.timeStamp : performance.now();
|
|
2359
2359
|
const [lastFormat, lastStyle, lastOffset, lastKey, timeStamp] = collapsedSelectionFormat;
|
|
2360
|
+
const root = $getRoot();
|
|
2361
|
+
const isRootTextContentEmpty = editor.isComposing() === false && root.getTextContent() === '';
|
|
2360
2362
|
if (currentTimeStamp < timeStamp + 200 && anchor.offset === lastOffset && anchor.key === lastKey) {
|
|
2361
2363
|
selection.format = lastFormat;
|
|
2362
2364
|
selection.style = lastStyle;
|
|
@@ -2364,7 +2366,7 @@ function onSelectionChange(domSelection, editor, isActive) {
|
|
|
2364
2366
|
if (anchor.type === 'text') {
|
|
2365
2367
|
selection.format = anchorNode.getFormat();
|
|
2366
2368
|
selection.style = anchorNode.getStyle();
|
|
2367
|
-
} else if (anchor.type === 'element') {
|
|
2369
|
+
} else if (anchor.type === 'element' && !isRootTextContentEmpty) {
|
|
2368
2370
|
selection.format = 0;
|
|
2369
2371
|
selection.style = '';
|
|
2370
2372
|
}
|
|
@@ -2521,6 +2523,11 @@ function onBeforeInput(event, editor) {
|
|
|
2521
2523
|
selection.format = anchorNode.getFormat();
|
|
2522
2524
|
selection.style = anchorNode.getStyle();
|
|
2523
2525
|
}
|
|
2526
|
+
const selectedText = selection.anchor.getNode().getTextContent();
|
|
2527
|
+
if (selectedText.length <= 1) {
|
|
2528
|
+
event.preventDefault();
|
|
2529
|
+
dispatchCommand(editor, DELETE_CHARACTER_COMMAND, true);
|
|
2530
|
+
}
|
|
2524
2531
|
} else {
|
|
2525
2532
|
event.preventDefault();
|
|
2526
2533
|
dispatchCommand(editor, DELETE_CHARACTER_COMMAND, true);
|
|
@@ -3646,8 +3653,8 @@ class LexicalNode {
|
|
|
3646
3653
|
const parent = latestNode.__parent;
|
|
3647
3654
|
const cloneNotNeeded = editor._cloneNotNeeded;
|
|
3648
3655
|
const selection = $getSelection();
|
|
3649
|
-
if (selection
|
|
3650
|
-
selection.
|
|
3656
|
+
if ($INTERNAL_isPointSelection(selection)) {
|
|
3657
|
+
selection.setCachedNodes(null);
|
|
3651
3658
|
}
|
|
3652
3659
|
if (cloneNotNeeded.has(key)) {
|
|
3653
3660
|
// Transforms clear the dirty node set on each iteration to keep track on newly dirty nodes
|
|
@@ -3977,6 +3984,12 @@ class LexicalNode {
|
|
|
3977
3984
|
createParentElementNode() {
|
|
3978
3985
|
return $createParagraphNode();
|
|
3979
3986
|
}
|
|
3987
|
+
selectStart() {
|
|
3988
|
+
return this.selectPrevious();
|
|
3989
|
+
}
|
|
3990
|
+
selectEnd() {
|
|
3991
|
+
return this.selectNext(0, 0);
|
|
3992
|
+
}
|
|
3980
3993
|
|
|
3981
3994
|
/**
|
|
3982
3995
|
* Moves selection to the previous sibling of this node, at the specified offsets.
|
|
@@ -4047,6 +4060,32 @@ function errorOnTypeKlassMismatch(type, klass) {
|
|
|
4047
4060
|
}
|
|
4048
4061
|
}
|
|
4049
4062
|
|
|
4063
|
+
/**
|
|
4064
|
+
* Insert a series of nodes after this LexicalNode (as next siblings)
|
|
4065
|
+
*
|
|
4066
|
+
* @param firstToInsert - The first node to insert after this one.
|
|
4067
|
+
* @param lastToInsert - The last node to insert after this one. Must be a
|
|
4068
|
+
* later sibling of FirstNode. If not provided, it will be its last sibling.
|
|
4069
|
+
*/
|
|
4070
|
+
function insertRangeAfter(node, firstToInsert, lastToInsert) {
|
|
4071
|
+
const lastToInsert2 = lastToInsert || firstToInsert.getParentOrThrow().getLastChild();
|
|
4072
|
+
let current = firstToInsert;
|
|
4073
|
+
const nodesToInsert = [firstToInsert];
|
|
4074
|
+
while (current !== lastToInsert2) {
|
|
4075
|
+
if (!current.getNextSibling()) {
|
|
4076
|
+
{
|
|
4077
|
+
throw Error(`insertRangeAfter: lastToInsert must be a later sibling of firstToInsert`);
|
|
4078
|
+
}
|
|
4079
|
+
}
|
|
4080
|
+
current = current.getNextSibling();
|
|
4081
|
+
nodesToInsert.push(current);
|
|
4082
|
+
}
|
|
4083
|
+
let currentNode = node;
|
|
4084
|
+
for (const nodeToInsert of nodesToInsert) {
|
|
4085
|
+
currentNode = currentNode.insertAfter(nodeToInsert);
|
|
4086
|
+
}
|
|
4087
|
+
}
|
|
4088
|
+
|
|
4050
4089
|
/**
|
|
4051
4090
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4052
4091
|
*
|
|
@@ -4635,7 +4674,8 @@ class TextNode extends LexicalNode {
|
|
|
4635
4674
|
}
|
|
4636
4675
|
|
|
4637
4676
|
/**
|
|
4638
|
-
* Applies the provided format to this TextNode if it's not present. Removes it if it
|
|
4677
|
+
* Applies the provided format to this TextNode if it's not present. Removes it if it's present.
|
|
4678
|
+
* The subscript and superscript formats are mutually exclusive.
|
|
4639
4679
|
* Prefer using this method to turn specific formats on and off.
|
|
4640
4680
|
*
|
|
4641
4681
|
* @param type - TextFormatType to toggle.
|
|
@@ -4643,8 +4683,9 @@ class TextNode extends LexicalNode {
|
|
|
4643
4683
|
* @returns this TextNode.
|
|
4644
4684
|
*/
|
|
4645
4685
|
toggleFormat(type) {
|
|
4646
|
-
const
|
|
4647
|
-
|
|
4686
|
+
const format = this.getFormat();
|
|
4687
|
+
const newFormat = toggleTextFormatType(format, type, null);
|
|
4688
|
+
return this.setFormat(newFormat);
|
|
4648
4689
|
}
|
|
4649
4690
|
|
|
4650
4691
|
/**
|
|
@@ -4738,6 +4779,13 @@ class TextNode extends LexicalNode {
|
|
|
4738
4779
|
}
|
|
4739
4780
|
return selection;
|
|
4740
4781
|
}
|
|
4782
|
+
selectStart() {
|
|
4783
|
+
return this.select(0, 0);
|
|
4784
|
+
}
|
|
4785
|
+
selectEnd() {
|
|
4786
|
+
const size = this.getTextContentSize();
|
|
4787
|
+
return this.select(size, size);
|
|
4788
|
+
}
|
|
4741
4789
|
|
|
4742
4790
|
/**
|
|
4743
4791
|
* Inserts the provided text into this TextNode at the provided offset, deleting the number of characters
|
|
@@ -5293,7 +5341,7 @@ class Point {
|
|
|
5293
5341
|
$setCompositionKey(key);
|
|
5294
5342
|
}
|
|
5295
5343
|
if (selection !== null) {
|
|
5296
|
-
selection.
|
|
5344
|
+
selection.setCachedNodes(null);
|
|
5297
5345
|
selection.dirty = true;
|
|
5298
5346
|
}
|
|
5299
5347
|
}
|
|
@@ -5364,12 +5412,68 @@ function $setPointValues(point, key, offset, type) {
|
|
|
5364
5412
|
point.offset = offset;
|
|
5365
5413
|
point.type = type;
|
|
5366
5414
|
}
|
|
5415
|
+
/**
|
|
5416
|
+
* This class is being used only for internal use case of migration GridSelection outside of core package.
|
|
5417
|
+
* DO NOT USE THIS CLASS DIRECTLY.
|
|
5418
|
+
*/
|
|
5419
|
+
class INTERNAL_PointSelection {
|
|
5420
|
+
constructor(anchor, focus) {
|
|
5421
|
+
this.anchor = anchor;
|
|
5422
|
+
this.focus = focus;
|
|
5423
|
+
anchor._selection = this;
|
|
5424
|
+
focus._selection = this;
|
|
5425
|
+
this._cachedNodes = null;
|
|
5426
|
+
this.dirty = false;
|
|
5427
|
+
}
|
|
5428
|
+
getCachedNodes() {
|
|
5429
|
+
return this._cachedNodes;
|
|
5430
|
+
}
|
|
5431
|
+
setCachedNodes(nodes) {
|
|
5432
|
+
this._cachedNodes = nodes;
|
|
5433
|
+
}
|
|
5434
|
+
is(selection) {
|
|
5435
|
+
if (!$INTERNAL_isPointSelection(selection)) {
|
|
5436
|
+
return false;
|
|
5437
|
+
}
|
|
5438
|
+
return this.anchor.is(selection.anchor) && this.focus.is(selection.focus);
|
|
5439
|
+
}
|
|
5440
|
+
isCollapsed() {
|
|
5441
|
+
return false;
|
|
5442
|
+
}
|
|
5443
|
+
extract() {
|
|
5444
|
+
return this.getNodes();
|
|
5445
|
+
}
|
|
5446
|
+
/**
|
|
5447
|
+
* Returns whether the Selection is "backwards", meaning the focus
|
|
5448
|
+
* logically precedes the anchor in the EditorState.
|
|
5449
|
+
* @returns true if the Selection is backwards, false otherwise.
|
|
5450
|
+
*/
|
|
5451
|
+
isBackward() {
|
|
5452
|
+
return this.focus.isBefore(this.anchor);
|
|
5453
|
+
}
|
|
5454
|
+
|
|
5455
|
+
/**
|
|
5456
|
+
* Returns the character-based offsets of the Selection, accounting for non-text Points
|
|
5457
|
+
* by using the children size or text content.
|
|
5458
|
+
*
|
|
5459
|
+
* @returns the character offsets for the Selection
|
|
5460
|
+
*/
|
|
5461
|
+
getCharacterOffsets() {
|
|
5462
|
+
return getCharacterOffsets(this);
|
|
5463
|
+
}
|
|
5464
|
+
}
|
|
5367
5465
|
class NodeSelection {
|
|
5368
5466
|
constructor(objects) {
|
|
5369
5467
|
this.dirty = false;
|
|
5370
5468
|
this._nodes = objects;
|
|
5371
5469
|
this._cachedNodes = null;
|
|
5372
5470
|
}
|
|
5471
|
+
getCachedNodes() {
|
|
5472
|
+
return this._cachedNodes;
|
|
5473
|
+
}
|
|
5474
|
+
setCachedNodes(nodes) {
|
|
5475
|
+
this._cachedNodes = nodes;
|
|
5476
|
+
}
|
|
5373
5477
|
is(selection) {
|
|
5374
5478
|
if (!$isNodeSelection(selection)) {
|
|
5375
5479
|
return false;
|
|
@@ -5456,6 +5560,9 @@ class NodeSelection {
|
|
|
5456
5560
|
function $isRangeSelection(x) {
|
|
5457
5561
|
return x instanceof RangeSelection;
|
|
5458
5562
|
}
|
|
5563
|
+
function $INTERNAL_isPointSelection(x) {
|
|
5564
|
+
return x instanceof INTERNAL_PointSelection;
|
|
5565
|
+
}
|
|
5459
5566
|
function DEPRECATED_$getGridCellNodeRect(GridCellNode) {
|
|
5460
5567
|
const [CellNode,, GridNode] = DEPRECATED_$getNodeTriplet(GridCellNode);
|
|
5461
5568
|
const rows = GridNode.getChildren();
|
|
@@ -5501,15 +5608,16 @@ function DEPRECATED_$getGridCellNodeRect(GridCellNode) {
|
|
|
5501
5608
|
}
|
|
5502
5609
|
return null;
|
|
5503
5610
|
}
|
|
5504
|
-
class GridSelection {
|
|
5611
|
+
class GridSelection extends INTERNAL_PointSelection {
|
|
5505
5612
|
constructor(gridKey, anchor, focus) {
|
|
5613
|
+
super(anchor, focus);
|
|
5506
5614
|
this.gridKey = gridKey;
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
this.
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5615
|
+
}
|
|
5616
|
+
getCachedNodes() {
|
|
5617
|
+
return this._cachedNodes;
|
|
5618
|
+
}
|
|
5619
|
+
setCachedNodes(nodes) {
|
|
5620
|
+
this._cachedNodes = nodes;
|
|
5513
5621
|
}
|
|
5514
5622
|
is(selection) {
|
|
5515
5623
|
if (!DEPRECATED_$isGridSelection(selection)) {
|
|
@@ -5530,12 +5638,6 @@ class GridSelection {
|
|
|
5530
5638
|
isCollapsed() {
|
|
5531
5639
|
return false;
|
|
5532
5640
|
}
|
|
5533
|
-
isBackward() {
|
|
5534
|
-
return this.focus.isBefore(this.anchor);
|
|
5535
|
-
}
|
|
5536
|
-
getCharacterOffsets() {
|
|
5537
|
-
return getCharacterOffsets(this);
|
|
5538
|
-
}
|
|
5539
5641
|
extract() {
|
|
5540
5642
|
return this.getNodes();
|
|
5541
5643
|
}
|
|
@@ -5721,16 +5823,17 @@ class GridSelection {
|
|
|
5721
5823
|
function DEPRECATED_$isGridSelection(x) {
|
|
5722
5824
|
return x instanceof GridSelection;
|
|
5723
5825
|
}
|
|
5724
|
-
class RangeSelection {
|
|
5826
|
+
class RangeSelection extends INTERNAL_PointSelection {
|
|
5725
5827
|
constructor(anchor, focus, format, style) {
|
|
5726
|
-
|
|
5727
|
-
this.focus = focus;
|
|
5728
|
-
this.dirty = false;
|
|
5828
|
+
super(anchor, focus);
|
|
5729
5829
|
this.format = format;
|
|
5730
5830
|
this.style = style;
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5831
|
+
}
|
|
5832
|
+
getCachedNodes() {
|
|
5833
|
+
return this._cachedNodes;
|
|
5834
|
+
}
|
|
5835
|
+
setCachedNodes(nodes) {
|
|
5836
|
+
this._cachedNodes = nodes;
|
|
5734
5837
|
}
|
|
5735
5838
|
|
|
5736
5839
|
/**
|
|
@@ -5746,15 +5849,6 @@ class RangeSelection {
|
|
|
5746
5849
|
return this.anchor.is(selection.anchor) && this.focus.is(selection.focus) && this.format === selection.format && this.style === selection.style;
|
|
5747
5850
|
}
|
|
5748
5851
|
|
|
5749
|
-
/**
|
|
5750
|
-
* Returns whether the Selection is "backwards", meaning the focus
|
|
5751
|
-
* logically precedes the anchor in the EditorState.
|
|
5752
|
-
* @returns true if the Selection is backwards, false otherwise.
|
|
5753
|
-
*/
|
|
5754
|
-
isBackward() {
|
|
5755
|
-
return this.focus.isBefore(this.anchor);
|
|
5756
|
-
}
|
|
5757
|
-
|
|
5758
5852
|
/**
|
|
5759
5853
|
* Returns whether the Selection is "collapsed", meaning the anchor and focus are
|
|
5760
5854
|
* the same node and have the same offset.
|
|
@@ -6372,53 +6466,59 @@ class RangeSelection {
|
|
|
6372
6466
|
return selection.insertNodes(nodes);
|
|
6373
6467
|
}
|
|
6374
6468
|
const firstBlock = $getAncestor(this.anchor.getNode(), INTERNAL_$isBlock);
|
|
6469
|
+
const last = nodes[nodes.length - 1];
|
|
6375
6470
|
|
|
6376
|
-
//
|
|
6471
|
+
// CASE 1: insert inside a code block
|
|
6377
6472
|
if ('__language' in firstBlock) {
|
|
6378
6473
|
if ('__language' in nodes[0]) {
|
|
6379
6474
|
this.insertText(nodes[0].getTextContent());
|
|
6380
6475
|
} else {
|
|
6381
6476
|
const index = removeTextAndSplitBlock(this);
|
|
6382
6477
|
firstBlock.splice(index, 0, nodes);
|
|
6383
|
-
|
|
6384
|
-
if (last.select) {
|
|
6385
|
-
last.select();
|
|
6386
|
-
} else last.selectNext(0, 0);
|
|
6478
|
+
last.selectEnd();
|
|
6387
6479
|
}
|
|
6388
6480
|
return;
|
|
6389
6481
|
}
|
|
6482
|
+
|
|
6483
|
+
// CASE 2: All elements of the array are inline
|
|
6390
6484
|
const notInline = node => ($isElementNode(node) || $isDecoratorNode(node)) && !node.isInline();
|
|
6391
|
-
|
|
6392
|
-
|
|
6485
|
+
if (!nodes.some(notInline)) {
|
|
6486
|
+
const index = removeTextAndSplitBlock(this);
|
|
6487
|
+
firstBlock.splice(index, 0, nodes);
|
|
6488
|
+
last.selectEnd();
|
|
6489
|
+
return;
|
|
6490
|
+
}
|
|
6491
|
+
|
|
6492
|
+
// CASE 3: At least 1 element of the array is not inline
|
|
6493
|
+
const blocksParent = $wrapInlineNodes(nodes);
|
|
6494
|
+
const nodeToSelect = blocksParent.getLastDescendant();
|
|
6495
|
+
const blocks = blocksParent.getChildren();
|
|
6496
|
+
const isLI = node => '__value' in node && '__checked' in node;
|
|
6497
|
+
const isMergeable = node => $isElementNode(node) && INTERNAL_$isBlock(node) && !node.isEmpty() && $isElementNode(firstBlock) && (!firstBlock.isEmpty() || isLI(firstBlock));
|
|
6393
6498
|
const shouldInsert = !$isElementNode(firstBlock) || !firstBlock.isEmpty();
|
|
6394
6499
|
const insertedParagraph = shouldInsert ? this.insertParagraph() : null;
|
|
6395
|
-
const
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
}
|
|
6408
|
-
if (insertedParagraph && $isElementNode(currentBlock) && INTERNAL_$isBlock(currentBlock)) {
|
|
6409
|
-
currentBlock.append(...insertedParagraph.getChildren());
|
|
6500
|
+
const lastToInsert = blocks[blocks.length - 1];
|
|
6501
|
+
let firstToInsert = blocks[0];
|
|
6502
|
+
if (isMergeable(firstToInsert)) {
|
|
6503
|
+
firstBlock.append(...firstToInsert.getChildren());
|
|
6504
|
+
firstToInsert = blocks[1];
|
|
6505
|
+
}
|
|
6506
|
+
if (firstToInsert) {
|
|
6507
|
+
insertRangeAfter(firstBlock, firstToInsert);
|
|
6508
|
+
}
|
|
6509
|
+
const lastInsertedBlock = $getAncestor(nodeToSelect, INTERNAL_$isBlock);
|
|
6510
|
+
if (insertedParagraph && $isElementNode(lastInsertedBlock) && (isLI(insertedParagraph) || INTERNAL_$isBlock(lastToInsert))) {
|
|
6511
|
+
lastInsertedBlock.append(...insertedParagraph.getChildren());
|
|
6410
6512
|
insertedParagraph.remove();
|
|
6411
6513
|
}
|
|
6412
6514
|
if ($isElementNode(firstBlock) && firstBlock.isEmpty()) {
|
|
6413
6515
|
firstBlock.remove();
|
|
6414
6516
|
}
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
nodeToSelect.select(nodeToSelectSize, nodeToSelectSize);
|
|
6419
|
-
}
|
|
6517
|
+
nodeToSelect.selectEnd();
|
|
6518
|
+
|
|
6519
|
+
// To understand this take a look at the test "can wrap post-linebreak nodes into new element"
|
|
6420
6520
|
const lastChild = $isElementNode(firstBlock) ? firstBlock.getLastChild() : null;
|
|
6421
|
-
if ($isLineBreakNode(lastChild) &&
|
|
6521
|
+
if ($isLineBreakNode(lastChild) && lastInsertedBlock !== firstBlock) {
|
|
6422
6522
|
lastChild.remove();
|
|
6423
6523
|
}
|
|
6424
6524
|
}
|
|
@@ -6464,16 +6564,6 @@ class RangeSelection {
|
|
|
6464
6564
|
}
|
|
6465
6565
|
}
|
|
6466
6566
|
|
|
6467
|
-
/**
|
|
6468
|
-
* Returns the character-based offsets of the Selection, accounting for non-text Points
|
|
6469
|
-
* by using the children size or text content.
|
|
6470
|
-
*
|
|
6471
|
-
* @returns the character offsets for the Selection
|
|
6472
|
-
*/
|
|
6473
|
-
getCharacterOffsets() {
|
|
6474
|
-
return getCharacterOffsets(this);
|
|
6475
|
-
}
|
|
6476
|
-
|
|
6477
6567
|
/**
|
|
6478
6568
|
* Extracts the nodes in the Selection, splitting nodes where necessary
|
|
6479
6569
|
* to get offset-level precision.
|
|
@@ -7060,10 +7150,10 @@ function internalCreateSelection(editor) {
|
|
|
7060
7150
|
const currentEditorState = editor.getEditorState();
|
|
7061
7151
|
const lastSelection = currentEditorState._selection;
|
|
7062
7152
|
const domSelection = getDOMSelection(editor._window);
|
|
7063
|
-
if ($
|
|
7064
|
-
return lastSelection
|
|
7153
|
+
if ($isRangeSelection(lastSelection) || lastSelection == null) {
|
|
7154
|
+
return internalCreateRangeSelection(lastSelection, domSelection, editor);
|
|
7065
7155
|
}
|
|
7066
|
-
return
|
|
7156
|
+
return lastSelection.clone();
|
|
7067
7157
|
}
|
|
7068
7158
|
function internalCreateRangeSelection(lastSelection, domSelection, editor) {
|
|
7069
7159
|
const windowObj = editor._window;
|
|
@@ -7504,6 +7594,34 @@ function removeTextAndSplitBlock(selection) {
|
|
|
7504
7594
|
}
|
|
7505
7595
|
return pointParent.getIndexWithinParent() + x;
|
|
7506
7596
|
}
|
|
7597
|
+
function $wrapInlineNodes(nodes) {
|
|
7598
|
+
// We temporarily insert the topLevelNodes into an arbitrary ElementNode,
|
|
7599
|
+
// since insertAfter does not work on nodes that have no parent (TO-DO: fix that).
|
|
7600
|
+
const virtualRoot = $createParagraphNode();
|
|
7601
|
+
let currentBlock = null;
|
|
7602
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
7603
|
+
const node = nodes[i];
|
|
7604
|
+
const isLineBreakNode = $isLineBreakNode(node);
|
|
7605
|
+
if (isLineBreakNode || $isDecoratorNode(node) && node.isInline() || $isElementNode(node) && node.isInline() || $isTextNode(node) || node.isParentRequired()) {
|
|
7606
|
+
if (currentBlock === null) {
|
|
7607
|
+
currentBlock = node.createParentElementNode();
|
|
7608
|
+
virtualRoot.append(currentBlock);
|
|
7609
|
+
// In the case of LineBreakNode, we just need to
|
|
7610
|
+
// add an empty ParagraphNode to the topLevelBlocks.
|
|
7611
|
+
if (isLineBreakNode) {
|
|
7612
|
+
continue;
|
|
7613
|
+
}
|
|
7614
|
+
}
|
|
7615
|
+
if (currentBlock !== null) {
|
|
7616
|
+
currentBlock.append(node);
|
|
7617
|
+
}
|
|
7618
|
+
} else {
|
|
7619
|
+
virtualRoot.append(node);
|
|
7620
|
+
currentBlock = null;
|
|
7621
|
+
}
|
|
7622
|
+
}
|
|
7623
|
+
return virtualRoot;
|
|
7624
|
+
}
|
|
7507
7625
|
|
|
7508
7626
|
/**
|
|
7509
7627
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -8180,6 +8298,10 @@ class DecoratorNode extends LexicalNode {
|
|
|
8180
8298
|
constructor(key) {
|
|
8181
8299
|
super(key);
|
|
8182
8300
|
}
|
|
8301
|
+
|
|
8302
|
+
/**
|
|
8303
|
+
* The returned value is added to the LexicalEditor._decorators
|
|
8304
|
+
*/
|
|
8183
8305
|
decorate(editor, config) {
|
|
8184
8306
|
{
|
|
8185
8307
|
throw Error(`decorate: base method not extended`);
|
|
@@ -8463,25 +8585,11 @@ class ElementNode extends LexicalNode {
|
|
|
8463
8585
|
}
|
|
8464
8586
|
selectStart() {
|
|
8465
8587
|
const firstNode = this.getFirstDescendant();
|
|
8466
|
-
|
|
8467
|
-
return firstNode.select(0, 0);
|
|
8468
|
-
}
|
|
8469
|
-
// Decorator or LineBreak
|
|
8470
|
-
if (firstNode !== null) {
|
|
8471
|
-
return firstNode.selectPrevious();
|
|
8472
|
-
}
|
|
8473
|
-
return this.select(0, 0);
|
|
8588
|
+
return firstNode ? firstNode.selectStart() : this.select();
|
|
8474
8589
|
}
|
|
8475
8590
|
selectEnd() {
|
|
8476
8591
|
const lastNode = this.getLastDescendant();
|
|
8477
|
-
|
|
8478
|
-
return lastNode.select();
|
|
8479
|
-
}
|
|
8480
|
-
// Decorator or LineBreak
|
|
8481
|
-
if (lastNode !== null) {
|
|
8482
|
-
return lastNode.selectNext();
|
|
8483
|
-
}
|
|
8484
|
-
return this.select();
|
|
8592
|
+
return lastNode ? lastNode.selectEnd() : this.select();
|
|
8485
8593
|
}
|
|
8486
8594
|
clear() {
|
|
8487
8595
|
const writableSelf = this.getWritable();
|
|
@@ -9847,6 +9955,7 @@ function DEPRECATED_$isGridRowNode(node) {
|
|
|
9847
9955
|
return node instanceof DEPRECATED_GridRowNode;
|
|
9848
9956
|
}
|
|
9849
9957
|
|
|
9958
|
+
exports.$INTERNAL_isPointSelection = $INTERNAL_isPointSelection;
|
|
9850
9959
|
exports.$addUpdateTag = $addUpdateTag;
|
|
9851
9960
|
exports.$applyNodeReplacement = $applyNodeReplacement;
|
|
9852
9961
|
exports.$copyNode = $copyNode;
|