w3c / webextensions

Charter and administrivia for the WebExtensions Community Group (WECG)
Other
578 stars 50 forks source link

Proposal: RegisteredContentScript.tabIds and RegisteredContentScript.excludeTabIds properties to filter injection #539

Open hackademix opened 5 months ago

hackademix commented 5 months ago

(As discussed in #103)

Use Case

Some time-critical features can be provided only by document_start registered content scripts which run before any page script has a chance to: scripting.executeScript() is useless for this, bacause it doesn't provide reliable time guarantees.

However users may want to turn such features on/off on certain tabs only, e.g. in order to be sure a multi-site workflow like an e-commerce check-out/payment one are not disrupted by the extension. That's the case of the Disable all restrictions for this tab NoScript command, for instance.

Proposal

The above use case would be served if script registration could be filtered by tabId.

Therefore, in addition to the RegisteredContentScript properties already specified, we propose to add:

If any of these two parametersThis filter could only be specified for non-persistent script registration, and would throw TypeError otherwise)

[^1]: even if this might seem just a fancy expensive way to disable the RegisteredContentScript, it can be argued that it's the least surprising and most consistent API. Alternatively, passing an empty array could throw as an invalid type. The worst, to be avoided at all costs to prevent bugs, would be an empty tabIds array falling back to match any tab.

[^2]: the different behavior regarding persistence between tabIds and excludeTabIds provides a reliable mechanism to both turn off persistent features and add temporary features on certain tabs only.

hackademix commented 4 months ago

Better clarified the use case and proposed behavior regarding persistence in the main issue description, as a follow up of today's meeting discussion.

oliverdunk commented 2 months ago

Hey @hackademix, thanks for opening this issue! I think you mentioned you had some workarounds for this in MV2 - would you be able to share what those are and how well they work?

We discussed this a bit on the Chrome side. We have no concerns about the capability, but are also concerned that this doesn't feel like the right sort of thing to be adding to this API. A better solution seems like being able to set global and per-tab parameters for content scripts, that you could then access synchronously from inside them. This is something we've discussed in the past and would still like to look at in the future.

Going to remove our follow-up label for now but definitely open to continuing the conversation.

hackademix commented 2 months ago

Hey @oliverdunk, thank you for looking into this.

I believe the work-around you might have heard me alluding to is (https://github.com/hackademix/nscl/blob/main/service/DocStartInjection.js]this DocStartInjection NSCL module), which I don't think easily translates to the MV3 world because:

  1. It depends on a combined use of browser.contentScripts.register() on Firefox and browser.tab.executeScript() on Chromium, carefully timed and/or brute forced from both webNavigation and webRequest listeners.
  2. It relies on belters and suspenders, based even on syncrhonous XHR, to reliably handle some edge cases such as file:/// URLs

Therefore I really hope you reconsider the opposed:chrome label you've just attached to this issue, or otherwise finally act ASAP on your parametrized content scripts proposal, because we've been talking about this for more than 3 years now but for some reason we're still stuck here. Thanks again!