From 134a0e55b80d5a77dbacc4b68c042a36c5fbf3e0 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Mon, 1 Jul 2019 14:08:50 -0500 Subject: [PATCH] Ensure that a textInput event is always emitted when text composition ends #1531 --- CHANGELOG.md | 2 ++ .../components/composer-editor/conversion.tsx | 2 ++ .../composer-editor/patch-chrome-ime.ts | 32 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 app/src/components/composer-editor/patch-chrome-ime.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d3c023637..f792fa7037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Fixes: - Drag and drop of files into the composer and drag and drop of threads into folders / labels in the left sidebar now works as expected in all cases. #1533, #1534 +- When typing in Japanese or another language that uses composition events / IME, the composer now always commits your text when the composition dropdown is dismissed. #1531 + - A small "download" icon on the event header displayed in calendar emails allows you to download the underlying ICS file. #1547 - Resolves top issues reported via our automated error collection, including several problems causing instability in the composer. diff --git a/app/src/components/composer-editor/conversion.tsx b/app/src/components/composer-editor/conversion.tsx index 90b9008019..1a1febf2e5 100644 --- a/app/src/components/composer-editor/conversion.tsx +++ b/app/src/components/composer-editor/conversion.tsx @@ -24,6 +24,8 @@ import LinkPlugins from './link-plugins'; import EmojiPlugins, { EMOJI_TYPE } from './emoji-plugins'; import { Rule, ComposerEditorPlugin } from './types'; +import './patch-chrome-ime'; + export const schema = { inlines: { [VARIABLE_TYPE]: { diff --git a/app/src/components/composer-editor/patch-chrome-ime.ts b/app/src/components/composer-editor/patch-chrome-ime.ts new file mode 100644 index 0000000000..68b8db8f19 --- /dev/null +++ b/app/src/components/composer-editor/patch-chrome-ime.ts @@ -0,0 +1,32 @@ +/* +This file fixes a bug in Chrome where blurring / moving selection away from the composition +dropdown "commits" the composition but does NOT fire a textInput event to tell Slate. + +To reproduce the bug, enter Japanese editing mode, type "korewa" and then exit the composition +dropdown without explicitly committing the text (via Return) by clicking anywhere outside the +box. The text will remain visible in the editor but no onChange event is fired. + +Patch: + +If composition ends but no textinput event has been seen since composition started, build and +dispatch a TextEvent into the editor manually. +*/ + +let lastTextInputEvent = null; +document.addEventListener('textInput', e => (lastTextInputEvent = e), true); +document.addEventListener('compositionstart', e => (lastTextInputEvent = null), true); +document.addEventListener( + 'compositionend', + (e: CompositionEvent) => { + if (e.target instanceof HTMLElement && e.target.closest('[data-slate-editor]')) { + if (!lastTextInputEvent) { + console.warn('Manually emitting textInput event for Chrome'); + const t = document.createEvent('TextEvent'); + t.initEvent('textInput', true, true); + Object.defineProperty(t, 'data', { value: e.data }); + e.target.dispatchEvent(t); + } + } + }, + true +);