Jump to content

Recommended Posts

  • Moderators

A bit of a weird topic name for a product which elevates Object Pascal using javascript.
I could have named it 'Web Components' (as I did a while ago) or maybe better 'Api Programming'.

There are a number of organisations which look after the web api's. W3C is the most known one, but there are others looking after specific parts (WhatWG, Khronos etc.). What they have in common is that they publish the web api's they're looking after in a specific formal format (WebIDL).

Smart has transformed these specifications in corresponding pascal classes, contained in the APIs directory in the RTL. These classes basically map directly onto functions and data available in the browser itself, and using them is sort of similar to for instance incorporating Microsoft Office functions in a Delphi program (although technically very different from using COM).

The RTL uses some of these api's under the hood, this post is about a mini-rtl if you like consisting of just 1 component.

I use this approach a lot for non-form based projects, single-page-apps (or multiple) and websites.

Demo of a semi-static SPA 

The inheritance chain of the DOM looks like
- EventTarget
  - Node
    - Element
      - HTMLElement

with all the various html elements underneath : HTMLDivElement for a <div>, HTMLAnchorElement for a <a> etc.
The code below wraps the HTMLElement, but allows its constructor to create any of the specialised sub-elements.

unit JElement;


uses W3C.HTML5, W3C.DOM, W3C.CSS;

  THTMLElement = class
    FHTMLElement: JHTMLElement;
    constructor Create(element: String; parent: THTMLElement; className: String; innerHTML : String); 


{ THTMLElement }

constructor THTMLElement.Create(element: String; parent: THTMLElement; className: String; innerHTML : String);
  // cache element and set innerHTML and className
  FHTMLElement := JHTMLElement(Document.createElement(element));
  FHTMLElement.innerHTML := innerHTML;
  FHTMLElement.className := ClassName;

  If parent = nil
    then document.body.appendChild(FHTMLElement)
    else parent.FHTMLElement.appendchild(FHTMLElement);


HTMLElements have as specifiers 'attributes' and 'properties'. Properties are any of the values in the 'style' attribute : in the html expression style="left=10px; color=white;" href="#" both 'left' and 'color' are properties, and both 'style' and 'href' are attributes.
So we need to add the setters for these parameters :

Procedure THTMLElement.SetProperty(s1: String; S2: String);
  var FElementStyle := JElementCSSInlineStyle(FHTMLElement).style;
  FElementStyle.setProperty(S1, S2);

Procedure THTMLElement.SetAttribute(S1: String; S2: String);
  FHTMLElement.setAttribute(S1, S2);

The first part of the demo app is an image, which fills the complete viewport on any device and orientation, a slightly darker tinted bar on top, and a button in the bar linking to an email form further down.

This header can be constructed as per below :

unit JHeader;


uses JHTMLElement, smartcl.system;

  THeader = class(THTMLElement)
    constructor Create(props: Variant);


{ THeader }

constructor THeader.Create(props: Variant);
  //hero image
  var hdr0  := THTMLElement.Create('div', nil, 'div');
      hdr0.setProperty('width', '100%');
      hdr0.setProperty('height', '100%');
      hdr0.setProperty('min-height', '100vh');

    //top bar 100px
    var hdr11  := THTMLElement.Create('div', hdr0, 'div');
        hdr11.setProperty('width', '100%');
        hdr11.setProperty('height', '100px');

      //contact button
      var hdr21  := THTMLElement.Create('a', hdr11, 'div', 'Contact');
          hdr21.setProperty('color', 'white');
          hdr21.SetAttribute('type', 'button');
          hdr21.setAttribute('href', '#contact');
          hdr21.SetProperty('background-color', 'rgb(21,21,21,0.2)');

which can be instantiated as in (with a variable for the image)

  props['header-img'] := 'assets/img/blueprint.jpg';

and which on execution time resolves in

<div class="div" style="width: 100%; height: 100%; min-height: 100vh; background-image: url(; background-size: cover;">
  <div class="div" style="width: 100%; height: 100px;">
    <a class="div" type="button" href="#contact" style="visibility: visible; display: inline-block; position: absolute; overflow: auto; left: 20px; top: 30px; width: 75px; height: 35px; color: white;">

Hence the title of this post : HTML programming.

The advantage of this approach is that once there are a number of these multi-purpose constructs like THeader available, making up another webpage is as easy as providing values for constructor parameters and stringing them together.

At some stage I created the constructs listed here
They need to be updated and streamlined a bit.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...