New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 784039 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Jan 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 3
Type: Bug



Sign in to add a comment

Speaking "Hello new paragraph" into a contenteditable element using Google voice input deletes the word

Project Member Reported by rlanday@chromium.org, Nov 11 2017

Issue description

Chrome Version: (copy from chrome://version)
OS: 64.0.3262.0 (Developer build) unknown (32-bit)

What steps will reproduce the problem?
(1) Navigate to data:text/html, <div contenteditable>
(2) Tap in the editable region at the top of the page to focus it
(3) Turn on Gboard's voice input feature and say "Hello new paragraph" 

What is the expected result?

"Hello" should be input, followed by two newlines.

What happens instead?

Only two newlines are input. The problem seems to be that InputMethodController::SetComposition() doesn't work properly with text that contains two newlines in a row (maybe one is enough to trigger the issue, I have tested yet).

There's an old TODO from 2005 in TypingCommand::InsertText() that seems relevant:

https://chromium.googlesource.com/chromium/src/+/75eeaf3bcdb8a5f679133c30036a221d9275bdc0/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp#610
  // FIXME: Need to implement selectInsertedText for cases where more than one
  // insert is involved. This requires support from insertTextRunWithoutNewlines
  // and insertParagraphSeparator for extending an existing selection; at the
  // moment they can either put the caret after what's inserted or select what's
  // inserted, but there's no way to "extend selection" to include both an old
  // selection that ends just before where we want to insert text and the newly
  // inserted text.

(InputMethodController()::SetComposition uses the select_inserted_text flag to keep the newly inserted text selected, so we can convert the selection back to a composition range).

Originally reported as Google-internal b/67531447
 
I tried to take a shortcut here by just selecting everything between the position the selection starts at when TypingCommand::InsertText() and the position the selection starts and ends at after the edit, but this doesn't quite work.

I tried two different approaches:

1. Use a DOM range to mark the position the selection starts at (hoping that it gets updated properly by the edits that occur). This doesn't work because if there's a non-breaking space character and then we insert text immediately afterward with SetComposition(), the nbsp is converted to a regular space and the selection after the edit is expanded to contain the nbsp as a result of the DOM range update (this case is tested in InputMethodControllerTest_SetCompositionWithGraphemeClusterAndMultipleNodes).

2. Use a Position object to record the position. This stays the same across nbsp/space conversions, but there are other cases where the Position becomes disconnected, which makes this problematic.

I think the approach mentioned in the TODO is probably the correct one. I will try that next.
Description: Show this description
Project Member

Comment 3 by bugdroid1@chromium.org, Dec 11 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/08e7d08bb2655a8d1d7aafd9db03700492db6722

commit 08e7d08bb2655a8d1d7aafd9db03700492db6722
Author: Ryan Landay <rlanday@chromium.org>
Date: Mon Dec 11 23:17:11 2017

Fix bug where speaking "new paragraph" deletes text

Gboard's voice input feature repeatedly calls InputConnection#setComposingText()
with the in-progress text composition. If you say "new paragraph", it inserts a
pair of newlines into the text. We currently don't handle this case properly
because InputMethodController::SetComposition() calls
TypingCommand::InsertText() (through InsertTextDuringCompositionWithEvents())
with the TypingCommand::kSelectInsertedText flag (which causes InsertText() to
leave the newly-inserted text selected).

InsertText() doesn't actually implement this behavior properly if the text being
composed has a newline in it. It processes the text in multiple "runs,"
inserting line breaks in between. Currently, it inserts the first run, leaving
it selected, then inserts a line break, replacing the first run of text (and
then proceeds similarly for subsequent runs of text).

There's currently a (quite old) FIXME in the code to fix this behavior. I'm
taking a slightly different approach from the one suggested there, and selecting
the inserted text all at once in TypingCommand::InsertText() instead of trying
to modify InsertTextCommand and InsertParagraphSeparatorCommand so they can
extend the current selection. I was inspired by the implementation of
AdjustSelectionAfterIncrementalInsertion() to use a plain text offset from the
start of the editable region to determine the start of the final selection. This
approach is robust to whitespace normalization (this was a problem I ran into
trying to use a DOM range).

Note that with this fix, we no longer need the fix in
https://chromium-review.googlesource.com/c/chromium/src/+/783770 to change the
ending selection in InputMethodController::SetComposition(), as we're no longer
setting the problematic ending selection in TypingCommand::InsertText().

Bug:  784039 
Change-Id: I4b0bb95d1ecf8a979f15b3494f57a0b23e6e2459
Reviewed-on: https://chromium-review.googlesource.com/801979
Reviewed-by: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: Changwan Ryu <changwan@chromium.org>
Commit-Queue: Ryan Landay <rlanday@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523244}
[modify] https://crrev.com/08e7d08bb2655a8d1d7aafd9db03700492db6722/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
[modify] https://crrev.com/08e7d08bb2655a8d1d7aafd9db03700492db6722/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
[modify] https://crrev.com/08e7d08bb2655a8d1d7aafd9db03700492db6722/third_party/WebKit/Source/core/editing/ime/InputMethodControllerTest.cpp

Project Member

Comment 4 by bugdroid1@chromium.org, Dec 11 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/1445f647c0c8d413001c1649ce38490178283774

commit 1445f647c0c8d413001c1649ce38490178283774
Author: Ryan Landay <rlanday@chromium.org>
Date: Mon Dec 11 23:34:24 2017

Remove unused param from TypingCommand::InsertTextRunWithoutNewlines()

The select_insert_text param in this method is only ever called with false after
https://chromium-review.googlesource.com/c/chromium/src/+/801979.

Bug:  784039 
Change-Id: I3c8d0176bfb6600605d42b83676341a61fd83aac
Reviewed-on: https://chromium-review.googlesource.com/820352
Commit-Queue: Ryan Landay <rlanday@chromium.org>
Reviewed-by: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523251}
[modify] https://crrev.com/1445f647c0c8d413001c1649ce38490178283774/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
[modify] https://crrev.com/1445f647c0c8d413001c1649ce38490178283774/third_party/WebKit/Source/core/editing/commands/TypingCommand.h

Project Member

Comment 5 by bugdroid1@chromium.org, Dec 12 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/e9cfc43960a7229e83b709a76dec3dead5730348

commit e9cfc43960a7229e83b709a76dec3dead5730348
Author: Ryan Landay <rlanday@chromium.org>
Date: Tue Dec 12 01:16:39 2017

Remove select_inserted_text param from Insert[Incremental]TextCommand

After https://chromium-review.googlesource.com/c/chromium/src/+/801979, we no
longer need the select_inserted_text functionality on either InsertTextCommand
or InsertIncrementalTextCommand, so we can remove the parameter.

Bug:  784039 
Change-Id: Icfb2688a83383cea9e295186f351b6f43ffadf6c
Reviewed-on: https://chromium-review.googlesource.com/807286
Commit-Queue: Ryan Landay <rlanday@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523288}
[modify] https://crrev.com/e9cfc43960a7229e83b709a76dec3dead5730348/third_party/WebKit/Source/core/editing/commands/InsertIncrementalTextCommand.cpp
[modify] https://crrev.com/e9cfc43960a7229e83b709a76dec3dead5730348/third_party/WebKit/Source/core/editing/commands/InsertIncrementalTextCommand.h
[modify] https://crrev.com/e9cfc43960a7229e83b709a76dec3dead5730348/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp
[modify] https://crrev.com/e9cfc43960a7229e83b709a76dec3dead5730348/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.h
[modify] https://crrev.com/e9cfc43960a7229e83b709a76dec3dead5730348/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp

Comment 6 by yosin@chromium.org, Jan 10 2018

Labels: Pri-3
Status: Fixed (was: Assigned)

Sign in to add a comment