From 18a09e95575f1f0e571ca15558d78c0492aa2c84 Mon Sep 17 00:00:00 2001 From: Marc Bernard <59966492+mbtools@users.noreply.github.com> Date: Thu, 26 Sep 2024 09:51:45 -0400 Subject: [PATCH 1/5] Use navigator.clipboard API Fixes issues with `document.execCommand('copy')` which is deprecated. Uses `navigator.clipboard` instead which has [browser compatibility](https://caniuse.com/mdn-api_clipboard_writetext) of +93%. Replaces #37 --- src/js/components/CopyToClipboard.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/js/components/CopyToClipboard.js b/src/js/components/CopyToClipboard.js index 62ea78d..3740c05 100644 --- a/src/js/components/CopyToClipboard.js +++ b/src/js/components/CopyToClipboard.js @@ -2,7 +2,7 @@ import React from 'react'; import { toType } from './../helpers/util'; -//clibboard icon +//clipboard icon import { Clippy } from './icons'; //theme @@ -26,20 +26,23 @@ export default class extends React.PureComponent { } handleCopy = () => { - const container = document.createElement('textarea'); const { clickCallback, src, namespace } = this.props; - container.innerHTML = JSON.stringify( + const textToCopy = JSON.stringify( this.clipboardValue(src), null, ' ' ); - document.body.appendChild(container); - container.select(); - document.execCommand('copy'); - - document.body.removeChild(container); + if (navigator.clipboard) { + await navigator.clipboard.writeText(textToCopy); + } else { + console.error( + 'react-json-view error:', + 'navigator.clipboard not supported by this browser' + ); + return; + }; this.copiedTimer = setTimeout(() => { this.setState({ From cf82428b20c84caf058b5f0014c0d329a19b34d8 Mon Sep 17 00:00:00 2001 From: Marc Bernard <59966492+mbtools@users.noreply.github.com> Date: Thu, 26 Sep 2024 13:54:28 -0400 Subject: [PATCH 2/5] Update CopyToClipboard.js --- src/js/components/CopyToClipboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/components/CopyToClipboard.js b/src/js/components/CopyToClipboard.js index 3740c05..34ffe14 100644 --- a/src/js/components/CopyToClipboard.js +++ b/src/js/components/CopyToClipboard.js @@ -35,7 +35,7 @@ export default class extends React.PureComponent { ); if (navigator.clipboard) { - await navigator.clipboard.writeText(textToCopy); + navigator.clipboard.writeText(textToCopy); } else { console.error( 'react-json-view error:', From c18ae22aaf29702f7d4fbe6d21abb171dcd82a04 Mon Sep 17 00:00:00 2001 From: Marc Bernard <59966492+mbtools@users.noreply.github.com> Date: Thu, 26 Sep 2024 20:55:45 -0400 Subject: [PATCH 3/5] Add fallback --- src/js/components/CopyToClipboard.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/js/components/CopyToClipboard.js b/src/js/components/CopyToClipboard.js index 34ffe14..8d8229d 100644 --- a/src/js/components/CopyToClipboard.js +++ b/src/js/components/CopyToClipboard.js @@ -35,7 +35,15 @@ export default class extends React.PureComponent { ); if (navigator.clipboard) { - navigator.clipboard.writeText(textToCopy); + navigator.clipboard.writeText(textToCopy).catch(err => { + // Fallback for non-secure contexts (i.e. http) + const textArea = document.createElement('textarea'); + textArea.value = textToCopy; + document.body.appendChild(textArea); + textArea.select(); + document.execCommand('copy'); + document.body.removeChild(textArea); + }); } else { console.error( 'react-json-view error:', From ec72456a6b6efd26558a302b9b653b8ea01bcf0b Mon Sep 17 00:00:00 2001 From: Marc Bernard <59966492+mbtools@users.noreply.github.com> Date: Fri, 27 Sep 2024 08:57:07 -0400 Subject: [PATCH 4/5] Add fallback for test env --- src/js/components/CopyToClipboard.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/js/components/CopyToClipboard.js b/src/js/components/CopyToClipboard.js index 8d8229d..addb6a2 100644 --- a/src/js/components/CopyToClipboard.js +++ b/src/js/components/CopyToClipboard.js @@ -25,6 +25,15 @@ export default class extends React.PureComponent { } } + copyToClipboardFallback = (textToCopy) => { + const textArea = document.createElement('textarea'); + textArea.value = textToCopy; + document.body.appendChild(textArea); + textArea.select(); + document.execCommand('copy'); + document.body.removeChild(textArea); + } + handleCopy = () => { const { clickCallback, src, namespace } = this.props; @@ -35,21 +44,13 @@ export default class extends React.PureComponent { ); if (navigator.clipboard) { - navigator.clipboard.writeText(textToCopy).catch(err => { + navigator.clipboard.writeText(textToCopy).catch(() => { // Fallback for non-secure contexts (i.e. http) - const textArea = document.createElement('textarea'); - textArea.value = textToCopy; - document.body.appendChild(textArea); - textArea.select(); - document.execCommand('copy'); - document.body.removeChild(textArea); + copyToClipboardFallback(textToCopy); }); } else { - console.error( - 'react-json-view error:', - 'navigator.clipboard not supported by this browser' - ); - return; + // Fallback for old browsers and test environments + copyToClipboardFallback(textToCopy); }; this.copiedTimer = setTimeout(() => { From 86bbd60caef8d80b812a45c8ea9326df62fcb02f Mon Sep 17 00:00:00 2001 From: Kiko Beats Date: Fri, 27 Sep 2024 15:07:18 +0200 Subject: [PATCH 5/5] fix: function call --- src/js/components/CopyToClipboard.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/components/CopyToClipboard.js b/src/js/components/CopyToClipboard.js index addb6a2..49746ca 100644 --- a/src/js/components/CopyToClipboard.js +++ b/src/js/components/CopyToClipboard.js @@ -46,11 +46,11 @@ export default class extends React.PureComponent { if (navigator.clipboard) { navigator.clipboard.writeText(textToCopy).catch(() => { // Fallback for non-secure contexts (i.e. http) - copyToClipboardFallback(textToCopy); + this.copyToClipboardFallback(textToCopy); }); } else { // Fallback for old browsers and test environments - copyToClipboardFallback(textToCopy); + this.copyToClipboardFallback(textToCopy); }; this.copiedTimer = setTimeout(() => {