From 0e03b2be2910af7cf7adbeb3a5ef96a00882198a Mon Sep 17 00:00:00 2001 From: Steve Clower Date: Tue, 4 Apr 2023 14:26:52 -0400 Subject: [PATCH 1/2] Add handler to support input composition events Specific purpose is to provide preliminary support for dictation in Chromebooks. --- src/services/saneKeyboardEvents.util.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/services/saneKeyboardEvents.util.ts b/src/services/saneKeyboardEvents.util.ts index 589c12c77..0f4554e3a 100644 --- a/src/services/saneKeyboardEvents.util.ts +++ b/src/services/saneKeyboardEvents.util.ts @@ -249,6 +249,8 @@ var saneKeyboardEvents = (function () { function onKeyup(e: KeyboardEvent) { everyTick.trigger(e); if (e.target !== textarea) return; + // Don't process composed keyup events which have no valid mapping + if (e.key === 'Unidentified' || e.key === 'Process') return; // Handle case of no keypress event being sent if (!!keydown && !keypress) { // only check for typed text if this key can type text. Otherwise @@ -360,6 +362,18 @@ var saneKeyboardEvents = (function () { everyTick.trigger(e); } + function onCompositionEnd(e: CompositionEvent) { + // Handle composed input events, such as those which come from dictation in Chrome. + everyTick.trigger(e); + if (!(textarea instanceof HTMLTextAreaElement) || e.target !== textarea) + return; + const text = e.data; + if (text.length === 0) return; + textarea.value = ''; + controller.writeLatex(text); + controller.scrollHoriz(); + } + if (controller.options && controller.options.disableCopyPaste) { controller.addTextareaEventListeners({ keydown: onKeydown, @@ -377,6 +391,7 @@ var saneKeyboardEvents = (function () { e.preventDefault(); }, input: onInput, + compositionend: onCompositionEnd, }); } else { controller.addTextareaEventListeners({ @@ -396,6 +411,7 @@ var saneKeyboardEvents = (function () { }, paste: onPaste, input: onInput, + compositionend: onCompositionEnd, }); } From b87990a1c93f4b7262b3a015ecd346f7cea69070 Mon Sep 17 00:00:00 2001 From: Steve Clower Date: Tue, 4 Apr 2023 15:52:30 -0400 Subject: [PATCH 2/2] Short-circuit typedText behavior if an input composition is in progress --- src/services/saneKeyboardEvents.util.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/services/saneKeyboardEvents.util.ts b/src/services/saneKeyboardEvents.util.ts index 0f4554e3a..26ac983f1 100644 --- a/src/services/saneKeyboardEvents.util.ts +++ b/src/services/saneKeyboardEvents.util.ts @@ -150,6 +150,7 @@ var saneKeyboardEvents = (function () { ) { var keydown: KeyboardEvent | null = null; var keypress: KeyboardEvent | null = null; + var isComposing: boolean = false; // everyTick.listen() is called after key or clipboard events to // say "Hey, I think something was just typed" or "pasted" etc, @@ -249,8 +250,6 @@ var saneKeyboardEvents = (function () { function onKeyup(e: KeyboardEvent) { everyTick.trigger(e); if (e.target !== textarea) return; - // Don't process composed keyup events which have no valid mapping - if (e.key === 'Unidentified' || e.key === 'Process') return; // Handle case of no keypress event being sent if (!!keydown && !keypress) { // only check for typed text if this key can type text. Otherwise @@ -266,6 +265,7 @@ var saneKeyboardEvents = (function () { } function typedText() { + if (isComposing) return; // If there is a selection, the contents of the textarea couldn't // possibly have just been typed in. // This happens in browsers like Firefox and Opera that fire @@ -362,9 +362,15 @@ var saneKeyboardEvents = (function () { everyTick.trigger(e); } + function onCompositionStart(e: CompositionEvent) { + everyTick.trigger(e); + isComposing = true; + } + function onCompositionEnd(e: CompositionEvent) { // Handle composed input events, such as those which come from dictation in Chrome. everyTick.trigger(e); + isComposing = false; if (!(textarea instanceof HTMLTextAreaElement) || e.target !== textarea) return; const text = e.data; @@ -391,6 +397,7 @@ var saneKeyboardEvents = (function () { e.preventDefault(); }, input: onInput, + compositionstart: onCompositionStart, compositionend: onCompositionEnd, }); } else { @@ -411,6 +418,7 @@ var saneKeyboardEvents = (function () { }, paste: onPaste, input: onInput, + compositionstart: onCompositionStart, compositionend: onCompositionEnd, }); }