Skip to content

Commit c664b96

Browse files
committed
merge main
2 parents be49f3a + 6ff1d0a commit c664b96

File tree

27 files changed

+255
-189
lines changed

27 files changed

+255
-189
lines changed

.changeset/fuzzy-lies-battle.md

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

.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.

.changeset/short-chicken-compare.md

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

.changeset/wicked-buses-work.md

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

packages/svelte/CHANGELOG.md

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

3+
## 5.2.9
4+
5+
### Patch Changes
6+
7+
- fix: show `:then` block for `null/undefined` value ([#14440](https://github.com/sveltejs/svelte/pull/14440))
8+
9+
- fix: relax html parent validation ([#14442](https://github.com/sveltejs/svelte/pull/14442))
10+
11+
- fix: prevent memory leak when creating deriveds inside untrack ([#14443](https://github.com/sveltejs/svelte/pull/14443))
12+
13+
- fix: disregard TypeScript nodes when pruning CSS ([#14446](https://github.com/sveltejs/svelte/pull/14446))
14+
15+
## 5.2.8
16+
17+
### Patch Changes
18+
19+
- fix: correctly prune each blocks ([#14403](https://github.com/sveltejs/svelte/pull/14403))
20+
21+
- fix: provide temporary `LegacyComponentType` ([#14257](https://github.com/sveltejs/svelte/pull/14257))
22+
23+
- fix: attach spread attribute events synchronously ([#14387](https://github.com/sveltejs/svelte/pull/14387))
24+
25+
- fix: ensure last empty text node correctly hydrates ([#14425](https://github.com/sveltejs/svelte/pull/14425))
26+
27+
- fix: correctly prune key blocks ([#14403](https://github.com/sveltejs/svelte/pull/14403))
28+
329
## 5.2.7
430

531
### 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.9",
66
"type": "module",
77
"types": "./types/index.d.ts",
88
"engines": {

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

Lines changed: 52 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { get_attribute_chunks, is_text_attribute } from '../../../utils/ast.js';
77

88
/**
99
* @typedef {{
10-
* stylesheet: Compiler.Css.StyleSheet;
1110
* element: Compiler.AST.RegularElement | Compiler.AST.SvelteElement;
1211
* from_render_tag: boolean;
1312
* }} State
@@ -61,9 +60,9 @@ export function prune(stylesheet, element) {
6160
const parent = get_element_parent(element);
6261
if (!parent) return;
6362

64-
walk(stylesheet, { stylesheet, element: parent, from_render_tag: true }, visitors);
63+
walk(stylesheet, { element: parent, from_render_tag: true }, visitors);
6564
} else {
66-
walk(stylesheet, { stylesheet, element, from_render_tag: false }, visitors);
65+
walk(stylesheet, { element, from_render_tag: false }, visitors);
6766
}
6867
}
6968

@@ -882,125 +881,71 @@ function get_element_parent(node) {
882881
}
883882

884883
/**
885-
* Finds the given node's previous sibling in the DOM
886-
*
887-
* The Svelte `<slot>` is just a placeholder and is not actually real. Any children nodes
888-
* in `<slot>` are 'flattened' and considered as the same level as the `<slot>`'s siblings
889-
*
890-
* e.g.
891-
* ```html
892-
* <h1>Heading 1</h1>
893-
* <slot>
894-
* <h2>Heading 2</h2>
895-
* </slot>
896-
* ```
897-
*
898-
* is considered to look like:
899-
* ```html
900-
* <h1>Heading 1</h1>
901-
* <h2>Heading 2</h2>
902-
* ```
903-
* @param {Compiler.SvelteNode} node
904-
* @returns {Compiler.SvelteNode}
905-
*/
906-
function find_previous_sibling(node) {
907-
/** @type {Compiler.SvelteNode} */
908-
let current_node = node;
909-
910-
while (
911-
// @ts-expect-error TODO
912-
!current_node.prev &&
913-
// @ts-expect-error TODO
914-
current_node.parent?.type === 'SlotElement'
915-
) {
916-
// @ts-expect-error TODO
917-
current_node = current_node.parent;
918-
}
919-
920-
// @ts-expect-error
921-
current_node = current_node.prev;
922-
923-
while (current_node?.type === 'SlotElement') {
924-
const slot_children = current_node.fragment.nodes;
925-
if (slot_children.length > 0) {
926-
current_node = slot_children[slot_children.length - 1];
927-
} else {
928-
break;
929-
}
930-
}
931-
932-
return current_node;
933-
}
934-
935-
/**
936-
* @param {Compiler.SvelteNode} node
884+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement} element
937885
* @param {boolean} adjacent_only
938886
* @returns {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag, NodeExistsValue>}
939887
*/
940-
function get_possible_element_siblings(node, adjacent_only) {
888+
function get_possible_element_siblings(element, adjacent_only) {
941889
/** @type {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag, NodeExistsValue>} */
942890
const result = new Map();
891+
const path = element.metadata.path;
943892

944893
/** @type {Compiler.SvelteNode} */
945-
let prev = node;
946-
while ((prev = find_previous_sibling(prev))) {
947-
if (prev.type === 'RegularElement') {
948-
if (
949-
!prev.attributes.find(
894+
let current = element;
895+
896+
let i = path.length;
897+
898+
while (i--) {
899+
const fragment = /** @type {Compiler.AST.Fragment} */ (path[i--]);
900+
let j = fragment.nodes.indexOf(current);
901+
902+
while (j--) {
903+
const node = fragment.nodes[j];
904+
905+
if (node.type === 'RegularElement') {
906+
const has_slot_attribute = node.attributes.some(
950907
(attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === 'slot'
951-
)
952-
) {
953-
result.set(prev, NODE_DEFINITELY_EXISTS);
954-
}
955-
if (adjacent_only) {
956-
break;
957-
}
958-
} else if (is_block(prev)) {
959-
const possible_last_child = get_possible_last_child(prev, adjacent_only);
960-
add_to_map(possible_last_child, result);
961-
if (adjacent_only && has_definite_elements(possible_last_child)) {
962-
return result;
963-
}
964-
} else if (
965-
prev.type === 'SlotElement' ||
966-
prev.type === 'RenderTag' ||
967-
prev.type === 'SvelteElement'
968-
) {
969-
result.set(prev, NODE_PROBABLY_EXISTS);
970-
// Special case: slots, render tags and svelte:element tags could resolve to no siblings,
971-
// so we want to continue until we find a definite sibling even with the adjacent-only combinator
972-
}
973-
}
908+
);
974909

975-
if (!prev || !adjacent_only) {
976-
/** @type {Compiler.SvelteNode | null} */
977-
let parent = node;
910+
if (!has_slot_attribute) {
911+
result.set(node, NODE_DEFINITELY_EXISTS);
978912

979-
while (
980-
// @ts-expect-error TODO
981-
(parent = parent?.parent) &&
982-
is_block(parent)
983-
) {
984-
const possible_siblings = get_possible_element_siblings(parent, adjacent_only);
985-
add_to_map(possible_siblings, result);
913+
if (adjacent_only) {
914+
return result;
915+
}
916+
}
917+
} else if (is_block(node)) {
918+
if (node.type === 'SlotElement') {
919+
result.set(node, NODE_PROBABLY_EXISTS);
920+
}
986921

987-
// @ts-expect-error
988-
if (parent.type === 'EachBlock' && !parent.fallback?.nodes.includes(node)) {
989-
// `{#each ...}<a /><b />{/each}` — `<b>` can be previous sibling of `<a />`
990-
add_to_map(get_possible_last_child(parent, adjacent_only), result);
922+
const possible_last_child = get_possible_last_child(node, adjacent_only);
923+
add_to_map(possible_last_child, result);
924+
if (adjacent_only && has_definite_elements(possible_last_child)) {
925+
return result;
926+
}
927+
} else if (node.type === 'RenderTag' || node.type === 'SvelteElement') {
928+
result.set(node, NODE_PROBABLY_EXISTS);
929+
// Special case: slots, render tags and svelte:element tags could resolve to no siblings,
930+
// so we want to continue until we find a definite sibling even with the adjacent-only combinator
991931
}
932+
}
992933

993-
if (adjacent_only && has_definite_elements(possible_siblings)) {
994-
break;
995-
}
934+
current = path[i];
935+
936+
if (!current || !is_block(current)) break;
937+
938+
if (current.type === 'EachBlock' && fragment === current.body) {
939+
// `{#each ...}<a /><b />{/each}` — `<b>` can be previous sibling of `<a />`
940+
add_to_map(get_possible_last_child(current, adjacent_only), result);
996941
}
997942
}
998943

999944
return result;
1000945
}
1001946

1002947
/**
1003-
* @param {Compiler.AST.EachBlock | Compiler.AST.IfBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock} node
948+
* @param {Compiler.AST.EachBlock | Compiler.AST.IfBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock | Compiler.AST.SlotElement} node
1004949
* @param {boolean} adjacent_only
1005950
* @returns {Map<Compiler.AST.RegularElement, NodeExistsValue>}
1006951
*/
@@ -1024,14 +969,15 @@ function get_possible_last_child(node, adjacent_only) {
1024969
break;
1025970

1026971
case 'KeyBlock':
972+
case 'SlotElement':
1027973
fragments.push(node.fragment);
1028974
break;
1029975
}
1030976

1031977
/** @type {NodeMap} */
1032978
const result = new Map();
1033979

1034-
let exhaustive = true;
980+
let exhaustive = node.type !== 'SlotElement';
1035981

1036982
for (const fragment of fragments) {
1037983
if (fragment == null) {
@@ -1123,13 +1069,14 @@ function loop_child(children, adjacent_only) {
11231069

11241070
/**
11251071
* @param {Compiler.SvelteNode} node
1126-
* @returns {node is Compiler.AST.IfBlock | Compiler.AST.EachBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock}
1072+
* @returns {node is Compiler.AST.IfBlock | Compiler.AST.EachBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock | Compiler.AST.SlotElement}
11271073
*/
11281074
function is_block(node) {
11291075
return (
11301076
node.type === 'IfBlock' ||
11311077
node.type === 'EachBlock' ||
11321078
node.type === 'AwaitBlock' ||
1133-
node.type === 'KeyBlock'
1079+
node.type === 'KeyBlock' ||
1080+
node.type === 'SlotElement'
11341081
);
11351082
}

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ export function analyze_component(root, source, options) {
287287

288288
const store_name = name.slice(1);
289289
const declaration = instance.scope.get(store_name);
290+
const init = /** @type {Node | undefined} */ (declaration?.initial);
290291

291292
// If we're not in legacy mode through the compiler option, assume the user
292293
// is referencing a rune and not a global store.
@@ -295,9 +296,9 @@ export function analyze_component(root, source, options) {
295296
!is_rune(name) ||
296297
(declaration !== null &&
297298
// const state = $state(0) is valid
298-
(get_rune(declaration.initial, instance.scope) === null ||
299+
(get_rune(init, instance.scope) === null ||
299300
// rune-line names received as props are valid too (but we have to protect against $props as store)
300-
(store_name !== 'props' && get_rune(declaration.initial, instance.scope) === '$props')) &&
301+
(store_name !== 'props' && get_rune(init, instance.scope) === '$props')) &&
301302
// allow `import { derived } from 'svelte/store'` in the same file as `const x = $derived(..)` because one is not a subscription to the other
302303
!(
303304
name === '$derived' &&

packages/svelte/src/compiler/phases/3-transform/client/utils.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ export function should_proxy(node, scope) {
259259
binding.initial.type !== 'FunctionDeclaration' &&
260260
binding.initial.type !== 'ClassDeclaration' &&
261261
binding.initial.type !== 'ImportDeclaration' &&
262-
binding.initial.type !== 'EachBlock'
262+
binding.initial.type !== 'EachBlock' &&
263+
binding.initial.type !== 'SnippetBlock'
263264
) {
264265
return should_proxy(binding.initial, null);
265266
}

0 commit comments

Comments
 (0)