Fix an issue with removeClippedSubviews and TextInput

Summary:This issue was found by brentvatne in https://github.com/facebook/react-native/issues/6805

The problem is an ordering issue.  The internal state of the TextView (Editor) is updated when we set the text value for a ReactTextInput. When removeClippedSubviews is false, we addView the view which attaches it to the window, and then set the text. When removeClippedSubviews is false, we defer adding the view (caching it in mAllChildren in ReactViewGroup) until we know whether the view is actually going to show.  This means when we set the initial text, that there is no window attached.  Not having a window attached means that the Editor can't display the popup for PASTE and thinks that the text is not selectable and won't respond to the long press.  To fix this we explicitly call setTextIsSelectable in onAttachedToWindow.  This will cause the underlying TextView to have the Editor update and all will be in agreement.

Note:
This also makes it really easy to expose a selectable property on both Text and TextInput at the js level now.

Reviewed By: andreicoman11

Differential Revision: D3173631

fb-gh-sync-id: a208214474a92ecc1277b3be0d38e2ef9327ea2e
fbshipit-source-id: a208214474a92ecc1277b3be0d38e2ef9327ea2e
This commit is contained in:
Dave Miller 2016-04-14 03:17:14 -07:00 committed by Facebook Github Bot 3
parent a8f4159fc7
commit 89340f1620
2 changed files with 16 additions and 0 deletions

View File

@ -23,6 +23,7 @@ public class ReactTextView extends TextView implements ReactCompoundView {
private boolean mContainsImages; private boolean mContainsImages;
private int mDefaultGravityHorizontal; private int mDefaultGravityHorizontal;
private int mDefaultGravityVertical; private int mDefaultGravityVertical;
private boolean mTextIsSelectable;
public ReactTextView(Context context) { public ReactTextView(Context context) {
super(context); super(context);
@ -81,6 +82,12 @@ public class ReactTextView extends TextView implements ReactCompoundView {
return target; return target;
} }
@Override
public void setTextIsSelectable(boolean selectable) {
mTextIsSelectable = selectable;
super.setTextIsSelectable(selectable);
}
@Override @Override
protected boolean verifyDrawable(Drawable drawable) { protected boolean verifyDrawable(Drawable drawable) {
if (mContainsImages && getText() instanceof Spanned) { if (mContainsImages && getText() instanceof Spanned) {
@ -136,6 +143,7 @@ public class ReactTextView extends TextView implements ReactCompoundView {
@Override @Override
public void onAttachedToWindow() { public void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
setTextIsSelectable(mTextIsSelectable);
if (mContainsImages && getText() instanceof Spanned) { if (mContainsImages && getText() instanceof Spanned) {
Spanned text = (Spanned) getText(); Spanned text = (Spanned) getText();
TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class); TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class);

View File

@ -66,6 +66,7 @@ public class ReactEditText extends EditText {
private @Nullable ArrayList<TextWatcher> mListeners; private @Nullable ArrayList<TextWatcher> mListeners;
private @Nullable TextWatcherDelegator mTextWatcherDelegator; private @Nullable TextWatcherDelegator mTextWatcherDelegator;
private int mStagedInputType; private int mStagedInputType;
private boolean mTextIsSelectable = true;
private boolean mContainsImages; private boolean mContainsImages;
private boolean mBlurOnSubmit; private boolean mBlurOnSubmit;
private @Nullable SelectionWatcher mSelectionWatcher; private @Nullable SelectionWatcher mSelectionWatcher;
@ -215,6 +216,12 @@ public class ReactEditText extends EditText {
setKeyListener(mKeyListener); setKeyListener(mKeyListener);
} }
@Override
public void setTextIsSelectable(boolean selectable) {
mTextIsSelectable = selectable;
super.setTextIsSelectable(selectable);
}
// VisibleForTesting from {@link TextInputEventsTestCase}. // VisibleForTesting from {@link TextInputEventsTestCase}.
public void requestFocusFromJS() { public void requestFocusFromJS() {
mIsJSSettingFocus = true; mIsJSSettingFocus = true;
@ -389,6 +396,7 @@ public class ReactEditText extends EditText {
@Override @Override
public void onAttachedToWindow() { public void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
setTextIsSelectable(mTextIsSelectable);
if (mContainsImages && getText() instanceof Spanned) { if (mContainsImages && getText() instanceof Spanned) {
Spanned text = (Spanned) getText(); Spanned text = (Spanned) getText();
TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class); TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class);