From ced66f167132ff8b556ad0df6204a6a8b09e2d77 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 9 Sep 2024 18:33:54 +0100 Subject: [PATCH] Lexical: Added single node backspace/delete support --- resources/js/wysiwyg/index.ts | 2 + resources/js/wysiwyg/nodes/code-block.ts | 2 +- .../js/wysiwyg/services/keyboard-handling.ts | 40 +++++++++++++++++++ .../js/wysiwyg/ui/decorators/code-block.ts | 10 +++-- 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 resources/js/wysiwyg/services/keyboard-handling.ts diff --git a/resources/js/wysiwyg/index.ts b/resources/js/wysiwyg/index.ts index 9015cea0c..c5dd151af 100644 --- a/resources/js/wysiwyg/index.ts +++ b/resources/js/wysiwyg/index.ts @@ -14,6 +14,7 @@ import {registerTableSelectionHandler} from "./ui/framework/helpers/table-select import {el} from "./utils/dom"; import {registerShortcuts} from "./services/shortcuts"; import {registerNodeResizer} from "./ui/framework/helpers/node-resizer"; +import {registerKeyboardHandling} from "./services/keyboard-handling"; export function createPageEditorInstance(container: HTMLElement, htmlContent: string, options: Record = {}): SimpleWysiwygEditorInterface { const config: CreateEditorArgs = { @@ -52,6 +53,7 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st registerRichText(editor), registerHistory(editor, createEmptyHistoryState(), 300), registerShortcuts(context), + registerKeyboardHandling(context), registerTableResizer(editor, editWrap), registerTableSelectionHandler(editor), registerTaskListHandler(editor, editArea), diff --git a/resources/js/wysiwyg/nodes/code-block.ts b/resources/js/wysiwyg/nodes/code-block.ts index a71e21e2e..76c171971 100644 --- a/resources/js/wysiwyg/nodes/code-block.ts +++ b/resources/js/wysiwyg/nodes/code-block.ts @@ -33,7 +33,7 @@ export class CodeBlockNode extends DecoratorNode { } 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; return newNode; } diff --git a/resources/js/wysiwyg/services/keyboard-handling.ts b/resources/js/wysiwyg/services/keyboard-handling.ts new file mode 100644 index 000000000..7e3323f86 --- /dev/null +++ b/resources/js/wysiwyg/services/keyboard-handling.ts @@ -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(); + }; +} \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/decorators/code-block.ts b/resources/js/wysiwyg/ui/decorators/code-block.ts index 650bd64c5..37d3df588 100644 --- a/resources/js/wysiwyg/ui/decorators/code-block.ts +++ b/resources/js/wysiwyg/ui/decorators/code-block.ts @@ -1,7 +1,7 @@ import {EditorDecorator} from "../framework/decorator"; import {EditorUiContext} from "../framework/core"; import {$openCodeEditorForNode, CodeBlockNode} from "../../nodes/code-block"; -import {BaseSelection} from "lexical"; +import {$isDecoratorNode, BaseSelection} from "lexical"; import {$selectionContainsNode, $selectSingleNode} from "../../utils/selection"; @@ -34,9 +34,11 @@ export class CodeBlockDecorator extends EditorDecorator { const startTime = Date.now(); element.addEventListener('click', event => { - context.editor.update(() => { - $selectSingleNode(this.getNode()); - }) + requestAnimationFrame(() => { + context.editor.update(() => { + $selectSingleNode(this.getNode()); + }); + }); }); element.addEventListener('dblclick', event => {