Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.

OnWebKitInitialized isn't fired

Albus

OnWebKitInitialized isn't fired

Post by Albus »

Hi, I'm trying to register an own extension to chromium with the CefRegisterExtension command. Here is my code:

Code: Select all

procedure ProcessHandler_OnWebKitInitializedEvent;
var
  code: string;
begin
  code := '__defineGetter__(''app'', function(){native function $get();return $get()});';
  CefRegisterExtension('app', code, TDVCefBridge.Create as ICefv8Handler);
end;

class procedure TMyClass.InitChromium;
var
  TempProcessHandler: TCefCustomRenderProcessHandler;
begin
  TDVCefBridge.FCallbackClasses := TDictionary<TChromium,TValue>.Create;

  TempProcessHandler := TCefCustomRenderProcessHandler.Create;
  TempProcessHandler.OnWebKitInitializedEvent := ProcessHandler_OnWebKitInitializedEvent;

  GlobalCEFApp := TCefApplication.Create;
  GlobalCEFApp.CheckCEFFiles := False;
  GlobalCEFApp.EnableHighDPISupport := True;
  GlobalCEFApp.RenderProcessHandler := TempProcessHandler as ICefRenderProcessHandler;
  GlobalCEFApp.StartMainProcess;
end;
I call the InitChromium procedure as first command in the dpr file. But neither the event procedure is ever called nor I can access "app" in JavaScript.

But when I add "GlobalCEFApp.SingleProcess := True;" to the Init procedure, everything works fine. But this is not an option for production use.

Can anyone help me? If you need more code or explanations, just ask :)
User avatar
salvadordf
Posts: 4049
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: OnWebKitInitialized isn't fired

Post by salvadordf »

Hi Albus,

The TCefCustomRenderProcessHandler.OnWebKitInitializedEvent event is triggered after a browser is created.
In the JSExtension demo the browser is created in the TJSExtensionFrm.FormShow event with the call to Chromium1.CreateBrowser(CEFWindowParent1, '').

You can check this by adding text messages to the 'debug.log' file with something like this :
CefLog('CEF4Delphi', 1, CEF_LOG_SEVERITY_ERROR, 'My custom debug text');
You'll probably need to add uCEFMiscFunctions and uCEFConstants to the uses clause to use the CefLog function.

Without the rest of your code, I can only tell you that the GlobalCEFApp.StartMainProcess call MUST be in a if..then clause like this :

Code: Select all

  if GlobalCEFApp.StartMainProcess then
    begin
      Application.Initialize;
      {$IFDEF DELPHI11_UP}
      Application.MainFormOnTaskbar := True;
      {$ENDIF}
      Application.CreateForm(TJSExtensionFrm, JSExtensionFrm);
      Application.CreateForm(TSimpleTextViewerFrm, SimpleTextViewerFrm);
      Application.Run;
    end;
If you don't do this you'll have problems with the subprocesses as explained in this web page :
https://www.briskbard.com/index.php?lang=en&pageid=cef

Take a look at the JSExtension demo to register your own extension.
Albus

Re: OnWebKitInitialized isn't fired

Post by Albus »

Hi, I changed my code know so I use the if-statement, but "nothing" changed. Where can I find the log file?
User avatar
salvadordf
Posts: 4049
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: OnWebKitInitialized isn't fired

Post by salvadordf »

I forgot to tell you that you have to add this before the GlobalCEFApp.StartMainProcess call :

Code: Select all

  GlobalCEFApp.LogFile              := 'debug.log';
  GlobalCEFApp.LogSeverity          := LOGSEVERITY_ERROR;
The 'debug.log' file will be next to your EXE.

Take the JSExtension as a base for your application. It's a working example of a simple javascript extension and its registration.

Edit : Be sure to give a unique name to your extension. There should be nothing called the same way.
Albus

Re: OnWebKitInitialized isn't fired

Post by Albus »

The log says that the OnWebkitinitialized Event is called twice (I have two browsers in my app), but still I can't access the registered extension from JavaScript.
But if I activate GlobalCEFApp.SingleProcess it works.
Albus

Re: OnWebKitInitialized isn't fired

Post by Albus »

Hm, I added some more logging, and saw that the Execute function is called every time a try to access the extension. But I can't debug the function (I think because of mutli processes?). Is there any way to debug the execute function without using singleprocess mode? Because in single process mode everything works fine
Albus

Re: OnWebKitInitialized isn't fired

Post by Albus »

Ok, I managed to debug the subprocess and found out directly where the error is. I had reimplemented the Execute function for the extensions to support some of my own behavior. This also includes storing values in a Dictionary from within the application, which are queried later in the Execute function. However, this dictionary is never filled in the subprocesses, and since it is empty, my Execute function terminates at the beginning with the return value False.
User avatar
salvadordf
Posts: 4049
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: OnWebKitInitialized isn't fired

Post by salvadordf »

Yes, javascript is executed in a different process and Delphi can't debug it.

As far as I know, you only have 3 options :
  • Use a single process and use Delphi to debug it.
  • Use multiple processes and call CefLog.
  • Use the DevTools.
In your case, I would call CefLog in multiple places. When you detect what part of the code is not executed then add more CefLog calls there with the variable contents converted to text.

You might find the DevTools useful to see any console error messages or to set javascript breakpoints. Take a look at the MiniBrowser demo to add the DevTools to your app.

Edit : I wrote this for your previous message :P I see now that you found the solution for yourself.
Albus

Re: OnWebKitInitialized isn't fired

Post by Albus »

My solution for debugging is the "Connect with process" function in the IDE. I started the application without debugging and then I connected the IDE to the right subprocess.

However I need a solution for this problem. Even we have to use the single process mode in production or there is an other better solution, because single process mode shouldn't been used for production.
User avatar
salvadordf
Posts: 4049
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: OnWebKitInitialized isn't fired

Post by salvadordf »

Perhaps you can use messages between processes to do that.

The JSEval demo sends messages in both ways :
Browser process <-> Render process
Post Reply