From 27d61388bd3c48f24788a3ef2fad28eb30866df3 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Thu, 23 Jan 2020 19:25:35 -0800 Subject: [PATCH] TextInput: update selection on native when JS calls view command Summary: We should have been calling this already. Trivial fix. The intent of the view command was always to update selection, I just forgot to add it. See test videos. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D19548178 fbshipit-source-id: 14a1bdc11d84c05f2435c48c3bb96b64e8c68cb4 --- .../react/views/textinput/ReactEditText.java | 26 ++++++++++++++++++- .../textinput/ReactTextInputManager.java | 5 ++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java index 67b4c1aa702..639e01ba1eb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java @@ -80,6 +80,8 @@ public class ReactEditText extends AppCompatEditText { /** The most recent event number acked by JavaScript. Should only be updated from JS, not C++. */ protected int mMostRecentEventCount; + private static final int UNSET = -1; + private @Nullable ArrayList mListeners; private @Nullable TextWatcherDelegator mTextWatcherDelegator; private int mStagedInputType; @@ -296,6 +298,24 @@ public class ReactEditText extends AppCompatEditText { mScrollWatcher = scrollWatcher; } + /** + * Attempt to set a selection or fail silently. Intentionally meant to handle bad inputs. + * EventCounter is the same one used as with text. + * + * @param eventCounter + * @param start + * @param end + */ + public void maybeSetSelection(int eventCounter, int start, int end) { + if (!canUpdateWithEventCount(eventCounter)) { + return; + } + + if (start != UNSET && end != UNSET) { + setSelection(start, end); + } + } + @Override public void setSelection(int start, int end) { // Skip setting the selection if the text wasn't set because of an out of date value. @@ -465,6 +485,10 @@ public class ReactEditText extends AppCompatEditText { mIsSettingTextFromState = false; } + public boolean canUpdateWithEventCount(int eventCounter) { + return eventCounter >= mNativeEventCount; + } + // VisibleForTesting from {@link TextInputEventsTestCase}. public void maybeSetText(ReactTextUpdate reactTextUpdate) { if (isSecureText() && TextUtils.equals(getText(), reactTextUpdate.getText())) { @@ -473,7 +497,7 @@ public class ReactEditText extends AppCompatEditText { // Only set the text if it is up to date. mMostRecentEventCount = reactTextUpdate.getJsEventCounter(); - if (mMostRecentEventCount < mNativeEventCount) { + if (!canUpdateWithEventCount(mMostRecentEventCount)) { return; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 423fd80a300..2e3bcf41507 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -239,6 +239,7 @@ public class ReactTextInputManager extends BaseViewManager