From 32f307430f983d4d38325f35a3d6dc4a204cddf6 Mon Sep 17 00:00:00 2001 From: matthewlipski Date: Wed, 12 Feb 2025 00:42:47 +0100 Subject: [PATCH] Fixed cut/copy handling in non-editable blocks and empty selections --- .../clipboard/toClipboard/copyExtension.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/core/src/api/clipboard/toClipboard/copyExtension.ts b/packages/core/src/api/clipboard/toClipboard/copyExtension.ts index 948f7c6836..c2f8706ff8 100644 --- a/packages/core/src/api/clipboard/toClipboard/copyExtension.ts +++ b/packages/core/src/api/clipboard/toClipboard/copyExtension.ts @@ -147,6 +147,34 @@ export function selectedFragmentToHTML< return { clipboardHTML, externalHTML, markdown }; } +const checkIfSelectionInNonEditableBlock = () => { + // Let browser handle event if selection is empty (nothing + // happens). + const selection = window.getSelection(); + if (!selection || selection.isCollapsed) { + return true; + } + + // Let browser handle event if it's within a non-editable + // "island". This means it's in selectable content within a + // non-editable block. We only need to check one node as it's + // not possible for the browser selection to start in an + // editable block and end in a non-editable one. + let node = selection.focusNode; + while (node) { + if ( + node instanceof HTMLElement && + node.getAttribute("contenteditable") === "false" + ) { + return true; + } + + node = node.parentElement; + } + + return false; +}; + const copyToClipboard = < BSchema extends BlockSchema, I extends InlineContentSchema, @@ -187,11 +215,19 @@ export const createCopyToClipboardExtension = < props: { handleDOMEvents: { copy(view, event) { + if (checkIfSelectionInNonEditableBlock()) { + return true; + } + copyToClipboard(editor, view, event); // Prevent default PM handler to be called return true; }, cut(view, event) { + if (checkIfSelectionInNonEditableBlock()) { + return true; + } + copyToClipboard(editor, view, event); if (view.editable) { view.dispatch(view.state.tr.deleteSelection());