[Pas2js] The way forward: Exit the VCL/LCL, enter the DOM

Michael Van Canneyt michael at freepascal.org
Mon Aug 5 00:24:39 CEST 2019


Hello,

I have just committed some proof of concept that I have been working on
lately. Please bear with me for a long mail !

Current attempts at widget sets focus on getting the VCL/LCL in the browser.
I think this is good as a first step, and TMS Web Core has proved it is
possible to do great thigs. But it is limiting: it is desktop programming,
ported to the browser.

To boot, to see the actual result, you must start the program in the browser, 
when it would be much better to see the application as rendered in the IDE:
True RAD and WYSIWYG.

The LCL and VCL miss out on a lot of things that are possible with HTML and
CSS.

I believe that we should instead embrace the DOM and CSS, and not stick
to mimicking a desktop concept started in the 90-ies. Get rid of Top,Left,
Width and Height. Use the power of CSS styles instead.

At the same time, current Web&Mobile programming IMHO is still missing some RAD
concepts that we love dearly. The 2-Way tools concepts introduced by Delphi and VB
are still not really available in Web. Definitely not for Pascal.

Therefor I created a start for what I think is the way forward.

There are 2 parts to this.

The first part is a widget set.
-------------------------------

In pas2js SVN, packages/webwidgets there is a very basic set of widgets.
It is just a start. But it lays the foundation of what I think should be the
road forward: combining RAD and HTML/CSS. It is a thin layer over HTML templates.
You can manipulate classes, Styles and the dataset functionality in HTML 5.

You have access to all events, and it will accept
procedure OnClick(var message); message 'onclick';
using the dispatch mechanism, just as for native applications !

Besides the basic widgets, it also shows how to do complex widgets.
It also shows that you can create unit-tested widget-sets: since they are
rendered in the browser, it is easy to widget test them.

(for example a TemplateWidget: pluck some html from internet, stick it in the Template
Tstrings oproperty, and it will be rendered)

This is web, so better look for yourself:

Demo at: https://www.freepascal.org/~michael/designdemo/designdemo.html
Zip at: https://www.freepascal.org/~michael/designdemo/designdemo.zip

It mimics a 'component palette' and a 'form'. You can click a button, and
click somewhere in the form, it will add the widget. You can reorder
widgets, reparent them etc. (JQuery UI Sortable is used for this).
The last but one button (looks like a 'target') is a "container": just a
div, which can be used for layouting.

The last button (with the Elephant) demonstrates the template widget:
it has the JumboTron (hence the elephant) sample demo of Bootstrap in it's
template.  best drop first a container and in the container the jumbotron.
(it's style settings are such that it takes all place)

The demo is not yet perfect, it is a proof of concept.

All this is embryonal, I intend to further the development of the widgets, 
as none of the other approaches I have seen will offer the same flexibility 
as this approach. (I must say projJ from WarleyAlex comes closest, in fact !)

The second part is: RAD.
------------------------

How do we integrate this in the IDE ? Be it Lazarus or Delphi.
We could program a Javascript and HTML rendering engine and create a
component.
This is a lot of work, and fortunately not necessary: it exists.
We can embed the browser in the IDE !

Downside is: communication with the browser is asynchronous.
A way around this is needed. I created one possible solution.

So, the second demo is: 
You can have the same demo as above, but as a desktop application:

See:
https://www.freepascal.org/~michael/designdemo/nativedesigner-win32.zip
https://www.freepascal.org/~michael/designdemo/nativedesigner-linux.zip

The browser used is Chromium on Windows (CEF4Delphi) and WebKit on linux.
(The latter can be found on https://github.com/sysrpl/Lazarus.WebBrowser)

Both work exactly the same.

Open the application on windows. You'll see the same toolbar with buttons,
but this is a native toolbar, not part of the browser.
(there is the same application for linux)

If you press the first 'go' button, a same page as the one above will be opened,
but in an embedded browser window. (you can see the pages in the directory
designdemo when unpacking).

But the buttons to add widgets will not be part of the webpage !
Instead, the webpage communicates with the native application. 
You can click a button and add a widget in the 'page', 
just as you do in the 100% webversion.  (it's the same source, BTW)

The native application has a small internal webserver, which serves the
files, and which has a small REST server for IDE 'commands'. The browser
polls the server for commands (in a later stage we'd probably want
websockets for this).

The tab 'log' contains the log of communications of the webbrowser.
When you select an element in the browser, the browser will notify the
native application, and it sends the current properties of the widget to the
native application (so later on we can show it in an Object Inspector).
You can see the notification in the log.

If it creates a new widget,  it also notifies the native application.
(it also appears in the log)

It looks like this:
---- 
Browser created widget of class TContainerWidget, name TContainerWidget10
Internal server request received: /IDE/Action/1/2
Browser selected widget of class TContainerWidget, name TContainerWidget10
Selected widget state: 
object TContainerWidget10: TContainerWidget
    ParentID = 'designpage'
    ElementID = 'ww-21'
    Classes = 'ui-sortable designerActive'
    Styles = <
      item
        Name = 'min-width'
        Value = '32px'
        Priority = spNone
      end
      item
        Name = 'min-height'
        Value = '12px'
        Priority = spNone
      end
      item
        Name = 'width'
        Value = '50%'
        Priority = spNone
      end
      item
        Name = 'height'
        Value = '50%'
        Priority = spNone
      end>
    StyleRefresh = srOnElementID
end
Internal server request received: /IDE/Command/1/
----

Everyone will recognize the DFM/LFM format :)

Now, if you close the application and restart it
(beware: it sometimes hangs, and you must kill it with the task manager, 
I still need to look at that. something with the internal webserver :(), 
Then you can press the second 'Go' button..

Then the application will load the same webpage in your system default browser. 
It then shows/does the exact same thing, and communicates in the
exact same way, but it is now designing in the browser...

The idea is now to embed this in an IDE and couple this to the component
pallette and object inspector in the IDE. There are of course still
architectural decisions to be made, but this shows that such an approach
could work.

This is all just a proof of concept and embryonal but I honestly believe this is the way to go :)

All is of course available for you to check out and committed in pas2js SVN:

packages/webwidget
demo/webwidget

Enjoy, and comments, ideas - but mostly help - welcome !

Michael.


More information about the Pas2js mailing list