mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-12 04:15:25 +00:00
Merge pull request #16885 from ShirasawaSama/patch-5
fix: fix Safari IME composition bug (#16615)
This commit is contained in:
commit
e3207f35d7
1 changed files with 32 additions and 26 deletions
|
|
@ -417,6 +417,30 @@
|
|||
let recording = false;
|
||||
|
||||
let isComposing = false;
|
||||
// Safari has a bug where compositionend is not triggered correctly #16615
|
||||
// when using the virtual keyboard on iOS.
|
||||
let compositionEndedAt = -2e8;
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
||||
function inOrNearComposition(event: Event) {
|
||||
if (isComposing) {
|
||||
return true;
|
||||
}
|
||||
// See https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/.
|
||||
// On Japanese input method editors (IMEs), the Enter key is used to confirm character
|
||||
// selection. On Safari, when Enter is pressed, compositionend and keydown events are
|
||||
// emitted. The keydown event triggers newline insertion, which we don't want.
|
||||
// This method returns true if the keydown event should be ignored.
|
||||
// We only ignore it once, as pressing Enter a second time *should* insert a newline.
|
||||
// Furthermore, the keydown event timestamp must be close to the compositionEndedAt timestamp.
|
||||
// This guards against the case where compositionend is triggered without the keyboard
|
||||
// (e.g. character confirmation may be done with the mouse), and keydown is triggered
|
||||
// afterwards- we wouldn't want to ignore the keydown event in this case.
|
||||
if (isSafari && Math.abs(event.timeStamp - compositionEndedAt) < 500) {
|
||||
compositionEndedAt = -2e8;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
let chatInputContainerElement;
|
||||
let chatInputElement;
|
||||
|
|
@ -1169,19 +1193,9 @@
|
|||
return res;
|
||||
}}
|
||||
oncompositionstart={() => (isComposing = true)}
|
||||
oncompositionend={() => {
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(
|
||||
navigator.userAgent
|
||||
);
|
||||
|
||||
if (isSafari) {
|
||||
// Safari has a bug where compositionend is not triggered correctly #16615
|
||||
// when using the virtual keyboard on iOS.
|
||||
// We use a timeout to ensure that the composition is ended after a short delay.
|
||||
setTimeout(() => (isComposing = false));
|
||||
} else {
|
||||
oncompositionend={(e) => {
|
||||
compositionEndedAt = e.timeStamp;
|
||||
isComposing = false;
|
||||
}
|
||||
}}
|
||||
on:keydown={async (e) => {
|
||||
e = e.detail.event;
|
||||
|
|
@ -1290,7 +1304,7 @@
|
|||
navigator.msMaxTouchPoints > 0
|
||||
)
|
||||
) {
|
||||
if (isComposing) {
|
||||
if (inOrNearComposition(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1393,17 +1407,9 @@
|
|||
command = getCommand();
|
||||
}}
|
||||
on:compositionstart={() => (isComposing = true)}
|
||||
on:compositionend={() => {
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
||||
|
||||
if (isSafari) {
|
||||
// Safari has a bug where compositionend is not triggered correctly #16615
|
||||
// when using the virtual keyboard on iOS.
|
||||
// We use a timeout to ensure that the composition is ended after a short delay.
|
||||
setTimeout(() => (isComposing = false));
|
||||
} else {
|
||||
oncompositionend={(e) => {
|
||||
compositionEndedAt = e.timeStamp;
|
||||
isComposing = false;
|
||||
}
|
||||
}}
|
||||
on:keydown={async (e) => {
|
||||
const isCtrlPressed = e.ctrlKey || e.metaKey; // metaKey is for Cmd key on Mac
|
||||
|
|
@ -1523,7 +1529,7 @@
|
|||
navigator.msMaxTouchPoints > 0
|
||||
)
|
||||
) {
|
||||
if (isComposing) {
|
||||
if (inOrNearComposition(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue