避免手机工具栏按钮在失焦重排时丢失点击

This commit is contained in:
2026-10-30 12:56:26 +08:00
parent a415bcdb88
commit 1902949f69
2 changed files with 14 additions and 7 deletions
+5 -3
View File
@@ -1842,9 +1842,11 @@ if(window.visualViewport){
window.addEventListener('pageshow', scheduleChatViewport);
inputDom.addEventListener('focus', scheduleChatViewport);
inputDom.addEventListener('blur', scheduleChatViewport);
// Keep an already open keyboard while tapping Send; keyboard navigation is unchanged.
sendBtn.addEventListener('pointerdown', function(event){
if(event.button === 0 && document.activeElement === inputDom) event.preventDefault();
// Let toolbar clicks complete before blur changes the keyboard and composer layout.
document.querySelector('.composer').addEventListener('pointerdown', function(event){
if(event.button === 0 && document.activeElement === inputDom && event.target.closest('button')){
event.preventDefault();
}
});
syncChatViewport();
+9 -4
View File
@@ -711,15 +711,20 @@ test('late AI completion does not steal focus or reopen a dismissed mobile keybo
}
});
test('mobile quick questions do not summon the keyboard and tapping Send retains an active draft focus', async () => {
test('mobile quick questions keep the keyboard closed and composer controls finish clicking before blur changes layout', async () => {
const app=await customerPage({human:false,width:390});
const input=app.element('input-text');
await app.context.window.fillInput('快捷咨询');await flush();
assert.equal(input.focusCalls.length,0);
input.focus();
let prevented=false;
app.element('send-button').listeners.pointerdown({button:0,preventDefault(){prevented=true;}});
assert.ok(prevented);
for(const name of ['send-button','voice-toggle','emoji-toggle','upload-btn']){
let prevented=false;
app.element('.composer').listeners.pointerdown({button:0,target:{closest:()=>app.element(name)},preventDefault(){prevented=true;}});
assert.ok(prevented);
}
let blockedTextSelection=false;
app.element('.composer').listeners.pointerdown({button:0,target:{closest:()=>null},preventDefault(){blockedTextSelection=true;}});
assert.equal(blockedTextSelection,false);
assert.equal(app.context.document.activeElement,input);
});