fix: correctly match :has()
's selector during css pruning
I've got some complex sibling combinator + :has
css selectors that match the DOM but are reported as unused by Svelte. Through further testing, it appears that some trivial cases are incorrectly marked as unused.
./packages/svelte/tests/css/samples/has/input.svelte
style
blockx:has(+ c) {
color: green;
}
x:has(~ c) {
color: green;
}
Notice that these are valid selectors based on the given DOM structure
css_unused_selector
errors. I've found that wrapping c
in :global()
seems to get rid of the errors, but I'm not sure if that should be required to get this selector working.No response
Svelte Version - 5.1.6
annoyance
Fixes #14072, alternative of #15207
:has()
was matching only against descendants or siblings, but not sibling's descendants.
In this variant, I made apply_selector
and related functions bidirectional. So the same logic can be applied to all selectors.
Changing the direction for selectors passed into :has()
broke p:has(+ y)
for the test has-with-render-tag
and to fix it I added diving into the @render()
tags during gathering siblings, which fixed the render-tag-loop
test.
I also tried to cache the function retrieving neighbor elements and got the following cache hits rates on the test cases: descendant_forward: 94,23% descendant_backward: 55,91% children_forward: 84,00% children_backward: 33,51% sibling_forward: 69,42% sibling_backward: 59,94% next_forward: 41,40% next_backward: 2,44% Though, I'm not sure how to measure performance change.
feat:
, fix:
, chore:
, or docs:
.packages/svelte/src
, add a changeset (npx changeset
).pnpm test
and lint the project with pnpm lint
Latest commit: 6b71df2
The changes in this PR will be included in the next version bump.
Name | Type |
---|---|
svelte | Patch |
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
pnpm add https://pkg.pr.new/svelte@15277
I was a bit busy and not sure how to properly benchmark, so eventually didn't get to it.