slate
slate copied to clipboard
Spellcheck On Android: Cursor Position Jumps To Corrected Letter & Inserts Space
Description
Firstly, THANK YOU SO MUCH to all those who have contributed to Android support improvements. It is finally usable for us with the most recent releases, but with a small new issue introduced:
As shown in the recording from one of our users, when applying a spellcheck correction on an Android device, the cursor position jumps to the letter that was changed and inserts a space right after it.
Recording
https://user-images.githubusercontent.com/34203886/137451687-d4590147-a46b-46ae-82b6-aeca83364581.mp4
Sandbox This should be reproducible on the Slate website: https://www.slatejs.org/examples/richtext
In case this is helpful, our Android test user reported this on our test environment (a simple sign up and go to "New Post" to find the editor) for this PR which simply updates all Slate packages to latest (currently 0.66.5
for slate
)
Steps To reproduce the behavior:
- On an Android device, type in the editor and make a spelling mistake
- Click on the correct suggestion from to correct the spelling
- Observe behaviour shown in the recording
Expectation See above.
Environment
- Slate Version: 0.66.5
- Operating System: Android
- Browser: Chrome
Context Until now we've had major IME and Android support issues where every word was doubled upon input, and deleting texts would insert more words with the cursor jumping all over the place. So this is still a HUGE improvement and finally makes the experience at least usable, albeit frustrating for Android users that are using spellcheck.
Hi @clauderic ! I hope you don't mind me tagging you but I know you've been a huge wealth of knowledge and contribution to this project and especially issues around Android support. I'd be more than happy to try and investigate this but honestly I have zero experience or expertise with Android development - is there any chance that on first glance at this issue, you have an immediate idea of where the problem is likely occurring to point me in the right direction?
Thanks so much for any time or thoughts you might have for this, ami!
@Slapbox I noticed you were having a quick look at this, I was just wondering if you have any initial ideas as to what could be causing this or where I could start digging around? I wish I was more familiar with addressing Android-specific issues. No worries at all if you don't have time to get back to me, I just wanted to see if there's anything I can do to support moving this forward in any way.
Thanks for all that you do 🙏🏼
@robin-macpherson unfortunately we're still on the 0.45.x
branch of Slate so I don't have any insights into what's going on here. I've just been poking around the latest version as we prepare for the sure-to-be arduous task of upgrading from 0.45.x
all the way up to 0.70.x
. All credit for things being as good as they are on Android to @thesunny and the work he's helped organize.
@thesunny is this just the state of things right now, or maybe a regression? Do you know if there are old versions of the examples available online for users to test with to try to do a sort of unofficial git bisect
without the git
part? Or are we limited to the Netlify deploy previews?
@Slapbox @robin-macpherson
Generally speaking (if I'm remembering correctly as it has been a while), whenever we do a spellcheck fix in Android, we wait for the compositionend
event and then we do a diff between the actual DOM text (i.e. what's in the browser) and the text that is in Slate's value
. We then apply that change to Slate's value and that updates the DOM.
I wonder if a recent version of Android is taking a spell check fix and executing it as (1) applying the spelling fix to the browser DOM in Android (2) moving the cursor to the end of the word (3) compositionend
fires (4) hitting the space to move onto the next word. Slate may then be reacting at step 3 above and doing (3a) read the DOM and diff it (3b) updating the value (3c) updating the DOM and leaving the cursor at the position where the change was made. Now the cursor is at the spell fix location and then (4) we get the space event. Slate reads the space event from Android then inserts the space at the wrong location. The fix might be to detect when a spell check has happened and make sure the cursor is at the end of the word so that when the space event happens, the cursor is at the end of the word.
I think it's possible, perhaps even likely, that this series of events isn't exactly what is happening; however, it's probably a good place to start the investigation. While checking these assumptions, I'm guessing it may reveal what's actually happening.
Going into the future, I think it might be worthwhile to include in the source code and/or in the documentation, more details about how Android support works. Unfortunately, my hope that the community would take up more of the load for supporting Android hasn't really panned out and I think that may be because it is hard to get up to speed on what's happening in the code. Also looking at the source code doesn't provide enough high level overview about why things are the way they are. With Android in particular, things happen at times that are not obvious from the source code and they also differ sometimes from version to version of Android. For example, the fact that enter
and space
trigger differently than other composition changes like typing, spell fixes, autocorrect, swipe gestures, etc.
@thesunny and @Slapbox - thank you both very much for your replies!
That's really helpful context @thesunny 🙏🏼 I'm sorry that the community hasn't taken up as much of the load as you had hoped with Android support - I spent a number of hours the other day reading through the long history of Android-related issues and PRs and saw how much you've been involved. So first of all thanks so much for everything you've done.
As I mentioned, this really isn't my team's area of expertise at all but we'd really like to try and help move these things forwards so I'll chat with my core teammate and we'll happily try our best to start investigating from the suggestions you provided and will see if we can get a PR together. I'll keep you updated!
@thesunny thanks for the explanation! I hope that community support for Slate Android will pick up in the next year. I think it was severely hampered by the fact that the community got split in two by the release of 0.50.x
as soon as Android support was starting to coalesce. We're still on 0.45.1
here, so any contributions we might have been able to make never happened since we're still on the other side of that divide.
I suspect we're not the only ones in this situation, and I'm hopeful that the community will be able to pick up more of the slack as things continue on. If we upgrade to 0.50.x
in the first half of 2022 as we intend to, then probably by the end of the year we'd be able to resume contributing to Slate; not to say that we contributed a ton, but I suspect this is a common situation and the missing contributions from various developers adds up.
When that time does come though, like you mentioned, well documented code will be the greatest gift to those hoping to contribute - because yeah, Android's composition management is some craziness that confuses the hell out of me, and even with my minimal understanding I'm probably in the 95th percentile as far as comprehending what's going on. I think it's going to be a rocky 12 to 18 months as far as the community taking up the mantle, but I remain hopeful in the long term.
I also remain hopeful that Android's own idiosyncrasies will smooth out in the coming years as older versions fall away and newer versions hopefully act more uniformly. Have you noticed that to be the case at all so far @thesunny?
A huge thank you again for your incredible organizing and development work!
@thesunny just FYI I've started looking into this. To be honest I'm still having trouble wrapping my head around how things specific to Android support work and haven't managed to get far enough to put up a PR yet, but I'm trying and have continued trying to see if I can find someone to help me through fixing this. Fingers crossed and thanks again for the really helpful info you provided to get me started 🤞🏼
Facebook just released Lexical. Editing works pretty smoothly on Android (including timetravel tool to step through the state.)
I wonder if there might be any relevant code that can be poached from Lexical and integrated into Slate?
https://github.com/facebook/lexical/search?q=composition