lexical 0.1.13 → 0.1.16
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.d.ts +13 -13
- package/Lexical.dev.js +177 -57
- package/Lexical.js.flow +14 -24
- package/Lexical.prod.js +152 -148
- package/LexicalCodeHighlightNode.dev.js +4 -24
- package/LexicalCodeHighlightNode.prod.js +3 -3
- package/LexicalCodeNode.dev.js +2 -17
- package/LexicalCodeNode.prod.js +6 -6
- package/LexicalExtendedNodes.dev.js +2 -2
- package/LexicalExtendedNodes.prod.js +2 -2
- package/LexicalHeadingNode.dev.js +2 -17
- package/LexicalHeadingNode.prod.js +4 -3
- package/LexicalLinkNode.dev.js +2 -17
- package/LexicalLinkNode.prod.js +3 -3
- package/LexicalQuoteNode.dev.js +2 -17
- package/LexicalQuoteNode.prod.js +3 -3
- package/README.md +1 -1
- package/package.json +1 -1
- package/HashtagNode.js +0 -9
- package/HashtagNode.js.flow +0 -27
- package/LexicalHashtagNode.dev.js +0 -111
- package/LexicalHashtagNode.prod.js +0 -9
package/Lexical.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ import {Class, $ReadOnly} from 'utility-types';
|
|
|
14
14
|
type ErrorHandler = (error: Error) => void;
|
|
15
15
|
type MutationListeners = Map<MutationListener, Class<LexicalNode>>;
|
|
16
16
|
export type NodeMutation = 'created' | 'destroyed';
|
|
17
|
-
export type ErrorListener = (error: Error) => void;
|
|
18
17
|
type UpdateListener = (arg0: {
|
|
19
18
|
tags: Set<string>;
|
|
20
19
|
prevEditorState: EditorState;
|
|
@@ -40,7 +39,6 @@ export type ReadOnlyListener = (readOnly: boolean) => void;
|
|
|
40
39
|
type CommandPayload = any;
|
|
41
40
|
type Listeners = {
|
|
42
41
|
decorator: Set<DecoratorListener>;
|
|
43
|
-
error: Set<ErrorListener>;
|
|
44
42
|
mutation: MutationListeners;
|
|
45
43
|
textcontent: Set<TextContentListener>;
|
|
46
44
|
root: Set<RootListener>;
|
|
@@ -99,7 +97,7 @@ export declare class LexicalEditor {
|
|
|
99
97
|
klass: Class<LexicalNode>,
|
|
100
98
|
listener: MutationListener,
|
|
101
99
|
): () => void;
|
|
102
|
-
|
|
100
|
+
addNodeTransform<T extends LexicalNode>(
|
|
103
101
|
klass: Class<T>,
|
|
104
102
|
listener: Transform<T>,
|
|
105
103
|
): () => void;
|
|
@@ -146,17 +144,9 @@ export type EditorThemeClasses = {
|
|
|
146
144
|
//@ts-expect-error
|
|
147
145
|
list?: {
|
|
148
146
|
ul?: EditorThemeClassName;
|
|
149
|
-
|
|
150
|
-
ul2?: EditorThemeClassName;
|
|
151
|
-
ul3?: EditorThemeClassName;
|
|
152
|
-
ul4?: EditorThemeClassName;
|
|
153
|
-
ul5?: EditorThemeClassName;
|
|
147
|
+
ulDepth?: Array<EditorThemeClassName>;
|
|
154
148
|
ol?: EditorThemeClassName;
|
|
155
|
-
|
|
156
|
-
ol2?: EditorThemeClassName;
|
|
157
|
-
ol3?: EditorThemeClassName;
|
|
158
|
-
ol4?: EditorThemeClassName;
|
|
159
|
-
ol5?: EditorThemeClassName;
|
|
149
|
+
olDepth?: Array<EditorThemeClassName>;
|
|
160
150
|
listitem?: EditorThemeClassName;
|
|
161
151
|
nested?: {
|
|
162
152
|
list?: EditorThemeClassName;
|
|
@@ -372,18 +362,28 @@ interface BaseSelection {
|
|
|
372
362
|
insertRawText(text: string): void;
|
|
373
363
|
is(selection: null | RangeSelection | NodeSelection | GridSelection): boolean;
|
|
374
364
|
}
|
|
365
|
+
export type GridSelectionShape = {
|
|
366
|
+
fromX: number;
|
|
367
|
+
fromY: number;
|
|
368
|
+
toX: number;
|
|
369
|
+
toY: number;
|
|
370
|
+
};
|
|
375
371
|
export declare class GridSelection {
|
|
376
372
|
gridKey: NodeKey;
|
|
377
373
|
anchorCellKey: NodeKey;
|
|
374
|
+
anchor: PointType;
|
|
378
375
|
focusCellKey: NodeKey;
|
|
376
|
+
focus: PointType;
|
|
379
377
|
dirty: boolean;
|
|
380
378
|
constructor(gridKey: NodeKey, anchorCellKey: NodeKey, focusCellKey: NodeKey);
|
|
381
379
|
is(selection: null | RangeSelection | NodeSelection | GridSelection): boolean;
|
|
382
380
|
set(gridKey: NodeKey, anchorCellKey: NodeKey, focusCellKey: NodeKey): void;
|
|
383
381
|
clone(): GridSelection;
|
|
384
382
|
extract(): Array<LexicalNode>;
|
|
383
|
+
isCollapsed(): boolean;
|
|
385
384
|
insertRawText(): void;
|
|
386
385
|
insertText(): void;
|
|
386
|
+
getShape(): GridSelectionShape;
|
|
387
387
|
getNodes(): Array<LexicalNode>;
|
|
388
388
|
getTextContent(): string;
|
|
389
389
|
}
|
package/Lexical.dev.js
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
*
|
|
15
15
|
*
|
|
16
16
|
*/
|
|
17
|
-
const getSelection = window.getSelection;
|
|
17
|
+
const getSelection = () => window.getSelection();
|
|
18
|
+
|
|
18
19
|
var getDOMSelection = getSelection;
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -136,12 +137,19 @@ const scheduleMicroTask = typeof queueMicrotask === 'function' ? queueMicrotask
|
|
|
136
137
|
// No window prefix intended (#1400)
|
|
137
138
|
Promise.resolve().then(fn);
|
|
138
139
|
};
|
|
140
|
+
|
|
141
|
+
function isSelectionCapturedInDecoratorInput(anchorDOM) {
|
|
142
|
+
const activeElement = document.activeElement;
|
|
143
|
+
const nodeName = activeElement !== null ? activeElement.nodeName : null;
|
|
144
|
+
return !$isDecoratorNode($getNearestNodeFromDOMNode(anchorDOM)) || nodeName !== 'INPUT' && nodeName !== 'TEXTAREA';
|
|
145
|
+
}
|
|
146
|
+
|
|
139
147
|
function isSelectionWithinEditor(editor, anchorDOM, focusDOM) {
|
|
140
148
|
const rootElement = editor.getRootElement();
|
|
141
149
|
|
|
142
150
|
try {
|
|
143
151
|
return rootElement !== null && rootElement.contains(anchorDOM) && rootElement.contains(focusDOM) && // Ignore if selection is within nested editor
|
|
144
|
-
anchorDOM !== null && getNearestEditorFromDOMNode(anchorDOM) === editor;
|
|
152
|
+
anchorDOM !== null && isSelectionCapturedInDecoratorInput(anchorDOM) && getNearestEditorFromDOMNode(anchorDOM) === editor;
|
|
145
153
|
} catch (error) {
|
|
146
154
|
return false;
|
|
147
155
|
}
|
|
@@ -461,7 +469,7 @@ function getEditorsToPropagate(editor) {
|
|
|
461
469
|
function createUID() {
|
|
462
470
|
return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
|
|
463
471
|
}
|
|
464
|
-
function $updateSelectedTextFromDOM(editor,
|
|
472
|
+
function $updateSelectedTextFromDOM(editor, compositionEndEvent) {
|
|
465
473
|
// Update the text content with the latest composition text
|
|
466
474
|
const domSelection = getDOMSelection();
|
|
467
475
|
|
|
@@ -469,8 +477,8 @@ function $updateSelectedTextFromDOM(editor, compositionEnd) {
|
|
|
469
477
|
return;
|
|
470
478
|
}
|
|
471
479
|
|
|
472
|
-
const
|
|
473
|
-
|
|
480
|
+
const anchorNode = domSelection.anchorNode;
|
|
481
|
+
let {
|
|
474
482
|
anchorOffset,
|
|
475
483
|
focusOffset
|
|
476
484
|
} = domSelection;
|
|
@@ -479,7 +487,17 @@ function $updateSelectedTextFromDOM(editor, compositionEnd) {
|
|
|
479
487
|
const node = $getNearestNodeFromDOMNode(anchorNode);
|
|
480
488
|
|
|
481
489
|
if ($isTextNode(node)) {
|
|
482
|
-
|
|
490
|
+
let textContent = anchorNode.nodeValue;
|
|
491
|
+
const data = compositionEndEvent !== null && compositionEndEvent.data; // Data is intentionally truthy, as we check for boolean, null and empty string.
|
|
492
|
+
|
|
493
|
+
if (textContent === ZERO_WIDTH_CHAR && data) {
|
|
494
|
+
const offset = data.length;
|
|
495
|
+
textContent = data;
|
|
496
|
+
anchorOffset = offset;
|
|
497
|
+
focusOffset = offset;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
$updateTextNodeFromDOMContent(node, textContent, anchorOffset, focusOffset, compositionEndEvent !== null);
|
|
483
501
|
}
|
|
484
502
|
}
|
|
485
503
|
}
|
|
@@ -711,12 +729,18 @@ function getCachedClassNameArray(classNamesTheme, classNameThemeType) {
|
|
|
711
729
|
|
|
712
730
|
return classNames;
|
|
713
731
|
}
|
|
714
|
-
function setMutatedNode(mutatedNodes, registeredNodes, node, mutation) {
|
|
715
|
-
|
|
732
|
+
function setMutatedNode(mutatedNodes, registeredNodes, mutationListeners, node, mutation) {
|
|
733
|
+
if (mutationListeners.size === 0) {
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
const nodeType = node.__type;
|
|
738
|
+
const nodeKey = node.__key;
|
|
739
|
+
const registeredNode = registeredNodes.get(nodeType);
|
|
716
740
|
|
|
717
741
|
if (registeredNode === undefined) {
|
|
718
742
|
{
|
|
719
|
-
throw Error(`Type ${
|
|
743
|
+
throw Error(`Type ${nodeType} not in registeredNodes`);
|
|
720
744
|
}
|
|
721
745
|
}
|
|
722
746
|
|
|
@@ -728,7 +752,9 @@ function setMutatedNode(mutatedNodes, registeredNodes, node, mutation) {
|
|
|
728
752
|
mutatedNodes.set(klass, mutatedNodesByType);
|
|
729
753
|
}
|
|
730
754
|
|
|
731
|
-
mutatedNodesByType.
|
|
755
|
+
if (!mutatedNodesByType.has(nodeKey)) {
|
|
756
|
+
mutatedNodesByType.set(nodeKey, mutation);
|
|
757
|
+
}
|
|
732
758
|
}
|
|
733
759
|
function $nodesOfType(klass) {
|
|
734
760
|
const editorState = getActiveEditorState();
|
|
@@ -789,6 +815,11 @@ function $getDecoratorNode(focus, isBackward) {
|
|
|
789
815
|
|
|
790
816
|
return null;
|
|
791
817
|
}
|
|
818
|
+
function isFirefoxClipboardEvents() {
|
|
819
|
+
const event = window.event;
|
|
820
|
+
const inputType = event && event.inputType;
|
|
821
|
+
return inputType === 'insertFromPaste' || inputType === 'insertFromPasteAsQuotation';
|
|
822
|
+
}
|
|
792
823
|
|
|
793
824
|
/**
|
|
794
825
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -1004,9 +1035,24 @@ function removeNode(nodeToRemove, restoreSelection) {
|
|
|
1004
1035
|
$updateElementSelectionOnCreateDeleteNode(selection, parent, index, -1);
|
|
1005
1036
|
}
|
|
1006
1037
|
|
|
1007
|
-
if (parent !== null && !$isRootNode(parent) && !parent.canBeEmpty() && parent.
|
|
1038
|
+
if (parent !== null && !$isRootNode(parent) && !parent.canBeEmpty() && parent.isEmpty()) {
|
|
1008
1039
|
removeNode(parent, restoreSelection);
|
|
1009
1040
|
}
|
|
1041
|
+
|
|
1042
|
+
if (parent !== null && $isRootNode(parent) && parent.isEmpty()) {
|
|
1043
|
+
parent.selectEnd();
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
function $getNodeByKeyOrThrow(key) {
|
|
1047
|
+
const node = $getNodeByKey(key);
|
|
1048
|
+
|
|
1049
|
+
if (node === null) {
|
|
1050
|
+
{
|
|
1051
|
+
throw Error(`Expected node with key ${key} to exist but it's not in the nodeMap.`);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
return node;
|
|
1010
1056
|
}
|
|
1011
1057
|
class LexicalNode {
|
|
1012
1058
|
// Flow doesn't support abstract classes unfortunately, so we can't _force_
|
|
@@ -1438,8 +1484,7 @@ class LexicalNode {
|
|
|
1438
1484
|
|
|
1439
1485
|
isComposing() {
|
|
1440
1486
|
return this.__key === $getCompositionKey();
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1487
|
+
}
|
|
1443
1488
|
|
|
1444
1489
|
getLatest() {
|
|
1445
1490
|
const latest = $getNodeByKey(this.__key);
|
|
@@ -1747,18 +1792,6 @@ class LexicalNode {
|
|
|
1747
1792
|
|
|
1748
1793
|
}
|
|
1749
1794
|
|
|
1750
|
-
function $getNodeByKeyOrThrow(key) {
|
|
1751
|
-
const node = $getNodeByKey(key);
|
|
1752
|
-
|
|
1753
|
-
if (node === null) {
|
|
1754
|
-
{
|
|
1755
|
-
throw Error(`Expected node with key ${key} to exist but it's not in the nodeMap.`);
|
|
1756
|
-
}
|
|
1757
|
-
}
|
|
1758
|
-
|
|
1759
|
-
return node;
|
|
1760
|
-
}
|
|
1761
|
-
|
|
1762
1795
|
function errorOnTypeKlassMismatch(type, klass) {
|
|
1763
1796
|
const registeredNode = getActiveEditor()._nodes.get(type); // Common error - split in its own invariant
|
|
1764
1797
|
|
|
@@ -2220,6 +2253,7 @@ let activeEditor$1;
|
|
|
2220
2253
|
let activeEditorNodes;
|
|
2221
2254
|
let treatAllNodesAsDirty = false;
|
|
2222
2255
|
let activeEditorStateReadOnly = false;
|
|
2256
|
+
let activeMutationListeners;
|
|
2223
2257
|
let activeTextDirection = null;
|
|
2224
2258
|
let activeDirtyElements;
|
|
2225
2259
|
let activeDirtyLeaves;
|
|
@@ -2248,7 +2282,7 @@ function destroyNode(key, parentDOM) {
|
|
|
2248
2282
|
}
|
|
2249
2283
|
|
|
2250
2284
|
if (node !== undefined) {
|
|
2251
|
-
setMutatedNode(mutatedNodes, activeEditorNodes, node, 'destroyed');
|
|
2285
|
+
setMutatedNode(mutatedNodes, activeEditorNodes, activeMutationListeners, node, 'destroyed');
|
|
2252
2286
|
}
|
|
2253
2287
|
}
|
|
2254
2288
|
|
|
@@ -2386,7 +2420,7 @@ function createNode(key, parentDOM, insertDOM) {
|
|
|
2386
2420
|
Object.freeze(node);
|
|
2387
2421
|
}
|
|
2388
2422
|
|
|
2389
|
-
setMutatedNode(mutatedNodes, activeEditorNodes, node, 'created');
|
|
2423
|
+
setMutatedNode(mutatedNodes, activeEditorNodes, activeMutationListeners, node, 'created');
|
|
2390
2424
|
return dom;
|
|
2391
2425
|
}
|
|
2392
2426
|
|
|
@@ -2593,6 +2627,10 @@ function reconcileNode(key, parentDOM) {
|
|
|
2593
2627
|
}
|
|
2594
2628
|
|
|
2595
2629
|
return dom;
|
|
2630
|
+
}
|
|
2631
|
+
|
|
2632
|
+
if (prevNode !== nextNode && isDirty) {
|
|
2633
|
+
setMutatedNode(mutatedNodes, activeEditorNodes, activeMutationListeners, nextNode, 'updated');
|
|
2596
2634
|
} // Update node. If it returns true, we need to unmount and re-create the node
|
|
2597
2635
|
|
|
2598
2636
|
|
|
@@ -2777,6 +2815,7 @@ function reconcileRoot(prevEditorState, nextEditorState, editor, dirtyType, dirt
|
|
|
2777
2815
|
activeEditor$1 = editor;
|
|
2778
2816
|
activeEditorConfig = editor._config;
|
|
2779
2817
|
activeEditorNodes = editor._nodes;
|
|
2818
|
+
activeMutationListeners = activeEditor$1._listeners.mutation;
|
|
2780
2819
|
activeDirtyElements = dirtyElements;
|
|
2781
2820
|
activeDirtyLeaves = dirtyLeaves;
|
|
2782
2821
|
activePrevNodeMap = prevEditorState._nodeMap;
|
|
@@ -3655,6 +3694,7 @@ function $flushMutations(editor, mutations, observer) {
|
|
|
3655
3694
|
|
|
3656
3695
|
const currentEditorState = editor._editorState;
|
|
3657
3696
|
let shouldRevertSelection = false;
|
|
3697
|
+
let possibleTextForFirefoxPaste = '';
|
|
3658
3698
|
|
|
3659
3699
|
for (let i = 0; i < mutations.length; i++) {
|
|
3660
3700
|
const mutation = mutations[i];
|
|
@@ -3685,7 +3725,15 @@ function $flushMutations(editor, mutations, observer) {
|
|
|
3685
3725
|
const node = getNodeFromDOMNode(addedDOM);
|
|
3686
3726
|
const parentDOM = addedDOM.parentNode;
|
|
3687
3727
|
|
|
3688
|
-
if (parentDOM != null && node === null) {
|
|
3728
|
+
if (parentDOM != null && node === null && (addedDOM.nodeName !== 'BR' || !isManagedLineBreak(addedDOM, parentDOM, editor))) {
|
|
3729
|
+
if (IS_FIREFOX) {
|
|
3730
|
+
const possibleText = addedDOM.innerText || addedDOM.nodeValue;
|
|
3731
|
+
|
|
3732
|
+
if (possibleText) {
|
|
3733
|
+
possibleTextForFirefoxPaste += possibleText;
|
|
3734
|
+
}
|
|
3735
|
+
}
|
|
3736
|
+
|
|
3689
3737
|
parentDOM.removeChild(addedDOM);
|
|
3690
3738
|
}
|
|
3691
3739
|
}
|
|
@@ -3780,13 +3828,17 @@ function $flushMutations(editor, mutations, observer) {
|
|
|
3780
3828
|
observer.takeRecords();
|
|
3781
3829
|
}
|
|
3782
3830
|
|
|
3783
|
-
|
|
3784
|
-
const selection = $getSelection() || getLastSelection(editor);
|
|
3831
|
+
const selection = $getSelection() || getLastSelection(editor);
|
|
3785
3832
|
|
|
3786
|
-
|
|
3833
|
+
if (selection !== null) {
|
|
3834
|
+
if (shouldRevertSelection) {
|
|
3787
3835
|
selection.dirty = true;
|
|
3788
3836
|
$setSelection(selection);
|
|
3789
3837
|
}
|
|
3838
|
+
|
|
3839
|
+
if (IS_FIREFOX && isFirefoxClipboardEvents()) {
|
|
3840
|
+
selection.insertRawText(possibleTextForFirefoxPaste);
|
|
3841
|
+
}
|
|
3790
3842
|
}
|
|
3791
3843
|
});
|
|
3792
3844
|
} finally {
|
|
@@ -3997,7 +4049,7 @@ class NodeSelection {
|
|
|
3997
4049
|
return this.getNodes();
|
|
3998
4050
|
}
|
|
3999
4051
|
|
|
4000
|
-
insertRawText() {// Do nothing?
|
|
4052
|
+
insertRawText(text) {// Do nothing?
|
|
4001
4053
|
}
|
|
4002
4054
|
|
|
4003
4055
|
insertText() {// Do nothing?
|
|
@@ -4037,7 +4089,9 @@ class GridSelection {
|
|
|
4037
4089
|
constructor(gridKey, anchorCellKey, focusCellKey) {
|
|
4038
4090
|
this.gridKey = gridKey;
|
|
4039
4091
|
this.anchorCellKey = anchorCellKey;
|
|
4092
|
+
this.anchor = $createPoint(anchorCellKey, 0, 'element');
|
|
4040
4093
|
this.focusCellKey = focusCellKey;
|
|
4094
|
+
this.focus = $createPoint(focusCellKey, 0, 'element');
|
|
4041
4095
|
this.dirty = false;
|
|
4042
4096
|
}
|
|
4043
4097
|
|
|
@@ -4060,18 +4114,90 @@ class GridSelection {
|
|
|
4060
4114
|
return new GridSelection(this.gridKey, this.anchorCellKey, this.focusCellKey);
|
|
4061
4115
|
}
|
|
4062
4116
|
|
|
4117
|
+
isCollapsed() {
|
|
4118
|
+
return false;
|
|
4119
|
+
}
|
|
4120
|
+
|
|
4063
4121
|
extract() {
|
|
4064
4122
|
return this.getNodes();
|
|
4065
4123
|
}
|
|
4066
4124
|
|
|
4067
|
-
insertRawText() {// Do nothing?
|
|
4125
|
+
insertRawText(text) {// Do nothing?
|
|
4068
4126
|
}
|
|
4069
4127
|
|
|
4070
4128
|
insertText() {// Do nothing?
|
|
4071
4129
|
}
|
|
4072
4130
|
|
|
4131
|
+
getShape() {
|
|
4132
|
+
const anchorCellNode = $getNodeByKey(this.anchorCellKey);
|
|
4133
|
+
|
|
4134
|
+
if (!anchorCellNode) {
|
|
4135
|
+
throw Error(`getNodes: expected to find AnchorNode`);
|
|
4136
|
+
}
|
|
4137
|
+
|
|
4138
|
+
const anchorCellNodeIndex = anchorCellNode.getIndexWithinParent();
|
|
4139
|
+
const anchorCelRoweIndex = anchorCellNode.getParentOrThrow().getIndexWithinParent();
|
|
4140
|
+
const focusCellNode = $getNodeByKey(this.focusCellKey);
|
|
4141
|
+
|
|
4142
|
+
if (!focusCellNode) {
|
|
4143
|
+
throw Error(`getNodes: expected to find FocusNode`);
|
|
4144
|
+
}
|
|
4145
|
+
|
|
4146
|
+
const focusCellNodeIndex = focusCellNode.getIndexWithinParent();
|
|
4147
|
+
const focusCellRowIndex = focusCellNode.getParentOrThrow().getIndexWithinParent();
|
|
4148
|
+
const startX = Math.min(anchorCellNodeIndex, focusCellNodeIndex);
|
|
4149
|
+
const stopX = Math.max(anchorCellNodeIndex, focusCellNodeIndex);
|
|
4150
|
+
const startY = Math.min(anchorCelRoweIndex, focusCellRowIndex);
|
|
4151
|
+
const stopY = Math.max(anchorCelRoweIndex, focusCellRowIndex);
|
|
4152
|
+
return {
|
|
4153
|
+
fromX: Math.min(startX, stopX),
|
|
4154
|
+
fromY: Math.min(startY, stopY),
|
|
4155
|
+
toX: Math.max(startX, stopX),
|
|
4156
|
+
toY: Math.max(startY, stopY)
|
|
4157
|
+
};
|
|
4158
|
+
}
|
|
4159
|
+
|
|
4073
4160
|
getNodes() {
|
|
4074
|
-
const nodes = [];
|
|
4161
|
+
const nodes = [];
|
|
4162
|
+
const {
|
|
4163
|
+
fromX,
|
|
4164
|
+
fromY,
|
|
4165
|
+
toX,
|
|
4166
|
+
toY
|
|
4167
|
+
} = this.getShape();
|
|
4168
|
+
const gridNode = $getNodeByKey(this.gridKey);
|
|
4169
|
+
|
|
4170
|
+
if (!$isGridNode(gridNode)) {
|
|
4171
|
+
{
|
|
4172
|
+
throw Error(`getNodes: expected to find GridNode`);
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
|
|
4176
|
+
const gridRowNodes = gridNode.getChildren();
|
|
4177
|
+
|
|
4178
|
+
for (let r = fromY; r <= toY; r++) {
|
|
4179
|
+
const gridRowNode = gridRowNodes[r];
|
|
4180
|
+
|
|
4181
|
+
if (!$isGridRowNode(gridRowNode)) {
|
|
4182
|
+
{
|
|
4183
|
+
throw Error(`getNodes: expected to find GridRowNode`);
|
|
4184
|
+
}
|
|
4185
|
+
}
|
|
4186
|
+
|
|
4187
|
+
const gridCellNodes = gridRowNode.getChildren();
|
|
4188
|
+
|
|
4189
|
+
for (let c = fromX; c <= toX; c++) {
|
|
4190
|
+
const gridCellNode = gridCellNodes[c];
|
|
4191
|
+
|
|
4192
|
+
if (!$isGridCellNode(gridCellNode)) {
|
|
4193
|
+
{
|
|
4194
|
+
throw Error(`getNodes: expected to find GridCellNode`);
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4197
|
+
|
|
4198
|
+
nodes.push(gridCellNode);
|
|
4199
|
+
}
|
|
4200
|
+
}
|
|
4075
4201
|
|
|
4076
4202
|
return nodes;
|
|
4077
4203
|
}
|
|
@@ -4838,6 +4964,9 @@ class RangeSelection {
|
|
|
4838
4964
|
if ($isElementNode(target) && !$isElementNode(sibling)) {
|
|
4839
4965
|
target.append(sibling);
|
|
4840
4966
|
target = sibling;
|
|
4967
|
+
} else if (!$isElementNode(target) && !$isElementNode(sibling)) {
|
|
4968
|
+
target.insertBefore(sibling);
|
|
4969
|
+
target = sibling;
|
|
4841
4970
|
} else {
|
|
4842
4971
|
if ($isElementNode(sibling) && !sibling.canInsertAfter(target)) {
|
|
4843
4972
|
const prevParentClone = prevParent.constructor.clone(prevParent);
|
|
@@ -5444,7 +5573,7 @@ function internalCreateSelection(editor) {
|
|
|
5444
5573
|
const lastSelection = currentEditorState._selection;
|
|
5445
5574
|
const domSelection = getDOMSelection();
|
|
5446
5575
|
|
|
5447
|
-
if ($isNodeSelection(lastSelection)) {
|
|
5576
|
+
if ($isNodeSelection(lastSelection) || $isGridSelection(lastSelection)) {
|
|
5448
5577
|
return lastSelection.clone();
|
|
5449
5578
|
}
|
|
5450
5579
|
|
|
@@ -6275,7 +6404,7 @@ class RootNode extends ElementNode {
|
|
|
6275
6404
|
}
|
|
6276
6405
|
}
|
|
6277
6406
|
|
|
6278
|
-
insertBefore() {
|
|
6407
|
+
insertBefore(nodeToInsert) {
|
|
6279
6408
|
{
|
|
6280
6409
|
throw Error(`insertBefore: cannot be called on root nodes`);
|
|
6281
6410
|
}
|
|
@@ -6491,7 +6620,12 @@ function $canRemoveText(anchorNode, focusNode) {
|
|
|
6491
6620
|
function onBeforeInput(event, editor) {
|
|
6492
6621
|
const inputType = event.inputType; // We let the browser do its own thing for composition.
|
|
6493
6622
|
|
|
6494
|
-
if (inputType === 'deleteCompositionText' || inputType === 'insertCompositionText'
|
|
6623
|
+
if (inputType === 'deleteCompositionText' || inputType === 'insertCompositionText' || // If we're pasting in FF, we shouldn't get this event
|
|
6624
|
+
// as the `paste` event should have triggered, unless the
|
|
6625
|
+
// user has dom.event.clipboardevents.enabled disabled in
|
|
6626
|
+
// about:config. In that case, we need to process the
|
|
6627
|
+
// pasted content in the DOM mutation phase.
|
|
6628
|
+
IS_FIREFOX && isFirefoxClipboardEvents()) {
|
|
6495
6629
|
return;
|
|
6496
6630
|
}
|
|
6497
6631
|
|
|
@@ -6685,7 +6819,7 @@ function onInput(event, editor) {
|
|
|
6685
6819
|
if (data != null && $isRangeSelection(selection) && $shouldPreventDefaultAndInsertText(selection, data, false)) {
|
|
6686
6820
|
editor.execCommand('insertText', data);
|
|
6687
6821
|
} else {
|
|
6688
|
-
$updateSelectedTextFromDOM(editor,
|
|
6822
|
+
$updateSelectedTextFromDOM(editor, null);
|
|
6689
6823
|
} // Also flush any other mutations that might have occured
|
|
6690
6824
|
// since the change.
|
|
6691
6825
|
|
|
@@ -6713,7 +6847,7 @@ function onCompositionStart(event, editor) {
|
|
|
6713
6847
|
});
|
|
6714
6848
|
}
|
|
6715
6849
|
|
|
6716
|
-
function
|
|
6850
|
+
function onCompositionEnd(event, editor) {
|
|
6717
6851
|
editor.update(() => {
|
|
6718
6852
|
const compositionKey = editor._compositionKey;
|
|
6719
6853
|
$setCompositionKey(null); // Handle termination of composition, as it can sometimes
|
|
@@ -6730,24 +6864,10 @@ function onCompositionEndInternal(event, editor) {
|
|
|
6730
6864
|
return;
|
|
6731
6865
|
}
|
|
6732
6866
|
|
|
6733
|
-
$updateSelectedTextFromDOM(editor,
|
|
6867
|
+
$updateSelectedTextFromDOM(editor, event);
|
|
6734
6868
|
});
|
|
6735
6869
|
}
|
|
6736
6870
|
|
|
6737
|
-
function onCompositionEnd(event, editor) {
|
|
6738
|
-
if (IS_FIREFOX) {
|
|
6739
|
-
// The order of onInput and onCompositionEnd is different
|
|
6740
|
-
// in FF. Given that onInput will fire after onCompositionEnd
|
|
6741
|
-
// in FF, we need to defer the $logic for onCompositionEnd to
|
|
6742
|
-
// ensure that any possible onInput events fire before.
|
|
6743
|
-
setTimeout(() => {
|
|
6744
|
-
onCompositionEndInternal(event, editor);
|
|
6745
|
-
}, 0);
|
|
6746
|
-
} else {
|
|
6747
|
-
onCompositionEndInternal(event, editor);
|
|
6748
|
-
}
|
|
6749
|
-
}
|
|
6750
|
-
|
|
6751
6871
|
function updateAndroidSoftKeyFlagIfAny(event) {
|
|
6752
6872
|
lastKeyWasMaybeAndroidSoftKey = event.key === 'Unidentified' && event.keyCode === 229;
|
|
6753
6873
|
}
|
|
@@ -8035,7 +8155,7 @@ class BaseLexicalEditor {
|
|
|
8035
8155
|
}
|
|
8036
8156
|
}
|
|
8037
8157
|
|
|
8038
|
-
|
|
8158
|
+
addNodeTransform( // There's no Flow-safe way to preserve the T in Transform<T>, but <T: LexicalNode> in the
|
|
8039
8159
|
// declaration below guarantees these are LexicalNodes.
|
|
8040
8160
|
klass, listener) {
|
|
8041
8161
|
const type = klass.getType();
|
|
@@ -8100,7 +8220,7 @@ class BaseLexicalEditor {
|
|
|
8100
8220
|
const style = nextRootElement.style;
|
|
8101
8221
|
style.userSelect = 'text';
|
|
8102
8222
|
style.whiteSpace = 'pre-wrap';
|
|
8103
|
-
style.
|
|
8223
|
+
style.wordBreak = 'break-word';
|
|
8104
8224
|
nextRootElement.setAttribute('data-lexical-editor', 'true');
|
|
8105
8225
|
this._dirtyType = FULL_RECONCILE;
|
|
8106
8226
|
initMutationObserver(getSelf(this));
|
|
@@ -8230,7 +8350,7 @@ class BaseLexicalEditor {
|
|
|
8230
8350
|
*
|
|
8231
8351
|
*
|
|
8232
8352
|
*/
|
|
8233
|
-
const VERSION = '0.1.
|
|
8353
|
+
const VERSION = '0.1.16';
|
|
8234
8354
|
|
|
8235
8355
|
/**
|
|
8236
8356
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
package/Lexical.js.flow
CHANGED
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
type MutationListeners = Map<MutationListener, Class<LexicalNode>>;
|
|
15
|
-
export type NodeMutation = 'created' | 'destroyed';
|
|
16
|
-
export type ErrorListener = (error: Error) => void;
|
|
15
|
+
export type NodeMutation = 'created' | 'updated' | 'destroyed';
|
|
17
16
|
type UpdateListener = ({
|
|
18
17
|
tags: Set<string>,
|
|
19
18
|
prevEditorState: EditorState,
|
|
@@ -44,7 +43,6 @@ export type ReadOnlyListener = (readOnly: boolean) => void;
|
|
|
44
43
|
type CommandPayload = any;
|
|
45
44
|
type Listeners = {
|
|
46
45
|
decorator: Set<DecoratorListener>,
|
|
47
|
-
error: Set<ErrorListener>,
|
|
48
46
|
mutation: MutationListeners,
|
|
49
47
|
textcontent: Set<TextContentListener>,
|
|
50
48
|
root: Set<RootListener>,
|
|
@@ -109,7 +107,7 @@ declare export class LexicalEditor {
|
|
|
109
107
|
klass: Class<LexicalNode>,
|
|
110
108
|
listener: MutationListener,
|
|
111
109
|
): () => void;
|
|
112
|
-
|
|
110
|
+
addNodeTransform<T: LexicalNode>(
|
|
113
111
|
klass: Class<T>,
|
|
114
112
|
listener: Transform<T>,
|
|
115
113
|
): () => void;
|
|
@@ -157,17 +155,9 @@ export type EditorThemeClasses = {
|
|
|
157
155
|
image?: EditorThemeClassName,
|
|
158
156
|
list?: {
|
|
159
157
|
ul?: EditorThemeClassName,
|
|
160
|
-
|
|
161
|
-
ul2?: EditorThemeClassName,
|
|
162
|
-
ul3?: EditorThemeClassName,
|
|
163
|
-
ul4?: EditorThemeClassName,
|
|
164
|
-
ul5?: EditorThemeClassName,
|
|
158
|
+
ulDepth?: Array<EditorThemeClassName>,
|
|
165
159
|
ol?: EditorThemeClassName,
|
|
166
|
-
|
|
167
|
-
ol2?: EditorThemeClassName,
|
|
168
|
-
ol3?: EditorThemeClassName,
|
|
169
|
-
ol4?: EditorThemeClassName,
|
|
170
|
-
ol5?: EditorThemeClassName,
|
|
160
|
+
olDepth?: Array<EditorThemeClassName>,
|
|
171
161
|
listitem?: EditorThemeClassName,
|
|
172
162
|
nested?: {
|
|
173
163
|
list?: EditorThemeClassName,
|
|
@@ -389,33 +379,33 @@ interface BaseSelection {
|
|
|
389
379
|
insertRawText(text: string): void;
|
|
390
380
|
is(selection: null | RangeSelection | NodeSelection | GridSelection): boolean;
|
|
391
381
|
}
|
|
392
|
-
|
|
382
|
+
export type GridSelectionShape = {
|
|
383
|
+
fromX: number,
|
|
384
|
+
fromY: number,
|
|
385
|
+
toX: number,
|
|
386
|
+
toY: number,
|
|
387
|
+
};
|
|
393
388
|
declare export class GridSelection implements BaseSelection {
|
|
394
389
|
gridKey: NodeKey;
|
|
395
390
|
anchorCellKey: NodeKey;
|
|
391
|
+
anchor: PointType;
|
|
396
392
|
focusCellKey: NodeKey;
|
|
393
|
+
focus: PointType;
|
|
397
394
|
dirty: boolean;
|
|
398
|
-
|
|
399
395
|
constructor(
|
|
400
396
|
gridKey: NodeKey,
|
|
401
397
|
anchorCellKey: NodeKey,
|
|
402
398
|
focusCellKey: NodeKey,
|
|
403
399
|
): void;
|
|
404
|
-
|
|
405
400
|
is(selection: null | RangeSelection | NodeSelection | GridSelection): boolean;
|
|
406
|
-
|
|
407
401
|
set(gridKey: NodeKey, anchorCellKey: NodeKey, focusCellKey: NodeKey): void;
|
|
408
|
-
|
|
409
402
|
clone(): GridSelection;
|
|
410
|
-
|
|
411
403
|
extract(): Array<LexicalNode>;
|
|
412
|
-
|
|
413
404
|
insertRawText(): void;
|
|
414
|
-
|
|
415
405
|
insertText(): void;
|
|
416
|
-
|
|
406
|
+
isCollapsed(): false;
|
|
407
|
+
getShape(): GridSelectionShape;
|
|
417
408
|
getNodes(): Array<LexicalNode>;
|
|
418
|
-
|
|
419
409
|
getTextContent(): string;
|
|
420
410
|
}
|
|
421
411
|
|