/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.flat;
import android.text.SpannableStringBuilder;
import com.facebook.react.uimanager.ReactShadowNode;
/**
* Base class for RCTVirtualText and RCTRawText.
*/
/* package */ abstract class FlatTextShadowNode extends FlatShadowNode {
// these 2 are only used between collectText() and applySpans() calls.
private int mTextBegin;
private int mTextEnd;
/**
* Propagates changes up to RCTText without dirtying current node.
*/
protected void notifyChanged(boolean shouldRemeasure) {
ReactShadowNode parent = getParent();
if (parent instanceof FlatTextShadowNode) {
((FlatTextShadowNode) parent).notifyChanged(shouldRemeasure);
}
}
@Override
public boolean isVirtual() {
return true;
}
/**
* Recursively visits FlatTextShadowNode and its children,
* appending text to SpannableStringBuilder.
*/
/* package */ final void collectText(SpannableStringBuilder builder) {
mTextBegin = builder.length();
performCollectText(builder);
mTextEnd = builder.length();
}
/**
* Whether or not to allow empty spans to be set
* This is used to bypass an optimization in {@code applySpans} that skips applying spans if
* there is no text (since, for TextInput, for example, we want to apply the span even if there
* is no text so that newly typed text gets styled properly).
*
* @return a boolean representing whether or not we should allow empty spans
*/
/* package */ boolean shouldAllowEmptySpans() {
return false;
}
/* package */ boolean isEditable() {
return false;
}
/**
* Recursively visits FlatTextShadowNode and its children,
* applying spans to SpannableStringBuilder.
*/
/* package */ final void applySpans(SpannableStringBuilder builder, boolean isEditable) {
if (mTextBegin != mTextEnd || shouldAllowEmptySpans()) {
performApplySpans(builder, mTextBegin, mTextEnd, isEditable);
}
}
protected abstract void performCollectText(SpannableStringBuilder builder);
protected abstract void performApplySpans(
SpannableStringBuilder builder,
int begin,
int end,
boolean isEditable);
protected abstract void performCollectAttachDetachListeners(StateBuilder stateBuilder);
}