From 38ca607428023d56ffb467456769094fc1dc3c96 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 9 Jun 2026 09:11:17 -0700 Subject: [PATCH 1/2] Simplify `BaseTextProps::appendTextAttributesProps` (#57150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: `BaseTextProps::appendTextAttributesProps` builds a `folly::dynamic` diff of ~29 text attributes through a long flat sequence of per-attribute `if (changed) result[key] = ...` blocks, many with an embedded `has_value() ? convert(...) : nullptr` ternary. That gave the function a cyclomatic complexity (CCN) of 47, well into the "complex, hard to test" range. This is a pure, behavior-preserving refactor. The four recurring compare-and-assign shapes — plain `!=`, `floatEquality`, optional-with-converter, and color dereference — are pulled into small file-local `static` helpers, and the function body becomes a flat list of helper calls in the exact same order, with the exact same keys, conversions, and values. The serialized output (including `folly::dynamic` insertion order) is identical. Only the `.cpp` is touched; there are no public header or API changes. Changelog: [Internal] Differential Revision: D108027815 --- .../components/text/BaseTextProps.cpp | 376 ++++++++++-------- 1 file changed, 208 insertions(+), 168 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp index e2ab6780f96d..8c3562cd79b1 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp @@ -354,185 +354,225 @@ static folly::dynamic toDynamic(const Size& size) { return sizeResult; } -void BaseTextProps::appendTextAttributesProps( +// Behavior-preserving helpers extracted from appendTextAttributesProps below to +// keep its cyclomatic complexity low. Each mirrors one of the recurring +// compare-and-assign shapes used per text attribute, so the serialized output +// (keys, values, and insertion order) is identical to the open-coded version. +template +static void appendIfChanged( folly::dynamic& result, - const BaseTextProps* oldProps) const { - if (textAttributes.foregroundColor != - oldProps->textAttributes.foregroundColor) { - result["color"] = *textAttributes.foregroundColor; - } - - if (textAttributes.fontFamily != oldProps->textAttributes.fontFamily) { - result["fontFamily"] = textAttributes.fontFamily; - } - - if (!floatEquality( - textAttributes.fontSize, oldProps->textAttributes.fontSize)) { - result["fontSize"] = textAttributes.fontSize; - } - - if (!floatEquality( - textAttributes.fontSizeMultiplier, - oldProps->textAttributes.fontSizeMultiplier)) { - result["fontSizeMultiplier"] = textAttributes.fontSizeMultiplier; - } - - if (textAttributes.fontWeight != oldProps->textAttributes.fontWeight) { - result["fontWeight"] = textAttributes.fontWeight.has_value() - ? toString(textAttributes.fontWeight.value()) - : folly::dynamic(nullptr); - } - - if (textAttributes.fontStyle != oldProps->textAttributes.fontStyle) { - result["fontStyle"] = textAttributes.fontStyle.has_value() - ? toString(textAttributes.fontStyle.value()) - : folly::dynamic(nullptr); - } - - if (textAttributes.fontVariant != oldProps->textAttributes.fontVariant) { - result["fontVariant"] = textAttributes.fontVariant.has_value() - ? toString(textAttributes.fontVariant.value()) - : folly::dynamic(nullptr); - } - - if (textAttributes.allowFontScaling != - oldProps->textAttributes.allowFontScaling) { - result["allowFontScaling"] = textAttributes.allowFontScaling.has_value() - ? textAttributes.allowFontScaling.value() - : folly::dynamic(nullptr); - } - - if (!floatEquality( - textAttributes.maxFontSizeMultiplier, - oldProps->textAttributes.maxFontSizeMultiplier)) { - result["maxFontSizeMultiplier"] = textAttributes.maxFontSizeMultiplier; - } - - if (textAttributes.dynamicTypeRamp != - oldProps->textAttributes.dynamicTypeRamp) { - result["dynamicTypeRamp"] = textAttributes.dynamicTypeRamp.has_value() - ? toString(textAttributes.dynamicTypeRamp.value()) - : folly::dynamic(nullptr); - } - - if (!floatEquality( - textAttributes.letterSpacing, - oldProps->textAttributes.letterSpacing)) { - result["letterSpacing"] = textAttributes.letterSpacing; - } - - if (textAttributes.textTransform != oldProps->textAttributes.textTransform) { - result["textTransform"] = textAttributes.textTransform.has_value() - ? toString(textAttributes.textTransform.value()) - : folly::dynamic(nullptr); - } - - if (!floatEquality( - textAttributes.lineHeight, oldProps->textAttributes.lineHeight)) { - result["lineHeight"] = textAttributes.lineHeight; - } - - if (textAttributes.alignment != oldProps->textAttributes.alignment) { - result["textAlign"] = textAttributes.alignment.has_value() - ? toString(textAttributes.alignment.value()) - : folly::dynamic(nullptr); - } - - if (textAttributes.baseWritingDirection != - oldProps->textAttributes.baseWritingDirection) { - result["baseWritingDirection"] = - textAttributes.baseWritingDirection.has_value() - ? toString(textAttributes.baseWritingDirection.value()) - : folly::dynamic(nullptr); - } - - if (textAttributes.lineBreakStrategy != - oldProps->textAttributes.lineBreakStrategy) { - result["lineBreakStrategyIOS"] = - textAttributes.lineBreakStrategy.has_value() - ? toString(textAttributes.lineBreakStrategy.value()) - : folly::dynamic(nullptr); - } - - if (textAttributes.lineBreakMode != oldProps->textAttributes.lineBreakMode) { - result["lineBreakModeIOS"] = textAttributes.lineBreakMode.has_value() - ? toString(textAttributes.lineBreakMode.value()) - : folly::dynamic(nullptr); - } - - if (textAttributes.textDecorationColor != - oldProps->textAttributes.textDecorationColor) { - result["textDecorationColor"] = *textAttributes.textDecorationColor; - } - - if (textAttributes.textDecorationLineType != - oldProps->textAttributes.textDecorationLineType) { - result["textDecorationLine"] = - textAttributes.textDecorationLineType.has_value() - ? toString(textAttributes.textDecorationLineType.value()) - : folly::dynamic(nullptr); - } - - if (textAttributes.textDecorationStyle != - oldProps->textAttributes.textDecorationStyle) { - result["textDecorationStyle"] = - textAttributes.textDecorationStyle.has_value() - ? toString(textAttributes.textDecorationStyle.value()) - : folly::dynamic(nullptr); - } - - if (textAttributes.textShadowOffset != - oldProps->textAttributes.textShadowOffset) { - result["textShadowOffset"] = textAttributes.textShadowOffset.has_value() - ? toDynamic(textAttributes.textShadowOffset.value()) - : folly::dynamic(nullptr); - } - - if (!floatEquality( - textAttributes.textShadowRadius, - oldProps->textAttributes.textShadowRadius)) { - result["textShadowRadius"] = textAttributes.textShadowRadius; - } - - if (textAttributes.textShadowColor != - oldProps->textAttributes.textShadowColor) { - result["textShadowColor"] = *textAttributes.textShadowColor; - } - - if (textAttributes.isHighlighted != oldProps->textAttributes.isHighlighted) { - result["isHighlighted"] = textAttributes.isHighlighted.has_value() - ? textAttributes.isHighlighted.value() - : folly::dynamic(nullptr); + const char* propName, + const T& newValue, + const T& oldValue) { + if (newValue != oldValue) { + result[propName] = newValue; } +} - if (textAttributes.isPressable != oldProps->textAttributes.isPressable) { - result["isPressable"] = textAttributes.isPressable.has_value() - ? textAttributes.isPressable.value() - : folly::dynamic(nullptr); +template +static void appendDerefIfChanged( + folly::dynamic& result, + const char* propName, + const T& newValue, + const T& oldValue) { + if (newValue != oldValue) { + result[propName] = *newValue; } +} - if (textAttributes.accessibilityRole != - oldProps->textAttributes.accessibilityRole) { - result["accessibilityRole"] = textAttributes.accessibilityRole.has_value() - ? toString(textAttributes.accessibilityRole.value()) - : folly::dynamic(nullptr); +static void appendFloatIfChanged( + folly::dynamic& result, + const char* propName, + Float newValue, + Float oldValue) { + if (!floatEquality(newValue, oldValue)) { + result[propName] = newValue; } +} - if (textAttributes.role != oldProps->textAttributes.role) { - result["role"] = textAttributes.role.has_value() - ? toString(textAttributes.role.value()) +template +static void appendOptionalIfChanged( + folly::dynamic& result, + const char* propName, + const std::optional& newValue, + const std::optional& oldValue, + Convert&& convert) { + if (newValue != oldValue) { + result[propName] = newValue.has_value() + ? folly::dynamic(convert(newValue.value())) : folly::dynamic(nullptr); } +} - if (!floatEquality( - textAttributes.opacity, oldProps->textAttributes.opacity)) { - result["opacity"] = textAttributes.opacity; - } +void BaseTextProps::appendTextAttributesProps( + folly::dynamic& result, + const BaseTextProps* oldProps) const { + auto asString = [](const auto& value) { return toString(value); }; + auto asIs = [](const auto& value) { return value; }; + auto asDynamic = [](const auto& value) { return toDynamic(value); }; - if (textAttributes.backgroundColor != - oldProps->textAttributes.backgroundColor) { - result["backgroundColor"] = *textAttributes.backgroundColor; - } + appendDerefIfChanged( + result, + "color", + textAttributes.foregroundColor, + oldProps->textAttributes.foregroundColor); + appendIfChanged( + result, + "fontFamily", + textAttributes.fontFamily, + oldProps->textAttributes.fontFamily); + appendFloatIfChanged( + result, + "fontSize", + textAttributes.fontSize, + oldProps->textAttributes.fontSize); + appendFloatIfChanged( + result, + "fontSizeMultiplier", + textAttributes.fontSizeMultiplier, + oldProps->textAttributes.fontSizeMultiplier); + appendOptionalIfChanged( + result, + "fontWeight", + textAttributes.fontWeight, + oldProps->textAttributes.fontWeight, + asString); + appendOptionalIfChanged( + result, + "fontStyle", + textAttributes.fontStyle, + oldProps->textAttributes.fontStyle, + asString); + appendOptionalIfChanged( + result, + "fontVariant", + textAttributes.fontVariant, + oldProps->textAttributes.fontVariant, + asString); + appendOptionalIfChanged( + result, + "allowFontScaling", + textAttributes.allowFontScaling, + oldProps->textAttributes.allowFontScaling, + asIs); + appendFloatIfChanged( + result, + "maxFontSizeMultiplier", + textAttributes.maxFontSizeMultiplier, + oldProps->textAttributes.maxFontSizeMultiplier); + appendOptionalIfChanged( + result, + "dynamicTypeRamp", + textAttributes.dynamicTypeRamp, + oldProps->textAttributes.dynamicTypeRamp, + asString); + appendFloatIfChanged( + result, + "letterSpacing", + textAttributes.letterSpacing, + oldProps->textAttributes.letterSpacing); + appendOptionalIfChanged( + result, + "textTransform", + textAttributes.textTransform, + oldProps->textAttributes.textTransform, + asString); + appendFloatIfChanged( + result, + "lineHeight", + textAttributes.lineHeight, + oldProps->textAttributes.lineHeight); + appendOptionalIfChanged( + result, + "textAlign", + textAttributes.alignment, + oldProps->textAttributes.alignment, + asString); + appendOptionalIfChanged( + result, + "baseWritingDirection", + textAttributes.baseWritingDirection, + oldProps->textAttributes.baseWritingDirection, + asString); + appendOptionalIfChanged( + result, + "lineBreakStrategyIOS", + textAttributes.lineBreakStrategy, + oldProps->textAttributes.lineBreakStrategy, + asString); + appendOptionalIfChanged( + result, + "lineBreakModeIOS", + textAttributes.lineBreakMode, + oldProps->textAttributes.lineBreakMode, + asString); + appendDerefIfChanged( + result, + "textDecorationColor", + textAttributes.textDecorationColor, + oldProps->textAttributes.textDecorationColor); + appendOptionalIfChanged( + result, + "textDecorationLine", + textAttributes.textDecorationLineType, + oldProps->textAttributes.textDecorationLineType, + asString); + appendOptionalIfChanged( + result, + "textDecorationStyle", + textAttributes.textDecorationStyle, + oldProps->textAttributes.textDecorationStyle, + asString); + appendOptionalIfChanged( + result, + "textShadowOffset", + textAttributes.textShadowOffset, + oldProps->textAttributes.textShadowOffset, + asDynamic); + appendFloatIfChanged( + result, + "textShadowRadius", + textAttributes.textShadowRadius, + oldProps->textAttributes.textShadowRadius); + appendDerefIfChanged( + result, + "textShadowColor", + textAttributes.textShadowColor, + oldProps->textAttributes.textShadowColor); + appendOptionalIfChanged( + result, + "isHighlighted", + textAttributes.isHighlighted, + oldProps->textAttributes.isHighlighted, + asIs); + appendOptionalIfChanged( + result, + "isPressable", + textAttributes.isPressable, + oldProps->textAttributes.isPressable, + asIs); + appendOptionalIfChanged( + result, + "accessibilityRole", + textAttributes.accessibilityRole, + oldProps->textAttributes.accessibilityRole, + asString); + appendOptionalIfChanged( + result, + "role", + textAttributes.role, + oldProps->textAttributes.role, + asString); + appendFloatIfChanged( + result, + "opacity", + textAttributes.opacity, + oldProps->textAttributes.opacity); + appendDerefIfChanged( + result, + "backgroundColor", + textAttributes.backgroundColor, + oldProps->textAttributes.backgroundColor); } #endif From 5663ef6bc38baff5880b255c92adef251736f2d3 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 9 Jun 2026 09:11:17 -0700 Subject: [PATCH 2/2] Simplify `AndroidTextInputProps::getDiffProps` (#57151) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: `AndroidTextInputProps::getDiffProps` computes a `folly::dynamic` prop diff through ~57 sequential per-prop `if (field != oldProps->field) result[key] = ...` blocks (plus a nested `has_value()` branch for `textAlignVertical` and an optional ternary for `acceptDragAndDropTypes`), giving the function a cyclomatic complexity (CCN) of 63 — past the landing threshold. This is a pure, behavior-preserving refactor. The recurring compare-and-assign shapes — plain `!=`, color dereference, `floatEquality`, direct `toString`/`toDynamic` conversion, and optional-with-converter — are pulled into small file-local `static` helpers, and the body becomes a flat list of helper calls in the exact same order, with the same keys, comparisons (`!=` vs `floatEquality`), conversions, and values. The serialized output (including `folly::dynamic` insertion order, so the duplicate `numberOfLines`/`includeFontPadding` keys still resolve identically) is unchanged. Only the `.cpp` is touched; there are no public header or API changes. Changelog: [Internal] Differential Revision: D108027818 --- .../AndroidTextInputProps.cpp | 502 +++++++++--------- 1 file changed, 251 insertions(+), 251 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp index 5b88b938f899..e78ea01e2bc9 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp @@ -361,274 +361,274 @@ ComponentName AndroidTextInputProps::getDiffPropsImplementationTarget() const { return "TextInput"; } -folly::dynamic AndroidTextInputProps::getDiffProps( - const Props* prevProps) const { - static const auto defaultProps = AndroidTextInputProps(); - - const AndroidTextInputProps* oldProps = prevProps == nullptr - ? &defaultProps - : static_cast(prevProps); - - folly::dynamic result = ViewProps::getDiffProps(oldProps); - - // Base text input paragraph props - if (paragraphAttributes.maximumNumberOfLines != - oldProps->paragraphAttributes.maximumNumberOfLines) { - result["numberOfLines"] = paragraphAttributes.maximumNumberOfLines; - } - - if (paragraphAttributes.ellipsizeMode != - oldProps->paragraphAttributes.ellipsizeMode) { - result["ellipsizeMode"] = toString(paragraphAttributes.ellipsizeMode); - } - - if (paragraphAttributes.textBreakStrategy != - oldProps->paragraphAttributes.textBreakStrategy) { - result["textBreakStrategy"] = - toString(paragraphAttributes.textBreakStrategy); - } - - if (paragraphAttributes.adjustsFontSizeToFit != - oldProps->paragraphAttributes.adjustsFontSizeToFit) { - result["adjustsFontSizeToFit"] = paragraphAttributes.adjustsFontSizeToFit; - } - - if (!floatEquality( - paragraphAttributes.minimumFontSize, - oldProps->paragraphAttributes.minimumFontSize)) { - result["minimumFontSize"] = paragraphAttributes.minimumFontSize; - } - - if (!floatEquality( - paragraphAttributes.maximumFontSize, - oldProps->paragraphAttributes.maximumFontSize)) { - result["maximumFontSize"] = paragraphAttributes.maximumFontSize; - } - - if (paragraphAttributes.includeFontPadding != - oldProps->paragraphAttributes.includeFontPadding) { - result["includeFontPadding"] = paragraphAttributes.includeFontPadding; - } - - if (paragraphAttributes.android_hyphenationFrequency != - oldProps->paragraphAttributes.android_hyphenationFrequency) { - result["android_hyphenationFrequency"] = - toString(paragraphAttributes.android_hyphenationFrequency); - } - - if (paragraphAttributes.textAlignVertical != - oldProps->paragraphAttributes.textAlignVertical) { - if (!paragraphAttributes.textAlignVertical.has_value()) { - result["textAlignVertical"] = nullptr; - } else { - result["textAlignVertical"] = - toString(*paragraphAttributes.textAlignVertical); - } - } - - // Base text input props - if (defaultValue != oldProps->defaultValue) { - result["defaultValue"] = defaultValue; - } - - if (placeholder != oldProps->placeholder) { - result["placeholder"] = placeholder; - } - - if (placeholderTextColor != oldProps->placeholderTextColor) { - result["placeholderTextColor"] = *placeholderTextColor; - } - - if (cursorColor != oldProps->cursorColor) { - result["cursorColor"] = *cursorColor; - } - - if (selectionColor != oldProps->selectionColor) { - result["selectionColor"] = *selectionColor; - } - - if (selectionHandleColor != oldProps->selectionHandleColor) { - result["selectionHandleColor"] = *selectionHandleColor; - } - - if (underlineColorAndroid != oldProps->underlineColorAndroid) { - result["underlineColorAndroid"] = *underlineColorAndroid; - } - - if (maxLength != oldProps->maxLength) { - result["maxLength"] = maxLength; +// Behavior-preserving helpers extracted from getDiffProps below to keep its +// cyclomatic complexity low. Each mirrors one of the recurring +// compare-and-assign shapes used per prop, so the serialized output (keys, +// values, conversions, and insertion order) is identical to the open-coded +// version. +template +static void appendIfChanged( + folly::dynamic& result, + const char* propName, + const T& newValue, + const T& oldValue) { + if (newValue != oldValue) { + result[propName] = newValue; } +} - if (text != oldProps->text) { - result["text"] = text; +template +static void appendDerefIfChanged( + folly::dynamic& result, + const char* propName, + const T& newValue, + const T& oldValue) { + if (newValue != oldValue) { + result[propName] = *newValue; } +} - if (mostRecentEventCount != oldProps->mostRecentEventCount) { - result["mostRecentEventCount"] = mostRecentEventCount; +static void appendFloatIfChanged( + folly::dynamic& result, + const char* propName, + Float newValue, + Float oldValue) { + if (!floatEquality(newValue, oldValue)) { + result[propName] = newValue; } +} - if (autoFocus != oldProps->autoFocus) { - result["autoFocus"] = autoFocus; +template +static void appendConvertedIfChanged( + folly::dynamic& result, + const char* propName, + const T& newValue, + const T& oldValue, + Convert&& convert) { + if (newValue != oldValue) { + result[propName] = convert(newValue); } +} - if (autoCapitalize != oldProps->autoCapitalize) { - result["autoCapitalize"] = autoCapitalize; +template +static void appendOptionalIfChanged( + folly::dynamic& result, + const char* propName, + const std::optional& newValue, + const std::optional& oldValue, + Convert&& convert) { + if (newValue != oldValue) { + result[propName] = newValue.has_value() + ? folly::dynamic(convert(newValue.value())) + : folly::dynamic(nullptr); } +} - if (editable != oldProps->editable) { - result["editable"] = editable; - } +folly::dynamic AndroidTextInputProps::getDiffProps( + const Props* prevProps) const { + static const auto defaultProps = AndroidTextInputProps(); - if (readOnly != oldProps->readOnly) { - result["readOnly"] = readOnly; - } + const AndroidTextInputProps* oldProps = prevProps == nullptr + ? &defaultProps + : static_cast(prevProps); - if (submitBehavior != oldProps->submitBehavior) { - result["submitBehavior"] = toDynamic(submitBehavior); - } + folly::dynamic result = ViewProps::getDiffProps(oldProps); - if (multiline != oldProps->multiline) { - result["multiline"] = multiline; - } + auto asString = [](const auto& value) { return toString(value); }; + auto asDynamic = [](const auto& value) { return toDynamic(value); }; - if (disableKeyboardShortcuts != oldProps->disableKeyboardShortcuts) { - result["disableKeyboardShortcuts"] = disableKeyboardShortcuts; - } + // Base text input paragraph props + appendIfChanged( + result, + "numberOfLines", + paragraphAttributes.maximumNumberOfLines, + oldProps->paragraphAttributes.maximumNumberOfLines); + appendConvertedIfChanged( + result, + "ellipsizeMode", + paragraphAttributes.ellipsizeMode, + oldProps->paragraphAttributes.ellipsizeMode, + asString); + appendConvertedIfChanged( + result, + "textBreakStrategy", + paragraphAttributes.textBreakStrategy, + oldProps->paragraphAttributes.textBreakStrategy, + asString); + appendIfChanged( + result, + "adjustsFontSizeToFit", + paragraphAttributes.adjustsFontSizeToFit, + oldProps->paragraphAttributes.adjustsFontSizeToFit); + appendFloatIfChanged( + result, + "minimumFontSize", + paragraphAttributes.minimumFontSize, + oldProps->paragraphAttributes.minimumFontSize); + appendFloatIfChanged( + result, + "maximumFontSize", + paragraphAttributes.maximumFontSize, + oldProps->paragraphAttributes.maximumFontSize); + appendIfChanged( + result, + "includeFontPadding", + paragraphAttributes.includeFontPadding, + oldProps->paragraphAttributes.includeFontPadding); + appendConvertedIfChanged( + result, + "android_hyphenationFrequency", + paragraphAttributes.android_hyphenationFrequency, + oldProps->paragraphAttributes.android_hyphenationFrequency, + asString); + appendOptionalIfChanged( + result, + "textAlignVertical", + paragraphAttributes.textAlignVertical, + oldProps->paragraphAttributes.textAlignVertical, + asString); - if (acceptDragAndDropTypes != oldProps->acceptDragAndDropTypes) { - result["acceptDragAndDropTypes"] = acceptDragAndDropTypes.has_value() - ? toDynamic(acceptDragAndDropTypes.value()) - : nullptr; - } + // Base text input props + appendIfChanged(result, "defaultValue", defaultValue, oldProps->defaultValue); + appendIfChanged(result, "placeholder", placeholder, oldProps->placeholder); + appendDerefIfChanged( + result, + "placeholderTextColor", + placeholderTextColor, + oldProps->placeholderTextColor); + appendDerefIfChanged( + result, "cursorColor", cursorColor, oldProps->cursorColor); + appendDerefIfChanged( + result, "selectionColor", selectionColor, oldProps->selectionColor); + appendDerefIfChanged( + result, + "selectionHandleColor", + selectionHandleColor, + oldProps->selectionHandleColor); + appendDerefIfChanged( + result, + "underlineColorAndroid", + underlineColorAndroid, + oldProps->underlineColorAndroid); + appendIfChanged(result, "maxLength", maxLength, oldProps->maxLength); + appendIfChanged(result, "text", text, oldProps->text); + appendIfChanged( + result, + "mostRecentEventCount", + mostRecentEventCount, + oldProps->mostRecentEventCount); + appendIfChanged(result, "autoFocus", autoFocus, oldProps->autoFocus); + appendIfChanged( + result, "autoCapitalize", autoCapitalize, oldProps->autoCapitalize); + appendIfChanged(result, "editable", editable, oldProps->editable); + appendIfChanged(result, "readOnly", readOnly, oldProps->readOnly); + appendConvertedIfChanged( + result, + "submitBehavior", + submitBehavior, + oldProps->submitBehavior, + asDynamic); + appendIfChanged(result, "multiline", multiline, oldProps->multiline); + appendIfChanged( + result, + "disableKeyboardShortcuts", + disableKeyboardShortcuts, + oldProps->disableKeyboardShortcuts); + appendOptionalIfChanged( + result, + "acceptDragAndDropTypes", + acceptDragAndDropTypes, + oldProps->acceptDragAndDropTypes, + asDynamic); // Android text input props - if (autoComplete != oldProps->autoComplete) { - result["autoComplete"] = autoComplete; - } - - if (returnKeyLabel != oldProps->returnKeyLabel) { - result["returnKeyLabel"] = returnKeyLabel; - } - - if (numberOfLines != oldProps->numberOfLines) { - result["numberOfLines"] = numberOfLines; - } - - if (disableFullscreenUI != oldProps->disableFullscreenUI) { - result["disableFullscreenUI"] = disableFullscreenUI; - } - - if (textBreakStrategy != oldProps->textBreakStrategy) { - result["textBreakStrategy"] = textBreakStrategy; - } - - if (inlineImageLeft != oldProps->inlineImageLeft) { - result["inlineImageLeft"] = inlineImageLeft; - } - - if (inlineImagePadding != oldProps->inlineImagePadding) { - result["inlineImagePadding"] = inlineImagePadding; - } - - if (importantForAutofill != oldProps->importantForAutofill) { - result["importantForAutofill"] = importantForAutofill; - } - - if (showSoftInputOnFocus != oldProps->showSoftInputOnFocus) { - result["showSoftInputOnFocus"] = showSoftInputOnFocus; - } - - if (autoCorrect != oldProps->autoCorrect) { - result["autoCorrect"] = autoCorrect; - } - - if (allowFontScaling != oldProps->allowFontScaling) { - result["allowFontScaling"] = allowFontScaling; - } - - if (maxFontSizeMultiplier != oldProps->maxFontSizeMultiplier) { - result["maxFontSizeMultiplier"] = maxFontSizeMultiplier; - } - - if (keyboardType != oldProps->keyboardType) { - result["keyboardType"] = keyboardType; - } - - if (returnKeyType != oldProps->returnKeyType) { - result["returnKeyType"] = returnKeyType; - } - - if (secureTextEntry != oldProps->secureTextEntry) { - result["secureTextEntry"] = secureTextEntry; - } - - if (value != oldProps->value) { - result["value"] = value; - } - - if (selectTextOnFocus != oldProps->selectTextOnFocus) { - result["selectTextOnFocus"] = selectTextOnFocus; - } - - if (caretHidden != oldProps->caretHidden) { - result["caretHidden"] = caretHidden; - } - - if (contextMenuHidden != oldProps->contextMenuHidden) { - result["contextMenuHidden"] = contextMenuHidden; - } - - if (textShadowColor != oldProps->textShadowColor) { - result["textShadowColor"] = *textShadowColor; - } - - if (textShadowRadius != oldProps->textShadowRadius) { - result["textShadowRadius"] = textShadowRadius; - } - - if (textDecorationLine != oldProps->textDecorationLine) { - result["textDecorationLine"] = textDecorationLine; - } - - if (fontStyle != oldProps->fontStyle) { - result["fontStyle"] = fontStyle; - } - - if (textShadowOffset != oldProps->textShadowOffset) { - result["textShadowOffset"] = toDynamic(textShadowOffset); - } - - if (lineHeight != oldProps->lineHeight) { - result["lineHeight"] = lineHeight; - } - - if (textTransform != oldProps->textTransform) { - result["textTransform"] = textTransform; - } - - if (letterSpacing != oldProps->letterSpacing) { - result["letterSpacing"] = letterSpacing; - } - - if (fontSize != oldProps->fontSize) { - result["fontSize"] = fontSize; - } - - if (textAlign != oldProps->textAlign) { - result["textAlign"] = textAlign; - } - - if (includeFontPadding != oldProps->includeFontPadding) { - result["includeFontPadding"] = includeFontPadding; - } - - if (fontWeight != oldProps->fontWeight) { - result["fontWeight"] = fontWeight; - } - - if (fontFamily != oldProps->fontFamily) { - result["fontFamily"] = fontFamily; - } + appendIfChanged(result, "autoComplete", autoComplete, oldProps->autoComplete); + appendIfChanged( + result, "returnKeyLabel", returnKeyLabel, oldProps->returnKeyLabel); + appendIfChanged( + result, "numberOfLines", numberOfLines, oldProps->numberOfLines); + appendIfChanged( + result, + "disableFullscreenUI", + disableFullscreenUI, + oldProps->disableFullscreenUI); + appendIfChanged( + result, + "textBreakStrategy", + textBreakStrategy, + oldProps->textBreakStrategy); + appendIfChanged( + result, "inlineImageLeft", inlineImageLeft, oldProps->inlineImageLeft); + appendIfChanged( + result, + "inlineImagePadding", + inlineImagePadding, + oldProps->inlineImagePadding); + appendIfChanged( + result, + "importantForAutofill", + importantForAutofill, + oldProps->importantForAutofill); + appendIfChanged( + result, + "showSoftInputOnFocus", + showSoftInputOnFocus, + oldProps->showSoftInputOnFocus); + appendIfChanged(result, "autoCorrect", autoCorrect, oldProps->autoCorrect); + appendIfChanged( + result, "allowFontScaling", allowFontScaling, oldProps->allowFontScaling); + appendIfChanged( + result, + "maxFontSizeMultiplier", + maxFontSizeMultiplier, + oldProps->maxFontSizeMultiplier); + appendIfChanged(result, "keyboardType", keyboardType, oldProps->keyboardType); + appendIfChanged( + result, "returnKeyType", returnKeyType, oldProps->returnKeyType); + appendIfChanged( + result, "secureTextEntry", secureTextEntry, oldProps->secureTextEntry); + appendIfChanged(result, "value", value, oldProps->value); + appendIfChanged( + result, + "selectTextOnFocus", + selectTextOnFocus, + oldProps->selectTextOnFocus); + appendIfChanged(result, "caretHidden", caretHidden, oldProps->caretHidden); + appendIfChanged( + result, + "contextMenuHidden", + contextMenuHidden, + oldProps->contextMenuHidden); + appendDerefIfChanged( + result, "textShadowColor", textShadowColor, oldProps->textShadowColor); + appendIfChanged( + result, "textShadowRadius", textShadowRadius, oldProps->textShadowRadius); + appendIfChanged( + result, + "textDecorationLine", + textDecorationLine, + oldProps->textDecorationLine); + appendIfChanged(result, "fontStyle", fontStyle, oldProps->fontStyle); + appendConvertedIfChanged( + result, + "textShadowOffset", + textShadowOffset, + oldProps->textShadowOffset, + asDynamic); + appendIfChanged(result, "lineHeight", lineHeight, oldProps->lineHeight); + appendIfChanged( + result, "textTransform", textTransform, oldProps->textTransform); + appendIfChanged( + result, "letterSpacing", letterSpacing, oldProps->letterSpacing); + appendIfChanged(result, "fontSize", fontSize, oldProps->fontSize); + appendIfChanged(result, "textAlign", textAlign, oldProps->textAlign); + appendIfChanged( + result, + "includeFontPadding", + includeFontPadding, + oldProps->includeFontPadding); + appendIfChanged(result, "fontWeight", fontWeight, oldProps->fontWeight); + appendIfChanged(result, "fontFamily", fontFamily, oldProps->fontFamily); return result; }