fpCef3: browser talk to Host (=Lazarus app) lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- PaulANormanNZ · 2018-01-22 03:01 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i
Hi!
Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.btnDoJavaScriptClick(Sender: TObject);begin   Chromium.Browser.MainFrame.ExecuteJavaScript('myFunct("hello")', 'about:blank', 0);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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i And then (pseudo code) something looking a bit like... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var ResponseText : string; 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 ---------------------------------------------------------------------- PaulANormanNZ · 2018-01-22 03:47 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 · 2018-01-22 07:23 Quote from: PaulANormanNZ on January 22, 2018, 04:47:29 amcarefully crafted JavaScript in the browser frame document could handle many things and return results to LazarusIf 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/ ---------------------------------------------------------------------- dliw · 2018-01-22 09:59 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.h tml#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. ---------------------------------------------------------------------- PaulANormanNZ · 2018-02-02 07:40 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?... QuoteFor 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 · 2018-02-02 09:01 The answer to both is: yes Please see the Javascript example: 1. See TCustomRenderProcessHandler.OnWebKitInitialized: There is Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i native function GetTestParam()which registers a Pascal function in Javascript. Every time you call a native function the registered handler Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i TMyHandler.Executeis called. There you have every information needed to handle the call: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i // Structure that should be implemented to handle V8 function calls. The// functions of this structure will be called on the thread associated with the// V8 function.TCefV8Handler = record  [..]   // Handle execution of the function identified by |name|. |object| is the  // receiver ('this' object) of the function. |arguments| is the list of  // arguments passed to the function. If execution succeeds set |retval| to the  // function return value. If execution fails set |exception| to the exception  // that will be thrown. Return true (1) if execution was handled.  execute: function(self: PCefv8Handler; const name: PCefString; object_: PCefv8Value;    argumentsCount: csize_t; arguments: PCefV8ValueArray; out retval: PCefV8Value;    exception: PCefString): Integer; cconv;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). QuoteAny 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn)  protected    function OnProcessMessageReceived(const browser: ICefBrowser; sourceProcess: TCefProcessId;      const message: ICefProcessMessage): Boolean; override;  end;  2. Implement messages, the example defines the message visitdom. You can pass data via ICefProcessMessage.ArgumentList. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TCustomRenderProcessHandler.OnProcessMessageReceived  (const browser: ICefBrowser; sourceProcess: TCefProcessId;  const message: ICefProcessMessage): Boolean;begin  case message.Name of    'visitdom':      begin        browser.MainFrame.VisitDomProc(@VisitDOM);        Result := True;    end;    else      Result := inherited;  end;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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 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. ---------------------------------------------------------------------- PaulANormanNZ · 2018-02-03 00:48 Thanks, QuoteI 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