fixes#15543
No test because this is a one-liner in a stable part of the code-base, also it can only happen within legacy mode when using bindings which is not getting any new updates at this point
* fix: prevent state runes from being called with spread
* prevent spread arguments for all runes except $inspect
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: allow get_proxied_value to return original value when error
closes#15546
* Update packages/svelte/src/internal/client/proxy.js
---------
Co-authored-by: Rich Harris <hello@rich-harris.dev>
* feat: make deriveds writable
* add optimistic UI example
* add note to when-not-to-use-effect
* add section on deep reactivity
* root-relative URL
* use hash URL
* mention const
* make handler async, move into script block
* Add failing JSDoc property svelte-migrate conversion tests
* Add further test case and remove default value in JSDoc output
* Look for inlined JSDoc comments after a hyphen
* Add changeset
* move parent property onto Signal
* don't self-invalidate when updating a source create inside current reaction
* lazily create deep state with parent reaction
* no need to push_derived_source with mutable_state, as it never coexists with $.derived
* reduce indirection
* remove state_unsafe_local_read error
* changeset
* tests
* fix test
* inelegant fix
* remove arg
* tweak
* some progress
* more
* tidy up
* parent -> p
* tmp
* alternative approach
* tidy up
* reduce diff size
* more
* update comment
Fixes#14072
`:has()` was matching only against descendants or siblings, but not sibling's descendants. This makes the logic be able to go forward or backwards, simplifying a lot of cases along the way.
For instance, specifying a tree-structural pseudo-class to
`::view-transition-new` should still constitute a valid global-like
selector.
Fixes#15312
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* ix: ensure transient writes to tracked parent effects works as expected
* lint
* format test
* tweak changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Fixes#14579
Although this isn't 100% correct because there's no `group` attribute, there's no better way to make people have components' props just be `HTMLInputAttributes` and allow them to reference `group`
* fix: on teardown, use the last known value for the signal before the se
* fix: on teardown, use the last known value for the signal before the se
* fix: on teardown, use the last known value for the signal before the se
* fix: on teardown, use the last known value for the signal before the se
* fix: on teardown, use the last known value for the signal before the se
* Update packages/svelte/src/internal/client/reactivity/props.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* Update packages/svelte/src/internal/client/reactivity/props.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* Update packages/svelte/src/internal/client/reactivity/props.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* lint
* lint
* lint
* Update .changeset/sharp-elephants-invite.md
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix null and warning for local handlers
* test
* changeset
* treat `let handler = () => {...}` the same as `function handler() {...}`
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* add style attribute when needed
* set_style()
* to_style()
* remove `style=""`
* use cssTest for perfs
* base test
* test
* changeset
* revert dom.style.cssText
* format name
* use style.cssText + adapt test
* Apply suggestions from code review
suggestions from dummdidumm
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix priority
* lint
* yawn
* update test
* we can simplify some stuff now
* simplify
* more
* simplify some more
* more
* more
* more
* more
* more
* remove continue
* tweak
* tweak
* tweak
* skip hash argument where possible
* tweak
* tweak
* tweak
* tweak
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* style must be set via set_attribute
* test
* changeset
* add empty string and null in test
* explanatory comment
* this is now redundant, set_attribute takes care of it
* drive-by
* tweak changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* set_attributes for <svelte:element>
* changeset
* Update .changeset/wise-hats-wonder.md
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* add changeset
* remove `chore` changeset — no need for non-user-facing changes to appear in changelog
* Update packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js
* determine element traits inside set_attributes
* unused
* stash lookup
---------
Co-authored-by: adiguba <frederic.martini@gmail.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix: correctly set `is_updating` before flushing root effects
* rename for consistency with update_effect
* use var
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
This ensures someone like Astro can render multiple islands and the unique ids produced in them are able to be deduplicated
---------
Co-authored-by: Hugos68 <hugokorteapple@gmail.com>
Co-authored-by: paoloricciuti <ricciutipaolo@gmail.com>
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
* fix: catch error on @const tag in svelte:boundary
* changeset
* edit changeset
* test
* fix
* rollback
* simpler way to do that
* rollback
* roolback again
---------
Co-authored-by: paoloricciuti <ricciutipaolo@gmail.com>
* this appears to be unnecessary
* DRY out
* this doesnt appear to do anything useful
* simplify
* remove unused if block
* simplify, make non-recursive
* unused
* DRY
* simplify
* tidy up
* simplify
* changeset
* unused
* Revert "changeset"
This reverts commit 946e00dcf7.
* make flush_sync non-recursive
* fix flushSync types
* fix
* unused
* simplify
* tidy up
* tidy up
* present unnecessary microtasks, avoid flushing if no function provided
* simplify
* no `?? ''` on some expressions
* changeset
* delete operator returns boolean
* inverted conditions are a lil confusing
* no need for else after return
* simplify condition
* may as well add special handling for undefined while we're here
* use normal string literal when there are no values
* omit assignment when there is no text content
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: `muted` reactive without `bind` and select/autofocus attributes working with function calls
Co-authored-by: Joel Howse <joel@helicalco.com>
* chore: add comments
---------
Co-authored-by: Joel Howse <joel@helicalco.com>
They DOM could've been updated already by the time the event bubbling logic is reached, so the target element itself could not be notified of the event because it is marked as disabled. But the target could not have been disabled because it emits the event in the first place, so we emit regardless.
No test because not reproducible in jsdom environment.
Fixes#15256
This was the result of a `@ts-expect-error` silencing other type errors, which lead to this creeping in. This changes it so that the object is fully set, so we'll get type errors when new properties need to be added
fixes#15284
- `$derived` can contain `$state` declarations so we cannot ignore them, so this reverts #14533
- instead, we add equality checks to not do this expensive work unnecessarily
- this also adds a render effect similar to the class ownership addition when it detects a getter on a POJO during ownership addition
fixes#15164
* fix: when an unowned derived is tracked again, remove unowned flag
* fix: when an unowned derived is tracked again, remove unowned flag
* test case
* test case
* cleanup unused logic
* simplify
* simplify
* simplify
* simplify
* add test
* fix other issue
* back to original plan
* Apply suggestions from code review
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix: ensure custom element updates don't run in hydration mode
When a custom element is created before Svelte hydration kicks in, it will scaffold itself, using the properties given via attributes.
Now when a custom element property is set during Svelte's hydration, the Svelte custom element component could run logic like updating an each block. Without turning off hydration mode during that time, the update would try to pick up existing element nodes (because it thinks they must be there because of hydration mode), and crash.
No test because it would require a setup where we can ensure the element is scaffolded before hydration runs.
Fixes#15213
* changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Avoid going through the `element.value = element.__value = newValue` condition because `__value` is actually how Lit stores the current value on the element, and messing with that would break things: Lit would think the value hasn't changed (because `__value` is already set to the new value by us) and doesn't fire an update.
fixes#15194
* fix: ensure tracking returns true, even if in unowned
* fix: ensure tracking returns true, even if in unowned
* Update packages/svelte/tests/runtime-runes/samples/effect-tracking-unowned/main.svelte
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
`slot` is treated as a regular prop if it is not used directly inside another component, but we were running validations on such regular props that should only be run on real slots.
Fixes#15125
Instead of doing ownership addition at each `getContext` call site, we do it once as the `setContext` call site and make the state basically global.
- avoids potential false positives in edge cases
- makes the whole thing more performant, especially around things like calling `getContext` inside a list item component
- false negatives are unlikely from this
fixes#15072
Fixes#14910
The issue occurs only when :has() targets at a component's root element and because include_self is false.
I came to the conclusion that this is the same case as :root:has(.scoped).
Fixes#15027 and fixes#14995
When the target element is inside a block or component, get_following_sibling_elements was looking only for sibling elements after the block/component. This PR fixes it by starting the search from the begging of the block/component and skipping nodes that go before the target element.
* fix: ensure signal write invalidation within effects is persistent
* fix: ensure signal write invalidation within effects is persistent
* fix: ensure signal write invalidation within effects is persistent
* address feedback
* fix: Make Tween duration 0 set current to target immediately
* Run prettier on test file
* tweak
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
... if it's not followed by another newline, according to the spec
Fixes#14767
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
* fix: ensure unowned deriveds correctly get re-linked to the graph
* fix: ensure unowned deriveds correctly get re-linked to the graph
* fix: ensure unowned deriveds correctly get re-linked to the graph
* add test
* add test
* cleaner apporach
* cleaner apporach
* cleaner apporach
* cleaner apporach
* handle invalid expression inside each key
* handle invalid expression inside each expression
* handle invalid expression inside await block
* handle "in the middle of typing" components with starting lowercase and dot at the end
* changeset
* fix: make `defaultValue` work with spread
* chore: apply suggestions from review
* tweak
* only stash defaults when relevant
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: avoid mutation validation for invalidate_inner_signals
* add test
* Update packages/svelte/src/internal/client/runtime.js
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
fixes#14532
This removes the `reactive_declaration_non_reactive_property` warning altogether. The first version caused many false positives at compile time. The refined runtime version (introduced in #14192) was hoped to fix this, but it turns out we now get loads of false positives at runtime.
fixes#14391
In #13337 the "when to set as a property" logic for custom elements was adjusted. A bug was introduced during this, and it consists of several parts, of which the latter I'm not sure what's the best solution, hence opening this to discuss.
The problem is that during set_custom_element_data, get_setters is the only check done to differentiate between setting the value as a prop (has a setter) or as an attribute (doesn't have a setter).
The solution is to take into account whether or not the custom element is already registered, and defer getting (and caching) its setters until then. Instead, fall back to a "an object is always set as a prop" heuristic.
* chore: provide links to documentation for errors/warnings
closes#11305
* changeset
* fix most of the tests
* fix mutations messing with nodes between runs
* more concise
* more test fixes
* last one
* feat: add Spring class
* add some docs, Spring.of static method
* add Tween class
* lint
* preserveMomentum in milliseconds
* deprecate tweened
* changeset
* wrestle with types
* more consolidation
* flesh out the distinction a bit more, deprecate `subscribe`
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
* chore: make if blocks dead code eliminable
* chore: make if blocks dead code eliminable
* chore: make if blocks dead code eliminable
* address feedback
* address feedback
* prettier
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
When the `value` or `checked` attribute of an input or the contents of a textarea were static, setting the `defaulValue/defaultChecked` property caused the latter to take precedence over the former. This is due to how we transform the code: If the value is static, we put it onto
* tests
* typings
* implement for defaultValue/defaultChecked on inputs
* docs (draft)
* selected
* fix test
* remove
* tweak
* changeset
* untrack reads, they could be inside an effect
* Apply suggestions from code review
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* handle select reset case
* handle reset case specifically: use different props/queries in that case
* enhance test
* fix
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: better error messages for invalid HTML trees
closes#13331
* fix test
* more concise
* tweak
* tweak messages
* adjust tests
* tweak message slightly, so it doesn't sound like the bad element is the one we're currently encountering
* put locations in generated message
* tidy up
* consistency
* fix
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* add failing test for #14268
* simplify
* proxify values when using ||=, &&= and ??= assignment operators
* proxify values assigned to private state fields
* changeset
* fix
* fix
* add warning
* update test
* fix: don't try to add owners to non-`$state` class fields
`$state.raw` and `$derived(.by)` will not have a state symbol on them, potentially causing a disastrous amount of traversal to potentially not find any state symbol. So it's better to not traverse them.
Potentially someone could create a `$state` while creating `$state.raw` or inside a `$derived.by`, but that feels so much of an edge case that it doesn't warrant a perf hit for the common case.
Fixes#14491
* for bind:, too
* fix: ensure SvelteDate cached methods have no reactive context
* fix: ensure SvelteDate cached methods have no reactive context
* fix
* lint
* use active reaction at time of instance creation
* tweak changeset
* Update packages/svelte/src/internal/client/dom/elements/bindings/shared.js
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
---------
Co-authored-by: Dominic Gannaway <dg@domgan.com>
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
* turn `reactive_declaration_non_reactive_property` into a runtime warning
* ignore warning
* Update packages/svelte/src/internal/client/reactivity/effects.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* Update packages/svelte/src/internal/client/runtime.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix
* test
* changeset
* Update .changeset/witty-turtles-bake.md
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* add some details
* check
* regenerate
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* Fix `$.update` and `$.update_pre` for bigints
* resolve conflicts
* fix some things
* fix thing i definitely didn't just break
* hopefully this will fix it
* fix formatting
* simplify
* style consistency
* simplify
* changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: upgrade to esm-env 1.2.1 to fix issues with non-Vite setups
* fix (albeit with annoying warnings)
* bundle with conditions to silence noise
* production is probably better
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
fixes#14466
The logic introduced in #14395 was flawed - not every text or expression outside the template is the child of an attribute. This turns it around: We know that every child of a fragment is inside the template, so we ignore all text/expression tags that are not child of a fragment
Fixes#14399
Add a mechanism to connect render tags to snippets to know where to walk when coming across render tags
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
fixes#14439
This bug was introduced in #13642 because setting the input to null means the equality check ("is the input different") fails if you set the value to null
Also fixes#14441 - this bug was present for a long time, and the reason is the same as for the other bug: The equality check always returns "yes this is the same" if the value is undefined initially. The fix is similar; we need to initialize the input to something that can never be equal to whatever value is passed
This reverts #13255 / #13158, and helps with the validation error part of #14120
If you would have a component like this...
```svelte
<td>hi there</td>
```
...and then render it on the server via our `render` function like this:
```js
const result = render(Main);
```
...then right now you get an error saying that `td` is not valid at this position. But that doesn't seem right, because we should give people the benefit of the doubt: It may very well be that someone renders such a component and then correctly puts it into a `tr` tag themselves on the server (another example is rendering a full html document like in #14120).
All the other validation where there's a known parent (X not valid inside Y) is untouched by this.
Doing this as cleanup prior to tackling #13331
* fix: always use set for private identifiers
* we can simplify this further - no need to check the value was transformed, since the outcome of not returning immediately is the same but with extra steps
* add explanatory note
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
through #14363 I noticed our `export default` validation wasn't quite right:
- missed checking for derived/state exports
- the "cannot have a default export" error was only thrown if you did `export default` from the instance script, but it shouldn't matter from which component part you export it; it's never ok
* fix: ensure internal cloning can work circular values
* better fixc
* 'original' feels slightly clearer than 'json_instance'
* use an optional parameter, so we can omit it in most cases
* Update packages/svelte/src/internal/shared/clone.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
The detection whether or not props are writable is buggy; it doesn't take into account the case when instantiating components via `mount` or legacy-`new`
Fixes#14161
This posed an interesting question: What to do about (non-)`bind:`able properties? The answer I arrived on was: Treat it as if everything that _can_ be bound _is_ treated as bound, and everything else as readonly. In other words, if you're reassigning a prop, it will diverge from the passed in props if it's not bindable or not set in the parent, otherwise it will mutate the passed in props. I think that makes the most sense, given that you can't control this behavior from the outside.
* fix: avoid marking subtree as dynamic for inlined attributes
* fix: i'm a silly goose 🪿
* chore: refactor `is_inlinable_expression` to accept the attribute
* feat: inline dom expression too
* fix: special case literals with `"` in it and fix standalone case
* chore: simpler check first
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
* typo
* add more stuff to snapshot test
* simplify/speedup by doing the work once, during analysis
* simplify
* simplify - no reason these cases should prevent inlining
* return template
* name is incorrect
* name is incorrect
* fix escaping
* no longer necessary
* remove obsolete description
* better concatenation
* fix test
* do the work at runtime
* fix another thing
* tidy
* tidy up
* simplify
* simplify
* fix
* note to self
* another
* simplify
* more accurate name
* simplify
* simplify
* explain what is happening
* tidy up
* simplify
* better inlining
* update test
* colocate some code
* better inlining
* use attribute metadata
* Update packages/svelte/src/compiler/phases/2-analyze/visitors/Identifier.js
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
* Apply suggestions from code review
---------
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
We previously marked all `:root` selectors as global-like, which excempted them from further analysis. This causes problems:
- things like `:not(...)` are never visited and therefore never marked as used -> we gotta do that directly when coming across this
- `:has(...)` was never visited, too. Just marking it as used is not enough though, because we might need to scope its contents
Therefore the logic is enhanced to account for these special cases. Fixes#14118
While fixing this I cleaned up some inconsistencies in what we mark as global. This simplified code and fixed some adjacent bugs, which conindicentally also fixes#14189
* fix: consider static attributes that are inlined in the template
* fix: use `is_inlinable_expression`
* fix: move check for inlinable expression as last
* fix: simplify and correct
* chore: accept single node in `is_inlinable_expression`
* chore: update comment
* chore: add snapshots for non static nodes