I finished writting my first extension and it works as I programmed it, but after completing it, I realised I made a mistake in its design, currently its designed to alert me before a event occurs (webRequest.onBeforeRequest()), I want to be alerted after the event has occurred and completed (webRequest.onCompleted()).
I tried changing, webRequest.onBeforeRequest() to webRequest.onCompleted() and make the necessary adjustments elsewhere but it just keeps throwing errors. I have removed as much irrelevant code as I can to keep my example short. I would appreciate any help.
manifest file:
{
"name": "shell",
"manifest_version": 2,
"version": "1.0",
"background": {"scripts": ["background.js"]},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"permissions": ["tabs","activeTab", "webRequest", "<all_urls>"]
}
Content.js file:
"use strict";
browser.runtime.onMessage.addListener((request) => {
console.log("Message from the background script:");
console.log(request.greeting);
return Promise.resolve({ response: "Hi from content script" });
});
background.js file:
activeTab = browser.tabs.query({currentWindow: true,active: true,}) //tabs.sendMessage must always send a message to a specific tab. Use this to get a tab
function onError(error){console.log("error")}
function sendMessageToTabs(activeTab) {
browser.tabs.sendMessage(activeTab.tabId, { greeting: "Hi from background script" })
.then((response) => {
console.log("Message from the content script:");
console.log(response.response);
})
.catch(onError);
}
// Trigger the messaging event when wiki/vihicle is visited
browser.webRequest.onBeforeRequest.addListener(sendMessageToTabs, {urls:["https://en.wikipedia.org/wiki/Vehicle"]});
The above works perfectly fine, the content script responds back to the background script, on the console when I visit wiki/vehicle:
Message from the content script:
Hi from content script
Where I am going wrong
But when I try to only rework the background.js file, so that it uses webRequest.onCompleted() rather than webRequest.onBeforeRequest, my extension stops working. I get the error:
Error: Type error for parameter tabId (Integer -1 is too small (must be at least 0)) for tabs.sendMessage.
The reworked background.js file is:
activeTab = browser.tabs.query({currentWindow: true,active: true,}) //tabs.sendMessage must always send a message to a specific tab. Use this to get a tab
function onError(error){console.log("error")}
function sendMessageToTabs(activeTab) {
browser.tabs.sendMessage(activeTab.tabId, { greeting: "Hi from background script" })
.then((response) => {
console.log("Message from the content script:");
console.log(response.response); //response is the object passed back by the content script
})
.catch(onError);
}
browser.webRequest.onCompleted.addListener(sendMessageToTabs, {urls:["https://en.wikipedia.org/wiki/Vehicle"]}); // this is used to trigger the messaging event
Edit1:
as per @wOxxOm suggestion, after reading the documentation again, I added the property types['main_frame'] the background.js file looks like:
activeTab = browser.tabs.query({currentWindow: true,active: true,}) //tabs.sendMessage must always send a message to a specific tab. Use this to get a tab
function onError(error){console.log("error")}
function sendMessageToTabs(activeTab) {
browser.tabs.sendMessage(activeTab.tabId, { greeting: "Hi from background script" })
.then((response) => {
console.log("Message from the content script:");
console.log(response.response); //response is the object passed back by the content script
})
.catch(onError);
}
browser.webRequest.onCompleted.addListener(sendMessageToTabs, {urls:["https://en.wikipedia.org/wiki/Vehicle"], types['main_frame']}); // this is used to trigger the messaging event
but I am still getting this error:Error: Type error for parameter tabId (Integer -1 is too small (must be at least 0)) for tabs.sendMessage.
types:['main_frame'], see the documentation.webNavigation.onCompletedmay be the right choice.webRequest.onBeforeRequest()correctly passes the tab id butwebRequest.onCompleted()passes-1as a tab id, which the docs state is a result of the request not being associated with a tab.webRequest.onCompleted(). The website I am targeting is one of these modern "app" sites, so the tite bar and url never changes. I am trying to target a event that automatically occurs by rellying on when the website request a resource on the background. I have tested for this event on the site manually and works as I expect it.chrome.tabs.query({url: '*://site.com/*'})and send a message to all found tabs. Note that if the resource is not the main page itself then it's notmain_framebut something else e.g.xmlhttprequestdepending on how that request is made.