lexical 0.25.1-nightly.20250228.0 → 0.26.1-nightly.20250303.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 +300 -347
- package/Lexical.dev.mjs +300 -348
- package/Lexical.js.flow +6 -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/LexicalNode.d.ts +2 -3
- package/caret/LexicalCaretUtils.d.ts +14 -1
- package/index.d.ts +1 -1
- package/nodes/LexicalLineBreakNode.d.ts +1 -0
- package/nodes/LexicalTextNode.d.ts +4 -0
- 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]];
|
|
@@ -1837,6 +1825,7 @@ let isInsertLineBreak = false;
|
|
|
1837
1825
|
let isFirefoxEndingComposition = false;
|
|
1838
1826
|
let isSafariEndingComposition = false;
|
|
1839
1827
|
let safariEndCompositionEventData = '';
|
|
1828
|
+
let postDeleteSelectionToRestore = null;
|
|
1840
1829
|
let collapsedSelectionFormat = [0, '', 0, 'root', 0];
|
|
1841
1830
|
|
|
1842
1831
|
// This function is used to determine if Lexical should attempt to override
|
|
@@ -1905,7 +1894,7 @@ function onSelectionChange(domSelection, editor, isActive) {
|
|
|
1905
1894
|
// We also need to check if the offset is at the boundary,
|
|
1906
1895
|
// because in this case, we might need to normalize to a
|
|
1907
1896
|
// sibling instead.
|
|
1908
|
-
if (shouldSkipSelectionChange(anchorDOM, anchorOffset) && shouldSkipSelectionChange(focusDOM, focusOffset)) {
|
|
1897
|
+
if (shouldSkipSelectionChange(anchorDOM, anchorOffset) && shouldSkipSelectionChange(focusDOM, focusOffset) && !postDeleteSelectionToRestore) {
|
|
1909
1898
|
return;
|
|
1910
1899
|
}
|
|
1911
1900
|
}
|
|
@@ -1919,7 +1908,23 @@ function onSelectionChange(domSelection, editor, isActive) {
|
|
|
1919
1908
|
if (!isSelectionWithinEditor(editor, anchorDOM, focusDOM)) {
|
|
1920
1909
|
return;
|
|
1921
1910
|
}
|
|
1922
|
-
|
|
1911
|
+
let selection = $getSelection();
|
|
1912
|
+
|
|
1913
|
+
// Restore selection in the event of incorrect rightward shift after deletion
|
|
1914
|
+
if (postDeleteSelectionToRestore && $isRangeSelection(selection) && selection.isCollapsed()) {
|
|
1915
|
+
const curAnchor = selection.anchor;
|
|
1916
|
+
const prevAnchor = postDeleteSelectionToRestore.anchor;
|
|
1917
|
+
if (
|
|
1918
|
+
// Rightward shift in same node
|
|
1919
|
+
curAnchor.key === prevAnchor.key && curAnchor.offset === prevAnchor.offset + 1 ||
|
|
1920
|
+
// Or rightward shift into sibling node
|
|
1921
|
+
curAnchor.offset === 1 && prevAnchor.getNode().is(curAnchor.getNode().getPreviousSibling())) {
|
|
1922
|
+
// Restore selection
|
|
1923
|
+
selection = postDeleteSelectionToRestore.clone();
|
|
1924
|
+
$setSelection(selection);
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
postDeleteSelectionToRestore = null;
|
|
1923
1928
|
|
|
1924
1929
|
// Update the selection format
|
|
1925
1930
|
if ($isRangeSelection(selection)) {
|
|
@@ -1944,12 +1949,12 @@ function onSelectionChange(domSelection, editor, isActive) {
|
|
|
1944
1949
|
} else {
|
|
1945
1950
|
if (anchor.type === 'text') {
|
|
1946
1951
|
if (!$isTextNode(anchorNode)) {
|
|
1947
|
-
|
|
1952
|
+
formatDevErrorMessage(`Point.getNode() must return TextNode when type is text`);
|
|
1948
1953
|
}
|
|
1949
1954
|
$updateSelectionFormatStyleFromTextNode(selection, anchorNode);
|
|
1950
1955
|
} else if (anchor.type === 'element' && !isRootTextContentEmpty) {
|
|
1951
1956
|
if (!$isElementNode(anchorNode)) {
|
|
1952
|
-
|
|
1957
|
+
formatDevErrorMessage(`Point.getNode() must return ElementNode when type is element`);
|
|
1953
1958
|
}
|
|
1954
1959
|
const lastNode = anchor.getNode();
|
|
1955
1960
|
if (
|
|
@@ -2132,7 +2137,7 @@ function onBeforeInput(event, editor) {
|
|
|
2132
2137
|
const anchorNode = selection.anchor.getNode();
|
|
2133
2138
|
anchorNode.markDirty();
|
|
2134
2139
|
if (!$isTextNode(anchorNode)) {
|
|
2135
|
-
|
|
2140
|
+
formatDevErrorMessage(`Anchor node must be a TextNode`);
|
|
2136
2141
|
}
|
|
2137
2142
|
$updateSelectionFormatStyleFromTextNode(selection, anchorNode);
|
|
2138
2143
|
}
|
|
@@ -2156,6 +2161,14 @@ function onBeforeInput(event, editor) {
|
|
|
2156
2161
|
}
|
|
2157
2162
|
if (!shouldLetBrowserHandleDelete) {
|
|
2158
2163
|
dispatchCommand(editor, DELETE_CHARACTER_COMMAND, true);
|
|
2164
|
+
// When deleting across paragraphs, Chrome on Android incorrectly shifts the selection rightwards
|
|
2165
|
+
// We save the correct selection to restore later during handling of selectionchange event
|
|
2166
|
+
const selectionAfterDelete = $getSelection();
|
|
2167
|
+
if (IS_ANDROID_CHROME && $isRangeSelection(selectionAfterDelete) && selectionAfterDelete.isCollapsed()) {
|
|
2168
|
+
postDeleteSelectionToRestore = selectionAfterDelete;
|
|
2169
|
+
// Cleanup in case selectionchange does not fire
|
|
2170
|
+
setTimeout(() => postDeleteSelectionToRestore = null);
|
|
2171
|
+
}
|
|
2159
2172
|
}
|
|
2160
2173
|
}
|
|
2161
2174
|
return;
|
|
@@ -2729,12 +2742,12 @@ function removeRootElementEvents(rootElement) {
|
|
|
2729
2742
|
const doc = rootElement.ownerDocument;
|
|
2730
2743
|
const documentRootElementsCount = rootElementsRegistered.get(doc);
|
|
2731
2744
|
if (!(documentRootElementsCount !== undefined)) {
|
|
2732
|
-
|
|
2745
|
+
formatDevErrorMessage(`Root element not registered`);
|
|
2733
2746
|
} // We only want to have a single global selectionchange event handler, shared
|
|
2734
2747
|
// between all editor instances.
|
|
2735
2748
|
const newCount = documentRootElementsCount - 1;
|
|
2736
2749
|
if (!(newCount >= 0)) {
|
|
2737
|
-
|
|
2750
|
+
formatDevErrorMessage(`Root element count less than 0`);
|
|
2738
2751
|
}
|
|
2739
2752
|
rootElementsRegistered.set(doc, newCount);
|
|
2740
2753
|
if (newCount === 0) {
|
|
@@ -2747,7 +2760,7 @@ function removeRootElementEvents(rootElement) {
|
|
|
2747
2760
|
rootElement.__lexicalEditor = null;
|
|
2748
2761
|
} else if (editor) {
|
|
2749
2762
|
{
|
|
2750
|
-
|
|
2763
|
+
formatDevErrorMessage(`Attempted to remove event handlers from a node that does not belong to this build of Lexical`);
|
|
2751
2764
|
}
|
|
2752
2765
|
}
|
|
2753
2766
|
const removeHandles = getRootElementRemoveHandles(rootElement);
|
|
@@ -2779,15 +2792,6 @@ function markCollapsedSelectionFormat(format, style, offset, key, timeStamp) {
|
|
|
2779
2792
|
collapsedSelectionFormat = [format, style, offset, key, timeStamp];
|
|
2780
2793
|
}
|
|
2781
2794
|
|
|
2782
|
-
/**
|
|
2783
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2784
|
-
*
|
|
2785
|
-
* This source code is licensed under the MIT license found in the
|
|
2786
|
-
* LICENSE file in the root directory of this source tree.
|
|
2787
|
-
*
|
|
2788
|
-
*/
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
2795
|
/**
|
|
2792
2796
|
* The base type for all serialized nodes
|
|
2793
2797
|
*/
|
|
@@ -2865,7 +2869,7 @@ class LexicalNode {
|
|
|
2865
2869
|
*/
|
|
2866
2870
|
static getType() {
|
|
2867
2871
|
{
|
|
2868
|
-
|
|
2872
|
+
formatDevErrorMessage(`LexicalNode: Node ${this.name} does not implement .getType().`);
|
|
2869
2873
|
}
|
|
2870
2874
|
}
|
|
2871
2875
|
|
|
@@ -2877,7 +2881,7 @@ class LexicalNode {
|
|
|
2877
2881
|
*/
|
|
2878
2882
|
static clone(_data) {
|
|
2879
2883
|
{
|
|
2880
|
-
|
|
2884
|
+
formatDevErrorMessage(`LexicalNode: Node ${this.name} does not implement .clone().`);
|
|
2881
2885
|
}
|
|
2882
2886
|
}
|
|
2883
2887
|
|
|
@@ -2969,7 +2973,7 @@ class LexicalNode {
|
|
|
2969
2973
|
}
|
|
2970
2974
|
isInline() {
|
|
2971
2975
|
{
|
|
2972
|
-
|
|
2976
|
+
formatDevErrorMessage(`LexicalNode: Node ${this.constructor.name} does not implement .isInline().`);
|
|
2973
2977
|
}
|
|
2974
2978
|
}
|
|
2975
2979
|
|
|
@@ -3073,7 +3077,7 @@ class LexicalNode {
|
|
|
3073
3077
|
const parent = this.getParent();
|
|
3074
3078
|
if (parent === null) {
|
|
3075
3079
|
{
|
|
3076
|
-
|
|
3080
|
+
formatDevErrorMessage(`Expected node ${this.__key} to have a parent.`);
|
|
3077
3081
|
}
|
|
3078
3082
|
}
|
|
3079
3083
|
return parent;
|
|
@@ -3090,7 +3094,7 @@ class LexicalNode {
|
|
|
3090
3094
|
const parent = node.getParent();
|
|
3091
3095
|
if ($isRootOrShadowRoot(parent)) {
|
|
3092
3096
|
if (!($isElementNode(node) || node === this && $isDecoratorNode(node))) {
|
|
3093
|
-
|
|
3097
|
+
formatDevErrorMessage(`Children of root nodes must be elements or decorators`);
|
|
3094
3098
|
}
|
|
3095
3099
|
return node;
|
|
3096
3100
|
}
|
|
@@ -3108,7 +3112,7 @@ class LexicalNode {
|
|
|
3108
3112
|
const parent = this.getTopLevelElement();
|
|
3109
3113
|
if (parent === null) {
|
|
3110
3114
|
{
|
|
3111
|
-
|
|
3115
|
+
formatDevErrorMessage(`Expected node ${this.__key} to have a top parent element.`);
|
|
3112
3116
|
}
|
|
3113
3117
|
}
|
|
3114
3118
|
return parent;
|
|
@@ -3252,7 +3256,7 @@ class LexicalNode {
|
|
|
3252
3256
|
return $getCommonAncestorResultBranchOrder(compare) === -1;
|
|
3253
3257
|
}
|
|
3254
3258
|
if (!(compare.type === 'same' || compare.type === 'ancestor')) {
|
|
3255
|
-
|
|
3259
|
+
formatDevErrorMessage(`LexicalNode.isBefore: exhaustiveness check`);
|
|
3256
3260
|
}
|
|
3257
3261
|
return false;
|
|
3258
3262
|
}
|
|
@@ -3313,7 +3317,7 @@ class LexicalNode {
|
|
|
3313
3317
|
do {
|
|
3314
3318
|
if (ancestor === null) {
|
|
3315
3319
|
{
|
|
3316
|
-
|
|
3320
|
+
formatDevErrorMessage(`getNodesBetween: ancestor is null`);
|
|
3317
3321
|
}
|
|
3318
3322
|
}
|
|
3319
3323
|
parentSibling = isBefore ? ancestor.getNextSibling() : ancestor.getPreviousSibling();
|
|
@@ -3353,7 +3357,7 @@ class LexicalNode {
|
|
|
3353
3357
|
const latest = $getNodeByKey(this.__key);
|
|
3354
3358
|
if (latest === null) {
|
|
3355
3359
|
{
|
|
3356
|
-
|
|
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.`);
|
|
3357
3361
|
}
|
|
3358
3362
|
}
|
|
3359
3363
|
return latest;
|
|
@@ -3425,7 +3429,7 @@ class LexicalNode {
|
|
|
3425
3429
|
* */
|
|
3426
3430
|
createDOM(_config, _editor) {
|
|
3427
3431
|
{
|
|
3428
|
-
|
|
3432
|
+
formatDevErrorMessage(`createDOM: base method not extended`);
|
|
3429
3433
|
}
|
|
3430
3434
|
}
|
|
3431
3435
|
|
|
@@ -3441,7 +3445,7 @@ class LexicalNode {
|
|
|
3441
3445
|
* */
|
|
3442
3446
|
updateDOM(_prevNode, _dom, _config) {
|
|
3443
3447
|
{
|
|
3444
|
-
|
|
3448
|
+
formatDevErrorMessage(`updateDOM: base method not extended`);
|
|
3445
3449
|
}
|
|
3446
3450
|
}
|
|
3447
3451
|
|
|
@@ -3486,7 +3490,7 @@ class LexicalNode {
|
|
|
3486
3490
|
* */
|
|
3487
3491
|
static importJSON(_serializedNode) {
|
|
3488
3492
|
{
|
|
3489
|
-
|
|
3493
|
+
formatDevErrorMessage(`LexicalNode: Node ${this.name} does not implement .importJSON().`);
|
|
3490
3494
|
}
|
|
3491
3495
|
}
|
|
3492
3496
|
|
|
@@ -3519,7 +3523,7 @@ class LexicalNode {
|
|
|
3519
3523
|
* ```
|
|
3520
3524
|
**/
|
|
3521
3525
|
updateFromJSON(serializedNode) {
|
|
3522
|
-
return $updateStateFromJSON(this, serializedNode[
|
|
3526
|
+
return $updateStateFromJSON(this, serializedNode[NODE_STATE_KEY]);
|
|
3523
3527
|
}
|
|
3524
3528
|
|
|
3525
3529
|
/**
|
|
@@ -3594,7 +3598,7 @@ class LexicalNode {
|
|
|
3594
3598
|
writableParent.__size = size;
|
|
3595
3599
|
if (includeChildren) {
|
|
3596
3600
|
if (!($isElementNode(this) && $isElementNode(writableReplaceWith))) {
|
|
3597
|
-
|
|
3601
|
+
formatDevErrorMessage(`includeChildren should only be true for ElementNodes`);
|
|
3598
3602
|
}
|
|
3599
3603
|
this.getChildren().forEach(child => {
|
|
3600
3604
|
writableReplaceWith.append(child);
|
|
@@ -3804,13 +3808,13 @@ function errorOnTypeKlassMismatch(type, klass) {
|
|
|
3804
3808
|
// Common error - split in its own invariant
|
|
3805
3809
|
if (registeredNode === undefined) {
|
|
3806
3810
|
{
|
|
3807
|
-
|
|
3811
|
+
formatDevErrorMessage(`Create node: Attempted to create node ${klass.name} that was not configured to be used on the editor.`);
|
|
3808
3812
|
}
|
|
3809
3813
|
}
|
|
3810
3814
|
const editorKlass = registeredNode.klass;
|
|
3811
3815
|
if (editorKlass !== klass) {
|
|
3812
3816
|
{
|
|
3813
|
-
|
|
3817
|
+
formatDevErrorMessage(`Create node: Type ${type} in node ${klass.name} does not match registered node ${editorKlass.name} with the same type`);
|
|
3814
3818
|
}
|
|
3815
3819
|
}
|
|
3816
3820
|
}
|
|
@@ -3829,7 +3833,7 @@ function insertRangeAfter(node, firstToInsert, lastToInsert) {
|
|
|
3829
3833
|
while (current !== lastToInsert2) {
|
|
3830
3834
|
if (!current.getNextSibling()) {
|
|
3831
3835
|
{
|
|
3832
|
-
|
|
3836
|
+
formatDevErrorMessage(`insertRangeAfter: lastToInsert must be a later sibling of firstToInsert`);
|
|
3833
3837
|
}
|
|
3834
3838
|
}
|
|
3835
3839
|
current = current.getNextSibling();
|
|
@@ -3869,6 +3873,9 @@ class LineBreakNode extends LexicalNode {
|
|
|
3869
3873
|
updateDOM() {
|
|
3870
3874
|
return false;
|
|
3871
3875
|
}
|
|
3876
|
+
isInline() {
|
|
3877
|
+
return true;
|
|
3878
|
+
}
|
|
3872
3879
|
static importDOM() {
|
|
3873
3880
|
return {
|
|
3874
3881
|
br: node => {
|
|
@@ -3931,14 +3938,6 @@ function isWhitespaceDomTextNode(node) {
|
|
|
3931
3938
|
return isDOMTextNode(node) && /^( |\t|\r?\n)+$/.test(node.textContent || '');
|
|
3932
3939
|
}
|
|
3933
3940
|
|
|
3934
|
-
/**
|
|
3935
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3936
|
-
*
|
|
3937
|
-
* This source code is licensed under the MIT license found in the
|
|
3938
|
-
* LICENSE file in the root directory of this source tree.
|
|
3939
|
-
*
|
|
3940
|
-
*/
|
|
3941
|
-
|
|
3942
3941
|
function getElementOuterTag(node, format) {
|
|
3943
3942
|
if (format & IS_CODE) {
|
|
3944
3943
|
return 'code';
|
|
@@ -4246,6 +4245,13 @@ class TextNode extends LexicalNode {
|
|
|
4246
4245
|
return true;
|
|
4247
4246
|
}
|
|
4248
4247
|
|
|
4248
|
+
/**
|
|
4249
|
+
* @returns true if the text node is inline, false otherwise.
|
|
4250
|
+
*/
|
|
4251
|
+
isInline() {
|
|
4252
|
+
return true;
|
|
4253
|
+
}
|
|
4254
|
+
|
|
4249
4255
|
// View
|
|
4250
4256
|
|
|
4251
4257
|
createDOM(config, editor) {
|
|
@@ -4288,7 +4294,7 @@ class TextNode extends LexicalNode {
|
|
|
4288
4294
|
const prevInnerDOM = dom.firstChild;
|
|
4289
4295
|
if (prevInnerDOM == null) {
|
|
4290
4296
|
{
|
|
4291
|
-
|
|
4297
|
+
formatDevErrorMessage(`updateDOM: prevInnerDOM is null or undefined`);
|
|
4292
4298
|
}
|
|
4293
4299
|
}
|
|
4294
4300
|
const nextInnerDOM = document.createElement(nextInnerTag);
|
|
@@ -4302,7 +4308,7 @@ class TextNode extends LexicalNode {
|
|
|
4302
4308
|
innerDOM = dom.firstChild;
|
|
4303
4309
|
if (innerDOM == null) {
|
|
4304
4310
|
{
|
|
4305
|
-
|
|
4311
|
+
formatDevErrorMessage(`updateDOM: innerDOM is null or undefined`);
|
|
4306
4312
|
}
|
|
4307
4313
|
}
|
|
4308
4314
|
}
|
|
@@ -4388,7 +4394,7 @@ class TextNode extends LexicalNode {
|
|
|
4388
4394
|
element
|
|
4389
4395
|
} = super.exportDOM(editor);
|
|
4390
4396
|
if (!isHTMLElement(element)) {
|
|
4391
|
-
|
|
4397
|
+
formatDevErrorMessage(`Expected TextNode createDOM to always return a HTMLElement`);
|
|
4392
4398
|
}
|
|
4393
4399
|
element.style.whiteSpace = 'pre-wrap';
|
|
4394
4400
|
// This is the only way to properly add support for most clients,
|
|
@@ -4783,7 +4789,7 @@ class TextNode extends LexicalNode {
|
|
|
4783
4789
|
const isBefore = target === this.getPreviousSibling();
|
|
4784
4790
|
if (!isBefore && target !== this.getNextSibling()) {
|
|
4785
4791
|
{
|
|
4786
|
-
|
|
4792
|
+
formatDevErrorMessage(`mergeWithSibling: sibling must be a previous or next sibling`);
|
|
4787
4793
|
}
|
|
4788
4794
|
}
|
|
4789
4795
|
const key = this.__key;
|
|
@@ -4871,7 +4877,7 @@ function $convertTextDOMNode(domNode) {
|
|
|
4871
4877
|
const domNode_ = domNode;
|
|
4872
4878
|
const parentDom = domNode.parentElement;
|
|
4873
4879
|
if (!(parentDom !== null)) {
|
|
4874
|
-
|
|
4880
|
+
formatDevErrorMessage(`Expected parentElement of Text not to be null`);
|
|
4875
4881
|
}
|
|
4876
4882
|
let textContent = domNode_.textContent || '';
|
|
4877
4883
|
// No collapse and preserve segment break for pre, pre-wrap and pre-line
|
|
@@ -5044,14 +5050,6 @@ function applyTextFormatFromStyle(style, shouldApply) {
|
|
|
5044
5050
|
};
|
|
5045
5051
|
}
|
|
5046
5052
|
|
|
5047
|
-
/**
|
|
5048
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
5049
|
-
*
|
|
5050
|
-
* This source code is licensed under the MIT license found in the
|
|
5051
|
-
* LICENSE file in the root directory of this source tree.
|
|
5052
|
-
*
|
|
5053
|
-
*/
|
|
5054
|
-
|
|
5055
5053
|
/** @noInheritDoc */
|
|
5056
5054
|
class TabNode extends TextNode {
|
|
5057
5055
|
static getType() {
|
|
@@ -5081,19 +5079,19 @@ class TabNode extends TextNode {
|
|
|
5081
5079
|
}
|
|
5082
5080
|
setTextContent(text) {
|
|
5083
5081
|
if (!(text === '\t' || text === '')) {
|
|
5084
|
-
|
|
5082
|
+
formatDevErrorMessage(`TabNode does not support setTextContent`);
|
|
5085
5083
|
}
|
|
5086
5084
|
return super.setTextContent(text);
|
|
5087
5085
|
}
|
|
5088
5086
|
setDetail(detail) {
|
|
5089
5087
|
if (!(detail === IS_UNMERGEABLE)) {
|
|
5090
|
-
|
|
5088
|
+
formatDevErrorMessage(`TabNode does not support setDetail`);
|
|
5091
5089
|
}
|
|
5092
5090
|
return this;
|
|
5093
5091
|
}
|
|
5094
5092
|
setMode(type) {
|
|
5095
5093
|
if (!(type === 'normal')) {
|
|
5096
|
-
|
|
5094
|
+
formatDevErrorMessage(`TabNode does not support setMode`);
|
|
5097
5095
|
}
|
|
5098
5096
|
return this;
|
|
5099
5097
|
}
|
|
@@ -5111,14 +5109,6 @@ function $isTabNode(node) {
|
|
|
5111
5109
|
return node instanceof TabNode;
|
|
5112
5110
|
}
|
|
5113
5111
|
|
|
5114
|
-
/**
|
|
5115
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
5116
|
-
*
|
|
5117
|
-
* This source code is licensed under the MIT license found in the
|
|
5118
|
-
* LICENSE file in the root directory of this source tree.
|
|
5119
|
-
*
|
|
5120
|
-
*/
|
|
5121
|
-
|
|
5122
5112
|
class Point {
|
|
5123
5113
|
constructor(key, offset, type) {
|
|
5124
5114
|
{
|
|
@@ -5138,29 +5128,19 @@ class Point {
|
|
|
5138
5128
|
return this.key === point.key && this.offset === point.offset && this.type === point.type;
|
|
5139
5129
|
}
|
|
5140
5130
|
isBefore(b) {
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
const aOffset = this.offset;
|
|
5144
|
-
const bOffset = b.offset;
|
|
5145
|
-
if ($isElementNode(aNode)) {
|
|
5146
|
-
const aNodeDescendant = aNode.getDescendantByIndex(aOffset);
|
|
5147
|
-
aNode = aNodeDescendant != null ? aNodeDescendant : aNode;
|
|
5148
|
-
}
|
|
5149
|
-
if ($isElementNode(bNode)) {
|
|
5150
|
-
const bNodeDescendant = bNode.getDescendantByIndex(bOffset);
|
|
5151
|
-
bNode = bNodeDescendant != null ? bNodeDescendant : bNode;
|
|
5131
|
+
if (this.key === b.key) {
|
|
5132
|
+
return this.offset < b.offset;
|
|
5152
5133
|
}
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
return aNode.isBefore(bNode);
|
|
5134
|
+
const aCaret = $normalizeCaret($caretFromPoint(this, 'next'));
|
|
5135
|
+
const bCaret = $normalizeCaret($caretFromPoint(b, 'next'));
|
|
5136
|
+
return $comparePointCaretNext(aCaret, bCaret) < 0;
|
|
5157
5137
|
}
|
|
5158
5138
|
getNode() {
|
|
5159
5139
|
const key = this.key;
|
|
5160
5140
|
const node = $getNodeByKey(key);
|
|
5161
5141
|
if (node === null) {
|
|
5162
5142
|
{
|
|
5163
|
-
|
|
5143
|
+
formatDevErrorMessage(`Point.getNode: node not found`);
|
|
5164
5144
|
}
|
|
5165
5145
|
}
|
|
5166
5146
|
return node;
|
|
@@ -5177,7 +5157,7 @@ class Point {
|
|
|
5177
5157
|
{
|
|
5178
5158
|
const node = $getNodeByKey(key);
|
|
5179
5159
|
if (!(type === 'text' ? $isTextNode(node) : $isElementNode(node))) {
|
|
5180
|
-
|
|
5160
|
+
formatDevErrorMessage(`PointType.set: node with key ${key} is ${node ? node.__type : '[not found]'} and can not be used for a ${type} point`);
|
|
5181
5161
|
}
|
|
5182
5162
|
}
|
|
5183
5163
|
if (!isCurrentlyReadOnlyMode()) {
|
|
@@ -5420,7 +5400,7 @@ class RangeSelection {
|
|
|
5420
5400
|
{
|
|
5421
5401
|
if (this.isCollapsed() && nodes.length > 1) {
|
|
5422
5402
|
{
|
|
5423
|
-
|
|
5403
|
+
formatDevErrorMessage(`RangeSelection.getNodes() returned ${String(nodes.length)} > 1 nodes in a collapsed selection`);
|
|
5424
5404
|
}
|
|
5425
5405
|
}
|
|
5426
5406
|
}
|
|
@@ -5659,7 +5639,7 @@ class RangeSelection {
|
|
|
5659
5639
|
let firstNode = selectedNodes[0];
|
|
5660
5640
|
if (!$isTextNode(firstNode)) {
|
|
5661
5641
|
{
|
|
5662
|
-
|
|
5642
|
+
formatDevErrorMessage(`insertText: first node is not a text node`);
|
|
5663
5643
|
}
|
|
5664
5644
|
}
|
|
5665
5645
|
const firstNodeText = firstNode.getTextContent();
|
|
@@ -6054,7 +6034,7 @@ class RangeSelection {
|
|
|
6054
6034
|
this.insertParagraph();
|
|
6055
6035
|
const selection = $getSelection();
|
|
6056
6036
|
if (!$isRangeSelection(selection)) {
|
|
6057
|
-
|
|
6037
|
+
formatDevErrorMessage(`Expected RangeSelection after insertParagraph`);
|
|
6058
6038
|
}
|
|
6059
6039
|
return selection.insertNodes(nodes);
|
|
6060
6040
|
}
|
|
@@ -6079,7 +6059,7 @@ class RangeSelection {
|
|
|
6079
6059
|
const notInline = node => ($isElementNode(node) || $isDecoratorNode(node)) && !node.isInline();
|
|
6080
6060
|
if (!nodes.some(notInline)) {
|
|
6081
6061
|
if (!$isElementNode(firstBlock)) {
|
|
6082
|
-
|
|
6062
|
+
formatDevErrorMessage(`Expected node ${firstNode.constructor.name} of type ${firstNode.getType()} to have a block ElementNode ancestor`);
|
|
6083
6063
|
}
|
|
6084
6064
|
const index = $removeTextAndSplitBlock(this);
|
|
6085
6065
|
firstBlock.splice(index, 0, nodes);
|
|
@@ -6098,14 +6078,14 @@ class RangeSelection {
|
|
|
6098
6078
|
let firstToInsert = blocks[0];
|
|
6099
6079
|
if (isMergeable(firstToInsert)) {
|
|
6100
6080
|
if (!$isElementNode(firstBlock)) {
|
|
6101
|
-
|
|
6081
|
+
formatDevErrorMessage(`Expected node ${firstNode.constructor.name} of type ${firstNode.getType()} to have a block ElementNode ancestor`);
|
|
6102
6082
|
}
|
|
6103
6083
|
firstBlock.append(...firstToInsert.getChildren());
|
|
6104
6084
|
firstToInsert = blocks[1];
|
|
6105
6085
|
}
|
|
6106
6086
|
if (firstToInsert) {
|
|
6107
6087
|
if (!(firstBlock !== null)) {
|
|
6108
|
-
|
|
6088
|
+
formatDevErrorMessage(`Expected node ${firstNode.constructor.name} of type ${firstNode.getType()} to have a block ancestor`);
|
|
6109
6089
|
}
|
|
6110
6090
|
insertRangeAfter(firstBlock, firstToInsert);
|
|
6111
6091
|
}
|
|
@@ -6141,7 +6121,7 @@ class RangeSelection {
|
|
|
6141
6121
|
const index = $removeTextAndSplitBlock(this);
|
|
6142
6122
|
const block = $getAncestor(this.anchor.getNode(), INTERNAL_$isBlock);
|
|
6143
6123
|
if (!$isElementNode(block)) {
|
|
6144
|
-
|
|
6124
|
+
formatDevErrorMessage(`Expected ancestor to be a block ElementNode`);
|
|
6145
6125
|
}
|
|
6146
6126
|
const firstToAppend = block.getChildAtIndex(index);
|
|
6147
6127
|
const nodesToInsert = firstToAppend ? [firstToAppend, ...firstToAppend.getNextSiblings()] : [];
|
|
@@ -6231,51 +6211,10 @@ class RangeSelection {
|
|
|
6231
6211
|
* @param granularity the granularity at which to apply the modification
|
|
6232
6212
|
*/
|
|
6233
6213
|
modify(alter, isBackward, granularity) {
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
const collapse = alter === 'move';
|
|
6237
|
-
|
|
6238
|
-
// Handle the selection movement around decorators.
|
|
6239
|
-
const possibleNode = $getAdjacentNode(focus, isBackward);
|
|
6240
|
-
if ($isDecoratorNode(possibleNode) && !possibleNode.isIsolated()) {
|
|
6241
|
-
// Make it possible to move selection from range selection to
|
|
6242
|
-
// node selection on the node.
|
|
6243
|
-
if (collapse && possibleNode.isKeyboardSelectable()) {
|
|
6244
|
-
const nodeSelection = $createNodeSelection();
|
|
6245
|
-
nodeSelection.add(possibleNode.__key);
|
|
6246
|
-
$setSelection(nodeSelection);
|
|
6247
|
-
return;
|
|
6248
|
-
}
|
|
6249
|
-
const sibling = isBackward ? possibleNode.getPreviousSibling() : possibleNode.getNextSibling();
|
|
6250
|
-
if (!$isTextNode(sibling)) {
|
|
6251
|
-
const parent = possibleNode.getParentOrThrow();
|
|
6252
|
-
let offset;
|
|
6253
|
-
let elementKey;
|
|
6254
|
-
if ($isElementNode(sibling)) {
|
|
6255
|
-
elementKey = sibling.__key;
|
|
6256
|
-
offset = isBackward ? sibling.getChildrenSize() : 0;
|
|
6257
|
-
} else {
|
|
6258
|
-
offset = possibleNode.getIndexWithinParent();
|
|
6259
|
-
elementKey = parent.__key;
|
|
6260
|
-
if (!isBackward) {
|
|
6261
|
-
offset++;
|
|
6262
|
-
}
|
|
6263
|
-
}
|
|
6264
|
-
focus.set(elementKey, offset, 'element');
|
|
6265
|
-
if (collapse) {
|
|
6266
|
-
anchor.set(elementKey, offset, 'element');
|
|
6267
|
-
}
|
|
6268
|
-
return;
|
|
6269
|
-
} else {
|
|
6270
|
-
const siblingKey = sibling.__key;
|
|
6271
|
-
const offset = isBackward ? sibling.getTextContent().length : 0;
|
|
6272
|
-
focus.set(siblingKey, offset, 'text');
|
|
6273
|
-
if (collapse) {
|
|
6274
|
-
anchor.set(siblingKey, offset, 'text');
|
|
6275
|
-
}
|
|
6276
|
-
return;
|
|
6277
|
-
}
|
|
6214
|
+
if ($modifySelectionAroundDecoratorsAndBlocks(this, alter, isBackward, granularity)) {
|
|
6215
|
+
return;
|
|
6278
6216
|
}
|
|
6217
|
+
const collapse = alter === 'move';
|
|
6279
6218
|
const editor = getActiveEditor();
|
|
6280
6219
|
const domSelection = getDOMSelection(getWindow(editor));
|
|
6281
6220
|
if (!domSelection) {
|
|
@@ -6283,12 +6222,26 @@ class RangeSelection {
|
|
|
6283
6222
|
}
|
|
6284
6223
|
const blockCursorElement = editor._blockCursorElement;
|
|
6285
6224
|
const rootElement = editor._rootElement;
|
|
6225
|
+
const focusNode = this.focus.getNode();
|
|
6286
6226
|
// Remove the block cursor element if it exists. This will ensure selection
|
|
6287
6227
|
// works as intended. If we leave it in the DOM all sorts of strange bugs
|
|
6288
6228
|
// occur. :/
|
|
6289
|
-
if (rootElement !== null && blockCursorElement !== null && $isElementNode(
|
|
6229
|
+
if (rootElement !== null && blockCursorElement !== null && $isElementNode(focusNode) && !focusNode.isInline() && !focusNode.canBeEmpty()) {
|
|
6290
6230
|
removeDOMBlockCursorElement(blockCursorElement, editor, rootElement);
|
|
6291
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
|
+
}
|
|
6292
6245
|
// We use the DOM selection.modify API here to "tell" us what the selection
|
|
6293
6246
|
// will be. We then use it to update the Lexical selection accordingly. This
|
|
6294
6247
|
// is much more reliable than waiting for a beforeinput and using the ranges
|
|
@@ -6345,6 +6298,9 @@ class RangeSelection {
|
|
|
6345
6298
|
}
|
|
6346
6299
|
}
|
|
6347
6300
|
}
|
|
6301
|
+
if (granularity === 'lineboundary') {
|
|
6302
|
+
$modifySelectionAroundDecoratorsAndBlocks(this, alter, isBackward, granularity, 'decorators');
|
|
6303
|
+
}
|
|
6348
6304
|
}
|
|
6349
6305
|
/**
|
|
6350
6306
|
* Helper for handling forward character and word deletion that prevents element nodes
|
|
@@ -6385,7 +6341,6 @@ class RangeSelection {
|
|
|
6385
6341
|
const initialCaret = $caretFromPoint(anchor, direction);
|
|
6386
6342
|
const initialRange = $extendCaretToRange(initialCaret);
|
|
6387
6343
|
if (initialRange.getTextSlices().every(slice => slice === null || slice.distance === 0)) {
|
|
6388
|
-
// debugger;
|
|
6389
6344
|
// There's no text in the direction of the deletion so we can explore our options
|
|
6390
6345
|
let state = {
|
|
6391
6346
|
type: 'initial'
|
|
@@ -6501,30 +6456,16 @@ class RangeSelection {
|
|
|
6501
6456
|
*/
|
|
6502
6457
|
deleteLine(isBackward) {
|
|
6503
6458
|
if (this.isCollapsed()) {
|
|
6504
|
-
// Since `domSelection.modify('extend', ..., 'lineboundary')` works well for text selections
|
|
6505
|
-
// but doesn't properly handle selections which end on elements, a space character is added
|
|
6506
|
-
// for such selections transforming their anchor's type to 'text'
|
|
6507
|
-
const anchorIsElement = this.anchor.type === 'element';
|
|
6508
|
-
if (anchorIsElement) {
|
|
6509
|
-
this.insertText(' ');
|
|
6510
|
-
}
|
|
6511
6459
|
this.modify('extend', isBackward, 'lineboundary');
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
const startPoint = isBackward ? this.anchor : this.focus;
|
|
6516
|
-
startPoint.set(startPoint.key, startPoint.offset + 1, startPoint.type);
|
|
6517
|
-
}
|
|
6518
|
-
// 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,
|
|
6519
6463
|
// use the deleteCharacter operation to handle all of the logic associated
|
|
6520
6464
|
// with navigating through the parent element
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
return this.deleteCharacter(isBackward);
|
|
6525
|
-
}
|
|
6465
|
+
this.deleteCharacter(isBackward);
|
|
6466
|
+
} else {
|
|
6467
|
+
this.removeText();
|
|
6526
6468
|
}
|
|
6527
|
-
this.removeText();
|
|
6528
6469
|
}
|
|
6529
6470
|
|
|
6530
6471
|
/**
|
|
@@ -6702,7 +6643,7 @@ function $updateCaretSelectionForUnicodeCharacter(selection, isBackward) {
|
|
|
6702
6643
|
function shouldDeleteExactlyOneCodeUnit(text) {
|
|
6703
6644
|
{
|
|
6704
6645
|
if (!(text.length > 1)) {
|
|
6705
|
-
|
|
6646
|
+
formatDevErrorMessage(`shouldDeleteExactlyOneCodeUnit: expecting to be called only with sequences of two or more code units`);
|
|
6706
6647
|
}
|
|
6707
6648
|
}
|
|
6708
6649
|
return !(doesContainSurrogatePair(text) || doesContainEmoji(text));
|
|
@@ -6824,13 +6765,13 @@ function $internalResolveSelectionPoint(dom, offset, lastPoint, editor) {
|
|
|
6824
6765
|
if ($isElementNode(resolvedElement)) {
|
|
6825
6766
|
const elementDOM = editor.getElementByKey(resolvedElement.getKey());
|
|
6826
6767
|
if (!(elementDOM !== null)) {
|
|
6827
|
-
|
|
6768
|
+
formatDevErrorMessage(`$internalResolveSelectionPoint: node in DOM but not keyToDOMMap`);
|
|
6828
6769
|
}
|
|
6829
6770
|
const slot = resolvedElement.getDOMSlot(elementDOM);
|
|
6830
6771
|
[resolvedElement, resolvedOffset] = slot.resolveChildIndex(resolvedElement, elementDOM, dom, offset);
|
|
6831
6772
|
// This is just a typescript workaround, it is true but lost due to mutability
|
|
6832
6773
|
if (!$isElementNode(resolvedElement)) {
|
|
6833
|
-
|
|
6774
|
+
formatDevErrorMessage(`$internalResolveSelectionPoint: resolvedElement is not an ElementNode`);
|
|
6834
6775
|
}
|
|
6835
6776
|
if (moveSelectionToEnd && resolvedOffset >= resolvedElement.getChildrenSize()) {
|
|
6836
6777
|
resolvedOffset = Math.max(0, resolvedElement.getChildrenSize() - 1);
|
|
@@ -6852,7 +6793,7 @@ function $internalResolveSelectionPoint(dom, offset, lastPoint, editor) {
|
|
|
6852
6793
|
resolvedOffset = getTextNodeOffset(child, moveSelectionToEnd);
|
|
6853
6794
|
} else if (child !== resolvedElement && moveSelectionToEnd && !hasBlockCursor) {
|
|
6854
6795
|
if (!$isElementNode(resolvedElement)) {
|
|
6855
|
-
|
|
6796
|
+
formatDevErrorMessage(`invariant`);
|
|
6856
6797
|
}
|
|
6857
6798
|
resolvedOffset = Math.min(resolvedElement.getChildrenSize(), resolvedOffset + 1);
|
|
6858
6799
|
}
|
|
@@ -7048,23 +6989,23 @@ function $internalCreateRangeSelection(lastSelection, domSelection, editor, even
|
|
|
7048
6989
|
function $validatePoint(editor, name, point) {
|
|
7049
6990
|
const node = $getNodeByKey(point.key);
|
|
7050
6991
|
if (!(node !== undefined)) {
|
|
7051
|
-
|
|
6992
|
+
formatDevErrorMessage(`$validatePoint: ${name} key ${point.key} not found in current editorState`);
|
|
7052
6993
|
}
|
|
7053
6994
|
if (point.type === 'text') {
|
|
7054
6995
|
if (!$isTextNode(node)) {
|
|
7055
|
-
|
|
6996
|
+
formatDevErrorMessage(`$validatePoint: ${name} key ${point.key} is not a TextNode`);
|
|
7056
6997
|
}
|
|
7057
6998
|
const size = node.getTextContentSize();
|
|
7058
6999
|
if (!(point.offset <= size)) {
|
|
7059
|
-
|
|
7000
|
+
formatDevErrorMessage(`$validatePoint: ${name} point.offset > node.getTextContentSize() (${String(point.offset)} > ${String(size)})`);
|
|
7060
7001
|
}
|
|
7061
7002
|
} else {
|
|
7062
7003
|
if (!$isElementNode(node)) {
|
|
7063
|
-
|
|
7004
|
+
formatDevErrorMessage(`$validatePoint: ${name} key ${point.key} is not an ElementNode`);
|
|
7064
7005
|
}
|
|
7065
7006
|
const size = node.getChildrenSize();
|
|
7066
7007
|
if (!(point.offset <= size)) {
|
|
7067
|
-
|
|
7008
|
+
formatDevErrorMessage(`$validatePoint: ${name} point.offset > node.getChildrenSize() (${String(point.offset)} > ${String(size)})`);
|
|
7068
7009
|
}
|
|
7069
7010
|
}
|
|
7070
7011
|
}
|
|
@@ -7228,6 +7169,20 @@ function adjustPointOffsetForMergedSibling(point, isBefore, key, target, textLen
|
|
|
7228
7169
|
point.set(point.key, point.offset - 1, 'element');
|
|
7229
7170
|
}
|
|
7230
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
|
+
}
|
|
7231
7186
|
function updateDOMSelection(prevSelection, nextSelection, editor, domSelection, tags, rootElement, nodeCount) {
|
|
7232
7187
|
const anchorDOMNode = domSelection.anchorNode;
|
|
7233
7188
|
const focusDOMNode = domSelection.focusNode;
|
|
@@ -7304,16 +7259,7 @@ function updateDOMSelection(prevSelection, nextSelection, editor, domSelection,
|
|
|
7304
7259
|
|
|
7305
7260
|
// Apply the updated selection to the DOM. Note: this will trigger
|
|
7306
7261
|
// a "selectionchange" event, although it will be asynchronous.
|
|
7307
|
-
|
|
7308
|
-
domSelection.setBaseAndExtent(nextAnchorNode, nextAnchorOffset, nextFocusNode, nextFocusOffset);
|
|
7309
|
-
} catch (error) {
|
|
7310
|
-
// If we encounter an error, continue. This can sometimes
|
|
7311
|
-
// occur with FF and there's no good reason as to why it
|
|
7312
|
-
// should happen.
|
|
7313
|
-
{
|
|
7314
|
-
console.warn(error);
|
|
7315
|
-
}
|
|
7316
|
-
}
|
|
7262
|
+
setDOMSelectionBaseAndExtent(domSelection, nextAnchorNode, nextAnchorOffset, nextFocusNode, nextFocusOffset);
|
|
7317
7263
|
if (!tags.has('skip-scroll-into-view') && nextSelection.isCollapsed() && rootElement !== null && rootElement === document.activeElement) {
|
|
7318
7264
|
const selectionTarget = $isRangeSelection(nextSelection) && nextSelection.anchor.type === 'element' ? nextAnchorNode.childNodes[nextAnchorOffset] || null : domSelection.rangeCount > 0 ? domSelection.getRangeAt(0) : null;
|
|
7319
7265
|
if (selectionTarget !== null) {
|
|
@@ -7356,7 +7302,7 @@ function $removeTextAndSplitBlock(selection) {
|
|
|
7356
7302
|
selection_ = newSelection;
|
|
7357
7303
|
}
|
|
7358
7304
|
if (!$isRangeSelection(selection_)) {
|
|
7359
|
-
|
|
7305
|
+
formatDevErrorMessage(`Unexpected dirty selection to be null`);
|
|
7360
7306
|
}
|
|
7361
7307
|
const anchor = selection_.anchor;
|
|
7362
7308
|
let node = anchor.getNode();
|
|
@@ -7501,12 +7447,74 @@ range) {
|
|
|
7501
7447
|
}
|
|
7502
7448
|
|
|
7503
7449
|
/**
|
|
7504
|
-
*
|
|
7505
|
-
*
|
|
7506
|
-
* This source code is licensed under the MIT license found in the
|
|
7507
|
-
* LICENSE file in the root directory of this source tree.
|
|
7450
|
+
* @internal
|
|
7508
7451
|
*
|
|
7452
|
+
* Modify the focus of the focus around possible decorators and blocks and return true
|
|
7453
|
+
* if the movement is done.
|
|
7509
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
|
+
}
|
|
7510
7518
|
|
|
7511
7519
|
let activeEditorState = null;
|
|
7512
7520
|
let activeEditor = null;
|
|
@@ -7524,21 +7532,21 @@ function isCurrentlyReadOnlyMode() {
|
|
|
7524
7532
|
function errorOnReadOnly() {
|
|
7525
7533
|
if (isReadOnlyMode) {
|
|
7526
7534
|
{
|
|
7527
|
-
|
|
7535
|
+
formatDevErrorMessage(`Cannot use method in read-only mode.`);
|
|
7528
7536
|
}
|
|
7529
7537
|
}
|
|
7530
7538
|
}
|
|
7531
7539
|
function errorOnInfiniteTransforms() {
|
|
7532
7540
|
if (infiniteTransformCount > 99) {
|
|
7533
7541
|
{
|
|
7534
|
-
|
|
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.`);
|
|
7535
7543
|
}
|
|
7536
7544
|
}
|
|
7537
7545
|
}
|
|
7538
7546
|
function getActiveEditorState() {
|
|
7539
7547
|
if (activeEditorState === null) {
|
|
7540
7548
|
{
|
|
7541
|
-
|
|
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()}`);
|
|
7542
7550
|
}
|
|
7543
7551
|
}
|
|
7544
7552
|
return activeEditorState;
|
|
@@ -7546,7 +7554,7 @@ function getActiveEditorState() {
|
|
|
7546
7554
|
function getActiveEditor() {
|
|
7547
7555
|
if (activeEditor === null) {
|
|
7548
7556
|
{
|
|
7549
|
-
|
|
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()}`);
|
|
7550
7558
|
}
|
|
7551
7559
|
}
|
|
7552
7560
|
return activeEditor;
|
|
@@ -7705,13 +7713,13 @@ function $parseSerializedNodeImpl(serializedNode, registeredNodes) {
|
|
|
7705
7713
|
const registeredNode = registeredNodes.get(type);
|
|
7706
7714
|
if (registeredNode === undefined) {
|
|
7707
7715
|
{
|
|
7708
|
-
|
|
7716
|
+
formatDevErrorMessage(`parseEditorState: type "${type}" + not found`);
|
|
7709
7717
|
}
|
|
7710
7718
|
}
|
|
7711
7719
|
const nodeClass = registeredNode.klass;
|
|
7712
7720
|
if (serializedNode.type !== nodeClass.getType()) {
|
|
7713
7721
|
{
|
|
7714
|
-
|
|
7722
|
+
formatDevErrorMessage(`LexicalNode: Node ${nodeClass.name} does not implement .importJSON().`);
|
|
7715
7723
|
}
|
|
7716
7724
|
}
|
|
7717
7725
|
const node = nodeClass.importJSON(serializedNode);
|
|
@@ -8067,7 +8075,7 @@ function processNestedUpdates(editor, initialSkipTransforms) {
|
|
|
8067
8075
|
if (options.discrete) {
|
|
8068
8076
|
const pendingEditorState = editor._pendingEditorState;
|
|
8069
8077
|
if (!(pendingEditorState !== null)) {
|
|
8070
|
-
|
|
8078
|
+
formatDevErrorMessage(`Unexpected empty pending editor state on discrete nested update`);
|
|
8071
8079
|
}
|
|
8072
8080
|
pendingEditorState._flushSync = true;
|
|
8073
8081
|
}
|
|
@@ -8146,7 +8154,7 @@ function $beginUpdate(editor, updateFn, options) {
|
|
|
8146
8154
|
const focusKey = pendingSelection.focus.key;
|
|
8147
8155
|
if (pendingNodeMap.get(anchorKey) === undefined || pendingNodeMap.get(focusKey) === undefined) {
|
|
8148
8156
|
{
|
|
8149
|
-
|
|
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.`);
|
|
8150
8158
|
}
|
|
8151
8159
|
}
|
|
8152
8160
|
} else if ($isNodeSelection(pendingSelection)) {
|
|
@@ -8218,15 +8226,6 @@ function updateEditor(editor, updateFn, options) {
|
|
|
8218
8226
|
}
|
|
8219
8227
|
}
|
|
8220
8228
|
|
|
8221
|
-
/**
|
|
8222
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
8223
|
-
*
|
|
8224
|
-
* This source code is licensed under the MIT license found in the
|
|
8225
|
-
* LICENSE file in the root directory of this source tree.
|
|
8226
|
-
*
|
|
8227
|
-
*/
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
8229
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
8231
8230
|
|
|
8232
8231
|
/**
|
|
@@ -8266,7 +8265,7 @@ class ElementDOMSlot {
|
|
|
8266
8265
|
insertChild(dom) {
|
|
8267
8266
|
const before = this.before || this.getManagedLineBreak();
|
|
8268
8267
|
if (!(before === null || before.parentElement === this.element)) {
|
|
8269
|
-
|
|
8268
|
+
formatDevErrorMessage(`ElementDOMSlot.insertChild: before is not in element`);
|
|
8270
8269
|
}
|
|
8271
8270
|
this.element.insertBefore(dom, before);
|
|
8272
8271
|
return this;
|
|
@@ -8276,7 +8275,7 @@ class ElementDOMSlot {
|
|
|
8276
8275
|
*/
|
|
8277
8276
|
removeChild(dom) {
|
|
8278
8277
|
if (!(dom.parentElement === this.element)) {
|
|
8279
|
-
|
|
8278
|
+
formatDevErrorMessage(`ElementDOMSlot.removeChild: dom is not in element`);
|
|
8280
8279
|
}
|
|
8281
8280
|
this.element.removeChild(dom);
|
|
8282
8281
|
return this;
|
|
@@ -8289,7 +8288,7 @@ class ElementDOMSlot {
|
|
|
8289
8288
|
*/
|
|
8290
8289
|
replaceChild(dom, prevDom) {
|
|
8291
8290
|
if (!(prevDom.parentElement === this.element)) {
|
|
8292
|
-
|
|
8291
|
+
formatDevErrorMessage(`ElementDOMSlot.replaceChild: prevDom is not in element`);
|
|
8293
8292
|
}
|
|
8294
8293
|
this.element.replaceChild(dom, prevDom);
|
|
8295
8294
|
return this;
|
|
@@ -8408,7 +8407,7 @@ function indexPath(root, child) {
|
|
|
8408
8407
|
path.push(i);
|
|
8409
8408
|
}
|
|
8410
8409
|
if (!(node === root)) {
|
|
8411
|
-
|
|
8410
|
+
formatDevErrorMessage(`indexPath: root is not a parent of child`);
|
|
8412
8411
|
}
|
|
8413
8412
|
return path.reverse();
|
|
8414
8413
|
}
|
|
@@ -8567,7 +8566,7 @@ class ElementNode extends LexicalNode {
|
|
|
8567
8566
|
const firstChild = this.getFirstChild();
|
|
8568
8567
|
if (firstChild === null) {
|
|
8569
8568
|
{
|
|
8570
|
-
|
|
8569
|
+
formatDevErrorMessage(`Expected node ${this.__key} to have a first child.`);
|
|
8571
8570
|
}
|
|
8572
8571
|
}
|
|
8573
8572
|
return firstChild;
|
|
@@ -8581,7 +8580,7 @@ class ElementNode extends LexicalNode {
|
|
|
8581
8580
|
const lastChild = this.getLastChild();
|
|
8582
8581
|
if (lastChild === null) {
|
|
8583
8582
|
{
|
|
8584
|
-
|
|
8583
|
+
formatDevErrorMessage(`Expected node ${this.__key} to have a last child.`);
|
|
8585
8584
|
}
|
|
8586
8585
|
}
|
|
8587
8586
|
return lastChild;
|
|
@@ -8762,7 +8761,7 @@ class ElementNode extends LexicalNode {
|
|
|
8762
8761
|
const oldSize = this.getChildrenSize();
|
|
8763
8762
|
const writableSelf = this.getWritable();
|
|
8764
8763
|
if (!(start + deleteCount <= oldSize)) {
|
|
8765
|
-
|
|
8764
|
+
formatDevErrorMessage(`ElementNode.splice: start + deleteCount > oldSize (${String(start)} + ${String(deleteCount)} > ${String(oldSize)})`);
|
|
8766
8765
|
}
|
|
8767
8766
|
const writableSelfKey = writableSelf.__key;
|
|
8768
8767
|
const nodesToInsertKeys = [];
|
|
@@ -8785,7 +8784,7 @@ class ElementNode extends LexicalNode {
|
|
|
8785
8784
|
for (let i = 0; i < deleteCount; i++) {
|
|
8786
8785
|
if (nodeToDelete === null) {
|
|
8787
8786
|
{
|
|
8788
|
-
|
|
8787
|
+
formatDevErrorMessage(`splice: sibling not found`);
|
|
8789
8788
|
}
|
|
8790
8789
|
}
|
|
8791
8790
|
const nextSibling = nodeToDelete.getNextSibling();
|
|
@@ -8818,7 +8817,7 @@ class ElementNode extends LexicalNode {
|
|
|
8818
8817
|
}
|
|
8819
8818
|
if (nodeToInsert.__key === writableSelfKey) {
|
|
8820
8819
|
{
|
|
8821
|
-
|
|
8820
|
+
formatDevErrorMessage(`append: attempting to append self`);
|
|
8822
8821
|
}
|
|
8823
8822
|
}
|
|
8824
8823
|
// Set child parent to self
|
|
@@ -9038,15 +9037,6 @@ function isPointRemoved(point, nodesToRemoveKeySet, nodesToInsertKeySet) {
|
|
|
9038
9037
|
return false;
|
|
9039
9038
|
}
|
|
9040
9039
|
|
|
9041
|
-
/**
|
|
9042
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
9043
|
-
*
|
|
9044
|
-
* This source code is licensed under the MIT license found in the
|
|
9045
|
-
* LICENSE file in the root directory of this source tree.
|
|
9046
|
-
*
|
|
9047
|
-
*/
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
9040
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
9051
9041
|
|
|
9052
9042
|
/** @noInheritDoc */
|
|
@@ -9057,7 +9047,7 @@ class DecoratorNode extends LexicalNode {
|
|
|
9057
9047
|
*/
|
|
9058
9048
|
decorate(editor, config) {
|
|
9059
9049
|
{
|
|
9060
|
-
|
|
9050
|
+
formatDevErrorMessage(`decorate: base method not extended`);
|
|
9061
9051
|
}
|
|
9062
9052
|
}
|
|
9063
9053
|
isIsolated() {
|
|
@@ -9074,14 +9064,6 @@ function $isDecoratorNode(node) {
|
|
|
9074
9064
|
return node instanceof DecoratorNode;
|
|
9075
9065
|
}
|
|
9076
9066
|
|
|
9077
|
-
/**
|
|
9078
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
9079
|
-
*
|
|
9080
|
-
* This source code is licensed under the MIT license found in the
|
|
9081
|
-
* LICENSE file in the root directory of this source tree.
|
|
9082
|
-
*
|
|
9083
|
-
*/
|
|
9084
|
-
|
|
9085
9067
|
/** @noInheritDoc */
|
|
9086
9068
|
class RootNode extends ElementNode {
|
|
9087
9069
|
/** @internal */
|
|
@@ -9098,7 +9080,7 @@ class RootNode extends ElementNode {
|
|
|
9098
9080
|
}
|
|
9099
9081
|
getTopLevelElementOrThrow() {
|
|
9100
9082
|
{
|
|
9101
|
-
|
|
9083
|
+
formatDevErrorMessage(`getTopLevelElementOrThrow: root nodes are not top level elements`);
|
|
9102
9084
|
}
|
|
9103
9085
|
}
|
|
9104
9086
|
getTextContent() {
|
|
@@ -9112,22 +9094,22 @@ class RootNode extends ElementNode {
|
|
|
9112
9094
|
}
|
|
9113
9095
|
remove() {
|
|
9114
9096
|
{
|
|
9115
|
-
|
|
9097
|
+
formatDevErrorMessage(`remove: cannot be called on root nodes`);
|
|
9116
9098
|
}
|
|
9117
9099
|
}
|
|
9118
9100
|
replace(node) {
|
|
9119
9101
|
{
|
|
9120
|
-
|
|
9102
|
+
formatDevErrorMessage(`replace: cannot be called on root nodes`);
|
|
9121
9103
|
}
|
|
9122
9104
|
}
|
|
9123
9105
|
insertBefore(nodeToInsert) {
|
|
9124
9106
|
{
|
|
9125
|
-
|
|
9107
|
+
formatDevErrorMessage(`insertBefore: cannot be called on root nodes`);
|
|
9126
9108
|
}
|
|
9127
9109
|
}
|
|
9128
9110
|
insertAfter(nodeToInsert) {
|
|
9129
9111
|
{
|
|
9130
|
-
|
|
9112
|
+
formatDevErrorMessage(`insertAfter: cannot be called on root nodes`);
|
|
9131
9113
|
}
|
|
9132
9114
|
}
|
|
9133
9115
|
|
|
@@ -9144,7 +9126,7 @@ class RootNode extends ElementNode {
|
|
|
9144
9126
|
const node = nodesToAppend[i];
|
|
9145
9127
|
if (!$isElementNode(node) && !$isDecoratorNode(node)) {
|
|
9146
9128
|
{
|
|
9147
|
-
|
|
9129
|
+
formatDevErrorMessage(`rootNode.append: Only element or decorator nodes can be appended to the root node`);
|
|
9148
9130
|
}
|
|
9149
9131
|
}
|
|
9150
9132
|
}
|
|
@@ -9165,14 +9147,6 @@ function $isRootNode(node) {
|
|
|
9165
9147
|
return node instanceof RootNode;
|
|
9166
9148
|
}
|
|
9167
9149
|
|
|
9168
|
-
/**
|
|
9169
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
9170
|
-
*
|
|
9171
|
-
* This source code is licensed under the MIT license found in the
|
|
9172
|
-
* LICENSE file in the root directory of this source tree.
|
|
9173
|
-
*
|
|
9174
|
-
*/
|
|
9175
|
-
|
|
9176
9150
|
function editorStateHasDirtySelection(editorState, editor) {
|
|
9177
9151
|
const currentSelection = editor.getEditorState()._selection;
|
|
9178
9152
|
const pendingSelection = editorState._selection;
|
|
@@ -9198,14 +9172,14 @@ function exportNodeToJSON(node) {
|
|
|
9198
9172
|
const nodeClass = node.constructor;
|
|
9199
9173
|
if (serializedNode.type !== nodeClass.getType()) {
|
|
9200
9174
|
{
|
|
9201
|
-
|
|
9175
|
+
formatDevErrorMessage(`LexicalNode: Node ${nodeClass.name} does not match the serialized type. Check if .exportJSON() is implemented and it is returning the correct type.`);
|
|
9202
9176
|
}
|
|
9203
9177
|
}
|
|
9204
9178
|
if ($isElementNode(node)) {
|
|
9205
9179
|
const serializedChildren = serializedNode.children;
|
|
9206
9180
|
if (!Array.isArray(serializedChildren)) {
|
|
9207
9181
|
{
|
|
9208
|
-
|
|
9182
|
+
formatDevErrorMessage(`LexicalNode: Node ${nodeClass.name} is an element but .exportJSON() does not have a children array.`);
|
|
9209
9183
|
}
|
|
9210
9184
|
}
|
|
9211
9185
|
const children = node.getChildren();
|
|
@@ -9386,15 +9360,6 @@ function $isParagraphNode(node) {
|
|
|
9386
9360
|
return node instanceof ParagraphNode;
|
|
9387
9361
|
}
|
|
9388
9362
|
|
|
9389
|
-
/**
|
|
9390
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
9391
|
-
*
|
|
9392
|
-
* This source code is licensed under the MIT license found in the
|
|
9393
|
-
* LICENSE file in the root directory of this source tree.
|
|
9394
|
-
*
|
|
9395
|
-
*/
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
9363
|
// https://github.com/microsoft/TypeScript/issues/3841
|
|
9399
9364
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9400
9365
|
|
|
@@ -9533,7 +9498,7 @@ function createEditor(editorConfig) {
|
|
|
9533
9498
|
const name = klass.name;
|
|
9534
9499
|
if (replaceWithKlass) {
|
|
9535
9500
|
if (!(replaceWithKlass.prototype instanceof klass)) {
|
|
9536
|
-
|
|
9501
|
+
formatDevErrorMessage(`${replaceWithKlass.name} doesn't extend the ${name}`);
|
|
9537
9502
|
}
|
|
9538
9503
|
}
|
|
9539
9504
|
if (name !== 'RootNode' && nodeType !== 'root' && nodeType !== 'artificial') {
|
|
@@ -9818,7 +9783,7 @@ class LexicalEditor {
|
|
|
9818
9783
|
registerCommand(command, listener, priority) {
|
|
9819
9784
|
if (priority === undefined) {
|
|
9820
9785
|
{
|
|
9821
|
-
|
|
9786
|
+
formatDevErrorMessage(`Listener for type "command" requires a "priority".`);
|
|
9822
9787
|
}
|
|
9823
9788
|
}
|
|
9824
9789
|
const commandsMap = this._commands;
|
|
@@ -9828,7 +9793,7 @@ class LexicalEditor {
|
|
|
9828
9793
|
const listenersInPriorityOrder = commandsMap.get(command);
|
|
9829
9794
|
if (listenersInPriorityOrder === undefined) {
|
|
9830
9795
|
{
|
|
9831
|
-
|
|
9796
|
+
formatDevErrorMessage(`registerCommand: Command ${String(command)} not found in command map`);
|
|
9832
9797
|
}
|
|
9833
9798
|
}
|
|
9834
9799
|
const listeners = listenersInPriorityOrder[priority];
|
|
@@ -9877,7 +9842,7 @@ class LexicalEditor {
|
|
|
9877
9842
|
const registeredNode = this._nodes.get(klass.getType());
|
|
9878
9843
|
if (registeredNode === undefined) {
|
|
9879
9844
|
{
|
|
9880
|
-
|
|
9845
|
+
formatDevErrorMessage(`Node ${klass.name} has not been registered. Ensure node has been passed to createEditor.`);
|
|
9881
9846
|
}
|
|
9882
9847
|
}
|
|
9883
9848
|
return registeredNode;
|
|
@@ -10086,7 +10051,7 @@ class LexicalEditor {
|
|
|
10086
10051
|
setEditorState(editorState, options) {
|
|
10087
10052
|
if (editorState.isEmpty()) {
|
|
10088
10053
|
{
|
|
10089
|
-
|
|
10054
|
+
formatDevErrorMessage(`setEditorState: the editor state is empty. Ensure the editor state's root node never becomes empty.`);
|
|
10090
10055
|
}
|
|
10091
10056
|
}
|
|
10092
10057
|
|
|
@@ -10256,15 +10221,7 @@ class LexicalEditor {
|
|
|
10256
10221
|
};
|
|
10257
10222
|
}
|
|
10258
10223
|
}
|
|
10259
|
-
LexicalEditor.version = "0.
|
|
10260
|
-
|
|
10261
|
-
/**
|
|
10262
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
10263
|
-
*
|
|
10264
|
-
* This source code is licensed under the MIT license found in the
|
|
10265
|
-
* LICENSE file in the root directory of this source tree.
|
|
10266
|
-
*
|
|
10267
|
-
*/
|
|
10224
|
+
LexicalEditor.version = "0.26.1-nightly.20250303.0+dev.cjs";
|
|
10268
10225
|
|
|
10269
10226
|
let keyCounter = 1;
|
|
10270
10227
|
function resetRandomKey() {
|
|
@@ -10277,7 +10234,7 @@ function getRegisteredNodeOrThrow(editor, nodeType) {
|
|
|
10277
10234
|
const registeredNode = editor._nodes.get(nodeType);
|
|
10278
10235
|
if (registeredNode === undefined) {
|
|
10279
10236
|
{
|
|
10280
|
-
|
|
10237
|
+
formatDevErrorMessage(`registeredNode: Type ${nodeType} not found`);
|
|
10281
10238
|
}
|
|
10282
10239
|
}
|
|
10283
10240
|
return registeredNode;
|
|
@@ -10430,11 +10387,11 @@ function errorOnNodeKeyConstructorMismatch(node, existingKey) {
|
|
|
10430
10387
|
// Lifted condition to if statement because the inverted logic is a bit confusing
|
|
10431
10388
|
if (node.constructor.name !== existingNode.constructor.name) {
|
|
10432
10389
|
{
|
|
10433
|
-
|
|
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.`);
|
|
10434
10391
|
}
|
|
10435
10392
|
} else {
|
|
10436
10393
|
{
|
|
10437
|
-
|
|
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.`);
|
|
10438
10395
|
}
|
|
10439
10396
|
}
|
|
10440
10397
|
}
|
|
@@ -10653,7 +10610,7 @@ function $setSelection(selection) {
|
|
|
10653
10610
|
{
|
|
10654
10611
|
if (Object.isFrozen(selection)) {
|
|
10655
10612
|
{
|
|
10656
|
-
|
|
10613
|
+
formatDevErrorMessage(`$setSelection called on frozen selection object. Ensure selection is cloned before passing in.`);
|
|
10657
10614
|
}
|
|
10658
10615
|
}
|
|
10659
10616
|
}
|
|
@@ -11024,7 +10981,7 @@ function setMutatedNode(mutatedNodes, registeredNodes, mutationListeners, node,
|
|
|
11024
10981
|
const registeredNode = registeredNodes.get(nodeType);
|
|
11025
10982
|
if (registeredNode === undefined) {
|
|
11026
10983
|
{
|
|
11027
|
-
|
|
10984
|
+
formatDevErrorMessage(`Type ${nodeType} not in registeredNodes`);
|
|
11028
10985
|
}
|
|
11029
10986
|
}
|
|
11030
10987
|
const klass = registeredNode.klass;
|
|
@@ -11109,7 +11066,7 @@ function getElementByKeyOrThrow(editor, key) {
|
|
|
11109
11066
|
const element = editor._keyToDOMMap.get(key);
|
|
11110
11067
|
if (element === undefined) {
|
|
11111
11068
|
{
|
|
11112
|
-
|
|
11069
|
+
formatDevErrorMessage(`Reconciliation: could not find DOM element for node key ${key}`);
|
|
11113
11070
|
}
|
|
11114
11071
|
}
|
|
11115
11072
|
return element;
|
|
@@ -11227,7 +11184,7 @@ function getWindow(editor) {
|
|
|
11227
11184
|
const windowObj = editor._window;
|
|
11228
11185
|
if (windowObj === null) {
|
|
11229
11186
|
{
|
|
11230
|
-
|
|
11187
|
+
formatDevErrorMessage(`window object not found`);
|
|
11231
11188
|
}
|
|
11232
11189
|
}
|
|
11233
11190
|
return windowObj;
|
|
@@ -11265,7 +11222,7 @@ function $applyNodeReplacement(node) {
|
|
|
11265
11222
|
const nodeType = node.constructor.getType();
|
|
11266
11223
|
const registeredNode = editor._nodes.get(nodeType);
|
|
11267
11224
|
if (!(registeredNode !== undefined)) {
|
|
11268
|
-
|
|
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.`);
|
|
11269
11226
|
}
|
|
11270
11227
|
const {
|
|
11271
11228
|
replace,
|
|
@@ -11276,15 +11233,15 @@ function $applyNodeReplacement(node) {
|
|
|
11276
11233
|
const replacementNodeKlass = replacementNode.constructor;
|
|
11277
11234
|
if (replaceWithKlass !== null) {
|
|
11278
11235
|
if (!(replacementNode instanceof replaceWithKlass)) {
|
|
11279
|
-
|
|
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}`);
|
|
11280
11237
|
}
|
|
11281
11238
|
} else {
|
|
11282
11239
|
if (!(replacementNode instanceof node.constructor && replacementNodeKlass !== node.constructor)) {
|
|
11283
|
-
|
|
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}.`);
|
|
11284
11241
|
}
|
|
11285
11242
|
}
|
|
11286
11243
|
if (!(replacementNode.__key !== node.__key)) {
|
|
11287
|
-
|
|
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.`);
|
|
11288
11245
|
}
|
|
11289
11246
|
return replacementNode;
|
|
11290
11247
|
}
|
|
@@ -11294,7 +11251,7 @@ function errorOnInsertTextNodeOnRoot(node, insertNode) {
|
|
|
11294
11251
|
const parentNode = node.getParent();
|
|
11295
11252
|
if ($isRootNode(parentNode) && !$isElementNode(insertNode) && !$isDecoratorNode(insertNode)) {
|
|
11296
11253
|
{
|
|
11297
|
-
|
|
11254
|
+
formatDevErrorMessage(`Only element or decorator nodes can be inserted in to the root node`);
|
|
11298
11255
|
}
|
|
11299
11256
|
}
|
|
11300
11257
|
}
|
|
@@ -11302,7 +11259,7 @@ function $getNodeByKeyOrThrow(key) {
|
|
|
11302
11259
|
const node = $getNodeByKey(key);
|
|
11303
11260
|
if (node === null) {
|
|
11304
11261
|
{
|
|
11305
|
-
|
|
11262
|
+
formatDevErrorMessage(`Expected node with key ${key} to exist but it's not in the nodeMap.`);
|
|
11306
11263
|
}
|
|
11307
11264
|
}
|
|
11308
11265
|
return node;
|
|
@@ -11407,7 +11364,7 @@ function $splitNode(node, offset) {
|
|
|
11407
11364
|
startNode = node;
|
|
11408
11365
|
}
|
|
11409
11366
|
if (!!$isRootOrShadowRoot(node)) {
|
|
11410
|
-
|
|
11367
|
+
formatDevErrorMessage(`Can not call $splitNode() on root element`);
|
|
11411
11368
|
}
|
|
11412
11369
|
const recurse = currentNode => {
|
|
11413
11370
|
const parent = currentNode.getParentOrThrow();
|
|
@@ -11417,7 +11374,7 @@ function $splitNode(node, offset) {
|
|
|
11417
11374
|
const nodeToMove = currentNode === startNode && !isParentRoot ? currentNode : $copyNode(currentNode);
|
|
11418
11375
|
if (isParentRoot) {
|
|
11419
11376
|
if (!($isElementNode(currentNode) && $isElementNode(nodeToMove))) {
|
|
11420
|
-
|
|
11377
|
+
formatDevErrorMessage(`Children of a root must be ElementNode`);
|
|
11421
11378
|
}
|
|
11422
11379
|
currentNode.insertAfter(nodeToMove);
|
|
11423
11380
|
return [currentNode, nodeToMove, nodeToMove];
|
|
@@ -11549,7 +11506,7 @@ function getCachedTypeToNodeMap(editorState) {
|
|
|
11549
11506
|
return EMPTY_TYPE_TO_NODE_MAP;
|
|
11550
11507
|
}
|
|
11551
11508
|
if (!editorState._readOnly) {
|
|
11552
|
-
|
|
11509
|
+
formatDevErrorMessage(`getCachedTypeToNodeMap called with a writable EditorState`);
|
|
11553
11510
|
}
|
|
11554
11511
|
let typeToNodeMap = cachedNodeMaps.get(editorState);
|
|
11555
11512
|
if (!typeToNodeMap) {
|
|
@@ -11596,10 +11553,10 @@ function $cloneWithProperties(latestNode) {
|
|
|
11596
11553
|
mutableNode.afterCloneFrom(latestNode);
|
|
11597
11554
|
{
|
|
11598
11555
|
if (!(mutableNode.__key === latestNode.__key)) {
|
|
11599
|
-
|
|
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`);
|
|
11600
11557
|
}
|
|
11601
11558
|
if (!(mutableNode.__parent === latestNode.__parent && mutableNode.__next === latestNode.__next && mutableNode.__prev === latestNode.__prev)) {
|
|
11602
|
-
|
|
11559
|
+
formatDevErrorMessage(`$cloneWithProperties: ${constructor.name}.clone(node) (with type '${constructor.getType()}') overrided afterCloneFrom but did not call super.afterCloneFrom(prevNode)`);
|
|
11603
11560
|
}
|
|
11604
11561
|
}
|
|
11605
11562
|
return mutableNode;
|
|
@@ -11631,15 +11588,6 @@ function isDOMUnmanaged(elementDom) {
|
|
|
11631
11588
|
return el.__lexicalUnmanaged === true;
|
|
11632
11589
|
}
|
|
11633
11590
|
|
|
11634
|
-
/**
|
|
11635
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11636
|
-
*
|
|
11637
|
-
* This source code is licensed under the MIT license found in the
|
|
11638
|
-
* LICENSE file in the root directory of this source tree.
|
|
11639
|
-
*
|
|
11640
|
-
*/
|
|
11641
|
-
|
|
11642
|
-
|
|
11643
11591
|
/**
|
|
11644
11592
|
* The direction of a caret, 'next' points towards the end of the document
|
|
11645
11593
|
* and 'previous' points towards the beginning
|
|
@@ -11806,7 +11754,7 @@ class AbstractCaret {
|
|
|
11806
11754
|
}
|
|
11807
11755
|
} else {
|
|
11808
11756
|
if (!(target !== null)) {
|
|
11809
|
-
|
|
11757
|
+
formatDevErrorMessage(`NodeCaret.splice: Underflow of expected nodesToRemove during splice (keys: ${Array.from(nodesToRemove).join(' ')})`);
|
|
11810
11758
|
}
|
|
11811
11759
|
}
|
|
11812
11760
|
} else {
|
|
@@ -12084,7 +12032,7 @@ function $getTextNodeOffset(origin, offset) {
|
|
|
12084
12032
|
const size = origin.getTextContentSize();
|
|
12085
12033
|
const numericOffset = offset === 'next' ? size : offset === 'previous' ? 0 : offset;
|
|
12086
12034
|
if (!(numericOffset >= 0 && numericOffset <= size)) {
|
|
12087
|
-
|
|
12035
|
+
formatDevErrorMessage(`$getTextNodeOffset: invalid offset ${String(offset)} for size ${String(size)}`);
|
|
12088
12036
|
}
|
|
12089
12037
|
return numericOffset;
|
|
12090
12038
|
}
|
|
@@ -12263,7 +12211,7 @@ function $extendCaretToRange(anchor) {
|
|
|
12263
12211
|
*/
|
|
12264
12212
|
function $getCaretRange(anchor, focus) {
|
|
12265
12213
|
if (!(anchor.direction === focus.direction)) {
|
|
12266
|
-
|
|
12214
|
+
formatDevErrorMessage(`$getCaretRange: anchor and focus must be in the same direction`);
|
|
12267
12215
|
}
|
|
12268
12216
|
return new CaretRangeImpl(anchor, focus, anchor.direction);
|
|
12269
12217
|
}
|
|
@@ -12341,7 +12289,7 @@ function compareNumber(a, b) {
|
|
|
12341
12289
|
function $comparePointCaretNext(a, b) {
|
|
12342
12290
|
const compare = $getCommonAncestor(a.origin, b.origin);
|
|
12343
12291
|
if (!(compare !== null)) {
|
|
12344
|
-
|
|
12292
|
+
formatDevErrorMessage(`$comparePointCaretNext: a (key ${a.origin.getKey()}) and b (key ${b.origin.getKey()}) do not have a common ancestor`);
|
|
12345
12293
|
}
|
|
12346
12294
|
switch (compare.type) {
|
|
12347
12295
|
case 'same':
|
|
@@ -12446,7 +12394,7 @@ function $getCommonAncestor(a, b) {
|
|
|
12446
12394
|
if (aChild === undefined) ; else if (aChild === null) {
|
|
12447
12395
|
// a is the ancestor
|
|
12448
12396
|
if (!$isSameNode(a, parent)) {
|
|
12449
|
-
|
|
12397
|
+
formatDevErrorMessage(`$originComparison: ancestor logic error`);
|
|
12450
12398
|
}
|
|
12451
12399
|
return {
|
|
12452
12400
|
commonAncestor: parent,
|
|
@@ -12455,7 +12403,7 @@ function $getCommonAncestor(a, b) {
|
|
|
12455
12403
|
} else if (child === null) {
|
|
12456
12404
|
// b is the ancestor
|
|
12457
12405
|
if (!$isSameNode(b, parent)) {
|
|
12458
|
-
|
|
12406
|
+
formatDevErrorMessage(`$originComparison: descendant logic error`);
|
|
12459
12407
|
}
|
|
12460
12408
|
return {
|
|
12461
12409
|
commonAncestor: parent,
|
|
@@ -12463,7 +12411,7 @@ function $getCommonAncestor(a, b) {
|
|
|
12463
12411
|
};
|
|
12464
12412
|
} else {
|
|
12465
12413
|
if (!(($isElementNode(aChild) || $isSameNode(a, aChild)) && ($isElementNode(child) || $isSameNode(b, child)) && parent.is(aChild.getParent()) && parent.is(child.getParent()))) {
|
|
12466
|
-
|
|
12414
|
+
formatDevErrorMessage(`$originComparison: branch logic error`);
|
|
12467
12415
|
}
|
|
12468
12416
|
return {
|
|
12469
12417
|
a: aChild,
|
|
@@ -12476,15 +12424,6 @@ function $getCommonAncestor(a, b) {
|
|
|
12476
12424
|
return null;
|
|
12477
12425
|
}
|
|
12478
12426
|
|
|
12479
|
-
/**
|
|
12480
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
12481
|
-
*
|
|
12482
|
-
* This source code is licensed under the MIT license found in the
|
|
12483
|
-
* LICENSE file in the root directory of this source tree.
|
|
12484
|
-
*
|
|
12485
|
-
*/
|
|
12486
|
-
|
|
12487
|
-
|
|
12488
12427
|
/**
|
|
12489
12428
|
* @param point
|
|
12490
12429
|
* @returns a PointCaret for the point
|
|
@@ -12498,12 +12437,12 @@ function $caretFromPoint(point, direction) {
|
|
|
12498
12437
|
const node = $getNodeByKeyOrThrow(point.key);
|
|
12499
12438
|
if (type === 'text') {
|
|
12500
12439
|
if (!$isTextNode(node)) {
|
|
12501
|
-
|
|
12440
|
+
formatDevErrorMessage(`$caretFromPoint: Node with type ${node.getType()} and key ${key} that does not inherit from TextNode encountered for text point`);
|
|
12502
12441
|
}
|
|
12503
12442
|
return $getTextPointCaret(node, direction, offset);
|
|
12504
12443
|
}
|
|
12505
12444
|
if (!$isElementNode(node)) {
|
|
12506
|
-
|
|
12445
|
+
formatDevErrorMessage(`$caretFromPoint: Node with type ${node.getType()} and key ${key} that does not inherit from ElementNode encountered for element point`);
|
|
12507
12446
|
}
|
|
12508
12447
|
return $getChildCaretAtIndex(node, point.offset, direction);
|
|
12509
12448
|
}
|
|
@@ -12530,7 +12469,7 @@ function $setPointFromCaret(point, caret) {
|
|
|
12530
12469
|
}
|
|
12531
12470
|
} else {
|
|
12532
12471
|
if (!($isChildCaret(caret) && $isElementNode(origin))) {
|
|
12533
|
-
|
|
12472
|
+
formatDevErrorMessage(`$setPointFromCaret: exhaustiveness check`);
|
|
12534
12473
|
}
|
|
12535
12474
|
point.set(origin.getKey(), isNext ? 0 : origin.getChildrenSize(), 'element');
|
|
12536
12475
|
}
|
|
@@ -12568,8 +12507,10 @@ function $caretRangeFromSelection(selection) {
|
|
|
12568
12507
|
anchor,
|
|
12569
12508
|
focus
|
|
12570
12509
|
} = selection;
|
|
12571
|
-
const
|
|
12572
|
-
|
|
12510
|
+
const anchorCaret = $caretFromPoint(anchor, 'next');
|
|
12511
|
+
const focusCaret = $caretFromPoint(focus, 'next');
|
|
12512
|
+
const direction = $comparePointCaretNext(anchorCaret, focusCaret) <= 0 ? 'next' : 'previous';
|
|
12513
|
+
return $getCaretRange($getCaretInDirection(anchorCaret, direction), $getCaretInDirection(focusCaret, direction));
|
|
12573
12514
|
}
|
|
12574
12515
|
|
|
12575
12516
|
/**
|
|
@@ -12719,7 +12660,7 @@ function $removeTextFromCaretRange(initialRange, sliceMode = 'removeEmptySlices'
|
|
|
12719
12660
|
return $getCaretRange(anchor, anchor);
|
|
12720
12661
|
}
|
|
12721
12662
|
{
|
|
12722
|
-
|
|
12663
|
+
formatDevErrorMessage(`$removeTextFromCaretRange: selection was lost, could not find a new anchor given candidates with keys: ${JSON.stringify(anchorCandidates.map(n => n.origin.__key))}`);
|
|
12723
12664
|
}
|
|
12724
12665
|
}
|
|
12725
12666
|
|
|
@@ -12816,6 +12757,17 @@ function $normalizeCaret(initialCaret) {
|
|
|
12816
12757
|
const adj = caret.getAdjacentCaret();
|
|
12817
12758
|
return $isSiblingCaret(adj) && $isTextNode(adj.origin) ? $getTextPointCaret(adj.origin, direction, flipDirection(direction)) : caret;
|
|
12818
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
|
+
}
|
|
12819
12771
|
|
|
12820
12772
|
/**
|
|
12821
12773
|
* Return the caret if it's in the given direction, otherwise return
|
|
@@ -12944,6 +12896,7 @@ exports.$isBlockElementNode = $isBlockElementNode;
|
|
|
12944
12896
|
exports.$isChildCaret = $isChildCaret;
|
|
12945
12897
|
exports.$isDecoratorNode = $isDecoratorNode;
|
|
12946
12898
|
exports.$isElementNode = $isElementNode;
|
|
12899
|
+
exports.$isExtendableTextPointCaret = $isExtendableTextPointCaret;
|
|
12947
12900
|
exports.$isInlineElementOrDecoratorNode = $isInlineElementOrDecoratorNode;
|
|
12948
12901
|
exports.$isLeafNode = $isLeafNode;
|
|
12949
12902
|
exports.$isLineBreakNode = $isLineBreakNode;
|