I want to ask how to correctly copy some text to clipboard in vaadin 8 java web application. I have found solution that works in Chrome and IE, but does not work in Firefox.

The Firefox is always saying error "document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler." in console.

The only way how to get Firefox to copy text to clipboard is by some user-triggered event handler (click or focus events). But I have failed to create or inject such handler to vaadin component (e.g. Button or MenuItem).

Or is there a setting/policy in Firefox to overcome this behaviour ?

So I want to ask how to make it work.

My solution is:

Define javascript helper functions in my_ui.js:

function copy_to_clipboard(elementId, text) {
    if (document.queryCommandSupported('copy')) {
        var e = document.getElementById(elementId);
        if (e != null) {
            e.value = text;
            e.select();
            document.execCommand('copy');
        }
    }
}

Include javascript dependency in vaadin.

Page.getCurrent().addDependency(new Dependency(Type.JAVASCRIPT, "vaadin://my_ui.js"));

Create Label with HTML content, put nearly invisible textarea into Label (needs to by at least 1x1px in Chrome).

Label clipboardHelperLabel = new Label();
clipboardHelperLabel.setContentMode(ContentMode.HTML);
clipboardHelperLabel.setValue(
    "<textarea " +
        "id=\"clipboard-helper-id\"" +
        "style=\"width: 1px; height: 1px; border: 0px solid black; padding: 0px; margin: 0px;\" " +
    ">" +
    "</textarea>"
);

Define helper function in java.

public static void copyToClipboard(String text) {
    String code = "copy_to_clipboard('clipboard-helper-id','" + text + "');";
    JavaScript.getCurrent().execute(code);
}

Define MenuItem with action in MenuBar in the UI.

MenuBar toolbar = new MenuBar();
MenuItem copyToClipboardMenuItem = toolbar.addItem(
    "Copy to clipboard",
    e -> {
        String text = "Hello clipboard";
        copyToClipboard(text);
    }
);

This solution works fine in Chrome and IE, I need to make it work also in Firefox.

1 Answers

3
Leif Åstrand On

I don't think there's any way of lifting that restriction in Firefox.

What you'd have to do instead is to use JavaScript to add a client-side click listener to the button that should trigger the copy operation, but then you also need to proactively send the contents to the client instead of only populating it on demand. Expressed as code, that could be something along the lines of this:

JavaScript.getCurrent().execute(
  "document.getElementById('button').addEventListener('click', function() {" +
    "copy_to_clipboard('clipboard-helper-id','" + text + "');" +
  "})");

EDIT: I noticed that there's also an add-on for this purpose: https://vaadin.com/directory/component/jsclipboard-add-on/overview