> If we were to do the implementation similarly to Dojo, then it would
> be 
> impossible to select only child elements on the context node. 
> Consider 
> this:
> 
> <div id=foo>
>    <div> <!-- A -->
>      <div> <!-- B -->
>      </div>
>    </div>
> </div>
> 
> foo.querySelectorAll("div");

Isn't that what the purpose of :root/:scope/$self/etc. was?

  foo.querySelectorAll(":scope > div")

The above would return only the child nodes of the #foo div.

> Assuming the selector won't match the context node (foo) itself, that
> would contain both descendant div elements (A and B).  But in the case
> where only child nodes of foo are wanted (A), this is impossible.
> This following would not work because the previous assumption was that
> selectors would not match the element itself.
> 
> foo.querySelectorAll("#foo>div");
> 
> Dojo gives the same result for that scenario.
> 
> dojo.query('#foo>div', foo);

That's a bug in Dojo. Notice that the following returns the correct result 
(using the above test page):

  var foo = document.getElementById("foo");
  dojo.query("p > span", foo)
  // => []

jQuery is the same (only without the obvious bug):
http://ejohn.org/files/bugs/qsa-root/jquery.html

  var foo = document.getElementById("foo");
  jQuery(foo).find("#foo > span")
  // => []
  jQuery(foo).find("p > span")
  // => []

> There are several reasons the spec is defined the way it is on this
> issue.
> 
> 1. It's how selectors work in existing Selector implementations. i.e.
> Given any element, the selector is evaluated against it in the context
> of the entire document tree. That makes it easier for implementations
> to 
> implement this API without requiring them to significantly alter their
> selector engines.

That's a fine goal - however wouldn't a better goal have been to base the work 
on all of the JavaScript libraries that are being emulated with this 
specification?

Considering that jQuery, alone, has millions of users it seems like it would be 
a smart choice to at least think about how things are currently being done:
http://code.google.com/p/jqueryjs/downloads/list

If the only thing that is kept in mind is how to best implement an API then 
you'll never succeed in creating a usable API: The two concepts are completely 
disassociated from each other. Of course it's completely possible to do both - 
but as we can see here, usability is being sacrificed on the altar of 
implementation simplicity.

> 2. This makes it more flexible for authors, so that they can select 
> based upon ancestor elements if needed.

When has that ever been a concern? I would think that there'd be, at least, a 
few users clamoring for that, right now, with jQuery - when that's hardly the 
case. Conflating two separate concerns: Finding elements beneath the current 
element that match an expression (contextually) versus one that matches 
globally (and, thus, matching ancestors) deserve two separate APIs. And if 
implementation, history, and massive, widespread, use are any indicator then 
contextual searching is the superior way of making this happen.

> 3. Introducing a :scope selector (or equivalent) solves all the issues
> you have raised, without sacrificing potentially useful functionality.
> :scope would also be useful in contexts outside of Selectors API, such
> as within HTML5's scoped stylesheets and possibly XBL.

Sure, it solves the technical problem but it doesn't solve the actual problem: 
The API is broken in its current state. Doing .querySelectorAll("div span") has 
the potential to return completely incorrect results - while, at the same time, 
providing no information as to how they should be used correctly. If everyone 
(save for the implementors, apparently) expects it to work in a contextual 
manner why should they even come to think about using a new selector expression 
to make it work?

> So while you haven't convinced me that we need to significantly alter
> the spec to address this issue, you have convinced me that we should
> try 
> to expedite the specification and implementation of a :scope selector
> (or equivalent).

I've lost something here: At one point you explain how it would be really hard 
for implementors to adjust their selector implementations to match contextually 
- and on the other hand you are now actively arguing for that exact feature to 
be included. Either it's hard, or not (regardless, that should have no affect 
on the actual API).

With the addition of :scope (or similar) useragents will now have to support 
contextual selectors - which completely removes any argument for not having 
them in the first place (other than "we don't want to change the spec because 
useragents started to implement it too early").

I would rather have one useragent that implements this specification correctly 
than 8 useragents that implement it incorrectly.

--John

Reply via email to