pstenstrm
pstenstrm

Reputation: 6489

Custom clipboardData datatype across browsers

We're trying to allow our users to copy-paste data between two systems. From a webpage to an Electron app.

The user will click a button on which we trigger a copy event with the help of copy-to-clipboard.

import copy from "copy-to-clipboard";

const copyHandler = (evt) => {
    evt.preventDefault();

    evt.clipboardData.setData("text/plain", url);
    evt.clipboardData.setData("mumbo/jumbo", JSON.stringify({
        foo: "bar"
    }));
}

document.addEventListener("copy", copyHandler);
copy();
document.removeEventListener("copy", copyHandler);

In the Electron app we listen to the paste event:

onPaste = (evt) => {
    if(evt.clipboardData.getData("mumbo/jumbo")) {
        // Handle custom data-type
    } else if(evt.clipboardData.getData("text/html")) {
        // Handle html
    } else {
        // Handle plain text
    }
}

When the user uses our webpage in Chrome everything works. We can read the data for the custom data-type. But when the user visits the webpage in Firefox evt.clipboardData.getData("mumbo/jumbo") will return undefined. The data we set for text/plain and text/html will still be available.

If we paste the data back to Firefox evt.clipboardData.getData("mumbo/jumbo") will properly return the data we set.

I've tried finding information about if this is even supposed to work, but can't find anything. Is custom clipboardData data types supported between browsers at all, and I'm doing something wrong? Or was it never going to work?

Doing the same thing with application/json data type also does not work between Firefox and Electron. The only data types we've been able to get to work is text/plain and text/html, but both are already used for other purposes.

Upvotes: 3

Views: 1983

Answers (1)

pstenstrm
pstenstrm

Reputation: 6489

In the end I went through all data types listed in clipboard W3C Working Draft. At this point I can only get text/plain and text/html to work when copy-pasting between Firefox and Chrome.

I ended up using text/html to pass the data:

const copyHandler = (evt) => {
    evt.preventDefault();

    evt.clipboardData.setData("text/plain", url);
    evt.clipboardData.setData("text/html", `<div id="${btoa("mumbo/jumbo")}" data-foo="${bar}"></div>`);
}

I Base64 encode the ID with btoa() to try to minimise conflicts with regular HTML pastes.

Upvotes: 4

Related Questions