W3C home > Mailing lists > Public > www-style@w3.org > September 2014

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

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Tue, 23 Sep 2014 13:32:07 -0700
Message-ID: <CAAWBYDBu4rGgKiRQXc6JyKi+ZsgSzVV_m3dLe3PsmhVvuByVRQ@mail.gmail.com>
To: Sean Hogan <shogun70@westnet.com.au>
Cc: Anne van Kesteren <annevk@annevk.nl>, Boris Zbarsky <bzbarsky@mit.edu>, "www-style@w3.org" <www-style@w3.org>, "www-dom@w3.org" <www-dom@w3.org>, David Håsäther <hasather@gmail.com>
On Tue, Sep 23, 2014 at 1:05 PM, Sean Hogan <shogun70@westnet.com.au> wrote:
> On 23/09/14 5:32 PM, Anne van Kesteren wrote:
>>
>> On Mon, Sep 22, 2014 at 11:54 AM, Sean Hogan <shogun70@westnet.com.au>
>> 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.

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

This archive was generated by hypermail 2.4.0 : Monday, 23 January 2023 02:14:44 UTC