From 9f3d5c0a23e5235c613243bc921a880aa6eba6bc Mon Sep 17 00:00:00 2001 From: Netduma Luke M Date: Tue, 19 Oct 2021 11:22:16 +0100 Subject: [PATCH] Re-allow clipboard copy on non-https sites (#17118) * Re-allow clipboard copy on non-https sites * fallback clipboard functions --- web_src/js/features/clipboard.js | 33 +++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/web_src/js/features/clipboard.js b/web_src/js/features/clipboard.js index 4781f8d6f..2c7ad013b 100644 --- a/web_src/js/features/clipboard.js +++ b/web_src/js/features/clipboard.js @@ -16,6 +16,33 @@ function onError(btn) { btn.dataset.content = btn.dataset.original; } +/** + * Fallback to use if navigator.clipboard doesn't exist. + * Achieved via creating a temporary textarea element, selecting the text, and using document.execCommand. + */ +function fallbackCopyToClipboard(text) { + if (!document.execCommand) return false; + + const tempTextArea = document.createElement('textarea'); + tempTextArea.value = text; + + // avoid scrolling + tempTextArea.style.top = 0; + tempTextArea.style.left = 0; + tempTextArea.style.position = 'fixed'; + + document.body.appendChild(tempTextArea); + + tempTextArea.select(); + + // if unsecure (not https), there is no navigator.clipboard, but we can still use document.execCommand to copy to clipboard + const success = document.execCommand('copy'); + + document.body.removeChild(tempTextArea); + + return success; +} + export default function initGlobalCopyToClipboardListener() { document.addEventListener('click', async (e) => { let target = e.target; @@ -33,7 +60,11 @@ export default function initGlobalCopyToClipboardListener() { await navigator.clipboard.writeText(text); onSuccess(target); } catch { - onError(target); + if (fallbackCopyToClipboard(text)) { + onSuccess(target); + } else { + onError(target); + } } break; }