Skip to content

Commit

Permalink
fix: correctly look for sibling elements inside blocks and components
Browse files Browse the repository at this point in the history
  • Loading branch information
7nik committed Jan 24, 2025
1 parent e9cc7dc commit 22b5193
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 61 deletions.
5 changes: 5 additions & 0 deletions .changeset/curly-balloons-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: correctly look for sibling elements inside blocks and components
21 changes: 12 additions & 9 deletions packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js
Original file line number Diff line number Diff line change
Expand Up @@ -638,19 +638,26 @@ function get_following_sibling_elements(element, include_self) {
/** @type {Array<Compiler.AST.RegularElement | Compiler.AST.SvelteElement>} */
const siblings = [];

// ...then walk them, starting from the node after the one
// containing the element in question
// ...then walk them, starting from the node containing the element in question
// skipping nodes that appears before the element

const seen = new Set();
let skip = true;

/** @param {Compiler.AST.SvelteNode} node */
function get_siblings(node) {
walk(node, null, {
RegularElement(node) {
siblings.push(node);
if (node === element) {
skip = false;
if (include_self) siblings.push(node);
} else if (!skip) siblings.push(node);
},
SvelteElement(node) {
siblings.push(node);
if (node === element) {
skip = false;
if (include_self) siblings.push(node);
} else if (!skip) siblings.push(node);
},
RenderTag(node) {
for (const snippet of node.metadata.snippets) {
Expand All @@ -663,14 +670,10 @@ function get_following_sibling_elements(element, include_self) {
});
}

for (const node of nodes.slice(nodes.indexOf(start) + 1)) {
for (const node of nodes.slice(nodes.indexOf(start))) {
get_siblings(node);
}

if (include_self) {
siblings.push(element);
}

return siblings;
}

Expand Down
118 changes: 66 additions & 52 deletions packages/svelte/tests/css/samples/has/_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,182 +6,196 @@ export default test({
code: 'css_unused_selector',
message: 'Unused CSS selector ".unused:has(y)"',
start: {
line: 31,
line: 33,
column: 1,
character: 308
character: 330
},
end: {
line: 31,
line: 33,
column: 15,
character: 322
character: 344
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector ".unused:has(:global(y))"',
start: {
line: 34,
line: 36,
column: 1,
character: 343
character: 365
},
end: {
line: 34,
line: 36,
column: 24,
character: 366
character: 388
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector "x:has(.unused)"',
start: {
line: 37,
line: 39,
column: 1,
character: 387
character: 409
},
end: {
line: 37,
line: 39,
column: 15,
character: 401
character: 423
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector ":global(.foo):has(.unused)"',
start: {
line: 40,
line: 42,
column: 1,
character: 422
character: 444
},
end: {
line: 40,
line: 42,
column: 27,
character: 448
character: 470
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector "x:has(y):has(.unused)"',
start: {
line: 50,
line: 52,
column: 1,
character: 556
character: 578
},
end: {
line: 50,
line: 52,
column: 22,
character: 577
character: 599
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector ".unused"',
start: {
line: 69,
line: 71,
column: 2,
character: 782
character: 804
},
end: {
line: 69,
line: 71,
column: 9,
character: 789
character: 811
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector ".unused x:has(y)"',
start: {
line: 85,
line: 87,
column: 1,
character: 936
character: 958
},
end: {
line: 85,
line: 87,
column: 17,
character: 952
character: 974
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector ".unused:has(.unused)"',
start: {
line: 88,
line: 90,
column: 1,
character: 973
character: 995
},
end: {
line: 88,
line: 90,
column: 21,
character: 993
character: 1015
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector "x:has(> z)"',
start: {
line: 98,
line: 100,
column: 1,
character: 1093
character: 1115
},
end: {
line: 98,
line: 100,
column: 11,
character: 1103
character: 1125
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector "x:has(> d)"',
start: {
line: 101,
line: 103,
column: 1,
character: 1124
character: 1146
},
end: {
line: 101,
line: 103,
column: 11,
character: 1134
character: 1156
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector "x:has(~ y)"',
start: {
line: 121,
line: 123,
column: 1,
character: 1326
character: 1348
},
end: {
line: 121,
line: 123,
column: 11,
character: 1336
character: 1358
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector "f:has(~ d)"',
start: {
line: 133,
column: 1,
character: 1446
},
end: {
line: 133,
column: 11,
character: 1456
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector ":has(.unused)"',
start: {
line: 129,
line: 141,
column: 2,
character: 1409
character: 1529
},
end: {
line: 129,
line: 141,
column: 15,
character: 1422
character: 1542
}
},
{
code: 'css_unused_selector',
message: 'Unused CSS selector "&:has(.unused)"',
start: {
line: 135,
line: 147,
column: 2,
character: 1480
character: 1600
},
end: {
line: 135,
line: 147,
column: 16,
character: 1494
character: 1614
}
}
]
Expand Down
10 changes: 10 additions & 0 deletions packages/svelte/tests/css/samples/has/expected.css
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@
color: red;
}*/

d.svelte-xyz:has(+ e:where(.svelte-xyz)) {
color: green;
}
d.svelte-xyz:has(~ f:where(.svelte-xyz)) {
color: green;
}
/* (unused) f:has(~ d) {
color: red;
}*/

.foo {
.svelte-xyz:has(x:where(.svelte-xyz)) {
color: green;
Expand Down
12 changes: 12 additions & 0 deletions packages/svelte/tests/css/samples/has/input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<z></z>
{#if foo}
<d></d>
<e></e>
<f></f>
{/if}
</y>
</x>
Expand Down Expand Up @@ -122,6 +124,16 @@
color: red;
}
d:has(+ e) {
color: green;
}
d:has(~ f) {
color: green;
}
f:has(~ d) {
color: red;
}
:global(.foo) {
:has(x) {
color: green;
Expand Down

0 comments on commit 22b5193

Please sign in to comment.