Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for :scope as a pseudo-class for querySelector[All] / matches / closest #578

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Paril
Copy link
Contributor

@Paril Paril commented Jan 19, 2024

:scope is a super useful tool in modern web dev, and it's hard to live without it once you're used to using it. This PR adds support for :scope in its most useful context: used as a scope limiter in Element-based selector functions.

This PR only covers the code-side use of :scope; :scope in an RCSS file will do nothing. I don't believe it's useful at all in RCSS without support for @scope or :root, so I didn't bother with those.

All of the use-cases here should apply & work: https://developer.mozilla.org/en-US/docs/Web/CSS/:scope#using_scope_in_javascript

@mikke89 mikke89 added the enhancement New feature or request label Jan 22, 2024
@mikke89
Copy link
Owner

mikke89 commented Jan 25, 2024

Hey, and thanks a lot for the contribution.

I haven't really looked at this pseudo class selector before. Looks handy when using query selectors, especially a bit complex ones.

I am a bit worried about how invasive this is code-wise. That's not great for maintenance and refactoring. I wonder if there is some way we could improve that? I understand that this selector can only be used once in a query, maybe something we could take advantage of, also performance-wise.

How does this selector behave when used in descendant elements? We should have some test cases for that.

What happens when using the selector in RCSS?

@Paril
Copy link
Contributor Author

Paril commented Jan 26, 2024

It's a staple of modern web development; its main use is to be able to use > while referring to the element being queried on, essentially a faster way of doing Array.from(element.childNodes).filter(e => e.matches("xxx")) or any other previously-necessary hack, one can just do element.querySelectorAll(":scope > xxx").

This was the least invasive way I had found to implement it; it only requires tracking a scope down to the querying function. I'm not sure where else it could go, and I didn't really want to modify all of the types involved just to store a single field on them. My first iteration tried to shove an element reference in structural_selectors somewhere but that didn't end up working. If you have a suggestion, let me know and I'll hammer away at it.

We don't have :is, but since it's basically just inverted :not, I did see that this works as expected: :scope > p:not(:scope > div) - it's a dumb selector but it behaves the same as it does on Chrome. When it comes to combining with ~ and +, that appears to work as expected as well; these two matches test succeed, as they do on Chrome:

	{ "G", "#F ~ :scope",    true },
	{ "G", "#F + :scope",    true }

I've never seen that used in the wild though, heh. The selector can appear more than once in a query, but it always refers to the same element.

When used in RCSS, :scope is null and will never match anything, so the selector matches nothing. The only deviation from CSS here is that, in CSS, when :scope is null, it instead refers to :root - we don't have :root so I left that unimplemented, but in theory it would just need to refer to the <rml> element.

@Paril Paril marked this pull request as draft February 6, 2024 22:58
@Paril
Copy link
Contributor Author

Paril commented Feb 6, 2024

Converting to draft for now as I won't have time for a while to poke these.

@Paril Paril marked this pull request as ready for review July 30, 2024 22:43
@Paril
Copy link
Contributor Author

Paril commented Jul 30, 2024

Okay, I'm back with this one - I wasn't sure of any alternative approaches for implementation, though, and I'm down to discuss any ideas on how to better approach it. It's been super useful in our own development to speed up matching direct descendent children elements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants