Skip to content

feat(core): predictive input model via beforeinput#131

Merged
Nowely merged 4 commits intonextfrom
reject-on-input
Mar 5, 2026
Merged

feat(core): predictive input model via beforeinput#131
Nowely merged 4 commits intonextfrom
reject-on-input

Conversation

@Nowely
Copy link
Owner

@Nowely Nowely commented Mar 5, 2026

Replaces the browser-driven input model with a predictive one: all text
mutations are now intercepted via beforeinput, applied programmatically
through NodeProxy, and synced to the token model — the DOM never mutates
natively during normal editing.

Changes

applySpanInput (new, @markput/core)
Handles all common input types using event.getTargetRanges() for exact
bounds and event.dataTransfer for text content. Returns false at token
boundaries to hand off to the existing mark-delete path.

Covered inputTypes:

  • insertText
  • deleteContentBackward / deleteContentForward
  • deleteWordBackward / deleteWordForward
  • deleteSoftLineBackward / deleteSoftLineForward
  • insertFromPaste
  • insertReplacementText (autocorrect / spellcheck)

handleBeforeInput extended to call applySpanInput for any
isEditable element — covers text spans and editable mark spans uniformly.

#handleDelete updated: for editable marks, the mark is only deleted
when the caret is at the boundary. Mid-content backspace/delete is now
handled by beforeinput.

Lifecycle.#subscribeInputEvent removed — the DOM input listener is
no longer needed. preventDefault() on beforeinput prevents input from
firing for all handled cases, and insertReplacementText closes the last gap.

React and Vue TextSpan / EditableSpan — removed onPaste +
document.execCommand('insertText') from both packages. Paste is handled
by insertFromPaste in core.

Before / After

Before After
Input model browser mutates DOM → input → read back beforeinputpreventDefault → apply to model
Paste execCommand('insertText') (deprecated) insertFromPaste via event.dataTransfer
Autocorrect input listener fallback insertReplacementText in applySpanInput
Editable mark backspace always deleted mark deletes mark only at caret boundary
React / Vue duplicate onPaste logic per framework no framework-level input handling

Nowely added 4 commits March 5, 2026 20:38
- Added applySpanInput function to handle various input events for span elements.
- Updated handleBeforeInput to utilize applySpanInput for better content management.
- Removed unused handlePaste function from TextSpan component.
- Exported applySpanInput from KeyDownController for broader usage.
- Added checks in KeyDownController to prevent deletion when caret is not at the beginning or end for editable marks.
- Updated handleBeforeInput to ensure focus is editable before processing input events.
- Removed unused handlePaste function from EditableSpan component to streamline code.
- Added support for 'insertReplacementText' in applySpanInput function to handle additional input events.
- Removed the unused #subscribeInputEvent method from Lifecycle class to streamline event management.
- Updated handleBeforeInput in KeyDownController to prevent default behavior for 'insertFromPaste' events.
- Removed unused handlePaste functions from EditableSpan and TextSpan components to streamline code.
@vercel
Copy link

vercel bot commented Mar 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marked-input Ready Ready Preview, Comment Mar 5, 2026 5:53pm
markput-website Ready Ready Preview, Comment Mar 5, 2026 5:53pm

@Nowely Nowely merged commit 80d0369 into next Mar 5, 2026
3 checks passed
@Nowely Nowely deleted the reject-on-input branch March 5, 2026 17:57
Nowely pushed a commit that referenced this pull request Mar 6, 2026
🤖 I have created a release *beep* *boop*
---


## [0.4.0](0.3.0...0.4.0)
(2026-03-06)


### Features

* **core:** predictive input model via beforeinput
([#131](#131))
([80d0369](80d0369))


### Documentation

* Add AGENTS.md
([#135](#135))
([675a8e2](675a8e2))
* update Storybook links and reorganize badges by framewor
([#137](#137))
([9884dc1](9884dc1))


### Miscellaneous

* migrate from prettier to oxfmt
([#139](#139))
([4349b1b](4349b1b))
* remove unused EditableSpan components
([#133](#133))
([2e5388a](2e5388a))
* remove unused Vercel configuration file from Storybook
([#136](#136))
([60129be](60129be))
* upgrade vue-tsc to v3.2.5
([#138](#138))
([a189b53](a189b53))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

1 participant