1 import {EditorUiContext} from "../ui/framework/core";
8 KEY_ENTER_COMMAND, KEY_TAB_COMMAND,
12 import {$isImageNode} from "../nodes/image";
13 import {$isMediaNode} from "../nodes/media";
14 import {getLastSelection} from "../utils/selection";
15 import {$getNearestNodeBlockParent} from "../utils/nodes";
16 import {$createCustomParagraphNode} from "../nodes/custom-paragraph";
17 import {$isCustomListItemNode} from "../nodes/custom-list-item";
18 import {$setInsetForSelection} from "../utils/lists";
20 function isSingleSelectedNode(nodes: LexicalNode[]): boolean {
21 if (nodes.length === 1) {
22 const node = nodes[0];
23 if ($isDecoratorNode(node) || $isImageNode(node) || $isMediaNode(node)) {
31 function deleteSingleSelectedNode(editor: LexicalEditor) {
32 const selectionNodes = getLastSelection(editor)?.getNodes() || [];
33 if (isSingleSelectedNode(selectionNodes)) {
35 selectionNodes[0].remove();
40 function insertAfterSingleSelectedNode(editor: LexicalEditor, event: KeyboardEvent|null): boolean {
41 const selectionNodes = getLastSelection(editor)?.getNodes() || [];
42 if (isSingleSelectedNode(selectionNodes)) {
43 const node = selectionNodes[0];
44 const nearestBlock = $getNearestNodeBlockParent(node) || node;
46 requestAnimationFrame(() => {
48 const newParagraph = $createCustomParagraphNode();
49 nearestBlock.insertAfter(newParagraph);
50 newParagraph.select();
53 event?.preventDefault();
61 function handleInsetOnTab(editor: LexicalEditor, event: KeyboardEvent|null) {
62 const change = event?.shiftKey ? -40 : 40;
64 const selection = $getSelection();
65 const nodes = selection?.getNodes() || [];
66 if (nodes.length > 1 || (nodes.length === 1 && $isCustomListItemNode(nodes[0].getParent()))) {
67 $setInsetForSelection(editor, change);
72 export function registerKeyboardHandling(context: EditorUiContext): () => void {
73 const unregisterBackspace = context.editor.registerCommand(KEY_BACKSPACE_COMMAND, (): boolean => {
74 deleteSingleSelectedNode(context.editor);
76 }, COMMAND_PRIORITY_LOW);
78 const unregisterDelete = context.editor.registerCommand(KEY_DELETE_COMMAND, (): boolean => {
79 deleteSingleSelectedNode(context.editor);
81 }, COMMAND_PRIORITY_LOW);
83 const unregisterEnter = context.editor.registerCommand(KEY_ENTER_COMMAND, (event): boolean => {
84 return insertAfterSingleSelectedNode(context.editor, event);
85 }, COMMAND_PRIORITY_LOW);
87 const unregisterTab = context.editor.registerCommand(KEY_TAB_COMMAND, (event): boolean => {
88 return handleInsetOnTab(context.editor, event);
89 }, COMMAND_PRIORITY_LOW);
92 unregisterBackspace();