Skip to content

Commit 254ebab

Browse files
JoshuaGrossfacebook-github-bot
authored andcommitted
AndroidTextInput: don't set TextInput value to placeholder; use eventCounter prop to send tree updates via state
Summary: Fix (1) placeholder (2) modifying TextInput in Fabric on Android. Changelog: [internal] Reviewed By: mdvacca Differential Revision: D18894538 fbshipit-source-id: 21103f56e6f6e108fcf6359a23c9dd9a0323250e
1 parent 5215703 commit 254ebab

File tree

2 files changed

+23
-22
lines changed

2 files changed

+23
-22
lines changed

ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,23 @@ AttributedString AndroidTextInputShadowNode::getAttributedString() const {
5050
fragment.textAttributes.backgroundColor = clearColor();
5151
fragment.parentShadowView = ShadowView(*this);
5252
attributedString.prependFragment(fragment);
53-
54-
// We know this is not empty, because we at least have the `text` value
55-
return attributedString;
56-
}
57-
58-
// No need to use placeholder if we have text at this point.
59-
if (!attributedString.isEmpty()) {
60-
return attributedString;
6153
}
6254

63-
return getPlaceholderAttributedString(false);
55+
return attributedString;
6456
}
6557

6658
// For measurement purposes, we want to make sure that there's at least a
6759
// single character in the string so that the measured height is greater
6860
// than zero. Otherwise, empty TextInputs with no placeholder don't
6961
// display at all.
70-
AttributedString AndroidTextInputShadowNode::getPlaceholderAttributedString(
71-
bool ensureMinimumLength) const {
62+
AttributedString AndroidTextInputShadowNode::getPlaceholderAttributedString()
63+
const {
7264
// Return placeholder text, since text and children are empty.
7365
auto textAttributedString = AttributedString{};
7466
auto fragment = AttributedString::Fragment{};
7567
fragment.string = getProps()->placeholder;
7668

77-
if (fragment.string.empty() && ensureMinimumLength) {
69+
if (fragment.string.empty()) {
7870
fragment.string = " ";
7971
}
8072

@@ -123,13 +115,23 @@ void AndroidTextInputShadowNode::updateStateIfNeeded() {
123115
auto defaultTextAttributes = TextAttributes::defaultTextAttributes();
124116
defaultTextAttributes.apply(getProps()->textAttributes);
125117

126-
setStateData(AndroidTextInputState{state.mostRecentEventCount,
127-
reactTreeAttributedString,
128-
reactTreeAttributedString,
129-
getProps()->paragraphAttributes,
130-
defaultTextAttributes,
131-
ShadowView(*this),
132-
textLayoutManager_});
118+
// Even if we're here and updating state, it may be only to update the layout
119+
// manager If that is the case, make sure we don't update text: pass in the
120+
// current attributedString unchanged, and pass in zero for the "event count"
121+
// so no changes are applied There's no way to prevent a state update from
122+
// flowing to Java, so we just ensure it's a noop in those cases.
123+
setStateData(AndroidTextInputState{
124+
(state.reactTreeAttributedString == reactTreeAttributedString
125+
? 0
126+
: getProps()->mostRecentEventCount),
127+
(state.reactTreeAttributedString == reactTreeAttributedString
128+
? state.attributedString
129+
: reactTreeAttributedString),
130+
reactTreeAttributedString,
131+
getProps()->paragraphAttributes,
132+
defaultTextAttributes,
133+
ShadowView(*this),
134+
textLayoutManager_});
133135
}
134136

135137
#pragma mark - LayoutableShadowNode
@@ -141,7 +143,7 @@ Size AndroidTextInputShadowNode::measure(
141143
AttributedString attributedString = state.attributedString;
142144

143145
if (attributedString.isEmpty()) {
144-
attributedString = getPlaceholderAttributedString(true);
146+
attributedString = getPlaceholderAttributedString();
145147
}
146148

147149
if (attributedString.isEmpty()) {

ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ class AndroidTextInputShadowNode : public ConcreteViewShadowNode<
3838
* Returns a `AttributedString` which represents text content of the node.
3939
*/
4040
AttributedString getAttributedString() const;
41-
AttributedString getPlaceholderAttributedString(
42-
bool ensureMinimumLength) const;
41+
AttributedString getPlaceholderAttributedString() const;
4342

4443
/*
4544
* Associates a shared TextLayoutManager with the node.

0 commit comments

Comments
 (0)