I've published latest updates to fpwebview:
Lazarus is an IDE-cum-widget set interface for developing
cross platform GUI applications. I've now implemented a demo of using
fpwebview with Lazarus, i.e., embedding webview
in a desktop Lazarus GUI application.
Here's a macOS screenshot:
In the screenshot, the three buttons above the web content are outside of the webview
display area, and are Lazarus components making up the GUI application. The 'Say Yo To
Webview' button demonstrates updating content shown by webview
in response to GUI
action, while the 'Lazarus Say Hello' button demonstrates standard GUI functionality.
Technically, this application demonstrates concurrent execution of the Lazarus GUI event
loop managing the application's windows, and webview
's own event loop that manages
the Lazarus window in which webview
is embedded.
The demo works on macOS (using Lazarus Cocoa widget set) and Windows (using Lazarus Windows widget set).
For Linux:
with Lazarus GTK2: Impossible, as GTK2 and GTK3 (which webview
on Linux uses)
cannot coexist in one application (that executes as one operating system process).
with Lazarus GTK3: Should be trivial. Note that at present Lazarus GTK3 is work-in-progress and not mature.
with Lazarus Qt5/Qt6: Possible, potentially tricky. The basic requirement is to convert
a Qt window handle into a GTK3 window suitable for use with webview
.
I've implemented an embedded localhost web server demo for fpwebview. The demo runs on Linux macOS, and Windows 10. Here's a Linux screenshot:
The program consists of a multi-threaded web server listening on localhost:8000
,
and the web browser widget showing the content, styled by CSS, all loaded from
said web server.
Because the embedded web server is listening on localhost:8000
, you
could visit it with a regular web browser running on the same machine.
However, in the demo program, the buttons work by using webview
APIs
to perform what is effectively in-process RPC between Javascript and
Pascal. From a regular web browser, clicking those buttons will have no
effect, since the browser's Javascript runtime has nothing to do with the
Pascal procedures implementing the buttons' functionalities.
For serious usage beyond a demo, additional security measures are possible to ensure that the embedded web server serves only the web browser widget and no other client.
Tags: fpwebview, PascalI've implemented bidirectional Javascript-Pascal calling for fpwebview. Here's the demo program:
program js_bidir;
{$linklib libwebview}
{$mode objfpc}{$H+}
uses
{$ifdef unix}cthreads,{$endif}
math,
webview;
var
w: PWebView;
html: String;
procedure SayHello(const seq: PAnsiChar; const req: PAnsiChar; arg: Pointer); cdecl;
var
s: String;
begin
s := 'var p = document.createElement("p")' + LineEnding +
'p.innerHTML = "Yo again!"' + LineEnding +
'document.body.appendChild(p)';
webview_eval(w, PAnsiChar(s));
webview_return(w, seq, WebView_Return_Ok, '{result: "<p>Yo!</p>"}');
end;
begin
{ Set math masks. libwebview throws at least one of these from somewhere deep inside. }
SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);
html := 'data:text/html,<html>' + LineEnding +
'<head></head>' + LineEnding +
'<body><button onClick="SayHello()">Say Hello</button>' + LineEnding +
'<div id="greeting"></div>' + LineEnding +
'<script>var SayHello = function() {' + LineEnding +
' HostSayHello().then((x) => document.getElementById("greeting").innerHTML = x.result)' + LineEnding +
'}</script>' + LineEnding +
'</body>' + LineEnding +
'</html>';
w := webview_create(WebView_DevTools, nil);
webview_set_size(w, 700, 200, WebView_Hint_None);
webview_set_title(w, PAnsiChar('WebView - Pascal Javascript Bidirectional'));
webview_bind(w, PAnsiChar('HostSayHello'), @SayHello, nil);
webview_navigate(w, PAnsiChar(html));
webview_run(w);
webview_destroy(w);
end.
In the program, the Pascal procedure SayHello
is made accessible to
Javascript as HostSayHello
. When Javascript calls HostSayHello
,
the Pascal code in turns invokes Javascript to update the DOM, then returns
a response to the Javascript caller.
Next up, an embedded web server to serve HTML, CSS and other content including Javascript source.
Tags: fpwebview, PascalWebview is a "tiny cross-platform webview library for C/C++/Golang to build modern cross-platform GUIs." Webview uses Cocoa/WebKit on macOS, gtk-webkit2 on Linux, and Edge on Windows 10.
There exist various language bindings for Webview, as listed on Webview's Github page. I've just published my Free Pascal binding here.
Here's a simple Pascal program that uses Webview to implement a web browser.
program browser_cli;
{$linklib libwebview}
uses
{$ifdef unix}cthreads,{$endif}
math,
webview;
var
w: PWebView;
begin
{ Set math masks. libwebview throws at least one of these from somewhere deep inside. }
SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);
writeln('Hello, webview, from Pascal!');
w := webview_create(WebView_DevTools, nil);
webview_set_size(w, 1024, 768, WebView_Hint_None);
webview_set_title(w, PAnsiChar('WebView Free Pascal'));
webview_navigate(w, PAnsiChar('https://www.freepascal.org/'));
webview_run(w);
webview_destroy(w);
writeln('Goodbye, webview.');
end.
Coincidentally, Tomaž Turk recently announced Pharo-WebView.
Tags: fpwebview, Pascal