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.

_______________________________________________
webkit-gtk mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-gtk

Reply via email to