Reputation: 3950
I'm trying to add a feature to the Chrome context menu to add a todo item from selected text. I pass the selected text from a context menu in background.js
like so:
function onClickHandler(info, tab) {
chrome.extension.sendMessage(info.selectionText, function(){});
}
chrome.contextMenus.onClicked.addListener(onClickHandler);
chrome.runtime.onInstalled.addListener(function() {
chrome.contextMenus.create({"title": "Add: %s", "contexts":["selection"]});
});
And then listen for the message in an app.js
content script:
chrome.extension.onMessage.addListener(function(task, sender, sendResponse) {
Task.setNewTask(task); // Saves the task in storage
});
The message is received correctly when my extension is open in a tab, but doesn't work when it is closed. This is because I don't set app.js
as a background script in my manifest.json
:
"permissions": [
"storage",
"contextMenus",
"tabs",
"notifications"
],
"background": {
"scripts": ["background.js"]
}
The reason I don't include app.js
as a background script is because it includes the rest of my app's code, which generates errors when tried to run in the background without a DOM.
Unfortunately I can't easily do the storage in the background.js
file because I need access to the function Task.setNewTask
which is in my content script.
My app has various methods of storing data depending on the environment – there would be a lot of duplication if I had to put this logic in background.js
.
I've tried including my app as a background page:
"background": {
"page": "index.html"
},
And then including both scripts at the bottom of the page:
<script src="background.js"></script>
<script src="js/app.js"></script>
</body>
But my app still won't add new tasks in the background.
Is there a way to:
background.js
as simple as possible,app.js
as a background script,app.js
is not in the background?Upvotes: 0
Views: 608
Reputation: 77482
Oh dear. Where did you find the base code you're modifying?
chrome.extension.sendMessage
/chrome.extension.onMessage
are deprecated to the point of not even being in the documentation anymore.
But even if you change them to the proper chrome.runtime
equivalents, it's still the wrong function to communicate with a content script.
Your original code fails, since chrome.runtime.sendMessage
(and deprecated chrome.extension
equivalent) are sending only to extension pages (e.g. to the chrome-extension://yourid/
origin), not to content scripts.
Your modified code fails, since messaging never sends a message to the same JS context it's running from.
What you need is chrome.tabs.sendMessage
function, that allows you to specify the tab where your context script is. If you want to send it to the current tab, it's passed as a parameter to the onClicked
listener.
function onClickHandler(info, tab) {
chrome.tabs.sendMessage(tab.id, info.selectionText);
}
On the context script side, don't forget to change to chrome.runtime
:
chrome.runtime.onMessage.addListener(function(task, sender, sendResponse) {
Task.setNewTask(task); // Saves the task in storage
});
Upvotes: 1