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.
So after re reading all of wOxxOm comments, especially his last one. I started to try random URLs such as the BBC and McDonalds etc. And they all worked. I did not even need to specify
type: ["main_frame"]
. I also tried it on my final site and it worked too. It seems, my failing came down to using Wikipedia as an example to test my code on, something I initially picked sole SO's "reproduceable" example convention. Lesson learned.The final Background.js is:
I just want to thank w0xx0m, I doubt I would have caught without their patient back and forth with me, cheers