mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
TextInput: support text value+child Text nodes
Summary: Fix and simplify `AndroidTextInputShadowNode::getAttributedString` so that it (1) works, and (2) is aligned with the equivalents in the old Java code. The issue is that we weren't picking up `text` attributes since we're only traversing children and not the TextInput node itself. If a `text` attribute is present it needs to be treated as its own Text node. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D18739830 fbshipit-source-id: 4b3bc81dbe8c241c2e06fe5be1f9b50e49132890
This commit is contained in:
committed by
Facebook Github Bot
parent
7590d9f8f4
commit
a09346f129
+39
-33
@@ -16,8 +16,6 @@
|
||||
#include <react/core/conversions.h>
|
||||
#include <react/jni/ReadableNativeMap.h>
|
||||
|
||||
#include <Glog/logging.h>
|
||||
|
||||
using namespace facebook::jni;
|
||||
|
||||
namespace facebook {
|
||||
@@ -33,44 +31,52 @@ void AndroidTextInputShadowNode::setContextContainer(
|
||||
|
||||
AttributedString AndroidTextInputShadowNode::getAttributedString(
|
||||
bool usePlaceholders) const {
|
||||
auto textAttributes = TextAttributes::defaultTextAttributes();
|
||||
textAttributes.apply(getProps()->textAttributes);
|
||||
|
||||
// Use BaseTextShadowNode to get attributed string from children
|
||||
auto const &attributedString =
|
||||
BaseTextShadowNode::getAttributedString(textAttributes, *this);
|
||||
auto childTextAttributes = TextAttributes::defaultTextAttributes();
|
||||
childTextAttributes.apply(getProps()->textAttributes);
|
||||
auto attributedString =
|
||||
BaseTextShadowNode::getAttributedString(childTextAttributes, *this);
|
||||
|
||||
// BaseTextShadowNode only gets children. We must detect and prepend text
|
||||
// value attributes manually.
|
||||
if (!getProps()->text.empty()) {
|
||||
auto textAttributes = TextAttributes::defaultTextAttributes();
|
||||
textAttributes.apply(getProps()->textAttributes);
|
||||
auto fragment = AttributedString::Fragment{};
|
||||
fragment.string = getProps()->text;
|
||||
fragment.textAttributes = textAttributes;
|
||||
fragment.parentShadowView = ShadowView(*this);
|
||||
attributedString.prependFragment(fragment);
|
||||
|
||||
// We know this is not empty, because we at least have the `text` value
|
||||
return attributedString;
|
||||
}
|
||||
|
||||
// No need to use placeholder if we have text at this point.
|
||||
if (!attributedString.isEmpty()) {
|
||||
return attributedString;
|
||||
}
|
||||
if (!getProps()->text.empty() || usePlaceholders) {
|
||||
// If the BaseTextShadowNode didn't detect any child Text nodes, we
|
||||
// may actually just have a `text` attribute.
|
||||
// TODO: figure out why BaseTextShadowNode doesn't pick this up, this
|
||||
// is a bug. A minimal Playground example that triggers this: P122991121
|
||||
auto textAttributedString = AttributedString{};
|
||||
auto fragment = AttributedString::Fragment{};
|
||||
fragment.string = getProps()->text;
|
||||
|
||||
if (usePlaceholders) {
|
||||
// Return placeholder text instead, if text was empty.
|
||||
if (fragment.string.empty()) {
|
||||
fragment.string = getProps()->placeholder;
|
||||
}
|
||||
// For measurement purposes, we want to make sure that there's at least a
|
||||
// single character in the string so that the measured height is greater
|
||||
// than zero. Otherwise, empty TextInputs with no placeholder don't
|
||||
// display at all.
|
||||
if (fragment.string.empty()) {
|
||||
fragment.string = " ";
|
||||
}
|
||||
}
|
||||
fragment.textAttributes = textAttributes;
|
||||
fragment.parentShadowView = ShadowView(*this);
|
||||
textAttributedString.appendFragment(fragment);
|
||||
return textAttributedString;
|
||||
// Return placeholder text, since text and children are empty.
|
||||
auto textAttributedString = AttributedString{};
|
||||
auto fragment = AttributedString::Fragment{};
|
||||
fragment.string = getProps()->placeholder;
|
||||
|
||||
// For measurement purposes, we want to make sure that there's at least a
|
||||
// single character in the string so that the measured height is greater
|
||||
// than zero. Otherwise, empty TextInputs with no placeholder don't
|
||||
// display at all.
|
||||
if (fragment.string.empty() && usePlaceholders) {
|
||||
fragment.string = " ";
|
||||
}
|
||||
|
||||
return attributedString;
|
||||
auto textAttributes = TextAttributes::defaultTextAttributes();
|
||||
textAttributes.apply(getProps()->textAttributes);
|
||||
|
||||
fragment.textAttributes = textAttributes;
|
||||
fragment.parentShadowView = ShadowView(*this);
|
||||
textAttributedString.appendFragment(fragment);
|
||||
return textAttributedString;
|
||||
}
|
||||
|
||||
void AndroidTextInputShadowNode::setTextLayoutManager(
|
||||
|
||||
Reference in New Issue
Block a user