lexical 0.26.0 → 0.27.0
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 +254 -328
- package/Lexical.dev.mjs +254 -329
- package/Lexical.js.flow +4 -0
- package/Lexical.mjs +1 -0
- package/Lexical.node.mjs +1 -0
- package/Lexical.prod.js +1 -1
- package/Lexical.prod.mjs +1 -1
- package/LexicalCommands.d.ts +5 -1
- package/LexicalEditor.d.ts +1 -0
- package/LexicalNode.d.ts +2 -3
- package/caret/LexicalCaretUtils.d.ts +13 -0
- package/index.d.ts +1 -1
- package/nodes/LexicalDecoratorNode.d.ts +1 -1
- package/package.json +1 -1
package/Lexical.dev.js
CHANGED
|
@@ -8,7 +8,19 @@
|
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the MIT license found in the
|
|
15
|
+
* LICENSE file in the root directory of this source tree.
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Do not require this module directly! Use normal `invariant` calls.
|
|
20
|
+
|
|
21
|
+
function formatDevErrorMessage(message) {
|
|
22
|
+
throw new Error(message);
|
|
23
|
+
}
|
|
12
24
|
|
|
13
25
|
/**
|
|
14
26
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -459,14 +471,6 @@ function initMutationObserver(editor) {
|
|
|
459
471
|
});
|
|
460
472
|
}
|
|
461
473
|
|
|
462
|
-
/**
|
|
463
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
464
|
-
*
|
|
465
|
-
* This source code is licensed under the MIT license found in the
|
|
466
|
-
* LICENSE file in the root directory of this source tree.
|
|
467
|
-
*
|
|
468
|
-
*/
|
|
469
|
-
|
|
470
474
|
function coerceToJSON(v) {
|
|
471
475
|
return v;
|
|
472
476
|
}
|
|
@@ -652,7 +656,7 @@ function $checkCollision(node, stateConfig, state) {
|
|
|
652
656
|
const collision = state.sharedConfigMap.get(stateConfig.key);
|
|
653
657
|
if (collision !== undefined && collision !== stateConfig) {
|
|
654
658
|
{
|
|
655
|
-
|
|
659
|
+
formatDevErrorMessage(`$setState: State key collision ${JSON.stringify(stateConfig.key)} detected in ${node.constructor.name} node with type ${node.getType()} and key ${node.getKey()}. Only one StateConfig with a given key should be used on a node.`);
|
|
656
660
|
}
|
|
657
661
|
}
|
|
658
662
|
}
|
|
@@ -768,11 +772,11 @@ class NodeState {
|
|
|
768
772
|
const computedSize = size !== undefined ? size : computeSize(sharedConfigMap, unknownState, knownState);
|
|
769
773
|
{
|
|
770
774
|
if (!(size === undefined || computedSize === size)) {
|
|
771
|
-
|
|
775
|
+
formatDevErrorMessage(`NodeState: size != computedSize (${String(size)} != ${String(computedSize)})`);
|
|
772
776
|
}
|
|
773
777
|
for (const stateConfig of knownState.keys()) {
|
|
774
778
|
if (!sharedConfigMap.has(stateConfig.key)) {
|
|
775
|
-
|
|
779
|
+
formatDevErrorMessage(`NodeState: sharedConfigMap missing knownState key ${stateConfig.key}`);
|
|
776
780
|
}
|
|
777
781
|
}
|
|
778
782
|
}
|
|
@@ -1141,14 +1145,6 @@ function $normalizePoint(point) {
|
|
|
1141
1145
|
}
|
|
1142
1146
|
}
|
|
1143
1147
|
|
|
1144
|
-
/**
|
|
1145
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
1146
|
-
*
|
|
1147
|
-
* This source code is licensed under the MIT license found in the
|
|
1148
|
-
* LICENSE file in the root directory of this source tree.
|
|
1149
|
-
*
|
|
1150
|
-
*/
|
|
1151
|
-
|
|
1152
1148
|
let subTreeTextContent = '';
|
|
1153
1149
|
let subTreeDirectionedTextContent = '';
|
|
1154
1150
|
let subTreeTextFormat = null;
|
|
@@ -1237,7 +1233,7 @@ function $createNode(key, slot) {
|
|
|
1237
1233
|
const node = activeNextNodeMap.get(key);
|
|
1238
1234
|
if (node === undefined) {
|
|
1239
1235
|
{
|
|
1240
|
-
|
|
1236
|
+
formatDevErrorMessage(`createNode: node does not exist in nodeMap`);
|
|
1241
1237
|
}
|
|
1242
1238
|
}
|
|
1243
1239
|
const dom = node.createDOM(activeEditorConfig, activeEditor$1);
|
|
@@ -1431,7 +1427,7 @@ function createChildrenArray(element, nodeMap) {
|
|
|
1431
1427
|
const node = nodeMap.get(nodeKey);
|
|
1432
1428
|
if (node === undefined) {
|
|
1433
1429
|
{
|
|
1434
|
-
|
|
1430
|
+
formatDevErrorMessage(`createChildrenArray: node does not exist in nodeMap`);
|
|
1435
1431
|
}
|
|
1436
1432
|
}
|
|
1437
1433
|
children.push(nodeKey);
|
|
@@ -1478,10 +1474,10 @@ function $reconcileChildren(prevElement, nextElement, slot) {
|
|
|
1478
1474
|
const prevChildren = createChildrenArray(prevElement, activePrevNodeMap);
|
|
1479
1475
|
const nextChildren = createChildrenArray(nextElement, activeNextNodeMap);
|
|
1480
1476
|
if (!(prevChildren.length === prevChildrenSize)) {
|
|
1481
|
-
|
|
1477
|
+
formatDevErrorMessage(`$reconcileChildren: prevChildren.length !== prevChildrenSize`);
|
|
1482
1478
|
}
|
|
1483
1479
|
if (!(nextChildren.length === nextChildrenSize)) {
|
|
1484
|
-
|
|
1480
|
+
formatDevErrorMessage(`$reconcileChildren: nextChildren.length !== nextChildrenSize`);
|
|
1485
1481
|
}
|
|
1486
1482
|
if (prevChildrenSize === 0) {
|
|
1487
1483
|
if (nextChildrenSize !== 0) {
|
|
@@ -1511,7 +1507,7 @@ function $reconcileNode(key, parentDOM) {
|
|
|
1511
1507
|
let nextNode = activeNextNodeMap.get(key);
|
|
1512
1508
|
if (prevNode === undefined || nextNode === undefined) {
|
|
1513
1509
|
{
|
|
1514
|
-
|
|
1510
|
+
formatDevErrorMessage(`reconcileNode: prevNode or nextNode does not exist in nodeMap`);
|
|
1515
1511
|
}
|
|
1516
1512
|
}
|
|
1517
1513
|
const isDirty = treatAllNodesAsDirty || activeDirtyLeaves.has(key) || activeDirtyElements.has(key);
|
|
@@ -1552,7 +1548,7 @@ function $reconcileNode(key, parentDOM) {
|
|
|
1552
1548
|
const replacementDOM = $createNode(key, null);
|
|
1553
1549
|
if (parentDOM === null) {
|
|
1554
1550
|
{
|
|
1555
|
-
|
|
1551
|
+
formatDevErrorMessage(`reconcileNode: parentDOM is null`);
|
|
1556
1552
|
}
|
|
1557
1553
|
}
|
|
1558
1554
|
parentDOM.replaceChild(replacementDOM, dom);
|
|
@@ -1747,7 +1743,7 @@ function getPrevElementByKeyOrThrow(key) {
|
|
|
1747
1743
|
const element = activePrevKeyToDOMMap.get(key);
|
|
1748
1744
|
if (element === undefined) {
|
|
1749
1745
|
{
|
|
1750
|
-
|
|
1746
|
+
formatDevErrorMessage(`Reconciliation: could not find DOM element for node key ${key}`);
|
|
1751
1747
|
}
|
|
1752
1748
|
}
|
|
1753
1749
|
return element;
|
|
@@ -1812,14 +1808,6 @@ const FOCUS_COMMAND = createCommand('FOCUS_COMMAND');
|
|
|
1812
1808
|
const BLUR_COMMAND = createCommand('BLUR_COMMAND');
|
|
1813
1809
|
const KEY_MODIFIER_COMMAND = createCommand('KEY_MODIFIER_COMMAND');
|
|
1814
1810
|
|
|
1815
|
-
/**
|
|
1816
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
1817
|
-
*
|
|
1818
|
-
* This source code is licensed under the MIT license found in the
|
|
1819
|
-
* LICENSE file in the root directory of this source tree.
|
|
1820
|
-
*
|
|
1821
|
-
*/
|
|
1822
|
-
|
|
1823
1811
|
const PASS_THROUGH_COMMAND = Object.freeze({});
|
|
1824
1812
|
const ANDROID_COMPOSITION_LATENCY = 30;
|
|
1825
1813
|
const rootElementEvents = [['keydown', onKeyDown], ['pointerdown', onPointerDown], ['compositionstart', onCompositionStart], ['compositionend', onCompositionEnd], ['input', onInput], ['click', onClick], ['cut', PASS_THROUGH_COMMAND], ['copy', PASS_THROUGH_COMMAND], ['dragstart', PASS_THROUGH_COMMAND], ['dragover', PASS_THROUGH_COMMAND], ['dragend', PASS_THROUGH_COMMAND], ['paste', PASS_THROUGH_COMMAND], ['focus', PASS_THROUGH_COMMAND], ['blur', PASS_THROUGH_COMMAND], ['drop', PASS_THROUGH_COMMAND]];
|
|
@@ -1961,12 +1949,12 @@ function onSelectionChange(domSelection, editor, isActive) {
|
|
|
1961
1949
|
} else {
|
|
1962
1950
|
if (anchor.type === 'text') {
|
|
1963
1951
|
if (!$isTextNode(anchorNode)) {
|
|
1964
|
-
|
|
1952
|
+
formatDevErrorMessage(`Point.getNode() must return TextNode when type is text`);
|
|
1965
1953
|
}
|
|
1966
1954
|
$updateSelectionFormatStyleFromTextNode(selection, anchorNode);
|
|
1967
1955
|
} else if (anchor.type === 'element' && !isRootTextContentEmpty) {
|
|
1968
1956
|
if (!$isElementNode(anchorNode)) {
|
|
1969
|
-
|
|
1957
|
+
formatDevErrorMessage(`Point.getNode() must return ElementNode when type is element`);
|
|
1970
1958
|
}
|
|
1971
1959
|
const lastNode = anchor.getNode();
|
|
1972
1960
|
if (
|
|
@@ -2149,7 +2137,7 @@ function onBeforeInput(event, editor) {
|
|
|
2149
2137
|
const anchorNode = selection.anchor.getNode();
|
|
2150
2138
|
anchorNode.markDirty();
|
|
2151
2139
|
if (!$isTextNode(anchorNode)) {
|
|
2152
|
-
|
|
2140
|
+
formatDevErrorMessage(`Anchor node must be a TextNode`);
|
|
2153
2141
|
}
|
|
2154
2142
|
$updateSelectionFormatStyleFromTextNode(selection, anchorNode);
|
|
2155
2143
|
}
|
|
@@ -2754,12 +2742,12 @@ function removeRootElementEvents(rootElement) {
|
|
|
2754
2742
|
const doc = rootElement.ownerDocument;
|
|
2755
2743
|
const documentRootElementsCount = rootElementsRegistered.get(doc);
|
|
2756
2744
|
if (!(documentRootElementsCount !== undefined)) {
|
|
2757
|
-
|
|
2745
|
+
formatDevErrorMessage(`Root element not registered`);
|
|
2758
2746
|
} // We only want to have a single global selectionchange event handler, shared
|
|
2759
2747
|
// between all editor instances.
|
|
2760
2748
|
const newCount = documentRootElementsCount - 1;
|
|
2761
2749
|
if (!(newCount >= 0)) {
|
|
2762
|
-
|
|
2750
|
+
formatDevErrorMessage(`Root element count less than 0`);
|
|
2763
2751
|
}
|
|
2764
2752
|
rootElementsRegistered.set(doc, newCount);
|
|
2765
2753
|
if (newCount === 0) {
|
|
@@ -2772,7 +2760,7 @@ function removeRootElementEvents(rootElement) {
|
|
|
2772
2760
|
rootElement.__lexicalEditor = null;
|
|
2773
2761
|
} else if (editor) {
|
|
2774
2762
|
{
|
|
2775
|
-
|
|
2763
|
+
formatDevErrorMessage(`Attempted to remove event handlers from a node that does not belong to this build of Lexical`);
|
|
2776
2764
|
}
|
|
2777
2765
|
}
|
|
2778
2766
|
const removeHandles = getRootElementRemoveHandles(rootElement);
|
|
@@ -2804,15 +2792,6 @@ function markCollapsedSelectionFormat(format, style, offset, key, timeStamp) {
|
|
|
2804
2792
|
collapsedSelectionFormat = [format, style, offset, key, timeStamp];
|
|
2805
2793
|
}
|
|
2806
2794
|
|
|
2807
|
-
/**
|
|
2808
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2809
|
-
*
|
|
2810
|
-
* This source code is licensed under the MIT license found in the
|
|
2811
|
-
* LICENSE file in the root directory of this source tree.
|
|
2812
|
-
*
|
|
2813
|
-
*/
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
2795
|
/**
|
|
2817
2796
|
* The base type for all serialized nodes
|
|
2818
2797
|
*/
|
|
@@ -2890,7 +2869,7 @@ class LexicalNode {
|
|
|
2890
2869
|
*/
|
|
2891
2870
|
static getType() {
|
|
2892
2871
|
{
|
|
2893
|
-
|
|
2872
|
+
formatDevErrorMessage(`LexicalNode: Node ${this.name} does not implement .getType().`);
|
|
2894
2873
|
}
|
|
2895
2874
|
}
|
|
2896
2875
|
|
|
@@ -2902,7 +2881,7 @@ class LexicalNode {
|
|
|
2902
2881
|
*/
|
|
2903
2882
|
static clone(_data) {
|
|
2904
2883
|
{
|
|
2905
|
-
|
|
2884
|
+
formatDevErrorMessage(`LexicalNode: Node ${this.name} does not implement .clone().`);
|
|
2906
2885
|
}
|
|
2907
2886
|
}
|
|
2908
2887
|
|
|
@@ -2994,7 +2973,7 @@ class LexicalNode {
|
|
|
2994
2973
|
}
|
|
2995
2974
|
isInline() {
|
|
2996
2975
|
{
|
|
2997
|
-
|
|
2976
|
+
formatDevErrorMessage(`LexicalNode: Node ${this.constructor.name} does not implement .isInline().`);
|
|
2998
2977
|
}
|
|
2999
2978
|
}
|
|
3000
2979
|
|
|
@@ -3098,7 +3077,7 @@ class LexicalNode {
|
|
|
3098
3077
|
const parent = this.getParent();
|
|
3099
3078
|
if (parent === null) {
|
|
3100
3079
|
{
|
|
3101
|
-
|
|
3080
|
+
formatDevErrorMessage(`Expected node ${this.__key} to have a parent.`);
|
|
3102
3081
|
}
|
|
3103
3082
|
}
|
|
3104
3083
|
return parent;
|
|
@@ -3115,7 +3094,7 @@ class LexicalNode {
|
|
|
3115
3094
|
const parent = node.getParent();
|
|
3116
3095
|
if ($isRootOrShadowRoot(parent)) {
|
|
3117
3096
|
if (!($isElementNode(node) || node === this && $isDecoratorNode(node))) {
|
|
3118
|
-
|
|
3097
|
+
formatDevErrorMessage(`Children of root nodes must be elements or decorators`);
|
|
3119
3098
|
}
|
|
3120
3099
|
return node;
|
|
3121
3100
|
}
|
|
@@ -3133,7 +3112,7 @@ class LexicalNode {
|
|
|
3133
3112
|
const parent = this.getTopLevelElement();
|
|
3134
3113
|
if (parent === null) {
|
|
3135
3114
|
{
|
|
3136
|
-
|
|
3115
|
+
formatDevErrorMessage(`Expected node ${this.__key} to have a top parent element.`);
|
|
3137
3116
|
}
|
|
3138
3117
|
}
|
|
3139
3118
|
return parent;
|
|
@@ -3277,7 +3256,7 @@ class LexicalNode {
|
|
|
3277
3256
|
return $getCommonAncestorResultBranchOrder(compare) === -1;
|
|
3278
3257
|
}
|
|
3279
3258
|
if (!(compare.type === 'same' || compare.type === 'ancestor')) {
|
|
3280
|
-
|
|
3259
|
+
formatDevErrorMessage(`LexicalNode.isBefore: exhaustiveness check`);
|
|
3281
3260
|
}
|
|
3282
3261
|
return false;
|
|
3283
3262
|
}
|
|
@@ -3338,7 +3317,7 @@ class LexicalNode {
|
|
|
3338
3317
|
do {
|
|
3339
3318
|
if (ancestor === null) {
|
|
3340
3319
|
{
|
|
3341
|
-
|
|
3320
|
+
formatDevErrorMessage(`getNodesBetween: ancestor is null`);
|
|
3342
3321
|
}
|
|
3343
3322
|
}
|
|
3344
3323
|
parentSibling = isBefore ? ancestor.getNextSibling() : ancestor.getPreviousSibling();
|
|
@@ -3378,7 +3357,7 @@ class LexicalNode {
|
|
|
3378
3357
|
const latest = $getNodeByKey(this.__key);
|
|
3379
3358
|
if (latest === null) {
|
|
3380
3359
|
{
|
|
3381
|
-
|
|
3360
|
+
formatDevErrorMessage(`Lexical node does not exist in active editor state. Avoid using the same node references between nested closures from editorState.read/editor.update.`);
|
|
3382
3361
|
}
|
|
3383
3362
|
}
|
|
3384
3363
|
return latest;
|
|
@@ -3450,7 +3429,7 @@ class LexicalNode {
|
|
|
3450
3429
|
* */
|
|
3451
3430
|
createDOM(_config, _editor) {
|
|
3452
3431
|
{
|
|
3453
|
-
|
|
3432
|
+
formatDevErrorMessage(`createDOM: base method not extended`);
|
|
3454
3433
|
}
|
|
3455
3434
|
}
|
|
3456
3435
|
|
|
@@ -3466,7 +3445,7 @@ class LexicalNode {
|
|
|
3466
3445
|
* */
|
|
3467
3446
|
updateDOM(_prevNode, _dom, _config) {
|
|
3468
3447
|
{
|
|
3469
|
-
|
|
3448
|
+
formatDevErrorMessage(`updateDOM: base method not extended`);
|
|
3470
3449
|
}
|
|
3471
3450
|
}
|
|
3472
3451
|
|
|
@@ -3511,7 +3490,7 @@ class LexicalNode {
|
|
|
3511
3490
|
* */
|
|
3512
3491
|
static importJSON(_serializedNode) {
|
|
3513
3492
|
{
|
|
3514
|
-
|
|
3493
|
+
formatDevErrorMessage(`LexicalNode: Node ${this.name} does not implement .importJSON().`);
|
|
3515
3494
|
}
|
|
3516
3495
|
}
|
|
3517
3496
|
|
|
@@ -3544,7 +3523,7 @@ class LexicalNode {
|
|
|
3544
3523
|
* ```
|
|
3545
3524
|
**/
|
|
3546
3525
|
updateFromJSON(serializedNode) {
|
|
3547
|
-
return $updateStateFromJSON(this, serializedNode[
|
|
3526
|
+
return $updateStateFromJSON(this, serializedNode[NODE_STATE_KEY]);
|
|
3548
3527
|
}
|
|
3549
3528
|
|
|
3550
3529
|
/**
|
|
@@ -3619,7 +3598,7 @@ class LexicalNode {
|
|
|
3619
3598
|
writableParent.__size = size;
|
|
3620
3599
|
if (includeChildren) {
|
|
3621
3600
|
if (!($isElementNode(this) && $isElementNode(writableReplaceWith))) {
|
|
3622
|
-
|
|
3601
|
+
formatDevErrorMessage(`includeChildren should only be true for ElementNodes`);
|
|
3623
3602
|
}
|
|
3624
3603
|
this.getChildren().forEach(child => {
|
|
3625
3604
|
writableReplaceWith.append(child);
|
|
@@ -3829,13 +3808,13 @@ function errorOnTypeKlassMismatch(type, klass) {
|
|
|
3829
3808
|
// Common error - split in its own invariant
|
|
3830
3809
|
if (registeredNode === undefined) {
|
|
3831
3810
|
{
|
|
3832
|
-
|
|
3811
|
+
formatDevErrorMessage(`Create node: Attempted to create node ${klass.name} that was not configured to be used on the editor.`);
|
|
3833
3812
|
}
|
|
3834
3813
|
}
|
|
3835
3814
|
const editorKlass = registeredNode.klass;
|
|
3836
3815
|
if (editorKlass !== klass) {
|
|
3837
3816
|
{
|
|
3838
|
-
|
|
3817
|
+
formatDevErrorMessage(`Create node: Type ${type} in node ${klass.name} does not match registered node ${editorKlass.name} with the same type`);
|
|
3839
3818
|
}
|
|
3840
3819
|
}
|
|
3841
3820
|
}
|
|
@@ -3854,7 +3833,7 @@ function insertRangeAfter(node, firstToInsert, lastToInsert) {
|
|
|
3854
3833
|
while (current !== lastToInsert2) {
|
|
3855
3834
|
if (!current.getNextSibling()) {
|
|
3856
3835
|
{
|
|
3857
|
-
|
|
3836
|
+
formatDevErrorMessage(`insertRangeAfter: lastToInsert must be a later sibling of firstToInsert`);
|
|
3858
3837
|
}
|
|
3859
3838
|
}
|
|
3860
3839
|
current = current.getNextSibling();
|
|
@@ -3959,14 +3938,6 @@ function isWhitespaceDomTextNode(node) {
|
|
|
3959
3938
|
return isDOMTextNode(node) && /^( |\t|\r?\n)+$/.test(node.textContent || '');
|
|
3960
3939
|
}
|
|
3961
3940
|
|
|
3962
|
-
/**
|
|
3963
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3964
|
-
*
|
|
3965
|
-
* This source code is licensed under the MIT license found in the
|
|
3966
|
-
* LICENSE file in the root directory of this source tree.
|
|
3967
|
-
*
|
|
3968
|
-
*/
|
|
3969
|
-
|
|
3970
3941
|
function getElementOuterTag(node, format) {
|
|
3971
3942
|
if (format & IS_CODE) {
|
|
3972
3943
|
return 'code';
|
|
@@ -4323,7 +4294,7 @@ class TextNode extends LexicalNode {
|
|
|
4323
4294
|
const prevInnerDOM = dom.firstChild;
|
|
4324
4295
|
if (prevInnerDOM == null) {
|
|
4325
4296
|
{
|
|
4326
|
-
|
|
4297
|
+
formatDevErrorMessage(`updateDOM: prevInnerDOM is null or undefined`);
|
|
4327
4298
|
}
|
|
4328
4299
|
}
|
|
4329
4300
|
const nextInnerDOM = document.createElement(nextInnerTag);
|
|
@@ -4337,7 +4308,7 @@ class TextNode extends LexicalNode {
|
|
|
4337
4308
|
innerDOM = dom.firstChild;
|
|
4338
4309
|
if (innerDOM == null) {
|
|
4339
4310
|
{
|
|
4340
|
-
|
|
4311
|
+
formatDevErrorMessage(`updateDOM: innerDOM is null or undefined`);
|
|
4341
4312
|
}
|
|
4342
4313
|
}
|
|
4343
4314
|
}
|
|
@@ -4423,7 +4394,7 @@ class TextNode extends LexicalNode {
|
|
|
4423
4394
|
element
|
|
4424
4395
|
} = super.exportDOM(editor);
|
|
4425
4396
|
if (!isHTMLElement(element)) {
|
|
4426
|
-
|
|
4397
|
+
formatDevErrorMessage(`Expected TextNode createDOM to always return a HTMLElement`);
|
|
4427
4398
|
}
|
|
4428
4399
|
element.style.whiteSpace = 'pre-wrap';
|
|
4429
4400
|
// This is the only way to properly add support for most clients,
|
|
@@ -4818,7 +4789,7 @@ class TextNode extends LexicalNode {
|
|
|
4818
4789
|
const isBefore = target === this.getPreviousSibling();
|
|
4819
4790
|
if (!isBefore && target !== this.getNextSibling()) {
|
|
4820
4791
|
{
|
|
4821
|
-
|
|
4792
|
+
formatDevErrorMessage(`mergeWithSibling: sibling must be a previous or next sibling`);
|
|
4822
4793
|
}
|
|
4823
4794
|
}
|
|
4824
4795
|
const key = this.__key;
|
|
@@ -4906,7 +4877,7 @@ function $convertTextDOMNode(domNode) {
|
|
|
4906
4877
|
const domNode_ = domNode;
|
|
4907
4878
|
const parentDom = domNode.parentElement;
|
|
4908
4879
|
if (!(parentDom !== null)) {
|
|
4909
|
-
|
|
4880
|
+
formatDevErrorMessage(`Expected parentElement of Text not to be null`);
|
|
4910
4881
|
}
|
|
4911
4882
|
let textContent = domNode_.textContent || '';
|
|
4912
4883
|
// No collapse and preserve segment break for pre, pre-wrap and pre-line
|
|
@@ -5079,14 +5050,6 @@ function applyTextFormatFromStyle(style, shouldApply) {
|
|
|
5079
5050
|
};
|
|
5080
5051
|
}
|
|
5081
5052
|
|
|
5082
|
-
/**
|
|
5083
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
5084
|
-
*
|
|
5085
|
-
* This source code is licensed under the MIT license found in the
|
|
5086
|
-
* LICENSE file in the root directory of this source tree.
|
|
5087
|
-
*
|
|
5088
|
-
*/
|
|
5089
|
-
|
|
5090
5053
|
/** @noInheritDoc */
|
|
5091
5054
|
class TabNode extends TextNode {
|
|
5092
5055
|
static getType() {
|
|
@@ -5116,19 +5079,19 @@ class TabNode extends TextNode {
|
|
|
5116
5079
|
}
|
|
5117
5080
|
setTextContent(text) {
|
|
5118
5081
|
if (!(text === '\t' || text === '')) {
|
|
5119
|
-
|
|
5082
|
+
formatDevErrorMessage(`TabNode does not support setTextContent`);
|
|
5120
5083
|
}
|
|
5121
5084
|
return super.setTextContent(text);
|
|
5122
5085
|
}
|
|
5123
5086
|
setDetail(detail) {
|
|
5124
5087
|
if (!(detail === IS_UNMERGEABLE)) {
|
|
5125
|
-
|
|
5088
|
+
formatDevErrorMessage(`TabNode does not support setDetail`);
|
|
5126
5089
|
}
|
|
5127
5090
|
return this;
|
|
5128
5091
|
}
|
|
5129
5092
|
setMode(type) {
|
|
5130
5093
|
if (!(type === 'normal')) {
|
|
5131
|
-
|
|
5094
|
+
formatDevErrorMessage(`TabNode does not support setMode`);
|
|
5132
5095
|
}
|
|
5133
5096
|
return this;
|
|
5134
5097
|
}
|
|
@@ -5146,14 +5109,6 @@ function $isTabNode(node) {
|
|
|
5146
5109
|
return node instanceof TabNode;
|
|
5147
5110
|
}
|
|
5148
5111
|
|
|
5149
|
-
/**
|
|
5150
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
5151
|
-
*
|
|
5152
|
-
* This source code is licensed under the MIT license found in the
|
|
5153
|
-
* LICENSE file in the root directory of this source tree.
|
|
5154
|
-
*
|
|
5155
|
-
*/
|
|
5156
|
-
|
|
5157
5112
|
class Point {
|
|
5158
5113
|
constructor(key, offset, type) {
|
|
5159
5114
|
{
|
|
@@ -5185,7 +5140,7 @@ class Point {
|
|
|
5185
5140
|
const node = $getNodeByKey(key);
|
|
5186
5141
|
if (node === null) {
|
|
5187
5142
|
{
|
|
5188
|
-
|
|
5143
|
+
formatDevErrorMessage(`Point.getNode: node not found`);
|
|
5189
5144
|
}
|
|
5190
5145
|
}
|
|
5191
5146
|
return node;
|
|
@@ -5202,7 +5157,7 @@ class Point {
|
|
|
5202
5157
|
{
|
|
5203
5158
|
const node = $getNodeByKey(key);
|
|
5204
5159
|
if (!(type === 'text' ? $isTextNode(node) : $isElementNode(node))) {
|
|
5205
|
-
|
|
5160
|
+
formatDevErrorMessage(`PointType.set: node with key ${key} is ${node ? node.__type : '[not found]'} and can not be used for a ${type} point`);
|
|
5206
5161
|
}
|
|
5207
5162
|
}
|
|
5208
5163
|
if (!isCurrentlyReadOnlyMode()) {
|
|
@@ -5445,7 +5400,7 @@ class RangeSelection {
|
|
|
5445
5400
|
{
|
|
5446
5401
|
if (this.isCollapsed() && nodes.length > 1) {
|
|
5447
5402
|
{
|
|
5448
|
-
|
|
5403
|
+
formatDevErrorMessage(`RangeSelection.getNodes() returned ${String(nodes.length)} > 1 nodes in a collapsed selection`);
|
|
5449
5404
|
}
|
|
5450
5405
|
}
|
|
5451
5406
|
}
|
|
@@ -5684,7 +5639,7 @@ class RangeSelection {
|
|
|
5684
5639
|
let firstNode = selectedNodes[0];
|
|
5685
5640
|
if (!$isTextNode(firstNode)) {
|
|
5686
5641
|
{
|
|
5687
|
-
|
|
5642
|
+
formatDevErrorMessage(`insertText: first node is not a text node`);
|
|
5688
5643
|
}
|
|
5689
5644
|
}
|
|
5690
5645
|
const firstNodeText = firstNode.getTextContent();
|
|
@@ -6079,7 +6034,7 @@ class RangeSelection {
|
|
|
6079
6034
|
this.insertParagraph();
|
|
6080
6035
|
const selection = $getSelection();
|
|
6081
6036
|
if (!$isRangeSelection(selection)) {
|
|
6082
|
-
|
|
6037
|
+
formatDevErrorMessage(`Expected RangeSelection after insertParagraph`);
|
|
6083
6038
|
}
|
|
6084
6039
|
return selection.insertNodes(nodes);
|
|
6085
6040
|
}
|
|
@@ -6104,7 +6059,7 @@ class RangeSelection {
|
|
|
6104
6059
|
const notInline = node => ($isElementNode(node) || $isDecoratorNode(node)) && !node.isInline();
|
|
6105
6060
|
if (!nodes.some(notInline)) {
|
|
6106
6061
|
if (!$isElementNode(firstBlock)) {
|
|
6107
|
-
|
|
6062
|
+
formatDevErrorMessage(`Expected node ${firstNode.constructor.name} of type ${firstNode.getType()} to have a block ElementNode ancestor`);
|
|
6108
6063
|
}
|
|
6109
6064
|
const index = $removeTextAndSplitBlock(this);
|
|
6110
6065
|
firstBlock.splice(index, 0, nodes);
|
|
@@ -6123,14 +6078,14 @@ class RangeSelection {
|
|
|
6123
6078
|
let firstToInsert = blocks[0];
|
|
6124
6079
|
if (isMergeable(firstToInsert)) {
|
|
6125
6080
|
if (!$isElementNode(firstBlock)) {
|
|
6126
|
-
|
|
6081
|
+
formatDevErrorMessage(`Expected node ${firstNode.constructor.name} of type ${firstNode.getType()} to have a block ElementNode ancestor`);
|
|
6127
6082
|
}
|
|
6128
6083
|
firstBlock.append(...firstToInsert.getChildren());
|
|
6129
6084
|
firstToInsert = blocks[1];
|
|
6130
6085
|
}
|
|
6131
6086
|
if (firstToInsert) {
|
|
6132
6087
|
if (!(firstBlock !== null)) {
|
|
6133
|
-
|
|
6088
|
+
formatDevErrorMessage(`Expected node ${firstNode.constructor.name} of type ${firstNode.getType()} to have a block ancestor`);
|
|
6134
6089
|
}
|
|
6135
6090
|
insertRangeAfter(firstBlock, firstToInsert);
|
|
6136
6091
|
}
|
|
@@ -6166,7 +6121,7 @@ class RangeSelection {
|
|
|
6166
6121
|
const index = $removeTextAndSplitBlock(this);
|
|
6167
6122
|
const block = $getAncestor(this.anchor.getNode(), INTERNAL_$isBlock);
|
|
6168
6123
|
if (!$isElementNode(block)) {
|
|
6169
|
-
|
|
6124
|
+
formatDevErrorMessage(`Expected ancestor to be a block ElementNode`);
|
|
6170
6125
|
}
|
|
6171
6126
|
const firstToAppend = block.getChildAtIndex(index);
|
|
6172
6127
|
const nodesToInsert = firstToAppend ? [firstToAppend, ...firstToAppend.getNextSiblings()] : [];
|
|
@@ -6256,51 +6211,10 @@ class RangeSelection {
|
|
|
6256
6211
|
* @param granularity the granularity at which to apply the modification
|
|
6257
6212
|
*/
|
|
6258
6213
|
modify(alter, isBackward, granularity) {
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
const collapse = alter === 'move';
|
|
6262
|
-
|
|
6263
|
-
// Handle the selection movement around decorators.
|
|
6264
|
-
const possibleNode = $getAdjacentNode(focus, isBackward);
|
|
6265
|
-
if ($isDecoratorNode(possibleNode) && !possibleNode.isIsolated()) {
|
|
6266
|
-
// Make it possible to move selection from range selection to
|
|
6267
|
-
// node selection on the node.
|
|
6268
|
-
if (collapse && possibleNode.isKeyboardSelectable()) {
|
|
6269
|
-
const nodeSelection = $createNodeSelection();
|
|
6270
|
-
nodeSelection.add(possibleNode.__key);
|
|
6271
|
-
$setSelection(nodeSelection);
|
|
6272
|
-
return;
|
|
6273
|
-
}
|
|
6274
|
-
const sibling = isBackward ? possibleNode.getPreviousSibling() : possibleNode.getNextSibling();
|
|
6275
|
-
if (!$isTextNode(sibling)) {
|
|
6276
|
-
const parent = possibleNode.getParentOrThrow();
|
|
6277
|
-
let offset;
|
|
6278
|
-
let elementKey;
|
|
6279
|
-
if ($isElementNode(sibling)) {
|
|
6280
|
-
elementKey = sibling.__key;
|
|
6281
|
-
offset = isBackward ? sibling.getChildrenSize() : 0;
|
|
6282
|
-
} else {
|
|
6283
|
-
offset = possibleNode.getIndexWithinParent();
|
|
6284
|
-
elementKey = parent.__key;
|
|
6285
|
-
if (!isBackward) {
|
|
6286
|
-
offset++;
|
|
6287
|
-
}
|
|
6288
|
-
}
|
|
6289
|
-
focus.set(elementKey, offset, 'element');
|
|
6290
|
-
if (collapse) {
|
|
6291
|
-
anchor.set(elementKey, offset, 'element');
|
|
6292
|
-
}
|
|
6293
|
-
return;
|
|
6294
|
-
} else {
|
|
6295
|
-
const siblingKey = sibling.__key;
|
|
6296
|
-
const offset = isBackward ? sibling.getTextContent().length : 0;
|
|
6297
|
-
focus.set(siblingKey, offset, 'text');
|
|
6298
|
-
if (collapse) {
|
|
6299
|
-
anchor.set(siblingKey, offset, 'text');
|
|
6300
|
-
}
|
|
6301
|
-
return;
|
|
6302
|
-
}
|
|
6214
|
+
if ($modifySelectionAroundDecoratorsAndBlocks(this, alter, isBackward, granularity)) {
|
|
6215
|
+
return;
|
|
6303
6216
|
}
|
|
6217
|
+
const collapse = alter === 'move';
|
|
6304
6218
|
const editor = getActiveEditor();
|
|
6305
6219
|
const domSelection = getDOMSelection(getWindow(editor));
|
|
6306
6220
|
if (!domSelection) {
|
|
@@ -6308,12 +6222,26 @@ class RangeSelection {
|
|
|
6308
6222
|
}
|
|
6309
6223
|
const blockCursorElement = editor._blockCursorElement;
|
|
6310
6224
|
const rootElement = editor._rootElement;
|
|
6225
|
+
const focusNode = this.focus.getNode();
|
|
6311
6226
|
// Remove the block cursor element if it exists. This will ensure selection
|
|
6312
6227
|
// works as intended. If we leave it in the DOM all sorts of strange bugs
|
|
6313
6228
|
// occur. :/
|
|
6314
|
-
if (rootElement !== null && blockCursorElement !== null && $isElementNode(
|
|
6229
|
+
if (rootElement !== null && blockCursorElement !== null && $isElementNode(focusNode) && !focusNode.isInline() && !focusNode.canBeEmpty()) {
|
|
6315
6230
|
removeDOMBlockCursorElement(blockCursorElement, editor, rootElement);
|
|
6316
6231
|
}
|
|
6232
|
+
if (this.dirty) {
|
|
6233
|
+
let nextAnchorDOM = getElementByKeyOrThrow(editor, this.anchor.key);
|
|
6234
|
+
let nextFocusDOM = getElementByKeyOrThrow(editor, this.focus.key);
|
|
6235
|
+
if (this.anchor.type === 'text') {
|
|
6236
|
+
nextAnchorDOM = getDOMTextNode(nextAnchorDOM);
|
|
6237
|
+
}
|
|
6238
|
+
if (this.focus.type === 'text') {
|
|
6239
|
+
nextFocusDOM = getDOMTextNode(nextFocusDOM);
|
|
6240
|
+
}
|
|
6241
|
+
if (nextAnchorDOM && nextFocusDOM) {
|
|
6242
|
+
setDOMSelectionBaseAndExtent(domSelection, nextAnchorDOM, this.anchor.offset, nextFocusDOM, this.focus.offset);
|
|
6243
|
+
}
|
|
6244
|
+
}
|
|
6317
6245
|
// We use the DOM selection.modify API here to "tell" us what the selection
|
|
6318
6246
|
// will be. We then use it to update the Lexical selection accordingly. This
|
|
6319
6247
|
// is much more reliable than waiting for a beforeinput and using the ranges
|
|
@@ -6370,6 +6298,9 @@ class RangeSelection {
|
|
|
6370
6298
|
}
|
|
6371
6299
|
}
|
|
6372
6300
|
}
|
|
6301
|
+
if (granularity === 'lineboundary') {
|
|
6302
|
+
$modifySelectionAroundDecoratorsAndBlocks(this, alter, isBackward, granularity, 'decorators');
|
|
6303
|
+
}
|
|
6373
6304
|
}
|
|
6374
6305
|
/**
|
|
6375
6306
|
* Helper for handling forward character and word deletion that prevents element nodes
|
|
@@ -6410,7 +6341,6 @@ class RangeSelection {
|
|
|
6410
6341
|
const initialCaret = $caretFromPoint(anchor, direction);
|
|
6411
6342
|
const initialRange = $extendCaretToRange(initialCaret);
|
|
6412
6343
|
if (initialRange.getTextSlices().every(slice => slice === null || slice.distance === 0)) {
|
|
6413
|
-
// debugger;
|
|
6414
6344
|
// There's no text in the direction of the deletion so we can explore our options
|
|
6415
6345
|
let state = {
|
|
6416
6346
|
type: 'initial'
|
|
@@ -6526,30 +6456,16 @@ class RangeSelection {
|
|
|
6526
6456
|
*/
|
|
6527
6457
|
deleteLine(isBackward) {
|
|
6528
6458
|
if (this.isCollapsed()) {
|
|
6529
|
-
// Since `domSelection.modify('extend', ..., 'lineboundary')` works well for text selections
|
|
6530
|
-
// but doesn't properly handle selections which end on elements, a space character is added
|
|
6531
|
-
// for such selections transforming their anchor's type to 'text'
|
|
6532
|
-
const anchorIsElement = this.anchor.type === 'element';
|
|
6533
|
-
if (anchorIsElement) {
|
|
6534
|
-
this.insertText(' ');
|
|
6535
|
-
}
|
|
6536
6459
|
this.modify('extend', isBackward, 'lineboundary');
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
const startPoint = isBackward ? this.anchor : this.focus;
|
|
6541
|
-
startPoint.set(startPoint.key, startPoint.offset + 1, startPoint.type);
|
|
6542
|
-
}
|
|
6543
|
-
// If the selection starts at the beginning of a text node (offset 0),
|
|
6460
|
+
}
|
|
6461
|
+
if (this.isCollapsed()) {
|
|
6462
|
+
// If the selection was already collapsed at the lineboundary,
|
|
6544
6463
|
// use the deleteCharacter operation to handle all of the logic associated
|
|
6545
6464
|
// with navigating through the parent element
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
return this.deleteCharacter(isBackward);
|
|
6550
|
-
}
|
|
6465
|
+
this.deleteCharacter(isBackward);
|
|
6466
|
+
} else {
|
|
6467
|
+
this.removeText();
|
|
6551
6468
|
}
|
|
6552
|
-
this.removeText();
|
|
6553
6469
|
}
|
|
6554
6470
|
|
|
6555
6471
|
/**
|
|
@@ -6727,7 +6643,7 @@ function $updateCaretSelectionForUnicodeCharacter(selection, isBackward) {
|
|
|
6727
6643
|
function shouldDeleteExactlyOneCodeUnit(text) {
|
|
6728
6644
|
{
|
|
6729
6645
|
if (!(text.length > 1)) {
|
|
6730
|
-
|
|
6646
|
+
formatDevErrorMessage(`shouldDeleteExactlyOneCodeUnit: expecting to be called only with sequences of two or more code units`);
|
|
6731
6647
|
}
|
|
6732
6648
|
}
|
|
6733
6649
|
return !(doesContainSurrogatePair(text) || doesContainEmoji(text));
|
|
@@ -6849,13 +6765,13 @@ function $internalResolveSelectionPoint(dom, offset, lastPoint, editor) {
|
|
|
6849
6765
|
if ($isElementNode(resolvedElement)) {
|
|
6850
6766
|
const elementDOM = editor.getElementByKey(resolvedElement.getKey());
|
|
6851
6767
|
if (!(elementDOM !== null)) {
|
|
6852
|
-
|
|
6768
|
+
formatDevErrorMessage(`$internalResolveSelectionPoint: node in DOM but not keyToDOMMap`);
|
|
6853
6769
|
}
|
|
6854
6770
|
const slot = resolvedElement.getDOMSlot(elementDOM);
|
|
6855
6771
|
[resolvedElement, resolvedOffset] = slot.resolveChildIndex(resolvedElement, elementDOM, dom, offset);
|
|
6856
6772
|
// This is just a typescript workaround, it is true but lost due to mutability
|
|
6857
6773
|
if (!$isElementNode(resolvedElement)) {
|
|
6858
|
-
|
|
6774
|
+
formatDevErrorMessage(`$internalResolveSelectionPoint: resolvedElement is not an ElementNode`);
|
|
6859
6775
|
}
|
|
6860
6776
|
if (moveSelectionToEnd && resolvedOffset >= resolvedElement.getChildrenSize()) {
|
|
6861
6777
|
resolvedOffset = Math.max(0, resolvedElement.getChildrenSize() - 1);
|
|
@@ -6877,7 +6793,7 @@ function $internalResolveSelectionPoint(dom, offset, lastPoint, editor) {
|
|
|
6877
6793
|
resolvedOffset = getTextNodeOffset(child, moveSelectionToEnd);
|
|
6878
6794
|
} else if (child !== resolvedElement && moveSelectionToEnd && !hasBlockCursor) {
|
|
6879
6795
|
if (!$isElementNode(resolvedElement)) {
|
|
6880
|
-
|
|
6796
|
+
formatDevErrorMessage(`invariant`);
|
|
6881
6797
|
}
|
|
6882
6798
|
resolvedOffset = Math.min(resolvedElement.getChildrenSize(), resolvedOffset + 1);
|
|
6883
6799
|
}
|
|
@@ -7073,23 +6989,23 @@ function $internalCreateRangeSelection(lastSelection, domSelection, editor, even
|
|
|
7073
6989
|
function $validatePoint(editor, name, point) {
|
|
7074
6990
|
const node = $getNodeByKey(point.key);
|
|
7075
6991
|
if (!(node !== undefined)) {
|
|
7076
|
-
|
|
6992
|
+
formatDevErrorMessage(`$validatePoint: ${name} key ${point.key} not found in current editorState`);
|
|
7077
6993
|
}
|
|
7078
6994
|
if (point.type === 'text') {
|
|
7079
6995
|
if (!$isTextNode(node)) {
|
|
7080
|
-
|
|
6996
|
+
formatDevErrorMessage(`$validatePoint: ${name} key ${point.key} is not a TextNode`);
|
|
7081
6997
|
}
|
|
7082
6998
|
const size = node.getTextContentSize();
|
|
7083
6999
|
if (!(point.offset <= size)) {
|
|
7084
|
-
|
|
7000
|
+
formatDevErrorMessage(`$validatePoint: ${name} point.offset > node.getTextContentSize() (${String(point.offset)} > ${String(size)})`);
|
|
7085
7001
|
}
|
|
7086
7002
|
} else {
|
|
7087
7003
|
if (!$isElementNode(node)) {
|
|
7088
|
-
|
|
7004
|
+
formatDevErrorMessage(`$validatePoint: ${name} key ${point.key} is not an ElementNode`);
|
|
7089
7005
|
}
|
|
7090
7006
|
const size = node.getChildrenSize();
|
|
7091
7007
|
if (!(point.offset <= size)) {
|
|
7092
|
-
|
|
7008
|
+
formatDevErrorMessage(`$validatePoint: ${name} point.offset > node.getChildrenSize() (${String(point.offset)} > ${String(size)})`);
|
|
7093
7009
|
}
|
|
7094
7010
|
}
|
|
7095
7011
|
}
|
|
@@ -7253,6 +7169,20 @@ function adjustPointOffsetForMergedSibling(point, isBefore, key, target, textLen
|
|
|
7253
7169
|
point.set(point.key, point.offset - 1, 'element');
|
|
7254
7170
|
}
|
|
7255
7171
|
}
|
|
7172
|
+
function setDOMSelectionBaseAndExtent(domSelection, nextAnchorDOM, nextAnchorOffset, nextFocusDOM, nextFocusOffset) {
|
|
7173
|
+
// Apply the updated selection to the DOM. Note: this will trigger
|
|
7174
|
+
// a "selectionchange" event, although it will be asynchronous.
|
|
7175
|
+
try {
|
|
7176
|
+
domSelection.setBaseAndExtent(nextAnchorDOM, nextAnchorOffset, nextFocusDOM, nextFocusOffset);
|
|
7177
|
+
} catch (error) {
|
|
7178
|
+
// If we encounter an error, continue. This can sometimes
|
|
7179
|
+
// occur with FF and there's no good reason as to why it
|
|
7180
|
+
// should happen.
|
|
7181
|
+
{
|
|
7182
|
+
console.warn(error);
|
|
7183
|
+
}
|
|
7184
|
+
}
|
|
7185
|
+
}
|
|
7256
7186
|
function updateDOMSelection(prevSelection, nextSelection, editor, domSelection, tags, rootElement, nodeCount) {
|
|
7257
7187
|
const anchorDOMNode = domSelection.anchorNode;
|
|
7258
7188
|
const focusDOMNode = domSelection.focusNode;
|
|
@@ -7329,16 +7259,7 @@ function updateDOMSelection(prevSelection, nextSelection, editor, domSelection,
|
|
|
7329
7259
|
|
|
7330
7260
|
// Apply the updated selection to the DOM. Note: this will trigger
|
|
7331
7261
|
// a "selectionchange" event, although it will be asynchronous.
|
|
7332
|
-
|
|
7333
|
-
domSelection.setBaseAndExtent(nextAnchorNode, nextAnchorOffset, nextFocusNode, nextFocusOffset);
|
|
7334
|
-
} catch (error) {
|
|
7335
|
-
// If we encounter an error, continue. This can sometimes
|
|
7336
|
-
// occur with FF and there's no good reason as to why it
|
|
7337
|
-
// should happen.
|
|
7338
|
-
{
|
|
7339
|
-
console.warn(error);
|
|
7340
|
-
}
|
|
7341
|
-
}
|
|
7262
|
+
setDOMSelectionBaseAndExtent(domSelection, nextAnchorNode, nextAnchorOffset, nextFocusNode, nextFocusOffset);
|
|
7342
7263
|
if (!tags.has('skip-scroll-into-view') && nextSelection.isCollapsed() && rootElement !== null && rootElement === document.activeElement) {
|
|
7343
7264
|
const selectionTarget = $isRangeSelection(nextSelection) && nextSelection.anchor.type === 'element' ? nextAnchorNode.childNodes[nextAnchorOffset] || null : domSelection.rangeCount > 0 ? domSelection.getRangeAt(0) : null;
|
|
7344
7265
|
if (selectionTarget !== null) {
|
|
@@ -7381,7 +7302,7 @@ function $removeTextAndSplitBlock(selection) {
|
|
|
7381
7302
|
selection_ = newSelection;
|
|
7382
7303
|
}
|
|
7383
7304
|
if (!$isRangeSelection(selection_)) {
|
|
7384
|
-
|
|
7305
|
+
formatDevErrorMessage(`Unexpected dirty selection to be null`);
|
|
7385
7306
|
}
|
|
7386
7307
|
const anchor = selection_.anchor;
|
|
7387
7308
|
let node = anchor.getNode();
|
|
@@ -7526,12 +7447,74 @@ range) {
|
|
|
7526
7447
|
}
|
|
7527
7448
|
|
|
7528
7449
|
/**
|
|
7529
|
-
*
|
|
7530
|
-
*
|
|
7531
|
-
* This source code is licensed under the MIT license found in the
|
|
7532
|
-
* LICENSE file in the root directory of this source tree.
|
|
7450
|
+
* @internal
|
|
7533
7451
|
*
|
|
7452
|
+
* Modify the focus of the focus around possible decorators and blocks and return true
|
|
7453
|
+
* if the movement is done.
|
|
7534
7454
|
*/
|
|
7455
|
+
function $modifySelectionAroundDecoratorsAndBlocks(selection, alter, isBackward, granularity, mode = 'decorators-and-blocks') {
|
|
7456
|
+
if (alter === 'move' && granularity === 'character' && !selection.isCollapsed()) {
|
|
7457
|
+
// moving left or right when the selection isn't collapsed will
|
|
7458
|
+
// just set the anchor to the focus or vice versa depending on
|
|
7459
|
+
// direction
|
|
7460
|
+
const [src, dst] = isBackward === selection.isBackward() ? [selection.focus, selection.anchor] : [selection.anchor, selection.focus];
|
|
7461
|
+
dst.set(src.key, src.offset, src.type);
|
|
7462
|
+
return true;
|
|
7463
|
+
}
|
|
7464
|
+
const initialFocus = $caretFromPoint(selection.focus, isBackward ? 'previous' : 'next');
|
|
7465
|
+
const isLineBoundary = granularity === 'lineboundary';
|
|
7466
|
+
const collapse = alter === 'move';
|
|
7467
|
+
let focus = initialFocus;
|
|
7468
|
+
let checkForBlock = mode === 'decorators-and-blocks';
|
|
7469
|
+
if (!$isExtendableTextPointCaret(focus)) {
|
|
7470
|
+
for (const siblingCaret of focus) {
|
|
7471
|
+
checkForBlock = false;
|
|
7472
|
+
const {
|
|
7473
|
+
origin
|
|
7474
|
+
} = siblingCaret;
|
|
7475
|
+
if ($isDecoratorNode(origin) && !origin.isIsolated()) {
|
|
7476
|
+
focus = siblingCaret;
|
|
7477
|
+
if (isLineBoundary && origin.isInline()) {
|
|
7478
|
+
continue;
|
|
7479
|
+
}
|
|
7480
|
+
}
|
|
7481
|
+
break;
|
|
7482
|
+
}
|
|
7483
|
+
if (checkForBlock) {
|
|
7484
|
+
for (const nextCaret of $extendCaretToRange(initialFocus).iterNodeCarets(alter === 'extend' ? 'shadowRoot' : 'root')) {
|
|
7485
|
+
if ($isChildCaret(nextCaret)) {
|
|
7486
|
+
if (!nextCaret.origin.isInline()) {
|
|
7487
|
+
focus = nextCaret;
|
|
7488
|
+
}
|
|
7489
|
+
} else if ($isElementNode(nextCaret.origin)) {
|
|
7490
|
+
continue;
|
|
7491
|
+
} else if ($isDecoratorNode(nextCaret.origin) && !nextCaret.origin.isInline()) {
|
|
7492
|
+
focus = nextCaret;
|
|
7493
|
+
}
|
|
7494
|
+
break;
|
|
7495
|
+
}
|
|
7496
|
+
}
|
|
7497
|
+
}
|
|
7498
|
+
if (focus === initialFocus) {
|
|
7499
|
+
return false;
|
|
7500
|
+
}
|
|
7501
|
+
// After this point checkForBlock is true if and only if we moved to a
|
|
7502
|
+
// different block, so we should stop regardless of the granularity
|
|
7503
|
+
if (collapse && !isLineBoundary && $isDecoratorNode(focus.origin) && focus.origin.isKeyboardSelectable()) {
|
|
7504
|
+
// Make it possible to move selection from range selection to
|
|
7505
|
+
// node selection on the node.
|
|
7506
|
+
const nodeSelection = $createNodeSelection();
|
|
7507
|
+
nodeSelection.add(focus.origin.getKey());
|
|
7508
|
+
$setSelection(nodeSelection);
|
|
7509
|
+
return true;
|
|
7510
|
+
}
|
|
7511
|
+
focus = $normalizeCaret(focus);
|
|
7512
|
+
if (collapse) {
|
|
7513
|
+
$setPointFromCaret(selection.anchor, focus);
|
|
7514
|
+
}
|
|
7515
|
+
$setPointFromCaret(selection.focus, focus);
|
|
7516
|
+
return checkForBlock || !isLineBoundary;
|
|
7517
|
+
}
|
|
7535
7518
|
|
|
7536
7519
|
let activeEditorState = null;
|
|
7537
7520
|
let activeEditor = null;
|
|
@@ -7549,21 +7532,21 @@ function isCurrentlyReadOnlyMode() {
|
|
|
7549
7532
|
function errorOnReadOnly() {
|
|
7550
7533
|
if (isReadOnlyMode) {
|
|
7551
7534
|
{
|
|
7552
|
-
|
|
7535
|
+
formatDevErrorMessage(`Cannot use method in read-only mode.`);
|
|
7553
7536
|
}
|
|
7554
7537
|
}
|
|
7555
7538
|
}
|
|
7556
7539
|
function errorOnInfiniteTransforms() {
|
|
7557
7540
|
if (infiniteTransformCount > 99) {
|
|
7558
7541
|
{
|
|
7559
|
-
|
|
7542
|
+
formatDevErrorMessage(`One or more transforms are endlessly triggering additional transforms. May have encountered infinite recursion caused by transforms that have their preconditions too lose and/or conflict with each other.`);
|
|
7560
7543
|
}
|
|
7561
7544
|
}
|
|
7562
7545
|
}
|
|
7563
7546
|
function getActiveEditorState() {
|
|
7564
7547
|
if (activeEditorState === null) {
|
|
7565
7548
|
{
|
|
7566
|
-
|
|
7549
|
+
formatDevErrorMessage(`Unable to find an active editor state. State helpers or node methods can only be used synchronously during the callback of editor.update(), editor.read(), or editorState.read().${collectBuildInformation()}`);
|
|
7567
7550
|
}
|
|
7568
7551
|
}
|
|
7569
7552
|
return activeEditorState;
|
|
@@ -7571,7 +7554,7 @@ function getActiveEditorState() {
|
|
|
7571
7554
|
function getActiveEditor() {
|
|
7572
7555
|
if (activeEditor === null) {
|
|
7573
7556
|
{
|
|
7574
|
-
|
|
7557
|
+
formatDevErrorMessage(`Unable to find an active editor. This method can only be used synchronously during the callback of editor.update() or editor.read().${collectBuildInformation()}`);
|
|
7575
7558
|
}
|
|
7576
7559
|
}
|
|
7577
7560
|
return activeEditor;
|
|
@@ -7730,13 +7713,13 @@ function $parseSerializedNodeImpl(serializedNode, registeredNodes) {
|
|
|
7730
7713
|
const registeredNode = registeredNodes.get(type);
|
|
7731
7714
|
if (registeredNode === undefined) {
|
|
7732
7715
|
{
|
|
7733
|
-
|
|
7716
|
+
formatDevErrorMessage(`parseEditorState: type "${type}" + not found`);
|
|
7734
7717
|
}
|
|
7735
7718
|
}
|
|
7736
7719
|
const nodeClass = registeredNode.klass;
|
|
7737
7720
|
if (serializedNode.type !== nodeClass.getType()) {
|
|
7738
7721
|
{
|
|
7739
|
-
|
|
7722
|
+
formatDevErrorMessage(`LexicalNode: Node ${nodeClass.name} does not implement .importJSON().`);
|
|
7740
7723
|
}
|
|
7741
7724
|
}
|
|
7742
7725
|
const node = nodeClass.importJSON(serializedNode);
|
|
@@ -8092,7 +8075,7 @@ function processNestedUpdates(editor, initialSkipTransforms) {
|
|
|
8092
8075
|
if (options.discrete) {
|
|
8093
8076
|
const pendingEditorState = editor._pendingEditorState;
|
|
8094
8077
|
if (!(pendingEditorState !== null)) {
|
|
8095
|
-
|
|
8078
|
+
formatDevErrorMessage(`Unexpected empty pending editor state on discrete nested update`);
|
|
8096
8079
|
}
|
|
8097
8080
|
pendingEditorState._flushSync = true;
|
|
8098
8081
|
}
|
|
@@ -8171,7 +8154,7 @@ function $beginUpdate(editor, updateFn, options) {
|
|
|
8171
8154
|
const focusKey = pendingSelection.focus.key;
|
|
8172
8155
|
if (pendingNodeMap.get(anchorKey) === undefined || pendingNodeMap.get(focusKey) === undefined) {
|
|
8173
8156
|
{
|
|
8174
|
-
|
|
8157
|
+
formatDevErrorMessage(`updateEditor: selection has been lost because the previously selected nodes have been removed and selection wasn't moved to another node. Ensure selection changes after removing/replacing a selected node.`);
|
|
8175
8158
|
}
|
|
8176
8159
|
}
|
|
8177
8160
|
} else if ($isNodeSelection(pendingSelection)) {
|
|
@@ -8243,15 +8226,6 @@ function updateEditor(editor, updateFn, options) {
|
|
|
8243
8226
|
}
|
|
8244
8227
|
}
|
|
8245
8228
|
|
|
8246
|
-
/**
|
|
8247
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
8248
|
-
*
|
|
8249
|
-
* This source code is licensed under the MIT license found in the
|
|
8250
|
-
* LICENSE file in the root directory of this source tree.
|
|
8251
|
-
*
|
|
8252
|
-
*/
|
|
8253
|
-
|
|
8254
|
-
|
|
8255
8229
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
8256
8230
|
|
|
8257
8231
|
/**
|
|
@@ -8291,7 +8265,7 @@ class ElementDOMSlot {
|
|
|
8291
8265
|
insertChild(dom) {
|
|
8292
8266
|
const before = this.before || this.getManagedLineBreak();
|
|
8293
8267
|
if (!(before === null || before.parentElement === this.element)) {
|
|
8294
|
-
|
|
8268
|
+
formatDevErrorMessage(`ElementDOMSlot.insertChild: before is not in element`);
|
|
8295
8269
|
}
|
|
8296
8270
|
this.element.insertBefore(dom, before);
|
|
8297
8271
|
return this;
|
|
@@ -8301,7 +8275,7 @@ class ElementDOMSlot {
|
|
|
8301
8275
|
*/
|
|
8302
8276
|
removeChild(dom) {
|
|
8303
8277
|
if (!(dom.parentElement === this.element)) {
|
|
8304
|
-
|
|
8278
|
+
formatDevErrorMessage(`ElementDOMSlot.removeChild: dom is not in element`);
|
|
8305
8279
|
}
|
|
8306
8280
|
this.element.removeChild(dom);
|
|
8307
8281
|
return this;
|
|
@@ -8314,7 +8288,7 @@ class ElementDOMSlot {
|
|
|
8314
8288
|
*/
|
|
8315
8289
|
replaceChild(dom, prevDom) {
|
|
8316
8290
|
if (!(prevDom.parentElement === this.element)) {
|
|
8317
|
-
|
|
8291
|
+
formatDevErrorMessage(`ElementDOMSlot.replaceChild: prevDom is not in element`);
|
|
8318
8292
|
}
|
|
8319
8293
|
this.element.replaceChild(dom, prevDom);
|
|
8320
8294
|
return this;
|
|
@@ -8433,7 +8407,7 @@ function indexPath(root, child) {
|
|
|
8433
8407
|
path.push(i);
|
|
8434
8408
|
}
|
|
8435
8409
|
if (!(node === root)) {
|
|
8436
|
-
|
|
8410
|
+
formatDevErrorMessage(`indexPath: root is not a parent of child`);
|
|
8437
8411
|
}
|
|
8438
8412
|
return path.reverse();
|
|
8439
8413
|
}
|
|
@@ -8592,7 +8566,7 @@ class ElementNode extends LexicalNode {
|
|
|
8592
8566
|
const firstChild = this.getFirstChild();
|
|
8593
8567
|
if (firstChild === null) {
|
|
8594
8568
|
{
|
|
8595
|
-
|
|
8569
|
+
formatDevErrorMessage(`Expected node ${this.__key} to have a first child.`);
|
|
8596
8570
|
}
|
|
8597
8571
|
}
|
|
8598
8572
|
return firstChild;
|
|
@@ -8606,7 +8580,7 @@ class ElementNode extends LexicalNode {
|
|
|
8606
8580
|
const lastChild = this.getLastChild();
|
|
8607
8581
|
if (lastChild === null) {
|
|
8608
8582
|
{
|
|
8609
|
-
|
|
8583
|
+
formatDevErrorMessage(`Expected node ${this.__key} to have a last child.`);
|
|
8610
8584
|
}
|
|
8611
8585
|
}
|
|
8612
8586
|
return lastChild;
|
|
@@ -8787,7 +8761,7 @@ class ElementNode extends LexicalNode {
|
|
|
8787
8761
|
const oldSize = this.getChildrenSize();
|
|
8788
8762
|
const writableSelf = this.getWritable();
|
|
8789
8763
|
if (!(start + deleteCount <= oldSize)) {
|
|
8790
|
-
|
|
8764
|
+
formatDevErrorMessage(`ElementNode.splice: start + deleteCount > oldSize (${String(start)} + ${String(deleteCount)} > ${String(oldSize)})`);
|
|
8791
8765
|
}
|
|
8792
8766
|
const writableSelfKey = writableSelf.__key;
|
|
8793
8767
|
const nodesToInsertKeys = [];
|
|
@@ -8810,7 +8784,7 @@ class ElementNode extends LexicalNode {
|
|
|
8810
8784
|
for (let i = 0; i < deleteCount; i++) {
|
|
8811
8785
|
if (nodeToDelete === null) {
|
|
8812
8786
|
{
|
|
8813
|
-
|
|
8787
|
+
formatDevErrorMessage(`splice: sibling not found`);
|
|
8814
8788
|
}
|
|
8815
8789
|
}
|
|
8816
8790
|
const nextSibling = nodeToDelete.getNextSibling();
|
|
@@ -8843,7 +8817,7 @@ class ElementNode extends LexicalNode {
|
|
|
8843
8817
|
}
|
|
8844
8818
|
if (nodeToInsert.__key === writableSelfKey) {
|
|
8845
8819
|
{
|
|
8846
|
-
|
|
8820
|
+
formatDevErrorMessage(`append: attempting to append self`);
|
|
8847
8821
|
}
|
|
8848
8822
|
}
|
|
8849
8823
|
// Set child parent to self
|
|
@@ -9063,15 +9037,6 @@ function isPointRemoved(point, nodesToRemoveKeySet, nodesToInsertKeySet) {
|
|
|
9063
9037
|
return false;
|
|
9064
9038
|
}
|
|
9065
9039
|
|
|
9066
|
-
/**
|
|
9067
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
9068
|
-
*
|
|
9069
|
-
* This source code is licensed under the MIT license found in the
|
|
9070
|
-
* LICENSE file in the root directory of this source tree.
|
|
9071
|
-
*
|
|
9072
|
-
*/
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
9040
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
9076
9041
|
|
|
9077
9042
|
/** @noInheritDoc */
|
|
@@ -9082,7 +9047,7 @@ class DecoratorNode extends LexicalNode {
|
|
|
9082
9047
|
*/
|
|
9083
9048
|
decorate(editor, config) {
|
|
9084
9049
|
{
|
|
9085
|
-
|
|
9050
|
+
formatDevErrorMessage(`decorate: base method not extended`);
|
|
9086
9051
|
}
|
|
9087
9052
|
}
|
|
9088
9053
|
isIsolated() {
|
|
@@ -9099,14 +9064,6 @@ function $isDecoratorNode(node) {
|
|
|
9099
9064
|
return node instanceof DecoratorNode;
|
|
9100
9065
|
}
|
|
9101
9066
|
|
|
9102
|
-
/**
|
|
9103
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
9104
|
-
*
|
|
9105
|
-
* This source code is licensed under the MIT license found in the
|
|
9106
|
-
* LICENSE file in the root directory of this source tree.
|
|
9107
|
-
*
|
|
9108
|
-
*/
|
|
9109
|
-
|
|
9110
9067
|
/** @noInheritDoc */
|
|
9111
9068
|
class RootNode extends ElementNode {
|
|
9112
9069
|
/** @internal */
|
|
@@ -9123,7 +9080,7 @@ class RootNode extends ElementNode {
|
|
|
9123
9080
|
}
|
|
9124
9081
|
getTopLevelElementOrThrow() {
|
|
9125
9082
|
{
|
|
9126
|
-
|
|
9083
|
+
formatDevErrorMessage(`getTopLevelElementOrThrow: root nodes are not top level elements`);
|
|
9127
9084
|
}
|
|
9128
9085
|
}
|
|
9129
9086
|
getTextContent() {
|
|
@@ -9137,22 +9094,22 @@ class RootNode extends ElementNode {
|
|
|
9137
9094
|
}
|
|
9138
9095
|
remove() {
|
|
9139
9096
|
{
|
|
9140
|
-
|
|
9097
|
+
formatDevErrorMessage(`remove: cannot be called on root nodes`);
|
|
9141
9098
|
}
|
|
9142
9099
|
}
|
|
9143
9100
|
replace(node) {
|
|
9144
9101
|
{
|
|
9145
|
-
|
|
9102
|
+
formatDevErrorMessage(`replace: cannot be called on root nodes`);
|
|
9146
9103
|
}
|
|
9147
9104
|
}
|
|
9148
9105
|
insertBefore(nodeToInsert) {
|
|
9149
9106
|
{
|
|
9150
|
-
|
|
9107
|
+
formatDevErrorMessage(`insertBefore: cannot be called on root nodes`);
|
|
9151
9108
|
}
|
|
9152
9109
|
}
|
|
9153
9110
|
insertAfter(nodeToInsert) {
|
|
9154
9111
|
{
|
|
9155
|
-
|
|
9112
|
+
formatDevErrorMessage(`insertAfter: cannot be called on root nodes`);
|
|
9156
9113
|
}
|
|
9157
9114
|
}
|
|
9158
9115
|
|
|
@@ -9169,7 +9126,7 @@ class RootNode extends ElementNode {
|
|
|
9169
9126
|
const node = nodesToAppend[i];
|
|
9170
9127
|
if (!$isElementNode(node) && !$isDecoratorNode(node)) {
|
|
9171
9128
|
{
|
|
9172
|
-
|
|
9129
|
+
formatDevErrorMessage(`rootNode.append: Only element or decorator nodes can be appended to the root node`);
|
|
9173
9130
|
}
|
|
9174
9131
|
}
|
|
9175
9132
|
}
|
|
@@ -9190,14 +9147,6 @@ function $isRootNode(node) {
|
|
|
9190
9147
|
return node instanceof RootNode;
|
|
9191
9148
|
}
|
|
9192
9149
|
|
|
9193
|
-
/**
|
|
9194
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
9195
|
-
*
|
|
9196
|
-
* This source code is licensed under the MIT license found in the
|
|
9197
|
-
* LICENSE file in the root directory of this source tree.
|
|
9198
|
-
*
|
|
9199
|
-
*/
|
|
9200
|
-
|
|
9201
9150
|
function editorStateHasDirtySelection(editorState, editor) {
|
|
9202
9151
|
const currentSelection = editor.getEditorState()._selection;
|
|
9203
9152
|
const pendingSelection = editorState._selection;
|
|
@@ -9223,14 +9172,14 @@ function exportNodeToJSON(node) {
|
|
|
9223
9172
|
const nodeClass = node.constructor;
|
|
9224
9173
|
if (serializedNode.type !== nodeClass.getType()) {
|
|
9225
9174
|
{
|
|
9226
|
-
|
|
9175
|
+
formatDevErrorMessage(`LexicalNode: Node ${nodeClass.name} does not match the serialized type. Check if .exportJSON() is implemented and it is returning the correct type.`);
|
|
9227
9176
|
}
|
|
9228
9177
|
}
|
|
9229
9178
|
if ($isElementNode(node)) {
|
|
9230
9179
|
const serializedChildren = serializedNode.children;
|
|
9231
9180
|
if (!Array.isArray(serializedChildren)) {
|
|
9232
9181
|
{
|
|
9233
|
-
|
|
9182
|
+
formatDevErrorMessage(`LexicalNode: Node ${nodeClass.name} is an element but .exportJSON() does not have a children array.`);
|
|
9234
9183
|
}
|
|
9235
9184
|
}
|
|
9236
9185
|
const children = node.getChildren();
|
|
@@ -9411,15 +9360,6 @@ function $isParagraphNode(node) {
|
|
|
9411
9360
|
return node instanceof ParagraphNode;
|
|
9412
9361
|
}
|
|
9413
9362
|
|
|
9414
|
-
/**
|
|
9415
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
9416
|
-
*
|
|
9417
|
-
* This source code is licensed under the MIT license found in the
|
|
9418
|
-
* LICENSE file in the root directory of this source tree.
|
|
9419
|
-
*
|
|
9420
|
-
*/
|
|
9421
|
-
|
|
9422
|
-
|
|
9423
9363
|
// https://github.com/microsoft/TypeScript/issues/3841
|
|
9424
9364
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9425
9365
|
|
|
@@ -9558,7 +9498,7 @@ function createEditor(editorConfig) {
|
|
|
9558
9498
|
const name = klass.name;
|
|
9559
9499
|
if (replaceWithKlass) {
|
|
9560
9500
|
if (!(replaceWithKlass.prototype instanceof klass)) {
|
|
9561
|
-
|
|
9501
|
+
formatDevErrorMessage(`${replaceWithKlass.name} doesn't extend the ${name}`);
|
|
9562
9502
|
}
|
|
9563
9503
|
}
|
|
9564
9504
|
if (name !== 'RootNode' && nodeType !== 'root' && nodeType !== 'artificial') {
|
|
@@ -9843,7 +9783,7 @@ class LexicalEditor {
|
|
|
9843
9783
|
registerCommand(command, listener, priority) {
|
|
9844
9784
|
if (priority === undefined) {
|
|
9845
9785
|
{
|
|
9846
|
-
|
|
9786
|
+
formatDevErrorMessage(`Listener for type "command" requires a "priority".`);
|
|
9847
9787
|
}
|
|
9848
9788
|
}
|
|
9849
9789
|
const commandsMap = this._commands;
|
|
@@ -9853,7 +9793,7 @@ class LexicalEditor {
|
|
|
9853
9793
|
const listenersInPriorityOrder = commandsMap.get(command);
|
|
9854
9794
|
if (listenersInPriorityOrder === undefined) {
|
|
9855
9795
|
{
|
|
9856
|
-
|
|
9796
|
+
formatDevErrorMessage(`registerCommand: Command ${String(command)} not found in command map`);
|
|
9857
9797
|
}
|
|
9858
9798
|
}
|
|
9859
9799
|
const listeners = listenersInPriorityOrder[priority];
|
|
@@ -9902,7 +9842,7 @@ class LexicalEditor {
|
|
|
9902
9842
|
const registeredNode = this._nodes.get(klass.getType());
|
|
9903
9843
|
if (registeredNode === undefined) {
|
|
9904
9844
|
{
|
|
9905
|
-
|
|
9845
|
+
formatDevErrorMessage(`Node ${klass.name} has not been registered. Ensure node has been passed to createEditor.`);
|
|
9906
9846
|
}
|
|
9907
9847
|
}
|
|
9908
9848
|
return registeredNode;
|
|
@@ -10111,7 +10051,7 @@ class LexicalEditor {
|
|
|
10111
10051
|
setEditorState(editorState, options) {
|
|
10112
10052
|
if (editorState.isEmpty()) {
|
|
10113
10053
|
{
|
|
10114
|
-
|
|
10054
|
+
formatDevErrorMessage(`setEditorState: the editor state is empty. Ensure the editor state's root node never becomes empty.`);
|
|
10115
10055
|
}
|
|
10116
10056
|
}
|
|
10117
10057
|
|
|
@@ -10281,15 +10221,7 @@ class LexicalEditor {
|
|
|
10281
10221
|
};
|
|
10282
10222
|
}
|
|
10283
10223
|
}
|
|
10284
|
-
LexicalEditor.version = "0.
|
|
10285
|
-
|
|
10286
|
-
/**
|
|
10287
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
10288
|
-
*
|
|
10289
|
-
* This source code is licensed under the MIT license found in the
|
|
10290
|
-
* LICENSE file in the root directory of this source tree.
|
|
10291
|
-
*
|
|
10292
|
-
*/
|
|
10224
|
+
LexicalEditor.version = "0.27.0+dev.cjs";
|
|
10293
10225
|
|
|
10294
10226
|
let keyCounter = 1;
|
|
10295
10227
|
function resetRandomKey() {
|
|
@@ -10302,7 +10234,7 @@ function getRegisteredNodeOrThrow(editor, nodeType) {
|
|
|
10302
10234
|
const registeredNode = editor._nodes.get(nodeType);
|
|
10303
10235
|
if (registeredNode === undefined) {
|
|
10304
10236
|
{
|
|
10305
|
-
|
|
10237
|
+
formatDevErrorMessage(`registeredNode: Type ${nodeType} not found`);
|
|
10306
10238
|
}
|
|
10307
10239
|
}
|
|
10308
10240
|
return registeredNode;
|
|
@@ -10455,11 +10387,11 @@ function errorOnNodeKeyConstructorMismatch(node, existingKey) {
|
|
|
10455
10387
|
// Lifted condition to if statement because the inverted logic is a bit confusing
|
|
10456
10388
|
if (node.constructor.name !== existingNode.constructor.name) {
|
|
10457
10389
|
{
|
|
10458
|
-
|
|
10390
|
+
formatDevErrorMessage(`Lexical node with constructor ${node.constructor.name} attempted to re-use key from node in active editor state with constructor ${existingNode.constructor.name}. Keys must not be re-used when the type is changed.`);
|
|
10459
10391
|
}
|
|
10460
10392
|
} else {
|
|
10461
10393
|
{
|
|
10462
|
-
|
|
10394
|
+
formatDevErrorMessage(`Lexical node with constructor ${node.constructor.name} attempted to re-use key from node in active editor state with different constructor with the same name (possibly due to invalid Hot Module Replacement). Keys must not be re-used when the type is changed.`);
|
|
10463
10395
|
}
|
|
10464
10396
|
}
|
|
10465
10397
|
}
|
|
@@ -10678,7 +10610,7 @@ function $setSelection(selection) {
|
|
|
10678
10610
|
{
|
|
10679
10611
|
if (Object.isFrozen(selection)) {
|
|
10680
10612
|
{
|
|
10681
|
-
|
|
10613
|
+
formatDevErrorMessage(`$setSelection called on frozen selection object. Ensure selection is cloned before passing in.`);
|
|
10682
10614
|
}
|
|
10683
10615
|
}
|
|
10684
10616
|
}
|
|
@@ -11049,7 +10981,7 @@ function setMutatedNode(mutatedNodes, registeredNodes, mutationListeners, node,
|
|
|
11049
10981
|
const registeredNode = registeredNodes.get(nodeType);
|
|
11050
10982
|
if (registeredNode === undefined) {
|
|
11051
10983
|
{
|
|
11052
|
-
|
|
10984
|
+
formatDevErrorMessage(`Type ${nodeType} not in registeredNodes`);
|
|
11053
10985
|
}
|
|
11054
10986
|
}
|
|
11055
10987
|
const klass = registeredNode.klass;
|
|
@@ -11134,7 +11066,7 @@ function getElementByKeyOrThrow(editor, key) {
|
|
|
11134
11066
|
const element = editor._keyToDOMMap.get(key);
|
|
11135
11067
|
if (element === undefined) {
|
|
11136
11068
|
{
|
|
11137
|
-
|
|
11069
|
+
formatDevErrorMessage(`Reconciliation: could not find DOM element for node key ${key}`);
|
|
11138
11070
|
}
|
|
11139
11071
|
}
|
|
11140
11072
|
return element;
|
|
@@ -11252,7 +11184,7 @@ function getWindow(editor) {
|
|
|
11252
11184
|
const windowObj = editor._window;
|
|
11253
11185
|
if (windowObj === null) {
|
|
11254
11186
|
{
|
|
11255
|
-
|
|
11187
|
+
formatDevErrorMessage(`window object not found`);
|
|
11256
11188
|
}
|
|
11257
11189
|
}
|
|
11258
11190
|
return windowObj;
|
|
@@ -11290,7 +11222,7 @@ function $applyNodeReplacement(node) {
|
|
|
11290
11222
|
const nodeType = node.constructor.getType();
|
|
11291
11223
|
const registeredNode = editor._nodes.get(nodeType);
|
|
11292
11224
|
if (!(registeredNode !== undefined)) {
|
|
11293
|
-
|
|
11225
|
+
formatDevErrorMessage(`$applyNodeReplacement node ${node.constructor.name} with type ${nodeType} must be registered to the editor. You can do this by passing the node class via the "nodes" array in the editor config.`);
|
|
11294
11226
|
}
|
|
11295
11227
|
const {
|
|
11296
11228
|
replace,
|
|
@@ -11301,15 +11233,15 @@ function $applyNodeReplacement(node) {
|
|
|
11301
11233
|
const replacementNodeKlass = replacementNode.constructor;
|
|
11302
11234
|
if (replaceWithKlass !== null) {
|
|
11303
11235
|
if (!(replacementNode instanceof replaceWithKlass)) {
|
|
11304
|
-
|
|
11236
|
+
formatDevErrorMessage(`$applyNodeReplacement failed. Expected replacement node to be an instance of ${replaceWithKlass.name} with type ${replaceWithKlass.getType()} but returned ${replacementNodeKlass.name} with type ${replacementNodeKlass.getType()} from original node ${node.constructor.name} with type ${nodeType}`);
|
|
11305
11237
|
}
|
|
11306
11238
|
} else {
|
|
11307
11239
|
if (!(replacementNode instanceof node.constructor && replacementNodeKlass !== node.constructor)) {
|
|
11308
|
-
|
|
11240
|
+
formatDevErrorMessage(`$applyNodeReplacement failed. Ensure replacement node ${replacementNodeKlass.name} with type ${replacementNodeKlass.getType()} is a subclass of the original node ${node.constructor.name} with type ${nodeType}.`);
|
|
11309
11241
|
}
|
|
11310
11242
|
}
|
|
11311
11243
|
if (!(replacementNode.__key !== node.__key)) {
|
|
11312
|
-
|
|
11244
|
+
formatDevErrorMessage(`$applyNodeReplacement failed. Ensure that the key argument is *not* used in your replace function (from node ${node.constructor.name} with type ${nodeType} to node ${replacementNodeKlass.name} with type ${replacementNodeKlass.getType()}), Node keys must never be re-used except by the static clone method.`);
|
|
11313
11245
|
}
|
|
11314
11246
|
return replacementNode;
|
|
11315
11247
|
}
|
|
@@ -11319,7 +11251,7 @@ function errorOnInsertTextNodeOnRoot(node, insertNode) {
|
|
|
11319
11251
|
const parentNode = node.getParent();
|
|
11320
11252
|
if ($isRootNode(parentNode) && !$isElementNode(insertNode) && !$isDecoratorNode(insertNode)) {
|
|
11321
11253
|
{
|
|
11322
|
-
|
|
11254
|
+
formatDevErrorMessage(`Only element or decorator nodes can be inserted in to the root node`);
|
|
11323
11255
|
}
|
|
11324
11256
|
}
|
|
11325
11257
|
}
|
|
@@ -11327,7 +11259,7 @@ function $getNodeByKeyOrThrow(key) {
|
|
|
11327
11259
|
const node = $getNodeByKey(key);
|
|
11328
11260
|
if (node === null) {
|
|
11329
11261
|
{
|
|
11330
|
-
|
|
11262
|
+
formatDevErrorMessage(`Expected node with key ${key} to exist but it's not in the nodeMap.`);
|
|
11331
11263
|
}
|
|
11332
11264
|
}
|
|
11333
11265
|
return node;
|
|
@@ -11432,7 +11364,7 @@ function $splitNode(node, offset) {
|
|
|
11432
11364
|
startNode = node;
|
|
11433
11365
|
}
|
|
11434
11366
|
if (!!$isRootOrShadowRoot(node)) {
|
|
11435
|
-
|
|
11367
|
+
formatDevErrorMessage(`Can not call $splitNode() on root element`);
|
|
11436
11368
|
}
|
|
11437
11369
|
const recurse = currentNode => {
|
|
11438
11370
|
const parent = currentNode.getParentOrThrow();
|
|
@@ -11442,7 +11374,7 @@ function $splitNode(node, offset) {
|
|
|
11442
11374
|
const nodeToMove = currentNode === startNode && !isParentRoot ? currentNode : $copyNode(currentNode);
|
|
11443
11375
|
if (isParentRoot) {
|
|
11444
11376
|
if (!($isElementNode(currentNode) && $isElementNode(nodeToMove))) {
|
|
11445
|
-
|
|
11377
|
+
formatDevErrorMessage(`Children of a root must be ElementNode`);
|
|
11446
11378
|
}
|
|
11447
11379
|
currentNode.insertAfter(nodeToMove);
|
|
11448
11380
|
return [currentNode, nodeToMove, nodeToMove];
|
|
@@ -11574,7 +11506,7 @@ function getCachedTypeToNodeMap(editorState) {
|
|
|
11574
11506
|
return EMPTY_TYPE_TO_NODE_MAP;
|
|
11575
11507
|
}
|
|
11576
11508
|
if (!editorState._readOnly) {
|
|
11577
|
-
|
|
11509
|
+
formatDevErrorMessage(`getCachedTypeToNodeMap called with a writable EditorState`);
|
|
11578
11510
|
}
|
|
11579
11511
|
let typeToNodeMap = cachedNodeMaps.get(editorState);
|
|
11580
11512
|
if (!typeToNodeMap) {
|
|
@@ -11621,10 +11553,10 @@ function $cloneWithProperties(latestNode) {
|
|
|
11621
11553
|
mutableNode.afterCloneFrom(latestNode);
|
|
11622
11554
|
{
|
|
11623
11555
|
if (!(mutableNode.__key === latestNode.__key)) {
|
|
11624
|
-
|
|
11556
|
+
formatDevErrorMessage(`$cloneWithProperties: ${constructor.name}.clone(node) (with type '${constructor.getType()}') did not return a node with the same key, make sure to specify node.__key as the last argument to the constructor`);
|
|
11625
11557
|
}
|
|
11626
11558
|
if (!(mutableNode.__parent === latestNode.__parent && mutableNode.__next === latestNode.__next && mutableNode.__prev === latestNode.__prev)) {
|
|
11627
|
-
|
|
11559
|
+
formatDevErrorMessage(`$cloneWithProperties: ${constructor.name}.clone(node) (with type '${constructor.getType()}') overrided afterCloneFrom but did not call super.afterCloneFrom(prevNode)`);
|
|
11628
11560
|
}
|
|
11629
11561
|
}
|
|
11630
11562
|
return mutableNode;
|
|
@@ -11656,15 +11588,6 @@ function isDOMUnmanaged(elementDom) {
|
|
|
11656
11588
|
return el.__lexicalUnmanaged === true;
|
|
11657
11589
|
}
|
|
11658
11590
|
|
|
11659
|
-
/**
|
|
11660
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11661
|
-
*
|
|
11662
|
-
* This source code is licensed under the MIT license found in the
|
|
11663
|
-
* LICENSE file in the root directory of this source tree.
|
|
11664
|
-
*
|
|
11665
|
-
*/
|
|
11666
|
-
|
|
11667
|
-
|
|
11668
11591
|
/**
|
|
11669
11592
|
* The direction of a caret, 'next' points towards the end of the document
|
|
11670
11593
|
* and 'previous' points towards the beginning
|
|
@@ -11831,7 +11754,7 @@ class AbstractCaret {
|
|
|
11831
11754
|
}
|
|
11832
11755
|
} else {
|
|
11833
11756
|
if (!(target !== null)) {
|
|
11834
|
-
|
|
11757
|
+
formatDevErrorMessage(`NodeCaret.splice: Underflow of expected nodesToRemove during splice (keys: ${Array.from(nodesToRemove).join(' ')})`);
|
|
11835
11758
|
}
|
|
11836
11759
|
}
|
|
11837
11760
|
} else {
|
|
@@ -12109,7 +12032,7 @@ function $getTextNodeOffset(origin, offset) {
|
|
|
12109
12032
|
const size = origin.getTextContentSize();
|
|
12110
12033
|
const numericOffset = offset === 'next' ? size : offset === 'previous' ? 0 : offset;
|
|
12111
12034
|
if (!(numericOffset >= 0 && numericOffset <= size)) {
|
|
12112
|
-
|
|
12035
|
+
formatDevErrorMessage(`$getTextNodeOffset: invalid offset ${String(offset)} for size ${String(size)}`);
|
|
12113
12036
|
}
|
|
12114
12037
|
return numericOffset;
|
|
12115
12038
|
}
|
|
@@ -12288,7 +12211,7 @@ function $extendCaretToRange(anchor) {
|
|
|
12288
12211
|
*/
|
|
12289
12212
|
function $getCaretRange(anchor, focus) {
|
|
12290
12213
|
if (!(anchor.direction === focus.direction)) {
|
|
12291
|
-
|
|
12214
|
+
formatDevErrorMessage(`$getCaretRange: anchor and focus must be in the same direction`);
|
|
12292
12215
|
}
|
|
12293
12216
|
return new CaretRangeImpl(anchor, focus, anchor.direction);
|
|
12294
12217
|
}
|
|
@@ -12366,7 +12289,7 @@ function compareNumber(a, b) {
|
|
|
12366
12289
|
function $comparePointCaretNext(a, b) {
|
|
12367
12290
|
const compare = $getCommonAncestor(a.origin, b.origin);
|
|
12368
12291
|
if (!(compare !== null)) {
|
|
12369
|
-
|
|
12292
|
+
formatDevErrorMessage(`$comparePointCaretNext: a (key ${a.origin.getKey()}) and b (key ${b.origin.getKey()}) do not have a common ancestor`);
|
|
12370
12293
|
}
|
|
12371
12294
|
switch (compare.type) {
|
|
12372
12295
|
case 'same':
|
|
@@ -12471,7 +12394,7 @@ function $getCommonAncestor(a, b) {
|
|
|
12471
12394
|
if (aChild === undefined) ; else if (aChild === null) {
|
|
12472
12395
|
// a is the ancestor
|
|
12473
12396
|
if (!$isSameNode(a, parent)) {
|
|
12474
|
-
|
|
12397
|
+
formatDevErrorMessage(`$originComparison: ancestor logic error`);
|
|
12475
12398
|
}
|
|
12476
12399
|
return {
|
|
12477
12400
|
commonAncestor: parent,
|
|
@@ -12480,7 +12403,7 @@ function $getCommonAncestor(a, b) {
|
|
|
12480
12403
|
} else if (child === null) {
|
|
12481
12404
|
// b is the ancestor
|
|
12482
12405
|
if (!$isSameNode(b, parent)) {
|
|
12483
|
-
|
|
12406
|
+
formatDevErrorMessage(`$originComparison: descendant logic error`);
|
|
12484
12407
|
}
|
|
12485
12408
|
return {
|
|
12486
12409
|
commonAncestor: parent,
|
|
@@ -12488,7 +12411,7 @@ function $getCommonAncestor(a, b) {
|
|
|
12488
12411
|
};
|
|
12489
12412
|
} else {
|
|
12490
12413
|
if (!(($isElementNode(aChild) || $isSameNode(a, aChild)) && ($isElementNode(child) || $isSameNode(b, child)) && parent.is(aChild.getParent()) && parent.is(child.getParent()))) {
|
|
12491
|
-
|
|
12414
|
+
formatDevErrorMessage(`$originComparison: branch logic error`);
|
|
12492
12415
|
}
|
|
12493
12416
|
return {
|
|
12494
12417
|
a: aChild,
|
|
@@ -12501,15 +12424,6 @@ function $getCommonAncestor(a, b) {
|
|
|
12501
12424
|
return null;
|
|
12502
12425
|
}
|
|
12503
12426
|
|
|
12504
|
-
/**
|
|
12505
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
12506
|
-
*
|
|
12507
|
-
* This source code is licensed under the MIT license found in the
|
|
12508
|
-
* LICENSE file in the root directory of this source tree.
|
|
12509
|
-
*
|
|
12510
|
-
*/
|
|
12511
|
-
|
|
12512
|
-
|
|
12513
12427
|
/**
|
|
12514
12428
|
* @param point
|
|
12515
12429
|
* @returns a PointCaret for the point
|
|
@@ -12523,12 +12437,12 @@ function $caretFromPoint(point, direction) {
|
|
|
12523
12437
|
const node = $getNodeByKeyOrThrow(point.key);
|
|
12524
12438
|
if (type === 'text') {
|
|
12525
12439
|
if (!$isTextNode(node)) {
|
|
12526
|
-
|
|
12440
|
+
formatDevErrorMessage(`$caretFromPoint: Node with type ${node.getType()} and key ${key} that does not inherit from TextNode encountered for text point`);
|
|
12527
12441
|
}
|
|
12528
12442
|
return $getTextPointCaret(node, direction, offset);
|
|
12529
12443
|
}
|
|
12530
12444
|
if (!$isElementNode(node)) {
|
|
12531
|
-
|
|
12445
|
+
formatDevErrorMessage(`$caretFromPoint: Node with type ${node.getType()} and key ${key} that does not inherit from ElementNode encountered for element point`);
|
|
12532
12446
|
}
|
|
12533
12447
|
return $getChildCaretAtIndex(node, point.offset, direction);
|
|
12534
12448
|
}
|
|
@@ -12555,7 +12469,7 @@ function $setPointFromCaret(point, caret) {
|
|
|
12555
12469
|
}
|
|
12556
12470
|
} else {
|
|
12557
12471
|
if (!($isChildCaret(caret) && $isElementNode(origin))) {
|
|
12558
|
-
|
|
12472
|
+
formatDevErrorMessage(`$setPointFromCaret: exhaustiveness check`);
|
|
12559
12473
|
}
|
|
12560
12474
|
point.set(origin.getKey(), isNext ? 0 : origin.getChildrenSize(), 'element');
|
|
12561
12475
|
}
|
|
@@ -12746,7 +12660,7 @@ function $removeTextFromCaretRange(initialRange, sliceMode = 'removeEmptySlices'
|
|
|
12746
12660
|
return $getCaretRange(anchor, anchor);
|
|
12747
12661
|
}
|
|
12748
12662
|
{
|
|
12749
|
-
|
|
12663
|
+
formatDevErrorMessage(`$removeTextFromCaretRange: selection was lost, could not find a new anchor given candidates with keys: ${JSON.stringify(anchorCandidates.map(n => n.origin.__key))}`);
|
|
12750
12664
|
}
|
|
12751
12665
|
}
|
|
12752
12666
|
|
|
@@ -12843,6 +12757,17 @@ function $normalizeCaret(initialCaret) {
|
|
|
12843
12757
|
const adj = caret.getAdjacentCaret();
|
|
12844
12758
|
return $isSiblingCaret(adj) && $isTextNode(adj.origin) ? $getTextPointCaret(adj.origin, direction, flipDirection(direction)) : caret;
|
|
12845
12759
|
}
|
|
12760
|
+
/**
|
|
12761
|
+
* Determine whether the TextPointCaret's offset can be extended further without leaving the TextNode.
|
|
12762
|
+
* Returns false if the given caret is not a TextPointCaret or the offset can not be moved further in
|
|
12763
|
+
* direction.
|
|
12764
|
+
*
|
|
12765
|
+
* @param caret A PointCaret
|
|
12766
|
+
* @returns true if caret is a TextPointCaret with an offset that is not at the end of the text given the direction.
|
|
12767
|
+
*/
|
|
12768
|
+
function $isExtendableTextPointCaret(caret) {
|
|
12769
|
+
return $isTextPointCaret(caret) && caret.offset !== $getTextNodeOffset(caret.origin, caret.direction);
|
|
12770
|
+
}
|
|
12846
12771
|
|
|
12847
12772
|
/**
|
|
12848
12773
|
* Return the caret if it's in the given direction, otherwise return
|
|
@@ -12971,6 +12896,7 @@ exports.$isBlockElementNode = $isBlockElementNode;
|
|
|
12971
12896
|
exports.$isChildCaret = $isChildCaret;
|
|
12972
12897
|
exports.$isDecoratorNode = $isDecoratorNode;
|
|
12973
12898
|
exports.$isElementNode = $isElementNode;
|
|
12899
|
+
exports.$isExtendableTextPointCaret = $isExtendableTextPointCaret;
|
|
12974
12900
|
exports.$isInlineElementOrDecoratorNode = $isInlineElementOrDecoratorNode;
|
|
12975
12901
|
exports.$isLeafNode = $isLeafNode;
|
|
12976
12902
|
exports.$isLineBreakNode = $isLineBreakNode;
|