Re: [SelectorsAPI] Thoughts on querySelectorAll

> So say the original |selector| is ":not(:link)" and the UA doesn't
> support 
> :link.  This will presumably split the string into ":not(" and
> ":link)", neither 
> of which is that useful.

Absolutely - however that's a semi-trivial check for the library (just look for an open :FOO(... before beginning to parse). What's important about the position is that we can determine, programmatically, WHAT selector is failing. The critical issue, right now, is that there is no way to do defensive, unobtrusive, testing of a browser's querySelectorAll implementation - it's a complete black box.

It's also not sufficient to provide the sequence of characters that are valid - since that still leaves us with a "black box" problem. If all you say is that "something inside the :not() isn't valid" then that doesn't help - we're back to where we started.

> Or say the original |selector| is "div ~ span" and the UA doesn't
> support the 
> '~' combinator.  You end up with "div" and "~ span" as the two pieces
> and then 
> what?  To apply the above query-and-filter solution you'd really want
> to 
> querySelectorAll("span") and then filter based on "div ~", I would
> think.

That's not really an issue - there isn't a single, publicly available, selector engine that queries in that manner. They all work from left-to-right (finding divs, then finding spans).

> This is not even worrying about cases when the querySelectorAll call
> passes in 
> multiple comma-separated selectors...

That's not really an issue, either, look at the following:

  div, :bad, span

Most JavaScript libraries, when they see the ',' interpret it to mean something like "take what we already have and push it on a stack for later retrieval" - that way when we hit an exception with :bad it'll really just be like handling any other selector.

> I could be wrong, of course.  Maybe someone will think of an error
> reporting 
> mechanism that provides information that's useful and isn't too
> cumbersome for 
> UAs.  But I should note that this can always be done as a later
> addition to the 
> specification.  That is, adding more information to the exception is a
> backwards-compatible change: if the information isn't present, just
> redo the 
> query by hand, else do something with the information.  So it might
> make more 
> sense for a later version of the specification, possibly, if it looks
> like 
> coming up with a decent solution here would take a while and people
> want to move 
>   the rest of the spec out of limbo.

This really must be done *now* before implementations get too baked. The fact that there's no way to determine what a useragent is capable of supporting (only through the crude "try it and see if it fails" technique) means that a new querySelectorAll will have to be performed on *every single selector call* just to see if it works or not. There is no way to say "Oh, hey, Mozilla doesn't like :hidden we should save the overhead of calling that every time."

Not to mention the fact that libraries are going to need to try and use querySelectorAll for as many queries as possible (or for as much of the query, as possible, if there's something bad in it). By providing an index it'll, at least, give them a fighting chance towards making that possible.

For example:

  div span > a[href]:hidden

With the extra index all of the leading "div span > a[href]" could be lopped off and re-run without a hitch - and then the extra :hidden could be handled by the library. However, as it stands now, the only thing that we can do is say "Oh well, I'm not sure what went wrong - I guess we'll do it the slow way."

Why this is of such great concern to me is that "invalid selectors" (ones provided by libraries) are actually used very frequently. For example, here's a break-down of the most common selectors used by some popular jQuery sites:
http://ejohn.org/files/selectors.html

Note that a large percentage of the queries involve a special selector (the ones in red) - those queries will receive absolutely no benefit from the introduction of querySelectorAll - and, hence, JavaScript libraries won't receive a benefit from querySelectorAll - with the current exception scheme. Additionally, some more of the queries could be "marked as red" if a useragent doesn't support them (such as IE8 not supporting a number of CSS selectors). Libraries would, again, be completely stuck for a way to work around those issues. The ability to, at least, determine if something should be handled by a library (by using the position, for example) would actually make this feasible and make this method useful, once again.

--John

Received on Thursday, 1 May 2008 13:36:55 UTC