2

Using the new Clipboard API I can easily read out the current content as text (sample code) and the API looks like it could support multiple 'types', but at least in Chrome and Edge it always only returns text/plain. Is this a bug/limitation in the new API, or should I do my call differently?

Full example how to trigger this behavior

Note: make sure to copy rich text content beforehand. (This is not a snippet as the new clipboard API doesn't seem to work in iframes)

<!DOCTYPE html>
<html>
  <head> </head>
  <body>
    <div contenteditable>
      paste into this area for old api
    </div>
    <button id="async">async api</button>
    <script>
      document.querySelector("#async").addEventListener("click", (e) => {
        navigator.permissions
          .query({ name: "clipboard-read" })
          .then((result) => {
            // If permission to read the clipboard is granted or if the user will
            // be prompted to allow it, we proceed.

            if (result.state == "granted" || result.state == "prompt") {
              navigator.clipboard.read().then((data) => {
                console.log(data.map((d) => d.types)); // always returns only [['text/plain']]
              });
            }
          });
      });
      document.querySelector("div").addEventListener("paste", (e) => {
        console.log(e.clipboardData.types); // returns for the same content ["text/plain", "text/html"]
      });
    </script>
  </body>
</html>

2 Answers 2

5

Chrome is still working on it: https://bugs.chromium.org/p/chromium/issues/detail?id=897289

For the time being, only text/plain and image/png can be retrieved and written through this API.

Unfortunately, they also blocked the access of this feature to cross-origin frames, meaning almost all online js fiddlers, Stack-Snippets included.

So here is a link to a code-sandbox external window, not sure how long these things last, and below is the main code of that sandbox:

  button.onclick = async (evt) => {
    const clipboard = navigator.clipboard;
    const item = (await clipboard.read())[0];
    const image =
      item.types.includes("image/png") && (await item.getType("image/png"));
    const text =
      item.types.includes("text/plain") && item.getType("text/plain");

    if (image) {
      document.body.appendChild(new Image()).src = URL.createObjectURL(
        image
      );
    }
    console.log(text);
  };

Note that the synchronous API accessible through the ClipboardEvent's clipboardData, can access these types.

Sign up to request clarification or add additional context in comments.

1 Comment

Current Chromium ticket state: "Given the security implications with this proposal, we're abandoning it."
0

Since readText() (and read(), for that matter) returns an empty string if the clipboard isn't text, this code is safe.

Source: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.