mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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
This commit is contained in:
committed by
Facebook Github Bot
parent
183b1c13c4
commit
27d61388bd
@@ -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<TextWatcher> 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;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -239,6 +239,7 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
// instead of calling setText, etc directly - doing that will definitely cause bugs.
|
||||
reactEditText.maybeSetTextFromJS(
|
||||
getReactTextUpdate(text, mostRecentEventCount, start, end));
|
||||
reactEditText.maybeSetSelection(mostRecentEventCount, start, end);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -281,8 +282,8 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
TextInlineImageSpan.possiblyUpdateInlineImageSpans(spannable, view);
|
||||
}
|
||||
view.maybeSetTextFromState(update);
|
||||
if (update.getSelectionStart() != UNSET && update.getSelectionEnd() != UNSET)
|
||||
view.setSelection(update.getSelectionStart(), update.getSelectionEnd());
|
||||
view.maybeSetSelection(
|
||||
update.getJsEventCounter(), update.getSelectionStart(), update.getSelectionEnd());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user