Manual injection of content_scripts to existing pages?

Is there a definitive way of handing open tabs when my add-on is first installed or updated?

I’m trying to use executeScript as is mentioned around abouts, but it’s a real PITA so far, and no existing existing “is my extension supposed to work on this tab” code works as-is.

Plus I seem to get the (on-update) injection occuring before the old one becomes deactivated on the pages (I’ve tried to add code to clear up dead ports upon update). It’s all getting very messy.

Without the content-scripts my add-on will quietly fail after install, or after update, without a restart which kind of makes no-restart updating somewhat pointless.

browser.tabs.executeScript() is definitely what you should use. What problem are you having with this method ?

Well, the main issue seems to be that the post-update injection I trigger manually (from background.js) is happening after the onDisconnect from the previous install that I have set up in the content script to clean up the port & event listeners, so my fresh injection immediately clears itself.

I’m wondering whether I need that odd JS stanza [ ( function() { {object+code-here} } )() ] I see around that declares my comms port and deregistration code within a transient object that somehow will survive a reload (?), if only briefly.

The other worrying aspect that made me think I was onto a loser is that even checking with debug that I’m only injecting onto tabs that already have my extension automatically, I still get async “need host permission” errors popping out afterwards.

Do you have <all_urls> in the permissions array of your manifest.json ?

Yes, and injection into pages that are freshly loaded or re-loaded works fine.

Also, I’ve added debug to show the URLs of the open tabs it’s being injected into and debug in the injected script.

I can see I’m only injecting into pages that I ought to, and those pages report the injection has succeeded (apart from the fatal issue above of the injection happening before the previous instance has been removed, meaning they get removed straight away).

Frankly, I’m more worried about that timing issue than seemingly incorrect permissions reports; I’ll play a little more with this odd transient object/function syntax as I have a feeling it’ll work better by uniquely tying the iterations’ comms ports and listener deregistrations with the correct earlier registrations. I’ll have a chance to tomorrow, been busy for the past couple of days so not looked at it since my first post.

I mostly wanted to ensure I was on the right path, as the number of odd things I was having to overcome made it look like it might be the wrong one.

These are my observations:

  • When the extension is disabled (before it’s update), Firefox nukes the sandboxes the content scripts are executed in. That means all event listeners and objects you created will be gone, but changes to the DOM can’t be undone. There is no way to detect an extension unload event in a content script.

  • Static content scripts defined in the manifest.json will be applied to already open pages by Firefox, but not by Chrome

My observations don’t seem to tally with yours :-/

I’d heard that Chrome injects static content scripts to open tabs for you, but FF doesn’t; this is what I see, and why I started trying to manually re-inject the ones from my manifest.

And you sort-of can detect updates from the content scripts if you have a port open: you get an onDisconnect callback.

However, the issue that’s driving me utterly insane is that I am repeatedly getting the onDisconnect for the previous install after the injection from the new update [which I am triggering from the bottom of my background.js].

I have tried all sorts of tricks to try to keep the connections separate, up to having a connection manager class that creates new instances each time. Or tries to. Nothing works, I cannot get injected content scripts to create & maintain a port to my updated extension. It only work if I refresh the tab and let FF do the injection.

I’m just going to have to give up, I think, and put a note on the pop-up readme that it won’t work on open tabs until you refresh them :frowning:

That works in Chrome, yes. The last time I checked it (version 54 maybe) it did not work in Firefox and my quick test now in FF57 confirms that.

However, the issue that’s driving me utterly insane is that I am repeatedly getting the onDisconnect for the previous install after the injection from the new update [which I am triggering from the bottom of my background.js].

If you are still talking about onDisconnect on ports, could’t you just stop listening on the port after the first event?