Commit fb489a09 authored by Moe Ahmadi's avatar Moe Ahmadi Committed by Commit Bot

[Realbox] Disable inline autocompletion when text is composed with IME

KeyboardEvent.isComposing is a boolean property indicating if the input
event is fired within a composition session started by an input method
editor (IME). IME is primarily used for inputting CJK (Chinese,
Japanese, and Korean) characters. Updating the input text via inline
autocompletion when a composition session is active can have undesired
effects such as the one described in the bug linked to in this CL.

While not an ideal solution, this is a safe one due to its small scope
allowing this change to be merged into a previous milestone. An ideal
solution would be to use a mechanism other than input text selection
for inline autocompletion such as how it is done in the omnibox via a
grey label: screenshot/8ougnH9pRAiDfb2

Bug: 1128310, 1149769
Change-Id: Ie6596c9f60da33adaf8b4847d891fc102c5d71c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2543546Reviewed-by: default avatarTommy Li <tommycli@chromium.org>
Commit-Queue: Moe Ahmadi <mahmadi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828471}
parent 94d2d696
...@@ -267,8 +267,11 @@ class RealboxElement extends PolymerElement { ...@@ -267,8 +267,11 @@ class RealboxElement extends PolymerElement {
const firstMatch = hasMatches ? this.result_.matches[0] : null; const firstMatch = hasMatches ? this.result_.matches[0] : null;
if (firstMatch && firstMatch.allowedToBeDefaultMatch) { if (firstMatch && firstMatch.allowedToBeDefaultMatch) {
this.$.matches.selectFirst(); this.$.matches.selectFirst();
this.updateInput_( const inlineAutocompletion =
{inline: decodeString16(firstMatch.inlineAutocompletion)}); decodeString16(firstMatch.inlineAutocompletion);
if (inlineAutocompletion) {
this.updateInput_({inline: inlineAutocompletion});
}
// Navigate to the default up-to-date match if the user typed and pressed // Navigate to the default up-to-date match if the user typed and pressed
// 'Enter' too fast. // 'Enter' too fast.
...@@ -355,9 +358,11 @@ class RealboxElement extends PolymerElement { ...@@ -355,9 +358,11 @@ class RealboxElement extends PolymerElement {
} }
/** /**
* @param {!InputEvent} e
* @suppress {missingProperties} 'isComposing' is not defined on InputEvent.
* @private * @private
*/ */
onInputInput_() { onInputInput_(e) {
const inputValue = this.$.input.value; const inputValue = this.$.input.value;
this.updateInput_({text: inputValue, inline: ''}); this.updateInput_({text: inputValue, inline: ''});
...@@ -370,7 +375,10 @@ class RealboxElement extends PolymerElement { ...@@ -370,7 +375,10 @@ class RealboxElement extends PolymerElement {
charTyped ? this.charTypedTime_ || window.performance.now() : 0; charTyped ? this.charTypedTime_ || window.performance.now() : 0;
if (inputValue.trim()) { if (inputValue.trim()) {
this.queryAutocomplete_(inputValue); // TODO(crbug.com/1149769): Rather than disabling inline autocompletion
// when the input event is fired within a composition session, change the
// mechanism via which inline autocompletion is shown in the realbox.
this.queryAutocomplete_(inputValue, e.isComposing);
} else { } else {
this.matchesAreVisible = false; this.matchesAreVisible = false;
this.clearAutocompleteMatches_(); this.clearAutocompleteMatches_();
...@@ -687,13 +695,14 @@ class RealboxElement extends PolymerElement { ...@@ -687,13 +695,14 @@ class RealboxElement extends PolymerElement {
/** /**
* @param {string} input * @param {string} input
* @param {boolean} preventInlineAutocomplete
* @private * @private
*/ */
queryAutocomplete_(input) { queryAutocomplete_(input, preventInlineAutocomplete = false) {
this.lastQueriedInput_ = input; this.lastQueriedInput_ = input;
const caretNotAtEnd = this.$.input.selectionStart !== input.length; const caretNotAtEnd = this.$.input.selectionStart !== input.length;
const preventInlineAutocomplete = preventInlineAutocomplete = preventInlineAutocomplete ||
this.isDeletingInput_ || this.pastedInInput_ || caretNotAtEnd; this.isDeletingInput_ || this.pastedInInput_ || caretNotAtEnd;
this.pageHandler_.queryAutocomplete( this.pageHandler_.queryAutocomplete(
mojoString16(input), preventInlineAutocomplete); mojoString16(input), preventInlineAutocomplete);
......
...@@ -503,6 +503,20 @@ suite('NewTabPageRealboxTest', () => { ...@@ -503,6 +503,20 @@ suite('NewTabPageRealboxTest', () => {
assertEquals(1, testProxy.handler.getCallCount('queryAutocomplete')); assertEquals(1, testProxy.handler.getCallCount('queryAutocomplete'));
testProxy.handler.reset(); testProxy.handler.reset();
// If text is being composed with an IME inline autocompletion is prevented.
realbox.$.input.value = 'hello 간';
const inputEvent = new CustomEvent('input');
inputEvent.isComposing = true;
realbox.$.input.dispatchEvent(inputEvent);
await testProxy.handler.whenCalled('queryAutocomplete').then((args) => {
assertEquals(decodeString16(args.input), realbox.$.input.value);
assertTrue(args.preventInlineAutocomplete);
});
assertEquals(1, testProxy.handler.getCallCount('queryAutocomplete'));
testProxy.handler.reset();
}); });
//============================================================================ //============================================================================
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment