Re: QSA, the problem with ":scope", and naming

On Thu, Oct 20, 2011 at 7:23 AM, Boris Zbarsky <bzbarsky@mit.edu> wrote:
> On 10/20/11 1:08 AM, Tab Atkins Jr. wrote:
>>
>> I disagree.  It's extremely useful and natural for .find(":scope +
>> div") to match sibling of the context node.
>
> I really don't think it is.  If you want that, use document.find(":scope +
> div", context).

Why do that, when the previous one is shorter and simpler, and unambiguous?

The whole point is that we *know* the behavior I suggest is well-known
and easy to use, because jQuery (and probably other selector engines?)
does it already.  I know for a fact that I've appreciated that
behavior in my own coding.  It would have been very annoying to me had
I been forced to break my chaining just to select a sibling, when the
exact same style works fine to select a child.  It's intuitive and
useful.

The behavior is useful in jQuery because it lets me evaluate a
selector, do some work to the matched elements, and then just
"continue" the selector to grab more, regardless of what form the
continuation takes.  Forcing me to think about the continuation's form
(and even worse, completely rearrange the call structure) is just
mean.  ^_^


>> Basically, the presence of :scope would turn off *all* the limitations
>
> That's a _really_ bizarre behavior.  So in this case:
>
>  foo.find(":scope + div, div")
>
> what all divs in the document would be found?  Or is the "oh, ignore the
> reference node except for matching :scope" meant to only apply on a
> per-selector basis inside the selector list?  That has its own issues,
> especially with performance (e.g. merging nodesets while preserving DOM
> order).

Per-selector basis; we're not talking about naive string manipulation
here.  Your example would return divs that are descendants or an
adjacent sibling of the scoping element.

I don't really see the performance issues.  If you use + or ~ off of
:scope, you know for a fact that all the nodes come *after* any
selectors that don't have :scope.  If you use the subject indicator or
the reference combinator that's not necessarily true, but those
selectors will be slow already.  Even then, sorting them into DOM
order should be relatively easy:

1. Run the :scope-carrying selectors across the document together,
automatically yielding a dom-ordered list.
2. Run the :scope-absent selectors together, automatically yielding a
dom-ordered list.
3. Find where the scoping element would be inserted in the #1 list,
and insert the entire #2 list there.

There's no further interleaving that could cause trouble.

~TJ

Received on Thursday, 20 October 2011 20:33:00 UTC