“Theory” of URLs for developers

We are using URLs these days quite a lot, but not all of us understand what they actually are.

By this post I will try to explain their structure and how Sciter/HTMLayout deals with them.
Please note that this is sort of informal explanation and I am using term “URL” here while “URI” is more correct name for that entity strictly speaking.

URLs are made from these 5 major parts:

<scheme name> : [//] <resource identification > [ ? <query> ] [ # <fragment> ]

Where:

  • scheme name – is in principle any name token – name of the URL scheme. Some of names are well known: “file:”, “http:”, etc.
  • // part – if present, means that the following “resource identification” part uses hierarchical naming convention, with ‘/’ character as a delimiter.
  • resource identification – is either ‘/’ separated path name if ‘//’ is provided. Or it is some “flat” name.
  • query part is in principle meaningful only for dynamic client/server scenarios. It is an instruction to the server to provide that resources with those parameters.
  • fragment – is a name or ID of some sort that identifies some location or part inside the resource.

Consider that you have the same HTML test-file.html available from these three locations:

  1. file:///c:/test-folder/test-file.htm
  2. http://example.com/test-folder/test-file.htm
  3. res:test-file.htm

Let’s imagine that the document contains image with relative path:

  <html>
  <img src="image.png">
  </html>

Sciter, while loading the document, will resolve relative path name “image.png” to these:

  1. file:///c:/test-folder/image.png – as base URL is hierarchical one.
  2. http://example.com/test-folder/image.png – ditto.
  3. res:image.png – but here only resource schema is inherited as base URL uses “flat” naming convention.

In principle your Sciter application can use your own URL schema. You just need to decide will it be hierarchical or flat.

For example if you will call SciterLoadHtml(html, "app://module/main.htm"); then all relative links inside that document
will be resolved against app://module/ base name. So in your SCN_LOAD_DATA handler you will get: “app://module/images/img1.png”, “app://module/styles.css” and so on.

But if you plan to put all your files into resource section of your executable then you should use “flat” schema, like “res:”.

And the last note: if you use hierarchical URLs in SciterLoadHtml and SciterLoadFile calls then these urls must be absolute ones otherwise Sciter will not be able to resolve them reliably.

Sciter,

Adding basic <video> support to Sciter.

The <video> element (behavior:video in fact) is rendered windowlessly as normal DOM element so can participate in animations, transforms and to have other DOM element rendered on it.

Here is a screenshot of Sciter made when it is playing video (standard 30 fps rate) under animation and transformation on semi-transparent background.

sciter video demo

[AngularJS] “you have ruined javascript”

Rob Ashton article: “you have ruined javascript”

While I am considering it as a bit of overreaction but I 100% agree with the nature of problems defined there.

Chase for silver bullet lead us in the same trap of over-engineered world of abstractions. Or over-abstracted world of engineering? Whatever …

Mac OSX, DPI and font sizes mess

Most of applications on Mac OS X use fixed 72 DPI settings despite of all these Retina and other high-DPI monitors. I understand that this is legacy we’ve got from last century. But c’mon, it is 2014 out there …

Even conventional browsers that supposed to handle scaling well by using CSS rules are failing to render simple things like:

  <div style="width:3in; width:3in; border:1px solid">
    is it 3 inch square?
  </div>

you will see everything but not 3 inches square here.

I am not getting what’s the problem to implement proper scaling. Here it is in Sciter on Mac:
DPI screenshot

Screenshot is taken on Mac with Dell UltraSharp U2711 monitor.

Repeatable: simple jQuery plugin for rendering lists, tables, etc.

While ago I’ve published simple and compact (90 lines of code) plugin for rendering, well, repeatables.

Here is its documentation and here is live demo.

The Repeatable is a mechanism of DOM population from array of objects. Repeatable template is defined directly in markup:

<ul id="people">
    <li><a href="mailto:{{this.email}}">{{this.name}}</a> <b if="this.age > 18">18+</b> </li> 
    <li>No data available</li>
</ul>

and that template gets cloned and instantiated for each record in the array.

History of one web UI component

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.

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

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

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

TIScript vs JavaScript.Harmony (ECMAScript 6), Part I


Variables, block scope

As we know local variables in JavaScript are declared in function scope. That creates many problems and surprises for people who came to JS from other languages using the same Java/C/C++ notation.

Consider sample that follows. Here we create array of 10 functions, each of them shall return idx value it was created with.

var farr = [];
for(var i = 0; i < 10; ++i) {
  var idx = i; 
  farr[idx] = function() { return idx; }
}

If you call functions from the farr array in JavaScript you will get these results:

console.log( farr[5]() ); // -> 9
console.log( farr[2]() ); // -> 9

Surprise? I think so.

And if you run the same code in TIScript you will get results you expect:

stdout.println( farr[5]() ); // -> 5
stdout.println( farr[2]() ); // -> 2

That’s because TIScript uses block scope – all variables declared inside some block { ... } are local to that block.

To "fix" that initial design mistake (IMO) authors of ECMAScript.6 introduced new keyword let that allows to define variables in block scope, so for that sample to work properly you will do this:

var farr = [];
for(var i = 0; i < 10; ++i) {
  let idx = i; // note the 'let' here. idx is in block scope now. 
  farr[idx] = function() { return idx; }
}

Not that perfect of course but at least something.

Constants

TIScript from the beginning supported const keyword – declaration of read only variables:

const mask = "*.tis";

Any attempt to change value of the mask generates an error in TIScript: for local constants – at compile time and for global constants – at runtime.

In JavaScript ‘const’ is introduced in ECMAScript.6 with exactly same meaning.

Default parameters

From the very beginning TIScript supports definition of default values of function parameters:

function person( name = "anonymous", age = null ) {
   return { name: name, 
            age:age };
}

We can call such function without any parameters:

var p = person(); // p.name ->  "anonymous", p.age -> null

ECMAScript.6 introduces exactly the same feature – parameters may have default values in JavaScript when browsers will catch up ECMAScript.6.

Rest parameters

In TIScript when you define function as this:

function foo( a, b, r.. ) { stdout.println(a,b,r) }

and call it as:

foo( 1,2,3,4 );

The r variable will be set to an array [3,4] and a and b will get 1 and 2 values correspondingly.

ECMAScript.6 uses slightly different syntax for the same feature:

function foo( a, b, ...r ) { console.log(a,b,r) } 

Array comprehensions

ECMAScript.6 officially introduces feature named "array comprehensions" – mechanism that allows to declare/initialize arrays using kinda declarative syntax. Array comprehensions came to JS from Python I believe. While in Python notation they probably look OK but in JS syntax the comprehensions are not readable most of the time.

Let’s say we have an array:

var numbers = [1, 2, 3, 21, 22, 30];

and we want to create another array that will have only even numbers. With the comprehensions we can define it as:

var evens = [i for (i of numbers) if (i % 2 === 0)]; 

Not quite readable in my opinion.

In TIScript I would write it as:

var evens = numbers.filter( :i: i % 2 === 0 );

– shorter and so more readable.

TIScript has no array comprehensions at the moment and probably will not have them until I’ll see really good use of them.