lexical 0.1.8 → 0.1.9
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 +383 -226
- package/Lexical.prod.js +144 -142
- package/LexicalAutoLinkNode.prod.js +1 -1
- package/LexicalCodeHighlightNode.prod.js +1 -1
- package/LexicalCodeNode.prod.js +1 -1
- package/LexicalExtendedNodes.dev.js +2 -4
- package/LexicalExtendedNodes.prod.js +2 -2
- package/LexicalHashtagNode.prod.js +1 -1
- package/LexicalHeadingNode.prod.js +1 -1
- package/LexicalLinkNode.prod.js +1 -1
- package/LexicalOverflowNode.prod.js +1 -1
- package/LexicalQuoteNode.prod.js +1 -1
- package/package.json +1 -1
- package/LexicalTableCellNode.dev.js +0 -81
- package/LexicalTableCellNode.prod.js +0 -9
- package/LexicalTableNode.dev.js +0 -638
- package/LexicalTableNode.prod.js +0 -21
- package/LexicalTableRowNode.dev.js +0 -76
- package/LexicalTableRowNode.prod.js +0 -8
- package/TableCellNode.js +0 -9
- package/TableNode.js +0 -9
- package/TableRowNode.js +0 -9
package/Lexical.dev.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*
|
|
15
15
|
*
|
|
16
16
|
*/
|
|
17
|
-
const VERSION = '0.1.
|
|
17
|
+
const VERSION = '0.1.9'; // DOM
|
|
18
18
|
|
|
19
19
|
const DOM_ELEMENT_TYPE = 1;
|
|
20
20
|
const DOM_TEXT_TYPE = 3; // Reconciling
|
|
@@ -159,7 +159,6 @@ function $flushMutations$1(editor, mutations, observer) {
|
|
|
159
159
|
|
|
160
160
|
try {
|
|
161
161
|
updateEditor(editor, () => {
|
|
162
|
-
$pushLogEntry('onMutation');
|
|
163
162
|
const badDOMTargets = new Map();
|
|
164
163
|
const rootElement = editor.getRootElement(); // We use the current edtior state, as that reflects what is
|
|
165
164
|
// actually "on screen".
|
|
@@ -218,7 +217,7 @@ function $flushMutations$1(editor, mutations, observer) {
|
|
|
218
217
|
|
|
219
218
|
if (removedDOMsLength !== unremovedBRs) {
|
|
220
219
|
if (targetDOM === rootElement) {
|
|
221
|
-
targetNode =
|
|
220
|
+
targetNode = internalGetRoot(currentEditorState);
|
|
222
221
|
}
|
|
223
222
|
|
|
224
223
|
badDOMTargets.set(targetDOM, targetNode);
|
|
@@ -299,7 +298,7 @@ function $flushMutations$1(editor, mutations, observer) {
|
|
|
299
298
|
$setSelection(selection);
|
|
300
299
|
}
|
|
301
300
|
}
|
|
302
|
-
}
|
|
301
|
+
});
|
|
303
302
|
} finally {
|
|
304
303
|
isProcessingMutations = false;
|
|
305
304
|
}
|
|
@@ -400,9 +399,14 @@ function toggleTextFormatType(format, type, alignWithFormat) {
|
|
|
400
399
|
return format;
|
|
401
400
|
}
|
|
402
401
|
function $isLeafNode(node) {
|
|
403
|
-
return $isTextNode(node) || $isLineBreakNode(node) || $isDecoratorNode(node)
|
|
402
|
+
return $isTextNode(node) || $isLineBreakNode(node) || $isDecoratorNode(node);
|
|
404
403
|
}
|
|
405
|
-
function $
|
|
404
|
+
function $setNodeKey(node, existingKey) {
|
|
405
|
+
if (existingKey != null) {
|
|
406
|
+
node.__key = existingKey;
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
|
|
406
410
|
errorOnReadOnly();
|
|
407
411
|
errorOnInfiniteTransforms();
|
|
408
412
|
const editor = getActiveEditor();
|
|
@@ -421,10 +425,10 @@ function $generateKey(node) {
|
|
|
421
425
|
editor._cloneNotNeeded.add(key);
|
|
422
426
|
|
|
423
427
|
editor._dirtyType = HAS_DIRTY_NODES;
|
|
424
|
-
|
|
428
|
+
node.__key = key;
|
|
425
429
|
}
|
|
426
430
|
|
|
427
|
-
function
|
|
431
|
+
function internalMarkParentElementsAsDirty(parentKey, nodeMap, dirtyElements) {
|
|
428
432
|
let nextParentKey = parentKey;
|
|
429
433
|
|
|
430
434
|
while (nextParentKey !== null) {
|
|
@@ -445,7 +449,7 @@ function $internallyMarkParentElementsAsDirty(parentKey, nodeMap, dirtyElements)
|
|
|
445
449
|
// the cloning heuristic. Instead use node.getWritable().
|
|
446
450
|
|
|
447
451
|
|
|
448
|
-
function
|
|
452
|
+
function internalMarkNodeAsDirty(node) {
|
|
449
453
|
errorOnInfiniteTransforms();
|
|
450
454
|
const latest = node.getLatest();
|
|
451
455
|
const parent = latest.__parent;
|
|
@@ -455,7 +459,7 @@ function $internallyMarkNodeAsDirty(node) {
|
|
|
455
459
|
const dirtyElements = editor._dirtyElements;
|
|
456
460
|
|
|
457
461
|
if (parent !== null) {
|
|
458
|
-
|
|
462
|
+
internalMarkParentElementsAsDirty(parent, nodeMap, dirtyElements);
|
|
459
463
|
}
|
|
460
464
|
|
|
461
465
|
const key = latest.__key;
|
|
@@ -468,16 +472,16 @@ function $internallyMarkNodeAsDirty(node) {
|
|
|
468
472
|
editor._dirtyLeaves.add(key);
|
|
469
473
|
}
|
|
470
474
|
}
|
|
471
|
-
function
|
|
475
|
+
function internalMarkSiblingsAsDirty(node) {
|
|
472
476
|
const previousNode = node.getPreviousSibling();
|
|
473
477
|
const nextNode = node.getNextSibling();
|
|
474
478
|
|
|
475
479
|
if (previousNode !== null) {
|
|
476
|
-
|
|
480
|
+
internalMarkNodeAsDirty(previousNode);
|
|
477
481
|
}
|
|
478
482
|
|
|
479
483
|
if (nextNode !== null) {
|
|
480
|
-
|
|
484
|
+
internalMarkNodeAsDirty(nextNode);
|
|
481
485
|
}
|
|
482
486
|
}
|
|
483
487
|
function $setCompositionKey(compositionKey) {
|
|
@@ -549,11 +553,6 @@ function cloneDecorators(editor) {
|
|
|
549
553
|
editor._pendingDecorators = pendingDecorators;
|
|
550
554
|
return pendingDecorators;
|
|
551
555
|
}
|
|
552
|
-
function $pushLogEntry(entry) {
|
|
553
|
-
const editor = getActiveEditor();
|
|
554
|
-
|
|
555
|
-
editor._log.push(entry);
|
|
556
|
-
}
|
|
557
556
|
function getEditorStateTextContent(editorState) {
|
|
558
557
|
return editorState.read(view => $getRoot().getTextContent());
|
|
559
558
|
}
|
|
@@ -579,12 +578,15 @@ function markAllNodesAsDirty(editor, type) {
|
|
|
579
578
|
const node = nodeMapEntries[i][1];
|
|
580
579
|
node.markDirty();
|
|
581
580
|
}
|
|
582
|
-
},
|
|
583
|
-
tag: '
|
|
581
|
+
}, editor._pendingEditorState === null ? {
|
|
582
|
+
tag: 'history-merge'
|
|
584
583
|
} : undefined);
|
|
585
584
|
}
|
|
586
|
-
function $getRoot(
|
|
587
|
-
return (
|
|
585
|
+
function $getRoot() {
|
|
586
|
+
return internalGetRoot(getActiveEditorState());
|
|
587
|
+
}
|
|
588
|
+
function internalGetRoot(editorState) {
|
|
589
|
+
return editorState._nodeMap.get('root' // $FlowFixMe: root is always in our Map
|
|
588
590
|
);
|
|
589
591
|
}
|
|
590
592
|
function $setSelection(selection) {
|
|
@@ -896,6 +898,25 @@ function getCachedClassNameArray(classNamesTheme, classNameThemeType) {
|
|
|
896
898
|
|
|
897
899
|
return classNames;
|
|
898
900
|
}
|
|
901
|
+
function setMutatedNode(mutatedNodes, registeredNodes, node, mutation) {
|
|
902
|
+
const registeredNode = registeredNodes.get(node.__type);
|
|
903
|
+
|
|
904
|
+
if (registeredNode === undefined) {
|
|
905
|
+
{
|
|
906
|
+
throw Error(`Type ${node.__type} not in registeredNodes`);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
const klass = registeredNode.klass;
|
|
911
|
+
let mutatedNodesByType = mutatedNodes.get(klass);
|
|
912
|
+
|
|
913
|
+
if (mutatedNodesByType === undefined) {
|
|
914
|
+
mutatedNodesByType = new Map();
|
|
915
|
+
mutatedNodes.set(klass, mutatedNodesByType);
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
mutatedNodesByType.set(node.__key, mutation);
|
|
919
|
+
}
|
|
899
920
|
|
|
900
921
|
/**
|
|
901
922
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -1065,17 +1086,41 @@ function $normalizeTextNode(textNode) {
|
|
|
1065
1086
|
*
|
|
1066
1087
|
*
|
|
1067
1088
|
*/
|
|
1089
|
+
function resolveElement(element, isBackward, focusOffset) {
|
|
1090
|
+
const parent = element.getParent();
|
|
1091
|
+
let offset = focusOffset;
|
|
1092
|
+
let block = element;
|
|
1093
|
+
|
|
1094
|
+
if (parent !== null) {
|
|
1095
|
+
if (isBackward && focusOffset === 0) {
|
|
1096
|
+
offset = block.getIndexWithinParent();
|
|
1097
|
+
block = parent;
|
|
1098
|
+
} else if (!isBackward && focusOffset === block.getChildrenSize()) {
|
|
1099
|
+
offset = block.getIndexWithinParent() + 1;
|
|
1100
|
+
block = parent;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
return block.getChildAtIndex(isBackward ? offset - 1 : offset);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1068
1107
|
function getPossibleDecoratorNode(focus, isBackward) {
|
|
1069
1108
|
const focusOffset = focus.offset;
|
|
1070
1109
|
|
|
1071
1110
|
if (focus.type === 'element') {
|
|
1072
1111
|
const block = focus.getNode();
|
|
1073
|
-
return block
|
|
1112
|
+
return resolveElement(block, isBackward, focusOffset);
|
|
1074
1113
|
} else {
|
|
1075
1114
|
const focusNode = focus.getNode();
|
|
1076
1115
|
|
|
1077
1116
|
if (isBackward && focusOffset === 0 || !isBackward && focusOffset === focusNode.getTextContentSize()) {
|
|
1078
|
-
|
|
1117
|
+
const possibleNode = isBackward ? focusNode.getPreviousSibling() : focusNode.getNextSibling();
|
|
1118
|
+
|
|
1119
|
+
if (possibleNode === null) {
|
|
1120
|
+
return resolveElement(focusNode.getParentOrThrow(), isBackward, focusNode.getIndexWithinParent() + (isBackward ? 0 : 1));
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
return possibleNode;
|
|
1079
1124
|
}
|
|
1080
1125
|
}
|
|
1081
1126
|
|
|
@@ -1200,15 +1245,20 @@ function $transferStartingElementPointToTextPoint(start, end, format) {
|
|
|
1200
1245
|
const element = start.getNode();
|
|
1201
1246
|
const placementNode = element.getChildAtIndex(start.offset);
|
|
1202
1247
|
const textNode = $createTextNode();
|
|
1248
|
+
const target = $isRootNode(element) ? $createParagraphNode().append(textNode) : textNode;
|
|
1203
1249
|
textNode.setFormat(format);
|
|
1204
1250
|
|
|
1205
1251
|
if (placementNode === null) {
|
|
1206
|
-
element.append(
|
|
1252
|
+
element.append(target);
|
|
1207
1253
|
} else {
|
|
1208
|
-
placementNode.insertBefore(
|
|
1254
|
+
placementNode.insertBefore(target);
|
|
1209
1255
|
} // Transfer the element point to a text point.
|
|
1210
1256
|
|
|
1211
1257
|
|
|
1258
|
+
if (start.is(end)) {
|
|
1259
|
+
end.set(textNode.getKey(), 0, 'text');
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1212
1262
|
start.set(textNode.getKey(), 0, 'text');
|
|
1213
1263
|
}
|
|
1214
1264
|
|
|
@@ -1322,7 +1372,7 @@ class RangeSelection {
|
|
|
1322
1372
|
}
|
|
1323
1373
|
|
|
1324
1374
|
textContent += text;
|
|
1325
|
-
} else if (($isDecoratorNode(node) || $isLineBreakNode(node)
|
|
1375
|
+
} else if (($isDecoratorNode(node) || $isLineBreakNode(node)) && (node !== lastNode || !this.isCollapsed())) {
|
|
1326
1376
|
textContent += node.getTextContent();
|
|
1327
1377
|
}
|
|
1328
1378
|
}
|
|
@@ -1333,7 +1383,9 @@ class RangeSelection {
|
|
|
1333
1383
|
|
|
1334
1384
|
applyDOMRange(range) {
|
|
1335
1385
|
const editor = getActiveEditor();
|
|
1336
|
-
const
|
|
1386
|
+
const currentEditorState = editor.getEditorState();
|
|
1387
|
+
const lastSelection = currentEditorState._selection;
|
|
1388
|
+
const resolvedSelectionPoints = internalResolveSelectionPoints(range.startContainer, range.startOffset, range.endContainer, range.endOffset, editor, lastSelection);
|
|
1337
1389
|
|
|
1338
1390
|
if (resolvedSelectionPoints === null) {
|
|
1339
1391
|
return;
|
|
@@ -1591,7 +1643,7 @@ class RangeSelection {
|
|
|
1591
1643
|
const selectedNode = selectedNodes[i];
|
|
1592
1644
|
const key = selectedNode.getKey();
|
|
1593
1645
|
|
|
1594
|
-
if (!markedNodeKeysForKeep.has(key)
|
|
1646
|
+
if (!markedNodeKeysForKeep.has(key)) {
|
|
1595
1647
|
selectedNode.remove();
|
|
1596
1648
|
}
|
|
1597
1649
|
}
|
|
@@ -1752,7 +1804,7 @@ class RangeSelection {
|
|
|
1752
1804
|
// append them after the last node we're inserting.
|
|
1753
1805
|
|
|
1754
1806
|
const nextSiblings = anchorNode.getNextSiblings();
|
|
1755
|
-
const topLevelElement = anchorNode.getTopLevelElementOrThrow();
|
|
1807
|
+
const topLevelElement = $isRootNode(anchorNode) ? null : anchorNode.getTopLevelElementOrThrow();
|
|
1756
1808
|
|
|
1757
1809
|
if ($isTextNode(anchorNode)) {
|
|
1758
1810
|
const textContent = anchorNode.getTextContent();
|
|
@@ -1869,9 +1921,15 @@ class RangeSelection {
|
|
|
1869
1921
|
}
|
|
1870
1922
|
|
|
1871
1923
|
if ($isTextNode(target)) {
|
|
1924
|
+
if (topLevelElement === null) {
|
|
1925
|
+
{
|
|
1926
|
+
throw Error(`insertNode: topLevelElement is root node`);
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1872
1930
|
target = topLevelElement;
|
|
1873
1931
|
}
|
|
1874
|
-
} else if (didReplaceOrMerge && $isRootNode(target.getParent())) {
|
|
1932
|
+
} else if (didReplaceOrMerge && !$isDecoratorNode(node) && $isRootNode(target.getParent())) {
|
|
1875
1933
|
{
|
|
1876
1934
|
throw Error(`insertNodes: cannot insert a non-element into a root node`);
|
|
1877
1935
|
}
|
|
@@ -1880,7 +1938,9 @@ class RangeSelection {
|
|
|
1880
1938
|
didReplaceOrMerge = false;
|
|
1881
1939
|
|
|
1882
1940
|
if ($isElementNode(target)) {
|
|
1883
|
-
if (
|
|
1941
|
+
if ($isDecoratorNode(node) && node.isTopLevel()) {
|
|
1942
|
+
target = target.insertAfter(node);
|
|
1943
|
+
} else if (!$isElementNode(node)) {
|
|
1884
1944
|
const firstChild = target.getFirstChild();
|
|
1885
1945
|
|
|
1886
1946
|
if (firstChild !== null) {
|
|
@@ -1895,9 +1955,21 @@ class RangeSelection {
|
|
|
1895
1955
|
continue;
|
|
1896
1956
|
}
|
|
1897
1957
|
|
|
1898
|
-
|
|
1958
|
+
if ($isRootNode(target)) {
|
|
1959
|
+
const placementNode = target.getChildAtIndex(anchorOffset);
|
|
1960
|
+
|
|
1961
|
+
if (placementNode !== null) {
|
|
1962
|
+
placementNode.insertBefore(node);
|
|
1963
|
+
} else {
|
|
1964
|
+
target.append(node);
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
target = node;
|
|
1968
|
+
} else {
|
|
1969
|
+
target = target.insertAfter(node);
|
|
1970
|
+
}
|
|
1899
1971
|
}
|
|
1900
|
-
} else if (!$isElementNode(node)) {
|
|
1972
|
+
} else if (!$isElementNode(node) || $isDecoratorNode(target) && target.isTopLevel()) {
|
|
1901
1973
|
target = target.insertAfter(node);
|
|
1902
1974
|
} else {
|
|
1903
1975
|
target = node.getParentOrThrow(); // Re-try again with the target being the parent
|
|
@@ -2008,6 +2080,21 @@ class RangeSelection {
|
|
|
2008
2080
|
}
|
|
2009
2081
|
} else {
|
|
2010
2082
|
currentElement = anchor.getNode();
|
|
2083
|
+
|
|
2084
|
+
if ($isRootNode(currentElement)) {
|
|
2085
|
+
const paragraph = $createParagraphNode();
|
|
2086
|
+
const child = currentElement.getChildAtIndex(anchorOffset);
|
|
2087
|
+
paragraph.select();
|
|
2088
|
+
|
|
2089
|
+
if (child !== null) {
|
|
2090
|
+
child.insertBefore(paragraph);
|
|
2091
|
+
} else {
|
|
2092
|
+
currentElement.append(paragraph);
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2095
|
+
return;
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2011
2098
|
nodesToMove = currentElement.getChildren().slice(anchorOffset).reverse();
|
|
2012
2099
|
}
|
|
2013
2100
|
|
|
@@ -2045,6 +2132,15 @@ class RangeSelection {
|
|
|
2045
2132
|
|
|
2046
2133
|
insertLineBreak(selectStart) {
|
|
2047
2134
|
const lineBreakNode = $createLineBreakNode();
|
|
2135
|
+
const anchor = this.anchor;
|
|
2136
|
+
|
|
2137
|
+
if (anchor.type === 'element') {
|
|
2138
|
+
const element = anchor.getNode();
|
|
2139
|
+
|
|
2140
|
+
if ($isRootNode(element)) {
|
|
2141
|
+
this.insertParagraph();
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2048
2144
|
|
|
2049
2145
|
if (selectStart) {
|
|
2050
2146
|
this.insertNodes([lineBreakNode], true);
|
|
@@ -2114,17 +2210,26 @@ class RangeSelection {
|
|
|
2114
2210
|
const anchor = this.anchor;
|
|
2115
2211
|
const collapse = alter === 'move'; // Handle the selection movement around decorators.
|
|
2116
2212
|
|
|
2117
|
-
const
|
|
2213
|
+
const possibleNode = getPossibleDecoratorNode(focus, isBackward);
|
|
2118
2214
|
|
|
2119
|
-
if ($isDecoratorNode(
|
|
2120
|
-
const sibling = isBackward ?
|
|
2215
|
+
if ($isDecoratorNode(possibleNode) && !possibleNode.isIsolated()) {
|
|
2216
|
+
const sibling = isBackward ? possibleNode.getPreviousSibling() : possibleNode.getNextSibling();
|
|
2121
2217
|
|
|
2122
2218
|
if (!$isTextNode(sibling)) {
|
|
2123
|
-
const
|
|
2124
|
-
let offset
|
|
2219
|
+
const parent = possibleNode.getParentOrThrow();
|
|
2220
|
+
let offset;
|
|
2221
|
+
let elementKey;
|
|
2222
|
+
|
|
2223
|
+
if ($isElementNode(sibling)) {
|
|
2224
|
+
elementKey = sibling.getKey();
|
|
2225
|
+
offset = isBackward ? sibling.getChildrenSize() : 0;
|
|
2226
|
+
} else {
|
|
2227
|
+
offset = possibleNode.getIndexWithinParent();
|
|
2228
|
+
elementKey = parent.getKey();
|
|
2125
2229
|
|
|
2126
|
-
|
|
2127
|
-
|
|
2230
|
+
if (!isBackward) {
|
|
2231
|
+
offset++;
|
|
2232
|
+
}
|
|
2128
2233
|
}
|
|
2129
2234
|
|
|
2130
2235
|
focus.set(elementKey, offset, 'element');
|
|
@@ -2165,9 +2270,7 @@ class RangeSelection {
|
|
|
2165
2270
|
const focus = this.focus;
|
|
2166
2271
|
let anchorNode = anchor.getNode();
|
|
2167
2272
|
|
|
2168
|
-
if (
|
|
2169
|
-
return;
|
|
2170
|
-
} else if (!isBackward && ( // Delete forward handle case
|
|
2273
|
+
if (!isBackward && ( // Delete forward handle case
|
|
2171
2274
|
anchor.type === 'element' && // $FlowFixMe: always an element node
|
|
2172
2275
|
anchor.offset === anchorNode.getChildrenSize() || anchor.type === 'text' && anchor.offset === anchorNode.getTextContentSize())) {
|
|
2173
2276
|
const nextSibling = anchorNode.getNextSibling() || anchorNode.getParentOrThrow().getNextSibling();
|
|
@@ -2334,7 +2437,12 @@ function $removeSegment(node, isBackward) {
|
|
|
2334
2437
|
}
|
|
2335
2438
|
}
|
|
2336
2439
|
|
|
2337
|
-
function
|
|
2440
|
+
function shouldResolveAncestor(resolvedElement, resolvedOffset, lastPoint) {
|
|
2441
|
+
const parent = resolvedElement.getParent();
|
|
2442
|
+
return lastPoint === null || parent === null || !parent.canBeEmpty() || parent !== lastPoint.getNode();
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2445
|
+
function internalResolveSelectionPoint(dom, offset, lastPoint) {
|
|
2338
2446
|
let resolvedOffset = offset;
|
|
2339
2447
|
let resolvedNode; // If we have selection on an element, we will
|
|
2340
2448
|
// need to figure out (using the offset) what text
|
|
@@ -2360,9 +2468,6 @@ function internalResolveSelectionPoint(dom, offset) {
|
|
|
2360
2468
|
|
|
2361
2469
|
if ($isTextNode(resolvedNode)) {
|
|
2362
2470
|
resolvedOffset = getTextNodeOffset(resolvedNode, moveSelectionToEnd);
|
|
2363
|
-
} else if ($isHorizontalRuleNode(resolvedNode)) {
|
|
2364
|
-
resolvedOffset = 0;
|
|
2365
|
-
return $createPoint(resolvedNode.__key, resolvedOffset, 'element');
|
|
2366
2471
|
} else {
|
|
2367
2472
|
let resolvedElement = getNodeFromDOM(dom); // Ensure resolvedElement is actually a element.
|
|
2368
2473
|
|
|
@@ -2373,7 +2478,7 @@ function internalResolveSelectionPoint(dom, offset) {
|
|
|
2373
2478
|
if ($isElementNode(resolvedElement)) {
|
|
2374
2479
|
let child = resolvedElement.getChildAtIndex(resolvedOffset);
|
|
2375
2480
|
|
|
2376
|
-
if ($isElementNode(child)) {
|
|
2481
|
+
if ($isElementNode(child) && shouldResolveAncestor(child, resolvedOffset, lastPoint)) {
|
|
2377
2482
|
const descendant = moveSelectionToEnd ? child.getLastDescendant() : child.getFirstDescendant();
|
|
2378
2483
|
|
|
2379
2484
|
if (descendant === null) {
|
|
@@ -2395,11 +2500,6 @@ function internalResolveSelectionPoint(dom, offset) {
|
|
|
2395
2500
|
} else {
|
|
2396
2501
|
resolvedOffset = resolvedElement.getIndexWithinParent() + 1;
|
|
2397
2502
|
resolvedElement = resolvedElement.getParentOrThrow();
|
|
2398
|
-
} // You can't select root nodes
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
if ($isRootNode(resolvedElement)) {
|
|
2402
|
-
return null;
|
|
2403
2503
|
}
|
|
2404
2504
|
|
|
2405
2505
|
if ($isElementNode(resolvedElement)) {
|
|
@@ -2418,18 +2518,18 @@ function internalResolveSelectionPoint(dom, offset) {
|
|
|
2418
2518
|
return $createPoint(resolvedNode.__key, resolvedOffset, 'text');
|
|
2419
2519
|
}
|
|
2420
2520
|
|
|
2421
|
-
function internalResolveSelectionPoints(anchorDOM, anchorOffset, focusDOM, focusOffset, editor) {
|
|
2521
|
+
function internalResolveSelectionPoints(anchorDOM, anchorOffset, focusDOM, focusOffset, editor, lastSelection) {
|
|
2422
2522
|
if (anchorDOM === null || focusDOM === null || !isSelectionWithinEditor(editor, anchorDOM, focusDOM)) {
|
|
2423
2523
|
return null;
|
|
2424
2524
|
}
|
|
2425
2525
|
|
|
2426
|
-
const resolvedAnchorPoint = internalResolveSelectionPoint(anchorDOM, anchorOffset);
|
|
2526
|
+
const resolvedAnchorPoint = internalResolveSelectionPoint(anchorDOM, anchorOffset, lastSelection !== null ? lastSelection.anchor : null);
|
|
2427
2527
|
|
|
2428
2528
|
if (resolvedAnchorPoint === null) {
|
|
2429
2529
|
return null;
|
|
2430
2530
|
}
|
|
2431
2531
|
|
|
2432
|
-
const resolvedFocusPoint = internalResolveSelectionPoint(focusDOM, focusOffset);
|
|
2532
|
+
const resolvedFocusPoint = internalResolveSelectionPoint(focusDOM, focusOffset, lastSelection !== null ? lastSelection.focus : null);
|
|
2433
2533
|
|
|
2434
2534
|
if (resolvedFocusPoint === null) {
|
|
2435
2535
|
return null;
|
|
@@ -2467,9 +2567,6 @@ function internalResolveSelectionPoints(anchorDOM, anchorOffset, focusDOM, focus
|
|
|
2467
2567
|
}
|
|
2468
2568
|
}
|
|
2469
2569
|
|
|
2470
|
-
const currentEditorState = editor.getEditorState();
|
|
2471
|
-
const lastSelection = currentEditorState._selection;
|
|
2472
|
-
|
|
2473
2570
|
if (editor.isComposing() && editor._compositionKey !== resolvedAnchorPoint.key && lastSelection !== null) {
|
|
2474
2571
|
const lastAnchor = lastSelection.anchor;
|
|
2475
2572
|
const lastFocus = lastSelection.focus;
|
|
@@ -2542,7 +2639,7 @@ function internalCreateRangeSelection(editor) {
|
|
|
2542
2639
|
// native selection.
|
|
2543
2640
|
|
|
2544
2641
|
|
|
2545
|
-
const resolvedSelectionPoints = internalResolveSelectionPoints(anchorDOM, anchorOffset, focusDOM, focusOffset, editor);
|
|
2642
|
+
const resolvedSelectionPoints = internalResolveSelectionPoints(anchorDOM, anchorOffset, focusDOM, focusOffset, editor, lastSelection);
|
|
2546
2643
|
|
|
2547
2644
|
if (resolvedSelectionPoints === null) {
|
|
2548
2645
|
return null;
|
|
@@ -2797,7 +2894,7 @@ function removeNode(nodeToRemove, restoreSelection) {
|
|
|
2797
2894
|
}
|
|
2798
2895
|
}
|
|
2799
2896
|
|
|
2800
|
-
|
|
2897
|
+
internalMarkSiblingsAsDirty(nodeToRemove);
|
|
2801
2898
|
parentChildren.splice(index, 1);
|
|
2802
2899
|
const writableNodeToRemove = nodeToRemove.getWritable();
|
|
2803
2900
|
writableNodeToRemove.__parent = null;
|
|
@@ -2830,8 +2927,8 @@ class LexicalNode {
|
|
|
2830
2927
|
|
|
2831
2928
|
constructor(key) {
|
|
2832
2929
|
this.__type = this.constructor.getType();
|
|
2833
|
-
this.
|
|
2834
|
-
this
|
|
2930
|
+
this.__parent = null;
|
|
2931
|
+
$setNodeKey(this, key); // Ensure custom nodes implement required methods.
|
|
2835
2932
|
|
|
2836
2933
|
{
|
|
2837
2934
|
const proto = Object.getPrototypeOf(this);
|
|
@@ -3269,7 +3366,7 @@ class LexicalNode {
|
|
|
3269
3366
|
|
|
3270
3367
|
if (cloneNotNeeded.has(key)) {
|
|
3271
3368
|
// Transforms clear the dirty node set on each iteration to keep track on newly dirty nodes
|
|
3272
|
-
|
|
3369
|
+
internalMarkNodeAsDirty(latestNode);
|
|
3273
3370
|
return latestNode;
|
|
3274
3371
|
}
|
|
3275
3372
|
|
|
@@ -3293,7 +3390,7 @@ class LexicalNode {
|
|
|
3293
3390
|
|
|
3294
3391
|
cloneNotNeeded.add(key);
|
|
3295
3392
|
mutableNode.__key = key;
|
|
3296
|
-
|
|
3393
|
+
internalMarkNodeAsDirty(mutableNode); // Update reference in node map
|
|
3297
3394
|
|
|
3298
3395
|
nodeMap.set(key, mutableNode); // $FlowFixMe this is LexicalNode
|
|
3299
3396
|
|
|
@@ -3349,7 +3446,7 @@ class LexicalNode {
|
|
|
3349
3446
|
}
|
|
3350
3447
|
}
|
|
3351
3448
|
|
|
3352
|
-
|
|
3449
|
+
internalMarkSiblingsAsDirty(writableReplaceWith);
|
|
3353
3450
|
children.splice(index, 1);
|
|
3354
3451
|
}
|
|
3355
3452
|
|
|
@@ -3368,7 +3465,7 @@ class LexicalNode {
|
|
|
3368
3465
|
children.splice(index, 0, newKey);
|
|
3369
3466
|
writableReplaceWith.__parent = newParent.__key;
|
|
3370
3467
|
removeNode(this, false);
|
|
3371
|
-
|
|
3468
|
+
internalMarkSiblingsAsDirty(writableReplaceWith);
|
|
3372
3469
|
const selection = $getSelection();
|
|
3373
3470
|
|
|
3374
3471
|
if (selection !== null) {
|
|
@@ -3411,7 +3508,7 @@ class LexicalNode {
|
|
|
3411
3508
|
}
|
|
3412
3509
|
}
|
|
3413
3510
|
|
|
3414
|
-
|
|
3511
|
+
internalMarkSiblingsAsDirty(writableNodeToInsert);
|
|
3415
3512
|
|
|
3416
3513
|
if (selection !== null) {
|
|
3417
3514
|
const oldParentKey = oldParent.getKey();
|
|
@@ -3438,7 +3535,7 @@ class LexicalNode {
|
|
|
3438
3535
|
}
|
|
3439
3536
|
|
|
3440
3537
|
children.splice(index + 1, 0, insertKey);
|
|
3441
|
-
|
|
3538
|
+
internalMarkSiblingsAsDirty(writableNodeToInsert);
|
|
3442
3539
|
|
|
3443
3540
|
if (selection !== null) {
|
|
3444
3541
|
$updateElementSelectionOnCreateDeleteNode(selection, writableParent, index + 1);
|
|
@@ -3473,7 +3570,7 @@ class LexicalNode {
|
|
|
3473
3570
|
}
|
|
3474
3571
|
}
|
|
3475
3572
|
|
|
3476
|
-
|
|
3573
|
+
internalMarkSiblingsAsDirty(writableNodeToInsert);
|
|
3477
3574
|
children.splice(index, 1);
|
|
3478
3575
|
}
|
|
3479
3576
|
|
|
@@ -3490,7 +3587,7 @@ class LexicalNode {
|
|
|
3490
3587
|
}
|
|
3491
3588
|
|
|
3492
3589
|
children.splice(index, 0, insertKey);
|
|
3493
|
-
|
|
3590
|
+
internalMarkSiblingsAsDirty(writableNodeToInsert);
|
|
3494
3591
|
const selection = $getSelection();
|
|
3495
3592
|
|
|
3496
3593
|
if (selection !== null) {
|
|
@@ -3605,7 +3702,7 @@ class DecoratorEditor {
|
|
|
3605
3702
|
|
|
3606
3703
|
if (editorState !== null) {
|
|
3607
3704
|
editor.setEditorState(editorState, {
|
|
3608
|
-
tag: '
|
|
3705
|
+
tag: 'history-merge'
|
|
3609
3706
|
});
|
|
3610
3707
|
}
|
|
3611
3708
|
}
|
|
@@ -3792,6 +3889,14 @@ class DecoratorNode extends LexicalNode {
|
|
|
3792
3889
|
}
|
|
3793
3890
|
}
|
|
3794
3891
|
|
|
3892
|
+
isIsolated() {
|
|
3893
|
+
return false;
|
|
3894
|
+
}
|
|
3895
|
+
|
|
3896
|
+
isTopLevel() {
|
|
3897
|
+
return false;
|
|
3898
|
+
}
|
|
3899
|
+
|
|
3795
3900
|
}
|
|
3796
3901
|
function $isDecoratorNode(node) {
|
|
3797
3902
|
return node instanceof DecoratorNode;
|
|
@@ -3960,6 +4065,7 @@ let subTreeDirectionedTextContent = '';
|
|
|
3960
4065
|
let editorTextContent = '';
|
|
3961
4066
|
let activeEditorConfig;
|
|
3962
4067
|
let activeEditor$1;
|
|
4068
|
+
let activeEditorNodes;
|
|
3963
4069
|
let treatAllNodesAsDirty = false;
|
|
3964
4070
|
let activeEditorStateReadOnly = false;
|
|
3965
4071
|
let activeTextDirection = null;
|
|
@@ -3968,6 +4074,7 @@ let activeDirtyLeaves;
|
|
|
3968
4074
|
let activePrevNodeMap;
|
|
3969
4075
|
let activeNextNodeMap;
|
|
3970
4076
|
let activePrevKeyToDOMMap;
|
|
4077
|
+
let mutatedNodes;
|
|
3971
4078
|
|
|
3972
4079
|
function destroyNode(key, parentDOM) {
|
|
3973
4080
|
const node = activePrevNodeMap.get(key);
|
|
@@ -3987,6 +4094,10 @@ function destroyNode(key, parentDOM) {
|
|
|
3987
4094
|
const children = node.__children;
|
|
3988
4095
|
destroyChildren(children, 0, children.length - 1, null);
|
|
3989
4096
|
}
|
|
4097
|
+
|
|
4098
|
+
if (node !== undefined) {
|
|
4099
|
+
setMutatedNode(mutatedNodes, activeEditorNodes, node, 'destroyed');
|
|
4100
|
+
}
|
|
3990
4101
|
}
|
|
3991
4102
|
|
|
3992
4103
|
function destroyChildren(children, _startIndex, endIndex, dom) {
|
|
@@ -4123,6 +4234,7 @@ function createNode(key, parentDOM, insertDOM) {
|
|
|
4123
4234
|
Object.freeze(node);
|
|
4124
4235
|
}
|
|
4125
4236
|
|
|
4237
|
+
setMutatedNode(mutatedNodes, activeEditorNodes, node, 'created');
|
|
4126
4238
|
return dom;
|
|
4127
4239
|
}
|
|
4128
4240
|
|
|
@@ -4512,12 +4624,15 @@ function reconcileRoot(prevEditorState, nextEditorState, editor, selection, dirt
|
|
|
4512
4624
|
activeTextDirection = null;
|
|
4513
4625
|
activeEditor$1 = editor;
|
|
4514
4626
|
activeEditorConfig = editor._config;
|
|
4627
|
+
activeEditorNodes = editor._nodes;
|
|
4515
4628
|
activeDirtyElements = dirtyElements;
|
|
4516
4629
|
activeDirtyLeaves = dirtyLeaves;
|
|
4517
4630
|
activePrevNodeMap = prevEditorState._nodeMap;
|
|
4518
4631
|
activeNextNodeMap = nextEditorState._nodeMap;
|
|
4519
4632
|
activeEditorStateReadOnly = nextEditorState._readOnly;
|
|
4520
4633
|
activePrevKeyToDOMMap = new Map(editor._keyToDOMMap);
|
|
4634
|
+
const currentMutatedNodes = new Map();
|
|
4635
|
+
mutatedNodes = currentMutatedNodes;
|
|
4521
4636
|
reconcileNode('root', null); // We don't want a bunch of void checks throughout the scope
|
|
4522
4637
|
// so instead we make it seem that these values are always set.
|
|
4523
4638
|
// We also want to make sure we clear them down, otherwise we
|
|
@@ -4526,6 +4641,8 @@ function reconcileRoot(prevEditorState, nextEditorState, editor, selection, dirt
|
|
|
4526
4641
|
|
|
4527
4642
|
activeEditor$1 = undefined; // $FlowFixMe
|
|
4528
4643
|
|
|
4644
|
+
activeEditorNodes = undefined; // $FlowFixMe
|
|
4645
|
+
|
|
4529
4646
|
activeDirtyElements = undefined; // $FlowFixMe
|
|
4530
4647
|
|
|
4531
4648
|
activeDirtyLeaves = undefined; // $FlowFixMe
|
|
@@ -4536,11 +4653,15 @@ function reconcileRoot(prevEditorState, nextEditorState, editor, selection, dirt
|
|
|
4536
4653
|
|
|
4537
4654
|
activeEditorConfig = undefined; // $FlowFixMe
|
|
4538
4655
|
|
|
4539
|
-
activePrevKeyToDOMMap = undefined;
|
|
4656
|
+
activePrevKeyToDOMMap = undefined; // $FlowFixMe
|
|
4657
|
+
|
|
4658
|
+
mutatedNodes = undefined;
|
|
4659
|
+
return currentMutatedNodes;
|
|
4540
4660
|
}
|
|
4541
4661
|
|
|
4542
4662
|
function updateEditorState(rootElement, currentEditorState, pendingEditorState, currentSelection, pendingSelection, needsUpdate, editor) {
|
|
4543
4663
|
const observer = editor._observer;
|
|
4664
|
+
let reconcileMutatedNodes = null;
|
|
4544
4665
|
|
|
4545
4666
|
if (needsUpdate && observer !== null) {
|
|
4546
4667
|
const dirtyType = editor._dirtyType;
|
|
@@ -4549,7 +4670,7 @@ function updateEditorState(rootElement, currentEditorState, pendingEditorState,
|
|
|
4549
4670
|
observer.disconnect();
|
|
4550
4671
|
|
|
4551
4672
|
try {
|
|
4552
|
-
reconcileRoot(currentEditorState, pendingEditorState, editor, pendingSelection, dirtyType, dirtyElements, dirtyLeaves);
|
|
4673
|
+
reconcileMutatedNodes = reconcileRoot(currentEditorState, pendingEditorState, editor, pendingSelection, dirtyType, dirtyElements, dirtyLeaves);
|
|
4553
4674
|
} finally {
|
|
4554
4675
|
observer.observe(rootElement, {
|
|
4555
4676
|
characterData: true,
|
|
@@ -4564,6 +4685,8 @@ function updateEditorState(rootElement, currentEditorState, pendingEditorState,
|
|
|
4564
4685
|
if (domSelection !== null && (needsUpdate || pendingSelection === null || pendingSelection.dirty)) {
|
|
4565
4686
|
reconcileSelection(currentSelection, pendingSelection, editor, domSelection);
|
|
4566
4687
|
}
|
|
4688
|
+
|
|
4689
|
+
return reconcileMutatedNodes;
|
|
4567
4690
|
}
|
|
4568
4691
|
|
|
4569
4692
|
function scrollIntoViewIfNeeded(node, rootElement) {
|
|
@@ -4979,19 +5102,20 @@ function commitPendingUpdates(editor) {
|
|
|
4979
5102
|
editor._updating = true;
|
|
4980
5103
|
|
|
4981
5104
|
try {
|
|
4982
|
-
updateEditorState(rootElement, currentEditorState, pendingEditorState, currentSelection, pendingSelection, needsUpdate, editor);
|
|
5105
|
+
const mutatedNodes = updateEditorState(rootElement, currentEditorState, pendingEditorState, currentSelection, pendingSelection, needsUpdate, editor);
|
|
5106
|
+
|
|
5107
|
+
if (mutatedNodes !== null) {
|
|
5108
|
+
triggerMutationListeners(editor, currentEditorState, pendingEditorState, mutatedNodes);
|
|
5109
|
+
}
|
|
4983
5110
|
} catch (error) {
|
|
4984
5111
|
// Report errors
|
|
4985
|
-
triggerListeners('error', editor, false, error
|
|
5112
|
+
triggerListeners('error', editor, false, error); // Reset editor and restore incoming editor state to the DOM
|
|
4986
5113
|
|
|
4987
5114
|
if (!isAttemptingToRecoverFromReconcilerError) {
|
|
4988
5115
|
resetEditor(editor, null, rootElement, pendingEditorState);
|
|
4989
5116
|
initMutationObserver(editor);
|
|
4990
5117
|
editor._dirtyType = FULL_RECONCILE;
|
|
4991
5118
|
isAttemptingToRecoverFromReconcilerError = true;
|
|
4992
|
-
|
|
4993
|
-
editor._log.push('ReconcileRecover');
|
|
4994
|
-
|
|
4995
5119
|
commitPendingUpdates(editor);
|
|
4996
5120
|
isAttemptingToRecoverFromReconcilerError = false;
|
|
4997
5121
|
}
|
|
@@ -5014,8 +5138,6 @@ function commitPendingUpdates(editor) {
|
|
|
5014
5138
|
const dirtyElements = editor._dirtyElements;
|
|
5015
5139
|
const normalizedNodes = editor._normalizedNodes;
|
|
5016
5140
|
const tags = editor._updateTags;
|
|
5017
|
-
const log = editor._log;
|
|
5018
|
-
editor._log = [];
|
|
5019
5141
|
|
|
5020
5142
|
if (needsUpdate) {
|
|
5021
5143
|
editor._dirtyType = NO_DIRTY_NODES;
|
|
@@ -5042,7 +5164,6 @@ function commitPendingUpdates(editor) {
|
|
|
5042
5164
|
dirtyElements,
|
|
5043
5165
|
dirtyLeaves,
|
|
5044
5166
|
editorState: pendingEditorState,
|
|
5045
|
-
log,
|
|
5046
5167
|
normalizedNodes,
|
|
5047
5168
|
prevEditorState: currentEditorState,
|
|
5048
5169
|
tags
|
|
@@ -5060,6 +5181,19 @@ function triggerTextContentListeners(editor, currentEditorState, pendingEditorSt
|
|
|
5060
5181
|
}
|
|
5061
5182
|
}
|
|
5062
5183
|
|
|
5184
|
+
function triggerMutationListeners(editor, currentEditorState, pendingEditorState, mutatedNodes) {
|
|
5185
|
+
const listeners = editor._listeners.mutation;
|
|
5186
|
+
listeners.forEach((klass, listener) => {
|
|
5187
|
+
const mutatedNodesByType = mutatedNodes.get(klass);
|
|
5188
|
+
|
|
5189
|
+
if (mutatedNodesByType === undefined) {
|
|
5190
|
+
return;
|
|
5191
|
+
}
|
|
5192
|
+
|
|
5193
|
+
listener(mutatedNodesByType);
|
|
5194
|
+
});
|
|
5195
|
+
}
|
|
5196
|
+
|
|
5063
5197
|
function triggerListeners(type, editor, isCurrentlyEnqueuingUpdates, // $FlowFixMe: needs refining
|
|
5064
5198
|
...payload) {
|
|
5065
5199
|
const previouslyUpdating = editor._updating;
|
|
@@ -5108,7 +5242,7 @@ function triggerEnqueuedUpdates(editor) {
|
|
|
5108
5242
|
|
|
5109
5243
|
if (queuedUpdates.length !== 0) {
|
|
5110
5244
|
const [updateFn, options] = queuedUpdates.shift();
|
|
5111
|
-
beginUpdate(editor, updateFn,
|
|
5245
|
+
beginUpdate(editor, updateFn, options);
|
|
5112
5246
|
}
|
|
5113
5247
|
}
|
|
5114
5248
|
|
|
@@ -5164,7 +5298,7 @@ function processNestedUpdates(editor) {
|
|
|
5164
5298
|
return skipTransforms;
|
|
5165
5299
|
}
|
|
5166
5300
|
|
|
5167
|
-
function beginUpdate(editor, updateFn,
|
|
5301
|
+
function beginUpdate(editor, updateFn, options) {
|
|
5168
5302
|
const updateTags = editor._updateTags;
|
|
5169
5303
|
let onUpdate;
|
|
5170
5304
|
let tag;
|
|
@@ -5214,12 +5348,6 @@ function beginUpdate(editor, updateFn, skipEmptyCheck, options) {
|
|
|
5214
5348
|
applySelectionTransforms(pendingEditorState, editor);
|
|
5215
5349
|
|
|
5216
5350
|
if (editor._dirtyType !== NO_DIRTY_NODES) {
|
|
5217
|
-
if (!skipEmptyCheck && pendingEditorState.isEmpty()) {
|
|
5218
|
-
{
|
|
5219
|
-
throw Error(`updateEditor: the pending editor state is empty. Ensure the root not never becomes empty from an update.`);
|
|
5220
|
-
}
|
|
5221
|
-
}
|
|
5222
|
-
|
|
5223
5351
|
if (skipTransforms) {
|
|
5224
5352
|
$normalizeAllDirtyTextNodes(pendingEditorState, editor);
|
|
5225
5353
|
} else {
|
|
@@ -5251,7 +5379,7 @@ function beginUpdate(editor, updateFn, skipEmptyCheck, options) {
|
|
|
5251
5379
|
}
|
|
5252
5380
|
} catch (error) {
|
|
5253
5381
|
// Report errors
|
|
5254
|
-
triggerListeners('error', editor, false, error
|
|
5382
|
+
triggerListeners('error', editor, false, error); // Restore existing editor state to the DOM
|
|
5255
5383
|
|
|
5256
5384
|
editor._pendingEditorState = currentEditorState;
|
|
5257
5385
|
editor._dirtyType = FULL_RECONCILE;
|
|
@@ -5262,8 +5390,6 @@ function beginUpdate(editor, updateFn, skipEmptyCheck, options) {
|
|
|
5262
5390
|
|
|
5263
5391
|
editor._dirtyElements.clear();
|
|
5264
5392
|
|
|
5265
|
-
editor._log.push('UpdateRecover');
|
|
5266
|
-
|
|
5267
5393
|
commitPendingUpdates(editor);
|
|
5268
5394
|
return;
|
|
5269
5395
|
} finally {
|
|
@@ -5296,11 +5422,11 @@ function beginUpdate(editor, updateFn, skipEmptyCheck, options) {
|
|
|
5296
5422
|
}
|
|
5297
5423
|
}
|
|
5298
5424
|
|
|
5299
|
-
function updateEditor(editor, updateFn,
|
|
5425
|
+
function updateEditor(editor, updateFn, options) {
|
|
5300
5426
|
if (editor._updating) {
|
|
5301
5427
|
editor._updates.push([updateFn, options]);
|
|
5302
5428
|
} else {
|
|
5303
|
-
beginUpdate(editor, updateFn,
|
|
5429
|
+
beginUpdate(editor, updateFn, options);
|
|
5304
5430
|
}
|
|
5305
5431
|
}
|
|
5306
5432
|
|
|
@@ -5592,7 +5718,7 @@ class ElementNode extends LexicalNode {
|
|
|
5592
5718
|
const lastChild = this.getLastChild();
|
|
5593
5719
|
|
|
5594
5720
|
if (lastChild !== null) {
|
|
5595
|
-
|
|
5721
|
+
internalMarkNodeAsDirty(lastChild);
|
|
5596
5722
|
}
|
|
5597
5723
|
|
|
5598
5724
|
for (let i = 0; i < nodesToAppendLength; i++) {
|
|
@@ -5683,7 +5809,7 @@ class ElementNode extends LexicalNode {
|
|
|
5683
5809
|
}
|
|
5684
5810
|
}
|
|
5685
5811
|
|
|
5686
|
-
|
|
5812
|
+
internalMarkSiblingsAsDirty(nodeToInsert);
|
|
5687
5813
|
children.splice(index, 1);
|
|
5688
5814
|
} // Set child parent to self
|
|
5689
5815
|
|
|
@@ -5697,13 +5823,13 @@ class ElementNode extends LexicalNode {
|
|
|
5697
5823
|
const nodeBeforeRange = this.getChildAtIndex(start - 1);
|
|
5698
5824
|
|
|
5699
5825
|
if (nodeBeforeRange) {
|
|
5700
|
-
|
|
5826
|
+
internalMarkNodeAsDirty(nodeBeforeRange);
|
|
5701
5827
|
}
|
|
5702
5828
|
|
|
5703
5829
|
const nodeAfterRange = this.getChildAtIndex(start + deleteCount);
|
|
5704
5830
|
|
|
5705
5831
|
if (nodeAfterRange) {
|
|
5706
|
-
|
|
5832
|
+
internalMarkNodeAsDirty(nodeAfterRange);
|
|
5707
5833
|
} // Remove defined range of children
|
|
5708
5834
|
|
|
5709
5835
|
|
|
@@ -5815,10 +5941,6 @@ class ElementNode extends LexicalNode {
|
|
|
5815
5941
|
return false;
|
|
5816
5942
|
}
|
|
5817
5943
|
|
|
5818
|
-
canSelectionRemove() {
|
|
5819
|
-
return true;
|
|
5820
|
-
}
|
|
5821
|
-
|
|
5822
5944
|
canMergeWith(node) {
|
|
5823
5945
|
return false;
|
|
5824
5946
|
}
|
|
@@ -5850,6 +5972,12 @@ class RootNode extends ElementNode {
|
|
|
5850
5972
|
this.__cachedText = null;
|
|
5851
5973
|
}
|
|
5852
5974
|
|
|
5975
|
+
getTopLevelElementOrThrow() {
|
|
5976
|
+
{
|
|
5977
|
+
throw Error(`getTopLevelElementOrThrow: root nodes are not top level elements`);
|
|
5978
|
+
}
|
|
5979
|
+
}
|
|
5980
|
+
|
|
5853
5981
|
getTextContent(includeInert, includeDirectionless) {
|
|
5854
5982
|
const cachedText = this.__cachedText;
|
|
5855
5983
|
|
|
@@ -5862,22 +5990,13 @@ class RootNode extends ElementNode {
|
|
|
5862
5990
|
return super.getTextContent(includeInert, includeDirectionless);
|
|
5863
5991
|
}
|
|
5864
5992
|
|
|
5865
|
-
select() {
|
|
5866
|
-
// You can't select root nodes.
|
|
5867
|
-
{
|
|
5868
|
-
throw Error(`select: cannot be called on root nodes`);
|
|
5869
|
-
}
|
|
5870
|
-
}
|
|
5871
|
-
|
|
5872
5993
|
remove() {
|
|
5873
|
-
// You can't select root nodes.
|
|
5874
5994
|
{
|
|
5875
5995
|
throw Error(`remove: cannot be called on root nodes`);
|
|
5876
5996
|
}
|
|
5877
5997
|
}
|
|
5878
5998
|
|
|
5879
5999
|
replace(node) {
|
|
5880
|
-
// You can't select root nodes.
|
|
5881
6000
|
{
|
|
5882
6001
|
throw Error(`replace: cannot be called on root nodes`);
|
|
5883
6002
|
}
|
|
@@ -5915,10 +6034,6 @@ class RootNode extends ElementNode {
|
|
|
5915
6034
|
return super.append(...nodesToAppend);
|
|
5916
6035
|
}
|
|
5917
6036
|
|
|
5918
|
-
canBeEmpty() {
|
|
5919
|
-
return false;
|
|
5920
|
-
}
|
|
5921
|
-
|
|
5922
6037
|
}
|
|
5923
6038
|
function $createRootNode() {
|
|
5924
6039
|
return new RootNode();
|
|
@@ -6023,27 +6138,14 @@ if (CAN_USE_BEFORE_INPUT) {
|
|
|
6023
6138
|
}
|
|
6024
6139
|
|
|
6025
6140
|
let lastKeyWasMaybeAndroidSoftKey = false;
|
|
6141
|
+
let rootElementsRegistered = 0;
|
|
6026
6142
|
|
|
6027
|
-
function onSelectionChange(editor) {
|
|
6028
|
-
const domSelection = window.getSelection();
|
|
6029
|
-
const parentEditors = getEditorsToPropagate(editor);
|
|
6030
|
-
const topLevelEditor = parentEditors[parentEditors.length - 1];
|
|
6031
|
-
const topLevelEditorElement = topLevelEditor.getRootElement(); // This is a hot-path, so let's avoid doing an update when
|
|
6032
|
-
// the anchorNode is not actually inside the editor (or its parent).
|
|
6033
|
-
|
|
6034
|
-
if (topLevelEditorElement && !topLevelEditorElement.contains(domSelection.anchorNode)) {
|
|
6035
|
-
return;
|
|
6036
|
-
} // This update functions as a way of reconciling a bad selection
|
|
6037
|
-
// to a good selection.
|
|
6038
|
-
|
|
6039
|
-
|
|
6143
|
+
function onSelectionChange(editor, isActive) {
|
|
6040
6144
|
editor.update(() => {
|
|
6041
|
-
|
|
6145
|
+
// Non-active editor don't need any extra logic for selection, it only needs update
|
|
6042
6146
|
// to reconcile selection (set it to null) to ensure that only one editor has non-null selection.
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
if (!isActiveEditor) {
|
|
6147
|
+
if (!isActive) {
|
|
6148
|
+
$setSelection(null);
|
|
6047
6149
|
return;
|
|
6048
6150
|
}
|
|
6049
6151
|
|
|
@@ -6071,7 +6173,6 @@ function onSelectionChange(editor) {
|
|
|
6071
6173
|
|
|
6072
6174
|
function onClick(event, editor) {
|
|
6073
6175
|
editor.update(() => {
|
|
6074
|
-
$pushLogEntry('onClick');
|
|
6075
6176
|
const selection = $getSelection();
|
|
6076
6177
|
|
|
6077
6178
|
if (selection === null) {
|
|
@@ -6113,7 +6214,6 @@ function onBeforeInput(event, editor) {
|
|
|
6113
6214
|
}
|
|
6114
6215
|
|
|
6115
6216
|
editor.update(() => {
|
|
6116
|
-
$pushLogEntry('onBeforeInputForRichText');
|
|
6117
6217
|
const selection = $getSelection();
|
|
6118
6218
|
|
|
6119
6219
|
if (selection === null) {
|
|
@@ -6130,7 +6230,7 @@ function onBeforeInput(event, editor) {
|
|
|
6130
6230
|
|
|
6131
6231
|
const data = event.data;
|
|
6132
6232
|
|
|
6133
|
-
if (!selection.dirty && selection.isCollapsed()) {
|
|
6233
|
+
if (!selection.dirty && selection.isCollapsed() && !$isRootNode(selection.anchor.getNode())) {
|
|
6134
6234
|
$applyTargetRange(selection, event);
|
|
6135
6235
|
}
|
|
6136
6236
|
|
|
@@ -6297,7 +6397,6 @@ function onInput(event, editor) {
|
|
|
6297
6397
|
// We don't want the onInput to bubble, in the case of nested editors.
|
|
6298
6398
|
event.stopPropagation();
|
|
6299
6399
|
editor.update(() => {
|
|
6300
|
-
$pushLogEntry('onInput');
|
|
6301
6400
|
const selection = $getSelection();
|
|
6302
6401
|
const data = event.data;
|
|
6303
6402
|
|
|
@@ -6315,7 +6414,6 @@ function onInput(event, editor) {
|
|
|
6315
6414
|
|
|
6316
6415
|
function onCompositionStart(event, editor) {
|
|
6317
6416
|
editor.update(() => {
|
|
6318
|
-
$pushLogEntry('onCompositionStart');
|
|
6319
6417
|
const selection = $getSelection();
|
|
6320
6418
|
|
|
6321
6419
|
if (selection !== null && !editor.isComposing()) {
|
|
@@ -6335,7 +6433,6 @@ function onCompositionStart(event, editor) {
|
|
|
6335
6433
|
|
|
6336
6434
|
function onCompositionEndInternal(event, editor) {
|
|
6337
6435
|
editor.update(() => {
|
|
6338
|
-
$pushLogEntry('onCompositionEnd');
|
|
6339
6436
|
$setCompositionKey(null);
|
|
6340
6437
|
$updateSelectedTextFromDOM(editor, true);
|
|
6341
6438
|
});
|
|
@@ -6443,12 +6540,12 @@ function isRootEditable(editor) {
|
|
|
6443
6540
|
|
|
6444
6541
|
function getRootElementRemoveHandles(rootElement) {
|
|
6445
6542
|
// $FlowFixMe: internal field
|
|
6446
|
-
let eventHandles = rootElement.
|
|
6543
|
+
let eventHandles = rootElement.__lexicalEventHandles;
|
|
6447
6544
|
|
|
6448
6545
|
if (eventHandles === undefined) {
|
|
6449
6546
|
eventHandles = []; // $FlowFixMe: internal field
|
|
6450
6547
|
|
|
6451
|
-
rootElement.
|
|
6548
|
+
rootElement.__lexicalEventHandles = eventHandles;
|
|
6452
6549
|
}
|
|
6453
6550
|
|
|
6454
6551
|
return eventHandles;
|
|
@@ -6457,7 +6554,11 @@ function getRootElementRemoveHandles(rootElement) {
|
|
|
6457
6554
|
function clearRootElementRemoveHandles(rootElement) {
|
|
6458
6555
|
// $FlowFixMe: internal field
|
|
6459
6556
|
rootElement._lexicalEventHandles = [];
|
|
6460
|
-
}
|
|
6557
|
+
} // Mapping root editors to their active nested editors, contains nested editors
|
|
6558
|
+
// mapping only, so if root editor is selected map will have no reference to free up memory
|
|
6559
|
+
|
|
6560
|
+
|
|
6561
|
+
const activeNestedEditorsMap = new Map();
|
|
6461
6562
|
|
|
6462
6563
|
function onDocumentSelectionChange(event) {
|
|
6463
6564
|
const sel = window.getSelection();
|
|
@@ -6465,10 +6566,31 @@ function onDocumentSelectionChange(event) {
|
|
|
6465
6566
|
|
|
6466
6567
|
while (node != null) {
|
|
6467
6568
|
if (node.contentEditable === 'true') {
|
|
6468
|
-
const
|
|
6569
|
+
const nextActiveEditor = node.__lexicalEditor;
|
|
6570
|
+
|
|
6571
|
+
if (nextActiveEditor !== undefined) {
|
|
6572
|
+
// When editor receives selection change event, we're checking if
|
|
6573
|
+
// it has any sibling editors (within same parent editor) that were active
|
|
6574
|
+
// before, and trigger selection change on it to nullify selection.
|
|
6575
|
+
const editors = getEditorsToPropagate(nextActiveEditor);
|
|
6576
|
+
const rootEditor = editors[editors.length - 1];
|
|
6577
|
+
const rootEditorKey = rootEditor._key;
|
|
6578
|
+
const activeNestedEditor = activeNestedEditorsMap.get(rootEditorKey);
|
|
6579
|
+
const prevActiveEditor = activeNestedEditor || rootEditor;
|
|
6580
|
+
|
|
6581
|
+
if (prevActiveEditor !== nextActiveEditor) {
|
|
6582
|
+
onSelectionChange(prevActiveEditor, false);
|
|
6583
|
+
}
|
|
6584
|
+
|
|
6585
|
+
onSelectionChange(nextActiveEditor, true); // If newly selected editor is nested, then add it to the map, clean map otherwise
|
|
6469
6586
|
|
|
6470
|
-
|
|
6471
|
-
|
|
6587
|
+
if (nextActiveEditor !== rootEditor) {
|
|
6588
|
+
activeNestedEditorsMap.set(rootEditorKey, nextActiveEditor);
|
|
6589
|
+
} else if (activeNestedEditor) {
|
|
6590
|
+
activeNestedEditorsMap.delete(rootEditorKey);
|
|
6591
|
+
}
|
|
6592
|
+
|
|
6593
|
+
return;
|
|
6472
6594
|
}
|
|
6473
6595
|
}
|
|
6474
6596
|
|
|
@@ -6476,18 +6598,17 @@ function onDocumentSelectionChange(event) {
|
|
|
6476
6598
|
}
|
|
6477
6599
|
}
|
|
6478
6600
|
|
|
6479
|
-
function
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
if (doc._lexicalEvent === undefined) {
|
|
6485
|
-
// $FlowFixMe: internal field
|
|
6486
|
-
doc._lexicalEvent = true;
|
|
6601
|
+
function addRootElementEvents(rootElement, editor) {
|
|
6602
|
+
// We only want to have a single global selectionchange event handler, shared
|
|
6603
|
+
// between all editor instances.
|
|
6604
|
+
if (rootElementsRegistered === 0) {
|
|
6605
|
+
const doc = rootElement.ownerDocument;
|
|
6487
6606
|
doc.addEventListener('selectionchange', onDocumentSelectionChange);
|
|
6488
6607
|
}
|
|
6489
|
-
|
|
6490
|
-
|
|
6608
|
+
|
|
6609
|
+
rootElementsRegistered++; // $FlowFixMe: internal field
|
|
6610
|
+
|
|
6611
|
+
rootElement.__lexicalEditor = editor;
|
|
6491
6612
|
const removeHandles = getRootElementRemoveHandles(rootElement);
|
|
6492
6613
|
|
|
6493
6614
|
for (let i = 0; i < rootElementEvents.length; i++) {
|
|
@@ -6508,7 +6629,17 @@ function addRootElementEvents(rootElement, editor) {
|
|
|
6508
6629
|
}
|
|
6509
6630
|
}
|
|
6510
6631
|
function removeRootElementEvents(rootElement) {
|
|
6511
|
-
//
|
|
6632
|
+
rootElementsRegistered--; // We only want to have a single global selectionchange event handler, shared
|
|
6633
|
+
// between all editor instances.
|
|
6634
|
+
|
|
6635
|
+
if (rootElementsRegistered === 0) {
|
|
6636
|
+
const doc = rootElement.ownerDocument;
|
|
6637
|
+
doc.removeEventListener('selectionchange', onDocumentSelectionChange);
|
|
6638
|
+
} // $FlowFixMe: internal field
|
|
6639
|
+
|
|
6640
|
+
|
|
6641
|
+
cleanActiveNestedEditorsMap(rootElement.__lexicalEditor); // $FlowFixMe: internal field
|
|
6642
|
+
|
|
6512
6643
|
rootElement.__lexicalEditor = null;
|
|
6513
6644
|
const removeHandles = getRootElementRemoveHandles(rootElement);
|
|
6514
6645
|
|
|
@@ -6519,43 +6650,21 @@ function removeRootElementEvents(rootElement) {
|
|
|
6519
6650
|
clearRootElementRemoveHandles(rootElement);
|
|
6520
6651
|
}
|
|
6521
6652
|
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
*/
|
|
6530
|
-
class HorizontalRuleNode extends LexicalNode {
|
|
6531
|
-
static getType() {
|
|
6532
|
-
return 'horizontal-rule';
|
|
6533
|
-
}
|
|
6534
|
-
|
|
6535
|
-
static clone(node) {
|
|
6536
|
-
return new HorizontalRuleNode(node.__key);
|
|
6537
|
-
}
|
|
6538
|
-
|
|
6539
|
-
constructor(key) {
|
|
6540
|
-
super(key);
|
|
6541
|
-
}
|
|
6542
|
-
|
|
6543
|
-
createDOM() {
|
|
6544
|
-
const element = document.createElement('hr');
|
|
6545
|
-
element.setAttribute('contenteditable', 'false');
|
|
6546
|
-
return element;
|
|
6547
|
-
}
|
|
6653
|
+
function cleanActiveNestedEditorsMap(editor) {
|
|
6654
|
+
// $FlowFixMe: internal field
|
|
6655
|
+
if (editor._parentEditor) {
|
|
6656
|
+
// For nested editor cleanup map if this editor was marked as active
|
|
6657
|
+
const editors = getEditorsToPropagate(editor);
|
|
6658
|
+
const rootEditor = editors[editors.length - 1];
|
|
6659
|
+
const rootEditorKey = rootEditor._key;
|
|
6548
6660
|
|
|
6549
|
-
|
|
6550
|
-
|
|
6661
|
+
if (activeNestedEditorsMap.get(rootEditorKey) === editor) {
|
|
6662
|
+
activeNestedEditorsMap.delete(rootEditorKey);
|
|
6663
|
+
}
|
|
6664
|
+
} else {
|
|
6665
|
+
// For top-level editors cleanup map
|
|
6666
|
+
activeNestedEditorsMap.delete(editor._key);
|
|
6551
6667
|
}
|
|
6552
|
-
|
|
6553
|
-
}
|
|
6554
|
-
function $createHorizontalRuleNode() {
|
|
6555
|
-
return new HorizontalRuleNode();
|
|
6556
|
-
}
|
|
6557
|
-
function $isHorizontalRuleNode(node) {
|
|
6558
|
-
return node instanceof HorizontalRuleNode;
|
|
6559
6668
|
}
|
|
6560
6669
|
|
|
6561
6670
|
/**
|
|
@@ -6685,7 +6794,25 @@ function setTextThemeClassNames(tag, prevFormat, nextFormat, dom, textClassNames
|
|
|
6685
6794
|
}
|
|
6686
6795
|
}
|
|
6687
6796
|
|
|
6797
|
+
function diffComposedText(a, b) {
|
|
6798
|
+
const aLength = a.length;
|
|
6799
|
+
const bLength = b.length;
|
|
6800
|
+
let left = 0;
|
|
6801
|
+
let right = 0;
|
|
6802
|
+
|
|
6803
|
+
while (left < aLength && left < bLength && a[left] === b[left]) {
|
|
6804
|
+
left++;
|
|
6805
|
+
}
|
|
6806
|
+
|
|
6807
|
+
while (right + left < aLength && right + left < bLength && a[aLength - right - 1] === b[bLength - right - 1]) {
|
|
6808
|
+
right++;
|
|
6809
|
+
}
|
|
6810
|
+
|
|
6811
|
+
return [left, aLength - left - right, b.slice(left, bLength - right)];
|
|
6812
|
+
}
|
|
6813
|
+
|
|
6688
6814
|
function setTextContent(nextText, dom, node) {
|
|
6815
|
+
// $FlowFixMe: first node is always text
|
|
6689
6816
|
const firstChild = dom.firstChild;
|
|
6690
6817
|
const isComposing = node.isComposing(); // Always add a suffix if we're composing a node
|
|
6691
6818
|
|
|
@@ -6694,8 +6821,19 @@ function setTextContent(nextText, dom, node) {
|
|
|
6694
6821
|
|
|
6695
6822
|
if (firstChild == null) {
|
|
6696
6823
|
dom.textContent = text;
|
|
6697
|
-
} else
|
|
6698
|
-
|
|
6824
|
+
} else {
|
|
6825
|
+
const nodeValue = firstChild.nodeValue;
|
|
6826
|
+
if (nodeValue !== text) if (isComposing) {
|
|
6827
|
+
const [index, remove, insert] = diffComposedText(nodeValue, text);
|
|
6828
|
+
|
|
6829
|
+
if (remove !== 0) {
|
|
6830
|
+
firstChild.deleteData(index, remove);
|
|
6831
|
+
}
|
|
6832
|
+
|
|
6833
|
+
firstChild.insertData(index, insert);
|
|
6834
|
+
} else {
|
|
6835
|
+
firstChild.nodeValue = text;
|
|
6836
|
+
}
|
|
6699
6837
|
}
|
|
6700
6838
|
}
|
|
6701
6839
|
|
|
@@ -7097,7 +7235,7 @@ class TextNode extends LexicalNode {
|
|
|
7097
7235
|
} // Insert the nodes into the parent's children
|
|
7098
7236
|
|
|
7099
7237
|
|
|
7100
|
-
|
|
7238
|
+
internalMarkSiblingsAsDirty(this);
|
|
7101
7239
|
const writableParent = parent.getWritable();
|
|
7102
7240
|
const writableParentChildren = writableParent.__children;
|
|
7103
7241
|
const insertionIndex = writableParentChildren.indexOf(key);
|
|
@@ -7215,21 +7353,25 @@ class ParagraphNode extends ElementNode {
|
|
|
7215
7353
|
}
|
|
7216
7354
|
|
|
7217
7355
|
collapseAtStart() {
|
|
7218
|
-
const children = this.getChildren();
|
|
7219
|
-
const sibling = this.getNextSibling(); // If we have an empty (trimmed) first paragraph and try and remove it,
|
|
7356
|
+
const children = this.getChildren(); // If we have an empty (trimmed) first paragraph and try and remove it,
|
|
7220
7357
|
// delete the paragraph as long as we have another sibling to go to
|
|
7221
7358
|
|
|
7222
|
-
if (
|
|
7223
|
-
const
|
|
7359
|
+
if (children.length === 0 || $isTextNode(children[0]) && children[0].getTextContent().trim() === '') {
|
|
7360
|
+
const nextSibling = this.getNextSibling();
|
|
7224
7361
|
|
|
7225
|
-
if (
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7362
|
+
if (nextSibling !== null) {
|
|
7363
|
+
this.selectNext();
|
|
7364
|
+
this.remove();
|
|
7365
|
+
return true;
|
|
7229
7366
|
}
|
|
7230
7367
|
|
|
7231
|
-
this.
|
|
7232
|
-
|
|
7368
|
+
const prevSibling = this.getPreviousSibling();
|
|
7369
|
+
|
|
7370
|
+
if (prevSibling !== null) {
|
|
7371
|
+
this.selectPrevious();
|
|
7372
|
+
this.remove();
|
|
7373
|
+
return true;
|
|
7374
|
+
}
|
|
7233
7375
|
}
|
|
7234
7376
|
|
|
7235
7377
|
return false;
|
|
@@ -7267,7 +7409,6 @@ function resetEditor(editor, prevRootElement, nextRootElement, pendingEditorStat
|
|
|
7267
7409
|
|
|
7268
7410
|
editor._normalizedNodes = new Set();
|
|
7269
7411
|
editor._updateTags = new Set();
|
|
7270
|
-
editor._log = [];
|
|
7271
7412
|
editor._updates = [];
|
|
7272
7413
|
const observer = editor._observer;
|
|
7273
7414
|
|
|
@@ -7296,7 +7437,7 @@ function createEditor(editorConfig) {
|
|
|
7296
7437
|
const disableEvents = config.disableEvents || false;
|
|
7297
7438
|
const editorState = createEmptyEditorState();
|
|
7298
7439
|
const initialEditorState = config.editorState;
|
|
7299
|
-
const nodes = [RootNode, TextNode,
|
|
7440
|
+
const nodes = [RootNode, TextNode, LineBreakNode, ParagraphNode, ...(config.nodes || [])];
|
|
7300
7441
|
const registeredNodes = new Map();
|
|
7301
7442
|
|
|
7302
7443
|
for (let i = 0; i < nodes.length; i++) {
|
|
@@ -7353,9 +7494,9 @@ class BaseLexicalEditor {
|
|
|
7353
7494
|
command: [new Set(), new Set(), new Set(), new Set(), new Set()],
|
|
7354
7495
|
decorator: new Set(),
|
|
7355
7496
|
error: new Set(),
|
|
7497
|
+
mutation: new Map(),
|
|
7356
7498
|
root: new Set(),
|
|
7357
7499
|
textcontent: new Set(),
|
|
7358
|
-
textmutation: new Set(),
|
|
7359
7500
|
update: new Set()
|
|
7360
7501
|
}; // Editor configuration for theme/context.
|
|
7361
7502
|
|
|
@@ -7373,9 +7514,7 @@ class BaseLexicalEditor {
|
|
|
7373
7514
|
this._normalizedNodes = new Set();
|
|
7374
7515
|
this._updateTags = new Set(); // Handling of DOM mutations
|
|
7375
7516
|
|
|
7376
|
-
this._observer = null; //
|
|
7377
|
-
|
|
7378
|
-
this._log = []; // Used for identifying owning editors
|
|
7517
|
+
this._observer = null; // Used for identifying owning editors
|
|
7379
7518
|
|
|
7380
7519
|
this._key = generateRandomKey();
|
|
7381
7520
|
}
|
|
@@ -7384,27 +7523,50 @@ class BaseLexicalEditor {
|
|
|
7384
7523
|
return this._compositionKey != null;
|
|
7385
7524
|
}
|
|
7386
7525
|
|
|
7387
|
-
addListener(type,
|
|
7526
|
+
addListener(type, arg1, arg2) {
|
|
7388
7527
|
const listenerSetOrMap = this._listeners[type];
|
|
7389
7528
|
|
|
7390
7529
|
if (type === 'command') {
|
|
7530
|
+
// $FlowFixMe: TODO refine
|
|
7531
|
+
const listener = arg1; // $FlowFixMe: TODO refine
|
|
7532
|
+
|
|
7533
|
+
const priority = arg2;
|
|
7534
|
+
|
|
7391
7535
|
if (priority === undefined) {
|
|
7392
7536
|
{
|
|
7393
7537
|
throw Error(`Listener for type "command" requires a "priority".`);
|
|
7394
7538
|
}
|
|
7395
|
-
} // $FlowFixMe: unsure how to
|
|
7539
|
+
} // $FlowFixMe: unsure how to cast this
|
|
7396
7540
|
|
|
7397
7541
|
|
|
7398
7542
|
const commands = listenerSetOrMap;
|
|
7399
|
-
const commandSet = commands[priority];
|
|
7400
|
-
|
|
7543
|
+
const commandSet = commands[priority];
|
|
7401
7544
|
commandSet.add(listener);
|
|
7402
7545
|
return () => {
|
|
7403
|
-
// $FlowFixMe: cast
|
|
7404
7546
|
commandSet.delete(listener);
|
|
7405
7547
|
};
|
|
7548
|
+
} else if (type === 'mutation') {
|
|
7549
|
+
// $FlowFixMe: refine
|
|
7550
|
+
const klass = arg1; // $FlowFixMe: refine
|
|
7551
|
+
|
|
7552
|
+
const mutationListener = arg2;
|
|
7553
|
+
|
|
7554
|
+
const registeredNode = this._nodes.get(klass.getType());
|
|
7555
|
+
|
|
7556
|
+
if (registeredNode === undefined) {
|
|
7557
|
+
{
|
|
7558
|
+
throw Error(`Node ${klass.name} has not been registered. Ensure node has been passed to createEditor.`);
|
|
7559
|
+
}
|
|
7560
|
+
}
|
|
7561
|
+
|
|
7562
|
+
const mutations = this._listeners.mutation;
|
|
7563
|
+
mutations.set(mutationListener, klass);
|
|
7564
|
+
return () => {
|
|
7565
|
+
mutations.delete(mutationListener);
|
|
7566
|
+
};
|
|
7406
7567
|
} else {
|
|
7407
|
-
// $FlowFixMe: TODO refine this from the above types
|
|
7568
|
+
const listener = arg1; // $FlowFixMe: TODO refine this from the above types
|
|
7569
|
+
|
|
7408
7570
|
listenerSetOrMap.add(listener);
|
|
7409
7571
|
const isRootType = type === 'root';
|
|
7410
7572
|
|
|
@@ -7497,12 +7659,11 @@ class BaseLexicalEditor {
|
|
|
7497
7659
|
this._dirtyType = FULL_RECONCILE;
|
|
7498
7660
|
initMutationObserver(getSelf(this));
|
|
7499
7661
|
|
|
7500
|
-
this._updateTags.add('
|
|
7662
|
+
this._updateTags.add('history-merge');
|
|
7501
7663
|
|
|
7502
7664
|
commitPendingUpdates(getSelf(this)); // TODO: remove this flag once we no longer use UEv2 internally
|
|
7503
7665
|
|
|
7504
7666
|
if (!this._config.disableEvents) {
|
|
7505
|
-
addDocumentSelectionChangeEvent(nextRootElement, getSelf(this));
|
|
7506
7667
|
addRootElementEvents(nextRootElement, getSelf(this));
|
|
7507
7668
|
}
|
|
7508
7669
|
}
|
|
@@ -7557,7 +7718,7 @@ class BaseLexicalEditor {
|
|
|
7557
7718
|
}
|
|
7558
7719
|
|
|
7559
7720
|
update(updateFn, options) {
|
|
7560
|
-
updateEditor(getSelf(this), updateFn,
|
|
7721
|
+
updateEditor(getSelf(this), updateFn, options);
|
|
7561
7722
|
}
|
|
7562
7723
|
|
|
7563
7724
|
focus(callbackFn) {
|
|
@@ -7576,7 +7737,7 @@ class BaseLexicalEditor {
|
|
|
7576
7737
|
} else if (root.getChildrenSize() !== 0) {
|
|
7577
7738
|
root.selectEnd();
|
|
7578
7739
|
}
|
|
7579
|
-
},
|
|
7740
|
+
}, {
|
|
7580
7741
|
onUpdate: () => {
|
|
7581
7742
|
rootElement.removeAttribute('autocapitalize');
|
|
7582
7743
|
|
|
@@ -7600,13 +7761,11 @@ class BaseLexicalEditor {
|
|
|
7600
7761
|
// For some reason, we can't do this via an interface without
|
|
7601
7762
|
// Flow messing up the types. It's hacky, but it improves DX.
|
|
7602
7763
|
|
|
7603
|
-
exports.$createHorizontalRuleNode = $createHorizontalRuleNode;
|
|
7604
7764
|
exports.$createLineBreakNode = $createLineBreakNode;
|
|
7605
7765
|
exports.$createNodeFromParse = $createNodeFromParse;
|
|
7606
7766
|
exports.$createParagraphNode = $createParagraphNode;
|
|
7607
7767
|
exports.$createRangeSelection = $createEmptyRangeSelection;
|
|
7608
7768
|
exports.$createTextNode = $createTextNode;
|
|
7609
|
-
exports.$getCompositionKey = $getCompositionKey;
|
|
7610
7769
|
exports.$getNearestNodeFromDOMNode = $getNearestNodeFromDOMNode;
|
|
7611
7770
|
exports.$getNodeByKey = $getNodeByKey;
|
|
7612
7771
|
exports.$getPreviousSelection = $getPreviousSelection;
|
|
@@ -7614,14 +7773,12 @@ exports.$getRoot = $getRoot;
|
|
|
7614
7773
|
exports.$getSelection = $getSelection;
|
|
7615
7774
|
exports.$isDecoratorNode = $isDecoratorNode;
|
|
7616
7775
|
exports.$isElementNode = $isElementNode;
|
|
7617
|
-
exports.$isHorizontalRuleNode = $isHorizontalRuleNode;
|
|
7618
7776
|
exports.$isLeafNode = $isLeafNode;
|
|
7619
7777
|
exports.$isLineBreakNode = $isLineBreakNode;
|
|
7620
7778
|
exports.$isParagraphNode = $isParagraphNode;
|
|
7621
7779
|
exports.$isRangeSelection = $isRangeSelection;
|
|
7622
7780
|
exports.$isRootNode = $isRootNode;
|
|
7623
7781
|
exports.$isTextNode = $isTextNode;
|
|
7624
|
-
exports.$log = $pushLogEntry;
|
|
7625
7782
|
exports.$setCompositionKey = $setCompositionKey;
|
|
7626
7783
|
exports.$setSelection = $setSelection;
|
|
7627
7784
|
exports.DecoratorNode = DecoratorNode;
|