H-SMILE core. CSSS! (css-script) language.
CSSS! is an extension of classic CSS (Cascading Style Sheets) by the scripting to give it the ability to define some basic behavioral styles of elements.
CSSS! script can appear in a) attributes with names ending with '!' (exclamation) mark and b) inside the
Here is list of active CSS attributes supported by h-smile core engine intrinsically.
Example, implementation of
<label for="id"> functionality but for any element that has attribute
hover-on! : $1(#< self.for >):hover = true;
hover-off! : $1(#< self.for >):hover = false;
active-on! : $1(#< self.for >):focus = true;
outline: 4px glow blue 1px;
hover-off are causing bound element of this label to get :hover state. Therefore mouse hover on the label is the same as hovering bound element itself. The rule
active-on!: does the magic - it sets focus on the bound element.
For the meaning of
$1(...) see chapter Selector pseudo-functions below.
CSSS! is used as embedded in host CSS syntax and grammar. This limits list of symbols/construction that can by used by the CSSS!. CSSS! is not using symbols:
'}' in its notation. To be precise symbol ';' is used as an end of script statement ending script text.
Identifiers (nmtokens) start with a alphabetic character, '-', '_' or '$' followed by any number of alphabetic characters, '-', '_', '$' or digits ([0-9]). Note the symbol '-' here, as in CSS syntax it is allowed to be a part of the name. To solve conflicts with sign '-' as an operator minus always enclose it by spaces.
nmtoken -> [a-zA-Z_\-$]+[a-zA-Z_\-$0-9]*
CSSS! has following keywords:
true false null self
< > <= == != >= && ||
+ - * / % ^ | &
Operators that will be supported in next versions:
~= ~/ ~% %~ /~
<condition> ? <true-part> [ # <false-part> ]
Note that ternary operators can be used as conditional statements (if ... then ... else ...):
self:value > 12 ?( self:current = true, self.scroll-to-view()); - if value of self element is larger than 12 make self current and scroll it to the view.
CSSS! is a typeless language. All variables can hold following values:
- null - no value;
- boolean that has two values: true and false;
- integer - 32bit signed integer;
- float - 64bit float number;
- string - string of UNICODE characters;
- object - reference to the DOM element;
- object-set - special object that represent set of DOM elements. Function $() returns such values.
- function-reference - references to functions declared in CSSS!
No aggregate types (like array) are supported. Intentionally.
accepts integer numbers, floating point numbers, stings literals, length units and regexp literals:
integer-literal -> [0-9]+ | '0x' [0-9A-Fa-f]+ | ''' character ''' | key-code-literal
float-literal -> [0-9]+ '.' [0-9]+
float-literal -> [0-9]+ '.' 'e'|'E' '+'|'-' [0-9]+
string-literal -> '"' [.]* '"'
regexp-literal -> '/' <single line regular expression> ['/ig'] ';'
length-literal -> <integer-literal> | <float-literal> immediately
followed by one of:
'pt' | 'px' | 'pc' | '%' | 'em' | 'ex' | 'in' | 'cm' | 'mm'
Key-code-literal is a single character enclosed by single quote or one of the following:
'RETURN' | 'LEFT' | 'RIGHT' | 'UP' | 'DOWN' | 'PRIOR' | 'NEXT' | 'TAB' | 'HOME' | 'END' | 'DELETE' | 'INSERT' | 'BACK'
To define key combinations Ctrl+X like prepend name of the key with symbol
34 - Integer
0xAFED1234 - Integer
1.52 - Float
1.e2 - Float
1.e-2 - Float
"Hello world!" - String
12pt - Length value that is getting resolved to
number of pixels in arithmetic expressions.
'A' - Code of character 'A', Integer
Example of key-code-literals:
key-code() == '^A'? ... # // Ctrl+A pressed
key-code() == '^NEXT'? ... ; // Ctrl+PgDown pressed
Comment is a sequence of characters ignored by compiler. There are two types of comments:
'//' <text-no-crlf> end-of-line
'/*' <text> '*/'
CSSS! program is a sequence of statements separated by
',' (comma) symbols. And ends by symbol
';'. Following statements are supported by the CSSS! script:
<left-side-expression> '=' <expression>.
<name> '=' <expression>
Block is a list of comma separated expressions:
'(' <expression> [, <expression>]* ')'
Value of the block equals to the value of last expression executed in the list.
<logical-expresion> '?' <when-true-expression> [ '#' <when-false-expression> ]
Logical expression is getting evaluated and if it is
true then expression on the right side of '?' is getting evaluated. In case of
false expresion on the right side of '#' (a.k.a. not equal) is geting evaluated. '#' part can be ommited.
No loops in CSSS!. Intentionally. (But there is a tail recursion in functions for that purposes)
return statement is used for returning values from functions:
For each, enumeration
<object-set> '->' <reference-to-function-with-single-parameter>
Enumeration is used for invocation of function on the right for each element of object-set-expression on the left. Such pseudo functions as
$c() produce sets - collection of DOM elements satisfying their selectors.
total = 0,
$(input.number) -> @(el) total = total + el:value,
$1(td#total):value = total;
Code above means following:
When value of some
<input class="number"> is getting changed do the following:
- declare variable total with initial value 0,
- declare function
@(el) total = total + el:value,
- call this function for any DOM element satisfying
- assign that total to the first element satisfying selector
DOM attributes and states access
Attributes of DOM elements can be accessed by using dot notation:
<object-or-object-set> '.' <attribute-name>
Example, for the element
<input type="text"> following:
t = self.type
will retrieve value of DOM attribute named "type" (that has "text" here) and assign it to the variable
State fields (runtime values) of DOM elements can be accessed by using following notation:
<object-or-object-set> ':' <state-name>
Where state-name is a name of one of state flags recognized by CSS:
CSS attributes access
CSS attributes of DOM elements can be accessed by using '::' accessor:
<object> '::' <css-attribute-name>
Example, following timer even handler will gradually make element transparent:
timer!: self::opacity < 1.0?
self::opacity = self::opacity + 0.1 #
self designates object - DOM element that has this rule applied to.
cancel designates special value that is used with
return statement to instruct runtime to stop event propagation further.
CSSS! intentionally supports only anonymous custom defined functions.
Functions are declared as:
'@(' <parameter-list> ')' <statement> | <block>
<parameter-list> is a comma separated list of names.
Function can be assigned to variable:
foo = @(p1, p2) p1 + p2, ...
That will declare function with two parameters
p2 and body
p1 + p2 and assign reference of the function to the
Invocation of functions is as usual
<variable> '(' <expression-1> , ... <expression-n> ')'
Example, following will invoke function foo above and assign its return value to variable bar:
bar = foo(1,2)
There are two global selector functions:
$(selector) - select elements globally with the
:root set to the root node of the document.
$1(selector) - returns object - first element matching the selector with the :root set to the root node of the document.
Function $() return set (possible empty) of DOM element selected. $1() function returns single DOM element - first element that matches the selector.
Selector functions support value concatenation in the form
$( ... <value> ... ) where '<' and '>' parameter inclusion brackets.
Example, followng statemets:
ncol = 2, $( table td:nth-child(< ncol >)).some-attr = "hi!";
will set "hi!" to attribute some-attr for all elements satisfying the selector:
int(val)- converts value val into integer;
float(val)- converts value val into float number;
length(val) - converts value val into length unit number;
min(val1, val2 ... valN)- returns minimal value of parameters passed;
max(val1, val2 ... valN)- returns maximum value of parameters passed;
limit(val, minval, maxval) - returns val if it is inside [minval...maxval] range, minval if val is less than minval or maxval otherwise.
String object properties and methods
string.length - property, length of the string object;
string.toUpper() - method, returns upper case version of the string;
string.toLower() - method, returns lover case version of the string;
string.substr(start[, length = -1]) - method, returns fragment of the string, if length is less than zero returns rest of the string.