[webkit-gtk] Calling a native (compiled) subprogram from JavaScript in WebKitGTK
Ludovic Brenta
ludovic at ludovic-brenta.org
Tue Sep 12 07:29:20 PDT 2017
Hello,
I am extending a multi-million-line-of-code application written
in Ada with a new WebKitGTK browser window, using the WebKit2GTK
API.
After reading [1] and [2] I am trying to expose an Ada (or C,
C++, Vala, whatever) subprogram to the JavaScript engine in
WebKit, so that JavaScript code can call it.
[1] http://www.davedoesdev.com/wrapping-webkit-part-1-gtk+-vala/
[2] https://karhm.com/JavaScriptCore_C_API/
The gist of it is: attach a callback to the "load-changed" signal
of the WebKitWebView. If the Load_Event is "finished", create a
new function object (by calling JSObjectMakeFunctionWithCallback);
add to the global object of the WebView a new property whose name
is the name of the function as seen from JavaScript and the value
is the function object.
If I try to call the function thus exported (and aptly named
"exported"), the JavaScript engine throws:
ReferenceError: Can't find variable: exported
I am suspecting that I'm attaching the property to the wrong
global object. Since I'm stuck with Red Hat Enterprise Linux
and the webkitgtk3-devel-2.4.9-6.el7.x86_64 package, I have no
debugging info available for WebKit itself (only for the host
application), so I can't easily debug what's happening. All I
can tell for sure is that Get_Javascript_Global_Context,
Get_Global_Object, String.To_JavaScript etc all return non-null
and that Exceptions remain null after the call to Set_Property.
Am I doing something wrong? Is this feature even supported with
WebKit2 or should I switch to the deprecated WebKit 1 that does not
use a separate process?
type Attribute_T is (None, Read_Only, Dont_Enum, Dont_Delete);
type Attributes_T is array (Attribute_T) of Boolean with Pack, Size
=> Interfaces.C.unsigned'Size;
function Get_Global_Object (Ctx : in Context_T) return T
with Convention => C, Import, External_Name =>
"JSContextGetGlobalObject";
procedure Set_Property (Ctx : in Context_T;
Object : in T;
Property_Name : in String.T;
New_Value : in Value.T;
Attributes : in Attributes_T;
Exceptions : out Value.T)
with Convention => C, Import, External_Name =>
"JSObjectSetProperty";
type Callback_T is access function (Ctx : in
Context_T;
Func : in T;
This : in T;
Argument_Count : in
Interfaces.C.size_t;
Arguments : in
Value.Arrays.Pointer;
Exceptions : out Value.T)
return Value.T with Convention => C;
function Make_Function_With_Callback (Ctx : in Context_T; Name : in
String.T; Callback : in Callback_T) return T
with Convention => C, Import, External_Name =>
"JSObjectMakeFunctionWithCallback";
procedure Export_Ada_Function_To_Javascript (Ctx : in
Context_T;
Javascript_Name : in
Standard.String;
Ada_Function : in
Callback_T) is
Global : constant T := Get_Global_Object (Ctx);
Name : constant String.T := String.To_Javascript (Javascript_Name);
Func_Obj : constant T := Make_Function_With_Callback (Ctx,
Name => Name,
Callback =>
Ada_Function);
Exceptions : Value.T;
begin
Set_Property (Ctx,
Object => Global,
Property_Name => Name,
New_Value => Value.T (Func_Obj),
Attributes => (Read_Only => True, others =>
False),
Exceptions => Exceptions);
-- TODO: log Exceptions, possibly raise an Ada exception?
end Export_Ada_Function_To_Javascript;
procedure On_Load_Changed (View : not null access
Webkit.Web_View.Record_T'Class;
Load_Event : in
Webkit.Web_View.Load_Event_T) is
begin
case Load_Event is
when Webkit.Web_View.Started | Webkit.Web_View.Redirected |
Webkit.Web_View.Committed => null;
when Webkit.Web_View.Finished =>
Javascript.Object.Export_Ada_Function_To_Javascript (Ctx =>
View.Get_Javascript_Global_Context,
Javascript_Name => "exported",
Ada_Function => Exported'Access);
end case;
exception
when others =>
UIF_Error.Report (Kind => UIF_Error.Operation_Aborted,
Unit_Name => Display_Name,
Message => "Exception in
Regulation_Editor.Browser_Window.On_Load_Changed");
end On_Load_Changed;
--
Ludovic Brenta.
More information about the webkit-gtk
mailing list