Re: Behavior of matches() and closest() with :scope()

On Tue, Sep 23, 2014 at 1:05 PM, Sean Hogan <> wrote:
> On 23/09/14 5:32 PM, Anne van Kesteren wrote:
>> On Mon, Sep 22, 2014 at 11:54 AM, Sean Hogan <>
>> wrote:
>>> No. I am also saying that if there is no explicit scope reference node
>>> passed in then the implied scope reference node is document (or some
>>> equivalent for elements not in document). I believe that currently the
>>> implied scope reference node is the element itself.
>>> Currently:
>>>      E.matches(':scope') -> true
>>>      E.matches(':scope ul li') -> false
>>> Should be:
>>>      E.matches(':scope') -> false
>>>      E.matches(':scope ul li') -> true if E.matches('ul li') is true
>> Why would that be better? As far as the :scope pseudo-element is
>> concerned, the current semantics seem much more intuitive. I could see
>> how you maybe want to rebind :scope, or restrict the tree traversed,
>> but not why you want to change the way :scope works.
>     E.matches(':scope')
>     E.closest(':has(:scope)')
> are not selectors anyone would write.
> They do not have to be useful.
> They should be consistent. e.g.
>     A.query(':scope > li > a[href]').matches(':scope > li > a[href]', A); //
> potentially true
>     document.query(':scope body').matches(':scope body'); // probably true
> Scoping is defining a boundary (not a reference node).

Correct, but irrelevant.  :scope is not directly related to selector
scoping, despite the name.  (The scoping elements are *one* source of
default :scope elements, though.)

> In the DOM, a single node can define a boundary for all the nodes *below*
> it.
> That's why in
>     A.queryAll(':scope > li > a[href]')
>     A.queryAll('> li > a[href]')
> the scope is naturally A, because queryAll() can find all nodes *below* A.

No, it can find nodes outside of A.  `A.queryAll("+ li > a[href]")`
can return an answer.  The arguments to query/queryAll are *not*
scoped selectors, they are relative selectors with a :scope element.

> SImilarly in
>     E.closest(':scope > li > a[href]', A);
> the scope is naturally A, because the search can find an element *below* A.

This is assuming a future extension where you explicitly provide a
reference element, right?  Yes, if you explicitly specify what :scope
should match, :scope should match it.

> Similarly in
>     E.closest('li > a[href]')
> the scope is naturally *document* because the search can find an element
> *below* document.

Doesn't follow, due the aforementioned fact that :scope and scoping
aren't related.  (That said, if Anne specifically says *nothing* about
scoping, :scope will default to matching the document root.)

> This is the same in
>     E.closest(':scope body')
> where the scope is document.
> Similarly it follows that in
>     E.matches(':scope > li > a[href], A);
> the scope is A.
> Similarly it follows that in
>     E.matches(':scope body')
> the scope is document.
> If there is a need for for pseudo-class in E.matches() that references E,
> then it should be a new pseudo-class, say :ref-node.

That's exactly the definition of :scope already.


Received on Tuesday, 23 September 2014 20:32:56 UTC