w3c / webextensions

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

Inconsistency: inIncognitoContext is not available in a userscript world in Chrome #605

Closed tophf closed 4 months ago

tophf commented 4 months ago

In Chrome chrome.extension.inIncognitoContext boolean is not available in a userscript world because the entire chrome.extension is not exposed there. It's exposed only in the default isolated world.

Since there's no API to communicate between the worlds securely, we can't read this value at document_start in a userscript of an extension that uses the default spanning incognito mode. Only when using the split mode an extension can embed the value in code of a registered userscript just for the incognito mode. Even when there will be a secure cross-world communication method, we still don't want to spin up an isolated world unnecessarily (if we can do everything in a userscript world) as that consumes more than 40kB of memory and some time to initialize the JS environment.

Arguably the entire chrome.extension should be exposed to the userscript world. Firefox already does that.

zombie commented 4 months ago

In the discussion about user script world, we had consensus that we want to minimize the number of APIs exposed, so in our (Mozilla) opinion, this feature request is best addressed through the secure communication channel with the content script world.

tophf commented 4 months ago

best addressed through the secure communication channel with the content script world

  1. It's unclear why you prefer unnecessarily spinning up a whole JS world rather than exposing a simple boolean.
  2. ~Does Mozilla plan to remove chrome.extension which is currently exposed to userscripts in Firefox?~
tophf commented 4 months ago

I was confused by Greasemonkey4, which surprisingly still uses a standard isolated content script world, so the rejection by Mozilla makes sense.

However, in Violentmonkey we don't need anything from the isolated content script world except this one boolean value. We don't use storage. We only use messaging, which is available in the userscript world. We don't want to waste memory for users who have a lot of tabs/frames, so if this is not implemented we'll have to abandon the idea of using the spanning incognito mode.

I guess I should make another issue about exposing this boolean in chrome.runtime and removing chrome.extension in the isolated world too because it only contains this one boolean value (in Chrome)?

Rob--W commented 4 months ago

best addressed through the secure communication channel with the content script world

  1. It's unclear why you prefer unnecessarily spinning up a whole JS world rather than exposing a simple boolean.

We are operating under the assumption that user script managers need to expose privileged functionality to some individual user scripts. Since many user script APIs are synchronous, this would either require all information to be available upfront and duplicated in each user script world, or for there to be some user script world "manager" that holds the central source of truth and selectively exposes the relevant information to individual user script worlds. An extension content script could have the responsibility of being that manager.

The user script world as a minimal set of APIs by design (https://github.com/w3c/webextensions/blob/main/proposals/user-scripts-api.md#user_script-world). If a content script world already contains the necessary information and (privileged) functionality that you need, then it would make sense to build upon that more general primitive than to introduce browser support for multiple individual user script APIs. As an example of other functionality: there is a separate feature request on having a global blocklist at #607. This could be implemented by the user script world "manager" (content script) to be notified before a script is executed, which could then decide to veto the injection of a user script.

If you are concerned about overhead: then you can make the isIncognito property of GM_info a getter that lazily retrieves the value of the incognito status. I expect this field to have relatively little use in user scripts, so for the common case the performance impact would be minimal.

tophf commented 4 months ago

For Violentmonkey's controller a userscript world is entirely sufficient, we don't need the isolated world.

If you are concerned about overhead: then you can make the isIncognito property of GM_info a getter

There's no API to lazily and synchronously create the isolated world.

So should I make another issue about exposing this boolean in chrome.runtime and removing chrome.extension in the isolated world altogether because it only contains this one boolean value (in Chrome)?

tophf commented 4 months ago

Superseded by #611.