fix(desktop): bots group chat sends message on IME composition Enter
macOS Chinese pinyin IME: pressing Enter to confirm a candidate word in the group-chat composer submitted the draft as a message mid-composition. The GroupMentionInput onKeyDown checked only `event.key === 'Enter' && !event.shiftKey` with no IME guard, unlike the core composer which guards isComposing + keyCode 229 (#44135). Add the same guard to the three Enter handlers in the bots plugin: - GroupMentionInput (group composer + reply box) — the reported bug - GroupClarifyCard free-text answer input — same premature-submit - skill-hub search input — same premature-trigger Closes #93528
This commit is contained in:
@@ -8951,6 +8951,10 @@ function HubSkillsSection({ forProfile, onInstalled }) {
|
||||
value: query,
|
||||
onChange: event => setQuery(event.target.value),
|
||||
onKeyDown: event => {
|
||||
// IME guard: Enter confirming a composed word must not search.
|
||||
if (event.nativeEvent?.isComposing || event.keyCode === 229) {
|
||||
return
|
||||
}
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault()
|
||||
void search()
|
||||
@@ -11859,6 +11863,14 @@ function GroupMentionInput({ members, onChange, onSubmitDraft, value, ...inputPr
|
||||
},
|
||||
onClick: event => refreshToken(event.target),
|
||||
onKeyDown: event => {
|
||||
// IME composition guard (same as the core composer): Enter here
|
||||
// confirms the composed Chinese/Japanese/Korean text — it must not
|
||||
// insert a mention nor submit the draft. nativeEvent.isComposing
|
||||
// covers Chromium; keyCode 229 covers macOS Chinese IMEs that fire
|
||||
// Enter after compositionend with isComposing already false.
|
||||
if (event.nativeEvent?.isComposing || event.keyCode === 229) {
|
||||
return
|
||||
}
|
||||
if (open) {
|
||||
if (event.key === 'ArrowDown') {
|
||||
event.preventDefault()
|
||||
@@ -12045,6 +12057,10 @@ function GroupClarifyCard({ entry, members }) {
|
||||
setDrafts(prev => ({ ...prev, [q.qid]: value }))
|
||||
},
|
||||
onKeyDown: event => {
|
||||
// IME guard: Enter confirming a composed word must not submit.
|
||||
if (event.nativeEvent?.isComposing || event.keyCode === 229) {
|
||||
return
|
||||
}
|
||||
if (event.key === 'Enter' && questions.length === 1) {
|
||||
event.preventDefault()
|
||||
void submit()
|
||||
|
||||
@@ -31,6 +31,33 @@ test('room composer is a textarea with Enter=submit, Shift+Enter=newline (#89884
|
||||
assert.match(component, /insert\(options\[active\]\.handle\)/)
|
||||
})
|
||||
|
||||
test('room composer swallows IME composition Enters before submit/mention (#93528)', () => {
|
||||
// macOS Chinese IME: Enter that confirms a candidate word fires a keydown
|
||||
// the composer mistook for a send — the message went out mid-composition.
|
||||
// The guard must run BEFORE the popover branch AND the submit branch, and
|
||||
// cover both Chromium's isComposing flag and the keyCode 229 legacy
|
||||
// VK_PROCESSKEY that macOS IMEs emit after compositionend.
|
||||
const start = source.indexOf('function GroupMentionInput')
|
||||
const nextFn = source.indexOf('\nfunction ', start + 1)
|
||||
const component = source.slice(start, nextFn)
|
||||
|
||||
const guard = component.indexOf('event.nativeEvent?.isComposing || event.keyCode === 229')
|
||||
assert.ok(guard >= 0, 'IME guard present in GroupMentionInput')
|
||||
const afterGuard = component.slice(guard)
|
||||
// Guard returns immediately (no mention insert, no submit)...
|
||||
assert.match(afterGuard.slice(0, 80), /return/)
|
||||
// ...and it sits before both the popover branch and the submit branch.
|
||||
assert.ok(afterGuard.indexOf('if (open) {') > 0, 'guard precedes popover branch')
|
||||
assert.ok(component.indexOf("event.key === 'Enter' && !event.shiftKey") > guard, 'guard precedes submit branch')
|
||||
})
|
||||
|
||||
test('clarify free-text input swallows IME composition Enters (#93528)', () => {
|
||||
const clarify = source.slice(source.indexOf('function GroupClarifyCard'), source.indexOf('function openGroupChat'))
|
||||
const guard = clarify.indexOf('event.nativeEvent?.isComposing || event.keyCode === 229')
|
||||
assert.ok(guard >= 0, 'IME guard present in GroupClarifyCard')
|
||||
assert.ok(clarify.indexOf("event.key === 'Enter' && questions.length === 1") > guard, 'guard precedes submit branch')
|
||||
})
|
||||
|
||||
test('both room composers wire onSubmitDraft (#89884)', () => {
|
||||
assert.match(source, /onSubmitDraft: submit,/)
|
||||
assert.match(source, /onSubmitDraft: \(\) => submitReply\(id\),/)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ShonnQ
|
||||
Reference in New Issue
Block a user