lexical 0.6.2 → 0.6.4
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 +167 -52
- package/Lexical.js.flow +4 -4
- package/Lexical.prod.js +168 -169
- package/LexicalNode.d.ts +4 -0
- package/LexicalSelection.d.ts +0 -2
- package/LexicalUtils.d.ts +5 -2
- package/LexicalVersion.d.ts +1 -1
- package/nodes/LexicalElementNode.d.ts +6 -0
- package/nodes/LexicalLineBreakNode.d.ts +1 -1
- package/nodes/LexicalParagraphNode.d.ts +1 -1
- package/nodes/LexicalRootNode.d.ts +1 -0
- package/package.json +1 -1
package/Lexical.dev.js
CHANGED
|
@@ -826,6 +826,13 @@ function getEditorsToPropagate(editor) {
|
|
|
826
826
|
function createUID() {
|
|
827
827
|
return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
|
|
828
828
|
}
|
|
829
|
+
function getAnchorTextFromDOM(anchorNode) {
|
|
830
|
+
if (anchorNode.nodeType === DOM_TEXT_TYPE) {
|
|
831
|
+
return anchorNode.nodeValue;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
829
836
|
function $updateSelectedTextFromDOM(isCompositionEnd, data) {
|
|
830
837
|
// Update the text content with the latest composition text
|
|
831
838
|
const domSelection = getDOMSelection();
|
|
@@ -840,12 +847,12 @@ function $updateSelectedTextFromDOM(isCompositionEnd, data) {
|
|
|
840
847
|
focusOffset
|
|
841
848
|
} = domSelection;
|
|
842
849
|
|
|
843
|
-
if (anchorNode !== null
|
|
850
|
+
if (anchorNode !== null) {
|
|
851
|
+
let textContent = getAnchorTextFromDOM(anchorNode);
|
|
844
852
|
const node = $getNearestNodeFromDOMNode(anchorNode);
|
|
845
853
|
|
|
846
|
-
if ($isTextNode(node)) {
|
|
847
|
-
|
|
848
|
-
|
|
854
|
+
if (textContent !== null && $isTextNode(node)) {
|
|
855
|
+
// Data is intentionally truthy, as we check for boolean, null and empty string.
|
|
849
856
|
if (textContent === COMPOSITION_SUFFIX && data) {
|
|
850
857
|
const offset = data.length;
|
|
851
858
|
textContent = data;
|
|
@@ -953,33 +960,6 @@ function $shouldInsertTextAfterOrBeforeTextNode(selection, node) {
|
|
|
953
960
|
} else {
|
|
954
961
|
return false;
|
|
955
962
|
}
|
|
956
|
-
} // This function is used to determine if Lexical should attempt to override
|
|
957
|
-
// the default browser behavior for insertion of text and use its own internal
|
|
958
|
-
// heuristics. This is an extremely important function, and makes much of Lexical
|
|
959
|
-
// work as intended between different browsers and across word, line and character
|
|
960
|
-
// boundary/formats. It also is important for text replacement, node schemas and
|
|
961
|
-
// composition mechanics.
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
function $shouldPreventDefaultAndInsertText(selection, text) {
|
|
965
|
-
const anchor = selection.anchor;
|
|
966
|
-
const focus = selection.focus;
|
|
967
|
-
const anchorNode = anchor.getNode();
|
|
968
|
-
const domSelection = getDOMSelection();
|
|
969
|
-
const domAnchorNode = domSelection !== null ? domSelection.anchorNode : null;
|
|
970
|
-
const anchorKey = anchor.key;
|
|
971
|
-
const backingAnchorElement = getActiveEditor().getElementByKey(anchorKey);
|
|
972
|
-
const textLength = text.length;
|
|
973
|
-
return anchorKey !== focus.key || // If we're working with a non-text node.
|
|
974
|
-
!$isTextNode(anchorNode) || // If we are replacing a range with a single character or grapheme, and not composing.
|
|
975
|
-
(textLength < 2 || doesContainGrapheme(text)) && anchor.offset !== focus.offset && !anchorNode.isComposing() || // Any non standard text node.
|
|
976
|
-
$isTokenOrSegmented(anchorNode) || // If the text length is more than a single character and we're either
|
|
977
|
-
// dealing with this in "beforeinput" or where the node has already recently
|
|
978
|
-
// been changed (thus is dirty).
|
|
979
|
-
anchorNode.isDirty() && textLength > 1 || // If the DOM selection element is not the same as the backing node
|
|
980
|
-
backingAnchorElement !== null && !anchorNode.isComposing() && domAnchorNode !== getDOMTextNode(backingAnchorElement) || // Check if we're changing from bold to italics, or some other format.
|
|
981
|
-
anchorNode.getFormat() !== selection.format || // One last set of heuristics to check against.
|
|
982
|
-
$shouldInsertTextAfterOrBeforeTextNode(selection, anchorNode);
|
|
983
963
|
}
|
|
984
964
|
function isTab(keyCode, altKey, ctrlKey, metaKey) {
|
|
985
965
|
return keyCode === 9 && !altKey && !ctrlKey && !metaKey;
|
|
@@ -1258,7 +1238,11 @@ function getElementByKeyOrThrow(editor, key) {
|
|
|
1258
1238
|
|
|
1259
1239
|
return element;
|
|
1260
1240
|
}
|
|
1261
|
-
function
|
|
1241
|
+
function getParentElement(element) {
|
|
1242
|
+
const parentElement = element.assignedSlot || element.parentElement;
|
|
1243
|
+
return parentElement !== null && parentElement.nodeType === 11 ? parentElement.host : parentElement;
|
|
1244
|
+
}
|
|
1245
|
+
function scrollIntoViewIfNeeded(editor, selectionRect, rootElement) {
|
|
1262
1246
|
const doc = rootElement.ownerDocument;
|
|
1263
1247
|
const defaultView = doc.defaultView;
|
|
1264
1248
|
|
|
@@ -1307,7 +1291,11 @@ function scrollIntoViewIfNeeded(editor, selectionRect, rootElement, tags) {
|
|
|
1307
1291
|
}
|
|
1308
1292
|
}
|
|
1309
1293
|
|
|
1310
|
-
|
|
1294
|
+
if (isBodyElement) {
|
|
1295
|
+
break;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
element = getParentElement(element);
|
|
1311
1299
|
}
|
|
1312
1300
|
}
|
|
1313
1301
|
function $addUpdateTag(tag) {
|
|
@@ -1427,6 +1415,15 @@ function $applyNodeReplacement(node) {
|
|
|
1427
1415
|
|
|
1428
1416
|
return node;
|
|
1429
1417
|
}
|
|
1418
|
+
function errorOnInsertTextNodeOnRoot(node, insertNode) {
|
|
1419
|
+
const parentNode = node.getParent();
|
|
1420
|
+
|
|
1421
|
+
if ($isRootNode(parentNode) && !$isElementNode(insertNode) && !$isDecoratorNode(insertNode)) {
|
|
1422
|
+
{
|
|
1423
|
+
throw Error(`Only element or decorator nodes can be inserted in to the root node`);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1430
1427
|
|
|
1431
1428
|
/**
|
|
1432
1429
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -1815,7 +1812,7 @@ function createChildren(children, _startIndex, endIndex, dom, insertDOM) {
|
|
|
1815
1812
|
function isLastChildLineBreakOrDecorator(children, nodeMap) {
|
|
1816
1813
|
const childKey = children[children.length - 1];
|
|
1817
1814
|
const node = nodeMap.get(childKey);
|
|
1818
|
-
return $isLineBreakNode(node) || $isDecoratorNode(node);
|
|
1815
|
+
return $isLineBreakNode(node) || $isDecoratorNode(node) && node.isInline();
|
|
1819
1816
|
} // If we end an element with a LineBreakNode, then we need to add an additional <br>
|
|
1820
1817
|
|
|
1821
1818
|
|
|
@@ -2267,12 +2264,43 @@ if (CAN_USE_BEFORE_INPUT) {
|
|
|
2267
2264
|
|
|
2268
2265
|
let lastKeyDownTimeStamp = 0;
|
|
2269
2266
|
let lastKeyCode = 0;
|
|
2267
|
+
let lastBeforeInputInsertTextTimeStamp = 0;
|
|
2270
2268
|
let rootElementsRegistered = 0;
|
|
2271
2269
|
let isSelectionChangeFromDOMUpdate = false;
|
|
2272
2270
|
let isSelectionChangeFromMouseDown = false;
|
|
2273
2271
|
let isInsertLineBreak = false;
|
|
2274
2272
|
let isFirefoxEndingComposition = false;
|
|
2275
|
-
let collapsedSelectionFormat = [0, 0, 'root', 0];
|
|
2273
|
+
let collapsedSelectionFormat = [0, 0, 'root', 0]; // This function is used to determine if Lexical should attempt to override
|
|
2274
|
+
// the default browser behavior for insertion of text and use its own internal
|
|
2275
|
+
// heuristics. This is an extremely important function, and makes much of Lexical
|
|
2276
|
+
// work as intended between different browsers and across word, line and character
|
|
2277
|
+
// boundary/formats. It also is important for text replacement, node schemas and
|
|
2278
|
+
// composition mechanics.
|
|
2279
|
+
|
|
2280
|
+
function $shouldPreventDefaultAndInsertText(selection, text, timeStamp, isBeforeInput) {
|
|
2281
|
+
const anchor = selection.anchor;
|
|
2282
|
+
const focus = selection.focus;
|
|
2283
|
+
const anchorNode = anchor.getNode();
|
|
2284
|
+
const domSelection = getDOMSelection();
|
|
2285
|
+
const domAnchorNode = domSelection !== null ? domSelection.anchorNode : null;
|
|
2286
|
+
const anchorKey = anchor.key;
|
|
2287
|
+
const backingAnchorElement = getActiveEditor().getElementByKey(anchorKey);
|
|
2288
|
+
const textLength = text.length;
|
|
2289
|
+
return anchorKey !== focus.key || // If we're working with a non-text node.
|
|
2290
|
+
!$isTextNode(anchorNode) || // If we are replacing a range with a single character or grapheme, and not composing.
|
|
2291
|
+
(!isBeforeInput && (!CAN_USE_BEFORE_INPUT || // We check to see if there has been
|
|
2292
|
+
// a recent beforeinput event for "textInput". If there has been one in the last
|
|
2293
|
+
// 50ms then we proceed as normal. However, if there is not, then this is likely
|
|
2294
|
+
// a dangling `input` event caused by execCommand('insertText').
|
|
2295
|
+
lastBeforeInputInsertTextTimeStamp < timeStamp + 50) || textLength < 2 || doesContainGrapheme(text)) && anchor.offset !== focus.offset && !anchorNode.isComposing() || // Any non standard text node.
|
|
2296
|
+
$isTokenOrSegmented(anchorNode) || // If the text length is more than a single character and we're either
|
|
2297
|
+
// dealing with this in "beforeinput" or where the node has already recently
|
|
2298
|
+
// been changed (thus is dirty).
|
|
2299
|
+
anchorNode.isDirty() && textLength > 1 || // If the DOM selection element is not the same as the backing node during beforeinput.
|
|
2300
|
+
(isBeforeInput || !CAN_USE_BEFORE_INPUT) && backingAnchorElement !== null && !anchorNode.isComposing() && domAnchorNode !== getDOMTextNode(backingAnchorElement) || // Check if we're changing from bold to italics, or some other format.
|
|
2301
|
+
anchorNode.getFormat() !== selection.format || // One last set of heuristics to check against.
|
|
2302
|
+
$shouldInsertTextAfterOrBeforeTextNode(selection, anchorNode);
|
|
2303
|
+
}
|
|
2276
2304
|
|
|
2277
2305
|
function shouldSkipSelectionChange(domNode, offset) {
|
|
2278
2306
|
return domNode !== null && domNode.nodeValue !== null && domNode.nodeType === DOM_TEXT_TYPE && offset !== 0 && offset !== domNode.nodeValue.length;
|
|
@@ -2508,11 +2536,12 @@ function onBeforeInput(event, editor) {
|
|
|
2508
2536
|
const text = event.dataTransfer.getData('text/plain');
|
|
2509
2537
|
event.preventDefault();
|
|
2510
2538
|
selection.insertRawText(text);
|
|
2511
|
-
} else if (data != null && $shouldPreventDefaultAndInsertText(selection, data)) {
|
|
2539
|
+
} else if (data != null && $shouldPreventDefaultAndInsertText(selection, data, event.timeStamp, true)) {
|
|
2512
2540
|
event.preventDefault();
|
|
2513
2541
|
dispatchCommand(editor, CONTROLLED_TEXT_INSERTION_COMMAND, data);
|
|
2514
2542
|
}
|
|
2515
2543
|
|
|
2544
|
+
lastBeforeInputInsertTextTimeStamp = event.timeStamp;
|
|
2516
2545
|
return;
|
|
2517
2546
|
} // Prevent the browser from carrying out
|
|
2518
2547
|
// the input event, so we can control the
|
|
@@ -2665,7 +2694,7 @@ function onInput(event, editor) {
|
|
|
2665
2694
|
const selection = $getSelection();
|
|
2666
2695
|
const data = event.data;
|
|
2667
2696
|
|
|
2668
|
-
if (data != null && $isRangeSelection(selection) && $shouldPreventDefaultAndInsertText(selection, data)) {
|
|
2697
|
+
if (data != null && $isRangeSelection(selection) && $shouldPreventDefaultAndInsertText(selection, data, event.timeStamp, false)) {
|
|
2669
2698
|
// Given we're over-riding the default behavior, we will need
|
|
2670
2699
|
// to ensure to disable composition before dispatching the
|
|
2671
2700
|
// insertText command for when changing the sequence for FF.
|
|
@@ -2674,7 +2703,22 @@ function onInput(event, editor) {
|
|
|
2674
2703
|
isFirefoxEndingComposition = false;
|
|
2675
2704
|
}
|
|
2676
2705
|
|
|
2677
|
-
|
|
2706
|
+
const anchor = selection.anchor;
|
|
2707
|
+
const anchorNode = anchor.getNode();
|
|
2708
|
+
const domSelection = getDOMSelection();
|
|
2709
|
+
|
|
2710
|
+
if (domSelection === null) {
|
|
2711
|
+
return;
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2714
|
+
const offset = anchor.offset; // If the content is the same as inserted, then don't dispatch an insertion.
|
|
2715
|
+
// Given onInput doesn't take the current selection (it uses the previous)
|
|
2716
|
+
// we can compare that against what the DOM currently says.
|
|
2717
|
+
|
|
2718
|
+
if (!CAN_USE_BEFORE_INPUT || selection.isCollapsed() || !$isTextNode(anchorNode) || domSelection.anchorNode === null || anchorNode.getTextContent().slice(0, offset) + data + anchorNode.getTextContent().slice(offset + selection.focus.offset) !== getAnchorTextFromDOM(domSelection.anchorNode)) {
|
|
2719
|
+
dispatchCommand(editor, CONTROLLED_TEXT_INSERTION_COMMAND, data);
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2678
2722
|
const textLength = data.length; // Another hack for FF, as it's possible that the IME is still
|
|
2679
2723
|
// open, even though compositionend has already fired (sigh).
|
|
2680
2724
|
|
|
@@ -2779,11 +2823,6 @@ function onCompositionEnd(event, editor) {
|
|
|
2779
2823
|
}
|
|
2780
2824
|
|
|
2781
2825
|
function onKeyDown(event, editor) {
|
|
2782
|
-
if (hasStoppedLexicalPropagation(event)) {
|
|
2783
|
-
return;
|
|
2784
|
-
}
|
|
2785
|
-
|
|
2786
|
-
stopLexicalPropagation(event);
|
|
2787
2826
|
lastKeyDownTimeStamp = event.timeStamp;
|
|
2788
2827
|
lastKeyCode = event.keyCode;
|
|
2789
2828
|
|
|
@@ -2992,10 +3031,22 @@ function addRootElementEvents(rootElement, editor) {
|
|
|
2992
3031
|
for (let i = 0; i < rootElementEvents.length; i++) {
|
|
2993
3032
|
const [eventName, onEvent] = rootElementEvents[i];
|
|
2994
3033
|
const eventHandler = typeof onEvent === 'function' ? event => {
|
|
3034
|
+
if (hasStoppedLexicalPropagation(event)) {
|
|
3035
|
+
return;
|
|
3036
|
+
}
|
|
3037
|
+
|
|
3038
|
+
stopLexicalPropagation(event);
|
|
3039
|
+
|
|
2995
3040
|
if (editor.isEditable()) {
|
|
2996
3041
|
onEvent(event, editor);
|
|
2997
3042
|
}
|
|
2998
3043
|
} : event => {
|
|
3044
|
+
if (hasStoppedLexicalPropagation(event)) {
|
|
3045
|
+
return;
|
|
3046
|
+
}
|
|
3047
|
+
|
|
3048
|
+
stopLexicalPropagation(event);
|
|
3049
|
+
|
|
2999
3050
|
if (editor.isEditable()) {
|
|
3000
3051
|
switch (eventName) {
|
|
3001
3052
|
case 'cut':
|
|
@@ -3185,6 +3236,7 @@ function selectPointOnNode(point, node) {
|
|
|
3185
3236
|
if ($isTextNode(nextSibling)) {
|
|
3186
3237
|
key = nextSibling.__key;
|
|
3187
3238
|
offset = 0;
|
|
3239
|
+
type = 'text';
|
|
3188
3240
|
} else {
|
|
3189
3241
|
const parentNode = node.getParent();
|
|
3190
3242
|
|
|
@@ -4260,8 +4312,18 @@ class RangeSelection {
|
|
|
4260
4312
|
const childrenLength = children.length;
|
|
4261
4313
|
|
|
4262
4314
|
if ($isElementNode(target)) {
|
|
4315
|
+
let firstChild = target.getFirstChild();
|
|
4316
|
+
|
|
4263
4317
|
for (let s = 0; s < childrenLength; s++) {
|
|
4264
|
-
|
|
4318
|
+
const child = children[s];
|
|
4319
|
+
|
|
4320
|
+
if (firstChild === null) {
|
|
4321
|
+
target.append(child);
|
|
4322
|
+
} else {
|
|
4323
|
+
firstChild.insertAfter(child);
|
|
4324
|
+
}
|
|
4325
|
+
|
|
4326
|
+
firstChild = child;
|
|
4265
4327
|
}
|
|
4266
4328
|
} else {
|
|
4267
4329
|
for (let s = childrenLength - 1; s >= 0; s--) {
|
|
@@ -4376,7 +4438,11 @@ class RangeSelection {
|
|
|
4376
4438
|
if (lastChild === null) {
|
|
4377
4439
|
target.select();
|
|
4378
4440
|
} else if ($isTextNode(lastChild)) {
|
|
4379
|
-
lastChild.
|
|
4441
|
+
if (lastChild.getTextContent() === '') {
|
|
4442
|
+
lastChild.selectPrevious();
|
|
4443
|
+
} else {
|
|
4444
|
+
lastChild.select();
|
|
4445
|
+
}
|
|
4380
4446
|
} else {
|
|
4381
4447
|
lastChild.selectNext();
|
|
4382
4448
|
}
|
|
@@ -4389,7 +4455,8 @@ class RangeSelection {
|
|
|
4389
4455
|
const sibling = siblings[i];
|
|
4390
4456
|
const prevParent = sibling.getParentOrThrow();
|
|
4391
4457
|
|
|
4392
|
-
if ($isElementNode(target) && !$isBlockElementNode(sibling) && !($isDecoratorNode(sibling) &&
|
|
4458
|
+
if ($isElementNode(target) && !$isBlockElementNode(sibling) && !($isDecoratorNode(sibling) && ( // Note: We are only looking for decorators that are inline and not isolated.
|
|
4459
|
+
!sibling.isInline() || sibling.isIsolated()))) {
|
|
4393
4460
|
if (originalTarget === target) {
|
|
4394
4461
|
target.append(sibling);
|
|
4395
4462
|
} else {
|
|
@@ -4711,7 +4778,8 @@ class RangeSelection {
|
|
|
4711
4778
|
if (domSelection.rangeCount > 0) {
|
|
4712
4779
|
const range = domSelection.getRangeAt(0); // Apply the DOM selection to our Lexical selection.
|
|
4713
4780
|
|
|
4714
|
-
const
|
|
4781
|
+
const anchorNode = this.anchor.getNode();
|
|
4782
|
+
const root = $isRootNode(anchorNode) ? anchorNode : $getNearestRootOrShadowRoot(anchorNode);
|
|
4715
4783
|
this.applyDOMRange(range);
|
|
4716
4784
|
this.dirty = true;
|
|
4717
4785
|
|
|
@@ -4776,6 +4844,24 @@ class RangeSelection {
|
|
|
4776
4844
|
if ($isElementNode(nextSibling) && !nextSibling.canExtractContents()) {
|
|
4777
4845
|
return;
|
|
4778
4846
|
}
|
|
4847
|
+
} // Handle the deletion around decorators.
|
|
4848
|
+
|
|
4849
|
+
|
|
4850
|
+
const possibleNode = $getDecoratorNode(focus, isBackward);
|
|
4851
|
+
|
|
4852
|
+
if ($isDecoratorNode(possibleNode) && !possibleNode.isIsolated()) {
|
|
4853
|
+
// Make it possible to move selection from range selection to
|
|
4854
|
+
// node selection on the node.
|
|
4855
|
+
if (possibleNode.isKeyboardSelectable() && $isElementNode(anchorNode) && anchorNode.getChildrenSize() === 0) {
|
|
4856
|
+
anchorNode.remove();
|
|
4857
|
+
const nodeSelection = $createNodeSelection();
|
|
4858
|
+
nodeSelection.add(possibleNode.__key);
|
|
4859
|
+
$setSelection(nodeSelection);
|
|
4860
|
+
} else {
|
|
4861
|
+
possibleNode.remove();
|
|
4862
|
+
}
|
|
4863
|
+
|
|
4864
|
+
return;
|
|
4779
4865
|
}
|
|
4780
4866
|
|
|
4781
4867
|
this.modify('extend', isBackward, 'character');
|
|
@@ -6386,6 +6472,8 @@ class LexicalNode {
|
|
|
6386
6472
|
// @ts-expect-error
|
|
6387
6473
|
this.__type = this.constructor.getType();
|
|
6388
6474
|
this.__parent = null;
|
|
6475
|
+
this.__prev = null;
|
|
6476
|
+
this.__next = null;
|
|
6389
6477
|
$setNodeKey(this, key);
|
|
6390
6478
|
|
|
6391
6479
|
{
|
|
@@ -6889,6 +6977,7 @@ class LexicalNode {
|
|
|
6889
6977
|
|
|
6890
6978
|
replace(replaceWith) {
|
|
6891
6979
|
errorOnReadOnly();
|
|
6980
|
+
errorOnInsertTextNodeOnRoot(this, replaceWith);
|
|
6892
6981
|
const toReplaceKey = this.__key;
|
|
6893
6982
|
const writableReplaceWith = replaceWith.getWritable();
|
|
6894
6983
|
removeFromParent(writableReplaceWith);
|
|
@@ -6932,6 +7021,7 @@ class LexicalNode {
|
|
|
6932
7021
|
|
|
6933
7022
|
insertAfter(nodeToInsert) {
|
|
6934
7023
|
errorOnReadOnly();
|
|
7024
|
+
errorOnInsertTextNodeOnRoot(this, nodeToInsert);
|
|
6935
7025
|
const writableSelf = this.getWritable();
|
|
6936
7026
|
const writableNodeToInsert = nodeToInsert.getWritable();
|
|
6937
7027
|
const oldParent = writableNodeToInsert.getParent();
|
|
@@ -6984,6 +7074,8 @@ class LexicalNode {
|
|
|
6984
7074
|
}
|
|
6985
7075
|
|
|
6986
7076
|
insertBefore(nodeToInsert) {
|
|
7077
|
+
errorOnReadOnly();
|
|
7078
|
+
errorOnInsertTextNodeOnRoot(this, nodeToInsert);
|
|
6987
7079
|
const writableSelf = this.getWritable();
|
|
6988
7080
|
const writableNodeToInsert = nodeToInsert.getWritable();
|
|
6989
7081
|
removeFromParent(writableNodeToInsert);
|
|
@@ -7127,10 +7219,20 @@ class ElementNode extends LexicalNode {
|
|
|
7127
7219
|
|
|
7128
7220
|
/** @internal */
|
|
7129
7221
|
|
|
7222
|
+
/** @internal */
|
|
7223
|
+
|
|
7224
|
+
/** @internal */
|
|
7225
|
+
|
|
7226
|
+
/** @internal */
|
|
7227
|
+
|
|
7130
7228
|
/** @internal */
|
|
7131
7229
|
constructor(key) {
|
|
7132
|
-
super(key);
|
|
7230
|
+
super(key); // TODO: remove children and switch to using first/last as part of linked list work
|
|
7231
|
+
|
|
7133
7232
|
this.__children = [];
|
|
7233
|
+
this.__first = null;
|
|
7234
|
+
this.__last = null;
|
|
7235
|
+
this.__size = 0;
|
|
7134
7236
|
this.__format = 0;
|
|
7135
7237
|
this.__indent = 0;
|
|
7136
7238
|
this.__dir = null;
|
|
@@ -7745,6 +7847,10 @@ class RootNode extends ElementNode {
|
|
|
7745
7847
|
};
|
|
7746
7848
|
}
|
|
7747
7849
|
|
|
7850
|
+
collapseAtStart() {
|
|
7851
|
+
return true;
|
|
7852
|
+
}
|
|
7853
|
+
|
|
7748
7854
|
}
|
|
7749
7855
|
function $createRootNode() {
|
|
7750
7856
|
return new RootNode();
|
|
@@ -8349,15 +8455,24 @@ class TextNode extends LexicalNode {
|
|
|
8349
8455
|
|
|
8350
8456
|
setMode(type) {
|
|
8351
8457
|
const mode = TEXT_MODE_TO_TYPE[type];
|
|
8458
|
+
|
|
8459
|
+
if (this.__mode === mode) {
|
|
8460
|
+
return this;
|
|
8461
|
+
}
|
|
8462
|
+
|
|
8352
8463
|
const self = this.getWritable();
|
|
8353
8464
|
self.__mode = mode;
|
|
8354
8465
|
return self;
|
|
8355
8466
|
}
|
|
8356
8467
|
|
|
8357
8468
|
setTextContent(text) {
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8469
|
+
if (this.__text === text) {
|
|
8470
|
+
return this;
|
|
8471
|
+
}
|
|
8472
|
+
|
|
8473
|
+
const self = this.getWritable();
|
|
8474
|
+
self.__text = text;
|
|
8475
|
+
return self;
|
|
8361
8476
|
}
|
|
8362
8477
|
|
|
8363
8478
|
select(_anchorOffset, _focusOffset) {
|
|
@@ -9400,7 +9515,7 @@ class LexicalEditor {
|
|
|
9400
9515
|
* LICENSE file in the root directory of this source tree.
|
|
9401
9516
|
*
|
|
9402
9517
|
*/
|
|
9403
|
-
const VERSION = '0.6.
|
|
9518
|
+
const VERSION = '0.6.4';
|
|
9404
9519
|
|
|
9405
9520
|
/**
|
|
9406
9521
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
package/Lexical.js.flow
CHANGED
|
@@ -494,7 +494,6 @@ type TextPointType = {
|
|
|
494
494
|
getNode: () => TextNode,
|
|
495
495
|
set: (key: NodeKey, offset: number, type: 'text' | 'element') => void,
|
|
496
496
|
getCharacterOffset: () => number,
|
|
497
|
-
isAtNodeEnd: () => boolean,
|
|
498
497
|
};
|
|
499
498
|
export type ElementPoint = ElementPointType;
|
|
500
499
|
type ElementPointType = {
|
|
@@ -505,7 +504,6 @@ type ElementPointType = {
|
|
|
505
504
|
isBefore: (PointType) => boolean,
|
|
506
505
|
getNode: () => ElementNode,
|
|
507
506
|
set: (key: NodeKey, offset: number, type: 'text' | 'element') => void,
|
|
508
|
-
isAtNodeEnd: () => boolean,
|
|
509
507
|
};
|
|
510
508
|
export type Point = PointType;
|
|
511
509
|
type PointType = TextPointType | ElementPointType;
|
|
@@ -629,7 +627,8 @@ declare export class LineBreakNode extends LexicalNode {
|
|
|
629
627
|
static importJSON(
|
|
630
628
|
serializedLineBreakNode: SerializedLineBreakNode,
|
|
631
629
|
): LineBreakNode;
|
|
632
|
-
|
|
630
|
+
// $FlowExpectedError[incompatible-extend] 'linebreak' is a literal string
|
|
631
|
+
exportJSON(): SerializedLineBreakNode;
|
|
633
632
|
}
|
|
634
633
|
declare export function $createLineBreakNode(): LineBreakNode;
|
|
635
634
|
declare export function $isLineBreakNode(
|
|
@@ -757,7 +756,8 @@ declare export class ParagraphNode extends ElementNode {
|
|
|
757
756
|
static importJSON(
|
|
758
757
|
serializedParagraphNode: SerializedParagraphNode,
|
|
759
758
|
): ParagraphNode;
|
|
760
|
-
|
|
759
|
+
// $FlowExpectedError[incompatible-extend] 'paragraph' is a literal string
|
|
760
|
+
exportJSON(): SerializedParagraphNode;
|
|
761
761
|
}
|
|
762
762
|
declare export function $createParagraphNode(): ParagraphNode;
|
|
763
763
|
declare export function $isParagraphNode(
|