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
This commit is contained in:
Matt Bierner 2023-04-18 19:19:09 -07:00 committed by GitHub
parent 6fefe056e2
commit 4f5c7b295c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 12 deletions

View file

@ -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);
}
}
}());

View file

@ -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'"
}
]
}

View file

@ -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"
}

View file

@ -76,7 +76,7 @@ class AudioPreview extends MediaPreview {
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src data: ${cspSource}; media-src ${cspSource}; script-src 'nonce-${nonce}'; style-src ${cspSource} 'nonce-${nonce}';">
<meta id="settings" data-settings="${escapeAttribute(JSON.stringify(settings))}">
</head>
<body class="container loading">
<body class="container loading" data-vscode-context='{ "preventDefaultContextMenuItems": true }'>
<div class="loading-indicator"></div>
<div class="loading-error">
<p>${vscode.l10n.t("An error occurred while loading the audio file.")}</p>

View file

@ -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 {
<link rel="stylesheet" href="${escapeAttribute(this.extensionResource('media', 'imagePreview.css'))}" type="text/css" media="screen" nonce="${nonce}">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src data: ${cspSource}; script-src 'nonce-${nonce}'; style-src ${cspSource} 'nonce-${nonce}';">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src data: ${cspSource}; connect-src ${cspSource}; script-src 'nonce-${nonce}'; style-src ${cspSource} 'nonce-${nonce}';">
<meta id="image-preview-settings" data-settings="${escapeAttribute(JSON.stringify(settings))}">
</head>
<body class="container image scale-to-fit loading">
<body class="container image scale-to-fit loading" data-vscode-context='{ "preventDefaultContextMenuItems": true }'>
<div class="loading-indicator"></div>
<div class="image-load-error">
<p>${vscode.l10n.t("An error occurred while loading the image.")}</p>
@ -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);
}

View file

@ -77,7 +77,7 @@ class VideoPreview extends MediaPreview {
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src data: ${cspSource}; media-src ${cspSource}; script-src 'nonce-${nonce}'; style-src ${cspSource} 'nonce-${nonce}';">
<meta id="settings" data-settings="${escapeAttribute(JSON.stringify(settings))}">
</head>
<body class="loading">
<body class="loading" data-vscode-context='{ "preventDefaultContextMenuItems": true }'>
<div class="loading-indicator"></div>
<div class="loading-error">
<p>${vscode.l10n.t("An error occurred while loading the video file.")}</p>