File tree

6 files changed

+46
-19
lines changed

6 files changed

+46
-19
lines changed
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
internalMarkNodeAsDirty,
4949
removeFromParent,
5050
} from './LexicalUtils';
51+
import {$insertAndSelectNewEmptyAdjacentNode} from "../../utils/nodes";
5152

5253
export type NodeMap = Map<NodeKey, LexicalNode>;
5354

@@ -1130,7 +1131,7 @@ export class LexicalNode {
11301131
const prevSibling = this.getPreviousSibling();
11311132
const parent = this.getParentOrThrow();
11321133
if (prevSibling === null) {
1133-
return parent.select(0, 0);
1134+
return $insertAndSelectNewEmptyAdjacentNode(this, false);
11341135
}
11351136
if ($isElementNode(prevSibling)) {
11361137
return prevSibling.select();
@@ -1152,7 +1153,7 @@ export class LexicalNode {
11521153
const nextSibling = this.getNextSibling();
11531154
const parent = this.getParentOrThrow();
11541155
if (nextSibling === null) {
1155-
return parent.select();
1156+
return $insertAndSelectNewEmptyAdjacentNode(this, true);
11561157
}
11571158
if ($isElementNode(nextSibling)) {
11581159
return nextSibling.select(0, 0);
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import invariant from 'lexical/shared/invariant';
1717
import {
1818
$createLineBreakNode,
1919
$createParagraphNode,
20-
$createTextNode,
20+
$createTextNode, $getNearestNodeFromDOMNode,
2121
$isDecoratorNode,
2222
$isElementNode,
2323
$isLineBreakNode,
@@ -63,6 +63,7 @@ import {
6363
toggleTextFormatType,
6464
} from './LexicalUtils';
6565
import {$createTabNode, $isTabNode} from './nodes/LexicalTabNode';
66+
import {$selectSingleNode} from "../../utils/selection";
6667

6768
export type TextPointType = {
6869
_selection: BaseSelection;
@@ -2568,6 +2569,17 @@ export function updateDOMSelection(
25682569
}
25692570

25702571
if (!$isRangeSelection(nextSelection)) {
2572+
2573+
// If the DOM selection enters a decorator node update the selection to a single node selection
2574+
if (activeElement !== null && domSelection.isCollapsed && focusDOMNode instanceof Node) {
2575+
const node = $getNearestNodeFromDOMNode(focusDOMNode);
2576+
if ($isDecoratorNode(node)) {
2577+
domSelection.removeAllRanges();
2578+
$selectSingleNode(node);
2579+
return;
2580+
}
2581+
}
2582+
25712583
// We don't remove selection if the prevSelection is null because
25722584
// of editor.setRootElement(). If this occurs on init when the
25732585
// editor is already focused, then this can cause the editor to
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,11 @@ export function getTable(tableElement: HTMLElement): TableDOMTable {
917917
while (currentNode != null) {
918918
const nodeMame = currentNode.nodeName;
919919

920+
if (nodeMame === 'COLGROUP') {
921+
currentNode = currentNode.nextSibling;
922+
continue;
923+
}
924+
920925
if (nodeMame === 'TD' || nodeMame === 'TH') {
921926
const elem = currentNode as HTMLElement;
922927
const cell = {
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,21 @@ function deleteSingleSelectedNode(editor: LexicalEditor) {
4747
* Insert a new empty node before/after the selection if the selection contains a single
4848
* selected node (like image, media etc...).
4949
*/
50-
function insertAfterSingleSelectedNode(editor: LexicalEditor, event: KeyboardEvent|null): boolean {
50+
function insertAdjacentToSingleSelectedNode(editor: LexicalEditor, event: KeyboardEvent|null): boolean {
5151
const selectionNodes = getLastSelection(editor)?.getNodes() || [];
5252
if (isSingleSelectedNode(selectionNodes)) {
5353
const node = selectionNodes[0];
5454
const nearestBlock = $getNearestNodeBlockParent(node) || node;
55+
const insertBefore = event?.shiftKey === true;
5556
if (nearestBlock) {
5657
requestAnimationFrame(() => {
5758
editor.update(() => {
5859
const newParagraph = $createParagraphNode();
59-
nearestBlock.insertAfter(newParagraph);
60+
if (insertBefore) {
61+
nearestBlock.insertBefore(newParagraph);
62+
} else {
63+
nearestBlock.insertAfter(newParagraph);
64+
}
6065
newParagraph.select();
6166
});
6267
});
@@ -75,22 +80,14 @@ function focusAdjacentOrInsertForSingleSelectNode(editor: LexicalEditor, event:
7580
}
7681

7782
event?.preventDefault();
78-
7983
const node = selectionNodes[0];
80-
const nearestBlock = $getNearestNodeBlockParent(node) || node;
81-
let target = after ? nearestBlock.getNextSibling() : nearestBlock.getPreviousSibling();
8284

8385
editor.update(() => {
84-
if (!target) {
85-
target = $createParagraphNode();
86-
if (after) {
87-
nearestBlock.insertAfter(target)
88-
} else {
89-
nearestBlock.insertBefore(target);
90-
}
86+
if (after) {
87+
node.selectNext();
88+
} else {
89+
node.selectPrevious();
9190
}
92-
93-
target.selectStart();
9491
});
9592

9693
return true;
@@ -220,7 +217,7 @@ export function registerKeyboardHandling(context: EditorUiContext): () => void {
220217
}, COMMAND_PRIORITY_LOW);
221218

222219
const unregisterEnter = context.editor.registerCommand(KEY_ENTER_COMMAND, (event): boolean => {
223-
return insertAfterSingleSelectedNode(context.editor, event)
220+
return insertAdjacentToSingleSelectedNode(context.editor, event)
224221
|| moveAfterDetailsOnEmptyLine(context.editor, event);
225222
}, COMMAND_PRIORITY_LOW);
226223

Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ export class EditorUIManager {
244244
if (selectionChange) {
245245
editor.update(() => {
246246
const selection = $getSelection();
247+
// console.log('manager::selection', selection);
247248
this.triggerStateUpdate({
248249
editor, selection,
249250
});
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
$isTextNode,
77
ElementNode,
88
LexicalEditor,
9-
LexicalNode
9+
LexicalNode, RangeSelection
1010
} from "lexical";
1111
import {LexicalNodeMatcher} from "../nodes";
1212
import {$generateNodesFromDOM} from "@lexical/html";
@@ -118,6 +118,17 @@ export function $sortNodes(nodes: LexicalNode[]): LexicalNode[] {
118118
return sorted;
119119
}
120120

121+
export function $insertAndSelectNewEmptyAdjacentNode(node: LexicalNode, after: boolean): RangeSelection {
122+
const target = $createParagraphNode();
123+
if (after) {
124+
node.insertAfter(target)
125+
} else {
126+
node.insertBefore(target);
127+
}
128+
129+
return target.select();
130+
}
131+
121132
export function nodeHasAlignment(node: object): node is NodeHasAlignment {
122133
return '__alignment' in node;
123134
}

0 commit comments

Comments
 (0)