react-native-windows 0.66.3 → 0.67.0-preview.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/.flowconfig +2 -1
  2. package/CHANGELOG.json +917 -85
  3. package/CHANGELOG.md +352 -37
  4. package/Chakra/Chakra.vcxitems +0 -1
  5. package/Chakra/Chakra.vcxitems.filters +0 -3
  6. package/Chakra/ChakraHelpers.cpp +0 -267
  7. package/Chakra/ChakraInstanceArgs.h +0 -5
  8. package/Chakra/ChakraPlatform.h +0 -4
  9. package/Chakra/ChakraTracing.cpp +0 -33
  10. package/Chakra/ChakraValue.h +0 -4
  11. package/Chakra/Utf8DebugExtensions.cpp +0 -5
  12. package/Chakra/Utf8DebugExtensions.h +0 -6
  13. package/Libraries/ActionSheetIOS/ActionSheetIOS.js +14 -1
  14. package/Libraries/ActionSheetIOS/NativeActionSheetManager.js +2 -0
  15. package/Libraries/Alert/Alert.windows.js +48 -21
  16. package/Libraries/Alert/NativeDialogManagerWindows.js +49 -0
  17. package/Libraries/Animated/AnimatedEvent.js +23 -4
  18. package/Libraries/Animated/NativeAnimatedHelper.js +2 -2
  19. package/Libraries/Animated/components/AnimatedImage.js +3 -3
  20. package/Libraries/Animated/components/AnimatedScrollView.js +3 -3
  21. package/Libraries/Animated/components/AnimatedText.js +3 -3
  22. package/Libraries/Animated/components/AnimatedView.js +1 -3
  23. package/Libraries/Animated/createAnimatedComponent.js +3 -34
  24. package/Libraries/Components/Button.js +3 -0
  25. package/Libraries/Components/Button.windows.js +70 -38
  26. package/Libraries/Components/DatePicker/DatePickerIOS.ios.js +3 -6
  27. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +4 -7
  28. package/Libraries/Components/Flyout/Flyout.js +3 -3
  29. package/Libraries/Components/Flyout/Flyout.js.map +1 -1
  30. package/Libraries/Components/Flyout/FlyoutProps.d.ts +4 -0
  31. package/Libraries/Components/Flyout/FlyoutProps.js.map +1 -1
  32. package/Libraries/Components/Glyph/Glyph.js +2 -2
  33. package/Libraries/Components/Glyph/Glyph.js.map +1 -1
  34. package/Libraries/Components/Keyboard/KeyboardExt.js +4 -3
  35. package/Libraries/Components/Keyboard/KeyboardExt.js.map +1 -1
  36. package/Libraries/Components/Popup/Popup.js +3 -3
  37. package/Libraries/Components/Popup/Popup.js.map +1 -1
  38. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +1 -0
  39. package/Libraries/Components/ScrollView/ScrollView.js +17 -16
  40. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +268 -252
  41. package/Libraries/Components/View/View.js +1 -1
  42. package/Libraries/Components/View/View.windows.js +1 -1
  43. package/Libraries/Components/View/ViewAccessibility.js +1 -1
  44. package/Libraries/Components/View/ViewAccessibility.windows.js +1 -1
  45. package/Libraries/Components/View/ViewWindows.js +1 -1
  46. package/Libraries/Components/View/ViewWindows.js.map +1 -1
  47. package/Libraries/Components/View/ViewWindowsProps.d.ts +42 -2
  48. package/Libraries/Components/View/ViewWindowsProps.js.map +1 -1
  49. package/Libraries/Core/ExceptionsManager.js +45 -80
  50. package/Libraries/Core/ExtendedError.js +0 -1
  51. package/Libraries/Core/ReactNativeVersion.js +2 -2
  52. package/Libraries/Core/setUpBatchedBridge.js +1 -1
  53. package/Libraries/Core/setUpGlobals.js +2 -4
  54. package/Libraries/Core/setUpTimers.js +2 -2
  55. package/Libraries/Image/Image.ios.js +6 -0
  56. package/Libraries/Image/Image.windows.js +6 -0
  57. package/Libraries/Image/ImageBackground.js +10 -8
  58. package/Libraries/Image/ImageProps.js +28 -0
  59. package/Libraries/LogBox/Data/LogBoxData.js +18 -19
  60. package/Libraries/LogBox/UI/LogBoxImages/alert-triangle.png +0 -0
  61. package/Libraries/LogBox/UI/LogBoxImages/chevron-left.png +0 -0
  62. package/Libraries/LogBox/UI/LogBoxImages/chevron-right.png +0 -0
  63. package/Libraries/LogBox/UI/LogBoxImages/close.png +0 -0
  64. package/Libraries/LogBox/UI/LogBoxImages/loader.png +0 -0
  65. package/Libraries/NewAppScreen/components/logo.png +0 -0
  66. package/Libraries/PermissionsAndroid/NativePermissionsAndroid.js +2 -1
  67. package/Libraries/PermissionsAndroid/PermissionsAndroid.js +2 -0
  68. package/Libraries/Pressability/Pressability.js +13 -13
  69. package/Libraries/Pressability/Pressability.windows.js +13 -13
  70. package/Libraries/Pressability/PressabilityPerformanceEventEmitter.js +1 -1
  71. package/Libraries/ReactNative/AppRegistry.js +4 -2
  72. package/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +1569 -875
  73. package/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +529 -319
  74. package/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +570 -362
  75. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +1592 -891
  76. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +521 -311
  77. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +562 -354
  78. package/Libraries/Share/Share.js +1 -1
  79. package/Libraries/StyleSheet/normalizeColor.js +2 -2
  80. package/Libraries/Text/Text.windows.js +1 -0
  81. package/Libraries/Text/TextNativeComponent.windows.js +72 -0
  82. package/Libraries/Text/TextProps.js +1 -7
  83. package/Libraries/TurboModule/TurboModuleRegistry.js +1 -1
  84. package/Libraries/Utilities/HMRClient.js +1 -1
  85. package/Microsoft.ReactNative/ABIViewManager.cpp +10 -1
  86. package/Microsoft.ReactNative/ABIViewManager.h +3 -0
  87. package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +0 -6
  88. package/Microsoft.ReactNative/IReactDispatcher.cpp +16 -1
  89. package/Microsoft.ReactNative/IViewManager.idl +25 -0
  90. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +35 -8
  91. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +60 -0
  92. package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +3 -4
  93. package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.h +3 -3
  94. package/Microsoft.ReactNative/Modules/AlertModule.cpp +57 -14
  95. package/Microsoft.ReactNative/Modules/AlertModule.h +17 -24
  96. package/Microsoft.ReactNative/Modules/Animated/InterpolationAnimatedNode.cpp +4 -2
  97. package/Microsoft.ReactNative/Modules/Animated/PropsAnimatedNode.cpp +3 -1
  98. package/Microsoft.ReactNative/Modules/AppStateModule.cpp +8 -6
  99. package/Microsoft.ReactNative/Modules/AppStateModule.h +6 -9
  100. package/Microsoft.ReactNative/Modules/DeviceInfoModule.cpp +34 -22
  101. package/Microsoft.ReactNative/Modules/DeviceInfoModule.h +8 -4
  102. package/Microsoft.ReactNative/Modules/I18nManagerModule.cpp +6 -4
  103. package/Microsoft.ReactNative/Modules/I18nManagerModule.h +3 -2
  104. package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +47 -95
  105. package/Microsoft.ReactNative/Modules/ImageViewManagerModule.h +28 -17
  106. package/Microsoft.ReactNative/Modules/LinkingManagerModule.cpp +14 -4
  107. package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +1 -1
  108. package/Microsoft.ReactNative/Modules/PaperUIManagerModule.cpp +82 -66
  109. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +14 -1
  110. package/Microsoft.ReactNative/ReactInstanceSettings.idl +3 -1
  111. package/Microsoft.ReactNative/ReactPointerEventArgs.cpp +37 -0
  112. package/Microsoft.ReactNative/ReactPointerEventArgs.h +28 -0
  113. package/Microsoft.ReactNative/ReactPointerEventArgs.idl +67 -0
  114. package/Microsoft.ReactNative/Utils/TextTransform.h +1 -1
  115. package/Microsoft.ReactNative/Utils/XamlIslandUtils.cpp +24 -10
  116. package/Microsoft.ReactNative/Utils/XamlIslandUtils.h +4 -2
  117. package/Microsoft.ReactNative/Version.rc +2 -19
  118. package/Microsoft.ReactNative/Views/FlyoutViewManager.cpp +57 -2
  119. package/Microsoft.ReactNative/Views/FrameworkElementTransferProperties.cpp +3 -0
  120. package/Microsoft.ReactNative/Views/FrameworkElementViewManager.cpp +7 -2
  121. package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +16 -6
  122. package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +18 -11
  123. package/Microsoft.ReactNative/Views/Image/ReactImage.h +3 -1
  124. package/Microsoft.ReactNative/Views/RawTextViewManager.cpp +4 -53
  125. package/Microsoft.ReactNative/Views/RawTextViewManager.h +0 -3
  126. package/Microsoft.ReactNative/Views/ShadowNodeBase.h +5 -0
  127. package/Microsoft.ReactNative/Views/Text/TextHighlighterVisitor.cpp +52 -0
  128. package/Microsoft.ReactNative/Views/Text/TextHighlighterVisitor.h +37 -0
  129. package/Microsoft.ReactNative/Views/Text/TextHitTestUtils.cpp +343 -0
  130. package/Microsoft.ReactNative/Views/Text/TextHitTestUtils.h +13 -0
  131. package/Microsoft.ReactNative/Views/Text/TextHitTestVisitor.cpp +76 -0
  132. package/Microsoft.ReactNative/Views/Text/TextHitTestVisitor.h +32 -0
  133. package/Microsoft.ReactNative/Views/Text/TextParentVisitor.cpp +12 -0
  134. package/Microsoft.ReactNative/Views/Text/TextParentVisitor.h +19 -0
  135. package/Microsoft.ReactNative/Views/Text/TextPropertyChangedParentVisitor.cpp +80 -0
  136. package/Microsoft.ReactNative/Views/Text/TextPropertyChangedParentVisitor.h +43 -0
  137. package/Microsoft.ReactNative/Views/Text/TextTransformParentVisitor.cpp +21 -0
  138. package/Microsoft.ReactNative/Views/Text/TextTransformParentVisitor.h +23 -0
  139. package/Microsoft.ReactNative/Views/Text/TextTransformVisitor.cpp +70 -0
  140. package/Microsoft.ReactNative/Views/Text/TextTransformVisitor.h +34 -0
  141. package/Microsoft.ReactNative/Views/Text/TextVisitor.cpp +56 -0
  142. package/Microsoft.ReactNative/Views/Text/TextVisitor.h +34 -0
  143. package/Microsoft.ReactNative/Views/Text/TextVisitorScope.h +35 -0
  144. package/Microsoft.ReactNative/Views/Text/TextVisitors.h +47 -0
  145. package/Microsoft.ReactNative/Views/TextViewManager.cpp +112 -103
  146. package/Microsoft.ReactNative/Views/TextViewManager.h +6 -12
  147. package/Microsoft.ReactNative/Views/TouchEventHandler.cpp +171 -129
  148. package/Microsoft.ReactNative/Views/TouchEventHandler.h +19 -15
  149. package/Microsoft.ReactNative/Views/ViewManagerBase.cpp +31 -0
  150. package/Microsoft.ReactNative/Views/ViewManagerBase.h +2 -0
  151. package/Microsoft.ReactNative/Views/ViewViewManager.cpp +0 -5
  152. package/Microsoft.ReactNative/Views/VirtualTextViewManager.cpp +21 -91
  153. package/Microsoft.ReactNative/Views/VirtualTextViewManager.h +5 -8
  154. package/Microsoft.ReactNative/XamlView.h +3 -3
  155. package/Microsoft.ReactNative/packages.config +1 -1
  156. package/Microsoft.ReactNative.Cxx/NativeModules.h +114 -0
  157. package/Microsoft.ReactNative.Cxx/VersionMacros.h +19 -0
  158. package/PropertySheets/External/Microsoft.ReactNative.Common.props +2 -0
  159. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.props +1 -0
  160. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppLib.props +1 -0
  161. package/PropertySheets/Generated/PackageVersion.g.props +19 -0
  162. package/PropertySheets/PackageVersionDefinitions.props +28 -0
  163. package/PropertySheets/React.Cpp.props +2 -0
  164. package/PropertySheets/WinUI.props +1 -1
  165. package/Scripts/Microsoft.ReactNative.Managed.nuspec +1 -1
  166. package/Scripts/copyRNLibraries.js +12 -0
  167. package/Scripts/rnw-dependencies.ps1 +25 -24
  168. package/Shared/HermesSamplingProfiler.cpp +3 -21
  169. package/Shared/JSI/ChakraApi.cpp +1 -37
  170. package/Shared/JSI/ChakraApi.h +0 -4
  171. package/Shared/JSI/ChakraJsiRuntime_edgemode.cpp +1 -5
  172. package/Shared/JSI/ChakraRuntime.cpp +0 -12
  173. package/Shared/JSI/ChakraRuntimeFactory.h +0 -2
  174. package/Shared/Modules/PlatformConstantsModule.cpp +1 -15
  175. package/Shared/OInstance.cpp +6 -19
  176. package/Shared/Shared.vcxitems +0 -1
  177. package/Shared/Shared.vcxitems.filters +0 -3
  178. package/Shared/Utils.cpp +58 -0
  179. package/Shared/Utils.h +3 -0
  180. package/codegen/NativeAccessibilityInfoSpec.g.h +9 -9
  181. package/codegen/NativeAccessibilityManagerSpec.g.h +49 -21
  182. package/codegen/NativeActionSheetManagerSpec.g.h +62 -6
  183. package/codegen/NativeAlertManagerSpec.g.h +4 -4
  184. package/codegen/NativeAnimatedModuleSpec.g.h +10 -10
  185. package/codegen/NativeAnimatedTurboModuleSpec.g.h +10 -10
  186. package/codegen/NativeAppStateSpec.g.h +25 -3
  187. package/codegen/NativeAppearanceSpec.g.h +3 -3
  188. package/codegen/NativeAsyncLocalStorageSpec.g.h +66 -18
  189. package/codegen/NativeAsyncSQLiteDBStorageSpec.g.h +66 -18
  190. package/codegen/NativeBlobModuleSpec.g.h +24 -6
  191. package/codegen/NativeBugReportingSpec.g.h +3 -3
  192. package/codegen/NativeDatePickerAndroidSpec.g.h +3 -3
  193. package/codegen/NativeDevLoadingViewSpec.g.h +3 -3
  194. package/codegen/NativeDeviceInfoSpec.g.h +18 -0
  195. package/codegen/NativeDialogManagerAndroidSpec.g.h +28 -4
  196. package/codegen/NativeDialogManagerWindowsSpec.g.h +77 -0
  197. package/codegen/NativeExceptionsManagerSpec.g.h +11 -11
  198. package/codegen/NativeFileReaderModuleSpec.g.h +6 -6
  199. package/codegen/NativeFrameRateLoggerSpec.g.h +11 -3
  200. package/codegen/NativeI18nManagerSpec.g.h +20 -0
  201. package/codegen/NativeImageEditorSpec.g.h +30 -6
  202. package/codegen/NativeImageLoaderAndroidSpec.g.h +6 -6
  203. package/codegen/NativeImageLoaderIOSSpec.g.h +6 -6
  204. package/codegen/NativeImagePickerIOSSpec.g.h +28 -12
  205. package/codegen/NativeImageStoreAndroidSpec.g.h +3 -3
  206. package/codegen/NativeImageStoreIOSSpec.g.h +21 -9
  207. package/codegen/NativeIntentAndroidSpec.g.h +3 -3
  208. package/codegen/NativeJSCHeapCaptureSpec.g.h +3 -3
  209. package/codegen/NativeJSCSamplingProfilerSpec.g.h +3 -3
  210. package/codegen/NativeJSDevSupportSpec.g.h +18 -0
  211. package/codegen/NativeNetworkingAndroidSpec.g.h +6 -6
  212. package/codegen/NativeNetworkingIOSSpec.g.h +26 -6
  213. package/codegen/NativePermissionsAndroidSpec.g.h +3 -3
  214. package/codegen/NativePlatformConstantsAndroidSpec.g.h +48 -0
  215. package/codegen/NativePlatformConstantsIOSSpec.g.h +38 -0
  216. package/codegen/NativePlatformConstantsWinSpec.g.h +32 -0
  217. package/codegen/NativePushNotificationManagerIOSSpec.g.h +35 -25
  218. package/codegen/NativeRedBoxSpec.g.h +3 -3
  219. package/codegen/NativeSampleTurboModuleSpec.g.h +32 -12
  220. package/codegen/NativeSegmentFetcherSpec.g.h +6 -6
  221. package/codegen/NativeSettingsManagerSpec.g.h +22 -6
  222. package/codegen/NativeShareModuleSpec.g.h +11 -3
  223. package/codegen/NativeSourceCodeSpec.g.h +16 -0
  224. package/codegen/NativeStatusBarManagerAndroidSpec.g.h +21 -3
  225. package/codegen/NativeStatusBarManagerIOSSpec.g.h +30 -6
  226. package/codegen/NativeToastAndroidSpec.g.h +24 -0
  227. package/codegen/NativeUIManagerSpec.g.h +63 -63
  228. package/codegen/NativeVibrationSpec.g.h +3 -3
  229. package/codegen/NativeWebSocketModuleSpec.g.h +9 -3
  230. package/index.js +15 -10
  231. package/index.windows.js +15 -10
  232. package/jest/mockModal.js +31 -0
  233. package/jest/setup.js +5 -3
  234. package/just-task.js +2 -1
  235. package/package.json +23 -20
  236. package/rntypes/BatchedBridge.d.ts +23 -0
  237. package/rntypes/Devtools.d.ts +20 -0
  238. package/rntypes/LaunchScreen.d.ts +9 -0
  239. package/rntypes/globals.d.ts +496 -0
  240. package/rntypes/index.d.ts +9966 -0
  241. package/rntypes/legacy-properties.d.ts +266 -0
  242. package/template/cpp-app/proj/MyApp.vcxproj +0 -5
  243. package/template/cpp-app/src/pch.h +1 -0
  244. package/template/cpp-lib/src/pch.h +3 -0
  245. package/template/cs-app/proj/MyApp.csproj +0 -6
  246. package/typings-index.d.ts +2 -1
  247. package/typings-index.js +7 -5
  248. package/typings-index.js.map +1 -1
  249. package/Chakra/ChakraCoreDebugger.h +0 -147
  250. package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js +0 -87
  251. package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js +0 -30
  252. package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.windows.js +0 -30
  253. package/Libraries/Components/DatePickerAndroid/DatePickerAndroidTypes.js +0 -30
  254. package/Libraries/Components/StaticContainer.react.js +0 -51
  255. package/Libraries/Components/Touchable/ensurePositiveDelayProps.js +0 -25
  256. package/Libraries/Interaction/InteractionMixin.js +0 -54
  257. package/Libraries/ReactNative/queryLayoutByID.js +0 -58
  258. package/Scripts/Microsoft.ChakraCore.ARM64.nuspec +0 -50
  259. package/Scripts/Microsoft.ChakraCore.ARM64.targets +0 -15
  260. package/Shared/JSI/ChakraCoreRuntime.h +0 -59
  261. package/template/cpp-app/keys/MyApp_TemporaryKey.pfx +0 -0
  262. package/template/cs-app/keys/MyApp_TemporaryKey.pfx +0 -0
@@ -0,0 +1,343 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+
6
+ #include "TextHitTestUtils.h"
7
+
8
+ #include <UI.Xaml.Documents.h>
9
+ #include <math.h>
10
+
11
+ namespace Microsoft::ReactNative {
12
+
13
+ struct BidirectionalTextBoundary {
14
+ xaml::Documents::TextPointer ltrPointer{nullptr};
15
+ xaml::Documents::TextPointer rtlPointer{nullptr};
16
+ winrt::Rect ltrRect;
17
+ winrt::Rect rtlRect;
18
+ };
19
+
20
+ /*
21
+ * Checks if two text pointers are on the same line.
22
+ */
23
+ static bool IsSameLine(const winrt::Rect &x, const winrt::Rect &y) {
24
+ return std::abs(x.Y - y.Y) <= std::numeric_limits<float>().epsilon();
25
+ }
26
+
27
+ /*
28
+ * Checks if a text pointer is zero width relative to the next character.
29
+ */
30
+ static bool IsZeroWidth(const winrt::Rect &x, const winrt::Rect &y) {
31
+ return std::abs(x.X - y.X) <= std::numeric_limits<float>().epsilon();
32
+ }
33
+
34
+ /**
35
+ * Finds the character closest to X = 0 for the first line. I.e., the
36
+ * leftmost character when flow direction is left-to-right.
37
+ * ┌─────> X ↓
38
+ * │ (x,y) ┌─<─┐<┌─>─┐
39
+ * │ ┌──────┘ └─┘ │
40
+ * │ │ │
41
+ * ↓ │ ┌──────────┘
42
+ * Y └─────┘
43
+ */
44
+ static BidirectionalTextBoundary FindStartRTLBoundary(
45
+ const xaml::Documents::TextPointer &start,
46
+ const xaml::Documents::TextPointer &end,
47
+ const winrt::Rect &target) {
48
+ auto textPointer = start;
49
+ auto L = start.Offset();
50
+ auto R = end.Offset();
51
+ while (L <= R) {
52
+ const auto m = /* floor */ (L + R) / 2;
53
+ const auto relativeOffset = m - textPointer.Offset();
54
+ textPointer = textPointer.GetPositionAtOffset(relativeOffset, xaml::Documents::LogicalDirection::Forward);
55
+ const auto rect = textPointer.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
56
+ // If median character is on different line, boundary is before median
57
+ if (!IsSameLine(rect, target)) {
58
+ R = m - 1;
59
+ } else {
60
+ const auto prevPointer = textPointer.GetPositionAtOffset(-1, xaml::Documents::LogicalDirection::Forward);
61
+ const auto prevRect = prevPointer.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
62
+ if (prevRect.X > target.X) {
63
+ // If previous character is right of start, boundary is before median
64
+ R = m - 1;
65
+ } else if (rect.X <= target.X) {
66
+ // If median character is left of start, boundary is after median
67
+ L = m + 1;
68
+ } else {
69
+ // Otherwise, we've found the boundary where the previous character is
70
+ // the last RTL character and the median is the first LTR character
71
+ BidirectionalTextBoundary result;
72
+ result.rtlPointer = prevPointer;
73
+ result.rtlRect = prevRect;
74
+ result.ltrPointer = textPointer;
75
+ result.ltrRect = rect;
76
+ return result;
77
+ }
78
+ }
79
+ }
80
+
81
+ // No LTR characters on first line, R points to last character on first line
82
+ auto lastRTL = start;
83
+ auto lastRTLRect = target;
84
+ if (R > start.Offset()) {
85
+ const auto relativeOffset = R - start.Offset();
86
+ lastRTL = start.GetPositionAtOffset(relativeOffset, xaml::Documents::LogicalDirection::Forward);
87
+ lastRTLRect = lastRTL.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
88
+ }
89
+
90
+ BidirectionalTextBoundary result;
91
+ result.rtlPointer = lastRTL;
92
+ result.rtlRect = lastRTLRect;
93
+ return result;
94
+ }
95
+
96
+ /**
97
+ * Finds the character farthest from X = 0 for the last line. I.e., the
98
+ * rightmost character when flow direction is left-to-right.
99
+ * ┌─────> X
100
+ * │ (x,y) ┌──────┐
101
+ * │ ┌─────┘ │
102
+ * │ │ │
103
+ * ↓ │ ┌─┐ ┌──┘
104
+ * Y └─>─┘<└─<─┘
105
+ * ↑
106
+ */
107
+ static BidirectionalTextBoundary FindEndRTLBoundary(
108
+ const xaml::Documents::TextPointer &start,
109
+ const xaml::Documents::TextPointer &end,
110
+ const winrt::Rect &target) {
111
+ auto textPointer = start;
112
+ auto L = start.Offset();
113
+ auto R = end.Offset();
114
+ while (L <= R) {
115
+ const auto m = /* floor */ (L + R) / 2;
116
+ const auto relativeOffset = m - textPointer.Offset();
117
+ textPointer = textPointer.GetPositionAtOffset(relativeOffset, xaml::Documents::LogicalDirection::Forward);
118
+ const auto rect = textPointer.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
119
+ // If median character is on different line, boundary is after median
120
+ if (!IsSameLine(rect, target)) {
121
+ L = m + 1;
122
+ } else if (m < R) {
123
+ const auto nextPointer = textPointer.GetPositionAtOffset(1, xaml::Documents::LogicalDirection::Forward);
124
+ const auto nextRect = nextPointer.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
125
+ if (nextRect.X < target.X) {
126
+ // If next character is left of end, boundary is after median
127
+ L = m + 1;
128
+ } else if (rect.X >= target.X) {
129
+ // If median character is right of end, boundary is before median
130
+ R = m - 1;
131
+ } else {
132
+ // Otherwise, we've found the boundary where the next character is the
133
+ // first RTL character and the median is the last LTR character
134
+ BidirectionalTextBoundary result;
135
+ result.rtlPointer = nextPointer;
136
+ result.rtlRect = nextRect;
137
+ result.ltrPointer = textPointer;
138
+ result.ltrRect = rect;
139
+ return result;
140
+ }
141
+ } else {
142
+ break;
143
+ }
144
+ }
145
+
146
+ // No LTR characters on last line, L points to first character on last line
147
+ auto lastRTL = end;
148
+ auto lastRTLRect = target;
149
+ if (L < end.Offset()) {
150
+ const auto relativeOffset = L - end.Offset();
151
+ lastRTL = end.GetPositionAtOffset(relativeOffset, xaml::Documents::LogicalDirection::Forward);
152
+ lastRTLRect = lastRTL.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
153
+ }
154
+
155
+ BidirectionalTextBoundary result;
156
+ result.rtlPointer = lastRTL;
157
+ result.rtlRect = lastRTLRect;
158
+ return result;
159
+ }
160
+
161
+ /**
162
+ * Determine if the next character in the given direction on the same line is
163
+ * RTL. If the next character is not on the same line, assume LTR. This may be
164
+ * The case if the run has only one character on the target line.
165
+ */
166
+ static bool IsRTL(const xaml::Documents::TextPointer &textPointer, const winrt::Rect &rect, int direction) {
167
+ auto currentPointer = textPointer.GetPositionAtOffset(direction, xaml::Documents::LogicalDirection::Forward);
168
+ while (currentPointer != nullptr) {
169
+ const auto currentRect = currentPointer.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
170
+ if (!IsSameLine(currentRect, rect)) {
171
+ return false;
172
+ } else if (!IsZeroWidth(currentRect, rect)) {
173
+ return direction > 0 ? currentRect.X < rect.X : currentRect.X > rect.X;
174
+ }
175
+
176
+ currentPointer = currentPointer.GetPositionAtOffset(direction, xaml::Documents::LogicalDirection::Forward);
177
+ }
178
+
179
+ return false;
180
+ }
181
+
182
+ /**
183
+ * Determine if the character is either the first or last character of a line in the given direction.
184
+ */
185
+ static std::optional<winrt::Rect>
186
+ GetBoundaryCharacter(const xaml::Documents::TextPointer &textPointer, const winrt::Rect &rect, int direction) {
187
+ const auto nextPosition = textPointer.GetPositionAtOffset(direction, xaml::Documents::LogicalDirection::Forward);
188
+ if (nextPosition) {
189
+ const auto nextRect = nextPosition.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
190
+ if (IsSameLine(nextRect, rect)) {
191
+ return nextRect;
192
+ }
193
+ }
194
+
195
+ return std::nullopt;
196
+ }
197
+
198
+ bool IsInBounds(const winrt::Point &point, float left, float right, float top, float bottom) {
199
+ return left <= point.X && right >= point.X && top <= point.Y && bottom >= point.Y;
200
+ }
201
+
202
+ bool TextHitTestUtils::HitTest(const xaml::Documents::Run &run, const winrt::Point &targetPoint) {
203
+ const auto start = run.ContentStart();
204
+ const auto end = run.ContentEnd();
205
+ const auto startRect = start.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
206
+ const auto endRect = end.GetCharacterRect(xaml::Documents::LogicalDirection::Forward);
207
+
208
+ // Get first and last line vertical bounds
209
+ const auto startTop = startRect.Y;
210
+ const auto startBottom = startRect.Y + startRect.Height;
211
+ const auto endTop = endRect.Y;
212
+ const auto endBottom = endRect.Y + endRect.Height;
213
+
214
+ // Check if we have a single line of unidirectional text
215
+ const auto isSingleLine = IsSameLine(startRect, endRect);
216
+ const auto isStartRTL = IsRTL(start, startRect, 1);
217
+ const auto isEndRTL = IsRTL(end, endRect, -1);
218
+ const auto isUnidirectional = (!isStartRTL && !isEndRTL) || (isSingleLine && endRect.X < startRect.X);
219
+
220
+ // For unidirectional runs on the same line, we can use a simple bounding box test
221
+ if (isSingleLine && isUnidirectional) {
222
+ return endRect.X < startRect.X
223
+ ? IsInBounds(targetPoint, endRect.X + endRect.Width, startRect.X, startTop, startBottom)
224
+ : IsInBounds(targetPoint, startRect.X, endRect.X + endRect.Width, startTop, startBottom);
225
+ }
226
+
227
+ // If we don't have a single line of unidirectional text, we need to search
228
+ // up to 5 bounding boxes for the target point:
229
+ // 1. The lines between the first and last lines
230
+ // 2. The LTR characters on the first line after initial RTL
231
+ // 3. The LTR characters on the last line before final RTL
232
+ // 4. The initial RTL characters on the first line
233
+ // 5. The final RTL characters on the last line
234
+ //
235
+ // We can optimize the following situations:
236
+ // a. Skip step 2 if no LTR characters on the first line
237
+ // b. Skip step 3 if no LTR characters on the last line
238
+ // c. Skip step 4 if the first character is LTR
239
+ // d. Skip step 5 if the last character is LTR
240
+
241
+ // Get the parent bounds
242
+ const auto maxLeft = 0;
243
+ const auto maxRight = static_cast<float>(start.VisualParent().Width());
244
+
245
+ // Check if run is either the start or end of a line
246
+ const auto characterBeforeStart = GetBoundaryCharacter(start, startRect, -1);
247
+ const auto characterAfterEnd = GetBoundaryCharacter(end, endRect, 1);
248
+
249
+ // Find leftmost character of the first line and first LTR character
250
+ BidirectionalTextBoundary startBoundary;
251
+ startBoundary.ltrPointer = start;
252
+ startBoundary.ltrRect = startRect;
253
+ if (isStartRTL) {
254
+ startBoundary = FindStartRTLBoundary(start, end, startRect);
255
+ }
256
+
257
+ // Find rightmost character of the last line and last LTR character
258
+ BidirectionalTextBoundary endBoundary;
259
+ endBoundary.ltrPointer = end;
260
+ endBoundary.ltrRect = endRect;
261
+ if (isEndRTL) {
262
+ endBoundary = FindEndRTLBoundary(start, end, endRect);
263
+ }
264
+
265
+ // Step 1: The lines between the first and last lines
266
+ const auto middleTop = startBottom;
267
+ const auto middleBottom = endRect.Y;
268
+ if (middleTop <= targetPoint.Y && middleBottom >= targetPoint.Y) {
269
+ return true;
270
+ }
271
+
272
+ // Step 2: The LTR characters on the first line before initial RTL
273
+ // Optimization b: Skip if no LTR characters in first line
274
+ if (startBoundary.ltrPointer) {
275
+ auto left = startBoundary.ltrRect.X;
276
+ if (!characterBeforeStart.has_value()) {
277
+ left = maxLeft;
278
+ }
279
+
280
+ auto right = maxRight;
281
+ if (isSingleLine && characterAfterEnd.has_value()) {
282
+ // TODO(#7792): last LTR character is ignored because width is always 0
283
+ right = endBoundary.ltrRect.X + endBoundary.ltrRect.Width;
284
+ }
285
+
286
+ if (IsInBounds(targetPoint, left, right, startTop, startBottom)) {
287
+ return true;
288
+ }
289
+ }
290
+
291
+ // Step 3: The LTR characters on the last line after final RTL
292
+ // Optimization b: Skip if no LTR characters in last line
293
+ if (!isSingleLine && endBoundary.ltrPointer) {
294
+ const auto left = 0;
295
+ // TODO(#7792): last LTR character is ignored because width is always 0
296
+ auto right = endBoundary.ltrRect.X + endBoundary.ltrRect.Width;
297
+ if (!characterAfterEnd.has_value()) {
298
+ right = maxRight;
299
+ }
300
+
301
+ if (IsInBounds(targetPoint, left, right, endTop, endBottom)) {
302
+ return true;
303
+ }
304
+ }
305
+
306
+ // Step 4: The initial RTL characters on the first line
307
+ // Optimization c: Skip if first line starts with LTR
308
+ if (isStartRTL) {
309
+ // TODO(#7792): last RTL character is ignored because width is always 0
310
+ auto left = startBoundary.rtlRect.X + startBoundary.rtlRect.Width;
311
+ if (!characterBeforeStart.has_value()) {
312
+ left = maxLeft;
313
+ }
314
+
315
+ auto right = maxRight;
316
+ if (isSingleLine) {
317
+ right = startRect.X;
318
+ }
319
+
320
+ if (IsInBounds(targetPoint, left, right, startTop, startBottom)) {
321
+ return true;
322
+ }
323
+ }
324
+
325
+ // Step 5: The final RTL characters on the last line
326
+ // Optimization d: Skip if last line ends with LTR
327
+ if (isEndRTL) {
328
+ // TODO(#7792): last RTL character is ignored because width is always 0
329
+ const auto left = endRect.X + endRect.Width;
330
+ auto right = endBoundary.rtlRect.X;
331
+ if (!characterAfterEnd.has_value()) {
332
+ right = maxRight;
333
+ }
334
+
335
+ if (IsInBounds(targetPoint, left, right, endTop, endBottom)) {
336
+ return true;
337
+ }
338
+ }
339
+
340
+ return false;
341
+ }
342
+
343
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,13 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <UI.Xaml.Controls.h>
7
+ #include <UI.Xaml.Documents.h>
8
+
9
+ namespace Microsoft::ReactNative {
10
+ struct TextHitTestUtils final {
11
+ static bool HitTest(const xaml::Documents::Run &run, const winrt::Point &targetPoint);
12
+ };
13
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,76 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "TextHitTestVisitor.h"
5
+ #include <Views/VirtualTextViewManager.h>
6
+ #include "TextHitTestUtils.h"
7
+
8
+ namespace winrt {
9
+ using namespace xaml::Documents;
10
+ } // namespace winrt
11
+
12
+ namespace Microsoft::ReactNative {
13
+
14
+ void TextHitTestVisitor::VisitCore(ShadowNodeBase *node) {
15
+ for (auto childTag : node->m_children) {
16
+ Visit(GetShadowNode(childTag));
17
+
18
+ // Stop recursion if we found the target
19
+ if (m_targetFound) {
20
+ break;
21
+ }
22
+ }
23
+ }
24
+
25
+ void TextHitTestVisitor::VisitRawText(ShadowNodeBase *node) {
26
+ // Only hit test the raw text if there is a pressable ancestor
27
+ if (m_hasPressableAncestor) {
28
+ const auto run = node->GetView().as<winrt::Run>();
29
+ if (TextHitTestUtils::HitTest(run, m_point)) {
30
+ m_targetFound = true;
31
+ }
32
+ }
33
+ }
34
+
35
+ void TextHitTestVisitor::VisitVirtualText(ShadowNodeBase *node) {
36
+ const auto textNode = static_cast<VirtualTextShadowNode *>(node);
37
+
38
+ // Update pressable count and set pressable ancestor flag
39
+ const auto hadPressableAncestor = m_hasPressableAncestor;
40
+ if (textNode->isPressable) {
41
+ m_pressableCount++;
42
+ m_hasPressableAncestor = true;
43
+ }
44
+
45
+ // Capture initial count to determine if node still has pressable descendants
46
+ const auto initialCount = m_pressableCount;
47
+
48
+ // Continue recursion if there is a pressable descendant or ancestor
49
+ if (textNode->hasDescendantPressable || m_hasPressableAncestor) {
50
+ // Visit children
51
+ Super::VisitVirtualText(node);
52
+
53
+ // Reset pressable descendant state if descendants are no longer pressable
54
+ if (m_pressableCount == initialCount) {
55
+ textNode->hasDescendantPressable = false;
56
+ }
57
+
58
+ // If the target is null after target was found, set the target to the
59
+ // current view. This will set the target to the first virtual text
60
+ // ancestor of the target raw text node as well as handle when a descendant
61
+ // view manager sets `pointerEvents` to "none" or "box-none".
62
+ if (m_targetFound && !m_args.Target()) {
63
+ m_args.Target(node->GetView());
64
+ }
65
+
66
+ // Invoke view manager OnPointerEvent method for `pointerEvents` behavior
67
+ if (m_args.Target()) {
68
+ node->GetViewManager()->OnPointerEvent(node, m_args);
69
+ }
70
+ }
71
+
72
+ // Reset pressable ancestor state
73
+ m_hasPressableAncestor = hadPressableAncestor;
74
+ }
75
+
76
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,32 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include "TextVisitor.h"
7
+
8
+ namespace Microsoft::ReactNative {
9
+
10
+ class TextHitTestVisitor : public TextVisitor {
11
+ using Super = TextVisitor;
12
+
13
+ public:
14
+ TextHitTestVisitor(winrt::Microsoft::ReactNative::ReactPointerEventArgs const &args, winrt::Point const &point)
15
+ : Super(), m_args{args}, m_point{point} {}
16
+
17
+ protected:
18
+ void VisitCore(ShadowNodeBase *node) override;
19
+
20
+ void VisitRawText(ShadowNodeBase *node) override;
21
+
22
+ void VisitVirtualText(ShadowNodeBase *node) override;
23
+
24
+ private:
25
+ winrt::Microsoft::ReactNative::ReactPointerEventArgs const &m_args;
26
+ winrt::Point const &m_point;
27
+ bool m_hasPressableAncestor{false};
28
+ int m_pressableCount{0};
29
+ bool m_targetFound{false};
30
+ };
31
+
32
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,12 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "TextParentVisitor.h"
5
+
6
+ namespace Microsoft::ReactNative {
7
+
8
+ void TextParentVisitor::VisitCore(ShadowNodeBase *node) {
9
+ Visit(GetShadowNode(node->m_parent));
10
+ }
11
+
12
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,19 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include "TextVisitor.h"
7
+
8
+ namespace Microsoft::ReactNative {
9
+
10
+ class TextParentVisitor : public TextVisitor {
11
+ using Super = TextVisitor;
12
+
13
+ protected:
14
+ void VisitCore(ShadowNodeBase *node) override;
15
+
16
+ void VisitText(ShadowNodeBase *node) override{};
17
+ };
18
+
19
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,80 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "TextPropertyChangedParentVisitor.h"
5
+ #include <UI.Xaml.Automation.Peers.h>
6
+ #include <UI.Xaml.Automation.h>
7
+ #include <UI.Xaml.Controls.h>
8
+ #include <UI.Xaml.Documents.h>
9
+ #include <Utils/ShadowNodeTypeUtils.h>
10
+ #include <Views/TextViewManager.h>
11
+ #include <Views/VirtualTextViewManager.h>
12
+
13
+ namespace winrt {
14
+ using namespace xaml::Automation;
15
+ using namespace xaml::Automation::Peers;
16
+ using namespace xaml::Documents;
17
+ } // namespace winrt
18
+
19
+ namespace Microsoft::ReactNative {
20
+ void TextPropertyChangedParentVisitor::VisitCore(ShadowNodeBase *node) {
21
+ // Update nested flag fast text updates
22
+ m_isNested = !IsRawTextShadowNode(node);
23
+ Super::VisitCore(node);
24
+ }
25
+
26
+ void TextPropertyChangedParentVisitor::VisitText(ShadowNodeBase *node) {
27
+ // Raise LiveRegionChanged event
28
+ const auto isTextUpdate = HasPropertyChangeType(PropertyChangeType::Text);
29
+ if (isTextUpdate) {
30
+ const auto element = node->GetView().as<xaml::Controls::TextBlock>();
31
+
32
+ // If name is set, it's controlled by accessibilityLabel, and it's already
33
+ // handled in FrameworkElementViewManager. Here it only handles when name is
34
+ // not set.
35
+ if (xaml::Automation::AutomationProperties::GetLiveSetting(element) != winrt::AutomationLiveSetting::Off &&
36
+ xaml::Automation::AutomationProperties::GetName(element).empty() &&
37
+ xaml::Automation::AutomationProperties::GetAccessibilityView(element) != winrt::AccessibilityView::Raw) {
38
+ if (auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement(element)) {
39
+ peer.RaiseAutomationEvent(winrt::AutomationEvents::LiveRegionChanged);
40
+ }
41
+ }
42
+
43
+ // Update fast text content
44
+ if (!m_isNested && node->m_children.size() == 1) {
45
+ if (const auto childNode = GetShadowNode(node->m_children[0])) {
46
+ const auto run = static_cast<ShadowNodeBase *>(childNode)->GetView().as<winrt::Run>();
47
+ element.Text(run.Text());
48
+ }
49
+ }
50
+ }
51
+
52
+ // Refresh text highlighters
53
+ const auto isHighlightAdded = HasPropertyChangeType(PropertyChangeType::AddHighlight);
54
+ const auto isHighlightRemoved = HasPropertyChangeType(PropertyChangeType::RemoveHighlight);
55
+ if (isTextUpdate || isHighlightAdded || isHighlightRemoved) {
56
+ TextViewManager::UpdateTextHighlighters(node, isHighlightAdded);
57
+ }
58
+
59
+ // Set pressable descendant
60
+ if (HasPropertyChangeType(PropertyChangeType::AddPressable)) {
61
+ TextViewManager::SetDescendantPressable(node);
62
+ }
63
+ }
64
+
65
+ void TextPropertyChangedParentVisitor::VisitVirtualText(ShadowNodeBase *node) {
66
+ const auto textNode = static_cast<VirtualTextShadowNode *>(node);
67
+ // Update descendant text highlight flag
68
+ if (HasPropertyChangeType(PropertyChangeType::AddHighlight)) {
69
+ textNode->hasDescendantTextHighlighter = true;
70
+ }
71
+
72
+ // Update pressable descendant flag
73
+ if (HasPropertyChangeType(PropertyChangeType::AddPressable)) {
74
+ textNode->hasDescendantPressable = true;
75
+ }
76
+
77
+ Super::VisitVirtualText(node);
78
+ }
79
+
80
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,43 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <Views/TextViewManager.h>
7
+ #include "TextParentVisitor.h"
8
+
9
+ namespace Microsoft::ReactNative {
10
+
11
+ enum class PropertyChangeType : std::uint_fast8_t {
12
+ None = 0,
13
+ Text = 1 << 0,
14
+ AddHighlight = 1 << 1,
15
+ RemoveHighlight = 1 << 2,
16
+ AddPressable = 1 << 3,
17
+ };
18
+
19
+ DEFINE_ENUM_FLAG_OPERATORS(PropertyChangeType);
20
+
21
+ class TextPropertyChangedParentVisitor : public TextParentVisitor {
22
+ using Super = TextParentVisitor;
23
+
24
+ public:
25
+ TextPropertyChangedParentVisitor(PropertyChangeType type) : m_propertyChangeType{type} {}
26
+
27
+ protected:
28
+ void VisitCore(ShadowNodeBase *node) override;
29
+
30
+ void VisitText(ShadowNodeBase *node) override;
31
+
32
+ void VisitVirtualText(ShadowNodeBase *node) override;
33
+
34
+ private:
35
+ PropertyChangeType m_propertyChangeType;
36
+ bool m_isNested{false};
37
+
38
+ bool HasPropertyChangeType(PropertyChangeType type) {
39
+ return (m_propertyChangeType & type) == type;
40
+ }
41
+ };
42
+
43
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,21 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "TextTransformParentVisitor.h"
5
+ #include <Views/TextViewManager.h>
6
+ #include <Views/VirtualTextViewManager.h>
7
+
8
+ namespace Microsoft::ReactNative {
9
+
10
+ void TextTransformParentVisitor::VisitText(ShadowNodeBase *node) {
11
+ textTransform = TextViewManager::GetTextTransformValue(node);
12
+ }
13
+
14
+ void TextTransformParentVisitor::VisitVirtualText(ShadowNodeBase *node) {
15
+ textTransform = static_cast<VirtualTextShadowNode *>(node)->textTransform;
16
+ if (textTransform == TextTransform::Undefined) {
17
+ Super::VisitVirtualText(node);
18
+ }
19
+ }
20
+
21
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,23 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <Utils/TextTransform.h>
7
+ #include "TextParentVisitor.h"
8
+
9
+ namespace Microsoft::ReactNative {
10
+
11
+ class TextTransformParentVisitor : public TextParentVisitor {
12
+ using Super = TextParentVisitor;
13
+
14
+ public:
15
+ TextTransform textTransform;
16
+
17
+ protected:
18
+ void VisitText(ShadowNodeBase *node) override;
19
+
20
+ void VisitVirtualText(ShadowNodeBase *node) override;
21
+ };
22
+
23
+ } // namespace Microsoft::ReactNative