Re: Supporting Scoped Selectors in Selectors API 2

Tab Atkins Jr. wrote:
> On Mon, Sep 28, 2009 at 3:59 PM, Lachlan Hunt<lachlan.hunt@lachy.id.au>  wrote:
>> The point is that in order to solve the problem, we need some kind of
>> indicator to say that this is a scoped selector.
>
> The problem with it as written, though, is that you're *only* using it
> in a single case, when you're trying to do a scoped selector that
> starts with the descendant combinator.  This makes it very likely that
> it will be overlooked, and authors will accidentally forget to use it
> when needed.  Even worse, it's likely that they won't ever notice it
> breaking from the wrong behavior, since the difference between scoped
> and regular querySelector is relatively minor.
>
> That's why I suggested, if you required a flag, to make it required in
> *all* cases, even when it's implicitly obvious from the selector
> string.  This way it becomes an automatic talisman that authors insert
> without thinking.  It's still crufty, but it's more likely to work
> without relatively subtle bugs creeping into pages by accident.  This
> is not my preferred solution, though.

That's how I had it when I first drafted it the other day. I then 
changed it as it seemed a little redundant in those cases.  I'm not 
really strongly opposed to changing it back, but I'll have to think 
about it.

>> The final option is to simply forgo the special parsing entirely and require
>> authors and javascript libraries to insert explicit :reference
>> pseudo-classes at the beginning of each selector, but we'd still need to
>> find some way of addressing the sibling element problem, and that would
>> require authors to use a more complicated approach like:
>>
>> elm.parentNode.querySelectorAll(":reference+p", elm);
>
> I don't see why.  You are already proposing that certain things in the
> query string implicitly trigger the new scoped behavior (the presence
> of a combinator at the start of a selector, or the ! symbol at the
> start).  Why not have :reference do that instead?

It needs to be a flag that is distinct from the pseudo-element itself, 
because otherwise it will make the processing requirements significantly 
more complex and even harder to define.

It might appear to work for the simple case above, but consider the 
following cases:

elm.querySelectorAll(":reference+p, div div");

Or the reverse of that:

elm.querySelectorAll("div div, :reference+p");

As defined, for non-scoped selectors, the implementation only needs to 
test descendants of elm.  For scoped selectors, it needs to check the 
whole tree (or at least the element's descendants, siblings and their 
descendants).

In the above case, it mixes both scoped and non-scoped selectors, so the 
implementation would need to perform complicated processing to ensure 
that "div div" was only evaluated against the element's decendants, and 
that :reference+p" was evaluated against the other elements.  Without 
doing that, you would end up with false positives and potentially 
confusing results.

> *Actually, my preferred solution is to just have a function that does
> scoped stuff automatically, since that is much more intuitive and in
> line with how javascript libraries do things already.

Maybe, if the syntactic flag solution isn't feasible and if I can avoid 
having to introduce too many extra methods by doing this.

> I'm not sure why we needed two separate functions either when a
> simple [0] tacked to the end of the *All call would work.

It's less efficient to use the All method when you know you only want 
the first result, since the implemention needs to find all results and 
create the node list only to have it discarded almost immediately. 
Anyway, this particular issue has been resolved and closed for a long 
time, so I won't discuss it further.

-- 
Lachlan Hunt - Opera Software
http://lachy.id.au/
http://www.opera.com/

Received on Monday, 28 September 2009 23:49:53 UTC