lexical 0.3.2 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Lexical.dev.js +219 -208
- package/Lexical.js.flow +17 -10
- package/Lexical.prod.js +172 -170
- package/LexicalCommands.d.ts +50 -0
- package/LexicalConstants.d.ts +42 -0
- package/LexicalEditor.d.ts +200 -0
- package/LexicalEditorState.d.ts +28 -0
- package/LexicalEvents.d.ts +14 -0
- package/LexicalGC.d.ts +12 -0
- package/LexicalMutations.d.ts +12 -0
- package/LexicalNode.d.ts +82 -0
- package/LexicalNormalization.d.ts +9 -0
- package/LexicalReconciler.d.ts +12 -0
- package/LexicalSelection.d.ts +147 -0
- package/LexicalUpdates.d.ts +25 -0
- package/LexicalUtils.d.ts +95 -0
- package/LexicalVersion.d.ts +8 -0
- package/README.md +1 -0
- package/index.d.ts +31 -0
- package/nodes/LexicalDecoratorNode.d.ts +18 -0
- package/nodes/LexicalElementNode.d.ts +71 -0
- package/nodes/LexicalGridCellNode.d.ts +18 -0
- package/nodes/LexicalGridNode.d.ts +12 -0
- package/nodes/LexicalGridRowNode.d.ts +12 -0
- package/nodes/LexicalLineBreakNode.d.ts +26 -0
- package/nodes/LexicalParagraphNode.d.ts +30 -0
- package/nodes/LexicalRootNode.d.ts +29 -0
- package/nodes/LexicalTextNode.d.ts +74 -0
- package/package.json +4 -2
- package/Lexical.d.ts +0 -849
package/Lexical.dev.js
CHANGED
|
@@ -6,6 +6,58 @@
|
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11
|
+
*
|
|
12
|
+
* This source code is licensed under the MIT license found in the
|
|
13
|
+
* LICENSE file in the root directory of this source tree.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
function createCommand() {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
const SELECTION_CHANGE_COMMAND = createCommand();
|
|
20
|
+
const CLICK_COMMAND = createCommand();
|
|
21
|
+
const DELETE_CHARACTER_COMMAND = createCommand();
|
|
22
|
+
const INSERT_LINE_BREAK_COMMAND = createCommand();
|
|
23
|
+
const INSERT_PARAGRAPH_COMMAND = createCommand();
|
|
24
|
+
const CONTROLLED_TEXT_INSERTION_COMMAND = createCommand();
|
|
25
|
+
const PASTE_COMMAND = createCommand();
|
|
26
|
+
const REMOVE_TEXT_COMMAND = createCommand();
|
|
27
|
+
const DELETE_WORD_COMMAND = createCommand();
|
|
28
|
+
const DELETE_LINE_COMMAND = createCommand();
|
|
29
|
+
const FORMAT_TEXT_COMMAND = createCommand();
|
|
30
|
+
const UNDO_COMMAND = createCommand();
|
|
31
|
+
const REDO_COMMAND = createCommand();
|
|
32
|
+
const KEY_ARROW_RIGHT_COMMAND = createCommand();
|
|
33
|
+
const MOVE_TO_END = createCommand();
|
|
34
|
+
const KEY_ARROW_LEFT_COMMAND = createCommand();
|
|
35
|
+
const MOVE_TO_START = createCommand();
|
|
36
|
+
const KEY_ARROW_UP_COMMAND = createCommand();
|
|
37
|
+
const KEY_ARROW_DOWN_COMMAND = createCommand();
|
|
38
|
+
const KEY_ENTER_COMMAND = createCommand();
|
|
39
|
+
const KEY_SPACE_COMMAND = createCommand();
|
|
40
|
+
const KEY_BACKSPACE_COMMAND = createCommand();
|
|
41
|
+
const KEY_ESCAPE_COMMAND = createCommand();
|
|
42
|
+
const KEY_DELETE_COMMAND = createCommand();
|
|
43
|
+
const KEY_TAB_COMMAND = createCommand();
|
|
44
|
+
const INDENT_CONTENT_COMMAND = createCommand();
|
|
45
|
+
const OUTDENT_CONTENT_COMMAND = createCommand();
|
|
46
|
+
const DROP_COMMAND = createCommand();
|
|
47
|
+
const FORMAT_ELEMENT_COMMAND = createCommand();
|
|
48
|
+
const DRAGSTART_COMMAND = createCommand();
|
|
49
|
+
const DRAGOVER_COMMAND = createCommand();
|
|
50
|
+
const DRAGEND_COMMAND = createCommand();
|
|
51
|
+
const COPY_COMMAND = createCommand();
|
|
52
|
+
const CUT_COMMAND = createCommand();
|
|
53
|
+
const CLEAR_EDITOR_COMMAND = createCommand();
|
|
54
|
+
const CLEAR_HISTORY_COMMAND = createCommand();
|
|
55
|
+
const CAN_REDO_COMMAND = createCommand();
|
|
56
|
+
const CAN_UNDO_COMMAND = createCommand();
|
|
57
|
+
const FOCUS_COMMAND = createCommand();
|
|
58
|
+
const BLUR_COMMAND = createCommand();
|
|
59
|
+
const KEY_MODIFIER_COMMAND = createCommand();
|
|
60
|
+
|
|
9
61
|
/**
|
|
10
62
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
11
63
|
*
|
|
@@ -173,12 +225,25 @@ function handleTextMutation(target, node, editor) {
|
|
|
173
225
|
$updateTextNodeFromDOMContent(node, text, anchorOffset, focusOffset, false);
|
|
174
226
|
}
|
|
175
227
|
|
|
228
|
+
function shouldUpdateTextNodeFromMutation(selection, targetDOM, targetNode) {
|
|
229
|
+
if ($isRangeSelection(selection)) {
|
|
230
|
+
const anchorNode = selection.anchor.getNode();
|
|
231
|
+
|
|
232
|
+
if (anchorNode.is(targetNode) && selection.format !== anchorNode.getFormat()) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return targetDOM.nodeType === DOM_TEXT_TYPE && targetNode.isAttached();
|
|
238
|
+
}
|
|
239
|
+
|
|
176
240
|
function $flushMutations$1(editor, mutations, observer) {
|
|
177
241
|
isProcessingMutations = true;
|
|
178
242
|
const shouldFlushTextMutations = performance.now() - lastTextEntryTimeStamp > TEXT_MUTATION_VARIANCE;
|
|
179
243
|
|
|
180
244
|
try {
|
|
181
245
|
updateEditor(editor, () => {
|
|
246
|
+
const selection = $getSelection() || getLastSelection(editor);
|
|
182
247
|
const badDOMTargets = new Map();
|
|
183
248
|
const rootElement = editor.getRootElement(); // We use the current edtior state, as that reflects what is
|
|
184
249
|
// actually "on screen".
|
|
@@ -200,7 +265,7 @@ function $flushMutations$1(editor, mutations, observer) {
|
|
|
200
265
|
if (type === 'characterData') {
|
|
201
266
|
// Text mutations are deferred and passed to mutation listeners to be
|
|
202
267
|
// processed outside of the Lexical engine.
|
|
203
|
-
if (shouldFlushTextMutations &&
|
|
268
|
+
if (shouldFlushTextMutations && $isTextNode(targetNode) && shouldUpdateTextNodeFromMutation(selection, targetDOM, targetNode)) {
|
|
204
269
|
handleTextMutation( // nodeType === DOM_TEXT_TYPE is a Text DOM node
|
|
205
270
|
targetDOM, targetNode);
|
|
206
271
|
}
|
|
@@ -315,8 +380,6 @@ function $flushMutations$1(editor, mutations, observer) {
|
|
|
315
380
|
observer.takeRecords();
|
|
316
381
|
}
|
|
317
382
|
|
|
318
|
-
const selection = $getSelection() || getLastSelection(editor);
|
|
319
|
-
|
|
320
383
|
if (selection !== null) {
|
|
321
384
|
if (shouldRevertSelection) {
|
|
322
385
|
selection.dirty = true;
|
|
@@ -664,7 +727,6 @@ function $setSelection(selection) {
|
|
|
664
727
|
const editorState = getActiveEditorState();
|
|
665
728
|
|
|
666
729
|
if (selection !== null) {
|
|
667
|
-
// @ts-ignore
|
|
668
730
|
{
|
|
669
731
|
if (Object.isFrozen(selection)) {
|
|
670
732
|
{
|
|
@@ -1173,11 +1235,12 @@ function scrollIntoViewIfNeeded(editor, anchor, rootElement, tags) {
|
|
|
1173
1235
|
} else if (rect.top < 0) {
|
|
1174
1236
|
element.scrollIntoView();
|
|
1175
1237
|
} else {
|
|
1176
|
-
const rootRect = rootElement.getBoundingClientRect();
|
|
1238
|
+
const rootRect = rootElement.getBoundingClientRect(); // Rects can returning decimal numbers that differ due to rounding
|
|
1239
|
+
// differences. So let's normalize the values.
|
|
1177
1240
|
|
|
1178
|
-
if (rect.bottom > rootRect.bottom) {
|
|
1241
|
+
if (Math.floor(rect.bottom) > Math.floor(rootRect.bottom)) {
|
|
1179
1242
|
element.scrollIntoView(false);
|
|
1180
|
-
} else if (rect.top < rootRect.top) {
|
|
1243
|
+
} else if (Math.floor(rect.top) < Math.floor(rootRect.top)) {
|
|
1181
1244
|
element.scrollIntoView();
|
|
1182
1245
|
}
|
|
1183
1246
|
}
|
|
@@ -1473,7 +1536,7 @@ function createNode(key, parentDOM, insertDOM) {
|
|
|
1473
1536
|
const text = node.getTextContent();
|
|
1474
1537
|
|
|
1475
1538
|
if ($isDecoratorNode(node)) {
|
|
1476
|
-
const decorator = node.decorate(activeEditor$1);
|
|
1539
|
+
const decorator = node.decorate(activeEditor$1, activeEditorConfig);
|
|
1477
1540
|
|
|
1478
1541
|
if (decorator !== null) {
|
|
1479
1542
|
reconcileDecorator(key, decorator);
|
|
@@ -1513,8 +1576,7 @@ function createNode(key, parentDOM, insertDOM) {
|
|
|
1513
1576
|
parentDOM.appendChild(dom);
|
|
1514
1577
|
}
|
|
1515
1578
|
}
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1579
|
+
}
|
|
1518
1580
|
|
|
1519
1581
|
{
|
|
1520
1582
|
// Freeze the node in DEV to prevent accidental mutations
|
|
@@ -1789,7 +1851,7 @@ function reconcileNode(key, parentDOM) {
|
|
|
1789
1851
|
const text = nextNode.getTextContent();
|
|
1790
1852
|
|
|
1791
1853
|
if ($isDecoratorNode(nextNode)) {
|
|
1792
|
-
const decorator = nextNode.decorate(activeEditor$1);
|
|
1854
|
+
const decorator = nextNode.decorate(activeEditor$1, activeEditorConfig);
|
|
1793
1855
|
|
|
1794
1856
|
if (decorator !== null) {
|
|
1795
1857
|
reconcileDecorator(key, decorator);
|
|
@@ -1810,8 +1872,7 @@ function reconcileNode(key, parentDOM) {
|
|
|
1810
1872
|
// Cache the latest text content.
|
|
1811
1873
|
nextNode = nextNode.getWritable();
|
|
1812
1874
|
nextNode.__cachedText = editorTextContent;
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1875
|
+
}
|
|
1815
1876
|
|
|
1816
1877
|
{
|
|
1817
1878
|
// Freeze the node in DEV to prevent accidental mutations
|
|
@@ -1970,58 +2031,6 @@ function getPrevElementByKeyOrThrow(key) {
|
|
|
1970
2031
|
return element;
|
|
1971
2032
|
}
|
|
1972
2033
|
|
|
1973
|
-
/**
|
|
1974
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
1975
|
-
*
|
|
1976
|
-
* This source code is licensed under the MIT license found in the
|
|
1977
|
-
* LICENSE file in the root directory of this source tree.
|
|
1978
|
-
*
|
|
1979
|
-
*/
|
|
1980
|
-
function createCommand() {
|
|
1981
|
-
return {};
|
|
1982
|
-
}
|
|
1983
|
-
const SELECTION_CHANGE_COMMAND = createCommand();
|
|
1984
|
-
const CLICK_COMMAND = createCommand();
|
|
1985
|
-
const DELETE_CHARACTER_COMMAND = createCommand();
|
|
1986
|
-
const INSERT_LINE_BREAK_COMMAND = createCommand();
|
|
1987
|
-
const INSERT_PARAGRAPH_COMMAND = createCommand();
|
|
1988
|
-
const CONTROLLED_TEXT_INSERTION_COMMAND = createCommand();
|
|
1989
|
-
const PASTE_COMMAND = createCommand();
|
|
1990
|
-
const REMOVE_TEXT_COMMAND = createCommand();
|
|
1991
|
-
const DELETE_WORD_COMMAND = createCommand();
|
|
1992
|
-
const DELETE_LINE_COMMAND = createCommand();
|
|
1993
|
-
const FORMAT_TEXT_COMMAND = createCommand();
|
|
1994
|
-
const UNDO_COMMAND = createCommand();
|
|
1995
|
-
const REDO_COMMAND = createCommand();
|
|
1996
|
-
const KEY_ARROW_RIGHT_COMMAND = createCommand();
|
|
1997
|
-
const MOVE_TO_END = createCommand();
|
|
1998
|
-
const KEY_ARROW_LEFT_COMMAND = createCommand();
|
|
1999
|
-
const MOVE_TO_START = createCommand();
|
|
2000
|
-
const KEY_ARROW_UP_COMMAND = createCommand();
|
|
2001
|
-
const KEY_ARROW_DOWN_COMMAND = createCommand();
|
|
2002
|
-
const KEY_ENTER_COMMAND = createCommand();
|
|
2003
|
-
const KEY_SPACE_COMMAND = createCommand();
|
|
2004
|
-
const KEY_BACKSPACE_COMMAND = createCommand();
|
|
2005
|
-
const KEY_ESCAPE_COMMAND = createCommand();
|
|
2006
|
-
const KEY_DELETE_COMMAND = createCommand();
|
|
2007
|
-
const KEY_TAB_COMMAND = createCommand();
|
|
2008
|
-
const INDENT_CONTENT_COMMAND = createCommand();
|
|
2009
|
-
const OUTDENT_CONTENT_COMMAND = createCommand();
|
|
2010
|
-
const DROP_COMMAND = createCommand();
|
|
2011
|
-
const FORMAT_ELEMENT_COMMAND = createCommand();
|
|
2012
|
-
const DRAGSTART_COMMAND = createCommand();
|
|
2013
|
-
const DRAGOVER_COMMAND = createCommand();
|
|
2014
|
-
const DRAGEND_COMMAND = createCommand();
|
|
2015
|
-
const COPY_COMMAND = createCommand();
|
|
2016
|
-
const CUT_COMMAND = createCommand();
|
|
2017
|
-
const CLEAR_EDITOR_COMMAND = createCommand();
|
|
2018
|
-
const CLEAR_HISTORY_COMMAND = createCommand();
|
|
2019
|
-
const CAN_REDO_COMMAND = createCommand();
|
|
2020
|
-
const CAN_UNDO_COMMAND = createCommand();
|
|
2021
|
-
const FOCUS_COMMAND = createCommand();
|
|
2022
|
-
const BLUR_COMMAND = createCommand();
|
|
2023
|
-
const KEY_MODIFIER_COMMAND = createCommand();
|
|
2024
|
-
|
|
2025
2034
|
/**
|
|
2026
2035
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2027
2036
|
*
|
|
@@ -2038,6 +2047,7 @@ if (CAN_USE_BEFORE_INPUT) {
|
|
|
2038
2047
|
}
|
|
2039
2048
|
|
|
2040
2049
|
let lastKeyDownTimeStamp = 0;
|
|
2050
|
+
let lastKeyCode = 0;
|
|
2041
2051
|
let rootElementsRegistered = 0;
|
|
2042
2052
|
let isSelectionChangeFromDOMUpdate = false;
|
|
2043
2053
|
let isInsertLineBreak = false;
|
|
@@ -2179,6 +2189,10 @@ function $canRemoveText(anchorNode, focusNode) {
|
|
|
2179
2189
|
return anchorNode !== focusNode || $isElementNode(anchorNode) || $isElementNode(focusNode) || !$isTokenOrInert(anchorNode) || !$isTokenOrInert(focusNode);
|
|
2180
2190
|
}
|
|
2181
2191
|
|
|
2192
|
+
function isPossiblyAndroidKeyPress(timeStamp) {
|
|
2193
|
+
return lastKeyCode === 229 && timeStamp < lastKeyDownTimeStamp + ANDROID_COMPOSITION_LATENCY;
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2182
2196
|
function onBeforeInput(event, editor) {
|
|
2183
2197
|
const inputType = event.inputType; // We let the browser do its own thing for composition.
|
|
2184
2198
|
|
|
@@ -2195,7 +2209,9 @@ function onBeforeInput(event, editor) {
|
|
|
2195
2209
|
// during composition and see if the previous text contains
|
|
2196
2210
|
// part of the composed text to work out the actual text that
|
|
2197
2211
|
// we need to insert.
|
|
2198
|
-
const composedText = event.data;
|
|
2212
|
+
const composedText = event.data; // TODO: evaluate if this is Android only. It doesn't always seem
|
|
2213
|
+
// to have any real impact, so could probably be refactored or removed
|
|
2214
|
+
// for an alternative approach.
|
|
2199
2215
|
|
|
2200
2216
|
if (composedText) {
|
|
2201
2217
|
updateEditor(editor, () => {
|
|
@@ -2239,20 +2255,32 @@ function onBeforeInput(event, editor) {
|
|
|
2239
2255
|
}
|
|
2240
2256
|
|
|
2241
2257
|
$setSelection(prevSelection.clone());
|
|
2242
|
-
}
|
|
2258
|
+
}
|
|
2243
2259
|
|
|
2260
|
+
if ($isRangeSelection(selection)) {
|
|
2261
|
+
// Used for handling backspace in Android.
|
|
2262
|
+
if (isPossiblyAndroidKeyPress(event.timeStamp) && selection.anchor.key === selection.focus.key) {
|
|
2263
|
+
$setCompositionKey(null);
|
|
2264
|
+
lastKeyDownTimeStamp = 0; // Fixes an Android bug where selection flickers when backspacing
|
|
2244
2265
|
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2266
|
+
setTimeout(() => {
|
|
2267
|
+
updateEditor(editor, () => {
|
|
2268
|
+
$setCompositionKey(null);
|
|
2269
|
+
});
|
|
2270
|
+
}, ANDROID_COMPOSITION_LATENCY);
|
|
2249
2271
|
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2272
|
+
if ($isRangeSelection(selection)) {
|
|
2273
|
+
const anchorNode = selection.anchor.getNode();
|
|
2274
|
+
anchorNode.markDirty();
|
|
2275
|
+
selection.format = anchorNode.getFormat();
|
|
2276
|
+
}
|
|
2277
|
+
} else {
|
|
2278
|
+
event.preventDefault();
|
|
2279
|
+
dispatchCommand(editor, DELETE_CHARACTER_COMMAND, false);
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
return;
|
|
2283
|
+
}
|
|
2256
2284
|
}
|
|
2257
2285
|
|
|
2258
2286
|
if (!$isRangeSelection(selection)) {
|
|
@@ -2438,9 +2466,8 @@ function onInput(event, editor) {
|
|
|
2438
2466
|
updateEditor(editor, () => {
|
|
2439
2467
|
const selection = $getSelection();
|
|
2440
2468
|
const data = event.data;
|
|
2441
|
-
const possibleTextReplacement = event.inputType === 'insertText' && data != null && data.length > 1 && !doesContainGrapheme(data);
|
|
2442
2469
|
|
|
2443
|
-
if (data != null && $isRangeSelection(selection) &&
|
|
2470
|
+
if (data != null && $isRangeSelection(selection) && $shouldPreventDefaultAndInsertText(selection, data)) {
|
|
2444
2471
|
// Given we're over-riding the default behavior, we will need
|
|
2445
2472
|
// to ensure to disable composition before dispatching the
|
|
2446
2473
|
// insertText command for when changing the sequence for FF.
|
|
@@ -2449,24 +2476,7 @@ function onInput(event, editor) {
|
|
|
2449
2476
|
isFirefoxEndingComposition = false;
|
|
2450
2477
|
}
|
|
2451
2478
|
|
|
2452
|
-
dispatchCommand(editor, CONTROLLED_TEXT_INSERTION_COMMAND, data);
|
|
2453
|
-
|
|
2454
|
-
if (possibleTextReplacement) {
|
|
2455
|
-
// If the DOM selection offset is higher than the existing
|
|
2456
|
-
// offset, then restore the offset as it's likely correct
|
|
2457
|
-
// in the case of text replacements.
|
|
2458
|
-
const {
|
|
2459
|
-
anchorOffset
|
|
2460
|
-
} = window.getSelection();
|
|
2461
|
-
const anchor = selection.anchor;
|
|
2462
|
-
const focus = selection.focus;
|
|
2463
|
-
|
|
2464
|
-
if (anchorOffset > anchor.offset) {
|
|
2465
|
-
anchor.set(anchor.key, anchorOffset, anchor.type);
|
|
2466
|
-
focus.set(anchor.key, anchorOffset, anchor.type);
|
|
2467
|
-
}
|
|
2468
|
-
} // This ensures consistency on Android.
|
|
2469
|
-
|
|
2479
|
+
dispatchCommand(editor, CONTROLLED_TEXT_INSERTION_COMMAND, data); // This ensures consistency on Android.
|
|
2470
2480
|
|
|
2471
2481
|
if (!IS_SAFARI && !IS_IOS && editor.isComposing()) {
|
|
2472
2482
|
lastKeyDownTimeStamp = 0;
|
|
@@ -2565,6 +2575,7 @@ function onCompositionEnd(event, editor) {
|
|
|
2565
2575
|
|
|
2566
2576
|
function onKeyDown(event, editor) {
|
|
2567
2577
|
lastKeyDownTimeStamp = event.timeStamp;
|
|
2578
|
+
lastKeyCode = event.keyCode;
|
|
2568
2579
|
|
|
2569
2580
|
if (editor.isComposing()) {
|
|
2570
2581
|
return;
|
|
@@ -2830,7 +2841,6 @@ function markCollapsedSelectionFormat(format, offset, key, timeStamp) {
|
|
|
2830
2841
|
* LICENSE file in the root directory of this source tree.
|
|
2831
2842
|
*
|
|
2832
2843
|
*/
|
|
2833
|
-
|
|
2834
2844
|
class Point {
|
|
2835
2845
|
constructor(key, offset, type) {
|
|
2836
2846
|
this._selection = null;
|
|
@@ -3467,6 +3477,7 @@ class RangeSelection {
|
|
|
3467
3477
|
|
|
3468
3478
|
if (!$isTextNode(nextSibling) || $isTokenOrInertOrSegmented(nextSibling)) {
|
|
3469
3479
|
nextSibling = $createTextNode();
|
|
3480
|
+
nextSibling.setFormat(format);
|
|
3470
3481
|
|
|
3471
3482
|
if (!firstNodeParent.canInsertTextAfter()) {
|
|
3472
3483
|
firstNodeParent.insertAfter(nextSibling);
|
|
@@ -3487,6 +3498,7 @@ class RangeSelection {
|
|
|
3487
3498
|
|
|
3488
3499
|
if (!$isTextNode(prevSibling) || $isTokenOrInertOrSegmented(prevSibling)) {
|
|
3489
3500
|
prevSibling = $createTextNode();
|
|
3501
|
+
prevSibling.setFormat(format);
|
|
3490
3502
|
|
|
3491
3503
|
if (!firstNodeParent.canInsertTextBefore()) {
|
|
3492
3504
|
firstNodeParent.insertBefore(prevSibling);
|
|
@@ -3504,6 +3516,7 @@ class RangeSelection {
|
|
|
3504
3516
|
}
|
|
3505
3517
|
} else if (firstNode.isSegmented() && startOffset !== firstNodeTextLength) {
|
|
3506
3518
|
const textNode = $createTextNode(firstNode.getTextContent());
|
|
3519
|
+
textNode.setFormat(format);
|
|
3507
3520
|
firstNode.replace(textNode);
|
|
3508
3521
|
firstNode = textNode;
|
|
3509
3522
|
} else if (!this.isCollapsed() && text !== '') {
|
|
@@ -3561,10 +3574,14 @@ class RangeSelection {
|
|
|
3561
3574
|
|
|
3562
3575
|
if (firstNode.getTextContent() === '') {
|
|
3563
3576
|
firstNode.remove();
|
|
3564
|
-
} else if (
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3577
|
+
} else if (this.anchor.type === 'text') {
|
|
3578
|
+
if (firstNode.isComposing()) {
|
|
3579
|
+
// When composing, we need to adjust the anchor offset so that
|
|
3580
|
+
// we correctly replace that right range.
|
|
3581
|
+
this.anchor.offset -= text.length;
|
|
3582
|
+
} else {
|
|
3583
|
+
this.format = firstNodeFormat;
|
|
3584
|
+
}
|
|
3568
3585
|
}
|
|
3569
3586
|
} else {
|
|
3570
3587
|
const markedNodeKeysForKeep = new Set([...firstNode.getParentKeys(), ...lastNode.getParentKeys()]); // We have to get the parent elements before the next section,
|
|
@@ -4763,15 +4780,15 @@ function internalMakeRangeSelection(anchorKey, anchorOffset, focusKey, focusOffs
|
|
|
4763
4780
|
editorState._selection = selection;
|
|
4764
4781
|
return selection;
|
|
4765
4782
|
}
|
|
4766
|
-
function $
|
|
4783
|
+
function $createRangeSelection() {
|
|
4767
4784
|
const anchor = $createPoint('root', 0, 'element');
|
|
4768
4785
|
const focus = $createPoint('root', 0, 'element');
|
|
4769
4786
|
return new RangeSelection(anchor, focus, 0);
|
|
4770
4787
|
}
|
|
4771
|
-
function $
|
|
4788
|
+
function $createNodeSelection() {
|
|
4772
4789
|
return new NodeSelection(new Set());
|
|
4773
4790
|
}
|
|
4774
|
-
function $
|
|
4791
|
+
function $createGridSelection() {
|
|
4775
4792
|
const anchor = $createPoint('root', 0, 'element');
|
|
4776
4793
|
const focus = $createPoint('root', 0, 'element');
|
|
4777
4794
|
return new GridSelection('root', anchor, focus);
|
|
@@ -5365,7 +5382,7 @@ function parseEditorState(serializedEditorState, editor, updateFn) {
|
|
|
5365
5382
|
} // Make the editorState immutable
|
|
5366
5383
|
|
|
5367
5384
|
|
|
5368
|
-
editorState._readOnly = true;
|
|
5385
|
+
editorState._readOnly = true;
|
|
5369
5386
|
|
|
5370
5387
|
{
|
|
5371
5388
|
handleDEVOnlyPendingUpdateGuarantees(editorState);
|
|
@@ -5470,6 +5487,9 @@ function commitPendingUpdates(editor) {
|
|
|
5470
5487
|
isAttemptingToRecoverFromReconcilerError = true;
|
|
5471
5488
|
commitPendingUpdates(editor);
|
|
5472
5489
|
isAttemptingToRecoverFromReconcilerError = false;
|
|
5490
|
+
} else {
|
|
5491
|
+
// To avoid a possible situation of infinite loops, lets throw
|
|
5492
|
+
throw error;
|
|
5473
5493
|
}
|
|
5474
5494
|
|
|
5475
5495
|
return;
|
|
@@ -5486,7 +5506,7 @@ function commitPendingUpdates(editor) {
|
|
|
5486
5506
|
}
|
|
5487
5507
|
}
|
|
5488
5508
|
|
|
5489
|
-
pendingEditorState._readOnly = true;
|
|
5509
|
+
pendingEditorState._readOnly = true;
|
|
5490
5510
|
|
|
5491
5511
|
{
|
|
5492
5512
|
handleDEVOnlyPendingUpdateGuarantees(pendingEditorState);
|
|
@@ -5827,8 +5847,17 @@ function updateEditor(editor, updateFn, options) {
|
|
|
5827
5847
|
beginUpdate(editor, updateFn, options);
|
|
5828
5848
|
}
|
|
5829
5849
|
}
|
|
5850
|
+
function internalGetActiveEditor() {
|
|
5851
|
+
return activeEditor;
|
|
5852
|
+
}
|
|
5830
5853
|
|
|
5831
|
-
|
|
5854
|
+
/**
|
|
5855
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
5856
|
+
*
|
|
5857
|
+
* This source code is licensed under the MIT license found in the
|
|
5858
|
+
* LICENSE file in the root directory of this source tree.
|
|
5859
|
+
*
|
|
5860
|
+
*/
|
|
5832
5861
|
function removeNode(nodeToRemove, restoreSelection, preserveEmptyParent) {
|
|
5833
5862
|
errorOnReadOnly();
|
|
5834
5863
|
const key = nodeToRemove.__key;
|
|
@@ -5895,6 +5924,7 @@ function $getNodeByKeyOrThrow(key) {
|
|
|
5895
5924
|
return node;
|
|
5896
5925
|
}
|
|
5897
5926
|
class LexicalNode {
|
|
5927
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5898
5928
|
// Flow doesn't support abstract classes unfortunately, so we can't _force_
|
|
5899
5929
|
// subclasses of Node to implement statics. All subclasses of Node should have
|
|
5900
5930
|
// a static getType and clone method though. We define getType and clone here so we can call it
|
|
@@ -5916,7 +5946,7 @@ class LexicalNode {
|
|
|
5916
5946
|
// @ts-expect-error
|
|
5917
5947
|
this.__type = this.constructor.getType();
|
|
5918
5948
|
this.__parent = null;
|
|
5919
|
-
$setNodeKey(this, key);
|
|
5949
|
+
$setNodeKey(this, key);
|
|
5920
5950
|
|
|
5921
5951
|
{
|
|
5922
5952
|
if (this.__type !== 'root') {
|
|
@@ -6385,52 +6415,11 @@ class LexicalNode {
|
|
|
6385
6415
|
|
|
6386
6416
|
exportDOM(editor) {
|
|
6387
6417
|
const element = this.createDOM(editor._config, editor);
|
|
6388
|
-
const serializedNode = this.exportJSON();
|
|
6389
|
-
element.setAttribute('data-lexical-node-type', this.__type);
|
|
6390
|
-
element.setAttribute('data-lexical-node-json', JSON.stringify(serializedNode));
|
|
6391
|
-
element.setAttribute('data-lexical-editor-key', editor._key);
|
|
6392
6418
|
return {
|
|
6393
6419
|
element
|
|
6394
6420
|
};
|
|
6395
6421
|
}
|
|
6396
6422
|
|
|
6397
|
-
static importDOM() {
|
|
6398
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6399
|
-
const proto = this.prototype.constructor;
|
|
6400
|
-
return {
|
|
6401
|
-
// Catch-all key because we don't know the nodeName of the element returned by exportDOM.
|
|
6402
|
-
'*': domNode => {
|
|
6403
|
-
if (!(domNode instanceof HTMLElement)) return null;
|
|
6404
|
-
const editorKey = domNode.getAttribute('data-lexical-editor-key');
|
|
6405
|
-
const nodeType = domNode.getAttribute('data-lexical-node-type');
|
|
6406
|
-
if (editorKey == null || nodeType == null) return null;
|
|
6407
|
-
const editor = getActiveEditor();
|
|
6408
|
-
|
|
6409
|
-
if (editorKey === editor.getKey() && nodeType === proto.getType()) {
|
|
6410
|
-
try {
|
|
6411
|
-
const json = domNode.getAttribute('data-lexical-node-json');
|
|
6412
|
-
|
|
6413
|
-
if (json != null) {
|
|
6414
|
-
const serializedNode = JSON.parse(json);
|
|
6415
|
-
const node = proto.importJSON(serializedNode);
|
|
6416
|
-
return {
|
|
6417
|
-
conversion: () => ({
|
|
6418
|
-
node
|
|
6419
|
-
}),
|
|
6420
|
-
// Max priority because of the 'data-lexical-node-type' attribute
|
|
6421
|
-
// matching the one on node klass guarantees a match.
|
|
6422
|
-
priority: 4
|
|
6423
|
-
}; // eslint-disable-next-line no-empty
|
|
6424
|
-
} // eslint-disable-next-line no-empty
|
|
6425
|
-
|
|
6426
|
-
} catch {}
|
|
6427
|
-
}
|
|
6428
|
-
|
|
6429
|
-
return null;
|
|
6430
|
-
}
|
|
6431
|
-
};
|
|
6432
|
-
}
|
|
6433
|
-
|
|
6434
6423
|
exportJSON() {
|
|
6435
6424
|
{
|
|
6436
6425
|
throw Error(`exportJSON: base method not extended`);
|
|
@@ -6649,7 +6638,7 @@ class DecoratorNode extends LexicalNode {
|
|
|
6649
6638
|
super(key);
|
|
6650
6639
|
}
|
|
6651
6640
|
|
|
6652
|
-
decorate(editor) {
|
|
6641
|
+
decorate(editor, config) {
|
|
6653
6642
|
{
|
|
6654
6643
|
throw Error(`decorate: base method not extended`);
|
|
6655
6644
|
}
|
|
@@ -7118,7 +7107,7 @@ class ElementNode extends LexicalNode {
|
|
|
7118
7107
|
return false;
|
|
7119
7108
|
}
|
|
7120
7109
|
|
|
7121
|
-
excludeFromCopy() {
|
|
7110
|
+
excludeFromCopy(destination) {
|
|
7122
7111
|
return false;
|
|
7123
7112
|
}
|
|
7124
7113
|
|
|
@@ -7561,7 +7550,9 @@ function setTextContent(nextText, dom, node) {
|
|
|
7561
7550
|
dom.textContent = text;
|
|
7562
7551
|
} else {
|
|
7563
7552
|
const nodeValue = firstChild.nodeValue;
|
|
7564
|
-
if (nodeValue !== text) if (isComposing) {
|
|
7553
|
+
if (nodeValue !== text) if (isComposing || IS_FIREFOX) {
|
|
7554
|
+
// We also use the diff composed text for general text in FF to avoid
|
|
7555
|
+
// the spellcheck red line from flickering.
|
|
7565
7556
|
const [index, remove, insert] = diffComposedText(nodeValue, text);
|
|
7566
7557
|
|
|
7567
7558
|
if (remove !== 0) {
|
|
@@ -8170,8 +8161,21 @@ function convertBringAttentionToElement(domNode) {
|
|
|
8170
8161
|
}
|
|
8171
8162
|
|
|
8172
8163
|
function convertTextDOMNode(domNode) {
|
|
8164
|
+
const {
|
|
8165
|
+
parentElement,
|
|
8166
|
+
textContent
|
|
8167
|
+
} = domNode;
|
|
8168
|
+
const textContentTrim = textContent.trim();
|
|
8169
|
+
const isPre = parentElement != null && parentElement.tagName.toLowerCase() === 'pre';
|
|
8170
|
+
|
|
8171
|
+
if (!isPre && textContentTrim.length === 0 && textContent.includes('\n')) {
|
|
8172
|
+
return {
|
|
8173
|
+
node: null
|
|
8174
|
+
};
|
|
8175
|
+
}
|
|
8176
|
+
|
|
8173
8177
|
return {
|
|
8174
|
-
node: $createTextNode(
|
|
8178
|
+
node: $createTextNode(textContent)
|
|
8175
8179
|
};
|
|
8176
8180
|
}
|
|
8177
8181
|
|
|
@@ -8384,10 +8388,11 @@ function initializeConversionCache(nodes) {
|
|
|
8384
8388
|
const conversionCache = new Map();
|
|
8385
8389
|
const handledConversions = new Set();
|
|
8386
8390
|
nodes.forEach(node => {
|
|
8387
|
-
// @ts-expect-error TODO Replace Class utility type with InstanceType
|
|
8388
|
-
|
|
8391
|
+
const importDOM = // @ts-expect-error TODO Replace Class utility type with InstanceType
|
|
8392
|
+
node.klass.importDOM != null ? // @ts-expect-error TODO Replace Class utility type with InstanceType
|
|
8393
|
+
node.klass.importDOM.bind(node.klass) : null;
|
|
8389
8394
|
|
|
8390
|
-
if (handledConversions.has(importDOM)) {
|
|
8395
|
+
if (importDOM == null || handledConversions.has(importDOM)) {
|
|
8391
8396
|
return;
|
|
8392
8397
|
}
|
|
8393
8398
|
|
|
@@ -8410,69 +8415,77 @@ function initializeConversionCache(nodes) {
|
|
|
8410
8415
|
return conversionCache;
|
|
8411
8416
|
}
|
|
8412
8417
|
|
|
8413
|
-
function createEditor(editorConfig
|
|
8414
|
-
const config = editorConfig;
|
|
8418
|
+
function createEditor(editorConfig) {
|
|
8419
|
+
const config = editorConfig || {};
|
|
8420
|
+
const activeEditor = internalGetActiveEditor();
|
|
8415
8421
|
const theme = config.theme || {};
|
|
8416
|
-
const parentEditor = config.parentEditor || null;
|
|
8422
|
+
const parentEditor = editorConfig === undefined ? activeEditor : config.parentEditor || null;
|
|
8417
8423
|
const disableEvents = config.disableEvents || false;
|
|
8418
8424
|
const editorState = createEmptyEditorState();
|
|
8425
|
+
const namespace = config.namespace || (parentEditor !== null ? parentEditor._config.namespace : createUID());
|
|
8419
8426
|
const initialEditorState = config.editorState;
|
|
8420
8427
|
const nodes = [RootNode, TextNode, LineBreakNode, ParagraphNode, ...(config.nodes || [])];
|
|
8421
8428
|
const onError = config.onError;
|
|
8422
8429
|
const isReadOnly = config.readOnly || false;
|
|
8423
|
-
|
|
8430
|
+
let registeredNodes;
|
|
8424
8431
|
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8432
|
+
if (editorConfig === undefined && activeEditor !== null) {
|
|
8433
|
+
registeredNodes = activeEditor._nodes;
|
|
8434
|
+
} else {
|
|
8435
|
+
registeredNodes = new Map();
|
|
8428
8436
|
|
|
8429
|
-
{
|
|
8430
|
-
const
|
|
8431
|
-
|
|
8432
|
-
if (name !== 'RootNode') {
|
|
8433
|
-
const proto = klass.prototype;
|
|
8434
|
-
['getType', 'clone'].forEach(method => {
|
|
8435
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
8436
|
-
if (!klass.hasOwnProperty(method)) {
|
|
8437
|
-
console.warn(`${name} must implement static "${method}" method`);
|
|
8438
|
-
}
|
|
8439
|
-
});
|
|
8437
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
8438
|
+
const klass = nodes[i]; // Ensure custom nodes implement required methods.
|
|
8440
8439
|
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
8445
|
-
|
|
8440
|
+
{
|
|
8441
|
+
const name = klass.name;
|
|
8442
|
+
|
|
8443
|
+
if (name !== 'RootNode') {
|
|
8444
|
+
const proto = klass.prototype;
|
|
8445
|
+
['getType', 'clone'].forEach(method => {
|
|
8446
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
8447
|
+
if (!klass.hasOwnProperty(method)) {
|
|
8448
|
+
console.warn(`${name} must implement static "${method}" method`);
|
|
8449
|
+
}
|
|
8450
|
+
});
|
|
8446
8451
|
|
|
8447
|
-
|
|
8448
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
8449
|
-
|
|
8450
|
-
console.warn(`${
|
|
8452
|
+
if ( // eslint-disable-next-line no-prototype-builtins
|
|
8453
|
+
!klass.hasOwnProperty('importDOM') && // eslint-disable-next-line no-prototype-builtins
|
|
8454
|
+
klass.hasOwnProperty('exportDOM')) {
|
|
8455
|
+
console.warn(`${name} should implement "importDOM" if using a custom "exportDOM" method to ensure HTML serialization (important for copy & paste) works as expected`);
|
|
8451
8456
|
}
|
|
8452
|
-
}
|
|
8453
8457
|
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
+
if (proto instanceof DecoratorNode) {
|
|
8459
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
8460
|
+
if (!proto.hasOwnProperty('decorate')) {
|
|
8461
|
+
console.warn(`${this.constructor.name} must implement "decorate" method`);
|
|
8462
|
+
}
|
|
8463
|
+
}
|
|
8458
8464
|
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8465
|
+
if ( // eslint-disable-next-line no-prototype-builtins
|
|
8466
|
+
!klass.hasOwnProperty('importJSON')) {
|
|
8467
|
+
console.warn(`${name} should implement "importJSON" method to ensure JSON and default HTML serialization works as expected`);
|
|
8468
|
+
}
|
|
8469
|
+
|
|
8470
|
+
if ( // eslint-disable-next-line no-prototype-builtins
|
|
8471
|
+
!proto.hasOwnProperty('exportJSON')) {
|
|
8472
|
+
console.warn(`${name} should implement "exportJSON" method to ensure JSON and default HTML serialization works as expected`);
|
|
8473
|
+
}
|
|
8462
8474
|
}
|
|
8463
|
-
}
|
|
8464
|
-
} // @ts-expect-error TODO Replace Class utility type with InstanceType
|
|
8475
|
+
} // @ts-expect-error TODO Replace Class utility type with InstanceType
|
|
8465
8476
|
|
|
8466
8477
|
|
|
8467
|
-
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
|
|
8471
|
-
|
|
8478
|
+
const type = klass.getType();
|
|
8479
|
+
registeredNodes.set(type, {
|
|
8480
|
+
klass,
|
|
8481
|
+
transforms: new Set()
|
|
8482
|
+
});
|
|
8483
|
+
}
|
|
8472
8484
|
}
|
|
8473
8485
|
|
|
8474
8486
|
const editor = new LexicalEditor(editorState, parentEditor, registeredNodes, {
|
|
8475
8487
|
disableEvents,
|
|
8488
|
+
namespace,
|
|
8476
8489
|
theme
|
|
8477
8490
|
}, onError, initializeConversionCache(registeredNodes), isReadOnly);
|
|
8478
8491
|
|
|
@@ -8629,9 +8642,7 @@ class LexicalEditor {
|
|
|
8629
8642
|
};
|
|
8630
8643
|
}
|
|
8631
8644
|
|
|
8632
|
-
registerNodeTransform(
|
|
8633
|
-
// declaration below guarantees these are LexicalNodes.
|
|
8634
|
-
klass, listener) {
|
|
8645
|
+
registerNodeTransform(klass, listener) {
|
|
8635
8646
|
// @ts-expect-error TODO Replace Class utility type with InstanceType
|
|
8636
8647
|
const type = klass.getType();
|
|
8637
8648
|
|
|
@@ -8653,7 +8664,7 @@ class LexicalEditor {
|
|
|
8653
8664
|
|
|
8654
8665
|
hasNodes(nodes) {
|
|
8655
8666
|
for (let i = 0; i < nodes.length; i++) {
|
|
8656
|
-
const klass = nodes[i]; // @ts-expect-error
|
|
8667
|
+
const klass = nodes[i]; // @ts-expect-error
|
|
8657
8668
|
|
|
8658
8669
|
const type = klass.getType();
|
|
8659
8670
|
|
|
@@ -8822,7 +8833,7 @@ class LexicalEditor {
|
|
|
8822
8833
|
|
|
8823
8834
|
toJSON() {
|
|
8824
8835
|
return {
|
|
8825
|
-
editorState: this._editorState
|
|
8836
|
+
editorState: this._editorState.toJSON()
|
|
8826
8837
|
};
|
|
8827
8838
|
}
|
|
8828
8839
|
|
|
@@ -8835,7 +8846,7 @@ class LexicalEditor {
|
|
|
8835
8846
|
* LICENSE file in the root directory of this source tree.
|
|
8836
8847
|
*
|
|
8837
8848
|
*/
|
|
8838
|
-
const VERSION = '0.3.
|
|
8849
|
+
const VERSION = '0.3.5';
|
|
8839
8850
|
|
|
8840
8851
|
/**
|
|
8841
8852
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -8885,11 +8896,11 @@ function $isGridRowNode(node) {
|
|
|
8885
8896
|
return node instanceof GridRowNode;
|
|
8886
8897
|
}
|
|
8887
8898
|
|
|
8888
|
-
exports.$createGridSelection = $
|
|
8899
|
+
exports.$createGridSelection = $createGridSelection;
|
|
8889
8900
|
exports.$createLineBreakNode = $createLineBreakNode;
|
|
8890
|
-
exports.$createNodeSelection = $
|
|
8901
|
+
exports.$createNodeSelection = $createNodeSelection;
|
|
8891
8902
|
exports.$createParagraphNode = $createParagraphNode;
|
|
8892
|
-
exports.$createRangeSelection = $
|
|
8903
|
+
exports.$createRangeSelection = $createRangeSelection;
|
|
8893
8904
|
exports.$createTextNode = $createTextNode;
|
|
8894
8905
|
exports.$getDecoratorNode = $getDecoratorNode;
|
|
8895
8906
|
exports.$getNearestNodeFromDOMNode = $getNearestNodeFromDOMNode;
|