History of one web UI component

November 23, 2013

Filed under: Philosophy,Sciter,Web Application Techologies — Andrew @ 6:29 pm

10 or so years ago I was asked to design Word Processor WYSIWYG editing component. The editor should handle editing of paged documents. It has notion of pages where document text is replaced. The text can wrap around absolutely positioned (page box related) blocks – images, text boxes, etc. To be short – something like micro-Word but lighter and PDF-output oriented.

The target application, where it was used initially, was online Web application with UI written as a quite large Java Applet. These days such a technology is know as “single page web applications”. But 10 years ago browsers (actually it was just one at that moment) were simply not ready for productive applications – applications that people are opening in the morning and closing when they leave workplace.

Even at that moment of time Java handled that type of UI pretty well. We just did our own UI framework/set of widgets for it but still.

The Word Processor component was written in C++ and integrated with the rest of Java application through JNI.

We were happy with the app and so did 70,000 users of the application. But joy was lasting only couple of years. As one day Microsoft and Sun did not reach an agreement on Java destiny inside the browser and so our application literally became deprecated in one day. Doh!

So the development of the UI of the application started from scratch again. At this moment of time Microsoft added almost accidentally AJAX support to IE and that gave a hope to the team that they can finally use HTML/CSS for UI of the app. And development started.

But it was still not clear what to do with our nice Word Processor and HTML WYSIWYG editor that used BlockNote editing engine for e-mails. Users already created tons of documents so we cannot simply drop editing functionality from the app. Web platform hadn’t and still has no means to support WYSIWYG editing of paged documents. And even HTML WYSIWYG editing (a.k.a. contenteditable) is still quite far from ideal (e.g. to insert an image you need to upload it to the server first, and so on).

At that moment I almost had Sciter v.1 ready and we’ve decided to wrap it as an ActiveX component (for IE) and so called Netscape Plugin (NPAPI, for Firefox). I’ve created editor’s chrome as Sciter’s HTML/CSS/tiscript and wrapped the editors as Sciter’s DOM behaviors. And we’ve got our application up and running again. As the same Sciter engine run in different browsers we saved a lot of time on cross-browser testing of the editors, it just worked in each of them. And even in Google Chrome that arrived later.

Word Processor in Sciter screenshot

Word Processor running in Sciter ActiveX on web page

Joy of having convenient and stable application lasted little bit longer this time. Up to couple of months ago when Google Chrome and Mozilla pretty much at the same time declared that, basta!, they are not going to support NPAPI starting next(!) year.

Their motivation is in principle quite understandable: 95% of internet users do not use any plugins at all so why to bother. But, hey, what about our 70,000 users? What they should do? Except of NPAPI there is simply no other means to run native components on the web page in GC and FF… And, again, that happened with 3 months notice… Cool, eh?

So the team is in this interesting position again – what to do with our app.

People, seriously, I believe it is time to consider Sciter as a front-end for even online (productive, business) web applications. Just create HTML/CSS/tiscript once and it will work in all Windows versions and Mac OSX (coming). Linux version will be ready shortly after OSX version.

And forget about testing everything separately in IE, FF, GC, Safari and Opera. Sciter does not require installations – just copy and run it.
Enough is enough, no?

And yet, if you not convinced yet then check this news for IE 11. If in your Asp.Net you happen to rely on things like
if(request.browser.ActiveXControls) ... else ... apply hot-fixes from the article above. Otherwise your app will not work properly in IE 11.

Just in case: here is an example of Word Processor document shown above saved as PDF.

Sciter, Mac OSX port progress report.

November 12, 2013

Filed under: Sciter — Andrew @ 9:50 pm

It is coming.

Here is structure of projects the Sciter is made of:

  • /demos/ – group of demonstration projects that go to public SDK:
    • inspector – DOM inspector, targets: /sdk/bin/inspector32.dll and /sdk/bin/inspector64.dll, uses/depends-on sciter.dll
    • sciter – main demo, UI "player" of HTML/CSS/TIScript, targets: /sdk/bin/sciter32.exe and /sdk/bin/sciter64.exe, uses/depends-on sciter.dll
  • /libs/ – external libraries, used "as is" by sciter.dll
    • dybase – Konstantin Knizhnik’s DyBASE, used by tiscriptlib to provide persistence (Storage and Index objects). Static library, part of sciter.dll
    • png – standard distribution of pnglib + animated PNG extension. Used by gool.  Static library, part of sciter.dll
    • zlib – standard distribution of zlib. Used by pnglib and sciter.dll. Static library, part of sciter.dll
  • d2d – Direct2D and DirectWrite gfx backend, used by gool and html. Static library, part of sciter.dll
  • gdi+ – GDI+ gfx backend implementation, used by gool and html. Static library, part of sciter.dll
  • gool – abstract graphics layer, used by html. Static library, part of sciter.dll
  • html – h-smile core – HTML/CSS engine. Static library, part of sciter.dll
  • sciter.dll – the sciter engine assembly per se. targets: /sdk/bin/sciter32.dll and /sdk/bin/sciter64.dll
  • tiscript – standalone tiscript interpretter/compiler assmbled as command line utility. Used for example to compile TIS sources to bytecodes. target: /sdk/bin/tiscript.exe (32bit).
  • tiscriptlib – TIScript core, uses /libs/dybase and tool static libraries. Static library, part of sciter.dll
  • tool – collection of common primitives: string, array<T>, hash_map<T>, etc. Static library, part of sciter.dll
  • win – window primitives (Windows)

So far I’ve ported /tool, /tiscript + /dybase

/gool and /html are platform independent but taking some attention.

Major things are graphics and windowing layers, they are taking most of the time at the moment.

Model-View-Whatever, the Plus engine for Sciter.

October 20, 2013

Preface

I would say that human history is a history of reinventing "wheels" of various kinds.

This time we see concept of data binding reincarnated with slightly pathetic name Model-View-Controller. Of course, as many people as many meaning they give to the MVC abbreviation but, nevertheless, it is all around basic idea of data binding – you have data (the Model these days) declaratevily bound with UI "controls" (the View). I believe Microsoft’s VisualBasic 4 and its IDE was the very first usable implementation of the idea. There was no Controller concept at that moment so their implementation was quite limiting – while you can implement 90% of your data editing needs using simple declarations you will spend 90% of your design time fighting with the rest of 10% of needed functionality.

The Plus framework for Sciter.

The Plus framework you can find in Sciter SDK is quite compact (400 LOC) and relatively simple implementation of that old data binding concept with controller means.

Note, the Plus is not an attempt to solve every html/css/script UI problem as AngularJS does. It is just a data binding mechanism with the concept of @observing functions (controllers in my interpretation).

Basics

Model in Plus interpretation is some tiscript namespace object that contains data variables (and optionally functions) to be bound with particular container in HTML DOM.

For example if you declare this script:

namespace Data {
  var correspondent = "world"; // variable to be bound
} 

and corresponding markup:

<section model="Data">
   Whom to greet: <input name="correspondent"> ?
   <p>The greeting: Hello <output name="correspondent">!</p>
</section>

and include in your document "plus.css" file you will get live data binding between Data.correspondent data variable and two DOM elements: two ways with input[name=correspondent] and one way (only view) binding with output[name=correspondent]. So when you type something in that input you will see the data also rendered in output element.  To see this alive load sdk/samples/+plus/demos/0-basic-variable-binding.htm in sciter.exe from its SDK.

The model and name DOM attributes.

Note that <section> element contains model="Data" attribute. It instructs the Plus engine to establish data binding between content of this section and members of namsepace Data {} in script. Name of the bound namespace can be any suitable, not just Data.

Any DOM element inside that section[model] may have name attribute defined. On binding initialization the Plus will try to find data element in the model with that name and if such data variable is found it will made two or one way (for <output> elements) binding between .value of that DOM element and the data variable. The name can be compound – may contain ‘.‘ (dot)-separated list of names. This way  you can bind DOM elements with object fields inside the model:

namespace Contact {
  var name = { first: "Albert", last: "Einshtein" };
  var phone = "....";
  ... 
}

and markup:

<form model="Contact" id="contact-details"> 
  <label for="name.first">First name></label> <input name="name.first">
  <label for="name.last">Last name></label> <input name="name.last">
  ...
</form>

Celsius to Fahrenheit convertor.

Controllers, the @observing function decorator.

File plus.tis (the Plus engine implementation) contains declaration of function decorator named @observing. With that decorator you can define functions that will be triggered (called by the engine) when variable(s) they are observing change.

As an example let’s define simple Celsius to Fahrenheit conversion tool that should work in two directions – when you define celcius value it will calculate its fahrenheit representation. And vice versa. Something similar to the form on the right:

First we will define our Data namespace:

      include "../plus.tis"; // model below uses @observing decorator defined in plus.tis  
      namespace Data // our model
      {  
        var celsius = 0; 
        var fahrenheit = 32;
        
        // this function is observing 'celsius' and calculates 'fahrenheit'
        @observing "celsius"
          function toFahrenheit() {
            fahrenheit = celsius * 9 / 5 + 32;
          }
        // this function is observing 'fahrenheit' and calculates 'celsius'
        @observing "fahrenheit"
          function toCelcius() {
            celsius = (fahrenheit - 32) * 5 / 9;
          }        
      }    

Note two functions above: function toFahrenheit() is observing celcius variable. When celcius variable will change, for example as a result of changes in <input|number(celsius)> field, the toFahrenheit() function will be triggered and will set value of fahrenheit variable. As we have another input bound with the fahrenheit variable:

<body model="Data">
  <p><input|number(celsius)>°C and <input|number(fahrenheit)>°F</p>
</body>

we will see in it results of calculation. This works in both directions – from fahrenheit to celcius and from celcius to fahrenheit.

To see this alive load sdk/samples/+plus/demos/1-basic-function-binding.htm sample in sciter.exe.

That’s it for now. In the next article I’ll explain use of repeatable attribute to bind arrays of objects with rpepatable sections and other samples. If you don’t want to wait check other samples in sdk/samples/+plus/demos/ folder of the SDK. They are self descriptive.

MVC or not MVC? The Formation Engine for jQuery

September 22, 2013

Filed under: HTML and CSS,Source code,Web Application Techologies — Andrew @ 10:01 pm

Various JavaScript frameworks provide data binding facilities (Knockout, AngularJS, etc.) these days.

They are based on kind-of-MVC concept: you have some data (structure, model), view rendering that data in html and some code in between that commonly named as controllers.

How successful/convenient those frameworks are subject of separate topic. For me they are too intrusive I would say. On some views/pages they make sense, on others final solution looks too ugly.

Anyway, here is an alternative idea…

Instead of separating data structure and its view we simply can create construction that is a data model and its view at the same time :)

I named that magic “construction” as Formation. Formation is essentially a collection of DOM elements organized in a tree that reproduces structure of the data (or model if you wish). Value of the formation is JSON data structure – the model per se.

Consider this example

Here you see collection of inputs and subsections (on the top).
On the bottom/right corner you see the Formation tree created of <section#inputs> container.

On the left you see live data of the Formation (editable textarea). Changes there reflect state of elements. In the same way changes in inputs reflect text in this textarea.

The Formation implementation does two major things:

  • creates formation trees and
  • initializes custom DOM elements (check that in HTML source – that friends list).

Couple of words about custom elements support in formations:

When formation sees custom DOM element ( any DOM element with tag name containing ‘-’ inside ) it tries to find its initializer in registry of jQuery plugins – that famous $.fn collection. And calls it if it was found. You can check js/jquery.list-input.js – it is normal jQuery plugin with the name matching that custom element tag name: “INPUT-LIST”.

To create/get formation of some container you can call either

  1. global [window.] formation( domel_or_$_wrapper ) function or
  2. $(selector).formation() plugin.

You can store created formation in some variable and access DOM elements in it in quite effective manner:

var inputs = $("section#inputs").formation();
$(inputs.firstName).on("change", function() {...});

Accessing formation members directly is faster than accessing them using jQuery selectors as these are just direct references.

You can download complete sample to play with from here.

Future Formation plans: to implement so called repeatable formations, so if you have this markup:

<ul repeatable name="stockItems">
   <li><output name="name">  <output name="price" type="currency"></li>
</ul>

and will feed it (through formation) by this data:

[
  {name:"Apple", price: 1.05 },
  {name:"Orange", price: 0.52 } 
]

it will render two <li>s in the list.

Another ng-inspired idea is to have class switches as Formation elements, this class declaration:

<div class="{someSwitch:collapsed|expanded}" >...</div>

will cause corresponding formation to have element named “someSwitch” that can be assigned false/true or 0|1 values to change class to either <div class=”collapsed”> or to <div class=”expanded”>…

UPDATE: see discussion about the Formation on jQuery forum : forum.jquery.com/topic/mvc-or-not-mvc-the-formation-engine

Sciter HTML parsing flavour

September 21, 2013

Filed under: HTML and CSS,Sciter — Andrew @ 12:24 pm

HTML parser in Sciter v.3 supports attribute shortcuts allowing to write HTML in more compact form. Compare these two declarations that are identical (for the Sciter):

Compact:

 
  <input|currency(itemPrice) value=1000> 

and standard:

 
  <input type="currency" name="itemPrice" value=1000> 

As you see the first one is slightly shorter and better readable (subjective of course).

Here is full list of supported attribute shortcuts:

  • #nameid, attribute name that starts from ‘#’ is parsed as id=”name”
  • .nameclass, this is an equivalent of class="name". Element may have multiple “dot attributes”. All of them are combined into single class attribute. So this <div.container.collapsed> is treated as this: <div class=”container collapsed”>
  • |nametype, attribute name that starts from ‘|’ is parsed as type="name"
  • (someName)name, attribute name enclosed into ‘(‘ and ‘)’ is parsed as name="someName"

Just in case :)

Sciter 3

September 8, 2013

Filed under: Sciter — Andrew @ 3:28 pm

Sciter 3 is officially out.

See its log file.

  • On Windows Vista/7 it uses Direct2D backend
  • On Windows XP it uses GDI+ backend

Known issue on Windows XP: rendering of linear and radial gradients is different from Direct2D backend as GDI+ has no notion of “open gradients”. I’ll fix it a bit later.

You shall expect that GDI+ rendering is not that effective as rendering by Direct2D so avoid animations affecting large areas. These two media rules allow to target different backends used:

 
  @media graphics-layer == 1 {
    /* GDI+ rules here.
       Less animation, etc. */
  }
  @media graphics-layer == 2 {
    /* Direct2D in WARP mode (software rendering but fast enough)        
     */
  }
  @media graphics-layer >= 3 {
    /* Direct2D in hardware mode, max performance. */
  }

But most of the time it is enough to have just two sections:

 
  @media graphics-layer == 1 {
    /* GDI+ rules here.
       Less animation, etc. */
  }
  @media graphics-layer > 1 {
    /* Direct2D, high performance. */
  }

In script you can check gfx backend used by reading view.backend (:integer) property.

« Previous PageNext Page »