Skip to content

feat(thumbjar): record each input event's target ranges, selection and whether its default was prevented - #3669

Merged
christianhg merged 2 commits into
mainfrom
feat/thumbjar-record-input-detail
Nov 12, 2026
Merged

christianhg merged 2 commits into
mainfrom
feat/thumbjar-record-input-detail

Conversation

@christianhg

@christianhg christianhg commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

recordInput now records what each input event carries, not just its type and data. Every recorded event gets the field's text and selection at the moment it fires. beforeinput and input also get isComposing, cancelable, the target ranges the browser reported (read during dispatch, as offsets in the field's text) and whether the default ended up prevented once the page's own handlers had run.

This makes a device run answer two questions it could not before: whether the browser's event alone says which text changed, and whether calling preventDefault() on it actually held on Android. Existing keys and their values are unchanged, so current tests read the same events as before.

defaultPrevented is written by a zero-delay timer after the dispatch, because a trusted event runs microtasks between listeners and the page's handlers, React's included, run after the recorder's document capture listener. Any read that throws is recorded as null so the recorder never breaks the page.


Note

Low Risk
Changes are confined to test instrumentation (recordInput) and driver reads, with broad unit test coverage and no production auth or data-path impact.

Overview
recordInput now captures richer per-event state for Android keyboard tests: every recorded event includes selection (direction-aware UTF-16 {anchor, focus}) and field text at dispatch time. beforeinput / input also record isComposing, cancelable, targetRanges (field-relative UTF-16 ranges, with null for out-of-field), and defaultPrevented (filled after dispatch via setTimeout(0) so page handlers can run first).

The page exposes window.__selection() so the Gboard driver no longer inlines selection logic in CDP; boundary reads use that API and step/event fixtures in tests were updated to expect the new fields.

Extensive jsdom unit tests and README documentation cover backward selection, contenteditable offsets, throwing getters, and deferred defaultPrevented logging.

Reviewed by Cursor Bugbot for commit d9d268c. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d9d268c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@vercel

vercel Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
portable-text-editor-documentation Ready Ready Preview Nov 12, 2026 4:06pm UTC
portable-text-example-basic Ready Ready Preview Nov 12, 2026 4:06pm UTC
portable-text-playground Ready Ready Preview Nov 12, 2026 4:06pm UTC

Request Review

@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Bundle Stats

✅ No significant changes.

All scenario measurements (34)

🗺️ @portabletext/block-tools / @portabletext/block-tools · @portabletext/block-tools / @portabletext/block-tools/rules · @portabletext/editor / @portabletext/editor · @portabletext/editor / @portabletext/editor/behaviors · @portabletext/editor / @portabletext/editor/plugins · @portabletext/editor / @portabletext/editor/selectors · @portabletext/editor / @portabletext/editor/traversal · @portabletext/editor / @portabletext/editor/utils · @portabletext/editor / defineSchema · @portabletext/editor / useEditor · @portabletext/editor / typical · @portabletext/html / @portabletext/html · @portabletext/html / @portabletext/html/rules · @portabletext/html / htmlToPortableText · @portabletext/keyboard-shortcuts / @portabletext/keyboard-shortcuts · @portabletext/patches / @portabletext/patches · @portabletext/repair / @portabletext/repair · @portabletext/sanity-bridge / @portabletext/sanity-bridge · @portabletext/schema / @portabletext/schema · @portabletext/plugin-character-pair-decorator / @portabletext/plugin-character-pair-decorator · @portabletext/plugin-decorations / @portabletext/plugin-decorations · @portabletext/plugin-dnd / @portabletext/plugin-dnd · @portabletext/plugin-emoji-picker / @portabletext/plugin-emoji-picker · @portabletext/plugin-input-rule / @portabletext/plugin-input-rule · @portabletext/plugin-list-index / @portabletext/plugin-list-index · @portabletext/plugin-markdown-shortcuts / @portabletext/plugin-markdown-shortcuts · @portabletext/plugin-one-line / @portabletext/plugin-one-line · @portabletext/plugin-paste-link / @portabletext/plugin-paste-link · @portabletext/plugin-typeahead-picker / @portabletext/plugin-typeahead-picker · @portabletext/plugin-typography / @portabletext/plugin-typography · @portabletext/toolbar / @portabletext/toolbar · @portabletext/toolbar / typical · @portabletext/plugin-table / @portabletext/plugin-table · @portabletext/plugin-table / @portabletext/plugin-table/ui · Artifacts

Scenario Kind Bundle (raw / gzip) Gzip change Import time Import change
⚪ @portabletext/block-tools / @portabletext/block-tools export 91.8 KB / 12.9 KB None 14 ms +0 ms, +3.4%
⚪ @portabletext/block-tools / @portabletext/block-tools/rules export 15.2 KB / 2.1 KB None 5 ms +0 ms, +1.8%
⚪ @portabletext/editor / @portabletext/editor export 1.02 MB / 130.6 KB None 74 ms +2 ms, +2.7%
⚪ @portabletext/editor / @portabletext/editor/behaviors export 4.3 KB / 147 B None 2 ms +0 ms, +3.7%
⚪ @portabletext/editor / @portabletext/editor/plugins export 5.1 KB / 645 B None 7 ms +0 ms, +0.7%
⚪ @portabletext/editor / @portabletext/editor/selectors export 96.3 KB / 9.4 KB None 8 ms -0 ms, -1.7%
⚪ @portabletext/editor / @portabletext/editor/traversal export 46.6 KB / 4.2 KB None 6 ms +0 ms, +3.6%
⚪ @portabletext/editor / @portabletext/editor/utils export 32.8 KB / 4.1 KB None 6 ms +0 ms, +0.7%
⚪ @portabletext/editor / defineSchema consumer 658 B / 69 B None None None
⚪ @portabletext/editor / typical consumer 1.02 MB / 130.3 KB None None None
⚪ @portabletext/editor / useEditor consumer 1.6 KB / 248 B None None None
⚪ @portabletext/html / @portabletext/html export 69.3 KB / 10.1 KB None 7 ms +0 ms, +1.2%
⚪ @portabletext/html / @portabletext/html/rules export 15.2 KB / 2.1 KB None 4 ms +0 ms, +1.5%
⚪ @portabletext/html / htmlToPortableText consumer 69.3 KB / 10.1 KB None None None
⚪ @portabletext/keyboard-shortcuts / @portabletext/keyboard-shortcuts export 7.0 KB / 858 B None 2 ms +0 ms, +6.9%
⚪ @portabletext/patches / @portabletext/patches export 50.0 KB / 7.7 KB None 4 ms +0 ms, +1.2%
⚪ @portabletext/plugin-character-pair-decorator / @portabletext/plugin-character-pair-decorator export 124.1 KB / 15.8 KB None None None
⚪ @portabletext/plugin-decorations / @portabletext/plugin-decorations export 16.4 KB / 2.3 KB None None None
⚪ @portabletext/plugin-dnd / @portabletext/plugin-dnd export 10.4 KB / 1.8 KB None None None
⚪ @portabletext/plugin-emoji-picker / @portabletext/plugin-emoji-picker export 150.1 KB / 18.6 KB None None None
⚪ @portabletext/plugin-input-rule / @portabletext/plugin-input-rule export 124.2 KB / 15.8 KB None None None
⚪ @portabletext/plugin-list-index / @portabletext/plugin-list-index export 7.4 KB / 1.1 KB None None None
⚪ @portabletext/plugin-markdown-shortcuts / @portabletext/plugin-markdown-shortcuts export 136.4 KB / 17.6 KB None None None
⚪ @portabletext/plugin-one-line / @portabletext/plugin-one-line export 2.6 KB / 608 B None None None
⚪ @portabletext/plugin-paste-link / @portabletext/plugin-paste-link export 4.3 KB / 1.0 KB None None None
⚪ @portabletext/plugin-table / @portabletext/plugin-table export 61.1 KB / 7.1 KB None None None
⚪ @portabletext/plugin-table / @portabletext/plugin-table/ui export 114.6 KB / 19.5 KB None None None
⚪ @portabletext/plugin-typeahead-picker / @portabletext/plugin-typeahead-picker export 166.2 KB / 19.9 KB None None None
⚪ @portabletext/plugin-typography / @portabletext/plugin-typography export 131.1 KB / 17.0 KB None None None
⚪ @portabletext/repair / @portabletext/repair export 4.5 KB / 636 B None 3 ms +0 ms, +4.6%
⚪ @portabletext/sanity-bridge / @portabletext/sanity-bridge export 27.0 KB / 3.0 KB None 3 ms -0 ms, -4.5%
⚪ @portabletext/schema / @portabletext/schema export 9.9 KB / 1.2 KB None 2 ms +0 ms, +0.0%
⚪ @portabletext/toolbar / @portabletext/toolbar export 153.3 KB / 17.3 KB None None None
⚪ @portabletext/toolbar / typical consumer 145.6 KB / 16.9 KB None None None

Significant means at least 1.0 KB and 1% gzip, or at least 5 ms and 10% import time.

This branch was successfully deployed

3 active deployments
Preview – portable-text-editor-documentation — d9d268c7 Deployed Nov 12, 2026 by vercel[bot]
Preview – portable-text-playground — d9d268c7 Deployed Nov 12, 2026 by vercel[bot]
Preview – portable-text-example-basic — d9d268c7 Deployed Nov 12, 2026 by vercel[bot]
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