W3C: “Selectors API Level 1” is out but …

February 24, 2013

Filed under: HTML and CSS,Sciter,Web Application Techologies — Andrew @ 8:26 pm

"Selectors API Level 1" document started in 2006 has reached status of W3C Recommendation these days. Which means we may see it implemented uniformly across all browsers ( those browsers that are alive yet 😉 ).  

But I am disappointed by features provided by this API. It de-facto contains 6 methods but only two of them (first two in the table below) are really useful.

jQuery and Sciter have full set of selector methods needed in practice, but the Selector API just scratched the surface as you see below.

Let’s take a look on what this API gives us and compare with similar features available in Sciter/HTMLayout and jQuery.

function W3C Selectors Sciter jQuery
find first matching element in a document document.querySelector("selector")
: Element
self.select("selector")
: Element
$("selector").first()
: $Obj
find all matching elements in a document document.querySelectorAll("selector")
: staticNodeList
self.selectAll("selector")
: array (of Elements)
$("selector")
: $Obj
find first matching sub-element of an element
using global selector
element.querySelector("selector")
: Element
(See below) (See below)
find all matching sub-elements of an element
using global selector
element.querySelectorAll("selector")
: staticNodeList
(See below) (See below)
find first matching sub-element of an element
using local selector
N/A element.select("selector")
: Element
$obj.find("selector").first()
: $Obj
find all matching sub-elements of an element
using local selector
N/A element.selectAll("selector")
: array (of Elements)
$obj.find("selector")
: $Obj
find first matching sub-element of an element
using rooted local selector
N/A element.select(":root > cont1 > cont2")
: Element
$obj.find("> cont1 > cont2").first()
: $Obj
find all matching sub-elements of an element
using rooted local selector
N/A element.selectAll(":root > cont1 > cont2")
: array (of Elements)
$obj.find("> cont1 > cont2")
: $Obj
find first parent matching the selector N/A element.selectParent("selector")
: Element
$obj.first().closest("selector")
: $Obj
find all parents matching the selector N/A element.selectAllParents("selector")
: array (of Elements)
$obj.first().parents("selector")
: $Obj
check if the element satisfies given selector N/A element.match("selector")
: true | false
$obj.first().is("selector")
: true | false

Where:

  • global selector – selector that uses document root as a selector root.
  • local selector – selector that uses the element itself as a selector root.
  • rooted local selector – selector that contains explicit reference of the element itself as first component.
    For example, in Sciter, this call: ul.selectAll(":root>li") will find all <li> elements that are direct children of the ul element.

The element.querySelector[All]() method defined in the Selector API is just a variation of document.querySelector[All]() but on subset of descendants of the element. Consider this HTML fragment:

<ul>
  <section id=test>
    <ol>
      <li>one</li>
      <li>one</li>
    </ol>
  </section>
</ul>

With the use of the Selector API this code:

var section = document.getElementById("test");
var nListItems = section.querySelectorAll("ul li");

will give you two [items].

But the same thing with jQuery (or Sciter):

var nListItems = $("#test").find("ul li");

will give you zero items. jQuery and Sciter use local selectors (rooted or not).

So methods provided by the Selectors API cannot be used by jQuery to implement its all selector look up methods natively. Only one of them – global look-up can use this API, All local look up methods shall still use home brewed selector implementation in script.

I haven’t seen anyone requesting such strange element.querySelectorAll method and have no clue why it was included in the spec. If someone really needs such local look up using global selectors then it is a matter of writing something like this (in Sciter or jQuery):

section.selectAll("*").filter( :child: child.match("ul li") );

But I don’t know why someone will ever need such method…

The Selectors API has mark "Level 1" so I hope rest of methods will be added soon in Level 2.

So far the mountain has brought forth a mouse. And yet it took 6 years to do so, eh?

Use of CSS constants in script.

February 17, 2013

Filed under: HTML and CSS,Sciter,Script,Source code — Andrew @ 7:31 pm

In Sciter you can define CSS constants using @const declarations like this:

<style>
  @const TEST_STR:"test";
  @const TEST_COLOR: rgb(128,0,0);
  @const TEST_NUMBER: 128;
</style>

and use them not only in CSS ( as @TEST_COLOR for example ) but also in script using accessor like this:

var test_str = self.style.constant("TEST_STR");

If you think that self.style.constant is too narrative then you can define short “stringizer” function for it:

  function $const( name ) { return self.style.constant(name) || ""; }

and later use it as:

var t1 = $const(TEST_STR); // "test" string
var t2 = $const(TEST_COLOR); // object of type Color, color(128,0,0)
var t3 = $const(TEST_NUMBER); // integer, 128

Can I get checkboxes back somehow?

February 9, 2013

Filed under: Usability — Andrew @ 2:55 pm

I think it is something wrong with modern variations of checkboxes. Consider this iOS version:

iOS checkbox

It is not clear is it in “On” state or you need to click on “On” label to switch it on?

But people from Windows 8 usability team went even further with their version:
Windows 8 checkbox

Am I the only one who think that this is completely non-intuitive?

The check box has to have two distinct visual styles telling its current state without need for the user to guess its state. IMO, old plain check mark is just perfect idiom for that, why do we need to reinvent the wheel here?

TIScript, hidden treasures: for/in loop

February 7, 2013

Filed under: Sciter,Script,Source code — Andrew @ 9:12 am

Integer data type in TIScript is iteration-able, means the following works in TIScript:

for(var i in 100)
  stdout.println(i);

The code above will print numbers from 0 to 99 in stdout.