Skip to content

Commit a57ee9a

Browse files
Refactor TextFragmentList into AttributedString
...preparing it to support another layer over fragments.
1 parent cfc0ba0 commit a57ee9a

12 files changed

Lines changed: 97 additions & 88 deletions

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import com.facebook.react.uimanager.ReactAccessibilityDelegate.Role;
3838
import com.facebook.react.uimanager.ReactStylesDiffMap;
3939
import com.facebook.react.uimanager.ViewProps;
40-
import com.facebook.react.views.text.fragments.BridgeTextFragmentList;
40+
import com.facebook.react.views.text.attributedstring.BridgeAttributedString;
4141
import com.facebook.react.views.text.internal.span.CustomLetterSpacingSpan;
4242
import com.facebook.react.views.text.internal.span.CustomLineHeightSpan;
4343
import com.facebook.react.views.text.internal.span.CustomStyleSpan;
@@ -113,15 +113,15 @@ public static void deleteCachedSpannableForTag(int reactTag) {
113113
sTagToSpannableCache.remove(reactTag);
114114
}
115115

116-
private static void buildSpannableFromFragments(
116+
private static void buildSpannableFromAttributedString(
117117
Context context,
118-
ReadableArray fragments,
118+
ReadableMap attributedString,
119119
SpannableStringBuilder sb,
120120
List<SetSpanOperation> ops) {
121121
if (ReactFeatureFlags.enableSpannableBuildingUnification) {
122-
buildSpannableFromFragmentsUnified(context, fragments, sb, ops);
122+
buildSpannableFromAttributedStringUnified(context, attributedString, sb, ops);
123123
} else {
124-
buildSpannableFromFragmentsDuplicated(context, fragments, sb, ops);
124+
buildSpannableFromFragmentsDuplicated(context, attributedString.getArray("fragments"), sb, ops);
125125
}
126126
}
127127

@@ -223,15 +223,15 @@ private static void buildSpannableFromFragmentsDuplicated(
223223
}
224224
}
225225

226-
private static void buildSpannableFromFragmentsUnified(
226+
private static void buildSpannableFromAttributedStringUnified(
227227
Context context,
228-
ReadableArray fragments,
228+
ReadableMap attributedString,
229229
SpannableStringBuilder sb,
230230
List<SetSpanOperation> ops) {
231231

232-
final BridgeTextFragmentList textFragmentList = new BridgeTextFragmentList(fragments);
232+
final BridgeAttributedString bridgeAttributedString = new BridgeAttributedString(attributedString);
233233

234-
TextLayoutUtils.buildSpannableFromTextFragmentList(context, textFragmentList, sb, ops);
234+
TextLayoutUtils.buildSpannableFromAttributedString(context, bridgeAttributedString, sb, ops);
235235
}
236236

237237
// public because both ReactTextViewManager and ReactTextInputManager need to use this
@@ -256,7 +256,7 @@ private static Spannable createSpannableFromAttributedString(
256256
// a new spannable will be wiped out
257257
List<SetSpanOperation> ops = new ArrayList<>();
258258

259-
buildSpannableFromFragments(context, attributedString.getArray("fragments"), sb, ops);
259+
buildSpannableFromAttributedString(context, attributedString, sb, ops);
260260

261261
// TODO T31905686: add support for inline Images
262262
// While setting the Spans on the final text, we also check whether any of them are images.

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@
3434
import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
3535
import com.facebook.react.config.ReactFeatureFlags;
3636
import com.facebook.react.uimanager.PixelUtil;
37+
import com.facebook.react.views.text.attributedstring.MapBufferAttributedString;
3738
import com.facebook.react.uimanager.ReactAccessibilityDelegate.AccessibilityRole;
3839
import com.facebook.react.uimanager.ReactAccessibilityDelegate.Role;
39-
import com.facebook.react.views.text.fragments.MapBufferTextFragmentList;
4040
import com.facebook.react.views.text.internal.span.CustomLetterSpacingSpan;
4141
import com.facebook.react.views.text.internal.span.CustomLineHeightSpan;
4242
import com.facebook.react.views.text.internal.span.CustomStyleSpan;
@@ -138,12 +138,12 @@ public static boolean isRTL(MapBuffer attributedString) {
138138
== LayoutDirection.RTL;
139139
}
140140

141-
private static void buildSpannableFromFragments(
142-
Context context, MapBuffer fragments, SpannableStringBuilder sb, List<SetSpanOperation> ops) {
141+
private static void buildSpannableFromAttributedString(
142+
Context context, MapBuffer attributedString, SpannableStringBuilder sb, List<SetSpanOperation> ops) {
143143
if (ReactFeatureFlags.enableSpannableBuildingUnification) {
144-
buildSpannableFromFragmentsUnified(context, fragments, sb, ops);
144+
buildSpannableFromFragmentsDuplicated(context, attributedString.getMapBuffer(AS_KEY_FRAGMENTS), sb, ops);
145145
} else {
146-
buildSpannableFromFragmentsDuplicated(context, fragments, sb, ops);
146+
buildSpannableFromAttributedStringUnified(context, attributedString, sb, ops);
147147
}
148148
}
149149

@@ -241,12 +241,12 @@ private static void buildSpannableFromFragmentsDuplicated(
241241
}
242242
}
243243

244-
private static void buildSpannableFromFragmentsUnified(
245-
Context context, MapBuffer fragments, SpannableStringBuilder sb, List<SetSpanOperation> ops) {
244+
private static void buildSpannableFromAttributedStringUnified(
245+
Context context, MapBuffer attributedString, SpannableStringBuilder sb, List<SetSpanOperation> ops) {
246246

247-
final MapBufferTextFragmentList textFragmentList = new MapBufferTextFragmentList(fragments);
247+
final MapBufferAttributedString mapBufferAttributedString = new MapBufferAttributedString(attributedString);
248248

249-
TextLayoutUtils.buildSpannableFromTextFragmentList(context, textFragmentList, sb, ops);
249+
TextLayoutUtils.buildSpannableFromAttributedString(context, mapBufferAttributedString, sb, ops);
250250
}
251251

252252
// public because both ReactTextViewManager and ReactTextInputManager need to use this
@@ -292,7 +292,7 @@ private static Spannable createSpannableFromAttributedString(
292292
// a new spannable will be wiped out
293293
List<SetSpanOperation> ops = new ArrayList<>();
294294

295-
buildSpannableFromFragments(context, attributedString.getMapBuffer(AS_KEY_FRAGMENTS), sb, ops);
295+
buildSpannableFromAttributedString(context, attributedString, sb, ops);
296296

297297
// TODO T31905686: add support for inline Images
298298
// While setting the Spans on the final text, we also check whether any of them are images.

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutUtils.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import android.view.View
1515
import com.facebook.react.common.ReactConstants
1616
import com.facebook.react.uimanager.PixelUtil
1717
import com.facebook.react.uimanager.ReactAccessibilityDelegate
18-
import com.facebook.react.views.text.fragments.TextFragment
19-
import com.facebook.react.views.text.fragments.TextFragmentList
18+
import com.facebook.react.views.text.attributedstring.AttributedString
19+
import com.facebook.react.views.text.attributedstring.AttributedStringFragment
2020
import com.facebook.react.views.text.internal.span.CustomLetterSpacingSpan
2121
import com.facebook.react.views.text.internal.span.CustomLineHeightSpan
2222
import com.facebook.react.views.text.internal.span.CustomStyleSpan
@@ -36,14 +36,14 @@ internal object TextLayoutUtils {
3636
private const val INLINE_VIEW_PLACEHOLDER = "0"
3737

3838
@JvmStatic
39-
fun buildSpannableFromTextFragmentList(
39+
fun buildSpannableFromAttributedString(
4040
context: Context,
41-
textFragmentList: TextFragmentList,
41+
attributedString: AttributedString,
4242
sb: SpannableStringBuilder,
4343
ops: MutableList<SetSpanOperation>,
4444
) {
45-
for (i in 0 until textFragmentList.count) {
46-
val fragment = textFragmentList.getFragment(i)
45+
for (i in 0 until attributedString.fragmentCount) {
46+
val fragment = attributedString.getFragment(i)
4747

4848
addApplicableFragmentSpans(
4949
context = context,
@@ -54,9 +54,10 @@ internal object TextLayoutUtils {
5454
}
5555
}
5656

57+
@JvmStatic
5758
private fun addApplicableFragmentSpans(
5859
context: Context,
59-
fragment: TextFragment,
60+
fragment: AttributedStringFragment,
6061
sb: SpannableStringBuilder,
6162
ops: MutableList<SetSpanOperation>,
6263
) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.views.text.attributedstring
9+
10+
/** Interface for an attributed string */
11+
internal interface AttributedString {
12+
fun getFragment(index: Int): AttributedStringFragment
13+
14+
val fragmentCount: Int
15+
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/fragments/TextFragment.kt renamed to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/attributedstring/AttributedStringFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
package com.facebook.react.views.text.fragments
8+
package com.facebook.react.views.text.attributedstring
99

1010
import com.facebook.react.views.text.TextAttributeProps
1111

12-
/** Interface for a text fragment */
13-
internal interface TextFragment {
12+
/** Interface for an attributed string fragment */
13+
internal interface AttributedStringFragment {
1414
val textAttributeProps: TextAttributeProps
1515

1616
val string: String?
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.views.text.attributedstring
9+
10+
import com.facebook.react.bridge.ReadableArray
11+
import com.facebook.react.bridge.ReadableMap
12+
13+
/** An [AttributedString] backed by a [ReadableMap] */
14+
internal class BridgeAttributedString(private val attributedString: ReadableMap) : AttributedString {
15+
override fun getFragment(index: Int): AttributedStringFragment = BridgeAttributedStringFragment(fragments.getMap(index))
16+
17+
override val fragmentCount: Int
18+
get() = fragments.size()
19+
20+
private val fragments: ReadableArray
21+
get() = attributedString.getArray("fragments")!!
22+
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/fragments/BridgeTextFragment.kt renamed to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/attributedstring/BridgeAttributedStringFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
package com.facebook.react.views.text.fragments
8+
package com.facebook.react.views.text.attributedstring
99

1010
import com.facebook.react.bridge.ReadableMap
1111
import com.facebook.react.uimanager.ReactStylesDiffMap
1212
import com.facebook.react.uimanager.ViewProps
1313
import com.facebook.react.views.text.TextAttributeProps
1414

15-
/** A [TextFragment] implementation backed by a a [ReadableMap] */
16-
internal class BridgeTextFragment(private val fragment: ReadableMap) : TextFragment {
15+
/** Am [AttributedStringFragment] implementation backed by a a [ReadableMap] */
16+
internal class BridgeAttributedStringFragment(private val fragment: ReadableMap) : AttributedStringFragment {
1717
override val textAttributeProps: TextAttributeProps
1818
get() =
1919
TextAttributeProps.fromReadableMap(ReactStylesDiffMap(fragment.getMap("textAttributes")))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.views.text.attributedstring
9+
10+
import com.facebook.react.common.mapbuffer.MapBuffer
11+
import com.facebook.react.views.text.TextLayoutManagerMapBuffer.AS_KEY_FRAGMENTS
12+
13+
/** An [AttributedString] backed by a [MapBuffer] */
14+
internal class MapBufferAttributedString(private val attributedString: MapBuffer) : AttributedString {
15+
override fun getFragment(index: Int): AttributedStringFragment =
16+
MapBufferAttributedStringFragment(fragments.getMapBuffer(index))
17+
18+
override val fragmentCount: Int
19+
get() = fragments.count
20+
21+
private val fragments: MapBuffer
22+
get() = attributedString.getMapBuffer(AS_KEY_FRAGMENTS.toInt())
23+
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/fragments/MapBufferTextFragment.kt renamed to packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/attributedstring/MapBufferAttributedStringFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
package com.facebook.react.views.text.fragments
8+
package com.facebook.react.views.text.attributedstring
99

1010
import com.facebook.react.common.mapbuffer.MapBuffer
1111
import com.facebook.react.views.text.TextAttributeProps
@@ -16,8 +16,8 @@ import com.facebook.react.views.text.TextLayoutManagerMapBuffer.FR_KEY_STRING
1616
import com.facebook.react.views.text.TextLayoutManagerMapBuffer.FR_KEY_TEXT_ATTRIBUTES
1717
import com.facebook.react.views.text.TextLayoutManagerMapBuffer.FR_KEY_WIDTH
1818

19-
/** A [TextFragment] implementation backed by a [MapBuffer] */
20-
internal class MapBufferTextFragment(private val fragment: MapBuffer) : TextFragment {
19+
/** An [AttributedStringFragment] implementation backed by a [MapBuffer] */
20+
internal class MapBufferAttributedStringFragment(private val fragment: MapBuffer) : AttributedStringFragment {
2121
override val textAttributeProps: TextAttributeProps
2222
get() = TextAttributeProps.fromMapBuffer(fragment.getMapBuffer(FR_KEY_TEXT_ATTRIBUTES.toInt()))
2323

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/fragments/BridgeTextFragmentList.kt

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)