Skip to content

Commit 0eb39d1

Browse files
authored
Merge branch 'main' into esm-1.2.1
2 parents eb4c4dc + 10a7729 commit 0eb39d1

File tree

18 files changed

+171
-84
lines changed

18 files changed

+171
-84
lines changed

.changeset/itchy-timers-relax.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: prevent infinite loops when pruning CSS

.changeset/sixty-kings-learn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: generate correct code when encountering object expression statement

.changeset/twelve-squids-wink.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"@vitest/coverage-v8": "^2.0.5",
3737
"eslint": "^9.9.1",
3838
"eslint-plugin-lube": "^0.4.3",
39-
"jsdom": "25.0.0",
39+
"jsdom": "25.0.1",
4040
"playwright": "^1.46.1",
4141
"prettier": "^3.2.4",
4242
"prettier-plugin-svelte": "^3.1.2",

packages/svelte/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# svelte
22

3+
## 5.2.11
4+
5+
### Patch Changes
6+
7+
- fix: ignore text and expressions outside the template when validating HTML ([#14468](https://github.com/sveltejs/svelte/pull/14468))
8+
9+
- fix: better account for render tags when pruning CSS ([#14456](https://github.com/sveltejs/svelte/pull/14456))
10+
311
## 5.2.10
412

513
### Patch Changes

packages/svelte/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "svelte",
33
"description": "Cybernetically enhanced web apps",
44
"license": "MIT",
5-
"version": "5.2.10",
5+
"version": "5.2.11",
66
"type": "module",
77
"types": "./types/index.d.ts",
88
"engines": {
@@ -143,7 +143,7 @@
143143
"aria-query": "^5.3.1",
144144
"axobject-query": "^4.1.0",
145145
"esm-env": "^1.2.1",
146-
"esrap": "^1.2.2",
146+
"esrap": "^1.2.3",
147147
"is-reference": "^3.0.3",
148148
"locate-character": "^3.0.0",
149149
"magic-string": "^0.30.11",

packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ const nesting_selector = {
4343
}
4444
};
4545

46+
/**
47+
* Snippets encountered already (avoids infinite loops)
48+
* @type {Set<Compiler.AST.SnippetBlock>}
49+
*/
50+
const seen = new Set();
51+
4652
/**
4753
*
4854
* @param {Compiler.Css.StyleSheet} stylesheet
@@ -60,6 +66,8 @@ export function prune(stylesheet, element) {
6066
ComplexSelector(node) {
6167
const selectors = get_relative_selectors(node);
6268

69+
seen.clear();
70+
6371
if (
6472
apply_selector(selectors, /** @type {Compiler.Css.Rule} */ (node.metadata.rule), element)
6573
) {
@@ -193,6 +201,9 @@ function apply_combinator(relative_selector, parent_selectors, rule, node) {
193201
const parent = path[i];
194202

195203
if (parent.type === 'SnippetBlock') {
204+
if (seen.has(parent)) return true;
205+
seen.add(parent);
206+
196207
for (const site of parent.metadata.sites) {
197208
if (apply_combinator(relative_selector, parent_selectors, rule, site)) {
198209
return true;
@@ -335,6 +346,8 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
335346
descendant_elements.push(element);
336347
}
337348

349+
const seen = new Set();
350+
338351
/**
339352
* @param {Compiler.SvelteNode} node
340353
* @param {{ is_child: boolean }} state
@@ -355,6 +368,9 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
355368
}
356369
} else if (node.type === 'RenderTag') {
357370
for (const snippet of node.metadata.snippets) {
371+
if (seen.has(snippet)) continue;
372+
373+
seen.add(snippet);
358374
walk_children(snippet.body, context.state);
359375
}
360376
} else {
@@ -618,6 +634,8 @@ function get_following_sibling_elements(element, include_self) {
618634
// ...then walk them, starting from the node after the one
619635
// containing the element in question
620636

637+
const seen = new Set();
638+
621639
/** @param {Compiler.SvelteNode} node */
622640
function get_siblings(node) {
623641
walk(node, null, {
@@ -629,6 +647,9 @@ function get_following_sibling_elements(element, include_self) {
629647
},
630648
RenderTag(node) {
631649
for (const snippet of node.metadata.snippets) {
650+
if (seen.has(snippet)) continue;
651+
652+
seen.add(snippet);
632653
get_siblings(snippet.body);
633654
}
634655
}
@@ -804,9 +825,10 @@ function get_element_parent(node) {
804825
/**
805826
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.RenderTag | Compiler.AST.Component | Compiler.AST.SvelteComponent | Compiler.AST.SvelteSelf} node
806827
* @param {boolean} adjacent_only
828+
* @param {Set<Compiler.AST.SnippetBlock>} seen
807829
* @returns {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag, NodeExistsValue>}
808830
*/
809-
function get_possible_element_siblings(node, adjacent_only) {
831+
function get_possible_element_siblings(node, adjacent_only, seen = new Set()) {
810832
/** @type {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag, NodeExistsValue>} */
811833
const result = new Map();
812834
const path = node.metadata.path;
@@ -865,8 +887,11 @@ function get_possible_element_siblings(node, adjacent_only) {
865887
}
866888

867889
if (current.type === 'SnippetBlock') {
890+
if (seen.has(current)) break;
891+
seen.add(current);
892+
868893
for (const site of current.metadata.sites) {
869-
const siblings = get_possible_element_siblings(site, adjacent_only);
894+
const siblings = get_possible_element_siblings(site, adjacent_only, seen);
870895
add_to_map(siblings, result);
871896

872897
if (adjacent_only && current.metadata.sites.size === 1 && has_definite_elements(siblings)) {

packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
99
* @param {Context} context
1010
*/
1111
export function ExpressionTag(node, context) {
12-
const in_attribute = context.path.at(-1)?.type === 'Attribute';
12+
const in_template = context.path.at(-1)?.type === 'Fragment';
1313

14-
if (!in_attribute && context.state.parent_element) {
14+
if (in_template && context.state.parent_element) {
1515
if (!is_tag_valid_with_parent('#text', context.state.parent_element)) {
1616
e.node_invalid_placement(node, '`{expression}`', context.state.parent_element);
1717
}

packages/svelte/src/compiler/phases/2-analyze/visitors/Text.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import * as e from '../../../errors.js';
99
* @param {Context} context
1010
*/
1111
export function Text(node, context) {
12-
const in_attribute = context.path.at(-1)?.type === 'Attribute';
12+
const in_template = context.path.at(-1)?.type === 'Fragment';
1313

14-
if (!in_attribute && context.state.parent_element && regex_not_whitespace.test(node.data)) {
14+
if (in_template && context.state.parent_element && regex_not_whitespace.test(node.data)) {
1515
if (!is_tag_valid_with_parent('#text', context.state.parent_element)) {
1616
e.node_invalid_placement(node, 'Text node', context.state.parent_element);
1717
}

packages/svelte/src/compiler/phases/2-analyze/visitors/shared/component.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function visit_component(node, context) {
5151
if (binding?.initial?.type === 'SnippetBlock') {
5252
node.metadata.snippets.add(binding.initial);
5353
}
54-
} else {
54+
} else if (expression.type !== 'Literal') {
5555
resolved = false;
5656
}
5757
}

0 commit comments

Comments
 (0)