feat(terminal): Chinese / IME input (P3)

Implement IME composition support and migrate regular character input to
a hidden textarea, matching the xterm.js approach.

Key changes:
- Add a hidden, absolutely-positioned `<textarea>` inside `.terminal-screen`
  that follows the terminal cursor cell. It receives focus on click, connect,
  and resize so the OS/browser IME candidate window appears at the cursor.
- `on:input` now sends regular printable characters; `on:keydown` only handles
  special keys (arrows, Enter, Esc, Backspace, F-keys, Ctrl combos).
- `on:compositionstart/end` track IME sessions and send the final composed
  string at the end, avoiding partial pinyin/jamo/kana leaks.
- Move `on:paste` and `on:keydown` from `.terminal-screen` to the textarea so
  focus stays on the IME target.
- Replace `.terminal-screen:focus` with `:focus-within` since the screen div
  no longer holds focus.
- Add `is_regular_text_input` helper and unit test.

Web-sys features extended with `InputEvent` and `CompositionEvent`.

Tests: 24/24 pass, clippy clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zhangheng
2026-06-18 16:09:45 +08:00
parent 843e4e55ab
commit f76d341501
4 changed files with 252 additions and 45 deletions

View File

@@ -610,13 +610,32 @@
scrollbar-color: rgb(148 163 184 / 60%) transparent;
}
.terminal-screen:focus {
.terminal-screen:focus-within {
border-color: #38bdf8;
box-shadow:
inset 0 1px 0 rgb(255 255 255 / 4%),
0 0 0 3px rgb(56 189 248 / 15%);
}
.terminal-ime {
position: absolute;
z-index: 100;
opacity: 0;
background: transparent;
color: transparent;
caret-color: transparent;
border: none;
outline: none;
resize: none;
padding: 0;
margin: 0;
overflow: hidden;
pointer-events: auto;
font-family: inherit;
font-size: 1px;
line-height: 1px;
}
.terminal-text {
margin: 0;
min-height: 100%;