From 327ff049195e6ab61f553493204e07d425fc1974 Mon Sep 17 00:00:00 2001 From: Gregory Moskaliuk Date: Wed, 28 Oct 2026 18:01:08 +0100 Subject: [PATCH] Parse textDecorationLine without compiling a regex on Android TextAttributeProps.setTextDecorationLine split the value with "-".toRegex(), which compiles a java.util.regex.Pattern for every text fragment that has a textDecorationLine, each time the text is laid out. Splitting on the '-' character gives the same parts without a regex. Co-Authored-By: Claude Opus 5.5 --- .../react/views/text/TextAttributeProps.kt | 6 +----- .../react/views/text/TextAttributePropsTest.kt | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.kt index 24aaea509f52..177a88cd3c3c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.kt @@ -283,11 +283,7 @@ public class TextAttributeProps private constructor() { isUnderlineTextDecorationSet = false isLineThroughTextDecorationSet = false if (textDecorationLineString != null) { - for (textDecorationLineSubString in - textDecorationLineString - .split("-".toRegex()) - .dropLastWhile { it.isEmpty() } - .toTypedArray()) { + for (textDecorationLineSubString in textDecorationLineString.split('-')) { if ("underline" == textDecorationLineSubString) { isUnderlineTextDecorationSet = true } else if ("strikethrough" == textDecorationLineSubString) { diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextAttributePropsTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextAttributePropsTest.kt index c7ea970d19be..b2ff436fb383 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextAttributePropsTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextAttributePropsTest.kt @@ -198,6 +198,24 @@ class TextAttributePropsTest { assertThat(textAttributes.lineHeight).isCloseTo(20f * DENSITY, within(0.001f)) } + @Test + fun mapBufferSetsTextDecorationLine() { + assertThat(textDecorationLine("none")).isEqualTo(false to false) + assertThat(textDecorationLine("underline")).isEqualTo(true to false) + assertThat(textDecorationLine("strikethrough")).isEqualTo(false to true) + assertThat(textDecorationLine("underline-strikethrough")).isEqualTo(true to true) + } + + /** Returns whether underline and line-through are set for the given textDecorationLine. */ + private fun textDecorationLine(value: String): Pair { + val textAttributes = + TextAttributeProps.fromMapBuffer( + WritableMapBuffer().put(TextAttributeProps.TA_KEY_TEXT_DECORATION_LINE, value), + ) + return textAttributes.isUnderlineTextDecorationSet to + textAttributes.isLineThroughTextDecorationSet + } + private fun setFontScale(fontScale: Float) { DisplayMetricsHolder.setScreenDisplayMetrics( DisplayMetrics().apply {