From 2c4aef5e2fca9c07378db0abef8f4225fcb75c82 Mon Sep 17 00:00:00 2001 From: abose Date: Thu, 23 Jul 2026 23:01:50 +0530 Subject: [PATCH] fix: paste Excel/spreadsheet copies as text instead of image (#2960) The image-paste handlers scanned the clipboard for an image file item and acted on it without checking for co-present text. Excel/Word/spreadsheet copies place BOTH a rendered bitmap and text/plain on the clipboard, so the image always won and cells pasted as an uploaded image. Prefer text when text/plain is present; only treat a paste as an image when the clipboard is image-only (screenshots, copy-image, Finder file copies have no text/plain). Fixes the CodeMirror markdown editor and the mdviewer live-preview paste paths. --- src-mdviewer/src/components/editor.js | 8 ++++++++ src/editor/EditorCommandHandlers.js | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/src-mdviewer/src/components/editor.js b/src-mdviewer/src/components/editor.js index 7aa72f4fe9..c7230a1c95 100644 --- a/src-mdviewer/src/components/editor.js +++ b/src-mdviewer/src/components/editor.js @@ -711,6 +711,14 @@ function handleImagePaste(e, contentEl) { if (!items) { return false; } + // Spreadsheet/word-processor copies (e.g. Excel cells) place BOTH a rendered + // bitmap AND plain text on the clipboard. Genuine image copies (screenshots, + // copy-image) carry no text/plain. Prefer text when present so such copies + // paste as text, not an uploaded image. See issue #2960. + const pastedText = e.clipboardData.getData && e.clipboardData.getData("text/plain"); + if (pastedText && pastedText.length > 0) { + return false; + } for (let i = 0; i < items.length; i++) { if (items[i].kind === "file" && ALLOWED_IMAGE_TYPES.includes(items[i].type)) { e.preventDefault(); diff --git a/src/editor/EditorCommandHandlers.js b/src/editor/EditorCommandHandlers.js index 4a726d303b..4b01e0c1a3 100644 --- a/src/editor/EditorCommandHandlers.js +++ b/src/editor/EditorCommandHandlers.js @@ -1299,6 +1299,16 @@ define(function (require, exports, module) { return false; } + // Spreadsheet/word-processor copies (e.g. Excel cells) place BOTH a rendered + // bitmap AND plain text on the clipboard. Genuine image copies (screenshots, + // copy-image from a browser/file manager) carry no text/plain. When text is + // present, prefer the normal text paste instead of uploading the bitmap so + // Excel cells paste as text, not an image. See issue #2960. + const pastedText = event.clipboardData.getData && event.clipboardData.getData("text/plain"); + if (pastedText && pastedText.length > 0) { + return false; + } + // Only handle in markdown files const doc = editor.document; if (!doc || !doc.file) {