Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is document.execCommand("paste") not working in Google Chrome?

I have a problem with my extension. I want to paste data from the clipboard.

So far, I've got this:

function pasteAndGo()
{
    document.execCommand('paste')
    alert("Pasted")
}

The alert comes up, but nothing has been pasted.

I've got a feeling it's the document part that needs changing, but I don't know what to do. Any ideas?

like image 558
Joseph Duffy Avatar asked Aug 06 '11 22:08

Joseph Duffy


People also ask

Can I use execCommand copy?

execCommand('copy') method. To copy a text from an input element or a textarea on DOM, you can use the document. execCommand method. The idea is to create a fully transparent textarea and attach it to the document's body.

Can I use document execCommand (' copy ')?

Using execCommand() The "cut" and "copy" commands of the document. execCommand() method are used to replace the clipboard's content with the selected material. These commands can be used without any special permission in short-lived event handlers for a user action (for example, a click handler).

How do I copy from chrome clipboard?

To copy text, highlight the section of text you want and use. Then hit Ctrl+C to copy and save it to the clipboard.


3 Answers

There used to be an experimental clipboard API in Chrome, but this was removed in Chrome 13.

Chrome has moved towards the more standard document.execCommand('paste'), document.execCommand('copy') and document.execCommand('cut') commands: https://developer.mozilla.org/en/Rich-Text_Editing_in_Mozilla#Executing%5FCommands

In Chrome you'll need permissions need to be added to your manifest: "clipboardRead" and "clipboardWrite". http://developer.chrome.com/extensions/declare_permissions.html

Up until Chrome 38, these clipboard permissions were only available to extension pages such as background scripts. As of Chrome 39, content scripts can also use these clipboard APIs after declaring the clipboard permissions in the manifest file (crbug.com/395376).

like image 51
Boris Smus Avatar answered Oct 09 '22 21:10

Boris Smus


Calling document.execCommand("paste") is not supported by "reasonable" browsers, because of security concerns as it might enable the script to read sensitive data (like passwords) from the clipboard.

This is the compatibility matrix of document.execCommand("...") concerning clipboard events:

"copy" "paste" "cut"
IE OK OK n/a
Edge OK n/a OK
Firefox OK n/a OK
Chrome OK n/a OK

My two cents to this:

  • The behaviour of Edge, Firefox and Chrome is "reasonable" as they prevent pasting/reading data from the clipboard. They do enable cut, as cut is simply a copy followed by a delete.
  • The behaviour of IE makes no sense to me, as it enables the "risky" paste, but does not execute the cut event.

You can feature detect the possible commands using the document.queryCommandSupported method.

Edit: According to MDN document.queryCommandSupported is now deprecated and should no longer be used.

like image 40
Krisztián Balla Avatar answered Oct 09 '22 22:10

Krisztián Balla


This works well for me in a background page.

function getClipboard() {
    var pasteTarget = document.createElement("div");
    pasteTarget.contentEditable = true;
    var actElem = document.activeElement.appendChild(pasteTarget).parentNode;
    pasteTarget.focus();
    document.execCommand("Paste", null, null);
    var paste = pasteTarget.innerText;
    actElem.removeChild(pasteTarget);
    return paste;
};

Of course your extension still needs "clipboardRead" permission and you have to use message passing to get this information back to your content script:

content.js:

chrome.extension.sendMessage({
    cmd: "clipboard", //$NON-NLS-0$
    action: "paste" //$NON-NLS-0$
}, function(response) {
    if (response.paste) {
        var range = document.getSelection().getRangeAt(0);
        range.deleteContents();
        range.insertNode(document.createTextNode(response.paste));
    }
});

background.js:

function getClipboard() {
    var pasteTarget = document.createElement("div");
    pasteTarget.contentEditable = true;
    var actElem = document.activeElement.appendChild(pasteTarget).parentNode;
    pasteTarget.focus();
    document.execCommand("Paste", null, null);
    var paste = pasteTarget.innerText;
    actElem.removeChild(pasteTarget);
    return paste;
};

function onClipboardMessage(request, sender, sendResponse) {
    if (request.action === "paste") { //$NON-NLS-0$
        sendResponse({
            paste: getClipboard()
        });
    }
}

chrome.extension.onMessage.addListener(onClipboardMessage);
like image 7
stackunderflow Avatar answered Oct 09 '22 22:10

stackunderflow