* fix: enable bound store props in runes mode components
* add some JSDoc, since it could be a headscratcher for future us
* make it clear that this is specifically about bindings
* skip intermediate value
* tweak other names too
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: internally wrap store subscribe in untrack
* lint
* Update packages/svelte/src/store/utils.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* Version Packages
* Update packages/svelte/CHANGELOG.md
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Closes#13493.
This PR allows the usage of getContext() inside $derived runes. Previously, you could use it, but only on init and not updates – and this inconsistency was unnecessary. We can make it work just like we do in other places.
I resisted this previously because it felt a bit wasteful, but I now think that there's really no way around this: Instead of only going upwards the tree while matching, for `:has` we go _down_ the tree to see what matches. More specifically, we're collecting the children of the current element and then check if one of those does match the selectors inside `:has`.
This makes the way the code works easier to reason about and also removes some boolean tracking we had to add for the previous approach.
Fixes#13779
Fixes#13717
There are two parts to this:
1. the parent selectors weren't passed along for the check inside `:has`, which in case of a leading combinator would mean it would always count as unused
2. In case if a selector like `x > y:has(z)`, the prior logic would correctly determine that for element `z` there's a match for the `:has` selector, by first checking its contents and then walking up the tree. But after it did that, it would try to walk up the tree once more, which is a) wasteful b) buggy because the tree walking mechanism would no longer be adjusted for the `:has` special case, resulting in false negatives. To fix that, the `:has` will return a new value from the function, signaling that it already fully checked the upper selectors, and so the function calling it will skip doing that.
- detect store mutations and not use `$derived` in that case, fixes#13723
- better detect `let x` that can be folded into `$derived`, fixes#13727
---------
Co-authored-by: ComputerGuy <63362464+Ocean-OS@users.noreply.github.com>
- correctly assign children snippet to default slot, fixes#13067
- allow `svelte:fragment` without `let:` directives to be rendered by `@render children()`, fixes#13066
* fix: avoid chromium issue with dispatching blur on element removal
* fix: avoid chromium issue with dispatching blur on element removal
* fix: avoid chromium issue with dispatching blur on element removal
* active effect too
* try/finally
* fix: moving deriveds during migration deletes part of the inserted code
* fix: use update instead of remove
* Update .changeset/cool-apes-confess.md
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
The other part of #13395
This implements scoping for selectors inside `:not(...)`. The approach is almot the same as for `:is/where(...)`.
This is a breaking change because people could've used `:not(.unknown)` with `.unknown` not appearing in the HTML, and so they need to do `:not(:global(.unknown))` instead.
While implementing it I also discovered a few bugs, which are fixed in this PR:
- `foo :is(bar baz)` wasn't properly handled. This selector can mean `foo bar baz` but it can also mean `bar foo baz` (super weird, but it is what it is). Since our current algorithm isn't suited for handling this, we just assume it matches and scope it. Worst case is we missed a prune
- `bar` in `:global(foo):is(bar)` was always marked as unused, even if it matched
The main part of #13395
This implements scoping for selectors inside `:has(...)`. The approach is to first descend into the contents of a `:has(...)` selector, then in case of a match, try to match the rest of the selector ignoring the `:has(...)` part. In other words, `.x:has(y)` is essentially treated as `x y` with `y` being matched first, then walking up the selector chain taking into account combinators.
This is a breaking change because people could've used `:has(.unknown)` with `.unknown` not appearing in the HTML, and so they need to do `:has(:global(.unknown))` instead
* fix: ensure effects destroy owned deriveds upon teardown
* add test
* make old test work
* tune
* tune
* Update packages/svelte/src/internal/client/runtime.js
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* do no rerun the each block when array change from empty to empty
* rename empty yo was_empty
* add test
* fix nullable array on SSR
* format
* rewrite
* chore: add changeset
---------
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
- make sure to not overfire before/afterUpdate
- make sure to not fire mutable sources when they were mutated
- only show deprecation warning when in runes mode to not clutter up console (this is in line with how we made it in other places)
fixes#13454
* fix: ensure set_text applies coercion to objects before diff
* lint
* feedback
* Update packages/svelte/src/internal/client/render.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
fixes#13270 by resetting the has_call boolean to false to style/class attributes, which means we're not creating a separate template effect for the attribute, instead they're added to the common template effect in which style/class directives are also added to later
Fix a bug where play/pause events may never be added to the media element. Also simplifies the logic by making it an effect instead of a render effect
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
* feat: migrate `svelte:self`
* chore: regenerate types
* fix: special case `<svelte:self></svelte:self>`
* chore: add special case to tests
* chore: add no filename test
* chore: better migration task message
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* chore: make filename an options object to futureproof it
* chore: simplify open tag `svelte:self`
* chore: simplify migration comment test
* chore: generate types
* chore: apply smart suggestion
* chore: changeset
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* feat: enable snippets to fill slots
This allows people to use snippets to fill slots. It is implemented in the same way the default slot interop is already implemented, by passing a boolean to the hidden `$$slots` object, and using that at runtime to determine the correct outcome. The impact on bundle size is neglible.
By enabling this, we can enhance our migration script to always transform slot usages (including `let:x` etc) to snippets. This wasn't possible before because we couldn't be sure if the other side was transformed to using render tags at the same time. This will be part of #13419. This is important because currently the migration script is transforming `<slot />` creations inside components, but since it's not touching its usage points the migration will make your app end up in a broken state which you have to finish by hand.
This is a reduced alternative to, and closes#11619, which was also enabling the other way around, but that is a) not as necessary and b) more likely to confuse people / break, because it only works if your render function has 0-1 arguments.
* unused
* ditto - annotation is redundant
* couple of drive-by consistency tweaks
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: allow combinator at start of nested CSS selector
Solved by moving the combinator positioning validation into the analysis phase
Fixes#13433
* highlight the combinator, not the start of the combinator
* fix
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* feat: fix accessors and support migration of accessors
* fix: exclude slots
* fix: remove call to proxy for accessors props
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* chore: add test for accessors
* chore: fix lint
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* feat: allow migration of `svelte:component`
* chore: simplify a lot (thanks @dummdidumm)
* chore: update output
* chore: use `next()` and `snip` instead of walking the AST
* fix: migrate nested `svelte:component`
* Update .changeset/good-vans-bake.md
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Fixes#13390
There's pruning logic in a different place where all unused selectors are commented out. If all selectors are unused, the whole prelude is commented out, resulting in invalid syntax. This is a case that shouldn't happen, therefore simplify the whole "is used" logic to only look at the prelude.
* fix: migrate events to be more inline with svelte 4
* fix: use function instead of action
* chore: generate types
* re-export event modifier substitutes
* chore: replace map with object
* fix: handle nullish values
* fix: use bubbler for delegated events
* chore: generate types
* chore: deprecate legacy stuff
* chore: damn type generations
* fix: implement bubble on props strategy
* chore: revert bubble as prop init but keep fix for restProps
* fix: use `passive` and `nonpassive` actions for `passive` and `nonpassive` modifiers
* chore: i swear i will setup a commit hook for generating types
* chore: update output
* tweak passive/nonpassive types to make them more compact and show up as deprecated
* make terminology more consistent with other places
* eat local, shop local, declare local
* unify name replacement stuff
* remove errant newline
* ensure modifier order is stable and matches svelte 4
* fix
* compute indent once
* joining without newlines seems to work better in common cases
* replace passive/nonpassive handlers in situ
* unused
* simplify
* simplify, remove errant spaces
* only import handlers when necessary
* changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: set strings as attributes, non-strings as properties if property exists
* simplify
* remove draggable from list, no longer needed
* in fact we dont need the lookup at all
* lint
* beef up test
* correctly SSR translate attribute
* fix: flip not accounting for scaled lengths
* zoom is uniform, one calculation will do
* stash width/height multipliers
* use var
* scale-first appears to work better?
* more robust zoom calculation
* changeset
---------
Co-authored-by: Etai Nadler <75544136+etainad008@users.noreply.github.com>
This was done previously to align with browser behavior, but the browser behavior actually only makes them passive on window/document/body. Since wheel events are not delegated, we can revert their passive-by-default setting. Closes#13318
For touchstart/touchmove we're not changing it because these events are delegated, which means they happen a lot more often on a target higher up the tree, which may cause jank.
#13225 did not fully fix the described issue: As soon as you have a child component, that child component's anchor will not be in the right ownerDocument yet, and so the logic falls down.
To fix that, we would need to move the ownerDocument check into the microtask - and that map check was mainly done to avoid just that. So instead I opted to simplify the code and just remove the map checks. According to my benchmarking (https://jsbench.me/3hm17l0bxl/1) this has no impact on performance assuming that you'll have cache hits roughly half the time - and even if you'd have much more cache hits, the performance loss is microscopic. Given that the default mode is to not inject styles, this will not be common anyway, so I favor removing that map.
* feat: provide guidance in browser console when logging `$state` objects
Wrap console.log/warn/error statements in DEV mode with a check whether or not they contain state objects. Closes#13123
This is an alternative or enhancement to #13070. Alternative if we deem it the better solution. Enhancement because it's not as robust as a custom formatter: We only check the top level of each entry (though we could maybe traverse a few levels), and if you're logging class instances, snapshot currently stops at the boundaries there and so you don't get snapshotted values for these (arguably this is a more general problem of $inspect and $state.snapshot), whereas with custom formatter it doesn't matter at which level you come across it.
* lint
* use normal warning mechanism, so we can link to docs etc
* add a few more methods
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: separate `template_effect` for dynamic class/style directive with dynamic attributes
* fix: only move to `init` if it `has_call`
* fix: initialize spread `needs_isolation` based on if there are directives with `has_call`
* fix: revert splitting templates and generate deriveds instead
* small tweaks
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: ensure function calls to identifiers are made reactive
* update test
* we have has_local at home
* add note
* make it a TODO
* Update .changeset/red-ladybugs-turn.md
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: escape more template-literal-related characters
Escape `{` at the start of a string, because it could be preceeded by a `$`, which in combination loads to the following characters being treated as a value
Fixes#13258
(used the opportunity to merge closely-related tests into one)
* sanitize template strings once assembled (#13263)
* only sanitize template quasis once assembled
* changeset
* remove old changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Our current validation was both too lax and too strict:
- too strict, because you can define a `$` variable in Svelte 4 if it's not at the top level
- too strict, because you can define `$`-prefixed function parameters, but not give the parameter the name `$`
- too lax, because you can define a `$`-prefixed variable if you're at least one level deep into a function. In runes mode, this should be an error
This PR aligns the behavior, ensures this isn't a breaking change in legacy anymore, and makes the validation in runes mode more strict
* fix: follow spec for `customElement` option
* tweak messages, add link to details that will be included on future docs site
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
This adds a new dev-time only `dev_effect_stack` variable, which executed effects are pushed to and eventually cleared out after everything's settled. If it doesn't settle however, i.e. you run into an infinite loop, the last ten effects are printed out so you get an idea where the error is coming from.
For proper source mapping I also had add location info to the generated effects.
Closes#13192
Fixes#13162
We were going from parentNode to parentNode but if something is a slot of a custom element we should first go to the assignedSlot or else the inside of the custom element will be skipped.
---------
Co-authored-by: Oscar Dominguez <dominguez.celada@gmail.com>
fixes#13194
We narrowed the allowed characters in #13057, but didn't take into account all possible (and for JavaScript identifiers allowed) unicode characters. This widens that, which also removes the accidental breaking change (because in Svelte 4 you were allowed to use these unicode characters).
Fixes#13203
The problem is that we were checking for NestingSelectors only in the selectors of the immediate child of the selectors. Since Nesting could be in selectors like :is or :where or :has that can also be nested i think we need to walk the selectors to find if there's a selector or not.
Fixes#13187. This ensures that we update the local fallback value in the case where the fallback is used so that we persist local changes to bindable props. Otherwise, any incoming changes from the outside will reset the incoming value back to the old fallback value.
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
Fixes#13146.
Sync effects are not possible with Svelte 5's push-pull system because they can make can break the reactive graph – which is also why we don't permit writes within a derived too. The same problem is occurring here, as inspect effects are run sync – they are actually happening as part of an existing derived – which means they're a bit like writes in a derived and can cause tearing to the reactive signal graph. To avoid this we can call flushSync just before invoking these effects, as that should ensure the graph is made consistent again.
Also another issue I found was that we don't "reset" the inspect_effects Set when we enter a derived – which we should as a derived can create it's own local state that should have no bearing on the parent inspect effect.
Add a new visitor to the "strip TS AST" logic. Strictly speaking this results in incorrect ASTs but esrap, our printer, just ignores them at those positions, so we can do that.
An alternative would be to adjust zimmerframe to be able to return something to say "delete this node"
Fixes#13173
In case of something like `foo = bar.map(...)`, foo would have ownership
of the array itself, while the individual items would have ownership
of the component that created the proxy. That means if we later do
`foo[0].baz = 42`, we could get a false-positive ownership violation,
since the two proxies are not connected to each other via the parent
relationship. For this reason, we need to widen the ownership of the
children upon access when we detect they are not connected.
Fixes#13137
Fixes#13174. Turns out that we we skipping this important work because we return true early – thus not connecting the unowned derived back to the reaction.
We have a `run_scripts` function which is invoked in case a template block contains a script tag, and that function replaces the script tags (so that they actually run). If such a script tag is first or last in the template, the replacement is not picked up by our `node.first_node/last_node` logic anymore, and so it contains a stale tag. That means on cleanup the remove logic fails. In the case of the referenced issue, it just runs past the script tag till the very end of the head, removing the just added style tag from the new page.
Fixes#13086
As a byproduct of #12239 some types were changed from being directly exported to indirectly exported. TypeScript is bad at following these types while generating d.ts files, so we can't do that. A check at the end of the types generation was added to prevent regressions in the future. Fixes#13128
Also removes the old types from `svelte/reactivity` which are deprecated for a while now.
part of #11502 - to close it completely, we also need to look at using and possibly implement heuristics within bundler plugins to give more details
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
Uses new dts-buddy capabilities and the corresponding tsconfig option to strip away types/properties (and their dependencies) that are marked with `@internal`
Also hides the legacy AST types from the output
To not clutter the exports, the AST types are moved into a namespace named AST
closes#12292
* fix: ensure signal status is set in legacy mode
fixes#13051
* add (failing) test
* alternative fix
* add changeset
* alternative fix
* add comment
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Dominic Gannaway <dg@domgan.com>
* simplify some parser logic, improve some compiler errors
* move logic into visitors
* more
* turns out we're doing a bunch of unnecessary work on closing tags
* tidy up
* changeset
* lint
This makes it possible to slow them down using dev tools, and overall ties the implementation more closely to WAAPI, which is good. Also fixes#12730 (all four cases, css, tick, css+tick, neither are now supported) and fixes#13019 (passed empty fallback object)
---------
Co-authored-by: Matei Trandafir <matei_trand@yahoo.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* fix: repair `href` attribute mismatches
The reasoning in #9662 turns out to be false: While it's true that the href would resolve to the same URL on the initial page, once you're doing a client-side navigation to a URL at a different depth, the relative path would now point to the wrong location. Therefore we need to repair href hydration mismatches
fixes https://github.com/sveltejs/kit/issues/12254
* remove test
* Revert "remove test"
This reverts commit fa43304329.
* fix test
* remove comment, since the rationale for skipping the attributes in question is covered by the one immediately below
* fix
* add test for <a> specifically
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* feat: allow non-synchronous legacy component instantiation
Add a new option to the legacy class component interface so that `flush_sync` can be omitted. Part of https://github.com/sveltejs/kit/issues/12248
* lint
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: ensure $inspect works with SvelteMap and SvelteSet
* build
* dev only
* dev only
* lint
* lint
* lint
* alternative
* Update packages/svelte/src/reactivity/map.js
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: more robust handling of var declarations
- fixes#12807: state declared with var is now retrieved using a new `safe_get` function, which works like `get` but checks for undefined
- fixes#12900: ensure we're not creating another new scope for block statements of function declarations, which resulted in var declarations getting "swallowed" (because they were hoisted to the function declaration scope and never seen by our logic)
* simplify
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
The backing store variable of a $store read could be a variable that itself needs a transformer, which is why we need to make accessing the reads lazy
fixes#12859
* breaking: deprecate `context="module"` in favor of `module`
Also reserve a few attributes, which we may or may not use in the future
closes#12637
* fix tests
* one more
* add svelte package to the root so eslint and prettier can use it
* tweak messages
* warn on unknown attributes
* regenerate
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* feat: adds $state.link rune
* add tests
* types
* docs
* debugger
* lint
* Update .changeset/friendly-rice-confess.md
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* Update packages/svelte/src/compiler/phases/2-analyze/index.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* feedback
* feedback
* feedback
* feedback
* rename link_state to linked_state for grammatical consistency
* oops, victim of find-replace
* no need to store linked_value if setting
* simplify tests
* test behaviour of objects
* update docs
* copy
* more direct example that shows unlinking and relinking
* add callback argument support
* fix
* tidy up
* document callback
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
We need to allow mixing those within custom element components because in a future version of Svelte where we remove the Svelte-version of slots, we'll preserve slots as-is, and people should use those within their components. At the same time they should be able to make use of snippets for reusable blocks of code.
Also document that you should continue using slots within custom elements.
closes#12892
* feat: treat tag with `[` as a component, even if lowercase
* chore: simpler regex
Co-authored-by: Conduitry <git@chor.date>
* feat: error on invalid component name
* fix: fully revert dot notation test
* tweak error message
---------
Co-authored-by: Conduitry <git@chor.date>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* step one
* WIP
* more
* fix
* collapse sequential sibling calls
* working
* working but messy
* tidy up
* unused
* tweak
* tweak
* tidy
* tweak
* tweak
* revert
* changeset
* Update packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* revert this bit
* align
* comments
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* chore: use closures for state proxies
* use variables
* early return
* tidy up
* move ownership stuff into separate object
* put original value directly on STATE_SYMBOL
* rename
* tidy up
* tidy
* tweak
* fix
* remove is_frozen check
* remove `$state.is`
* avoid mutations
* tweak
* changesets
* changeset
* changeset
* regenerate
* add comment
* add note
* add test
* fix: improve createRawSnippet types
Add cleanup type to return value of setup function
* changeset
---------
Co-authored-by: Rich Harris <hello@rich-harris.dev>
* fix: avoid throwing `store_invalid_subscription_module` for runes
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
* move test to the validator suite, which is faster
---------
Co-authored-by: Paolo Ricciuti <ricciutipaolo@gmail.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* analyse exports before walking
* more
* another
* this is unused
* move stuff/tidy up
* this appears to be unnecessary
* this is all unnecessary
* simplify
* simplify
* simplify
* simplify
* move more stuff over
* changeset
* unused
* separate reassignment from mutation
* regenerate
* lint
* feat: add compiler error when encountering a $-prefixed store value outside a .svelte file
* add fromState/toState APIs
* another test, update types
* rename fromState to toStore, and toState to fromStore
* docs
* add docs
* separate client/server entry points for svelte/store
* fix: provide more hydration mismatch coverage
* tweak
* add test for safari borking stuff
* fix
* fix windows test
* failing test
* oops
* revert playground changes
* simplify
* template content hydration logic should really be separate from reset logic
* actually the test is incorrect, and now i cant seem to recreate what i saw before... hmm
* update comment to no longer mention templates
* failing test
* delete test for now
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* speed up exclude_from_object
* changeset
* convert prop names to string at compile time
* faster still
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* chore: add warning for derived self referencin
* update build
* address feedback
* address feedback
* build
* messages shouldn't end with a period
* simplify test
* regenerate
* newlines are free
* no need to export this, we can move it closer to where it's used
* fix double negative
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* simplify
* fix/simplify
* fix/simplify
* start getting a grip of this mess
* tidy up
* more
* more
* more
* tidy up
* make things a bit less weird
* tweak
* more
* more
* add once once
* consolidate event handling code
* some progress. man, this stuff is entangled
* more
* tidy up
* simplify
* simplify
* more
* fix
* fix test names
* fix a bug
* tidy up
* changeset
* simplify
* regenerate
* tidy up
* tidy up
* tidy up
* simplify
* the module declaration case is already accounted for, above
* simplify/document
* typo
* "hoistable" is a misnomer
* hoist non_hoistable, rename
* more typos
* tweak
* regenerate
* fix: add css hash to custom element rendered with `svelte:element`
* simplify
* skip arg where possible
* drive-by improvements — remove some unnecessary arguments where possible
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* feat: function called as tagged template literal is reactively called
Co-authored-by: Oscar Dominguez <dominguez.celada@gmail.com>
* chore: re-organize import of visitors
* simplify
---------
Co-authored-by: Oscar Dominguez <dominguez.celada@gmail.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* start refactoring client transform visitor code
* more
* more
* more
* more
* more
* more
* more
* more
* more
* more
* more
* more
* more
* more
* more
* tweak
* painful
* more
* simplify
* more
* more
* more
* more
* more
* tidy up
* changeset
* fix: allow nested `<dt>`/`<dd>` elements if they are within a `<dl>` element
This introduces a resets array, which means descendants that are forbidden are allowed again, if an element within the resets array is encountered between the tag and the forbidden descendant
fixes#12676
* better name
* chore: perf tweaks for actions/styles/classes
- check if we really need to add/remove the class (calling `includes` first is cheaper than always setting/removing it)
- check if we really need to update a style (calling `getPropertyValue/setProperty` is expensive)
- check if we should call the action's update function (this is not only a perf tweak but also a correctness fix)
closes#12652
* changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* start moving visitors into separate modules
* remove unused code
* more
* more
* tidy up
* more
* more
* more
* more
* more
* more
* more
* more
* more
* more
* more
* alphabetize
* more
* fix
* more
* more
* consolidate
* more
* more
* more
* more
* more
* more
* more
* tweak
* more
* more
* more
* more
* more
* more
* more
* more
* more
* more
* jfc what are we doing here
* more
* bizarre
* more
* more
* more
* more
* more
* more
* tidy
* one down
* dont merge
* hmm
* DRY
* more
* more
* tidy up
* tidy up
* add changeset, as this should have its own release
* tidy up
* oh i should probably hit save
* feat: make `<svelte:component>` unnecessary in runes mode
In Svelte 4, writing `<Component />` meant that the component instance is static. If you made the variable `Component` a reactive state variable and updated the component value, the component would not be reinstantiated with the new value - you had to use `<svelte:component>` for that. One reason was that having a dynamic component was more overhead, which is no longer the case in Svelte 5. We can therefore reduce the potential API surface area (by maybe deprecating `<svelte:component>` in the future) by allowing Svelte to recognize when a component variable is potentially dynamic. It turned out that this was already mostly the case. This PR fixes one case where it wasn't, and fixes another where this was wrongfully applied in legacy mode.
* we already have this function
* add interactive demos
* changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
language tools has to type its own shape for backwards compatibility, and it currently doesn't include the `$on` and `$set` methods, which means without widening the type as done here you would get a "this shape is not accepted" type error when passing it to `ComponentProps`
closes#12627
Closes#12643
Very weird behaviour from the draggable setter...if you set element.draggable="false" it will actually set draggable to true (the boolean).
* better code generation for slot props in SSR
* simplify
* remove getters mechanism from server compiler
* changeset
* no need to use getters in SSR mode
* fix comment
* add state.getters as alternative to binding.expression
* on second thoughts
* fix
* first of many
* couple more
* regenerate types
* more
* another
* more
* another
* another
* another
* remove binding.expression from client-side code
* tweak
* last one
* comment
* regenerate types
* add a changeset
* small tidy up
* simplify
* simplify
* simplify and fix
* simplify
* fix: ensure dynamic event handlers are wrapped in a derived
* fix test
* feedback
* more feedback
* address feedback
* we have .svelte.js files
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: bail-out of hydrating head if no anchor is found
* add failing test
* fix
* fix comment
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* add invalid_default_snippet error message
* fix: improve validation error that occurs when using `{@render ...}` to render default slotted content
* cheeky hack to keep treeshakeability until we can nuke this validation altogether
Previously, if transitions/animations were playing in quick succession, overlapping each other, it could have disastrous outcomes, leading to elements jumping all over the place.
This PR gets that into much better state (not completely fixed, but close) by applying a few fixes:
- destructure style object from `getComputedStyles`, because it's a live object with getters and we're interested in the fixed values at the beginning
- `unfix` for animations didn't reset the transition styles
- don't apply `fix` when we detect already-running animations on the element. That means it's already away from its original position, and doesn't need fixing. Worse, applying an absolute position can lead to the element jumping to the top left if the running animation also applies a transition style - those take precedence over the one we would apply
fixes#10252
* fix: properly assign trailing comments
Trailing comments were added even if they started before the node end, which violates the definition of trailing comments.
This fixes that, with the consequence that some comments no longer show up in the AST at all. Previously they were stuffed _somewhere_, but arguably at the wrong positions. For example the last comment in a function body got assigned as a trailing comma for the body, which is wrong, because the body ends _after_ the comma.
The special case is comments at the end of an expression tag - they are added even if there are multiple, and they are added regardless of whether they are separated by newlines or not. This ensures the expression tag end is calculated correctly.
Fixes#12466
* support multiple trailing comments after last statement in a body
* simplify, handle object and array expressions
* parse `foo={bar}` attribute as `value: { type: 'ExpressionTag', .. }` (i.e. don't wrap in an array)
* warn on quoted single-expression-attributes
* breaking: warn on quotes single-expression attributes in runes mode
In a future version, that will mean things are getting stringified, which is a departure from how things work today, therefore a warning first.
Related to #7925
* Update .changeset/plenty-items-build.md
* Apply suggestions from code review
* missed a spot
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
The head hydration anchor didn't update after hydrating the contents of one `<svelte:head>` element, which meant subsequent `<svelte:head>` elements would always start at the beginning of the head. This PR fixes that. The test was updated such that the shape of each `<svelte:head>` content is sufficiently different to throw an error if this wasn't fixed.
fixes#12458
* fix: ensure `$state.snapshot` never errors
Snapshotting can error on un-cloneable objects. It's not practical to error in this case; often there's no way out of this for users, so it makes sense to return the original value in that case, and warn in dev mode about it.
closes#12438
* lint
* single warning per snapshot call, list affected properties
* lint
* lint
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: ensure previous transitions are properly aborted
- nullify options when the transition is aborted. This ensures a change in options is reflected the next time, else it would stick around indefinetly
- abort previous intro (if exists) when new intro plays (same for outro)
fixes#11372
* add a test
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
When Vite calls `hot.accept`, it passes the wrapped component, which means we're passing the HMR wrapper along as the new component. Avoid that by maintaining a reference to the original component.
* feat: add ability to ignore warnings through compiler option
Some people want to disable certain warnings for their whole application without having to add svelte-ignore comments everywhere. This new option makes that possible.
closes#9188
part of https://github.com/sveltejs/language-tools/issues/650
* make it a function
* singular
* warningFilter
* make internal filter non-nullable
* Update .changeset/little-seals-reflect.md
* filter_warning -> warning_filter, for symmetry with public option
* fix
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
We've marked several methods used for walking the DOM with a `__NO_SIDE_EFFECTS__` comment. That was good historically, because we didn't need those kept around if its results were unused, but since the hydration changes in #12335 this actually introduces a bug: Because that PR now relies on the hydration nodes being correct due to walking the DOM, tree-shaking unused variables/calls results in the walk being incorrect, leading to bugs
Fixes#12422
* fix: prevent whitespaces merging across component boundaries
The logic that was there didn't take components into account. The underlying problem is that the parent isn't properly set to `Fragment` in all cases because of nested `visit` calls we do in some places.
Fixes#12447
* update test
This enhances our "variable was mutated" detection to also recognize that `foo` in `[foo[1]] = [..]` was mutated. This allows us to be more granular about detecting mutations to each expressions in legacy mode, which fixes#12169
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
* move cloning logic into new file, use structuredClone, add tests
* changeset
* breaking
* tweak
* use same cloning approach between server and client
* get types mostly working
* fix type error that popped up
* cheeky hack
* we no longer need deep_snapshot
* shallow copy state when freezing
* throw if argument is a state proxy
* docs
* regenerate
The previous validation for checking if slots with let directives were rendered with `{@render children(...)}` had false positives
- threw an error even if the other side didn't make use of the arguments, i.e. wasn't actually using a let directive
- didn't check that the rendered snippet actually was the children property
This fixes the validation by only applying it to children render tags, and by adding the slot to `$$slots.default` instead of `$$props.children` in more cases (when it's using `<svelte:fragment>` or `let:` directives, which both mean you're using old slot syntax)
Fixes#12414
* fix: cache call expressions in render tag arguments
Ensure that they're called at most once per change, not once per access within the snippet
fixes#12187
* leverage state
* types
* fix
* fix: properly delay intro transitions
WAAPI applies the styles of a delayed animation only when that animation starts. In the case of fade-in transitions that means the element is visible, then goes invisible and fades in. Fix that by never applying a delay on intro transitions, instead add keyframes of the initial state for the duration of the delay.
Fixes#10876
* fix bug, make test pass
* make test more selfcontained, test outro delay aswell and add functionality for that in animation-helpers
* lint
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: more event handling tweaks
- ensure we only have a single document listener per event+runtime
- add `<svelte:body>` listeners to `before_init` similar to the document/window elements
- move some code into `events.js` where it belongs
* add a counter
* changeset
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* feat: runtime dev warn for mismatched `@html`
* fix: limit the length of the client value shown in the error
* put logic inside a helper
* remove $.hash, no longer needed
* fix
* tweak
* update changeset
* fix
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* separated url-search params and url classes and added more tests
* making URL aware of SvelteURLSearchParams changes so they are in sync
* added changeset
* generated types
* bail out if url.sp and SvelteSp are already in sync
* sync search on searchParams change because of how node18 handles it
* use ts-expect-error instead of ts-ignore
* remove a bit of indirection
* tweak
* fix
* regenerate types
* short-circuit in both directions
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>