Draft-js: Text gets lost on mobile devices

Created on 16 Mar 2017  Â·  21Comments  Â·  Source: facebook/draft-js

I've used draft-js form and got a feedback from some users, that on mobile devices wrotten text disappears.
Couldnt reproduce it by myself, but however bug appears.

android duplicate ios

Most helpful comment

if auto-correct is on, word is replaced with a whitespace after pressing spacebar

Doesn't reproduce on older Chromium-based browsers or on older mobile Chrome 54.
Reproduces on newer mobile Chrome 58.
Keyboard-agnostic, reproduces both on GBoard or Samsung Default Keyboard (tested on a Galaxy phone).

In newer Chrome, there are no textInput + input events about the actual word confirmed and inputted.
In older Chrome, these two events are present. After these two events, another pair of textInput + input is fired, now about whitespace being inserted.

So, if we input "orange" with auto-correct, normally we expect:

  • textInput (about word "orange")
  • input
  • textInput (about " ")
  • input

In newer Chrome, first two are not fired.

Draft.js may depend on that. With what it gets, it may decide that only whitespace was inserted, and changes Editor's contents accordingly.


Working idea to solve this it to read data from compositionend event after word is entered (https://github.com/pofigizm/draft-js/commit/87ccadc56c94ffa6df813160ec81496b6b404810). Most probably Chrome's intent is that textinput event duplicated compositionend, and should've been removed.

All 21 comments

I've seen a similar issue on both android and ios browsers. I'm hoping #1035 will give us the tools to fix the problem.

+1

When I visit draftjs.org and type on my Google Pixel each word that I type disappears after I press space.

Seems to be somewhat keyboard dependent. On the draftjs.org editor using a Google Pixel XL, Android 7.1.1, Chrome 57:

  • GBoard (android default): I can type text, but as soon as I press space the word disappears. However there's a few edge cases with autocomplete. If I use the keyboards word suggestions without typing anything, that text is entered. If I start typing a word, and select an autocorrect/suggestion, the text for the current word that I've entered is removed and a portion of the autocorrection is applied.

  • SwiftKey: I can type a few letters on occasion, but generally the virtual keyboard is dismissed after typing a letter or selecting an autosuggestion.

This bug is present on Facebook's own https://www.messenger.com (you need to select "Request Desktop site" in Chrome's menu)

Looking deeper into this issue, it looks like Chrome with GBoard doesn't do the same thing as every other browser.

There's a 5 year old issue about that on Chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=118639 (marked as WontFix in 2014).

Here is a codepen that appends Draft's internal state with every "onChange": http://codepen.io/anon/pen/rmwdxz

Debugging a bit on _a real device_ with it, it looks like Chrome changes the text directly inside the contentEditable element, but sends dummy keyboard events on each keypress.

I think that any fix for this issue will have to look at what was added inside the element directly, instead of trying to catch every single event that could change the text.

if auto-correct is on, word is replaced with a whitespace after pressing spacebar

Doesn't reproduce on older Chromium-based browsers or on older mobile Chrome 54.
Reproduces on newer mobile Chrome 58.
Keyboard-agnostic, reproduces both on GBoard or Samsung Default Keyboard (tested on a Galaxy phone).

In newer Chrome, there are no textInput + input events about the actual word confirmed and inputted.
In older Chrome, these two events are present. After these two events, another pair of textInput + input is fired, now about whitespace being inserted.

So, if we input "orange" with auto-correct, normally we expect:

  • textInput (about word "orange")
  • input
  • textInput (about " ")
  • input

In newer Chrome, first two are not fired.

Draft.js may depend on that. With what it gets, it may decide that only whitespace was inserted, and changes Editor's contents accordingly.


Working idea to solve this it to read data from compositionend event after word is entered (https://github.com/pofigizm/draft-js/commit/87ccadc56c94ffa6df813160ec81496b6b404810). Most probably Chrome's intent is that textinput event duplicated compositionend, and should've been removed.

@flarnie @pofigizm we're hearing about this bug from our Android users over at Patreon. We can reproduce on newer versions of Chrome (tapping spacebar removes text). Good to know that you're working on it.
What's the plan with https://github.com/pofigizm/draft-js/commit/87ccadc56c94ffa6df813160ec81496b6b404810 moving forward? This is a significant issue for our users, so if the fix isn't likely to make it into master how dangerous would it be to point to that fork?

I didn't work on it.
@tedmx worked with the problem and going to open PR when he has free time. I don't know current status.

Sup everyone, thanks for appreciating effort of @pofigizm's team.

  • Short answer: feel free to get some insight from the repo, but please test it and don't trust it. There are many more issues which immediately crop out. Some may seem to appear because of that very fix.

Initially I thought that there are just a couple of things broken with composition*s on Android. It turns out, one issue immediately brings another to the table.

You fixed this one? Well, here you are, _deleting the symbols_ is not working. Can't blame draft-js, it's the mobile Chrome which doesn't tell a tiny distinguishable thing about backspace key -- you have no clue about the key pressed being backspace -- events have ambigous code (did I press "a"? maybe a number? maybe it was a backspace?), no special event, you have to guess from how DOM is changed. [1]

Okay, imagine we fix that somehow. Then immediately you'll find a bug of that tapping on another word while in composition mode breaks things. Seriously, just _tapping_ on other word.

So the problem with composition on Android is big, not solveable with a couple of glorious PRs with precise fixes. Chrome mobile has changed its APIs for composition* events a couple of times in just preceding month, working with it looks like a guessing game, and you'll have to build a kind of guessing adapter to get even basic stability in that area. No single fix, no fast fix, and that all should go inside 'Chrome on Android' conditional branch in source code.

The file which has to be reworked into the mega-combine is src/component/handlers/composition/DraftEditorCompositionHandler.js.

[1] Just look at that beautiful log of frustration here: https://bugs.chromium.org/p/chromium/issues/detail?id=118639#c260. We're not the only ones, guys!

Yeah, from what I have seen when I looked at it a few months ago, it looks
like an architectural issue. Draft operates by catching all keyboard events
and changing its state from that, whereas Chrome changes the DOM directly
while being quite vague on keyboard events.

Le sam. 5 août 2017 06:26, Fyodor Ananiev notifications@github.com a
écrit :

Sup everyone, thanks for appreciating effort of @pofigizm
https://github.com/pofigizm's team.

  • Short answer: feel free to get some insight from the repo, but
    please test it and don't trust it. There are many more issues which
    immediately crop out. Some may seem to appear because of that very fix.

Initially I thought that there are just a couple of things broken with
composition*s on Android. It turns out, one issue immediately brings the
other to the table.

You fixed this one? Well, here you are, deleting the symbols is not
working. Can't blame draft-js, it's the mobile Chrome which doesn't tell
a tiny distinguishable thing about backspace key -- you have no clue
about the key pressed being backspace -- events have ambigous code (did I
press "a"? maybe a number? maybe it was a backspace?), no special event,
you have to guess from how DOM is changed.

Okay, imagine we fix that somehow. Then immediately you'll find a bug of
that tapping on another word while in composition mode breaks things.
Seriously, just tapping on other word.

So the problem with composition on Android is big, not solveable with a
couple of glorious PRs with precise fixes. Chrome mobile has changed its
APIs for mobile events a couple of times in just preceding month, working
with composition* events looks like a guessing game, and you'll have to
build a kind of guessing adapter to get even basic stability in that area.
No single fix, no fast fix, and that all should go inside 'Chrome on
Android' conditional branch in source code.

The core file which has to be reworked into the mega-combine is
src/component/handlers/composition/DraftEditorCompositionHandler.js.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/facebook/draft-js/issues/1077#issuecomment-320435905,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AA2C7gIkp309408UteB9Ds_suKLNnJMFks5sVENQgaJpZM4MfRBV
.

Can repro this in browserstack with Pixel XL and default chrome browser, here's a gif of the behavior (notice after I press spacebar the word disappears):
android

I get the same issue using Chrome Mobile and Google Keyboard on a BLU Vivo 5.

And yes as @tedmx said, many things trigger it so to would be crazy to fix one by one. For what I was able to test: space key, : key, picking a word from predictive suggestions.

@ashevtcov has a PR fixing this issue, would be nice to have code review and get more support there.
https://github.com/facebook/draft-js/pull/1500

@tedmx any update on this issue? @fabiomcosta were you able to get your pull request merged?

@maxhartshorn that's not my PR, but it says it's not merged yet.

I also encountered this problem. Is it possible to come up with a solution?

@maxhartshorn
My PMs have really put off whole "we want RTE on mobile" to suspension when hearing about scale of the issue, so I have no full alternative code solution now.

Although I already have a huge recommendation to core Draft.js developers: please be flexible — fully parametrize logic from DraftEditorCompositionHandler.js ASAP. Not only it's useless for many cases, it doesn't give developers an option to use anything alternative. Make a parameter for Editor, call it something like customCompositionHandler, let it handle the stuff when present.

While Draft.js is thinking about this, end-developers may fork Draft.js and themselves do that kind of parametrization.

Everyone: when writing custom handler, be prepared for tons of work — this stuff gonna be hard. #1500 looks like 1/20th of work which must be done. Idea: start with hard copy of current DraftEditorCompositionHandler.js (it's still better than going completely from scratch), then gently go from there, fixing an issue after issue.

Has this been fixed? I'm still seeing issues.

@julianguyen No, unfortunately. It's well over a year on, and nothing seems to have been done here.

If it's never going to be actioned, it'd be great if FB made it a tad more obvious that this doesn't work...

Merging this into a general Android bug issue - see https://github.com/facebook/draft-js/issues/1895

Space bar erases previous input in Android Desktop versions of Twitter et Facebook
I have suffered the same bug for years on my Android 4 ICS (Ice Cream Sandwich), 6 Marshmallow, et 9 Pie.
After a number of tries and tests I found that, in my case at least, the bug systematically existed on facebook AND TWITTER pages in Android, NOT in Windows; when the web page was open in its DESKTOP version, NOT in the MOBILE version; and that no other change would have any influence on it (in particular changing the keyboard, as Samsung keyboard, Google Gboard, etc, or any other settings, brought no change). Only reverting from my habit of systematically requesting the desktop site as soon as arriving on any web page (Android > Chrome > Settings > Desktop site) and remaining on the MOBILE SITE did remove the bug.
Versailles, Tue 10 Sep 2019 12:37:10 +0200, edited (title turned link) 12:40:15

Was this page helpful?
0 / 5 - 0 ratings