Skip to content

Commit 1f9c9cc

Browse files
committed
Merge branch 'main' into default-values
2 parents 228a5ac + 2b5c0e7 commit 1f9c9cc

File tree

20 files changed

+184
-142
lines changed

20 files changed

+184
-142
lines changed

.changeset/lovely-mayflies-sing.md

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

.changeset/rich-worms-burn.md

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

packages/svelte/CHANGELOG.md

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

3+
## 5.2.8
4+
5+
### Patch Changes
6+
7+
- fix: correctly prune each blocks ([#14403](https://github.com/sveltejs/svelte/pull/14403))
8+
9+
- fix: provide temporary `LegacyComponentType` ([#14257](https://github.com/sveltejs/svelte/pull/14257))
10+
11+
- fix: attach spread attribute events synchronously ([#14387](https://github.com/sveltejs/svelte/pull/14387))
12+
13+
- fix: ensure last empty text node correctly hydrates ([#14425](https://github.com/sveltejs/svelte/pull/14425))
14+
15+
- fix: correctly prune key blocks ([#14403](https://github.com/sveltejs/svelte/pull/14403))
16+
317
## 5.2.7
418

519
### Patch Changes

packages/svelte/package.json

Lines changed: 1 addition & 1 deletion
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.7",
5+
"version": "5.2.8",
66
"type": "module",
77
"types": "./types/index.d.ts",
88
"engines": {

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

Lines changed: 57 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ function get_possible_element_siblings(node, adjacent_only) {
955955
if (adjacent_only) {
956956
break;
957957
}
958-
} else if (prev.type === 'EachBlock' || prev.type === 'IfBlock' || prev.type === 'AwaitBlock') {
958+
} else if (is_block(prev)) {
959959
const possible_last_child = get_possible_last_child(prev, adjacent_only);
960960
add_to_map(possible_last_child, result);
961961
if (adjacent_only && has_definite_elements(possible_last_child)) {
@@ -979,7 +979,7 @@ function get_possible_element_siblings(node, adjacent_only) {
979979
while (
980980
// @ts-expect-error TODO
981981
(parent = parent?.parent) &&
982-
(parent.type === 'EachBlock' || parent.type === 'IfBlock' || parent.type === 'AwaitBlock')
982+
is_block(parent)
983983
) {
984984
const possible_siblings = get_possible_element_siblings(parent, adjacent_only);
985985
add_to_map(possible_siblings, result);
@@ -1000,73 +1000,57 @@ function get_possible_element_siblings(node, adjacent_only) {
10001000
}
10011001

10021002
/**
1003-
* @param {Compiler.AST.EachBlock | Compiler.AST.IfBlock | Compiler.AST.AwaitBlock} relative_selector
1003+
* @param {Compiler.AST.EachBlock | Compiler.AST.IfBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock} node
10041004
* @param {boolean} adjacent_only
10051005
* @returns {Map<Compiler.AST.RegularElement, NodeExistsValue>}
10061006
*/
1007-
function get_possible_last_child(relative_selector, adjacent_only) {
1007+
function get_possible_last_child(node, adjacent_only) {
10081008
/** @typedef {Map<Compiler.AST.RegularElement, NodeExistsValue>} NodeMap */
10091009

1010+
/** @type {Array<Compiler.AST.Fragment | undefined | null>} */
1011+
let fragments = [];
1012+
1013+
switch (node.type) {
1014+
case 'EachBlock':
1015+
fragments.push(node.body, node.fallback);
1016+
break;
1017+
1018+
case 'IfBlock':
1019+
fragments.push(node.consequent, node.alternate);
1020+
break;
1021+
1022+
case 'AwaitBlock':
1023+
fragments.push(node.pending, node.then, node.catch);
1024+
break;
1025+
1026+
case 'KeyBlock':
1027+
fragments.push(node.fragment);
1028+
break;
1029+
}
1030+
10101031
/** @type {NodeMap} */
10111032
const result = new Map();
1012-
if (relative_selector.type === 'EachBlock') {
1013-
/** @type {NodeMap} */
1014-
const each_result = loop_child(relative_selector.body.nodes, adjacent_only);
1015-
1016-
/** @type {NodeMap} */
1017-
const else_result = relative_selector.fallback
1018-
? loop_child(relative_selector.fallback.nodes, adjacent_only)
1019-
: new Map();
1020-
const not_exhaustive = !has_definite_elements(else_result);
1021-
if (not_exhaustive) {
1022-
mark_as_probably(each_result);
1023-
mark_as_probably(else_result);
1024-
}
1025-
add_to_map(each_result, result);
1026-
add_to_map(else_result, result);
1027-
} else if (relative_selector.type === 'IfBlock') {
1028-
/** @type {NodeMap} */
1029-
const if_result = loop_child(relative_selector.consequent.nodes, adjacent_only);
1030-
1031-
/** @type {NodeMap} */
1032-
const else_result = relative_selector.alternate
1033-
? loop_child(relative_selector.alternate.nodes, adjacent_only)
1034-
: new Map();
1035-
const not_exhaustive = !has_definite_elements(if_result) || !has_definite_elements(else_result);
1036-
if (not_exhaustive) {
1037-
mark_as_probably(if_result);
1038-
mark_as_probably(else_result);
1033+
1034+
let exhaustive = true;
1035+
1036+
for (const fragment of fragments) {
1037+
if (fragment == null) {
1038+
exhaustive = false;
1039+
continue;
10391040
}
1040-
add_to_map(if_result, result);
1041-
add_to_map(else_result, result);
1042-
} else if (relative_selector.type === 'AwaitBlock') {
1043-
/** @type {NodeMap} */
1044-
const pending_result = relative_selector.pending
1045-
? loop_child(relative_selector.pending.nodes, adjacent_only)
1046-
: new Map();
1047-
1048-
/** @type {NodeMap} */
1049-
const then_result = relative_selector.then
1050-
? loop_child(relative_selector.then.nodes, adjacent_only)
1051-
: new Map();
1052-
1053-
/** @type {NodeMap} */
1054-
const catch_result = relative_selector.catch
1055-
? loop_child(relative_selector.catch.nodes, adjacent_only)
1056-
: new Map();
1057-
const not_exhaustive =
1058-
!has_definite_elements(pending_result) ||
1059-
!has_definite_elements(then_result) ||
1060-
!has_definite_elements(catch_result);
1061-
if (not_exhaustive) {
1062-
mark_as_probably(pending_result);
1063-
mark_as_probably(then_result);
1064-
mark_as_probably(catch_result);
1041+
1042+
const map = loop_child(fragment.nodes, adjacent_only);
1043+
exhaustive &&= has_definite_elements(map);
1044+
1045+
add_to_map(map, result);
1046+
}
1047+
1048+
if (!exhaustive) {
1049+
for (const key of result.keys()) {
1050+
result.set(key, NODE_PROBABLY_EXISTS);
10651051
}
1066-
add_to_map(pending_result, result);
1067-
add_to_map(then_result, result);
1068-
add_to_map(catch_result, result);
10691052
}
1053+
10701054
return result;
10711055
}
10721056

@@ -1107,13 +1091,6 @@ function higher_existence(exist1, exist2) {
11071091
return exist1 > exist2 ? exist1 : exist2;
11081092
}
11091093

1110-
/** @param {Map<Compiler.AST.RegularElement, NodeExistsValue>} result */
1111-
function mark_as_probably(result) {
1112-
for (const key of result.keys()) {
1113-
result.set(key, NODE_PROBABLY_EXISTS);
1114-
}
1115-
}
1116-
11171094
/**
11181095
* @param {Compiler.SvelteNode[]} children
11191096
* @param {boolean} adjacent_only
@@ -1132,11 +1109,7 @@ function loop_child(children, adjacent_only) {
11321109
if (adjacent_only) {
11331110
break;
11341111
}
1135-
} else if (
1136-
child.type === 'EachBlock' ||
1137-
child.type === 'IfBlock' ||
1138-
child.type === 'AwaitBlock'
1139-
) {
1112+
} else if (is_block(child)) {
11401113
const child_result = get_possible_last_child(child, adjacent_only);
11411114
add_to_map(child_result, result);
11421115
if (adjacent_only && has_definite_elements(child_result)) {
@@ -1147,3 +1120,16 @@ function loop_child(children, adjacent_only) {
11471120

11481121
return result;
11491122
}
1123+
1124+
/**
1125+
* @param {Compiler.SvelteNode} node
1126+
* @returns {node is Compiler.AST.IfBlock | Compiler.AST.EachBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock}
1127+
*/
1128+
function is_block(node) {
1129+
return (
1130+
node.type === 'IfBlock' ||
1131+
node.type === 'EachBlock' ||
1132+
node.type === 'AwaitBlock' ||
1133+
node.type === 'KeyBlock'
1134+
);
1135+
}

packages/svelte/src/internal/client/dom/operations.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,22 +154,31 @@ export function first_child(fragment, is_text) {
154154
*/
155155
export function sibling(node, count = 1, is_text = false) {
156156
let next_sibling = hydrating ? hydrate_node : node;
157+
var last_sibling;
157158

158159
while (count--) {
160+
last_sibling = next_sibling;
159161
next_sibling = /** @type {TemplateNode} */ (get_next_sibling(next_sibling));
160162
}
161163

162164
if (!hydrating) {
163165
return next_sibling;
164166
}
165167

166-
var type = next_sibling.nodeType;
168+
var type = next_sibling?.nodeType;
167169

168170
// if a sibling {expression} is empty during SSR, there might be no
169171
// text node to hydrate — we must therefore create one
170172
if (is_text && type !== 3) {
171173
var text = create_text();
172-
next_sibling?.before(text);
174+
// If the next sibling is `null` and we're handling text then it's because
175+
// the SSR content was empty for the text, so we need to generate a new text
176+
// node and insert it after the last sibling
177+
if (next_sibling === null) {
178+
last_sibling?.after(text);
179+
} else {
180+
next_sibling.before(text);
181+
}
173182
set_hydrate_node(text);
174183
return text;
175184
}

packages/svelte/src/version.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
* https://svelte.dev/docs/svelte-compiler#svelte-version
77
* @type {string}
88
*/
9-
export const VERSION = '5.2.7';
9+
export const VERSION = '5.2.8';
1010
export const PUBLIC_VERSION = '5';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
warnings: []
5+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
.a.svelte-xyz ~ .b:where(.svelte-xyz) { color: green; }
3+
.a.svelte-xyz ~ .c:where(.svelte-xyz) { color: green; }
4+
.b.svelte-xyz ~ .c:where(.svelte-xyz) { color: green; }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<div class="a"></div>
2+
3+
{#key x}
4+
<div class="b"></div>
5+
{/key}
6+
7+
<div class="c"></div>
8+
9+
<style>
10+
.a ~ .b { color: green; }
11+
.a ~ .c { color: green; }
12+
.b ~ .c { color: green; }
13+
</style>

0 commit comments

Comments
 (0)