Follow-up to #16271.
## Summary
- Allow `{@html}` blocks to accept `TrustedHTML` objects (from
TrustedTypes policies) without coercing them to strings
- This enables usage like `{@html myPolicy.createHTML(someHTML)}`
- Works in regular HTML, SVG, and MathML contexts
## Changes
- **`html.js`**: Instead of calling `create_fragment_from_html`, create
the wrapper element directly (`<template>`, `<svg>`, or `<math>`
depending on context) and assign the value to `innerHTML`. This
preserves `TrustedHTML` objects.
- **`reconciler.js`**: Removed the `trusted` parameter from
`create_fragment_from_html` since it's no longer used by `{@html}` and
all remaining callers want trusted HTML.
- **`template.js`** and **`snippet.js`**: Removed the second argument
from `create_fragment_from_html` calls.
## Notes
No tests added because JSDOM doesn't implement TrustedTypes.
Fixes#17735
Use the if/else hydration markers to know what "branch" (component or no
component) was rendered, and repair if differing.
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
# Releases
## svelte@5.51.5
### Patch Changes
- fix: check to make sure `svelte:element` tags are valid during SSR
([`73098bb26c6f06e7fd1b0746d817d2c5ee90755f`](73098bb26c))
- fix: misc option escaping and backwards compatibility
([#17741](https://github.com/sveltejs/svelte/pull/17741))
- fix: strip event handlers during SSR
([`a0c7f289156e9fafaeaf5ca14af6c06fe9b9eae5`](a0c7f28915))
- fix: replace usage of `for in` with `for of Object.keys`
([`f89c7ddd7eebaa1ef3cc540400bec2c9140b330c`](f89c7ddd7e))
- fix: always escape option body in SSR
([`f7c80da18c215e3727c2a611b0b8744cc6e504c5`](f7c80da18c))
- chore: upgrade `devalue`
([#17739](https://github.com/sveltejs/svelte/pull/17739))
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
### Before submitting the PR, please make sure you do the following
- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [ ] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [ ] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [ ] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [ ] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
### Before submitting the PR, please make sure you do the following
- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [ ] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [ ] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [ ] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [ ] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
# Releases
## svelte@5.51.4
### Patch Changes
- chore: proactively defer effects in pending boundary
([#17734](https://github.com/sveltejs/svelte/pull/17734))
- fix: detect and error on non-idempotent each block keys in dev mode
([#17732](https://github.com/sveltejs/svelte/pull/17732))
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Currently, (render/template) effects inside pending boundaries are
deferred, but in an indirect manner: first we schedule them, then we
`flush` the current batch, and in the course of traversing the effect
tree we find any dirty effects and defer them at the level of the
topmost pending boundary.
This doesn't really make sense — we can just skip to the end state and
skip the scheduling/traversal, since the effects don't become relevant
until the boundary resolves.
This PR implements that. It is a stepping stone towards a larger
refactor, in which scheduling becomes batch-centric and lazier. While it
shouldn't change any observable behaviour, I've added a changeset out of
an abundance of caution.
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
## Summary
Fixes#17721
In dev mode, detect when a keyed each block has a key function that
returns different values when called multiple times for the same item
(non-idempotent). This catches the common mistake of using array
literals like `[thing.group, thing.id]` as keys, which creates a new
array object each time and will never match by reference.
- Adds new `each_key_volatile` error with helpful message explaining the
issue
- Checks key idempotency in the each block loop during dev mode
- Provides a clear error instead of the cryptic "Cannot read properties
of undefined" that occurred previously
---------
Co-authored-by: 7nik <kifiranet@gmail.com>
We have a bunch of repeated logic around incrementing/decrementing
pending states. This DRYs it out to unblock some forthcoming changes
around scheduling
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
# Releases
## svelte@5.51.3
### Patch Changes
- fix: prevent event delegation logic conflicting between svelte
instances ([#17728](https://github.com/sveltejs/svelte/pull/17728))
- fix: treat CSS attribute selectors as case-insensitive for HTML
enumerated attributes
([#17712](https://github.com/sveltejs/svelte/pull/17712))
- fix: locate Rollup annontaion friendly to JS downgraders
([#17724](https://github.com/sveltejs/svelte/pull/17724))
- fix: run effects in pending snippets
([#17719](https://github.com/sveltejs/svelte/pull/17719))
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Fixes https://github.com/sveltejs/svelte.dev/issues/1793. There are
actually two fixes here, and either is sufficient to fix the playground,
but they are complementary. First, we only add the delegated event
handler _after_ the component has successfully mounted, otherwise it
will never get cleaned up if an error occurs during mount.
Second, instead of storing data on `event.__root` (which leaks between
instances), we reuse the existing `event_symbol` to provide the
necessary encapsulation. (I'll be honest I don't totally understand what
this property is for anyway and can't be bothered to figure it out right
now, but I'm sure it's important.)
No test because I'm not really sure how you _would_ test this; it
requires a fairly esoteric setup.
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Fixes#17207
CSS attribute selectors for HTML enumerated attributes (like `method`,
`type`, `dir`, etc.) are supposed to match case-insensitively per the
HTML spec. Browsers handle this correctly — `form[method="get"]` matches
`<form method="GET">`. But Svelte's CSS pruning was doing a strict
case-sensitive comparison, which meant:
1. The selector got incorrectly flagged as unused (no
`css_unused_selector` warning was shown when spreads were involved, but
the selector was still pruned)
2. The scoping class wasn't applied to the matching element
3. Styles silently disappeared in production builds
The fix adds a set of known HTML attributes with case-insensitive
enumerated values (sourced from the HTML spec) and uses it during CSS
attribute selector matching. The explicit CSS `s` flag still overrides
this behavior, as expected.
### Before
```svelte
<form method="GET">
<h1>Hello</h1>
</form>
<style>
form[method="get"] h1 { color: red; }
/* ^ incorrectly pruned, <h1> not styled */
</style>
```
### After
The selector correctly matches and styles are applied.
### Test plan
- Added `attribute-selector-html-case-insensitive` CSS test covering
`form[method]` and `input[type]` cases
- All 179 existing CSS tests pass
- Verified the existing `attribute-selector-case-sensitive` test (using
`s` flag) still works correctly
- Compiler error tests and validator tests all pass
---------
Co-authored-by: Rich Harris <hello@rich-harris.dev>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Boundaries are buggy: if the `pending` snippet contains state, changes
to that state [won't cause
updates](https://svelte.dev/playground/hello-world?version=5.51.2#H4sIAAAAAAAAE22SQW-DMAyF_0qUTSpoE92uFJh223Hate0hJWaNliZRYsoqxH9fQtJW6noD-33Pz4aRKnYAWtIPkFKTQVvJSQZcIPCcPtNOSHC0XI8UTyboQsHXE_VuTOGOIDHUdszBvXqrFYJCb0Mr11phsNmoDUpAYsFpeQTrSE3W25Uv-0bXqxaFVsT0bp8dmewhJ2PobNB7OSQcOrAWuKc-rT4IB8UgcP91dsvyVZRf_IvZK8tJ3VzoInXTiCuDvVVXlYkT5u50k9DtRYfZJd11XGq8FSlKAsPOre4V-uSPDhlC9hIE1fJ6GFXtekRvrlUrRftTjzF25J5q8jrN9xOqtXDwhw14RO7jc5bIzI-3-vihyp3358yeZmFlmpENTGD8CIu0GV_kU7U0TdxmfHBKGON3MqC4UN9ZPsVDBHzOe1bjuEzaad7230j_nyD8Ii3R9jBt_RsTchCK07Jj0sH0B6hNF6aqAgAA):
```svelte
<script>
let resolvers = [];
function push(value) {
const deferred = Promise.withResolvers();
resolvers.push(() => deferred.resolve(value));
return deferred.promise;
}
function shift() {
resolvers.shift()?.();
}
let count = $state(0);
</script>
<button onclick={() => count += 1}>
increment
</button>
<button onclick={shift}>
shift
</button>
<svelte:boundary>
<p>{await push('resolved')}</p>
{#snippet pending()}
<p>{count}</p>
{/snippet}
</svelte:boundary>
```
The issue is that the boundary's `this.#effect` has the
`BOUNDARY_EFFECT` flag, and `this.#pending_effect` is a child thereof.
Instead, `this.#main_effect` should have the flag. (It turns out
`this.#failed_effect` _also_ needs the flag, because errors that occur
in a `failed` snippet cause the boundary to re-render in its `failed`
state, which I found somewhat confusing to be honest. Probably the right
choice though.)
I was able to simplify the code a bit, too.
~~(Actually now that I think about it do we need `this.#effect` at all?
Will check.)~~
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Closes#17722
Looks like after downgrading `?.`, `/* @__PURE__ */` may happen in an
invalid location.
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
# Releases
## svelte@5.51.2
### Patch Changes
- fix: take async into consideration for dev delegated handlers
([#17710](https://github.com/sveltejs/svelte/pull/17710))
- fix: emit state_referenced_locally warning for non-destructured props
([#17708](https://github.com/sveltejs/svelte/pull/17708))
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Non-destructured `$props()` access in runes mode silently skipped the
`state_referenced_locally` warning, leading to missed guidance when
users read `props` via identifiers or member expressions.
- **Analyzer behavior**
- Include `rest_prop` bindings in `state_referenced_locally` detection
so reads of `$props()` identifiers warn consistently with destructured
props.
- **Validation coverage**
- Add a validator fixture for `$props()` identifiers and update the
`props-identifier` snapshot expectations to capture the new warnings.
Example:
```svelte
<script>
const props = $props();
const { model } = props; // now warns
const value = props.model.value; // now warns
</script>
```
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>False negative for `state_referenced_locally` warning on
not destructured `$props` access?</issue_title>
> <issue_description>### Describe the bug
>
> I was looking for a workaround for sveltejs/svelte#17669 and thought
of not destructuring the `$props` directly; to my surprise there were no
warnings at all.
>
>
> ### Reproduction
>
> ```js
> const props = $props();
> const { model } = props; // missing warning
>
> const value = props.model.value; // missing warning
> ```
>
>
[Playground](https://svelte.dev/playground/untitled?version=5.50.2#H4sIAAAAAAAACn2QT4vCQAzFv0oIe1CQ9l51YY97lj1tPYxtXAam6TAT_1H63U0HUax1j3nvJeT3OmTTEBb4w2LFUY0L3FtHEYvfDuXiB28QVL8lv7zP4pGcDNrORJrSq5aFWPQMrmIVrJfPkktROQp00LQ1OehhDR8-tD7O5ku174GjcQdSM8WyNC0hz4HOniqhGk4msOW_klf54zrPNkTwzVUbgsZuz8z1G6GzYCHhQP3iDdV47Zltwv2XMEGN6Cbgk5vIGhujAj3AXstI4WxcycvivZFn7q1OxrqT5RqLvXGR-itXywVk_AEAAA)
>
> ### Logs
>
> ```shell
>
> ```
>
> ### System Info
>
> ```shell
> REPL - Svelte v.5.50.2
> ```
>
> ### Severity
>
> annoyance</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixessveltejs/svelte#17685
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Rich-Harris <1162160+Rich-Harris@users.noreply.github.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
Closes#17709
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
# Releases
## svelte@5.51.1
### Patch Changes
- fix: don't crash on undefined `document.contentType`
([#17707](https://github.com/sveltejs/svelte/pull/17707))
- fix: use symbols for encapsulated event delegation
([#17703](https://github.com/sveltejs/svelte/pull/17703))
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
# Releases
## svelte@5.51.0
### Minor Changes
- feat: Use `TrustedTypes` for HTML handling where supported
([#16271](https://github.com/sveltejs/svelte/pull/16271))
### Patch Changes
- fix: sanitize template-literal-special-characters in SSR attribute
values ([#17692](https://github.com/sveltejs/svelte/pull/17692))
- fix: follow-up formatting in `print()` — flush block-level elements
into separate sequences
([#17699](https://github.com/sveltejs/svelte/pull/17699))
- fix: preserve delegated event handlers as long as one or more root
components are using them
([#17695](https://github.com/sveltejs/svelte/pull/17695))
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Follow-up to #17319.
The `Fragment` visitor in `print()` only flushed sequences on
`RegularElement`, causing block-level elements (`Component`,
`SvelteHead`, `SvelteBoundary`, etc.) to be lumped into the same
sequence as adjacent nodes. This broke tools that programmatically
manipulate the AST (e.g.
[sveltejs/cli#915](https://github.com/sveltejs/cli/pull/915)).
The fix flushes before and after all block-level element types, ensuring
they get their own sequence and proper line separation.
### Before
```svelte
<svelte:head><title>Page Title</title></svelte:head><div>no space</div>
<Component /><Component />
<Component><span>child</span></Component><div>after component</div>
<svelte:boundary><div>boundary content</div></svelte:boundary><div>after boundary</div>
<!--comment--><div>after comment</div>
<div>before comment</div>
<!--comment-->
{#each items as item}
<div>{item}</div>
{/each}<div>after each</div>
{@render children()}<div>after render</div>
<div>before render</div>
{@render children()}
```
### After
```svelte
<svelte:head><title>Page Title</title></svelte:head>
<div>no space</div>
<Component />
<Component />
<Component><span>child</span></Component>
<div>after component</div>
<svelte:boundary><div>boundary content</div></svelte:boundary>
<div>after boundary</div>
<!--comment-->
<div>after comment</div>
<div>before comment</div>
<!--comment-->
{#each items as item}
<div>{item}</div>
{/each}
<div>after each</div>
{@render children()}
<div>after render</div>
<div>before render</div>
{@render children()}
```
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
Fixes#17694
Not really sure how to add a failing test here.
The code was generated by Codex 5.3, but I cleaned it up and manually
reviewed it myself. Not sure if this is the best approach to solving the
issue, though. It does add some overhead with the extra maps.
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
### Before submitting the PR, please make sure you do the following
Resolves https://github.com/sveltejs/svelte/issues/14438
Resolves https://github.com/sveltejs/svelte/issues/10826
This PR makes it possible to use Svelte on pages which require
`TrustedTypes` support via their CSP by wrapping assignments to
`innerHTML` in a `TrustedTypePolicy` called `svelte-trusted-html` if the
`TrustedTypes` API exists.
Servers can allowlist the policy by setting `require-trusted-types-for
'script'; trusted-types svelte-trusted-html` in their
`Content-Security-Policy` header.
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
Note: I haven't run the tests since I don't have `pnpm` setup properly.
I have tested that:
1. A project with a CSP fails with Tip of Tree Svelte
2. That project works when installing this revision of Svelte
3. The project (with this revision) works in Browsers with no
`TrustedTypes` support (i.e. Firefox, Safari)
- [ ] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
My test project is here:
https://github.com/fallaciousreasoning/svelte-tt-test/blob/master/src/routes/%2Bpage.server.js
The only changes to the default project is adding the CSP in
`src/routes/page.server.js`
---------
Co-authored-by: 7nik <kfiiranet@gmail.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
Fixes a minor bug where HTML entities could be decoded into significant
characters in the template literal we output for SSR, leading to weird
effects. Not a security issue because it has to be literally written
into the svelte file you're compiling, but still wrong.
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Fixes#16342.
Errors thrown inside `$effect` were previously treated as
subtree-creation errors when `EFFECT_RAN === 0`, which caused them to be
rethrown instead of propagating to the nearest `<svelte:boundary>`. As a
result, `$effect` errors bypassed boundaries and appeared as uncaught
runtime errors. This change ensures that errors originating from effects
(`EFFECT`) are routed through `invoke_error_boundary`, allowing them to
bubble up the effect tree and be handled correctly by the closest
boundary. Existing subtree-creation behavior for non-effect cases
remains unchanged.
---
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
It should be the last piece of XHTML compliance.
We missed fixing `mutltiple` and `selected` attributes on `<select>` and
`<option>`.
Also, it seems the test runtime-legacy/select-multiple-spread was
broken.
I just copied to runtime-xhtml and updated tests that fail when a
`nodeName` comparison is broken. For `<progress>` no test due to JSDOM
quirks (at least in the past), and for `<template>` and `<script>`
nothing got broken 🤔
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
This supersedes #16595, and fixes the issue by 'freezing' effects inside
deriveds when those deriveds are disconnected, and unfreezing them when
they reconnect. This is preferable to the current asymmetric behaviour
on `main` (in which effects are destroyed when the derived is
disconnected, and never recreated) and #16595, which causes the derived
itself to be re-evaluated.
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
follow-up to #17418. This replaces every occurrence of
`document.createElement` with a helper, `create_element`, that delegates
to `document.createElementNS`. This makes the code a tiny bit simpler
and in theory should allow Svelte to run on `text/xml` documents, though
I'm not ready to add a test suite to prevent regressions for something
so niche.
If we choose to merge this, I think we can safely close#17418 as all
the other points (around case sensitivity etc) have already been taken
care of AFAICT.
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [ ] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Tee Ming <chewteeming01@gmail.com>
Another XHTML thing, per
https://github.com/sveltejs/svelte/pull/17418#issuecomment-3863029273
(that PR doesn't address this issue)
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
## Summary
Fixes#13768
`<select bind:value={derived.prop}>` in legacy (non-runes) components
throws `effect_update_depth_exceeded` when the bound value comes from a
`$:` reactive statement.
**Root cause:** `setup_select_synchronization` created a
`template_effect` that called `invalidate_inner_signals`, which reads
and writes the same signals on every change — creating an infinite
update loop when those signals feed back into derived state.
**Fix:** Remove the effect-based synchronization entirely. Instead,
populate `legacy_indirect_bindings` during the analyze phase for
`<select bind:value>` elements, and call `invalidate_inner_signals`
inline at the mutation point in `AssignmentExpression` — only when the
binding is actually mutated, avoiding the read-write cycle.
Based on the approach outlined in #16200.
## Changes
- **`scope.js`**: Add `legacy_indirect_bindings` field to `Binding`
class
- **`RegularElement.js` (analyze)**: For `<select bind:value={foo}>`,
collect scope references as indirect bindings on the bound variable
- **`RegularElement.js` (transform)**: Remove
`setup_select_synchronization` function and its call site
- **`AssignmentExpression.js` (transform)**: When mutating a binding
with indirect bindings, append `invalidate_inner_signals` call after the
mutation
## Test plan
- Added `binding-select-reactive-derived` test that reproduces the exact
scenario from #13768
- All 3291 runtime-legacy tests pass (0 regressions)
- All 2312 runtime-runes tests pass
- All snapshot and compiler tests pass
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Currently, the [newly introduced `parseCss` from
`svelte/compiler`](https://github.com/sveltejs/svelte/pull/17496)
returns `Omit<AST.CSS.StyleSheet, 'attributes' | 'content'>`. If you try
to work with this in external tooling, everywhere where you pass around
the result of this method, you need to use that type as well, which is
quite cumbersome. (I'm trying to integrate this into `sv` to get rid of
a workaround)
This creates a new type in the CSS AST to differentiate between one
stylesheet only having the roles, and one beeing the full one that is
used in `parse` itself. Im 100% open on the name of the new type or any
better ideas.
### Before submitting the PR, please make sure you do the following
- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
This was actually several bugs:
- We used `scopes` for the blockers, that's actually the template
scopes, should be `instance.scopes` instead
- We missed setting the scope for `touch`
- We didn't take return statements into account when calculating
blockers. We cannot know when/if something within the return statement
is called, so we gotta assume it is and touch everything transitively
from it
Combined this fixes#17667 (and possibly other cases not showing up in
the issue tracker yet)
Initially I just thought "ok I guess we have to traverse into functions,
too" but then I thought that feels too unoptimized and came up with the
return-statement-inspection, at which point I discovered the other bugs.
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
* chore: update ESLint to v10
Update eslint and related plugins/configs. Bump CI lint job to Node 24
(ESLint 10 requires ^20.19.0 || ^22.13.0 || >=24). Replace removed
Linter.FlatConfig type with Linter.Config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address new `no-useless-assignment` violations from ESLint 10
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* dedupe
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: reduce if block nesting
This reduces if block nesting similar to how we did it in #15250 (which got lost during the `await` feature introduction): If the if expression doesn't contain an await expression or is not dependent on a blocker that is not already resolved, then we can avoid creating a separate `$.if()` statement. The one trade-off is that we'll do re-invocations for all the conditions leading up to the condition that matches. Therefore non-simple if expressions are wrapper in `$.derived` to avoid excessive recomputations.
closes#17659 (~320 markers in prod mode possible now; less in dev because of our "wrap this component with devtime info" method)
helps with #15200
* tweak
* feedback
If the render tag is wrapped in `$.async`, that `$.async` call already contains surrounding markers, so we must not add our own to avoid hydration mismatches. Related to #17641, fixes#17225
* add xhtml tests
* unused
* tweak
* more tests
* tweak
* we don't need to actually check the HTML - if it's malformed in SSR or mount, it will throw
* same here
* unused, so we can revert this
* and this
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* docs: wrap JSDoc URLs in @see and @link tags
* fix: move curly brace to end of URL
* chore: add changeset
* add link text
* regenerate
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: allow NaN in key blocks
* lol whoops
* Update packages/svelte/src/internal/client/dom/blocks/key.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* treat menu element like ul/ol for a11y role checks
The <menu> element has the same implicit role (list) as <ul> and <ol>,
so it should receive the same treatment in a11y checks:
- Allow <menu role="list"> without redundant role warning (CSS
list-style:none can remove semantics, role restores them)
- Allow <menu> with interactive roles like menu, menubar, radiogroup,
tablist, tree, treegrid (same exceptions as ul/ol)
Fixes#8529
* changeset
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix: exit resolved async blocks on correct node when hydrating
* expand test + fix
* tweak, add note to self
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
This is basically #17611, minus #17640, plus #17639. We need to add the $.next() call after render tags as well as components; rather than duplicating the logic, we can use is_standalone to determine when this is necessary (since this is what prevents $.append(...) from being used).
Fixes#17261Fixes#17608
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
creates a few abstractions in the compiler code around common "if-else" scenarios, as well as introducing a new runtime render helper
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
The store invalidation detection in each blocks only checked for
Identifier and MemberExpression AST node types. This caused bind:
on iteration variables to silently fail when the expression used
logical operators (e.g. `{#each $store.items ?? [] as item}`).
Use expression metadata dependencies instead of AST type checking
to find store_sub bindings, which correctly handles all expression
shapes.
Fixes#14625
* fix: emit `each_key_duplicate` error in production
* fix: preserve key
* Update packages/svelte/src/internal/client/dom/blocks/each.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* Update packages/svelte/src/internal/client/dom/blocks/each.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: ensure keys are validated
* fix silly test name
* fix: cover other case of duplicate keys
* emit error on hydration
* ensure the error is handled
* drop useless tests
* unused
* finish merge
* add lost check back
* chore: bump playwright (#17565)
* chore: bump playwright
* maybe this will help somehow?
* err whatever
* fix
* chore: allow testing in production env 2 (#17590)
* Revert "chore: allow testing in production env (#16840)"
This reverts commit ffd65e90fe.
* new approach
* fix: handle renderer.run rejections (#17591)
* fix: handle renderer run rejections
* add test
* changeset
* simplify
* explanatory comment
---------
Co-authored-by: Antonio Bennett <abennett@mabelslabels.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: only create async functions in SSR output when necessary (#17593)
* fix: only create async functions in SSR output when necessary
* actually...
* simplify generated code a bit more
* simplify
* fix: merge consecutive text nodes during hydration for large text content (#17587)
* fix: merge consecutive text nodes during hydration for large text content
Fixes#17582
Browsers automatically split text nodes exceeding 65536 characters into
multiple consecutive text nodes during HTML parsing. This causes hydration
mismatches when Svelte expects a single text node.
The fix merges consecutive text nodes during hydration by:
- Detecting when the current node is a text node
- Finding all consecutive text node siblings
- Merging their content into the first text node
- Removing the extra text nodes
This restores correct hydration behavior for large text content.
* add test, fix
* fix
* fix
* changeset
---------
Co-authored-by: Miner <miner@example.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* Version Packages (#17585)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Revert "drop useless tests"
This reverts commit 65f77ef840.
* update tests
* fix test
* we don't need to expose this function any more
* figured it out... we cant have errors during reconcile
* simplify
* tweak
* unused
* revert no-longer-needed change
* unused
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Antonio Bennett <31296212+Antonio-Bennett@users.noreply.github.com>
Co-authored-by: Antonio Bennett <abennett@mabelslabels.com>
Co-authored-by: FORMI <239411042+Richman018@users.noreply.github.com>
Co-authored-by: Miner <miner@example.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Remove SvelteKit data attributes from elements.d.ts
Removed SvelteKit specific data attributes from elements.d.ts.
* Remove SvelteKit data attributes from elements.d.ts
Removed SvelteKit data attributes from elements.d.ts.
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
fixes#17595
When an if/key/etc block has an expression that depends on an async blocker (e.g., is inside a component with top level `await`), the compiler incorrectly treats the expression as async - even when the expression itself contains no `await`.
This causes the expression to be added to `$.async`'s `expressions` array, which wraps it in an `async_derived`. This is not only unnecessary but also buggy: it breaks the direct reactive connection between the source and its dependent effects, causing inconsistent effect executions.
The fix is to only add expressions to `$.async`'s `expressions` array when they actually contain an `await`.
When a branch is speculatively marked for destruction (condition temporarily falsy), its child effects are reset to `CLEAN` to prevent them running in a doomed branch (as of #17581). However, if the branch survives (condition becomes truthy again), those effects remain `CLEAN` and never run - the source was already marked dirty before the reset, so no new dirty marking occurs.
The fix is to change `skipped_effects` from a `Set` to a `Map` that tracks which child effects were dirty/maybe_dirty before being reset. When a branch is unskipped (survives), restore their status and reschedule them.
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: merge consecutive text nodes during hydration for large text content
Fixes#17582
Browsers automatically split text nodes exceeding 65536 characters into
multiple consecutive text nodes during HTML parsing. This causes hydration
mismatches when Svelte expects a single text node.
The fix merges consecutive text nodes during hydration by:
- Detecting when the current node is a text node
- Finding all consecutive text node siblings
- Merging their content into the first text node
- Removing the extra text nodes
This restores correct hydration behavior for large text content.
* add test, fix
* fix
* fix
* changeset
---------
Co-authored-by: Miner <miner@example.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: prevent reactivity loss during fork
fixes#17197, fixes#17304, fixes#17301, fixes#17309
* add samples
* add changeset
* fix var casing in tests
* don't remove reactions during fork
* add sample for derived dep tracking in fork
* fix sample type check error
* set derived.v on first eval in fork
* add sample for derived.v remaining UNINITIALIZED
* lost current_batch import in runtime.js
* Delete how
* Update packages/svelte/src/internal/client/reactivity/deriveds.js
* delete test in favour of #17577
* extract runtime.js changes into separate PR
* alternative approach
* revert
* clear skipped branches when deferring
* fix
* fix
* changeset
* rename test
* update test
* unused test
---------
Co-authored-by: David Roizenman <david@hmnd.io>
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
Co-authored-by: Tee Ming <chewteeming01@gmail.com>
* fix: make onintrostart respect delay parameter
Fixes#14009
The onintrostart event now fires after the delay period completes,
rather than immediately when the transition is initiated. This ensures
that the event accurately reflects when the intro animation actually
starts.
Changes:
- Added on_start callback parameter to animate() function
- Dispatch introstart event after delay animation finishes
- Handle edge case where duration is 0 but delay > 0
* fix: format code with prettier
* add (failing) tests
* fix
* changeset
* missed a spot
* fix
---------
Co-authored-by: Miner <miner@example.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* add check for negative idx to sourcemaps test
* fix: format
* Update packages/svelte/tests/sourcemaps/test.ts
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: mark parent effect as dirty on error boundary initialization
This change ensures that if an error occurs while a parent effect is still initializing, the parent effect is marked as dirty and scheduled to re-run. This addresses scenarios where state updates in the onerror handler do not trigger a re-evaluation of the condition, improving error handling in Svelte components.
* chore: add changeset for #17553
* fix: run boundary callbacks in a microtask, in case they result in the boundary's destruction
---------
Co-authored-by: frozenflux2 <snowflake30518@gmail.com>
* fix: each block breaking with effects interspersed among items
* test sample with interspersed non-branch effects
* Apply suggestion from @Rich-Harris
* use $effect.pre in sample instead
---------
Co-authored-by: Rich Harris <hello@rich-harris.dev>
* fix: add pointer and touch events to a11y_no_static_element_interactions warning
Fixes#17527
The a11y_no_static_element_interactions warning now triggers for pointer
and touch events (onpointerdown, onpointerenter, ontouchstart, etc.)
in addition to mouse and drag events.
This ensures accessibility warnings are consistent across all pointer
input methods.
* fix test
---------
Co-authored-by: Daniel <daniel@example.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: handle falsy dynamic components in SSR
Closes#17408
Adds a dynamic check for the component in the SSR.
Changes:
- Modified server-side component renderer to use b.maybe_call for dynamic components
- Added SSR test case for falsy component values
* fix types
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: avoid using dev-mode array.includes wrapper on internal array checks
* use includes rather than index_of
* unused imports
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* add samples for async readable freeze
* test updating without changing reference too
* fix: treat block effects as maybe dirty in revive()
* even simpler - put block effects in maybe_dirty_effects
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
PR #17461 added the `wait` function to `reactivity/async.js` and modified the compiler to generate `$.wait()` calls, but forgot to export it from `index.js`.
This causes a runtime error when using `await` inside `$derived()` with `experimental.async: true`:
```
TypeError: $.wait is not a function
```
Fixes#17529
* fix: batch resolution of async work
Co-authored-by: David Roizenman <hmnd@users.noreply.github.com>
* fix
* drive-by tidy up — Batch.enqueue is (apparently?) a useless wrapper around queue_micro_task
* 99% sure it's impossible for is_flushing to be true inside a queued task
* add some comments
* return early, reduce indentation
---------
Co-authored-by: David Roizenman <hmnd@users.noreply.github.com>
* chore: reduce indirection, simplify logic in batch.process(...)
* this is unnecessary, previous_batch is only read in specific effects that run later
* perf: use Set for new_deps to avoid O(n) includes check
* fix: only call revive() when batch is no longer deferred
* fix: avoid unnecessary async tracking when blockers are already settled
* add changeset
* only record promises as settled after cleanup is complete
* don't flush when already flushing
* skip settled blockers more aggressively
* batch decrement and pending count updates to reduce flush pressure
* extract new_deps changes to a separate PR
* remove changeset that applies to the other branch
* mark promises as settled as they settle — at the end is too late to do any good
* remove unnecessary microtask
* extract batch changes to separate PR
* this too
* avoid assigning to parameter
* wrong promise added to settled_promises due to reassignment
* WIP
* WIP
* fix
* unused
* oops
* bad import
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: handle non-string values in svelte:element this attribute
* chore: add changeset
* fix(review): throw error in DEV for invalid svelte:element tag, ignore in PROD
* chore: remove unused expected.html from test
* fix(review): refine validate.js logic
* fix(review): use else if (string) logic in server/index.js
* fix(review): swap validation order in compiler, revert runtime changes
* test: move reproduction to runtime-legacy per review
* Apply suggestion from @7nik
---------
Co-authored-by: tensorworker <tensorworker@proton.me>
Co-authored-by: 7nik <kfiiranet@gmail.com>
* feat: export from
* changeset
* fix: Errors
* set_source, so state is correct if an error occurs
* simplify
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* feat: customizable select
* fix: treat inner of options as separate templates
* fix: add hydration comment
* fix: clear with textContent
* fix: mark rich content option as dynamic and allow optgroup
* fix: allow select with rich content and rename
* chore: revert tests
* fix: recursively check rich options
* chore: change name of template
* fix: mark boundary as dynamic
* chore: add snapshot tests
* chore: include comprehensive hydration test
* fix: consider `selectedelement` as ancestor of `option` elements
* fix: make `:has` work with `selectedcontent`
* chore: failing test for css
* fix: also return parent for adjacent_only
* fix: move hydration marker at the end
* chore: apply suggestions from code review
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: treat text elements in select and optgroup as rich
* fix hydration
* colocate code
* drop the element, it's cleaner
* rename module
* update test
* Update .changeset/chubby-dingos-laugh.md
* fix a11y warning that occurs when button only contains selectedcontent
* remove unused parameter
* last part is redundant
* simplify
* unnecessary, the constraints overlap
* this is taken care of during analysis
* simplify
* tweak
* tweak
* tweak
* fix/tweak
* tweak
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* add test sample
* add test for sveltejs/kit#15059
* fix: reconnect deriveds inside branch effects
* add changeset
* fix: derived with no deps always set as MAYBE_DIRTY
fixes#17342
* add test for #17342
* additional changeset
* refactor: extract setting derived status to helper, apply to sources.js
* add test case for #17352
* fix: reconnect child deriveds when evaluating connected parent derived
fixes#17352
* fix import order causing Cannot read properties of undefined on dev load
* remove duplicate iteration over deps
* minor style tweaks
* oops, fix merge
* use update_derived_status, so that we never set a dep-less derived MAYBE_DIRTY
* tweak
* reaction.deps cannot be null for a MAYBE_DIRTY derived
* make it such that reactions without deps are never MAYBE_DIRTY
* since we no longer need to check reaction.deps === null, we can revert this bit
* more explicit check
* tidy up
* more
* gah whoops
* move import
* simplify test
* make dep-less derived behaviour more explicit, move it above is_destroying_effect handling
* remove test - this is adequately covered by #17445
* replace tricky unit test with component-based test
* remove incorrect test
* remove the BRANCH_EFFECT stuff
* tidy up
* DRY
* tweak, add explanatory comment
* tweak
* explanatory comment
* remove changeset
* update changeset
---------
Co-authored-by: Tee Ming <chewteeming01@gmail.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* feat: type `currentTarget` in `on` function
* `EventTarget &` is redundant, `Element` already extends `EventTarget`
* no need for optional chaining
* add currentTarget for other overloads
* update changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: prevent infinite loop when HMRing a component with an `await`
* update test
* fix
* reintroduce old logic to fix ever-growing stack of block effects
* update snapshot
* tweak names for clarity, simplify `update` slightly
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
* fix: set Root start/end to null when fragment contains only whitespace
* format
* always set root.start to 0 and root.end to template.length
* Update .changeset/fruity-knives-ring.md
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
In #17105 one line in `update_reaction` was changed that can cause reactivity loss. It checks if the reaction is updated inside of an effect and only then will push to the reactions. The prior version had an additional check to still add to the reactions if there is already at least one reaction on the derived, indicating it is connected. Removing this check fixes#17263 while keeping correctness: a connected derived by definition at least has one reaction and therefore can properly cleanup.
* chore: more effect helpers
This adds two new helpers that helped me tremendously with getting to the bottom of #17197:
- `log_reactions`: Logs the graph of reactions starting from the given signal, and also checks if the effect leafs are reachable and if they are able to schedule a root
- `log_inconsistent_branches`: Logs if there are paths in the graph where a branch is clean above a non-clean branch, which means that the part of the graph cannot schedule batches anymore
* shut up eslint
* fix: link offscreen items and last effect in each block correctly
It's possible that due to how new elements are inserted into the array that `effect.last` is wrong. We need to ensure it is really the last item to keep items properly connected to the graph. In addition we link offscreen items after all onscreen items, to ensure they don't have wrong pointers.
Fixes#17201
* revert #17244
* add test
* use local version of esrap, for now
* WIP
* WIP
* fixes
* more
* add `Declaration` visitor
* add `TransitionDirective`
* `UseDirective`, `OnDirective`
* more directives
* `SpreadAttribute`, directive shorthands
* `{#if ...} {:else ...}`
* fix
* more
* add tags, `AnimateDirective`
* `KeyBlock`
* `SelectorList`, `<svelte:whatever />`
* quote text in `Attribute` visitor
* tweak test logic to reduce false negatives
* fix
* fix
* add separate test suite
* fix
* more
* slightly nicer printing
* install from pkg.pr.new
* merge main
* bump
* fix
* remove any
* fix indentation
* replace TODO with a type error
* bump
* fix
* esrap@2
* lockfile
* try this
* regenerate
* add small comment
* fix test file
* ensure new lines at end of file
* common tests
* tests for A-nodes
* fix interface
* tests for B-nodes
* delete basic test
* tests for C-nodes
* combine css tests
* tests for E-nodes
* tests for H-nodes
* tests for I-nodes
* tests for K-nodes
* tests for L-nodes
* tests for N-nodes
* add todo
* remove other todo
* tests for O-nodes
* tests for P-nodes
* tests for R-nodes
* tests for S-nodes
* tests for T-nodes
* tests for U-nodes
* seperate css and svelte visitors for clarity
* fix failing test
* rename early tests
* fix const test
* fix svelte-element
* move block to css visitors
* fix css output
* fix #if indentation
* fix self closing tag problems
* use common method for attributes
* put attributes into multiple lines if too long
* fix new lines for #each:else
* fix svelte element new lines
* rmeove usless comments & fix playground
* improved formatting
* support formatting for a lot more nodes
* style
* fixes for formatting
* cleanup
* make typescript happy
* add formatting related test
* add docs
* changeset
* regenerate types
* fix self-closing tags
* fix bracket placement
* break length 50
* add support for additional comments
* remove abstract keyword
* strip out more typescript gubbins
---------
Co-authored-by: ComputerGuy <63362464+Ocean-OS@users.noreply.github.com>
Co-authored-by: Manuel Serret <mserret99@gmail.com>
Fixes#17236
* fix: generate correct code for simple destructurings
* add a test (existing one doesn't fail on main)
* adjust existing test so it fails on main
* slightly neater approach (with identical outcome)
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
This ensures that an animation does not run when the element is first transitioning in. Else the animation would mess with the transition (overriding its animation basically). Due to our test setup it's not testable but I veryfied it fixes#17181 (tested all reproductions in there)
It's possible that due to how new elements are inserted into the array that `effect.last` is wrong. We need to ensure it is really the last item to keep items properly connected to the graph.
Fixes#17201
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>