kishorekumaru
kishorekumaru

Reputation: 1578

Navigator.clipboard copy doesnt work on Safari when the copy text is grabbed via asynchronous call

I have a react file, using a copyText with navigatorClipboard and documentExec command. However in Safari both are not working when the call is wrapped up with asynchronous mode. Here is an example created in codesandbox:

https://codesandbox.io/s/goofy-worker-rypyr?file=/src/App.js

  
    let textArea;

const isOS = () => navigator.userAgent.match(/ipad|iphone/i);

const selectText = (text) => {
  textArea = document.createElement("textArea");
  textArea.value = text;
  document.body.appendChild(textArea);

  if (isOS()) {
    const range = document.createRange();
    range.selectNodeContents(textArea);
    const selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
    textArea.setSelectionRange(0, 999999);
  } else {
    textArea.select();
  }
};

const copyToClipboard = () => {
  const success = document.execCommand("copy");
  console.log(success);
  document.body.removeChild(textArea);
};

const copyExecText = (text) => {
  selectText(text);
  copyToClipboard();
};

const copyNavText = (text) => {
  navigator.clipboard.writeText(text).then(
    () => {
      console.log("Async: Copying to clipboard was successful!");
    },
    (err) => {
      console.error("Async: Could not copy text: ", err);
    }
  );
};

export { copyExecText, copyNavText };

    
    const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

  
  const makeCopyText = async () => {
    await wait(1000);
    copyNavText("Non Sync copy text with Navigator!");
  };

  const makeCopyTextExec = async () => {
    await wait(1000);
    copyExecText("Non Sync copy text with exec!");
  };
<div>
        <button onClick={makeCopyTextExec}>Async Copy Exec Text</button>
        <button onClick={makeCopyText}>Copy Nav Text</button>
        </div>

Ideally, I am trying to get the copy context from an API (Async way) and put that in the clipboard. Safari rejects both the function straightaway and I am unable put the content in the Clipboard. However both Chrome and Firefox works fine.

Please let me know is there any way to make the Safari works on Asynchronous mode.

Upvotes: 2

Views: 3925

Answers (1)

Fabio Caccamo
Fabio Caccamo

Reputation: 1971

I'm having the same problem with Safari and it seems that there are not workarounds:

The implementation is available through the navigator.clipboard API which must be called within user gesture event handlers like pointerdown or pointerup, and only works for content served in a secure context (e.g. https://). Instead of a permissions-based model for reading from the clipboard, a native UI is displayed when the page calls into the clipboard API; the clipboard can only be accessed if the user then explicitly interacts with the platform UI.

Source: https://webkit.org/blog/10247/new-webkit-features-in-safari-13-1/

Upvotes: 1

Related Questions