From 4f5c7b295c70604aa05e163969eccbba81a3b1ae Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 18 Apr 2023 19:19:09 -0700 Subject: [PATCH] Allow copying images from image preview (#180269) Allow copying image from image preview Fixes #171616 Lets you cmd+c / right click to copy images from the image preview Also disables the copy/paste options in the other media previews since they don't currently support copying --- .../media-preview/media/imagePreview.js | 33 +++++++++++++++---- extensions/media-preview/package.json | 15 +++++++++ extensions/media-preview/package.nls.json | 3 +- extensions/media-preview/src/audioPreview.ts | 2 +- .../media-preview/src/imagePreview/index.ts | 15 +++++++-- extensions/media-preview/src/videoPreview.ts | 2 +- 6 files changed, 58 insertions(+), 12 deletions(-) diff --git a/extensions/media-preview/media/imagePreview.js b/extensions/media-preview/media/imagePreview.js index 92a77fb3f85..e62c8259276 100644 --- a/extensions/media-preview/media/imagePreview.js +++ b/extensions/media-preview/media/imagePreview.js @@ -327,21 +327,40 @@ } switch (e.data.type) { - case 'setScale': + case 'setScale': { updateScale(e.data.scale); break; - - case 'setActive': + } + case 'setActive': { setActive(e.data.value); break; - - case 'zoomIn': + } + case 'zoomIn': { zoomIn(); break; - - case 'zoomOut': + } + case 'zoomOut': { zoomOut(); break; + } + case 'copyImage': { + copyImage(); + break; + } } }); + + document.addEventListener('copy', () => { + copyImage(); + }); + + async function copyImage() { + try { + await navigator.clipboard.write([new ClipboardItem({ + 'image/png': fetch(image.src).then(request => request.blob()) + })]); + } catch (e) { + console.error(e); + } + } }()); diff --git a/extensions/media-preview/package.json b/extensions/media-preview/package.json index 8c54d78d769..795316f8b89 100644 --- a/extensions/media-preview/package.json +++ b/extensions/media-preview/package.json @@ -69,6 +69,11 @@ "command": "imagePreview.zoomOut", "title": "%command.zoomOut%", "category": "Image Preview" + }, + { + "command": "imagePreview.copyImage", + "title": "%command.copyImage%", + "category": "Image Preview" } ], "menus": { @@ -82,6 +87,16 @@ "command": "imagePreview.zoomOut", "when": "activeCustomEditorId == 'imagePreview.previewEditor'", "group": "1_imagePreview" + }, + { + "command": "imagePreview.copyImage", + "when": "false" + } + ], + "webview/context": [ + { + "command": "imagePreview.copyImage", + "when": "webviewId == 'imagePreview.previewEditor'" } ] } diff --git a/extensions/media-preview/package.nls.json b/extensions/media-preview/package.nls.json index 3e45e4d0d2e..27fe241cf6b 100644 --- a/extensions/media-preview/package.nls.json +++ b/extensions/media-preview/package.nls.json @@ -5,5 +5,6 @@ "customEditor.imagePreview.displayName": "Image Preview", "customEditor.videoPreview.displayName": "Video Preview", "command.zoomIn": "Zoom in", - "command.zoomOut": "Zoom out" + "command.zoomOut": "Zoom out", + "command.copyImage": "Copy" } diff --git a/extensions/media-preview/src/audioPreview.ts b/extensions/media-preview/src/audioPreview.ts index 9e2670cddad..e21a4189d7b 100644 --- a/extensions/media-preview/src/audioPreview.ts +++ b/extensions/media-preview/src/audioPreview.ts @@ -76,7 +76,7 @@ class AudioPreview extends MediaPreview { - +

${vscode.l10n.t("An error occurred while loading the audio file.")}

diff --git a/extensions/media-preview/src/imagePreview/index.ts b/extensions/media-preview/src/imagePreview/index.ts index f62f6699a2a..007e466d99f 100644 --- a/extensions/media-preview/src/imagePreview/index.ts +++ b/extensions/media-preview/src/imagePreview/index.ts @@ -135,6 +135,13 @@ class ImagePreview extends MediaPreview { } } + public copyImage() { + if (this.previewState === PreviewState.Active) { + this.webviewEditor.reveal(); + this.webviewEditor.webview.postMessage({ type: 'copyImage' }); + } + } + protected override updateState() { super.updateState(); @@ -173,10 +180,10 @@ class ImagePreview extends MediaPreview { - + - +

${vscode.l10n.t("An error occurred while loading the image.")}

@@ -231,5 +238,9 @@ export function registerImagePreviewSupport(context: vscode.ExtensionContext, bi previewManager.activePreview?.zoomOut(); })); + disposables.push(vscode.commands.registerCommand('imagePreview.copyImage', () => { + previewManager.activePreview?.copyImage(); + })); + return vscode.Disposable.from(...disposables); } diff --git a/extensions/media-preview/src/videoPreview.ts b/extensions/media-preview/src/videoPreview.ts index 092d9b96751..5897792f667 100644 --- a/extensions/media-preview/src/videoPreview.ts +++ b/extensions/media-preview/src/videoPreview.ts @@ -77,7 +77,7 @@ class VideoPreview extends MediaPreview { - +

${vscode.l10n.t("An error occurred while loading the video file.")}