Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

the proper use of execcommand("paste") in a chrome extension

Tags:

I'm trying to paste clipboard data into a textarea using execcommand("paste") with a chome extension, but i cannot seem to get it to work. permissions are set. I have tried to set focus() on the textarea, but document.execCommand("paste") does nothing, and I get no error. calling execcommand("paste") from background page also does nothing.

<form>
     <textarea id="ta"></textarea>    
</form>
<script type="text/javascript">
    document.findElemetById("ta").focus();
    document.execCommand("paste");
</script>
like image 996
monopoint Avatar asked Aug 22 '11 08:08

monopoint


People also ask

What does document execCommand do?

Selects all of the content of the editable region. Toggles strikethrough on/off for the selection or at the insertion point. Toggles subscript on/off for the selection or at the insertion point. Toggles superscript on/off for the selection or at the insertion point.

What can I use instead of execCommand copy?

The alternative is the Clipboard API, as stated on MDN: "This API is designed to supersede accessing the clipboard using document. execCommand() ." However note that support for this API is not widespread yet, so as recommended in the linked dupe target, you'll probably end up falling back to document.

How to access clipboard data in JavaScript?

Using the Clipboard APIreadText() and navigator. clipboard. read() methods let you read arbitrary text or binary data from the clipboard in secure contexts. This lets you access the data in the clipboard without pasting it into an editable element.


2 Answers

Clipboard functionality is a key part of my extension so I've seen all the normal problems. On my background page I expose a copy and a paste function and the page itself contains <textarea id="sandbox"></textarea>;

function copy(str) {
    var sandbox = $('#sandbox').val(str).select();
    document.execCommand('copy');
    sandbox.val('');
}

function paste() {
    var result = '',
        sandbox = $('#sandbox').val('').select();
    if (document.execCommand('paste')) {
        result = sandbox.val();
    }
    sandbox.val('');
    return result;
}

I'm using jQuery for simplicity but you get the idea. Now any time I want to use the clipboard functionality I simply call the relevant function. Other pages in my extension can access this API via chrome.extension.getBackgroundPage() but you can also use chrome.runtime.getBackgroundPage(callback) if your background page is an event page.

I'm not sure if this is best practice or if such a thing even exists for this functionality yet but this definitely works for me and is very clean.

like image 69
neocotic Avatar answered Oct 22 '22 02:10

neocotic


This is too long for a comment on Alasdair's excellent response, so I'm creating another answer. Alasdair's answer is excellent and worked great for me, but as a newcomer to Chrome extensions it still took me a while to get it working. For anyone in a similar position, here is an expansion on his answer.

Background/event pages are able to interact with the system clipboard, provided you've requested the appropriate permissions. They are not able to interact with the DOM of pages the user has loaded. Content scripts cannot interact with the system clipboard, but they can interact with the DOM of pages the user has loaded. Take a look at the explanation of the extension architecture for a good overview of all this.

This essentially means you need to do the copy/paste actions from the system clipboard in your event/background pages, which is what Alasdair has outlined above. Any pasting or copying from the DOM of the page the user is viewing has to occur in your content script. The two scripts are able to communicate pretty easily with message passing.

I have an extension whose only purpose is to paste, and the architecture came largely from this post. If you want to see the above technique in practice, take a look at the code. In particular, background.html, background.js, and contentscript.js.

If you're in a real hurry, here is a gist.

like image 27
user1978019 Avatar answered Oct 22 '22 03:10

user1978019