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:
parent
1b77f1a372
commit
4622532ca4
|
@ -59,17 +59,25 @@ import com.facebook.react.uimanager.ReactShadowNode;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* package */ boolean isEditable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively visits FlatTextShadowNode and its children,
|
* Recursively visits FlatTextShadowNode and its children,
|
||||||
* applying spans to SpannableStringBuilder.
|
* applying spans to SpannableStringBuilder.
|
||||||
*/
|
*/
|
||||||
/* package */ final void applySpans(SpannableStringBuilder builder) {
|
/* package */ final void applySpans(SpannableStringBuilder builder, boolean isEditable) {
|
||||||
if (mTextBegin != mTextEnd || shouldAllowEmptySpans()) {
|
if (mTextBegin != mTextEnd || shouldAllowEmptySpans()) {
|
||||||
performApplySpans(builder, mTextBegin, mTextEnd);
|
performApplySpans(builder, mTextBegin, mTextEnd, isEditable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void performCollectText(SpannableStringBuilder builder);
|
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);
|
protected abstract void performCollectAttachDetachListeners(StateBuilder stateBuilder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,11 @@ import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void performApplySpans(SpannableStringBuilder builder, int begin, int end) {
|
protected void performApplySpans(
|
||||||
|
SpannableStringBuilder builder,
|
||||||
|
int begin,
|
||||||
|
int end,
|
||||||
|
boolean isEditable) {
|
||||||
builder.setSpan(
|
builder.setSpan(
|
||||||
this,
|
this,
|
||||||
begin,
|
begin,
|
||||||
|
|
|
@ -50,7 +50,11 @@ import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void performApplySpans(SpannableStringBuilder builder, int begin, int end) {
|
protected void performApplySpans(
|
||||||
|
SpannableStringBuilder builder,
|
||||||
|
int begin,
|
||||||
|
int end,
|
||||||
|
boolean isEditable) {
|
||||||
mInlineImageSpan.freeze();
|
mInlineImageSpan.freeze();
|
||||||
builder.setSpan(
|
builder.setSpan(
|
||||||
mInlineImageSpan,
|
mInlineImageSpan,
|
||||||
|
|
|
@ -169,6 +169,11 @@ public class RCTTextInput extends RCTVirtualText implements AndroidView, CSSNode
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isEditable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void performCollectText(SpannableStringBuilder builder) {
|
protected void performCollectText(SpannableStringBuilder builder) {
|
||||||
if (mText != null) {
|
if (mText != null) {
|
||||||
|
|
|
@ -54,14 +54,19 @@ import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void performApplySpans(SpannableStringBuilder builder, int begin, int end) {
|
protected void performApplySpans(SpannableStringBuilder builder, int begin, int end, boolean isEditable) {
|
||||||
mFontStylingSpan.freeze();
|
mFontStylingSpan.freeze();
|
||||||
|
|
||||||
// All spans will automatically extend to the right of the text, but not the left - except
|
// 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.
|
// for spans that start at the beginning of the text.
|
||||||
final int flag = begin == 0 ?
|
final int flag;
|
||||||
|
if (isEditable) {
|
||||||
|
flag = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE;
|
||||||
|
} else {
|
||||||
|
flag = begin == 0 ?
|
||||||
Spannable.SPAN_INCLUSIVE_INCLUSIVE :
|
Spannable.SPAN_INCLUSIVE_INCLUSIVE :
|
||||||
Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
|
Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
|
||||||
|
}
|
||||||
|
|
||||||
builder.setSpan(
|
builder.setSpan(
|
||||||
mFontStylingSpan,
|
mFontStylingSpan,
|
||||||
|
@ -81,7 +86,7 @@ import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
|
|
||||||
for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {
|
for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {
|
||||||
FlatTextShadowNode child = (FlatTextShadowNode) getChildAt(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() {
|
/* package */ final SpannableStringBuilder getText() {
|
||||||
SpannableStringBuilder sb = new SpannableStringBuilder();
|
SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||||
collectText(sb);
|
collectText(sb);
|
||||||
applySpans(sb);
|
applySpans(sb, isEditable());
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -233,7 +233,7 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
||||||
float clipBottom) {
|
float clipBottom) {
|
||||||
boolean hasUpdates = node.hasNewLayout();
|
boolean hasUpdates = node.hasNewLayout();
|
||||||
|
|
||||||
boolean expectingUpdate = hasUpdates || node.isUpdated() ||
|
boolean expectingUpdate = hasUpdates || node.isUpdated() || node.hasUnseenUpdates() ||
|
||||||
node.clipBoundsChanged(clipLeft, clipTop, clipRight, clipBottom);
|
node.clipBoundsChanged(clipLeft, clipTop, clipRight, clipBottom);
|
||||||
if (SKIP_UP_TO_DATE_NODES && !expectingUpdate) {
|
if (SKIP_UP_TO_DATE_NODES && !expectingUpdate) {
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue