From 628e6e56e43cfda4240bf2d5c4dc79443580a768 Mon Sep 17 00:00:00 2001 From: Travis Shivers Date: Fri, 18 Sep 2020 14:40:33 -0500 Subject: [PATCH] fix(clipboard): add legacy fallback --- src/mixins/clipboard.js | 50 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/mixins/clipboard.js b/src/mixins/clipboard.js index 6b361db5..b88d4f17 100644 --- a/src/mixins/clipboard.js +++ b/src/mixins/clipboard.js @@ -1,8 +1,56 @@ +const cssText = 'position:fixed;pointer-events:none;z-index:-9999;opacity:0;'; + +const isString = (s) => typeof (s) === 'string' || s instanceof String; + +const legacyCopy = (text) => { + const value = isString(text) + ? text + : JSON.stringify(text); + + const textarea = document.createElement('textarea'); + + textarea.value = value; + textarea.setAttribute('readonly', ''); + textarea.style.cssText = cssText; + + document.body.appendChild(textarea); + + if (navigator.userAgent.match(/ipad|ipod|iphone/i)) { + textarea.contentEditable = true; + textarea.readOnly = true; + + const range = document.createRange(); + + range.selectNodeContents(textarea); + + const selection = window.getSelection(); + + selection.removeAllRanges(); + selection.addRange(range); + textarea.setSelectionRange(0, 999999); + } else { + textarea.select(); + } + + try { + document.execCommand('copy'); + } finally { + document.body.removeChild(textarea); + } +}; + export default { methods: { async copyToClipboard(text) { - await navigator.clipboard.writeText(text); + try { + // The clipboard API can only be used in secure contexts, so fall back to legacy method if + // this fails + await navigator.clipboard.writeText(text); + } catch (e) { + console.warn(e); + } + legacyCopy(text); await this.$store.dispatch('DISPLAY_NOTIFICATION', { text: 'Copied to clipboard', color: 'success',