Lexical: Added single node backspace/delete support

This commit is contained in:
Dan Brown 2024-09-09 18:33:54 +01:00
parent fb49371c6b
commit ced66f1671
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
4 changed files with 49 additions and 5 deletions

View File

@ -14,6 +14,7 @@ import {registerTableSelectionHandler} from "./ui/framework/helpers/table-select
import {el} from "./utils/dom"; import {el} from "./utils/dom";
import {registerShortcuts} from "./services/shortcuts"; import {registerShortcuts} from "./services/shortcuts";
import {registerNodeResizer} from "./ui/framework/helpers/node-resizer"; import {registerNodeResizer} from "./ui/framework/helpers/node-resizer";
import {registerKeyboardHandling} from "./services/keyboard-handling";
export function createPageEditorInstance(container: HTMLElement, htmlContent: string, options: Record<string, any> = {}): SimpleWysiwygEditorInterface { export function createPageEditorInstance(container: HTMLElement, htmlContent: string, options: Record<string, any> = {}): SimpleWysiwygEditorInterface {
const config: CreateEditorArgs = { const config: CreateEditorArgs = {
@ -52,6 +53,7 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st
registerRichText(editor), registerRichText(editor),
registerHistory(editor, createEmptyHistoryState(), 300), registerHistory(editor, createEmptyHistoryState(), 300),
registerShortcuts(context), registerShortcuts(context),
registerKeyboardHandling(context),
registerTableResizer(editor, editWrap), registerTableResizer(editor, editWrap),
registerTableSelectionHandler(editor), registerTableSelectionHandler(editor),
registerTaskListHandler(editor, editArea), registerTaskListHandler(editor, editArea),

View File

@ -33,7 +33,7 @@ export class CodeBlockNode extends DecoratorNode<EditorDecoratorAdapter> {
} }
static clone(node: CodeBlockNode): CodeBlockNode { static clone(node: CodeBlockNode): CodeBlockNode {
const newNode = new CodeBlockNode(node.__language, node.__code); const newNode = new CodeBlockNode(node.__language, node.__code, node.__key);
newNode.__id = node.__id; newNode.__id = node.__id;
return newNode; return newNode;
} }

View File

@ -0,0 +1,40 @@
import {EditorUiContext} from "../ui/framework/core";
import {
$isDecoratorNode,
COMMAND_PRIORITY_LOW,
KEY_BACKSPACE_COMMAND,
KEY_DELETE_COMMAND,
LexicalEditor
} from "lexical";
import {$isImageNode} from "../nodes/image";
import {$isMediaNode} from "../nodes/media";
import {getLastSelection} from "../utils/selection";
function deleteSingleSelectedNode(editor: LexicalEditor) {
const selectionNodes = getLastSelection(editor)?.getNodes() || [];
if (selectionNodes.length === 1) {
const node = selectionNodes[0];
if ($isDecoratorNode(node) || $isImageNode(node) || $isMediaNode(node)) {
editor.update(() => {
node.remove();
});
}
}
}
export function registerKeyboardHandling(context: EditorUiContext): () => void {
const unregisterBackspace = context.editor.registerCommand(KEY_BACKSPACE_COMMAND, (): boolean => {
deleteSingleSelectedNode(context.editor);
return false;
}, COMMAND_PRIORITY_LOW);
const unregisterDelete = context.editor.registerCommand(KEY_DELETE_COMMAND, (): boolean => {
deleteSingleSelectedNode(context.editor);
return false;
}, COMMAND_PRIORITY_LOW);
return () => {
unregisterBackspace();
unregisterDelete();
};
}

View File

@ -1,7 +1,7 @@
import {EditorDecorator} from "../framework/decorator"; import {EditorDecorator} from "../framework/decorator";
import {EditorUiContext} from "../framework/core"; import {EditorUiContext} from "../framework/core";
import {$openCodeEditorForNode, CodeBlockNode} from "../../nodes/code-block"; import {$openCodeEditorForNode, CodeBlockNode} from "../../nodes/code-block";
import {BaseSelection} from "lexical"; import {$isDecoratorNode, BaseSelection} from "lexical";
import {$selectionContainsNode, $selectSingleNode} from "../../utils/selection"; import {$selectionContainsNode, $selectSingleNode} from "../../utils/selection";
@ -34,9 +34,11 @@ export class CodeBlockDecorator extends EditorDecorator {
const startTime = Date.now(); const startTime = Date.now();
element.addEventListener('click', event => { element.addEventListener('click', event => {
context.editor.update(() => { requestAnimationFrame(() => {
$selectSingleNode(this.getNode()); context.editor.update(() => {
}) $selectSingleNode(this.getNode());
});
});
}); });
element.addEventListener('dblclick', event => { element.addEventListener('dblclick', event => {