Bug 238598 - [WPE][GTK] Missing API to pass client-side messages to new pages on the web extension side
Summary: [WPE][GTK] Missing API to pass client-side messages to new pages on the web e...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: WPE WebKit (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Pablo Saavedra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-03-31 02:18 PDT by Claudio Saavedra
Modified: 2022-05-24 07:02 PDT (History)
4 users (show)

See Also:


Attachments
1st tentative patch (17.02 KB, patch)
2022-05-13 02:26 PDT, Pablo Saavedra
no flags Details | Formatted Diff | Diff
2st tentative patch (20.20 KB, patch)
2022-05-19 07:55 PDT, Pablo Saavedra
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Claudio Saavedra 2022-03-31 02:18:10 PDT
While it is possible to pass client-side messages to a web page right after a view has been created (with the webkit_web_view_send_message_to_page() API), there's no way for the WebView to know if the web process has created a new page (due to navigation, for example), in order to send a message to that new page, for cases when data should be available to a specific page and not to all via web extension data.

There could be two independent approaches to do this, both would require some new API in WebKit:

1. For data that is immutable, one could mimic webkit_web_context_set_web_extensions_initialization_user_data() and add a webkit_web_view_set_web_page_initialization_data() method that would allow passing of initialization data to pages. Then on the web extension side, one could call a webkit_web_page_get_initialization_data() method (for example, in the "page-created" signal handler), in order to get that data. This would not allow to pass arbitrary messages any time that a new page is created, though.

2. For the latter, an alternative would be to have a WebKitWebView:page-created signal that can be used to send a new message via the existing webkit_web_view_send_message_to_page() method, if needed.

These approaches are complementary and both could be implemented, for our use-case either would work, so the idea is to discuss here possible drawbacks and a course of action before starting any implementation.
Comment 1 Pablo Saavedra 2022-04-22 04:09:41 PDT
This proposal that comes after a conversation with  aperez (igalia.com):


We could add a new signal in the webview. There is a `didReceiveSynchronousMessageFromInjectedBundle()`, when the webprocess sends a sync message to the uiprocess it will pause waiting for a reply. We could send a sync message whenever a new page is created (new page in webprocess = new page load). It would be like this:

1. When a WebKitWebPage is going to be created (which happens for every new load), send a sync message to the UIProcess.
2. In the UIProcess, receive the message, emit signal WebKitWebView::configure-web-extension-page (maybe not the best name) that it runs once per WebKitWebPage
3. If a signal handler for the signal returns a GVariant, send it back as response to the sync message.
4. Back in the WebProcess, if a GVariant is received, assign it to the WebKitWebPage.initialization-data property.
5. Emit WebKitWebExtension::page-created normally. Signal handlers in webprocess extensions can read the data returned in (2.) using the WebKitPage.initialization-data property at this point, before the load starts, or even later when WebKitScriptWorld::window-object-cleared is emitted (because signal handlers for this signal receive the WebKitWebPage, too)
Comment 2 Pablo Saavedra 2022-04-27 06:41:38 PDT
Unfortunately the `WKBundlePostSynchronousMessage()` is a deprecated method of the C API nowadays:

Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundle.h:WK_EXPORT void WKBundlePostSynchronousMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnRetainedData) WK_C_API_DEPRECATED;
Comment 3 Pablo Saavedra 2022-05-13 02:26:16 PDT
Created attachment 459285 [details]
1st tentative patch
Comment 4 Pablo Saavedra 2022-05-13 02:34:36 PDT
I just uploaded a 1st tentative but functional patch that in some how could establish the ground for this change.

Example of use:


- UI-process:

  ```
  g_signal_connect(webView, "initialize-web-extensions", G_CALLBACK(onInitializeWebExtensions), nullptr);

  void View::onInitializeWebExtensions(WebKitWebView* webView, gpointer*)
  {
    webkit_web_view_set_web_extensions_initialization_user_data(webView, g_variant_ref_sink(g_variant_new("(s)", "foo")));
  }
  ```

- WebProcess extension:

  ```
  g_signal_connect(
    webExtension,
    "initialize-web-extensions",
    G_CALLBACK(+[](WebKitWebExtension*, GVariant* userData, WebProcessExtension* self)
    {
        // Callback
    }),
    this);
  ```
Comment 5 Pablo Saavedra 2022-05-19 07:55:23 PDT
Created attachment 459586 [details]
2st tentative patch
Comment 6 Pablo Saavedra 2022-05-22 00:19:36 PDT
Pull request: https://github.com/WebKit/WebKit/pull/891