whatwg / dom

DOM Standard
https://dom.spec.whatwg.org/
Other
1.58k stars 294 forks source link

Element.matches and :scope #1081

Open lifaon74 opened 2 years ago

lifaon74 commented 2 years ago

Currently, the css selector :scope matches the element itself (spec: https://dom.spec.whatwg.org/#ref-for-dom-element-matches%E2%91%A0), for the .matches method.

However, usually, we use :scope to match a parent element and select for example its direct descendants.

document.body.querySelectorAll(':scope > *')

Sadly with the current .matches definition we cannot reproduce a similar behavior.

document.body.children[0].matches(':scope > *'); // because we can't supply the ':scope' node, the selector will always return false

So we can't "reverse" querySelector with matches:

const childNode = parentNode.querySelector(':scope > *');
childNode.matches(':scope > *'); // false => :'(

I suggest, that we could update the .matches definition to accept a specific ':scope' as second parameter:

interface ElementMatchesOptions {
  scope?: ParentNode; // by default this values is set to the Element itself
}

interface Element {
  matches(
    selector: string,
    options?: ElementMatchesOptions,
  ): boolean;
}

The update definition is subject to discussion/modification, here it's just an example.

So we could have:

const childNode = parentNode.querySelector(':scope > *');
childNode.matches(':scope > *', { scope: parentNode }); // true => works !

What do you think guys ?

annevk commented 2 years ago

Heya, please take note of https://heyguys.cc/ for the future. (https://whatwg.org/faq#adding-new-features and https://whatwg.org/working-mode#changes might also be of interest.)

This sounds like an interesting idea and I think it might have been suggested in the past. Do libraries typically provide for this? Are they often used? Any questions on Stack Overflow? It would help to have some idea with respect to developer needs in order to prioritize this.

lifaon74 commented 2 years ago

Well actually, I didn't find any subject or topic asking for a .matches with the possibility to specify a :scope. It seems that the :scope selector is not used frequently, after a few searches on github, stackoverflow or google.

A workaround exists:

const childNode = parentNode.querySelector(':scope > *');
childNode.matches('* > :scope'); // true => works !

However, it has 2 drawbacks:

But as you said, it requires some community approval, requirement and/or interest. Maybe I'm the only one to find interest in it.

morille commented 1 year ago

This would be very useful for event delegation.