Re: [SelectorsAPI] Thoughts on querySelectorAll

On May 2, 2008, at 2:15 PM, John Resig wrote:

>
>
> There's a solution to the above that is both simple and intuitive:  
> The first character of the selector that the UA doesn't know what to  
> do with. For example, in the above, it would be:
>
> :not(a:link)
>       ^
> :not|test|
> ^
> :note
> ^

Your proposed "first character of the selector that the UA doesn't  
know what to do with" carries a lot of assumptions. For example, it's  
not obvious to me why in the second case, | isn't "the first character  
the UA doesn't know what to do with". It's also not clear why the  
error pointer is not at "a" in the second example, since the whole  
subexpression inside :not is what is in error (since it is not a  
simple selector).

I think it would be fairly complicated to define a way of reporting a  
specific "error character" in the face of varying browser support for  
different aspects of selectors. What exactly is the goal? Are you  
trying to distinguish real syntax errors from selectors that the UA  
doesn't know, but the library does? Or are you trying to find a  
reliable way to feature-test for different aspects of selectors up  
front?

In the former case, why not just have the library always try to parse  
the selector, and if it fails, you know that neither the UA nor the  
library could handle it. In the latter case, you could do it like this:

querySelector("a") --> exception means simple element selectors are  
not supported, unlikely, but probably means this impl is unusable
querySelector("a > b") --> exception means direct descendant  
combinator is not supported
querySelector(":not(a)") --> exception means :not descendant  
combinator is not supported
querySelector(":not(a > b)") --> exception means non-simple selectors  
inside :not are not supported

I am not entirely sure how this preflighting helps, but perhaps in  
some cases, you could arrange to have querySelector do most of the  
work for a selector it can't handle, with additional filtering by the  
JS library. I think specific capability testing would be more useful  
for this than an indicator of the error location.

> You just have to ask yourself "am I use this expression?" if not,  
> then it's an error and that's where you mark it. It's  
> inconsequential that the useragent supports :not in the :not|test|  
> example since not enough information is provided to actually use it.

I'm not sure I understand the distinction. What about this invalid  
selector: ":not(a". The error is lack of a close paren. Is the failure  
past the a (where you saw the end of the string instead of a close  
paren or some other character that would be allowed), or at the a  
(since that is the start if the subexpression that did not complete  
":not(") or at the colon, since you don't have a full valid :not  
expression? I am not sure how to tell. To a Selectors parser this case  
is actually no different than your :not(a:link) case, since you push a  
":not(" token and then an "a" token and then hit a parse error. But it  
is not really the same kind of mistake.

So, in summary, it is pretty complex to define interoperable "first  
bad character" error info. And this doesn't even match the way CSS  
parsers tend to work. If you build an LALR(1) parser, as with the  
reference grammar, the failure is often that it can't combine a  
sequence of tokens that are individually valid and the parser doesn't  
generally know enough to identify which token was bad. Compare this to  
a C compiler. They have basically the same idea of what programs are  
valid, but gcc and MSVC will not give you identical column numbers for  
errors, even though the C grammar is well-defined. It would take  
additional spec language to guarantee that.


We may still be able to help the use case you want handled, but I'd  
still like to understand more what you want to do with the error info.  
Is it for total library fallback, partial library fallback, or some  
other reason?

By the way, I appreciate that you and other JS library authors are  
looking at this API and providing feedback. I am inclined to add :- 
webkit-scoped support in WebKit's implementation as this would allow a  
very easy way to achieve the usual JS library semantics.

Regards,
Maciej

Received on Friday, 2 May 2008 22:31:14 UTC