mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 22:17:00 +00:00
fix(webchat): skip textarea resize during IME composition to eliminate typing lag
This commit is contained in:
committed by
Vincent Koc
parent
2ee4b523b4
commit
820e10fa49
@@ -1839,6 +1839,33 @@ describe("chat composer IME composition", () => {
|
||||
expect(onSend).not.toHaveBeenCalled();
|
||||
expect(onHistoryKeydown).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not force textarea resize during IME composition", () => {
|
||||
const container = renderChatView({});
|
||||
const textarea = requireElement(
|
||||
container,
|
||||
".agent-chat__composer-combobox > textarea",
|
||||
"composer textarea",
|
||||
) as HTMLTextAreaElement;
|
||||
|
||||
// Set a sentinel height to detect unwanted overwrites
|
||||
textarea.style.height = "42px";
|
||||
|
||||
textarea.dispatchEvent(new CompositionEvent("compositionstart", { bubbles: true }));
|
||||
textarea.value = "shi";
|
||||
textarea.dispatchEvent(new InputEvent("input", { bubbles: true, isComposing: true }));
|
||||
textarea.value = "shichang";
|
||||
textarea.dispatchEvent(new InputEvent("input", { bubbles: true, isComposing: true }));
|
||||
|
||||
// Height must stay untouched — no forced reflow during composition
|
||||
expect(textarea.style.height).toBe("42px");
|
||||
|
||||
textarea.value = "市场";
|
||||
textarea.dispatchEvent(new CompositionEvent("compositionend", { bubbles: true }));
|
||||
|
||||
// After composition ends, adjustTextareaHeight runs via syncComposerValue
|
||||
expect(textarea.style.height).not.toBe("42px");
|
||||
});
|
||||
});
|
||||
|
||||
describe("chat slash menu accessibility", () => {
|
||||
|
||||
@@ -2422,7 +2422,10 @@ export function renderChat(props: ChatProps) {
|
||||
const handleInput = (e: InputEvent) => {
|
||||
const target = e.target as HTMLTextAreaElement;
|
||||
if (vs.composerComposing || e.isComposing) {
|
||||
adjustTextareaHeight(target);
|
||||
// Skip adjustTextareaHeight during IME composition — each pinyin
|
||||
// keystroke fires `input` and the height read/write forces a
|
||||
// synchronous reflow that blocks the composition thread.
|
||||
// Resize runs once in handleCompositionEnd → syncComposerValue.
|
||||
draftMirror.value = target.value;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user