diff --git a/.changeset/three-steaks-wash.md b/.changeset/three-steaks-wash.md deleted file mode 100644 index caf0ea2bfe..0000000000 --- a/.changeset/three-steaks-wash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'svelte': patch ---- - -fix: correctly tag private class state fields diff --git a/documentation/docs/03-template-syntax/17-style.md b/documentation/docs/03-template-syntax/17-style.md index 749376c6e2..aa61cdcde3 100644 --- a/documentation/docs/03-template-syntax/17-style.md +++ b/documentation/docs/03-template-syntax/17-style.md @@ -34,8 +34,10 @@ To mark a style as important, use the `|important` modifier:
...
``` -When `style:` directives are combined with `style` attributes, the directives will take precedence: +When `style:` directives are combined with `style` attributes, the directives will take precedence, +even over `!important` properties: ```svelte -
This will be red
+
This will be red
+
This will still be red
``` diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md index 34e1c2fc6e..020942f5fd 100644 --- a/packages/svelte/CHANGELOG.md +++ b/packages/svelte/CHANGELOG.md @@ -1,5 +1,29 @@ # svelte +## 5.34.3 + +### Patch Changes + +- fix: don't eagerly execute deriveds on resume ([#16150](https://github.com/sveltejs/svelte/pull/16150)) + +- fix: prevent memory leaking signals in legacy mode ([#16145](https://github.com/sveltejs/svelte/pull/16145)) + +- fix: don't define `error.message` if it's not configurable ([#16149](https://github.com/sveltejs/svelte/pull/16149)) + +## 5.34.2 + +### Patch Changes + +- fix: add missing typings for some dimension bindings ([#16142](https://github.com/sveltejs/svelte/pull/16142)) + +- fix: prune typescript class field declarations ([#16154](https://github.com/sveltejs/svelte/pull/16154)) + +## 5.34.1 + +### Patch Changes + +- fix: correctly tag private class state fields ([#16132](https://github.com/sveltejs/svelte/pull/16132)) + ## 5.34.0 ### Minor Changes diff --git a/packages/svelte/elements.d.ts b/packages/svelte/elements.d.ts index 076cc71b38..fe4078f56a 100644 --- a/packages/svelte/elements.d.ts +++ b/packages/svelte/elements.d.ts @@ -844,6 +844,10 @@ export interface HTMLAttributes extends AriaAttributes, D readonly 'bind:borderBoxSize'?: Array | undefined | null; readonly 'bind:devicePixelContentBoxSize'?: Array | undefined | null; readonly 'bind:focused'?: boolean | undefined | null; + readonly 'bind:clientWidth'?: number | undefined | null; + readonly 'bind:clientHeight'?: number | undefined | null; + readonly 'bind:offsetWidth'?: number | undefined | null; + readonly 'bind:offsetHeight'?: number | undefined | null; // SvelteKit 'data-sveltekit-keepfocus'?: true | '' | 'off' | undefined | null; diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 3ecb1c42f5..c2a27b2595 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -2,7 +2,7 @@ "name": "svelte", "description": "Cybernetically enhanced web apps", "license": "MIT", - "version": "5.34.0", + "version": "5.34.3", "type": "module", "types": "./types/index.d.ts", "engines": { diff --git a/packages/svelte/src/compiler/phases/1-parse/remove_typescript_nodes.js b/packages/svelte/src/compiler/phases/1-parse/remove_typescript_nodes.js index aba94ee20d..cb498c3c13 100644 --- a/packages/svelte/src/compiler/phases/1-parse/remove_typescript_nodes.js +++ b/packages/svelte/src/compiler/phases/1-parse/remove_typescript_nodes.js @@ -115,6 +115,19 @@ const visitors = { TSDeclareFunction() { return b.empty; }, + ClassBody(node, context) { + const body = []; + for (const _child of node.body) { + const child = context.visit(_child); + if (child.type !== 'PropertyDefinition' || !child.declare) { + body.push(child); + } + } + return { + ...node, + body + }; + }, ClassDeclaration(node, context) { if (node.declare) { return b.empty; diff --git a/packages/svelte/src/internal/client/dom/blocks/await.js b/packages/svelte/src/internal/client/dom/blocks/await.js index 99bdc0000c..47df5fc9a5 100644 --- a/packages/svelte/src/internal/client/dom/blocks/await.js +++ b/packages/svelte/src/internal/client/dom/blocks/await.js @@ -58,8 +58,10 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) { /** @type {Effect | null} */ var catch_effect; - var input_source = (runes ? source : mutable_source)(/** @type {V} */ (undefined)); - var error_source = (runes ? source : mutable_source)(undefined); + var input_source = runes + ? source(/** @type {V} */ (undefined)) + : mutable_source(/** @type {V} */ (undefined), false, false); + var error_source = runes ? source(undefined) : mutable_source(undefined, false, false); var resolved = false; /** diff --git a/packages/svelte/src/internal/client/dom/blocks/each.js b/packages/svelte/src/internal/client/dom/blocks/each.js index 3144233df8..0a8179958e 100644 --- a/packages/svelte/src/internal/client/dom/blocks/each.js +++ b/packages/svelte/src/internal/client/dom/blocks/each.js @@ -636,7 +636,7 @@ function create_item( var reactive = (flags & EACH_ITEM_REACTIVE) !== 0; var mutable = (flags & EACH_ITEM_IMMUTABLE) === 0; - var v = reactive ? (mutable ? mutable_source(value) : source(value)) : value; + var v = reactive ? (mutable ? mutable_source(value, false, false) : source(value)) : value; var i = (flags & EACH_INDEX_REACTIVE) === 0 ? index : source(index); if (DEV && reactive) { diff --git a/packages/svelte/src/internal/client/error-handling.js b/packages/svelte/src/internal/client/error-handling.js index b79c1ce74f..594ef72d25 100644 --- a/packages/svelte/src/internal/client/error-handling.js +++ b/packages/svelte/src/internal/client/error-handling.js @@ -4,7 +4,7 @@ import { DEV } from 'esm-env'; import { FILENAME } from '../../constants.js'; import { is_firefox } from './dom/operations.js'; import { BOUNDARY_EFFECT, EFFECT_RAN } from './constants.js'; -import { define_property } from '../shared/utils.js'; +import { define_property, get_descriptor } from '../shared/utils.js'; import { active_effect } from './runtime.js'; /** @@ -63,6 +63,12 @@ function adjust_error(error, effect) { if (adjusted_errors.has(error)) return; adjusted_errors.add(error); + const message_descriptor = get_descriptor(error, 'message'); + + // if the message was already changed and it's not configurable we can't change it + // or it will throw a different error swallowing the original error + if (message_descriptor && !message_descriptor.configurable) return; + var indent = is_firefox ? ' ' : '\t'; var component_stack = `\n${indent}in ${effect.fn?.name || ''}`; var context = effect.ctx; diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 1aa9754a94..15f16a0691 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -338,6 +338,7 @@ export function render_effect(fn, flags = 0) { * @param {(...expressions: any) => void | (() => void)} fn * @param {Array<() => any>} sync * @param {Array<() => Promise>} async + * @param {(fn: () => T) => Derived} d */ export function template_effect(fn, sync = [], async = [], d = derived) { var batch = current_batch; @@ -626,15 +627,11 @@ function resume_children(effect, local) { if ((effect.f & INERT) === 0) return; effect.f ^= INERT; - // Ensure the effect is marked as clean again so that any dirty child - // effects can schedule themselves for execution - if ((effect.f & CLEAN) === 0) { - effect.f ^= CLEAN; - } - // If a dependency of this effect changed while it was paused, - // schedule the effect to update - if (check_dirtiness(effect)) { + // schedule the effect to update. we don't use `check_dirtiness` + // here because we don't want to eagerly recompute a derived like + // `{#if foo}{foo.bar()}{/if}` if `foo` is now `undefined + if ((effect.f & CLEAN) === 0) { set_signal_status(effect, DIRTY); schedule_effect(effect); } diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index 2398cd48bc..b09d079479 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -102,7 +102,7 @@ export function state(v, stack) { * @returns {Source} */ /*#__NO_SIDE_EFFECTS__*/ -export function mutable_source(initial_value, immutable = false) { +export function mutable_source(initial_value, immutable = false, trackable = true) { const s = source(initial_value); if (!immutable) { s.equals = safe_equals; @@ -110,7 +110,7 @@ export function mutable_source(initial_value, immutable = false) { // bind the signal to the component context, in case we need to // track updates to trigger beforeUpdate/afterUpdate callbacks - if (legacy_mode_flag && component_context !== null && component_context.l !== null) { + if (legacy_mode_flag && trackable && component_context !== null && component_context.l !== null) { (component_context.l.s ??= []).push(s); } diff --git a/packages/svelte/src/legacy/legacy-client.js b/packages/svelte/src/legacy/legacy-client.js index bb9a5a9c03..45c478ecab 100644 --- a/packages/svelte/src/legacy/legacy-client.js +++ b/packages/svelte/src/legacy/legacy-client.js @@ -82,7 +82,7 @@ class Svelte4Component { * @param {unknown} value */ var add_source = (key, value) => { - var s = mutable_source(value); + var s = mutable_source(value, false, false); sources.set(key, s); return s; }; diff --git a/packages/svelte/src/version.js b/packages/svelte/src/version.js index 42f59dffad..01888eaa78 100644 --- a/packages/svelte/src/version.js +++ b/packages/svelte/src/version.js @@ -4,5 +4,5 @@ * The current version, as set in package.json. * @type {string} */ -export const VERSION = '5.34.0'; +export const VERSION = '5.34.3'; export const PUBLIC_VERSION = '5'; diff --git a/packages/svelte/tests/runtime-runes/samples/if-nested-template/Component.svelte b/packages/svelte/tests/runtime-runes/samples/if-nested-template/Component.svelte new file mode 100644 index 0000000000..b4281bbcbd --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/if-nested-template/Component.svelte @@ -0,0 +1,7 @@ + diff --git a/packages/svelte/tests/runtime-runes/samples/if-nested-template/_config.js b/packages/svelte/tests/runtime-runes/samples/if-nested-template/_config.js new file mode 100644 index 0000000000..673f668916 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/if-nested-template/_config.js @@ -0,0 +1,17 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target, logs }) { + const [btn1, btn2] = target.querySelectorAll('button'); + const [div] = target.querySelectorAll('div'); + + flushSync(() => btn1?.click()); + assert.htmlEqual(div.innerHTML, '123 123'); + assert.equal(div.inert, true); + + flushSync(() => btn2?.click()); + assert.htmlEqual(div.innerHTML, ''); + assert.deepEqual(logs, ['123']); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/if-nested-template/main.svelte b/packages/svelte/tests/runtime-runes/samples/if-nested-template/main.svelte new file mode 100644 index 0000000000..04afa7d664 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/if-nested-template/main.svelte @@ -0,0 +1,23 @@ + + +{#if outer} +
+ {#if inner} + {@const text = inner.toString()} + {text} {inner.toString()} + + {/if} +
+{/if} + + + diff --git a/packages/svelte/tests/runtime-runes/samples/non-configurable-errors/_config.js b/packages/svelte/tests/runtime-runes/samples/non-configurable-errors/_config.js new file mode 100644 index 0000000000..5bbe4483d3 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/non-configurable-errors/_config.js @@ -0,0 +1,8 @@ +import { test } from '../../test'; + +export default test({ + compileOptions: { + dev: true + }, + error: 'test' +}); diff --git a/packages/svelte/tests/runtime-runes/samples/non-configurable-errors/main.svelte b/packages/svelte/tests/runtime-runes/samples/non-configurable-errors/main.svelte new file mode 100644 index 0000000000..f71a5e6c43 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/non-configurable-errors/main.svelte @@ -0,0 +1,11 @@ + diff --git a/packages/svelte/tests/runtime-runes/samples/typescript/main.svelte b/packages/svelte/tests/runtime-runes/samples/typescript/main.svelte index d1b6452df4..4fc7c4ec38 100644 --- a/packages/svelte/tests/runtime-runes/samples/typescript/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/typescript/main.svelte @@ -14,6 +14,7 @@ class Foo { public name: string; + declare bar: string; x = 'x' as const; constructor(name: string) { this.name = name;