Skip to content

Commit 3156a24

Browse files
committed
merge main
2 parents 61a11a5 + c4b32c2 commit 3156a24

File tree

32 files changed

+202
-62
lines changed

32 files changed

+202
-62
lines changed

.changeset/clever-dodos-jam.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: untrack `$inspect.with` and add check for unsafe mutation

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ Cannot set prototype of `$state` object
131131
### state_unsafe_mutation
132132

133133
```
134-
Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
134+
Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
135135
```
136136

137137
This error occurs when state is updated while evaluating a `$derived`. You might encounter it while trying to 'derive' two pieces of state in one go:

packages/svelte/CHANGELOG.md

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

3+
## 5.34.7
4+
5+
### Patch Changes
6+
7+
- fix: address css class matching regression ([#16204](https://github.com/sveltejs/svelte/pull/16204))
8+
9+
## 5.34.6
10+
11+
### Patch Changes
12+
13+
- fix: match class and style directives against attribute selector ([#16179](https://github.com/sveltejs/svelte/pull/16179))
14+
315
## 5.34.5
416

517
### Patch Changes

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-long
8686
8787
## state_unsafe_mutation
8888

89-
> Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
89+
> Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
9090
9191
This error occurs when state is updated while evaluating a `$derived`. You might encounter it while trying to 'derive' two pieces of state in one go:
9292

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

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -628,24 +628,33 @@ function attribute_matches(node, name, expected_value, operator, case_insensitiv
628628
if (attribute.type === 'SpreadAttribute') return true;
629629
if (attribute.type === 'BindDirective' && attribute.name === name) return true;
630630

631+
const name_lower = name.toLowerCase();
631632
// match attributes against the corresponding directive but bail out on exact matching
632-
if (attribute.type === 'StyleDirective' && name.toLowerCase() === 'style') return true;
633-
if (attribute.type === 'ClassDirective' && name.toLowerCase() === 'class') {
634-
if (operator == '~=') {
633+
if (attribute.type === 'StyleDirective' && name_lower === 'style') return true;
634+
if (attribute.type === 'ClassDirective' && name_lower === 'class') {
635+
if (operator === '~=') {
635636
if (attribute.name === expected_value) return true;
636637
} else {
637638
return true;
638639
}
639640
}
640641

641642
if (attribute.type !== 'Attribute') continue;
642-
if (attribute.name.toLowerCase() !== name.toLowerCase()) continue;
643+
if (attribute.name.toLowerCase() !== name_lower) continue;
643644

644645
if (attribute.value === true) return operator === null;
645646
if (expected_value === null) return true;
646647

647648
if (is_text_attribute(attribute)) {
648-
return test_attribute(operator, expected_value, case_insensitive, attribute.value[0].data);
649+
const matches = test_attribute(
650+
operator,
651+
expected_value,
652+
case_insensitive,
653+
attribute.value[0].data
654+
);
655+
// continue if we still may match against a class/style directive
656+
if (!matches && (name_lower === 'class' || name_lower === 'style')) continue;
657+
return matches;
649658
}
650659

651660
const chunks = get_attribute_chunks(attribute.value);
@@ -654,7 +663,7 @@ function attribute_matches(node, name, expected_value, operator, case_insensitiv
654663
/** @type {string[]} */
655664
let prev_values = [];
656665
for (const chunk of chunks) {
657-
const current_possible_values = get_possible_values(chunk, name === 'class');
666+
const current_possible_values = get_possible_values(chunk, name_lower === 'class');
658667

659668
// impossible to find out all combinations
660669
if (!current_possible_values) return true;

packages/svelte/src/internal/client/constants.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,8 @@ export const LEGACY_PROPS = Symbol('legacy props');
3535
export const LOADING_ATTR_SYMBOL = Symbol('');
3636

3737
export const STALE_REACTION = Symbol('stale reaction');
38+
39+
export const ELEMENT_NODE = 1;
40+
export const TEXT_NODE = 3;
41+
export const COMMENT_NODE = 8;
42+
export const DOCUMENT_FRAGMENT_NODE = 11;

packages/svelte/src/internal/client/dev/elements.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/** @import { SourceLocation } from '#client' */
2+
import { COMMENT_NODE, DOCUMENT_FRAGMENT_NODE, ELEMENT_NODE } from '#client/constants';
23
import { HYDRATION_END, HYDRATION_START, HYDRATION_START_ELSE } from '../../../constants.js';
34
import { hydrating } from '../dom/hydration.js';
45

@@ -12,7 +13,7 @@ export function add_locations(fn, filename, locations) {
1213
return (/** @type {any[]} */ ...args) => {
1314
const dom = fn(...args);
1415

15-
var node = hydrating ? dom : dom.nodeType === 11 ? dom.firstChild : dom;
16+
var node = hydrating ? dom : dom.nodeType === DOCUMENT_FRAGMENT_NODE ? dom.firstChild : dom;
1617
assign_locations(node, filename, locations);
1718

1819
return dom;
@@ -45,13 +46,13 @@ function assign_locations(node, filename, locations) {
4546
var depth = 0;
4647

4748
while (node && i < locations.length) {
48-
if (hydrating && node.nodeType === 8) {
49+
if (hydrating && node.nodeType === COMMENT_NODE) {
4950
var comment = /** @type {Comment} */ (node);
5051
if (comment.data === HYDRATION_START || comment.data === HYDRATION_START_ELSE) depth += 1;
5152
else if (comment.data[0] === HYDRATION_END) depth -= 1;
5253
}
5354

54-
if (depth === 0 && node.nodeType === 1) {
55+
if (depth === 0 && node.nodeType === ELEMENT_NODE) {
5556
assign_location(/** @type {Element} */ (node), filename, locations[i++]);
5657
}
5758

packages/svelte/src/internal/client/dev/inspect.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { UNINITIALIZED } from '../../../constants.js';
22
import { snapshot } from '../../shared/clone.js';
33
import { inspect_effect, validate_effect } from '../reactivity/effects.js';
4+
import { untrack } from '../runtime.js';
45

56
/**
67
* @param {() => any[]} get_value
@@ -28,7 +29,10 @@ export function inspect(get_value, inspector = console.log) {
2829
}
2930

3031
if (value !== UNINITIALIZED) {
31-
inspector(initial ? 'init' : 'update', ...snapshot(value, true));
32+
var snap = snapshot(value, true);
33+
untrack(() => {
34+
inspector(initial ? 'init' : 'update', ...snap);
35+
});
3236
}
3337

3438
initial = false;

packages/svelte/src/internal/client/dom/blocks/each.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
} from '../../reactivity/effects.js';
3737
import { source, mutable_source, internal_set } from '../../reactivity/sources.js';
3838
import { array_from, is_array } from '../../../shared/utils.js';
39-
import { INERT } from '#client/constants';
39+
import { COMMENT_NODE, INERT } from '#client/constants';
4040
import { queue_micro_task } from '../task.js';
4141
import { active_effect, get } from '../../runtime.js';
4242
import { DEV } from 'esm-env';
@@ -227,7 +227,7 @@ export function each(node, flags, get_collection, get_key, render_fn, fallback_f
227227

228228
for (var i = 0; i < length; i++) {
229229
if (
230-
hydrate_node.nodeType === 8 &&
230+
hydrate_node.nodeType === COMMENT_NODE &&
231231
/** @type {Comment} */ (hydrate_node).data === HYDRATION_END
232232
) {
233233
// The server rendered fewer items than expected,

0 commit comments

Comments
 (0)