Skip to content

fix(composer): add IME composition guard to textarea paste handler - #216

Merged
jackwener merged 1 commit into
mainfrom
yuejing/fe-bug-hunt-10
Jun 24, 2026
Merged

fix(composer): add IME composition guard to textarea paste handler#216
jackwener merged 1 commit into
mainfrom
yuejing/fe-bug-hunt-10

Conversation

@jackwener

Copy link
Copy Markdown
Member

PR-FE-BUG-HUNT-10 — extending PR #202's IME pattern from keydown to paste.

Bug

`onTextareaPaste` at `packages/ui/src/components.tsx:5726` was missing an IME composition guard. The sibling `onTextareaKeyDown` at line 5640 already had `if (event.nativeEvent.isComposing || event.key === 'Process') return;` (added in PR #202 for the Enter-during-CJK case), but the paste path was left out.

Symptom

A user mid-CJK composition who pastes a clipboard file (e.g. macOS screenshot captured via `Cmd+Ctrl+Shift+4` lands in clipboard) hits the file-import branch, which calls `event.preventDefault()` — that aborts the in-flight IME composition and eats the partially-typed character. Rare but real, same pattern as the keydown bug PR #202 fixed.

Fix

Prepend `if (event.nativeEvent.isComposing) return;` at the top of `onTextareaPaste`, matching the keydown pattern at line 5640. When IME is active, paste should fall through to the native textarea so the IME can handle (or ignore) it as the user expects. The file-import path only matters after composition ends.

Hunt context

Found via parallel Explore-agent scan on 3 layers (Daily Review, cron, composer). The other two findings were false positives on manual verify:

  • Daily Review archive-list race: agent contradicted itself mid-output; not actionable
  • Cron `reminder.schedule` null-safety: impossible — TypeScript types `PlanReminder.schedule` as required non-null at `packages/core/src/plan-reminders.ts:64`

Reporting transparently so kenji / WAWQAQ can discount them.

Diff

`1 file changed, 8 insertions(+), 0 deletions(-)` — single function, single guard, matches existing sibling pattern verbatim.

Verification

Disk still ~100%, couldn't run `pnpm install && pnpm test`. Pattern-matches PR #202's verified keydown guard, so behavior outside the IME edge case is unchanged.

PR #202 added an IME guard to the composer textarea's keydown
handler so Enter during CJK composition wouldn't fire submit
mid-character. The paste handler (components.tsx:5726) had the
same exposure but was left out.

Symptom: a user mid-CJK composition who pastes a clipboard file
(e.g. screenshot captured via system shortcut) hits the file-import
path, which calls `event.preventDefault()` — that aborts the
in-flight IME composition and eats the partially-typed character.
Rare but real. The same kind of bug pattern as the keydown one.

Fix: prepend `if (event.nativeEvent.isComposing) return;` at the
top of `onTextareaPaste`, matching the exact pattern at line 5640
in the keydown handler. 2 lines + 6-line WHY comment.

When IME is active, the paste should fall through to the textarea's
native paste so the IME can handle (or ignore) it as the user
expects. The file-import path only matters once composition has
ended.

Found via PR-FE-BUG-HUNT scan; 2 sibling Explore agents also
ran on Daily Review and cron PlanReminderPanel — both reported
findings that I manually verified as false positives (Daily Review
agent contradicted itself mid-output; cron `reminder.schedule`
null-safety claim is impossible because TypeScript types it as
required non-null). Reporting transparently so kenji/WAWQAQ can
discount those.

## Diff

1 file, 8 insertions(+), 0 deletions(-). No overlap with any open PR.

## Verification

Disk still ~100%, couldn't run `pnpm install && pnpm test`.
Matches existing pattern verbatim, so behavior outside the IME
edge case is unchanged.
@jackwener
jackwener merged commit 31498db into main Jun 24, 2026
@jackwener
jackwener deleted the yuejing/fe-bug-hunt-10 branch June 24, 2026 17:30
jackwener added a commit that referenced this pull request Jun 24, 2026
…216) (#221)

WAWQAQ reported `pnpm dev` build broken with:

  src/components.tsx:5732:27 - error TS2339:
  Property 'isComposing' does not exist on type 'ClipboardEvent'.

      if (event.nativeEvent.isComposing) return;
                            ~~~~~~~~~~~

PR #216 (paste-handler IME guard) copied the
`event.nativeEvent.isComposing` pattern verbatim from the keydown
handler at line 5640. That works on the keydown handler because the
DOM types declare `isComposing: boolean` on `KeyboardEvent` and
`InputEvent`. ClipboardEvent does NOT declare it — even though most
browsers happen to expose it on the underlying event.

Hot-fix: narrow the runtime check with `'isComposing' in native` +
a typed-cast to `{ isComposing?: boolean }`. Compiles cleanly AND
preserves the runtime IME guard when the browser does expose it.

Behavior unchanged for the normal path:
- IME active + paste → bail (same as before)
- No IME + paste of file → import (same as before)
- No IME + text paste → fall through (same as before)

In browsers that don't expose `isComposing` on ClipboardEvent at all,
the guard becomes a no-op — same as PR #216 before this hotfix,
just without breaking the build.
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