From 92d528bbd352f1dddf4ef6c9b4bab1be006d75ab Mon Sep 17 00:00:00 2001 From: Anthony Stewart <150152+a-stewart@users.noreply.github.com> Date: Thu, 20 Apr 2023 20:51:41 +0200 Subject: [PATCH] Support copying non-pngs and wait for focus to avoid race conditions (#180322) * Support copying non-pngs and wait for focus to avoid race conditions * Remove the temporary canvas element after copying * Update to place entire canvas creation inside promise. * Increasing to 5 retries 20ms apart --- .../media-preview/media/imagePreview.js | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/extensions/media-preview/media/imagePreview.js b/extensions/media-preview/media/imagePreview.js index e62c8259276..ab8ad542a2d 100644 --- a/extensions/media-preview/media/imagePreview.js +++ b/extensions/media-preview/media/imagePreview.js @@ -354,10 +354,27 @@ copyImage(); }); - async function copyImage() { + async function copyImage(retries = 5) { + if (!document.hasFocus() && retries > 0) { + // copyImage is called at the same time as webview.reveal, which means this function is running whilst the webview is gaining focus. + // Since navigator.clipboard.write requires the document to be focused, we need to wait for focus. + // We cannot use a listener, as there is a high chance the focus is gained during the setup of the listener resulting in us missing it. + setTimeout(() => { copyImage(retries - 1); }, 20); + return; + } + try { await navigator.clipboard.write([new ClipboardItem({ - 'image/png': fetch(image.src).then(request => request.blob()) + 'image/png': new Promise((resolve, reject) => { + const canvas = document.createElement('canvas'); + canvas.width = image.naturalWidth; + canvas.height = image.naturalHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + canvas.toBlob((blob) => { + resolve(blob); + canvas.remove(); + }, 'image/png'); + }) })]); } catch (e) { console.error(e);