Skip to content

Conversation

@trueadm
Copy link
Contributor

@trueadm trueadm commented Dec 10, 2024

Closes #14630.

We can actually restore selection on an input that has bind:value and the input differs because of a function binding accessor. In fact, we can re-use the restoration logic implementation from React.

Unfortunately, JSDOM doesn't seem to emulate selection changes when the value changes, so I didn't come up with a test.

@changeset-bot
Copy link

changeset-bot bot commented Dec 10, 2024

🦋 Changeset detected

Latest commit: 7747876

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

Playground

pnpm add https://pkg.pr.new/svelte@14649

Copy link
Member

@dummdidumm dummdidumm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

@trueadm trueadm merged commit 9cfd2e2 into main Dec 10, 2024
11 checks passed
@trueadm trueadm deleted the restore-input-selection branch December 10, 2024 12:44
@github-actions github-actions bot mentioned this pull request Dec 10, 2024
fabhari added a commit to fabhari/svelte that referenced this pull request Aug 19, 2025
Old Fix: Restore input binding selection position (sveltejs#14649)
Current Fix: Remove unnecessary cursor manipulation as the presence of runes no longer requires special handling.
Rich-Harris added a commit that referenced this pull request Aug 25, 2025
* fix : remove cursor manipulation for input bindings

Old Fix: Restore input binding selection position (#14649)
Current Fix: Remove unnecessary cursor manipulation as the presence of runes no longer requires special handling.

* fix : add change set  to my previous commit

* Revert "fix : add change set  to my previous commit"

This reverts commit 6ca8ef3.

* fix: revert previous changeset added new  to fix lint errors

* chore : resolve lint error to fix pipeline issue

* Revert "fix: revert previous changeset added new  to fix lint errors"

This reverts commit 9109494.

* fix: input binding to handle code in a synchronous manner

Introduced Promise.resolve to ensure that the 'set' operation completes before the 'get' operation Minimizing update delays.

* Fix: resolve cursor jumps and change sets

* better fix

* test

* changeset

* simplify

* failing test

* gah we can't fix the input in an effect, need to do it here, but after a tick so that changes have been flushed through each blocks

* add explanatory comment

* fix test

* this seems to work?

---------

Co-authored-by: Hariharan Srinivasan <[email protected]>
Co-authored-by: Rich Harris <[email protected]>
dummdidumm added a commit that referenced this pull request Oct 10, 2025
If cursor was at end and new input is longer, move cursor to new end

No test because not possible to reproduce using our test setup.

Follow-up to #14649, helps with #16577
Rich-Harris pushed a commit that referenced this pull request Oct 13, 2025
If cursor was at end and new input is longer, move cursor to new end

No test because not possible to reproduce using our test setup.

Follow-up to #14649, helps with #16577
Rich-Harris added a commit that referenced this pull request Oct 14, 2025
* runtime-first approach

* revert these

* type safety, lint

* fix: better input cursor restoration for `bind:value` (#16925)

If cursor was at end and new input is longer, move cursor to new end

No test because not possible to reproduce using our test setup.

Follow-up to #14649, helps with #16577

* Version Packages (#16920)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* docs: await no longer need pending (#16900)

* docs: link to custom renderer issue in Svelte Native discussion (#16896)

* fix code block (#16937)

Updated code block syntax from Svelte to JavaScript for clarity.

* fix: unset context on stale promises (#16935)

* fix: unset context on stale promises

When a stale promise is rejected in `async_derived`, and the promise eventually resolves, `d.resolve` will be noop and `d.promise.then(handler, ...)` will never run. That in turns means any restored context (via `(await save(..))()`) will never be unset. We have to handle this case and unset the context to prevent errors such as false-positive state mutation errors

* fix: unset context on stale promises (slightly different approach) (#16936)

* slightly different approach to #16935

* move unset_context call

* get rid of logs

---------

Co-authored-by: Rich Harris <[email protected]>

* fix: svg `radialGradient` `fr` attribute missing in types (#16943)

* fix(svg radialGradient): fr attribute missing in types

* chore: add changeset

* Version Packages (#16940)

* Version Packages

* Update packages/svelte/CHANGELOG.md

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Rich Harris <[email protected]>

* chore: simplify `batch.apply()` (#16945)

* chore: simplify `batch.apply()`

* belt and braces

* note to self

* unused

* fix: don't rerun async effects unnecessarily (#16944)

Since #16866, when an async effect runs multiple times, we rebase older batches and rerun those effects. This can have unintended consequences: In a case where an async effect only depends on a single source, and that single source was updated in a later batch, we know that we don't need to / should not rerun the older batch.

This PR makes it so: We collect all the sources of older batches that are not part of the current batch that just committed, and then only mark those async effects as dirty which depend on one of those other sources. Fixes the bug I noticed while working on #16935

* fix: ensure map iteration order is correct (#16947)

quick follow-up to #16944
Resetting a map entry does not change its position in the map when iterating. We need to make sure that reset makes that batch jump "to the front" for the "reject all stale batches" logic below. Edge case for which I can't come up with a test case but it _is_ a possibility.

* feat: add `createContext` utility for type-safe context (#16948)

* feat: add `createContext` utility for type-safe context

* regenerate

* Version Packages (#16946)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore: Remove annoying sync-async warning (#16949)

* fix

* use `$state.eager(value)` instead of `$effect.pending(value)`

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hyunbin Seo <[email protected]>
Co-authored-by: Ben McCann <[email protected]>
Co-authored-by: Rich Harris <[email protected]>
Co-authored-by: Hannes Rüger <[email protected]>
Co-authored-by: Elliott Johnson <[email protected]>
Rich-Harris added a commit that referenced this pull request Oct 18, 2025
* WIP implement `$effect.pending(...)`

* feat: `$state.eager(value)` (#16926)

* runtime-first approach

* revert these

* type safety, lint

* fix: better input cursor restoration for `bind:value` (#16925)

If cursor was at end and new input is longer, move cursor to new end

No test because not possible to reproduce using our test setup.

Follow-up to #14649, helps with #16577

* Version Packages (#16920)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* docs: await no longer need pending (#16900)

* docs: link to custom renderer issue in Svelte Native discussion (#16896)

* fix code block (#16937)

Updated code block syntax from Svelte to JavaScript for clarity.

* fix: unset context on stale promises (#16935)

* fix: unset context on stale promises

When a stale promise is rejected in `async_derived`, and the promise eventually resolves, `d.resolve` will be noop and `d.promise.then(handler, ...)` will never run. That in turns means any restored context (via `(await save(..))()`) will never be unset. We have to handle this case and unset the context to prevent errors such as false-positive state mutation errors

* fix: unset context on stale promises (slightly different approach) (#16936)

* slightly different approach to #16935

* move unset_context call

* get rid of logs

---------

Co-authored-by: Rich Harris <[email protected]>

* fix: svg `radialGradient` `fr` attribute missing in types (#16943)

* fix(svg radialGradient): fr attribute missing in types

* chore: add changeset

* Version Packages (#16940)

* Version Packages

* Update packages/svelte/CHANGELOG.md

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Rich Harris <[email protected]>

* chore: simplify `batch.apply()` (#16945)

* chore: simplify `batch.apply()`

* belt and braces

* note to self

* unused

* fix: don't rerun async effects unnecessarily (#16944)

Since #16866, when an async effect runs multiple times, we rebase older batches and rerun those effects. This can have unintended consequences: In a case where an async effect only depends on a single source, and that single source was updated in a later batch, we know that we don't need to / should not rerun the older batch.

This PR makes it so: We collect all the sources of older batches that are not part of the current batch that just committed, and then only mark those async effects as dirty which depend on one of those other sources. Fixes the bug I noticed while working on #16935

* fix: ensure map iteration order is correct (#16947)

quick follow-up to #16944
Resetting a map entry does not change its position in the map when iterating. We need to make sure that reset makes that batch jump "to the front" for the "reject all stale batches" logic below. Edge case for which I can't come up with a test case but it _is_ a possibility.

* feat: add `createContext` utility for type-safe context (#16948)

* feat: add `createContext` utility for type-safe context

* regenerate

* Version Packages (#16946)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore: Remove annoying sync-async warning (#16949)

* fix

* use `$state.eager(value)` instead of `$effect.pending(value)`

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hyunbin Seo <[email protected]>
Co-authored-by: Ben McCann <[email protected]>
Co-authored-by: Rich Harris <[email protected]>
Co-authored-by: Hannes Rüger <[email protected]>
Co-authored-by: Elliott Johnson <[email protected]>

* decouple from boundaries

* use queue_micro_task

* add test

* fix

* changeset

* revert

* tidy up

* update docs

* Update packages/svelte/src/internal/client/reactivity/batch.js

Co-authored-by: Simon H <[email protected]>

* minor tweak

---------

Co-authored-by: Simon H <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hyunbin Seo <[email protected]>
Co-authored-by: Ben McCann <[email protected]>
Co-authored-by: Hannes Rüger <[email protected]>
Co-authored-by: Elliott Johnson <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bind:value with function bindings don't work well with the input caret when value is changed in set

2 participants