Note this document is written intentionally close to ReactJS/JSX introduction

Introducing SSX

Consider this variable declaration in Sciter's script:

const velement = <h1 id="hw">Hello, world!</h1>;

It is called SSX, and it is an integral part of Sciter's script syntax. Therefore parsing of such SSX literals does not require invocation of any preprocessor as in browser with JSX.

That above is neither a string nor HTML but exactly this tuple declaration:

const velement = [h1: { id:"hw"}, ["Hello, world!"] ];

Technically SSX is not strictly required - we can use tuple literals directly. It is just that such HTML-ish syntax is more familiar.

Expressions in SSX

Here we declare a variable name and use it in tuple construction:

const name = "Alice";
const velement = <h1>Hello, {name}</h1>;

That above can be written exactly as this: 

const velement = [h1: {}, [name] ];

And you can put any valid script expression inside those curly braces:

const velement = <div>1 + 1 is { 1 + 1 }</div>;

SSX is an expression too

As SSX literal is actually a tuple literal then we can use it in our code as any other literals:

function getGreeting(user) {
  if (user)
    return <h1>Hello, {formatName(user)}!</h1>;
  else
    return <h1>Hello, Stranger.</h1>;
}

The above function returns one of two tuples defined there. 

Specifying Attributes in SSX

You may use quotes to specify string literals as attributes:

const velement = <div tabindex="0"></div>;

You may also provide value of attribute from a variable or expression:

const velement = <img src={user.avatarUrl}></img>;

Note: you should either use quotes (for string values) or curly braces (for expressions), but not both in the same attribute.

Specifying Children with SSX

If tag is empty then you may close it immediately with /> :

const velement = <img src={user.avatarUrl} />;

Note: SSX does not support "tail-less" HTML tags like: <img>, <input> or <br>.  These one must be explicitly closed: <img />, <input /> or <br />.

Yet SSX may contain children:

const velement = 
  <div> 
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2> 
  </div>;

Specifying runtime states with SSX

Along with attributes you may want to define runtime states of elements:

const velement = 
  <li :expanded={ isOpen(item) } > 
    <caption>Hello!</caption>
    <div></div> 
  </div>;

States here correspond to so called pseudo-classes in CSS: :active, :hover, :checked and so on.

Specifying runtime value of input elements

To specify current runtime value of <input> elements use :value runtime state attribute - it reflects current value of the input at runtime:

<input|text(firstname) :value="John" />

Note that just value attribute: <input|text(firstname) value="Initial value" /> specifies initial value that is set once upon creation of the element.

Sciter HTML parsing flavor support in SSX

SSX follows HTML parsing shortcut rules used in Sciter and so:

References in SSX

To define properties, states and content of DOM elements we normally use SSX declarations. But in some cases you may wish "to talk to DOM elements directly", so to get reference to physical DOM element and call its runtime methods from script. 

In order to get reference to DOM element you can either use

this.elLookup = container.select("input#lookup"); 

or its "stringizer" form:

this.elLookup = container.$(input#lookup); 

Alternatively you can ask SSX to provide you the reference to the element:

<input #lookup @{this.lookup} />

This @{variable location expression}, when used in attributes, means the following request: "when you (runtime) will create physical DOM element for this vnode please set reference of the DOM element to the given variable".

VNODE: SSX is just another form of tuple literals

SSX generates tuple literals with predefined structure. Tuples of such structure are known as VNODEs - virtual DOM node definitions:

[tag: {attributes}, [children] ] //or 
[tag: {attributes}, [children], {states} ]

Where:

VNODE: usage, a.k.a. rendering

Some methods of Element class allow to populate DOM by the vnode definitions:

container.content(<div>Hello wonderful world</div>);

After that the container will have single child element: <div>

var arr = [1,2,3];
var children = arr.map( (n) => <li>item #{n}</li> );
container.content(children);

The container will have three <li> children with texts "item #1", "item #3" and "item #3".

List of Element class functions that accept VNODEs and so SSX declarations: children with texts "item #1", "item #3" and "item #3".

Element.merge(vnode) - DOM reconciliation (a.k.a patching) by vnode

The element.merge(vnode)element

The merge() function uses the following match criteria. Particular element/vnode pair is considered as matching if:

Otherwise DOM element and vnode treated as not matching. function uses the following match criteria

Otherwise DOM element and vnode treated as not matching.