Recent

Author Topic: fpCef3: browser talk to Host (=Lazarus app)  (Read 4287 times)

PaulANormanNZ

  • Full Member
  • ***
  • Posts: 117
fpCef3: browser talk to Host (=Lazarus app)
« on: January 22, 2018, 04:01:23 am »
Before I start dredging the enormous thousands of the CEF Forum messages -

1. has any one successfully implemented Javascript in a hosted document "talking" to FP objects / procedures in a Lazarus Host project - I see hints in the DOM that this might be achievable...

2. Also in a similar way I see that we can call a JavaScript function in the Browser from Lazarus - can we receive a returned string,  object etc... into Lazarus from the hosted browser?

Ok, so we can do...

Code: HTML5  [Select][+][-]
  1. function myFunct(text){
  2. alert(text);
  3. }
  4. <div id="trialArea">Hi!</div>
  5. </body></html>

Code: Pascal  [Select][+][-]
  1. procedure TForm1.btnDoJavaScriptClick(Sender: TObject);
  2. begin
  3.    Chromium.Browser.MainFrame.ExecuteJavaScript('myFunct("hello")', 'about:blank', 0);
  4. end;

And a nice alert() or whatever requested will take place.

But can I usefully receive something back to a Lazarus app from JavaScript in the Browser? As in the html script being along the lines of...

Code: Javascript  [Select][+][-]
  1. <script>
  2. function myFunct(text){
  3.  
  4. return text + ' - ok';
  5. }
  6. </script>

And then (pseudo code) something looking a bit like...

Code: Pascal  [Select][+][-]
  1. var ResponseText : string;
  2.  
  3. ResponseText := Chromium.Browser.MainFrame.ExecuteJavaScript('myFunct("hello")', 'about:blank', 0) as string;

Or even an ICef object or variant of some sort?

Any help appreciated please,

Paul
« Last Edit: January 22, 2018, 04:46:17 am by PaulANormanNZ »

PaulANormanNZ

  • Full Member
  • ***
  • Posts: 117
Re: fpCef3: browser talk to Host (=Lazarus app)
« Reply #1 on: January 22, 2018, 04:47:29 am »
P.S.  related to other posts I've made on fpCEF - I'm thinking it would be useful to be able to exchange JSON strings between Lazarus and the hosted CEF browser,
where carefully crafted JavaScript in the browser frame document could handle many things and return results to Lazarus
- avoiding much Lazarus coding perhaps - why rebuild the wheel if JavaScript in the Lazarus hosted Browser can already drive the DOM?

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: fpCef3: browser talk to Host (=Lazarus app)
« Reply #2 on: January 22, 2018, 08:23:57 am »
carefully crafted JavaScript in the browser frame document could handle many things and return results to Lazarus
If you decide to take this route then JSONRPC might be interesting to you:
FPC: https://github.com/graemeg/freepascal/tree/master/packages/fcl-web/examples/jsonrpc/demo1
3rd party: http://www.jbsolucoes.net/ceosserver/
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

dliw

  • New Member
  • *
  • Posts: 21
Re: fpCef3: browser talk to Host (=Lazarus app)
« Reply #3 on: January 22, 2018, 10:59:43 am »
If you combine the DomAccess and JavaScript fpCEF examples, you have all you need.

Also see this code on how to use messaging:
https://forum.lazarus.freepascal.org/index.php/topic,34519.msg226411.html#msg226411

fpCEF already provides an OOP abstraction for all low level APIs, but one cannot abstract the complexity of having multiple processes.

For message passing you have ICefProcessMessage, which allows you to pass all default value types and even binary streams (see ICefValue).
Of course you could pass data only via JSON strings, but IMO you would only replace the existing in-built system with a different one adding even more complexity.
« Last Edit: January 22, 2018, 11:01:41 am by dliw »

PaulANormanNZ

  • Full Member
  • ***
  • Posts: 117
Re: fpCef3: browser talk to Host (=Lazarus app)
« Reply #4 on: February 02, 2018, 08:40:31 am »
Hi,
Thanks for the Posts.

Still just wondering ...

1. has any one successfully implemented Javascript in a hosted document "talking" to FP objects / procedures in a Lazarus Host project - I see hints in the DOM that this might be achievable...

2. Also in a similar way I see that we can call a JavaScript function in the Browser from Lazarus - can we receive a returned string,  object etc... into Lazarus from the hosted browser?
 - I can't yet see how messaging does that. Can these get "things" back to the application?...

Quote
For message passing you have ICefProcessMessage, which allows you to pass all default value types and even binary streams (see ICefValue).

Any thoughts please,

Paul

dliw

  • New Member
  • *
  • Posts: 21
Re: fpCef3: browser talk to Host (=Lazarus app)
« Reply #5 on: February 02, 2018, 10:01:51 am »
The answer to both is: yes

Please see the Javascript example:

1. See TCustomRenderProcessHandler.OnWebKitInitialized:
There is
Code: Pascal  [Select][+][-]
  1. native function GetTestParam()
which registers a Pascal function in Javascript.

Every time you call a native function the registered handler
Code: Pascal  [Select][+][-]
  1. TMyHandler.Execute
is called.
There you have every information needed to handle the call:
Code: Pascal  [Select][+][-]
  1. // Structure that should be implemented to handle V8 function calls. The
  2. // functions of this structure will be called on the thread associated with the
  3. // V8 function.
  4. TCefV8Handler = record
  5.   [..]
  6.  
  7.   // Handle execution of the function identified by |name|. |object| is the
  8.   // receiver ('this' object) of the function. |arguments| is the list of
  9.   // arguments passed to the function. If execution succeeds set |retval| to the
  10.   // function return value. If execution fails set |exception| to the exception
  11.   // that will be thrown. Return true (1) if execution was handled.
  12.   execute: function(self: PCefv8Handler; const name: PCefString; object_: PCefv8Value;
  13.     argumentsCount: csize_t; arguments: PCefV8ValueArray; out retval: PCefV8Value;
  14.     exception: PCefString): Integer; cconv;
  15. end;

This also is the bridge between Pascal and Javascript: You can pass data to Pascal by calling a native function, you can pass data to Javascript by calling a Javascript function, which in turn calls a native function: retval can be a ICefDictionaryValue, so it is not limited to a single value.

If you have a lot of data to pass to Javascript, you could also register a custom scheme with a custom scheme handler (think of it as a custom protocol, e.g. cefinternal://). Javascript then could load data from this scheme (e.g. JSON files).


Quote
Any thoughts please,
Code has already been posted here.

The relevant parts are:
1. A custom render process handler for the render process:
Code: Pascal  [Select][+][-]
  1. type
  2.   TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn)
  3.   protected
  4.     function OnProcessMessageReceived(const browser: ICefBrowser; sourceProcess: TCefProcessId;
  5.       const message: ICefProcessMessage): Boolean; override;
  6.   end;
  7.  

2. Implement messages, the example defines the message visitdom.
You can pass data via ICefProcessMessage.ArgumentList.

Code: Pascal  [Select][+][-]
  1. function TCustomRenderProcessHandler.OnProcessMessageReceived
  2.   (const browser: ICefBrowser; sourceProcess: TCefProcessId;
  3.   const message: ICefProcessMessage): Boolean;
  4. begin
  5.   case message.Name of
  6.     'visitdom':
  7.       begin
  8.         browser.MainFrame.VisitDomProc(@VisitDOM);
  9.         Result := True;
  10.       end;
  11.     else
  12.       Result := inherited;
  13.   end;
  14. end;

This part is for communicating UI process to render process

3. The counterpart for the UI process is OnProcessMessageReceived in TChromium. There you can handle messages for communicating render process to UI process.

4. Send messages:
Code: Pascal  [Select][+][-]
  1. browser.SendProcessMessage(PID_RENDERER, TCefProcessMessageRef.New('visitdom'));

For also passing data you only need to set TCefProcessMessageRef.ArgumentList.

I really hope this helps you to get started finally.
« Last Edit: February 02, 2018, 10:40:01 am by dliw »

PaulANormanNZ

  • Full Member
  • ***
  • Posts: 117
Re: fpCef3: browser talk to Host (=Lazarus app)
« Reply #6 on: February 03, 2018, 01:48:20 am »
Thanks,

Quote
I really hope this helps you to get started finally.

I'm sure it will, for some reason it just hadn't "clicked" into place - it actually seems all very indirect, or "bulky" in approach I suppose.

Will get head down and follow it all through.

Thanks again for patiently explaining it,

Paul

 

TinyPortal © 2005-2018