Recent

Author Topic: WebBrowser control and smart pointer request  (Read 3540 times)

sysrpl

  • Sr. Member
  • ****
  • Posts: 315
    • Get Lazarus
WebBrowser control and smart pointer request
« on: April 29, 2018, 09:27:54 pm »
Here is a video overview of this message

I've run into an almost must have use case for FPC smart pointers as described and implemented by Maciej. I wanted to know from the people who make decision about what to merge, what's the status of rolling his enhancements at following location into FPC trunk?

svn ls https://svn.freepascal.org/svn/fpc/branches/maciej/smart_pointers/

My use case is for adding a free pascal interface to Webit's JavaScriptCore. The JSC objects all follow Apple's design pattern where C style API functions return and operate on ref pointer types that must be destroyed using specific API calls for each type.

It seems like a natural fit with smart pointers, such that record types could be used to hold onto things such as JSStringRef, JSClassRef, JSValueRef, and more, retaining and releasing them for you automatically with the appropriate JSC API when they go out of scope using the smart pointer Initialize, Finalize, and Copy operators.

e.g. JSClassRetain, JSClassRelease

For those interested, the JSC library works on all platforms and allows for integrations between native code applications, and a high performance java scripting engine. The same engine powering webkit browsers. The API allows you to expose your native code functions as javascript functions or classes, as well as providing a virtual machine to execute javascript. Properly confiruged, the javascript can callback your pascal code optionally passing javascript objects are arguments to your native code.

All of these operations would be much easier to program against with stack based types (record or object) if smart pointer support was present in FPC.

Finally, with JSC it's quite easy and possible for developers to embed webkit webview windows in their desktop applications, and optionally grant any web page the ability invoke free pascal code you decide to expose, and for free pascal in return invoke arbitrary javascript objects or functions.

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: WebBrowser control and smart pointer request
« Reply #1 on: April 29, 2018, 10:48:09 pm »
My use case is for adding a free pascal interface to Webit's JavaScriptCore.

Interface units for iOS JavaScriptCore are here, already parsed:

https://github.com/genericptr/

I don't see them for macOS, but the header parser could be used there as well if the iOS framework differs much from the macOS framework.

Finally, with JSC it's quite easy and possible for developers to embed webkit webview windows in their desktop applications, and optionally grant any web page the ability invoke free pascal code you decide to expose, and for free pascal in return invoke arbitrary javascript objects or functions.

WebKit-based TWebBrower control for Cocoa and Qt is here:

https://macpgmr.github.io

sysrpl

  • Sr. Member
  • ****
  • Posts: 315
    • Get Lazarus
Re: WebBrowser control and smart pointer request
« Reply #2 on: April 29, 2018, 11:43:27 pm »
Phil, thanks for that information. The Qt web browser you linked is extremely minimal, it's just a WebView with four methods LoadPage, LoadPageHtml, and EvaluateJavaScript. It'll be a good reference for me to extend to Qt and Cocoa, but just to be clear I've added the following:

Gtk2, Gtk3 support.
TWebInspector control.
Customizable platform independent TWebAddressBar control.
Platform independent TWebStatusPanel control used to display web page mouse hit test information and resource load progress bar.
Platform independent TWebEditorBar control used to convert a web view into a word processor editor with support for MHTML storage.
Search engine, and map providers.
Full web page image capture and printing support.
Processing many more web page events, customizable alert/confirm/prompt events, page level error notification, console log intercept, download management, resource request alteration, customizing context menus, and more.

Currently I am working on improving the javascript integration so that it will be possible to allow for pascal object to be accessible to web pages at the discretion of the developer. This is where smart pointer support would be much appreciated. It can be done without smart pointers, but it would be much more messy.

Thanks for the OSX link, but I believe I can create a small pascal file for each webkit API, both webview and javascriptcore, with cross platform support for at least OSX, Qt, and Gtk, given what you provided and with all of the features I described above, plus maybe a few extra IDE designers.

I look at supporting Windows last.

A final note, as far as Gtk support for webkit goes, we really need to improve Gtk3 support in Lazarus, because webkit stopped supporting Gtk2 a few years back and it's stuck with an old version with many security problems.

As such I've done some work on LCL Gtk3, fixing things and adding things. I'll submit my LCL Gtk3 changes as a patch when I release the first public version on the packing I'm writing.

If smart pointer are going to be moved into trunk I'll be using them, otherwise I'll use a less elegant solution.

« Last Edit: April 29, 2018, 11:46:43 pm by sysrpl »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: WebBrowser control and smart pointer request
« Reply #3 on: April 30, 2018, 11:44:49 am »
Note that it is only a fit when the relevant types are not used very finely grained. (iow in tight loops) If you start e.g. walking DOMs with such APIs, you don't want smartpointer, it would be noticably slowing.

sysrpl

  • Sr. Member
  • ****
  • Posts: 315
    • Get Lazarus
Re: WebBrowser control and smart pointer request
« Reply #4 on: April 30, 2018, 01:04:12 pm »
Note that it is only a fit when the relevant types are not used very finely grained. (iow in tight loops) If you start e.g. walking DOMs with such APIs, you don't want smartpointer, it would be noticably slowing.

The solution I came up with for now is to use records that hold reference counted interfaces. For example, here is my javascript context wrapper:

Code: Pascal  [Select][+][-]
  1.   JSContext = record
  2.   private
  3.     FRef: IJSContext;
  4.   public
  5.     class function Create: JSContext; static;
  6.     class function Retain(C: JSContextRef): JSContext; static;
  7.     class operator Implicit(C: JSContext): JSContextRef;
  8.     function EvaluateScript(const Script: string): JSValue;
  9.     function CreateFunction(const Name: string; Callback: JSFunction): JSObject;
  10.     function CreateMethod(const Name: string; Callback: JSMethod): JSObject;
  11.     function CreateUndefined: JSValue;
  12.     function CreateNull: JSValue;
  13.     function CreateBoolean(Value: Boolean): JSValue;
  14.     function CreateNumber(Value: Double): JSValue;
  15.     function CreateString(const Value: string): JSValue;
  16.     function CreateJSON(const Value: string): JSValue;
  17.   end;

So you would write code like this to run javascript:

Code: Pascal  [Select][+][-]
  1. function TestCallback(Context: JSContext; Args: JSValues): JSValue;
  2. begin
  3.   Result := JSContext.CreateString('You passed ' + IntToStr(Args.Length) + ' arguments');
  4. end;
  5.  
  6. function MessageBoxCallback(Context: JSContext; Args: JSValues): JSValue;
  7. begin
  8.   if Args.Length > 0 then
  9.     ShowMessage(Args[0].AsString);
  10.   Result := JSContext.CreateUndefined;
  11. end;
  12.  
  13. procedure TForm1.Button1Click(Sender: TObject);
  14. var
  15.   C: JSContext;
  16.   R: JSValue;
  17. begin
  18.   C := JSContext.Create;
  19.   C.CreateFunction('test', TestCallback);
  20.   C.CreateFunction('messageBox', MessageBoxCallback);
  21.   R := C.ExecuteScript(
  22.     'let s = test(123, "hello");' +
  23.     'messageBox("test gave us:" + s);' +
  24.     'let result = "okay, we are done.";');
  25.   Caption := R.AsString;
  26. end;

Note, using my records with interfaces we don't have to clean up anything, and the javascript context is destroyed when Button1Click exits.

cbsistem

  • New Member
  • *
  • Posts: 39
Re: WebBrowser control and smart pointer request
« Reply #5 on: September 20, 2018, 05:29:20 pm »
Hello. How can I change the Style of the Button component?


PlayButton.font.color = clRead; /// does not work

is it possible to load a CSS file or a javascript file?

 

TinyPortal © 2005-2018