From a1e7efee12aab65f4baf7d54cf08a8ef89d7ec05 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Tue, 24 Oct 2023 10:18:58 -0700 Subject: [PATCH] ConverationView.onPaste: Better handling of clipboard contents --- patches/quill+1.3.7.patch | 11 ++++++++++- stylesheets/_global.scss | 4 ++++ ts/components/conversation/ConversationView.tsx | 13 ++++++++++--- ts/quill/signal-clipboard/util.ts | 2 +- ts/windows/main/start.ts | 2 +- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/patches/quill+1.3.7.patch b/patches/quill+1.3.7.patch index a8d2360d1846..fbd4c90c577a 100644 --- a/patches/quill+1.3.7.patch +++ b/patches/quill+1.3.7.patch @@ -1,7 +1,16 @@ diff --git a/node_modules/quill/dist/quill.js b/node_modules/quill/dist/quill.js -index 811b3d0..fe5d034 100644 +index 811b3d0..9243ab6 100644 --- a/node_modules/quill/dist/quill.js +++ b/node_modules/quill/dist/quill.js +@@ -4295,7 +4295,7 @@ var Scroll = function (_Parchment$Scroll) { + value: function enable() { + var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + +- this.domNode.setAttribute('contenteditable', enabled); ++ this.domNode.setAttribute('contenteditable', enabled ? 'plaintext-only' : false); + } + }, { + key: 'formatAt', @@ -8896,7 +8896,8 @@ var debug = (0, _logger2.default)('quill:clipboard'); var DOM_KEY = '__ql-matcher'; diff --git a/stylesheets/_global.scss b/stylesheets/_global.scss index 189e0019127f..370455daad1a 100644 --- a/stylesheets/_global.scss +++ b/stylesheets/_global.scss @@ -34,6 +34,10 @@ body { } } +[contenteditable] { + -webkit-user-modify: read-write-plaintext-only; +} + ::-webkit-scrollbar { // For vertical scrollbars width: 9px; diff --git a/ts/components/conversation/ConversationView.tsx b/ts/components/conversation/ConversationView.tsx index cb3090b63078..ad42bd7dee67 100644 --- a/ts/components/conversation/ConversationView.tsx +++ b/ts/components/conversation/ConversationView.tsx @@ -57,14 +57,15 @@ export function ConversationView({ const onPaste = React.useCallback( (event: React.ClipboardEvent) => { - event.stopPropagation(); - event.preventDefault(); - if (!event.clipboardData) { return; } const { items } = event.clipboardData; + const fileItems = [...items].filter(item => item.kind === 'file'); + if (fileItems.length === 0) { + return; + } const allVisual = fileItems.every(item => { const type = item.type.split('/')[0]; @@ -84,6 +85,9 @@ export function ConversationView({ files, }); + event.stopPropagation(); + event.preventDefault(); + return; } @@ -93,6 +97,9 @@ export function ConversationView({ conversationId, files: [firstAttachment], }); + + event.stopPropagation(); + event.preventDefault(); } }, [conversationId, processAttachments] diff --git a/ts/quill/signal-clipboard/util.ts b/ts/quill/signal-clipboard/util.ts index b5553cdbf636..de4ed3654fc1 100644 --- a/ts/quill/signal-clipboard/util.ts +++ b/ts/quill/signal-clipboard/util.ts @@ -16,7 +16,7 @@ export function createEventHandler({ if ( !activeElement || activeElement.matches('input, textarea') || - !activeElement.closest('[contenteditable=true]') + !activeElement.closest('[contenteditable=plaintext-only]') ) { return; } diff --git a/ts/windows/main/start.ts b/ts/windows/main/start.ts index 33b6ec35f0cf..44e5dcfa33ea 100644 --- a/ts/windows/main/start.ts +++ b/ts/windows/main/start.ts @@ -27,7 +27,7 @@ window.addEventListener('contextmenu', e => { const node = e.target as Element | null; const isEditable = Boolean( - node?.closest('textarea, input, [contenteditable="true"]') + node?.closest('textarea, input, [contenteditable="plaintext-only"]') ); const isLink = Boolean(node?.closest('a')); const isImage = Boolean(node?.closest('.Lightbox img'));