Skip to content

Commit 15c6306

Browse files
committed
Merge remote-tracking branch 'origin/main' into templateless-template-generation
2 parents 97817a9 + bfb969a commit 15c6306

File tree

40 files changed

+481
-142
lines changed

40 files changed

+481
-142
lines changed

documentation/docs/98-reference/.generated/compile-errors.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@ A `:global` selector cannot modify an existing selector
274274
A `:global` selector can only be modified if it is a descendant of other selectors
275275
```
276276

277+
### css_global_block_invalid_placement
278+
279+
```
280+
A `:global` selector cannot be inside a pseudoclass
281+
```
282+
277283
### css_global_invalid_placement
278284

279285
```

packages/svelte/CHANGELOG.md

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

3+
## 5.28.1
4+
5+
### Patch Changes
6+
7+
- fix: ensure `<svelte:boundary>` properly removes error content in production mode ([#15793](https://github.com/sveltejs/svelte/pull/15793))
8+
9+
- fix: `update_version` after `delete` if `source` is `undefined` and `prop` in `target` ([#15796](https://github.com/sveltejs/svelte/pull/15796))
10+
11+
- fix: emit error on wrong placement of the `:global` block selector ([#15794](https://github.com/sveltejs/svelte/pull/15794))
12+
13+
## 5.28.0
14+
15+
### Minor Changes
16+
17+
- feat: partially evaluate more expressions ([#15781](https://github.com/sveltejs/svelte/pull/15781))
18+
19+
## 5.27.3
20+
21+
### Patch Changes
22+
23+
- fix: use function declaration for snippets in server output to avoid TDZ violation ([#15789](https://github.com/sveltejs/svelte/pull/15789))
24+
325
## 5.27.2
426

527
### Patch Changes

packages/svelte/messages/compile-errors/style.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ x y {
5050

5151
> A `:global` selector can only be modified if it is a descendant of other selectors
5252
53+
## css_global_block_invalid_placement
54+
55+
> A `:global` selector cannot be inside a pseudoclass
56+
5357
## css_global_invalid_placement
5458

5559
> `:global(...)` can be at the start or end of a selector sequence, but not in the middle

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

packages/svelte/src/compiler/errors.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,15 @@ export function css_global_block_invalid_modifier_start(node) {
581581
e(node, 'css_global_block_invalid_modifier_start', `A \`:global\` selector can only be modified if it is a descendant of other selectors\nhttps://svelte.dev/e/css_global_block_invalid_modifier_start`);
582582
}
583583

584+
/**
585+
* A `:global` selector cannot be inside a pseudoclass
586+
* @param {null | number | NodeLike} node
587+
* @returns {never}
588+
*/
589+
export function css_global_block_invalid_placement(node) {
590+
e(node, 'css_global_block_invalid_placement', `A \`:global\` selector cannot be inside a pseudoclass\nhttps://svelte.dev/e/css_global_block_invalid_placement`);
591+
}
592+
584593
/**
585594
* `:global(...)` can be at the start or end of a selector sequence, but not in the middle
586595
* @param {null | number | NodeLike} node

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,12 @@ const css_visitors = {
6868
const global = node.children.find(is_global);
6969

7070
if (global) {
71-
const idx = node.children.indexOf(global);
71+
const is_nested = context.path.at(-2)?.type === 'PseudoClassSelector';
72+
if (is_nested && !global.selectors[0].args) {
73+
e.css_global_block_invalid_placement(global.selectors[0]);
74+
}
7275

76+
const idx = node.children.indexOf(global);
7377
if (global.selectors[0].args !== null && idx !== 0 && idx !== node.children.length - 1) {
7478
// ensure `:global(...)` is not used in the middle of a selector (but multiple `global(...)` in sequence are ok)
7579
for (let i = idx + 1; i < node.children.length; i++) {

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,17 @@ export function build_template_chunk(
6969
node.metadata.expression
7070
);
7171

72-
has_state ||= node.metadata.expression.has_state;
72+
const evaluated = state.scope.evaluate(value);
73+
74+
has_state ||= node.metadata.expression.has_state && !evaluated.is_known;
7375

7476
if (values.length === 1) {
7577
// If we have a single expression, then pass that in directly to possibly avoid doing
7678
// extra work in the template_effect (instead we do the work in set_text).
79+
if (evaluated.is_known) {
80+
value = b.literal(evaluated.value);
81+
}
82+
7783
return { value, has_state };
7884
}
7985

@@ -89,8 +95,6 @@ export function build_template_chunk(
8995
}
9096
}
9197

92-
const evaluated = state.scope.evaluate(value);
93-
9498
if (evaluated.is_known) {
9599
quasi.value.cooked += evaluated.value + '';
96100
} else {
Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { ArrowFunctionExpression, BlockStatement, CallExpression } from 'estree' */
1+
/** @import { BlockStatement } from 'estree' */
22
/** @import { AST } from '#compiler' */
33
/** @import { ComponentContext } from '../types.js' */
44
import { dev } from '../../../../state.js';
@@ -9,27 +9,21 @@ import * as b from '#compiler/builders';
99
* @param {ComponentContext} context
1010
*/
1111
export function SnippetBlock(node, context) {
12-
const body = /** @type {BlockStatement} */ (context.visit(node.body));
12+
let fn = b.function_declaration(
13+
node.expression,
14+
[b.id('$$payload'), ...node.parameters],
15+
/** @type {BlockStatement} */ (context.visit(node.body))
16+
);
1317

14-
if (dev) {
15-
body.body.unshift(b.stmt(b.call('$.validate_snippet_args', b.id('$$payload'))));
16-
}
18+
// @ts-expect-error - TODO remove this hack once $$render_inner for legacy bindings is gone
19+
fn.___snippet = true;
1720

18-
/** @type {ArrowFunctionExpression | CallExpression} */
19-
let fn = b.arrow([b.id('$$payload'), ...node.parameters], body);
21+
const statements = node.metadata.can_hoist ? context.state.hoisted : context.state.init;
2022

2123
if (dev) {
22-
fn = b.call('$.prevent_snippet_stringification', fn);
24+
fn.body.body.unshift(b.stmt(b.call('$.validate_snippet_args', b.id('$$payload'))));
25+
statements.push(b.stmt(b.call('$.prevent_snippet_stringification', fn.id)));
2326
}
2427

25-
const declaration = b.declaration('const', [b.declarator(node.expression, fn)]);
26-
27-
// @ts-expect-error - TODO remove this hack once $$render_inner for legacy bindings is gone
28-
fn.___snippet = true;
29-
30-
if (node.metadata.can_hoist) {
31-
context.state.hoisted.push(declaration);
32-
} else {
33-
context.state.init.push(declaration);
34-
}
28+
statements.push(fn);
3529
}

0 commit comments

Comments
 (0)