8000 Merge branch 'main' into lazy-derived-server · sveltejs/svelte@846d780 · GitHub
[go: up one dir, main page]

Skip to content

Commit 846d780

Browse files
committed
Merge branch 'main' into lazy-derived-server
2 parents 895e048 + 9250c9c commit 846d780

File tree

84 files changed

+1004
-313
lines changed

Some content is hidden

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

84 files changed

+1004
-313
lines changed

.changeset/wise-tigers-happen.md

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

documentation/docs/98-reference/.generated/client-warnings.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,19 @@ Consider the following code:
200200
201201
To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable).
202202
203+
### select_multiple_invalid_value
204+
205+
```
206+
The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is.
207+
```
208+
209+
When using `<select multiple value={...}>`, Svelte will mark all selected `<option>` elements as selected by iterating over the array passed to `value`. If `value` is not an array, Svelte will emit this warning and keep the selected options as they are.
210+
211+
To silence the warning, ensure that `value`:
212+
213+
- is an array for an explicit selection
214+
- is `null` or `undefined` to keep the selection as is
215+
203216
### state_proxy_equality_mismatch
204217
205218
```

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,25 @@ In some situations a selector may target an element that is not 'visible' to the
632632
</style>
633633
```
634634

635+
### element_implicitly_closed
636+
637+
```
638+
This element is implicitly closed by the following `%tag%`, which can cause an unexpected DOM structure. Add an explicit `%closing%` to avoid surprises.
639+
```
640+
641+
In HTML, some elements are implicitly closed by another element. For example, you cannot nest a `<p>` inside another `<p>`:
642+
643+
```html
644+
<!-- this HTML... -->
645+
<p><p>hello</p>
646+
647+
<!-- results in this DOM structure -->
648+
<p></p>
649+
<p>hello</p>
650+
```
651+
652+
Similarly, a parent element's closing tag will implicitly close all child elements, even if the `</` was a typo and you meant to create a _new_ element. To avoid ambiguity, it's always a good idea to have an explicit closing tag.
653+
635654
### element_invalid_self_closing_tag
636655

637656
```

packages/svelte/CHANGELOG.md

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

3+
## 5.33.0
4+
5+
### Minor Changes
6+
7+
- feat: XHTML compliance ([#15538](https://github.com/sveltejs/svelte/pull/15538))
8+
9+
- feat: add `fragments: 'html' | 'tree'` option for wider CSP compliance ([#15538](https://github.com/sveltejs/svelte/pull/15538))
10+
11+
## 5.32.2
12+
13+
### Patch Changes
14+
15+
- chore: simplify `<pre>` cleaning ([#15980](https://github.com/sveltejs/svelte/pull/15980))
16+
17+
- fix: attach `__svelte_meta` correctly to elements following a CSS wrapper ([#15982](https://github.com/sveltejs/svelte/pull/15982))
18+
19+
- fix: import untrack directly from client in `svelte/attachments` ([#15974](https://github.com/sveltejs/svelte/pull/15974))
20+
21+
## 5.32.1
22+
23+
### Patch Changes
24+
25+
- Warn when an invalid `<select multiple>` value is given ([#14816](https://github.com/sveltejs/svelte/pull/14816))
26+
27+
## 5.32.0
28+
29+
### Minor Changes
30+
31+
- feat: warn on implicitly closed tags ([#15932](https://github.com/sveltejs/svelte/pull/15932))
32+
33+
- feat: attachments `fromAction` utility ([#15933](https://github.com/sveltejs/svelte/pull/15933))
34+
35+
### Patch Changes
36+
37+
- fix: only re-run directly applied attachment if it changed ([#15962](https://github.com/sveltejs/svelte/pull/15962))
38+
339
## 5.31.1
440

541
### Patch Changes

packages/svelte/messages/client-warnings/warnings.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ Consider the following code:
168168
169169
To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable).
170170
171+
## select_multiple_invalid_value
172+
173+
> The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is.
174+
175+
When using `<select multiple value={...}>`, Svelte will mark all selected `<option>` elements as selected by iterating over the array passed to `value`. If `value` is not an array, Svelte will emit this warning and keep the selected options as they are.
176+
177+
To silence the warning, ensure that `value`:
178+
179+
- is an array for an explicit selection
180+
- is `null` or `undefined` to keep the selection as is
181+
171182
## state_proxy_equality_mismatch
172183
173184
> Reactive `$state(...)` proxies and the values they proxy have different identities. Because of this, comparisons with `%operator%` will produce unexpected results

packages/svelte/messages/compile-warnings/template.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@
3030

3131
> `<%name%>` will be treated as an HTML element unless it begins with a capital letter
3232
33+
## element_implicitly_closed
34+
35+
> This element is implicitly closed by the following `%tag%`, which can cause an unexpected DOM structure. Add an explicit `%closing%` to avoid surprises.
36+
37+
In HTML, some elements are implicitly closed by another element. For example, you cannot nest a `<p>` inside another `<p>`:
38+
39+
```html
40+
<!-- this HTML... -->
41+
<p><p>hello</p>
42+
43+
<!-- results in this DOM structure -->
44+
<p></p>
45+
<p>hello</p>
46+
```
47+
48+
Similarly, a parent element's closing tag will implicitly close all child elements, even if the `</` was a typo and you meant to create a _new_ element. To avoid ambiguity, it's always a good idea to have an explicit closing tag.
49+
3350
## element_invalid_self_closing_tag
3451

3552
> Self-closing HTML tags for non-void elements are ambiguous — use `<%name% ...></%name%>` rather than `<%name% ... />`

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

packages/svelte/src/attachments/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/** @import { Attachment } from './public' */
33
import { noop, render_effect } from 'svelte/internal/client';
44
import { ATTACHMENT_KEY } from '../constants.js';
5-
import { untrack } from 'svelte';
5+
import { untrack } from '../index-client.js';
66
import { teardown } from '../internal/client/reactivity/effects.js';
77

88
/**

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,16 @@ export default function element(parser) {
9393
}
9494
}
9595

96-
if (parent.type !== 'RegularElement' && !parser.loose) {
96+
if (parent.type === 'RegularElement') {
97+
if (!parser.last_auto_closed_tag || parser.last_auto_closed_tag.tag !== name) {
98+
const end = parent.fragment.nodes[0]?.start ?? start;
99+
w.element_implicitly_closed(
100+
{ start: parent.start, end },
101+
`</${name}>`,
102+
`</${parent.name}>`
103+
);
104+
}
105+
} else if (!parser.loose) {
97106
if (parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name) {
98107
e.element_invalid_closing_tag_autoclosed(start, name, parser.last_auto_closed_tag.reason);
99108
} else {
@@ -186,6 +195,8 @@ export default function element(parser) {
186195
parser.allow_whitespace();
187196

188197
if (parent.type === 'RegularElement' && closing_tag_omitted(parent.name, name)) {
198+
const end = parent.fragment.nodes[0]?.start ?? start;
199+
w.element_implicitly_closed({ start: parent.start, end }, `<${name}>`, `</${parent.name}>`);
189200
parent.end = start;
190201
parser.pop();
191202
parser.last_auto_closed_tag = {

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,6 @@ export function client_component(analysis, options) {
154154
legacy_reactive_imports: [],
155155
legacy_reactive_statements: new Map(),
156156
metadata: {
157-
context: {
158-
template_needs_import_node: false,
159-
template_contains_script_tag: false
160-
},
161157
namespace: options.namespace,
162158
bound_contenteditable: false
163159
},
@@ -174,8 +170,7 @@ export function client_component(analysis, options) {
174170
update: /** @type {any} */ (null),
175171
expressions: /** @type {any} */ (null),
176172
after_update: /** @type {any} */ (null),
177-
template: /** @type {any} */ (null),
178-
locations: /** @type {any} */ (null)
173+
template: /** @type {any} */ (null)
179174
};
180175

181176
const module = /** @type {ESTree.Program} */ (

packages/svelte/src/compiler/phases/3-transform/client/transform-template/fix-attribute-casing.js

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/** @import { Location } from 'locate-character' */
2+
/** @import { Namespace } from '#compiler' */
3+
/** @import { ComponentClientTransformState } from '../types.js' */
4+
/** @import { Node } from './types.js' */
5+
import { TEMPLATE_USE_MATHML, TEMPLATE_USE_SVG } from '../../../../../constants.js';
6+
import { dev, locator } from '../../../../state.js';
7+
import * as b from '../../../../utils/builders.js';
8+
9+
/**
10+
* @param {Node[]} nodes
11+
*/
12+
function build_locations(nodes) {
13+
const array = b.array([]);
14+
15+
for (const node of nodes) {
16+
if (node.type !== 'element') continue;
17+
18+
const { line, column } = /** @type {Location} */ (locator(node.start));
19+
20+
const expression = b.array([b.literal(line), b.literal(column)]);
21+
const children = build_locations(node.children);
22+
23+
if (children.elements.length > 0) {
24+
expression.elements.push(children);
25+
}
26+
27+
array.elements.push(expression);
28+
}
29+
30+
return array;
31+
}
32+
33+
/**
34+
* @param {ComponentClientTransformState} state
35+
* @param {Namespace} namespace
36+
* @param {number} [flags]
37+
*/
38+
export function transform_template(state, namespace, flags = 0) {
39+
const tree = state.options.fragments === 'tree';
40+
41+
const expression = tree ? state.template.as_tree() : state.template.as_html();
42+
43+
if (tree) {
44+
if (namespace === 'svg') flags |= TEMPLATE_USE_SVG;
45+
if (namespace === 'mathml') flags |= TEMPLATE_USE_MATHML;
46+
}
47+
48+
let call = b.call(
49+
tree ? `$.from_tree` : `$.from_${namespace}`,
50+
expression,
51+
flags ? b.literal(flags) : undefined
52+
);
53+
54+
if (state.template.contains_script_tag) {
55+
call = b.call(`$.with_script`, call);
56+
}
57+
58+
if (dev) {
59+
call = b.call(
60+
'$.add_locations',
61+
call,
62+
b.member(b.id(state.analysis.name), '$.FILENAME', true),
63+
build_locations(state.template.nodes)
64+
);
65+
}
66+
67+
return call;
68+
}

0 commit comments

Comments
 (0)
0