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) {