Skip to content

Commit 1e633fe

Browse files
Merge branch 'main' of github.com:sveltejs/svelte
2 parents f4e98bf + 0e0f01e commit 1e633fe

File tree

45 files changed

+484
-260
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+484
-260
lines changed

.changeset/strong-shoes-whisper.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: disallow $state/$derived in const tags

.github/workflows/docs-preview-create-request.yml

-26
This file was deleted.

.github/workflows/docs-preview-delete-request.yml

-27
This file was deleted.

.github/workflows/sync-request.yml

-22
This file was deleted.

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ We use [GitHub issues](https://github.com/sveltejs/svelte/issues) for our public
5151

5252
If you have questions about using Svelte, contact us on Discord at [svelte.dev/chat](https://svelte.dev/chat), and we will do our best to answer your questions.
5353

54-
If you see anything you'd like to be implemented, create a [feature request issue](https://github.com/sveltejs/svelte/issues/new?template=feature_request.yml)
54+
If you see anything you'd like to be implemented, create a [feature request issue](https://github.com/sveltejs/svelte/issues/new?template=feature_request.yml).
5555

5656
### Reporting new issues
5757

packages/svelte/CHANGELOG.md

+24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
# svelte
22

3+
## 5.19.3
4+
5+
### Patch Changes
6+
7+
- fix: don't throw for `undefined` non delegated event handlers ([#15087](https://github.com/sveltejs/svelte/pull/15087))
8+
9+
- fix: consistently set value to blank string when value attribute is undefined ([#15057](https://github.com/sveltejs/svelte/pull/15057))
10+
11+
- fix: optimise || expressions in template ([#15092](https://github.com/sveltejs/svelte/pull/15092))
12+
13+
- fix: correctly handle `novalidate` attribute casing ([#15083](https://github.com/sveltejs/svelte/pull/15083))
14+
15+
- fix: expand boolean attribute support ([#15095](https://github.com/sveltejs/svelte/pull/15095))
16+
17+
- fix: avoid double deriveds in component props ([#15089](https://github.com/sveltejs/svelte/pull/15089))
18+
19+
- fix: add check for `is` attribute to correctly detect custom elements ([#15086](https://github.com/sveltejs/svelte/pull/15086))
20+
21+
## 5.19.2
22+
23+
### Patch Changes
24+
25+
- fix: address regression with untrack ([#15079](https://github.com/sveltejs/svelte/pull/15079))
26+
327
## 5.19.1
428

529
### Patch Changes

packages/svelte/package.json

+1-1
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.19.1",
5+
"version": "5.19.3",
66
"type": "module",
77
"types": "./types/index.d.ts",
88
"engines": {

packages/svelte/src/compiler/phases/1-parse/state/tag.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ function special(parser) {
706706
expression: /** @type {AST.RenderTag['expression']} */ (expression),
707707
metadata: {
708708
dynamic: false,
709-
args_with_call_expression: new Set(),
709+
arguments: [],
710710
path: [],
711711
snippets: new Set()
712712
}

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

+10-11
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,15 @@ export function analyze_module(ast, options) {
243243
}
244244
}
245245

246-
const analysis = { runes: true, tracing: false };
246+
/** @type {Analysis} */
247+
const analysis = {
248+
module: { ast, scope, scopes },
249+
name: options.filename,
250+
accessors: false,
251+
runes: true,
252+
immutable: true,
253+
tracing: false
254+
};
247255

248256
walk(
249257
/** @type {Node} */ (ast),
@@ -256,14 +264,7 @@ export function analyze_module(ast, options) {
256264
visitors
257265
);
258266

259-
return {
260-
module: { ast, scope, scopes },
261-
name: options.filename,
262-
accessors: false,
263-
runes: true,
264-
immutable: true,
265-
tracing: analysis.tracing
266-
};
267+
return analysis;
267268
}
268269

269270
/**
@@ -604,7 +605,6 @@ export function analyze_component(root, source, options) {
604605
has_props_rune: false,
605606
component_slots: new Set(),
606607
expression: null,
607-
render_tag: null,
608608
private_derived_state: [],
609609
function_depth: scope.function_depth,
610610
instance_scope: instance.scope,
@@ -676,7 +676,6 @@ export function analyze_component(root, source, options) {
676676
reactive_statements: analysis.reactive_statements,
677677
component_slots: new Set(),
678678
expression: null,
679-
render_tag: null,
680679
private_derived_state: [],
681680
function_depth: scope.function_depth
682681
};

packages/svelte/src/compiler/phases/2-analyze/types.d.ts

-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ export interface AnalysisState {
1919
component_slots: Set<string>;
2020
/** Information about the current expression/directive/block value */
2121
expression: ExpressionMetadata | null;
22-
/** The current {@render ...} tag, if any */
23-
render_tag: null | AST.RenderTag;
2422
private_derived_state: string[];
2523
function_depth: number;
2624

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

+2-13
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ export function CallExpression(node, context) {
7979
case '$derived':
8080
case '$derived.by':
8181
if (
82-
parent.type !== 'VariableDeclarator' &&
82+
(parent.type !== 'VariableDeclarator' ||
83+
get_parent(context.path, -3).type === 'ConstTag') &&
8384
!(parent.type === 'PropertyDefinition' && !parent.static && !parent.computed)
8485
) {
8586
e.state_invalid_placement(node, rune);
@@ -186,18 +187,6 @@ export function CallExpression(node, context) {
186187
break;
187188
}
188189

189-
if (context.state.render_tag) {
190-
// Find out which of the render tag arguments contains this call expression
191-
const arg_idx = unwrap_optional(context.state.render_tag.expression).arguments.findIndex(
192-
(arg) => arg === node || context.path.includes(arg)
193-
);
194-
195-
// -1 if this is the call expression of the render tag itself
196-
if (arg_idx !== -1) {
197-
context.state.render_tag.metadata.args_with_call_expression.add(arg_idx);
198-
}
199-
}
200-
201190
if (node.callee.type === 'Identifier') {
202191
const binding = context.state.scope.get(node.callee.name);
203192

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

+14-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as e from '../../../errors.js';
55
import { validate_opening_tag } from './shared/utils.js';
66
import { mark_subtree_dynamic } from './shared/fragment.js';
77
import { is_resolved_snippet } from './shared/snippets.js';
8+
import { create_expression_metadata } from '../../nodes.js';
89

910
/**
1011
* @param {AST.RenderTag} node
@@ -15,7 +16,8 @@ export function RenderTag(node, context) {
1516

1617
node.metadata.path = [...context.path];
1718

18-
const callee = unwrap_optional(node.expression).callee;
19+
const expression = unwrap_optional(node.expression);
20+
const callee = expression.callee;
1921

2022
const binding = callee.type === 'Identifier' ? context.state.scope.get(callee.name) : null;
2123

@@ -52,5 +54,15 @@ export function RenderTag(node, context) {
5254

5355
mark_subtree_dynamic(context.path);
5456

55-
context.next({ ...context.state, render_tag: node });
57+
context.visit(callee);
58+
59+
for (const arg of expression.arguments) {
60+
const metadata = create_expression_metadata();
61+
node.metadata.arguments.push(metadata);
62+
63+
context.visit(arg, {
64+
...context.state,
65+
expression: metadata
66+
});
67+
}
5668
}

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

-35
Original file line numberDiff line numberDiff line change
@@ -269,41 +269,6 @@ export function should_proxy(node, scope) {
269269
return true;
270270
}
271271

272-
/**
273-
* @param {Pattern} node
274-
* @param {import('zimmerframe').Context<AST.SvelteNode, ComponentClientTransformState>} context
275-
* @returns {{ id: Pattern, declarations: null | Statement[] }}
276-
*/
277-
export function create_derived_block_argument(node, context) {
278-
if (node.type === 'Identifier') {
279-
context.state.transform[node.name] = { read: get_value };
280-
return { id: node, declarations: null };
281-
}
282-
283-
const pattern = /** @type {Pattern} */ (context.visit(node));
284-
const identifiers = extract_identifiers(node);
285-
286-
const id = b.id('$$source');
287-
const value = b.id('$$value');
288-
289-
const block = b.block([
290-
b.var(pattern, b.call('$.get', id)),
291-
b.return(b.object(identifiers.map((identifier) => b.prop('init', identifier, identifier))))
292-
]);
293-
294-
const declarations = [b.var(value, create_derived(context.state, b.thunk(block)))];
295-
296-
for (const id of identifiers) {
297-
context.state.transform[id.name] = { read: get_value };
298-
299-
declarations.push(
300-
b.var(id, create_derived(context.state, b.thunk(b.member(b.call('$.get', value), id))))
301-
);
302-
}
303-
304-
return { id, declarations };
305-
}
306-
307272
/**
308273
* Svelte legacy mode should use safe equals in most places, runes mode shouldn't
309274
* @param {ComponentClientTransformState} state

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

+39-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
/** @import { BlockStatement, Expression, Pattern, Statement } from 'estree' */
22
/** @import { AST } from '#compiler' */
3-
/** @import { ComponentContext } from '../types' */
3+
/** @import { ComponentClientTransformState, ComponentContext } from '../types' */
4+
import { extract_identifiers } from '../../../../utils/ast.js';
45
import * as b from '../../../../utils/builders.js';
5-
import { create_derived_block_argument } from '../utils.js';
6+
import { create_derived } from '../utils.js';
7+
import { get_value } from './shared/declarations.js';
68

79
/**
810
* @param {AST.AwaitBlock} node
@@ -65,3 +67,38 @@ export function AwaitBlock(node, context) {
6567
)
6668
);
6769
}
70+
71+
/**
72+
* @param {Pattern} node
73+
* @param {import('zimmerframe').Context<AST.SvelteNode, ComponentClientTransformState>} context
74+
* @returns {{ id: Pattern, declarations: null | Statement[] }}
75+
*/
76+
function create_derived_block_argument(node, context) {
77+
if (node.type === 'Identifier') {
78+
context.state.transform[node.name] = { read: get_value };
79+
return { id: node, declarations: null };
80+
}
81+
82+
const pattern = /** @type {Pattern} */ (context.visit(node));
83+
const identifiers = extract_identifiers(node);
84+
85+
const id = b.id('$$source');
86+
const value = b.id('$$value');
87+
88+
const block = b.block([
89+
b.var(pattern, b.call('$.get', id)),
90+
b.return(b.object(identifiers.map((identifier) => b.prop('init', identifier, identifier))))
91+
]);
92+
93+
const declarations = [b.var(value, create_derived(context.state, b.thunk(block)))];
94+
95+
for (const id of identifiers) {
96+
context.state.transform[id.name] = { read: get_value };
97+
98+
declarations.push(
99+
b.var(id, create_derived(context.state, b.thunk(b.member(b.call('$.get', value), id))))
100+
);
101+
}
102+
103+
return { id, declarations };
104+
}

0 commit comments

Comments
 (0)