I am trying to create a context menu option which copies some text to the system clipboard.
Currently, I am just copying a hard-coded string literal, but I am wondering how it could be changed to copy selected text. Specifically, I don't know how to properly create the createProperties
object (see bottom)
It is my understanding that this can only be done through a background page.
I have the following background page:
background.html
<textarea id="temp"></textarea>
<script src="context.js"></script>
context.js
is as follows:
chrome.contextMenus.create({
"title": "Freedom",
"contexts": ["editable"],
"onclick" : copyToClipboard
});
function copyToClipboard()
{
var tempNode = document.getElementById("temp");
tempNode.value = "some text";
tempNode.select();
var status = document.execCommand('copy',false,null);
if(status) alert('successful');
else alert('unsuccessful');
}
my manifest.json
is as follows:
{
"manifest_version": 2,
"name": "Freedom",
"description": "Provides users useful and fun context menu options that they can access from anywhere.",
"version": "1.0",
"permissions": [
"contextMenus",
"clipboardWrite"
],
"background": {
"page": "background.html"
}
}
I am apparently declaring the chrome.contextMenus.create() function incorrectly. I have read the docs for it and I can only imagine that I am not properly creating the createProperties
object.
I have been trying to mimic these sources:
Is that possible calling content script method by context menu item in Chrome extension?
http://paul.kinlan.me/chrome-extension-adding-context-menus/
some other related questions are:
Copy to Clipboard in Chrome Extension
How to copy text to clipboard from a Google Chrome extension?
"createProperties" in the documentation is the dictionary that is passed to the chrome.contextMenus.create
method (i.e. that thing with "title", "contexts", etc.)
The onclick
event description of chrome.contextMenus.create
states that the function receives two parameters. The first parameter ("info") is a dictionary with information about the selected text. The second parameter ("tab") contains information about the tab (in your case, you don't need though).
The "info" dictionary has a property "selectionText" that holds the selected text when the context menu item was clicked. This can be used in your code as follows:
function copyToClipboard(info) {
var tempNode = document.getElementById("temp");
tempNode.value = info.selectionText; // <-- Selected text
tempNode.select();
document.execCommand('copy', false, null);
}
That would solve your immediate question.
Besides that, your extension can be improved by converting your background page to an event page. The main benefit of event pages over background pages is that your extension will not unnecessarily use memory while sitting idle in the background.
// background.js
// Register context menu
chrome.runtime.onInstalled.addListener(function() {
chrome.contextMenus.create({
"id": "some id", // Required for event pages
"title": "Copy selected text to clipboard",
"contexts": ["editable"],
// "onclick" : ... // Removed in favor of chrome.contextMenus.onClicked
});
});
// Register a contextmenu click handler.
chrome.contextMenus.onClicked.addListener(copyToClipboard);
Here is a minimal manifest.json (note the "persistent": false
key, which specifies that you want to use an event page)
{
"manifest_version": 2,
"name": "Copy selected text to clipboard",
"version": "1.0",
"permissions": [
"contextMenus",
"clipboardWrite"
],
"background": {
"page": "background.html",
"persistent": false
}
}