[webkit-gtk] Custom JavaScript injection API and Isolated Worlds in WebKit2GTK+

Carlos Garcia Campos cgarcia at igalia.com
Fri Aug 9 08:04:37 PDT 2013


I've finally started to work on those APIs. They will be available
through the Web Extensions API since the JavaScript has to be injected
in the WebProcess. 

First of all, we need to expose Frames in the API, since java script
contexts and script worlds are associated with Frames. We have managed
to not expose frames in the UI process API so far, but we can't never be
sure if we'll need it eventually, so I propose to call frames in Web
Extensions API WebKitWebPageFrame (as the frame of a page, since we
already have WebKitWebPage in the extensions API). This way, if we end
up exposing frames in the UI process API we can call it WebKitWebFrame.
We could do the opposite, and use WebKitWebFrame in the web extensions
API and if we eventually expose frames in the UI process we call them
WebKitWebViewFrame. I think it could be more confusing because
WebKitWebFrame is a frame of a WebKitWebView in WebKit1, but I'm open to
both options in any case.

My initial proposal for frames API would be something like this:

gboolean webkit_web_page_frame_is_main_frame (WebKitWebPageFrame *web_frame);

const gchar *webkit_web_page_frame_get_uri (WebKitWebPageFrame *web_frame);

JSGlobalContextRef webkit_web_page_frame_get_javascript_global_context (WebKitWebPageFrame *web_frame);

Instead of adding a window-object-cleared signal to the frame, I think
we could make it more explicit that this is happening for a script
world. So I propose to add a WebKitScriptWorld object with the
window-object-cleared signal. The WebKitScriptWorld API would be very
simple:

WebKitScriptWorld *webkit_script_world_get_default (void);

WebKitScriptWorld *webkit_script_world_new (void);

The default script world is the one associated to the main thread of the
web process, the one always used in WebKit1, also called the normal
world in WebKit. Then you can create isolated worlds with
webkit_script_world_new(). To get the JS context of the isolated worlds
we need to add a new method to the frame API:

JSGlobalContextRef webkit_web_page_frame_get_javascript_context_for_script_world (WebKitWebPageFrame *web_frame,
                                                                                  WebKitScriptWorld  *world);

Once you have the context you can use the JSCore API to evaluate script
in the isolated world, or whatever. 

To inject custom javascript in the normal world, using the
window-object-cleared signal like in WebKit1, you just need to connect
to the window-object-cleared signal of the default script world.

g_signal_connect(webkit_script_world_get_default (), "window-object-cleared", 
                 G_CALLBACK(window_object_cleared), NULL);

In the callback you can get the javascript context and the global object
to inject the custom code using the JSC API.

static void 
window_object_cleared (WebKitScriptWorld  *world, 
                       WebKitWebPage      *page, 
                       WebKitWebPageFrame *frame, 
                       gpointer            user_data)
{
    JSGlobalContextRef jsContext = webkit_web_page_frame_get_javascript_context_for_script_world (frame, world);
    JSObjectRef globalObject = JSContextGetGlobalObject (jsContext);
    .....
}


This would be the minimal API to be able to inject custom javascript,
then we can add more API on top, like a method to get the security
origin of a frame, etc.

What do you think? is this enough or am I missing something?

-- 
Carlos Garcia Campos
http://pgp.rediris.es:11371/pks/lookup?op=get&search=0xF3D322D0EC4582C3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://lists.webkit.org/pipermail/webkit-gtk/attachments/20130809/09558932/attachment.sig>


More information about the webkit-gtk mailing list