mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 17:32:41 +00:00
enable copying svg cell output (#203843)
* find the correct svg element and write it to the clipboard * add context to allow context menu * simplify selection * better logs for error states
This commit is contained in:
parent
6aad7f2ec9
commit
7a56623b82
|
@ -113,7 +113,7 @@
|
|||
"webview/context": [
|
||||
{
|
||||
"command": "notebook.cellOutput.copy",
|
||||
"when": "webviewId == 'notebook.output' && webviewSection == 'image'"
|
||||
"when": "webviewId == 'notebook.output'"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -38,7 +38,11 @@ function renderImage(outputInfo: OutputItem, element: HTMLElement): IDisposable
|
|||
if (alt) {
|
||||
image.alt = alt;
|
||||
}
|
||||
image.setAttribute('data-vscode-context', JSON.stringify({ webviewSection: 'image', outputId: outputInfo.id, 'preventDefaultContextMenuItems': true }));
|
||||
image.setAttribute('data-vscode-context', JSON.stringify({
|
||||
webviewSection: 'image',
|
||||
outputId: outputInfo.id,
|
||||
'preventDefaultContextMenuItems': true
|
||||
}));
|
||||
const display = document.createElement('div');
|
||||
display.classList.add('display');
|
||||
display.appendChild(image);
|
||||
|
@ -78,7 +82,7 @@ function getAltText(outputInfo: OutputItem) {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
function injectTitleForSvg(outputInfo: OutputItem, element: HTMLElement) {
|
||||
function fixUpSvgElement(outputInfo: OutputItem, element: HTMLElement) {
|
||||
if (outputInfo.mime.indexOf('svg') > -1) {
|
||||
const svgElement = element.querySelector('svg');
|
||||
const altText = getAltText(outputInfo);
|
||||
|
@ -87,6 +91,16 @@ function injectTitleForSvg(outputInfo: OutputItem, element: HTMLElement) {
|
|||
title.innerText = altText;
|
||||
svgElement.prepend(title);
|
||||
}
|
||||
|
||||
if (svgElement) {
|
||||
svgElement.classList.add('output-image');
|
||||
|
||||
svgElement.setAttribute('data-vscode-context', JSON.stringify({
|
||||
webviewSection: 'image',
|
||||
outputId: outputInfo.id,
|
||||
'preventDefaultContextMenuItems': true
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +110,7 @@ async function renderHTML(outputInfo: OutputItem, container: HTMLElement, signal
|
|||
const htmlContent = outputInfo.text();
|
||||
const trustedHtml = ttPolicy?.createHTML(htmlContent) ?? htmlContent;
|
||||
element.innerHTML = trustedHtml as string;
|
||||
injectTitleForSvg(outputInfo, element);
|
||||
fixUpSvgElement(outputInfo, element);
|
||||
|
||||
for (const hook of hooks) {
|
||||
element = (await hook.postRender(outputInfo, element, signal)) ?? element;
|
||||
|
|
|
@ -1394,21 +1394,34 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
}
|
||||
|
||||
try {
|
||||
const image = $window.document.getElementById(outputId)?.querySelector('img')
|
||||
?? $window.document.getElementById(altOutputId)?.querySelector('img');
|
||||
const outputElement = $window.document.getElementById(outputId)
|
||||
?? $window.document.getElementById(altOutputId);
|
||||
|
||||
let image = outputElement?.querySelector('img');
|
||||
|
||||
if (!image) {
|
||||
const svgImage = outputElement?.querySelector('svg.output-image');
|
||||
if (svgImage) {
|
||||
image = new Image();
|
||||
image.src = 'data:image/svg+xml,' + encodeURIComponent(svgImage.outerHTML);
|
||||
}
|
||||
}
|
||||
|
||||
if (image) {
|
||||
const imageToCopy = image;
|
||||
await navigator.clipboard.write([new ClipboardItem({
|
||||
'image/png': new Promise((resolve) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
if (canvas !== null) {
|
||||
canvas.width = image.naturalWidth;
|
||||
canvas.height = image.naturalHeight;
|
||||
const context = canvas.getContext('2d');
|
||||
context?.drawImage(image, 0, 0);
|
||||
}
|
||||
canvas.width = imageToCopy.naturalWidth;
|
||||
canvas.height = imageToCopy.naturalHeight;
|
||||
const context = canvas.getContext('2d');
|
||||
context!.drawImage(imageToCopy, 0, 0);
|
||||
|
||||
canvas.toBlob((blob) => {
|
||||
if (blob) {
|
||||
resolve(blob);
|
||||
} else {
|
||||
console.error('No blob data to write to clipboard');
|
||||
}
|
||||
canvas.remove();
|
||||
}, 'image/png');
|
||||
|
|
Loading…
Reference in a new issue