Fix TextInput Spannable flags

Summary:
The TextInput spannables are being set wrong by Nodes. Consequently,
when you hit space after a word, anything you type is highlighted, though it
shouldn't be.

Differential Revision: D3507516
This commit is contained in:
Ahmed El-Helw 2016-07-01 15:12:57 -07:00
parent 1b77f1a372
commit 4622532ca4
6 changed files with 38 additions and 12 deletions

View File

@ -59,17 +59,25 @@ import com.facebook.react.uimanager.ReactShadowNode;
return false;
}
/* package */ boolean isEditable() {
return false;
}
/**
* Recursively visits FlatTextShadowNode and its children,
* applying spans to SpannableStringBuilder.
*/
/* package */ final void applySpans(SpannableStringBuilder builder) {
/* package */ final void applySpans(SpannableStringBuilder builder, boolean isEditable) {
if (mTextBegin != mTextEnd || shouldAllowEmptySpans()) {
performApplySpans(builder, mTextBegin, mTextEnd);
performApplySpans(builder, mTextBegin, mTextEnd, isEditable);
}
}
protected abstract void performCollectText(SpannableStringBuilder builder);
protected abstract void performApplySpans(SpannableStringBuilder builder, int begin, int end);
protected abstract void performApplySpans(
SpannableStringBuilder builder,
int begin,
int end,
boolean isEditable);
protected abstract void performCollectAttachDetachListeners(StateBuilder stateBuilder);
}

View File

@ -31,7 +31,11 @@ import com.facebook.react.uimanager.annotations.ReactProp;
}
@Override
protected void performApplySpans(SpannableStringBuilder builder, int begin, int end) {
protected void performApplySpans(
SpannableStringBuilder builder,
int begin,
int end,
boolean isEditable) {
builder.setSpan(
this,
begin,

View File

@ -50,7 +50,11 @@ import com.facebook.react.uimanager.annotations.ReactProp;
}
@Override
protected void performApplySpans(SpannableStringBuilder builder, int begin, int end) {
protected void performApplySpans(
SpannableStringBuilder builder,
int begin,
int end,
boolean isEditable) {
mInlineImageSpan.freeze();
builder.setSpan(
mInlineImageSpan,

View File

@ -169,6 +169,11 @@ public class RCTTextInput extends RCTVirtualText implements AndroidView, CSSNode
return true;
}
@Override
boolean isEditable() {
return true;
}
@Override
protected void performCollectText(SpannableStringBuilder builder) {
if (mText != null) {

View File

@ -54,14 +54,19 @@ import com.facebook.react.uimanager.annotations.ReactProp;
}
@Override
protected void performApplySpans(SpannableStringBuilder builder, int begin, int end) {
protected void performApplySpans(SpannableStringBuilder builder, int begin, int end, boolean isEditable) {
mFontStylingSpan.freeze();
// All spans will automatically extend to the right of the text, but not the left - except
// for spans that start at the beginning of the text.
final int flag = begin == 0 ?
Spannable.SPAN_INCLUSIVE_INCLUSIVE :
Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
final int flag;
if (isEditable) {
flag = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE;
} else {
flag = begin == 0 ?
Spannable.SPAN_INCLUSIVE_INCLUSIVE :
Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
}
builder.setSpan(
mFontStylingSpan,
@ -81,7 +86,7 @@ import com.facebook.react.uimanager.annotations.ReactProp;
for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {
FlatTextShadowNode child = (FlatTextShadowNode) getChildAt(i);
child.applySpans(builder);
child.applySpans(builder, isEditable);
}
}
@ -259,7 +264,7 @@ import com.facebook.react.uimanager.annotations.ReactProp;
/* package */ final SpannableStringBuilder getText() {
SpannableStringBuilder sb = new SpannableStringBuilder();
collectText(sb);
applySpans(sb);
applySpans(sb, isEditable());
return sb;
}

View File

@ -233,7 +233,7 @@ import com.facebook.react.uimanager.events.EventDispatcher;
float clipBottom) {
boolean hasUpdates = node.hasNewLayout();
boolean expectingUpdate = hasUpdates || node.isUpdated() ||
boolean expectingUpdate = hasUpdates || node.isUpdated() || node.hasUnseenUpdates() ||
node.clipBoundsChanged(clipLeft, clipTop, clipRight, clipBottom);
if (SKIP_UP_TO_DATE_NODES && !expectingUpdate) {
return false;