1

All I want to do is get copying text working in a chrome extension. I found this answer, the proper use of execcommand("paste") in a chrome extension, which gives this copy() function:

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

The problem is, it doesn't work if I put that on the background page and call it because the background page doesn't have access to the DOM elements (and can't access $('#sandbox')). So how can I send the DOM element $('#sandbox') from my content.js (which can access the DOM) script to my background.js script?

I figured out how to send a message from my content.js script to my background.js script and receive a response through this:

content.js:

$('#copybutton').click(function(){
       chrome.runtime.sendMessage({callCopyFunc: "callstart"}, function(response) {
          console.log(response.callCopyFunc);
        });
});

background.js:

chrome.runtime.onMessage.addListener(function(request,sender,sendResponse){
    if(request.callCopyFunc == "callstart"){
        sendResponse({callCopyFunc: "callfinished"});
    }
});

That works great! When I click the "copybutton" element on my webpage (just a button), content.js sends "callstart" to background.js and background.js sends back "callfinished" which is then displayed in the console log.

My question is: How do I send the DOM element $('#sandbox') to the background.js file from content.js so I can use the copy() function on the background page itself? I'm not understanding how to actually send an element, only text.

Sorry if this is really simple, I've been stuck on this for two days. Thanks!

Community
  • 1
  • 1
Shivang Saxena
  • 195
  • 1
  • 2
  • 13

1 Answers1

2

Well after hours of spending time on what should be a simple chrome clipboard API call, I found a solution. I don't think anybody really needs it, but I'll post it here anyway since I spend way too much time on it looking for a solution.

I downloaded "plus for trello" on the chrome app store and looked at it's code. Essentially, all the copy functionality is done on background.html (background page) and background.js (script included on background page).

In your manifest you need these two things:

"background": {
        "page": "background.html",
        "persistent": true
    },

"permissions":["clipboardWrite"],

Then in your background.html page you need to include the background.js script and also include a div with a id you will use in your background.js script:

<html>
<head>
    <title></title>
    <link href="css/style.css" rel="stylesheet" type="text/css">
    <script type="text/javascript" src="background.js"></script>
</head>
<body>
    <div id="selectionPlaceholder"></div>
</body>
</html> 

Then, in your background.js script (which you included on background.html), you need this function (I got this from the "plus for trello" extension):

function handleCopyClipboard(html) {
    if (window.getSelection && document.createRange) {
        var elemReplace = document.getElementById("selectionPlaceholder");
        elemReplace.innerHTML = html; //This is what it will copy
        var sel = window.getSelection();
        var range = document.createRange();
        range.selectNodeContents(elemReplace);
        sel.removeAllRanges();
        sel.addRange(range);
        document.execCommand("Copy");
        elemReplace.innerHTML = ""; //blank it when done
        return;
    }

}

And you need to pass this function some text. I passed it text from my content.js script using the runetime.onMessage messaging system I described in my original post. It can be called right from background.js since this script has access to your background.html page (it's included in it).

EDIT: And also, if you prefer the shorter copy() function, you can include jquery.js on your background.html page, include a <textarea id="sandbox></textarea> on your background.html page, and just call copy() from your background.js file.

Shivang Saxena
  • 195
  • 1
  • 2
  • 13