Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for UI-less extensions #3258

Open
RendijsSmukulis opened this issue Mar 2, 2023 · 6 comments
Open

Support for UI-less extensions #3258

RendijsSmukulis opened this issue Mar 2, 2023 · 6 comments
Assignees
Labels
feature request feature request tracked We are tracking this work internally.

Comments

@RendijsSmukulis
Copy link

RendijsSmukulis commented Mar 2, 2023

Our browser would benefit from support of webextensions in WebView2:

  • Being able to load our own existing extensions would significantly reduce the amount of effort required to port existing features from our existing extensions to native code.
  • In some situations, this will also give us additional capabilities that WebView2 currently does not support (for example modifying the Cookie header of the request).

We realize that some APIs (such as "tabs") don't make sense in the context of WebView2, but since we would control both extension and native code we can make those work (as needed) ourselves. On the WebView2 side of things those could be noops.

Additional notes:

  • We envision extension to be shipped with our browser.
  • Initial set of extension APIs that's crucial to us:
  • Apple is currently in the process of adding extension support to their WKWebView.

AB#43658387

@novac42
Copy link
Contributor

novac42 commented Mar 3, 2023

@RendijsSmukulis Thanks for the post. We are tracking extension related feature request under #191.

@novac42 novac42 self-assigned this Mar 3, 2023
@MarkIngramUK
Copy link

@novac42 , there's a big difference between extensions with UI support, and extensions without. Does it make sense to track both feature requests under one ticket?

@MarkIngramUK
Copy link

Related: #3259

@novac42
Copy link
Contributor

novac42 commented Mar 6, 2023

@MarkIngramUK 191 is the overall post for extensions requests but I understand your point. I will add tracked label to generate a separate item in backlog for UI-less extensions specifically.

@novac42 novac42 added the tracked We are tracking this work internally. label Mar 6, 2023
@MarkIngramUK
Copy link

Thanks @novac42 , I appreciate the consideration.

@RendijsSmukulis
Copy link
Author

As the Extensions API proposal is now published, as discussed previously we're happy to provide some background how we intend to use the feature.

Background

We are currently looking to migrate a subset of our Privacy Essentials Extension functionality to the our WebView2-based browser using the proposed WebView2 Extensions API.

As the initial version of this API is understood to be "UI-less", that is, will not provide ways to surface UI elements to the user (such as the extension popup window or the extension's status icon on the address bar), we are looking for ways to host these elements in our application's native components.

After the review of the proposed Extensions API, we have two high-level questions to judge the feasibility of what we're trying to achieve:

  1. How will communications between the native app an extension be supported?
  2. What set of Extension APIs will be expected to work on initial release?

1. Extension-To-Native Communications

To be able to host the extension's UI in a native control, separate from WebView2, the state of the extension needs to be communicated to the native code in some way. For example, when user modifies a setting in the native app, the setting change needs to be sent to the extension to modify its behaviour. Similarly, when some event happens in the extension (e.g. it has blocked a network request), this information needs to flow through the native code to be presented to the user.

Similarly, the two-way communication is also required to fill in API gaps for concepts that exist outside a webview, such as "tabs" and "windows". For example, there is no way for WebView2 to correctly respond to the extensions query of "What tabs exist in the active window" if it has no concept of:

  • Current collection of windows,
  • Currently active window
  • Tabs in windows
  • Information specific to those tabs, such as sizing (or at least what WebView2 instance is associated with said tab).

As no API is currently presented to convey these concepts from native app to webview2, a method of communicating between the extension and native code is required to create "polyfill" that can allow the app's native code side to respond to the queries (even if this requires changes to the extension's code to use the polyfill version rather than the "chrome.tabs", "chrome.window" or similar APIs)

Apple is currently in the process of adding extension support to their WKWebView, and has published some interfaces that, implemented by the host app, allows to communicate the required information to the WebView:

  • Their API is also allowing the host application to communicate such info as tab and window data to the extensions by providing interfaces that can be implemented in the host app to represent concepts that the extensions "understand", e.g.:
  • _WKWebExtensionTab.h interface to communicate a tab state to the extension and accept commands from the extension, e.g.:
    • (BOOL)isSelectedForWebExtensionContext:(_WKWebExtensionContext *)context; to indicate if the tab is the currently selected tab
    • (void)reloadForWebExtensionContext:(_WKWebExtensionContext *)context; to force a reload of the specific frame
  • and _WKWebExtensionWindow.h to achieve the same, but for a window, e.g.:
    • NSArray<id <_WKWebExtensionTab>> *)tabsForWebExtensionContext to get the tabs in a specific window
    • (BOOL)isFocusedForWebExtensionContext:(_WKWebExtensionContext *)context; to indicate if the window is currently focused
    • (NSRect)frameForWebExtensionContext:(_WKWebExtensionContext *)context; to get the window size/location

2. What Extension APIs Will Be Supported?

The second open question is what is the set of supported APIs for extensions in the initial release. It's clear that such apis as "chrome.tabs" and "chrome.windows" can't currently be supported, but it is not clear what other APIs might be expected to not be functional. We provide a list of APIs we currently rely on in Appendix A.

Appendix A

What APIs the Privacy Extension currently relies on

Note: this list skips UI-specific apis, as the current iteration of WebView2 is not expected to support any UI elements for extensions.

webRequest

chrome.webRequest.onBeforeRequest.addListener - multiple features
chrome.webRequest.onBeforeSendHeaders.addListener - 3rd party cookie protection, GPC header protection, referrer trimming feature
chrome.webRequest.onHeadersReceived.addListener - 3rd party cookie protection, ad click detection

webNavigation

chrome.webNavigation.onCommitted.addListener
chrome.webNavigation.onCommitted.removeListener
chrome.webNavigation.onCreatedNavigationTarget.addListener
chrome.webNavigation.onBeforeNavigate.addListener
chrome.webNavigation.onCompleted.addListener

declarativeNetRequest

Same functionality as the webRequest API above, required for when MV2 is no longer supported
chrome.declarativeNetRequest.updateSessionRules
chrome.declarativeNetRequest.updateDynamicRules

runtime

chrome.runtime.onMessage.addListener - multiple features (e.g. injected content scripts communicating with the extension)
chrome.runtime.sendMessage - as above

tabs

chrome.tabs.update(thisTab.id, { url: newUrl }): for AMP protections
chrome.tabs.sendMessage(tab.id, {..}): autofill
chrome.tabs.onCreated.addListener: keeping track of current tabs, multiple features
chrome.tabs.onUpdated.addListener((id, info) ..: keeping track of current tabs, multiple features
chrome.tabs.onRemoved.addListener((id, info) ..: keeping track of current tabs, multiple features
chrome.tabs.query({}) - autofill

scripting

chrome.scripting.insertCSS
chrome.scripting.registerContentScripts

storage

chrome.storage.local.set
chrome.storage.local.get
chrome.storage.session.set
chrome.storage.session.get
chrome.storage.session.remove

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request feature request tracked We are tracking this work internally.
Projects
None yet
Development

No branches or pull requests

4 participants