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.

1

There are 1 answers

0
Ralf_Reddings On

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:

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://final/web/site/here.com"]});  //This time it does not send `-1`

I just want to thank w0xx0m, I doubt I would have caught without their patient back and forth with me, cheers