From the very beginning Sciter supported declarative scripting class assignment to DOM elements.
If you want all div.some-widget elements in your document to behave in some special way (be subclassed) then you will need:
1. in script to declare
class SomeWidget : Behavior { function attached() { ... } // called with 'this' set to the DOM element // being subclassed on DOM construction function detached() { ... } // ... SomeWidget specific methods here }
2. and in CSS to declare
div.some-widget { behavior:SomeWidget; } /* or if SomeWidget id declared in other file: */ div.some-widget { SomeWidget url(some-widget.tis); }
After that all div elements having class=”some-widget” will have SomeWidget class assigned to them. I have explained this mechanism 8 years ago (time is passing, yes) here.
This works reliably and is quite convenient.
The only problem with behaviors/prototypes – at any given moment of time particular DOM element can have one and only one scripting class. JavaScript and TIScript do not support multiple inheritance.
Imagine that you have multiple functions in script aimed to configure some DOM element to serve some specific functionality.
In other words each of such functions adds its own aspect (partial functionality) to the element it is called on. Like:
function addClickHandlerFor(element) { // adds onClick handler defined by "click" element attribute in html element.on("click", function() { var attrClick = element.attributes["click"]; element.eval(attrClick); // evaluate the expression }); }
You can have set of such functions configuring different aspects of elements/behaviors.
This works in principle but you will need to call such functions explicitly for all elements for which you will need such configurations. And don’t forget to call them it for content created dynamically (non-trivial task by itself).
Considered all these I have introduced new ‘aspect’ Sciter specific CSS property.
The aspect
CSS property
It is declared as
aspect: "function name" [ url(of-function-implementation-file) ];
Where "function name"
is fully qualified name of the “aspect” function that is aimed to configure/setup some additional functionality on the element. And the url()
is file name where it is defined.
Principles of aspect handling:
The “aspect” function is an ordinary tiscript function that gets called
- with
this
set to the DOM element satisfying the CSS rule. - strictly once per life time of the DOM element.
And yet, the aspect CSS property uses non-standard inheritance – if the element has multiple matching rules with the aspect defined the used aspect is a list of all aspects. Thus if you have have these rules (example taken from the Plus engine):
[click] { aspect:"Plus.Click"; } [dblclick] { aspect:"Plus.DblClick"; }
and the element defined in markup as
<b id="clickable" click="..." dblclick="...">text</b>
It will get two calls – Plus.Click()
and Plus.DblClick()
for it. As if you have the following in your CSS:
#clickable { aspect:"Plus.Click" "Plus.DblClick"; }
The aspect mechanism is actively used by Plus ( /samples/+plus/ ) and Lang ( /samples/+lang/ ) engines in Sciter SDK.
Plus provides declarative data binding facilities “a la” AngularJS and Lang is about i18n support.