Friday, May 2nd, 2008

We are JavaScript library authors. Hear us roar!

Category: Browsers, CSS, JavaScript

John Resig “doesn’t think there’s a single JavaScript developer who isn’t excited about the new Selectors API specification (and the upcoming implementations).”

He was asked to provide feedback on the API, and he sent them an email with just that.

He had three concerns:

DOMElement.querySelectorAll returning incorrect elements

This is the most critical issue. As it stands DOM Element-rooted queries are borderline useless to libraries – and users. Their default behavior is unexpected and confusing. Demonstrated with an example, using Dojo:

  1. <div><p id="foo"><span></span></p></div>
  2.   <script src="http://o.aolcdn.com/dojo/1.1.0/dojo/dojo.xd.js"></script>
  3.   <script>
  4.   var foo = document.getElementById("foo");
  5.   // should return nothing
  6.   alert( dojo.query('div span', foo).length );
  7.   // will return the SPAN (booo!)
  8.   alert( foo.querySelectorAll('div span').length );
  9.   </script>

He then asked other library authors if they agreed:

Andrew Dupont (creator of Prototype’s selector engine):

My issue with this is that it violates principle of least surprise and bears no resemblance to the APIs in the wild.

Alex Russell (creator of Dojo’s selector engine):

This is a spec bug.

Combinator-rooted Queries

I read about some prior discussion concerning this (especially in relation to DOMElement.querySelectorAll-style queries). This is an important part of most libraries, as it stands. Maciej’s proposed solution of using :root to allow for front-leading combinators is perfectly acceptable to me (where :root is made equivalent to the element, not the document element).

javascript

  1. // jQuery
  2.   $("#foo").find("> span");
  3.  
  4.   // DOM
  5.   document.getElementById("foo").querySelectorAll(":root > span")

This is something that a library can easily detect and inject.

Error-handling

I’m perfectly fine with the proposed try/catch solution however there must be a way of easily determining what the invalid portion of the selector was. Currently the following occurs in Safari:

javascript

  1. try {
  2.     document.querySelectorAll("div:foo");
  3.   } catch(e) {
  4.     alert(e); // "Error: SYNTAX_ERR: DOM Exception 12"
  5.   }

If there were extra properties to point to what the inappropriate selector was, that’d be fundamentally important. Probably the best solution (for both implementors and JavaScript library authors) would be to simply provide a character index, working something like the following:

javascript

  1. var selector = "div:foo";
  2.   try {
  3.     document.querySelectorAll(selector);
  4.   } catch(e) {
  5.     alert(selector.slice(e.position)); // ":foo"
  6.   }

It is nice to see this all in the open, and especially watching the library authors get involved in the specs that effect us all.

Posted by Dion Almaer at 10:40 am
2 Comments

+++--
3.9 rating from 27 votes

2 Comments »

Comments feed TrackBack URI

Having more information when exceptions occur is nice, but it’s trivial to test selectors using the current frameworks in something like firebug. Are a lot of people generating selectors dynamically?

Comment by AndyB — May 2, 2008

I’ve generated a few selectors dynamically, for example when using naming conventions in the code. But I try to avoid this if at all possible. In any case, by stepping through the code you should be able to see which selector it choked on.

Comment by jdempcy — May 8, 2008

Leave a comment

You must be logged in to post a comment.