Split blocks from the input event so double-Enter works on touch keyboards

Split blocks from the input event so double-Enter works on touch keyboards

#12 in Riparion/riparion-editor — merged 2026-06-08

Problem

On phones/tablets, pressing Return twice (double-Enter) did not close/split a block. Same root cause as arrow-key block nav being unavailable on touch: the feature was driven entirely from onkeydown checking e.key() == Key::Enter, but soft keyboards (iOS/Android IMEs) don't deliver Enter as a Key::Enter keydown — under predictive-text composition the keydown fires as Unidentified/keyCode 229, and the Return key surfaces through oninput as an insertLineBreak instead.

Fix

Add an input-event counterpart to the existing keydown handle_enter:

  • input_linebreak_caret() — reads the textarea value + caret from the oninput event, gated on inputType (insertLineBreak / insertParagraph / insertText of "\n") so typing, paste, and autocorrect can't trigger a split.
  • handle_input_split() — runs the same head/tail split as handle_enter when the just-inserted newline completes a blank line (text up to the caret ends in \n\n). Wired into oninput ahead of the normal commit.
  • Adds "InputEvent" to the web-sys features.

The desktop keydown path is unchanged: handle_enter prevent_default()s on the split, so no input event fires — no double-trigger.

Testing

cargo clippy/check clean for both --features web and default; 38 unit tests pass. Also drove the markdown example in Chromium via Playwright:

  • ✅ Single inserted newline does not split (stays a soft newline)
  • ✅ Double-Enter via insertLineBreak (no keydown) splits → new empty focused block; head becomes a rendered block
  • ✅ Desktop real-keyboard Enter→Enter still splits (no regression)

Note: Playwright fires real keydowns and can't reproduce a true mobile IME keyCode 229 stream; the new path was tested by dispatching the newline through the input event with no Enter keydown — the exact path mobile exercises. Real-device confirmation still worth a quick check.

🤖 Generated with Claude Code

Last updated 2026-06-08