fix(web): surround selected text with dead-key quotes#21360

open2
main
GitHub fork: fix/composer-dead-key-quotes
opened5d agobyGGustav0ar
View on GitHubTwo-way sync enabledPR last imported 3d ago

With US-International input, selecting word and pressing apostrophe then Space replaces the word with ' on Linux and macOS. This restores the existing selection-surround behavior for dead keys after #20350. Related: the maintainer's request to verify selection wrapping.

Keep eligible selected text in place while the dead key resolves, then surround it when a delimiter commits. Accented letters still replace the selection. Handle both native composition and Windows' direct text commits, preserve one-step undo, and discard stale selections.

Verification:

  • 32 focused browser tests pass across the input, navigation, and citation-draft tests. They cover preedit replacement, wrapping, accents, cancellation, undo/redo, and stale selections.
  • Web typecheck, targeted lint, and formatting pass. The shared web/desktop editor is covered in rich and plain modes; mobile uses a separate native input.
  • Native Electron 44.4.5: 16 cases pass per target across rich and plain modes on Windows, macOS, Linux X11, and native Linux Wayland. OS layout probes precede the composer tests. Selected words stay present throughout wrapping, with one-step undo and redo.
  • Linux automation uses Ubuntu 24.04 with Xvfb/Openbox for X11 and isolated Sway for Wayland. Wayland has XWayland disabled and no X11 display, and the test verifies an Electron xdg_shell surface. The reporter also verified the isolated desktop build on CachyOS/Wayland.

Reproduce the focused browser checks with:

sh
1cd apps/web
2../../node_modules/.bin/vp test run --project browser src/components/ComposerPromptEditorTiptap.{input,navigation,citationDraft}.browser.test.tsx

macOS before the fix: apostrophe + Space replaces the selected word with '.

macOS before the fix: only an apostrophe remains

https://github.com/user-attachments/assets/347b0a56-e70f-40c6-b759-b2eeb7a47f17

macOS after the fix: apostrophe + Space produces 'word' and keeps word selected.

macOS after the fix: the selected word is surrounded by apostrophes

https://github.com/user-attachments/assets/1b873d6a-44cd-4495-8ebd-bf5cb7001c75

Windows native verification

All 16 cases pass in rich and plain modes, including accents, selection wrapping, and undo/redo.

Windows after the fix: the selected word is surrounded by apostrophes

https://github.com/user-attachments/assets/7f3fddf9-8796-4dbf-b31f-8bb0adecba39

Linux X11 and native Wayland verification

X11: all 16 native cases pass under Xvfb/Openbox.

Linux X11: the selected word remains surrounded by apostrophes

https://github.com/user-attachments/assets/b5244c8a-701e-4ac1-8a1a-1f66837333f0

Native Wayland: all 16 cases pass under Sway, with XWayland disabled. The selected word remains in every recorded transaction and frame.

Native Linux Wayland: the selected word remains surrounded by apostrophes

https://github.com/user-attachments/assets/f3e76c64-4c75-4967-90a3-038ef7309c0c

Passing Linux run, X11 environment and event traces, and Wayland environment, surface, and event traces.

The recordings include layout probes and native keyboard cases. Passing Windows and macOS native run, macOS event traces, and Windows event traces. The test code stays on the fork's test branch.

Implemented with GPT-6.1-sol in Codex.

Checks

All checks passed

Added 1 commit

  • fix(web): surround selected text with dead-key quotes55ea809
CCopilotBotreviewed5d ago
Synced from GitHub

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Synced from GitHub

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This production editor fix adds substantial cross-platform composition and dead-key state handling, including asynchronous reconciliation and undo integration. Its focused tests reduce risk, but the new runtime state machine is complex enough to merit human review.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fefe93c0-2bc7-4517-bbc0-151404afce08
📥 Commits

Reviewing files that changed from the base of the PR and between 55ea8098f7a552914ffe0dbff155b1e4acdda177 and 18e33fb223ed2994ec0a5a5001e240155f46a958.

📒 Files selected for processing: 2
  • apps/web/src/components/ComposerPromptEditorTiptap.input.browser.test.tsx
  • apps/web/src/components/ComposerPromptEditorTiptap.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

The editor preserves eligible selections during dead-key input. It wraps selected text for paired characters, replaces it with committed text, or abandons the pending operation when the captured editor state no longer matches. Browser tests cover composition, selection changes, cancellation, and undo behavior.

Changes: Dead-key input

Layer / File(s)Summary
Selection eligibility and pending state
apps/web/src/components/ComposerPromptEditorTiptap.tsx
The editor checks whether a selection can be surrounded and stores the selection and editor state for pending dead-key input.
Dead-key capture, resolution, and validation
apps/web/src/components/ComposerPromptEditorTiptap.tsx, apps/web/src/components/ComposerPromptEditorTiptap.input.browser.test.tsx
The editor handles dead-key and Process input during composition and text input. Browser tests cover wrapping, replacement, cancellation, undo and redo, and selection cases.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Sequence Diagram(s)

mermaid
1sequenceDiagram
2 participant Browser
3 participant ComposerPromptEditorTiptap
4 participant ProseMirror
5 Browser->>ComposerPromptEditorTiptap: Send Dead or Process keydown
6 ComposerPromptEditorTiptap->>ProseMirror: Collapse eligible selection and save editor state
7 Browser->>ComposerPromptEditorTiptap: Send composition or committed text
8 ComposerPromptEditorTiptap->>ProseMirror: Wrap, replace, or restore selection

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to 18e33

The dead-key selection change is ready to merge after normal checks; no actionable issue remains identified.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Title checkPassedThe title clearly and concisely describes the main change: restoring dead-key quote wrapping for selected text.
Description checkPassedThe description explains the problem, implementation, scope, verification steps, cross-platform results, evidence, and agent usage. It does not use the template headings exactly and does not state mai…
Full details: Description check

Explanation

The description explains the problem, implementation, scope, verification steps, cross-platform results, evidence, and agent usage. It does not use the template headings exactly and does not state maintainer approval in explicit terms, but it provides a related maintainer request and sufficient focused context.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Added 1 commit

  • refactor(web): simplify dead-key selection handling18e33fb