react-native-windows 0.81.15 → 0.81.18
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.
- package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.cpp +20 -31
- package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.h +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +56 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +6 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +135 -18
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +10 -0
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +5 -0
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +3 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +3 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.cpp +2 -7
- package/Microsoft.ReactNative/IReactPackageBuilder.idl +5 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -1
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +2 -0
- package/Microsoft.ReactNative/ReactPackageBuilder.cpp +7 -0
- package/Microsoft.ReactNative/ReactPackageBuilder.h +1 -0
- package/Microsoft.ReactNative/TurboModulesProvider.cpp +5 -10
- package/Microsoft.ReactNative/TurboModulesProvider.h +2 -0
- package/Microsoft.ReactNative.Cxx/ModuleRegistration.cpp +8 -2
- package/Microsoft.ReactNative.Cxx/ModuleRegistration.h +17 -4
- package/Microsoft.ReactNative.Cxx/NativeModules.h +5 -0
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpApp.targets +1 -1
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.targets +1 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +2 -1
- package/PropertySheets/WinUI.props +3 -3
- package/Scripts/Tfs/Invoke-WebRequestWithRetry.ps1 +40 -0
- package/Shared/Shared.vcxitems.filters +2 -0
- package/package.json +1 -1
|
@@ -9,18 +9,6 @@
|
|
|
9
9
|
|
|
10
10
|
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
11
11
|
|
|
12
|
-
// Ideally isColorMeaningful would be sufficient here. But it appears to detect platformColors as not meaningful
|
|
13
|
-
// https://github.com/microsoft/react-native-windows/issues/14006
|
|
14
|
-
bool isColorMeaningful(
|
|
15
|
-
const facebook::react::SharedColor &color,
|
|
16
|
-
winrt::Microsoft::ReactNative::Composition::implementation::Theme *theme) noexcept {
|
|
17
|
-
if (!color) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return theme->Color(*color).A > 0;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
12
|
// We don't want half pixel borders, or border radii - they lead to blurry borders
|
|
25
13
|
// Also apply scale factor to the radii at this point
|
|
26
14
|
void pixelRoundBorderRadii(facebook::react::BorderRadii &borderRadii, float scaleFactor) noexcept {
|
|
@@ -40,22 +28,20 @@ void pixelRoundBorderRadii(facebook::react::BorderRadii &borderRadii, float scal
|
|
|
40
28
|
};
|
|
41
29
|
}
|
|
42
30
|
|
|
31
|
+
float pixelRoundAndScaleBorderWidth(float width, float scaleFactor) noexcept {
|
|
32
|
+
if (width == 0)
|
|
33
|
+
return width = 0;
|
|
34
|
+
return std::max(1.f, std::round(width * scaleFactor));
|
|
35
|
+
}
|
|
36
|
+
|
|
43
37
|
void scaleAndPixelRoundBorderWidths(
|
|
44
38
|
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
45
39
|
facebook::react::BorderMetrics &borderMetrics,
|
|
46
40
|
float scaleFactor) noexcept {
|
|
47
|
-
borderMetrics.borderWidths.left = (borderMetrics.borderWidths.left
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
borderMetrics.borderWidths.
|
|
51
|
-
? 0.f
|
|
52
|
-
: std::max(1.f, std::round(borderMetrics.borderWidths.top * scaleFactor));
|
|
53
|
-
borderMetrics.borderWidths.right = (borderMetrics.borderWidths.right == 0)
|
|
54
|
-
? 0.f
|
|
55
|
-
: std::max(1.f, std::round(borderMetrics.borderWidths.right * scaleFactor));
|
|
56
|
-
borderMetrics.borderWidths.bottom = (borderMetrics.borderWidths.bottom == 0)
|
|
57
|
-
? 0.f
|
|
58
|
-
: std::max(1.f, std::round(borderMetrics.borderWidths.bottom * scaleFactor));
|
|
41
|
+
borderMetrics.borderWidths.left = pixelRoundAndScaleBorderWidth(borderMetrics.borderWidths.left, scaleFactor);
|
|
42
|
+
borderMetrics.borderWidths.top = pixelRoundAndScaleBorderWidth(borderMetrics.borderWidths.top, scaleFactor);
|
|
43
|
+
borderMetrics.borderWidths.right = pixelRoundAndScaleBorderWidth(borderMetrics.borderWidths.right, scaleFactor);
|
|
44
|
+
borderMetrics.borderWidths.bottom = pixelRoundAndScaleBorderWidth(borderMetrics.borderWidths.bottom, scaleFactor);
|
|
59
45
|
|
|
60
46
|
// If we rounded both sides of the borderWidths up, we may have made the borderWidths larger than the total
|
|
61
47
|
if (layoutMetrics.frame.size.width * scaleFactor <
|
|
@@ -356,7 +342,7 @@ void SetBorderLayerPropertiesCommon(
|
|
|
356
342
|
// Clear with transparency
|
|
357
343
|
pRT->Clear();
|
|
358
344
|
|
|
359
|
-
if (!isColorMeaningful(borderColor
|
|
345
|
+
if (!facebook::react::isColorMeaningful(borderColor)) {
|
|
360
346
|
return;
|
|
361
347
|
}
|
|
362
348
|
|
|
@@ -724,7 +710,7 @@ winrt::com_ptr<ID2D1GeometryGroup> GetGeometryForRoundedBorder(
|
|
|
724
710
|
BorderPrimitive::BorderPrimitive(
|
|
725
711
|
winrt::Microsoft::ReactNative::Composition::implementation::ComponentView &outer,
|
|
726
712
|
const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &rootVisual)
|
|
727
|
-
: m_outer(&outer), m_rootVisual(rootVisual) {}
|
|
713
|
+
: m_outer(&outer), m_rootVisual(rootVisual), m_ownsRootVisual(false) {}
|
|
728
714
|
|
|
729
715
|
BorderPrimitive::BorderPrimitive(winrt::Microsoft::ReactNative::Composition::implementation::ComponentView &outer)
|
|
730
716
|
: m_outer(&outer), m_rootVisual(outer.CompositionContext().CreateSpriteVisual()) {}
|
|
@@ -740,9 +726,9 @@ bool BorderPrimitive::requiresBorder(
|
|
|
740
726
|
auto borderStyle = borderMetrics.borderStyles.left;
|
|
741
727
|
|
|
742
728
|
bool hasMeaningfulColor =
|
|
743
|
-
!borderMetrics.borderColors.isUniform() ||
|
|
729
|
+
!borderMetrics.borderColors.isUniform() || facebook::react::isColorMeaningful(borderMetrics.borderColors.left);
|
|
744
730
|
bool hasMeaningfulWidth = !borderMetrics.borderWidths.isUniform() || (borderMetrics.borderWidths.left != 0);
|
|
745
|
-
if (!hasMeaningfulColor
|
|
731
|
+
if (!hasMeaningfulColor || !hasMeaningfulWidth) {
|
|
746
732
|
return false;
|
|
747
733
|
}
|
|
748
734
|
return true;
|
|
@@ -802,8 +788,10 @@ BorderPrimitive::FindSpecialBorderLayers() const noexcept {
|
|
|
802
788
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
|
|
803
789
|
|
|
804
790
|
if (m_numBorderVisuals) {
|
|
791
|
+
auto borderInsertAtIndex = m_ownsRootVisual ? 0 : m_outer->borderInsertAtIndex();
|
|
792
|
+
|
|
805
793
|
for (uint8_t i = 0; i < m_numBorderVisuals; i++) {
|
|
806
|
-
auto visual = m_rootVisual.GetAt(i);
|
|
794
|
+
auto visual = m_rootVisual.GetAt(i + borderInsertAtIndex);
|
|
807
795
|
layers[i] = visual.as<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual>();
|
|
808
796
|
}
|
|
809
797
|
}
|
|
@@ -830,7 +818,7 @@ bool BorderPrimitive::TryUpdateSpecialBorderLayers(
|
|
|
830
818
|
auto borderStyle = borderMetrics.borderStyles.left;
|
|
831
819
|
|
|
832
820
|
bool hasMeaningfulColor =
|
|
833
|
-
!borderMetrics.borderColors.isUniform() || !isColorMeaningful(borderMetrics.borderColors.left
|
|
821
|
+
!borderMetrics.borderColors.isUniform() || !facebook::react::isColorMeaningful(borderMetrics.borderColors.left);
|
|
834
822
|
bool hasMeaningfulWidth = !borderMetrics.borderWidths.isUniform() || (borderMetrics.borderWidths.left != 0);
|
|
835
823
|
if (!hasMeaningfulColor && !hasMeaningfulWidth) {
|
|
836
824
|
return false;
|
|
@@ -838,9 +826,10 @@ bool BorderPrimitive::TryUpdateSpecialBorderLayers(
|
|
|
838
826
|
|
|
839
827
|
// Create the special border layers if they don't exist yet
|
|
840
828
|
if (!spBorderVisuals[0]) {
|
|
829
|
+
auto borderInsertAtIndex = m_ownsRootVisual ? 0 : m_outer->borderInsertAtIndex();
|
|
841
830
|
for (uint8_t i = 0; i < SpecialBorderLayerCount; i++) {
|
|
842
831
|
auto visual = m_outer->CompositionContext().CreateSpriteVisual();
|
|
843
|
-
m_rootVisual.InsertAt(visual, i);
|
|
832
|
+
m_rootVisual.InsertAt(visual, i + borderInsertAtIndex);
|
|
844
833
|
spBorderVisuals[i] = std::move(visual);
|
|
845
834
|
m_numBorderVisuals++;
|
|
846
835
|
}
|
|
@@ -14,6 +14,8 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
|
14
14
|
|
|
15
15
|
struct ComponentView;
|
|
16
16
|
|
|
17
|
+
float pixelRoundAndScaleBorderWidth(float width, float scaleFactor) noexcept;
|
|
18
|
+
|
|
17
19
|
// Controls adding/removing appropriate visuals to a parent to render a specific border without requiring
|
|
18
20
|
struct BorderPrimitive {
|
|
19
21
|
static constexpr size_t SpecialBorderLayerCount = 8;
|
|
@@ -74,7 +76,8 @@ struct BorderPrimitive {
|
|
|
74
76
|
uint8_t m_numBorderVisuals{0};
|
|
75
77
|
winrt::Microsoft::ReactNative::Composition::implementation::ComponentView *m_outer;
|
|
76
78
|
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_rootVisual{nullptr};
|
|
77
|
-
bool m_needsUpdate{true};
|
|
79
|
+
bool m_needsUpdate : 1 {true};
|
|
80
|
+
bool m_ownsRootVisual : 1 {false};
|
|
78
81
|
};
|
|
79
82
|
|
|
80
83
|
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -1098,12 +1098,26 @@ void CompositionEventHandler::onPointerCaptureLost(
|
|
|
1098
1098
|
if (SurfaceId() == -1)
|
|
1099
1099
|
return;
|
|
1100
1100
|
|
|
1101
|
-
if (m_pointerCapturingComponentTag) {
|
|
1101
|
+
if (m_pointerCapturingComponentTag != -1) {
|
|
1102
1102
|
// copy array to avoid iterator being invalidated during deletion
|
|
1103
1103
|
std::unordered_set<PointerId> capturedPointers = m_capturedPointers;
|
|
1104
1104
|
|
|
1105
1105
|
for (auto pointerId : capturedPointers) {
|
|
1106
1106
|
releasePointerCapture(pointerId, m_pointerCapturingComponentTag);
|
|
1107
|
+
|
|
1108
|
+
// Cancel any active touch for this pointer so React Native is notified that
|
|
1109
|
+
// the touch ended. Without this, m_activeTouches retains a zombie entry and
|
|
1110
|
+
// RN JS is never told the touch is gone — leaving Pressables stuck in a
|
|
1111
|
+
// pressed state after a system-interrupted gesture (e.g. system back swipe,
|
|
1112
|
+
// Alt+Tab, another window coming foreground).
|
|
1113
|
+
auto activeTouch = m_activeTouches.find(pointerId);
|
|
1114
|
+
if (activeTouch != m_activeTouches.end()) {
|
|
1115
|
+
ActiveTouch cancelledTouchCopy = std::move(activeTouch->second);
|
|
1116
|
+
m_activeTouches.erase(activeTouch);
|
|
1117
|
+
if (cancelledTouchCopy.eventEmitter) {
|
|
1118
|
+
DispatchSynthesizedTouchCancelForActiveTouch(cancelledTouchCopy, pointerPoint, keyModifiers);
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1107
1121
|
}
|
|
1108
1122
|
|
|
1109
1123
|
m_pointerCapturingComponentTag = -1;
|
|
@@ -1220,6 +1234,37 @@ void CompositionEventHandler::onPointerExited(
|
|
|
1220
1234
|
}
|
|
1221
1235
|
}
|
|
1222
1236
|
|
|
1237
|
+
// Windows touch pointer IDs can be arbitrarily large (e.g. 2233). React Native's JS
|
|
1238
|
+
// touch handler uses identifiers as array indices and warns/misbehaves for values > 20.
|
|
1239
|
+
// This function maps each live Windows pointer to a small identifier in [0, 19] by
|
|
1240
|
+
// scanning m_activeTouches for in-use slots and cycling from the last assigned index.
|
|
1241
|
+
// Identifier MOUSE_POINTER_ID (1) is permanently reserved for mouse and never returned here.
|
|
1242
|
+
int CompositionEventHandler::AllocateTouchIdentifier() noexcept {
|
|
1243
|
+
constexpr int kMaxTouchIdentifier = 20;
|
|
1244
|
+
for (int i = 0; i < kMaxTouchIdentifier; i++) {
|
|
1245
|
+
int candidate = (m_touchId + i) % kMaxTouchIdentifier;
|
|
1246
|
+
if (candidate == static_cast<int>(MOUSE_POINTER_ID)) {
|
|
1247
|
+
continue; // reserved for mouse
|
|
1248
|
+
}
|
|
1249
|
+
bool inUse = std::any_of(m_activeTouches.begin(), m_activeTouches.end(), [candidate](const auto &pair) {
|
|
1250
|
+
return pair.second.touch.identifier == candidate;
|
|
1251
|
+
});
|
|
1252
|
+
if (!inUse) {
|
|
1253
|
+
m_touchId = (candidate + 1) % kMaxTouchIdentifier;
|
|
1254
|
+
return candidate;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
// All non-mouse slots occupied (> 19 simultaneous touch/pen points) — wrap anyway,
|
|
1258
|
+
// skipping the mouse-reserved slot.
|
|
1259
|
+
int fallback = m_touchId;
|
|
1260
|
+
m_touchId = (m_touchId + 1) % kMaxTouchIdentifier;
|
|
1261
|
+
if (fallback == static_cast<int>(MOUSE_POINTER_ID)) {
|
|
1262
|
+
fallback = m_touchId;
|
|
1263
|
+
m_touchId = (m_touchId + 1) % kMaxTouchIdentifier;
|
|
1264
|
+
}
|
|
1265
|
+
return fallback;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1223
1268
|
void CompositionEventHandler::onPointerPressed(
|
|
1224
1269
|
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
|
|
1225
1270
|
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
|
|
@@ -1328,11 +1373,18 @@ void CompositionEventHandler::onPointerPressed(
|
|
|
1328
1373
|
UpdateActiveTouch(activeTouch, ptScaled, ptLocal);
|
|
1329
1374
|
|
|
1330
1375
|
activeTouch.isPrimary = pointerId == 1;
|
|
1331
|
-
|
|
1376
|
+
// Map the Windows pointer ID to a small identifier (0–19) safe for use as a JS array index.
|
|
1377
|
+
// Windows touch IDs can be arbitrarily large (e.g. 2233), which causes React Native to warn
|
|
1378
|
+
// and corrupts touch state, leaving Pressables stuck after a scroll.
|
|
1379
|
+
// Mouse pointer ID is always 1 (MOUSE_POINTER_ID), which is already within the safe range —
|
|
1380
|
+
// use it directly to preserve stable, predictable identifier assignment for mouse input.
|
|
1381
|
+
activeTouch.touch.identifier = (pointerPoint.PointerDeviceType() == Composition::Input::PointerDeviceType::Mouse)
|
|
1382
|
+
? static_cast<int>(MOUSE_POINTER_ID)
|
|
1383
|
+
: AllocateTouchIdentifier();
|
|
1332
1384
|
|
|
1333
1385
|
// If the pointer has not been marked as hovering over views before the touch started, we register
|
|
1334
1386
|
// that the activeTouch should not maintain its hovered state once the pointer has been lifted.
|
|
1335
|
-
auto currentlyHoveredTags = m_currentlyHoveredViewsPerPointer.find(
|
|
1387
|
+
auto currentlyHoveredTags = m_currentlyHoveredViewsPerPointer.find(pointerId);
|
|
1336
1388
|
if (currentlyHoveredTags == m_currentlyHoveredViewsPerPointer.end() || currentlyHoveredTags->second.empty()) {
|
|
1337
1389
|
activeTouch.shouldLeaveWhenReleased = true;
|
|
1338
1390
|
}
|
|
@@ -1647,7 +1699,7 @@ void CompositionEventHandler::DispatchTouchEvent(
|
|
|
1647
1699
|
continue;
|
|
1648
1700
|
}
|
|
1649
1701
|
|
|
1650
|
-
if (
|
|
1702
|
+
if (pair.first == pointerId) {
|
|
1651
1703
|
event.changedTouches.insert(activeTouch.touch);
|
|
1652
1704
|
}
|
|
1653
1705
|
uniqueEventEmitters.insert(activeTouch.eventEmitter);
|
|
@@ -162,8 +162,13 @@ class CompositionEventHandler : public std::enable_shared_from_this<CompositionE
|
|
|
162
162
|
void UpdateCursor() noexcept;
|
|
163
163
|
void SetCursor(facebook::react::Cursor cursor, HCURSOR hcur) noexcept;
|
|
164
164
|
|
|
165
|
+
// Allocates a small touch identifier (0–19) that is safe to use as a JS array index.
|
|
166
|
+
// Windows pointer IDs can be arbitrarily large, which causes React Native to warn and
|
|
167
|
+
// back-fill huge arrays, corrupting touch state after scrolling.
|
|
168
|
+
int AllocateTouchIdentifier() noexcept;
|
|
169
|
+
|
|
165
170
|
std::map<PointerId, ActiveTouch> m_activeTouches; // iOS is map of touch event args to ActiveTouch..?
|
|
166
|
-
|
|
171
|
+
int m_touchId = 0; // cycling base used by AllocateTouchIdentifier
|
|
167
172
|
|
|
168
173
|
std::map<PointerId, std::vector<ReactTaggedView>> m_currentlyHoveredViewsPerPointer;
|
|
169
174
|
winrt::weak_ref<winrt::Microsoft::ReactNative::ReactNativeIsland> m_wkRootView;
|
|
@@ -40,9 +40,11 @@ constexpr float FOCUS_VISUAL_RADIUS = 3.0f;
|
|
|
40
40
|
|
|
41
41
|
// m_outerVisual
|
|
42
42
|
// |
|
|
43
|
-
// ----- m_visual
|
|
43
|
+
// ----- m_visual - Can be a custom visual depending on Component type
|
|
44
44
|
// |
|
|
45
|
-
// -----
|
|
45
|
+
// ----- m_backgroundVisual <-- Background / clip (ComponentViewFeatures::Background)
|
|
46
|
+
// ----- Border Visuals x N (BorderPrimitive attached to m_visual) (ComponentViewFeatures::NativeBorder)
|
|
47
|
+
// ----- Outline Visuals x N(BorderPrimitive) (ComponentViewFeatures::NativeBorder)
|
|
46
48
|
// ----- <children> (default: directly in m_visual after border visuals)
|
|
47
49
|
// ----- m_childrenContainer (created on demand when overflow:hidden, children moved here)
|
|
48
50
|
// ------Focus Visual Container (created when hosting focus visuals)
|
|
@@ -81,18 +83,16 @@ facebook::react::Props::Shared ComponentView::props() noexcept {
|
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
void ComponentView::onThemeChanged() noexcept {
|
|
84
|
-
if (
|
|
85
|
-
|
|
86
|
-
Visual().as<Experimental::ISpriteVisual>().Brush(theme()->Brush(*viewProps()->backgroundColor));
|
|
87
|
-
} else {
|
|
88
|
-
Visual().as<Experimental::ISpriteVisual>().Brush(nullptr);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
86
|
+
if (m_backgroundVisual)
|
|
87
|
+
m_backgroundVisual.Brush(theme()->Brush(*viewProps()->backgroundColor));
|
|
91
88
|
|
|
92
89
|
if (m_borderPrimitive) {
|
|
93
90
|
m_borderPrimitive->onThemeChanged(
|
|
94
91
|
m_layoutMetrics, BorderPrimitive::resolveAndAlignBorderMetrics(m_layoutMetrics, *viewProps()));
|
|
95
92
|
}
|
|
93
|
+
if (m_outlinePrimitive) {
|
|
94
|
+
m_outlinePrimitive->onThemeChanged(outlineLayoutMetrics(), outlineBorderMetrics());
|
|
95
|
+
}
|
|
96
96
|
if (m_componentHostingFocusVisual) {
|
|
97
97
|
if (m_componentHostingFocusVisual->m_focusPrimitive->m_focusInnerPrimitive) {
|
|
98
98
|
auto innerFocusMetrics = focusLayoutMetrics(true /*inner*/);
|
|
@@ -156,10 +156,18 @@ void ComponentView::updateProps(
|
|
|
156
156
|
|
|
157
157
|
if ((m_flags & ComponentViewFeatures::Background) == ComponentViewFeatures::Background) {
|
|
158
158
|
if (oldViewProps.backgroundColor != newViewProps.backgroundColor) {
|
|
159
|
-
if (newViewProps.backgroundColor) {
|
|
160
|
-
|
|
159
|
+
if (facebook::react::isColorMeaningful(newViewProps.backgroundColor)) {
|
|
160
|
+
if (!m_backgroundVisual) {
|
|
161
|
+
m_backgroundVisual = m_compContext.CreateSpriteVisual();
|
|
162
|
+
m_backgroundVisual.RelativeSizeWithOffset({0, 0}, {1.0f, 1.0f});
|
|
163
|
+
Visual().InsertAt(m_backgroundVisual, 0);
|
|
164
|
+
}
|
|
165
|
+
m_backgroundVisual.Brush(theme()->Brush(*newViewProps.backgroundColor));
|
|
166
|
+
updateClippingPath(m_layoutMetrics, *viewProps());
|
|
161
167
|
} else {
|
|
162
|
-
|
|
168
|
+
if (m_backgroundVisual) {
|
|
169
|
+
m_backgroundVisual.Brush(nullptr);
|
|
170
|
+
}
|
|
163
171
|
}
|
|
164
172
|
}
|
|
165
173
|
}
|
|
@@ -168,6 +176,16 @@ void ComponentView::updateProps(
|
|
|
168
176
|
m_borderPrimitive->updateProps(oldViewProps, newViewProps);
|
|
169
177
|
}
|
|
170
178
|
|
|
179
|
+
if (m_outlinePrimitive) {
|
|
180
|
+
if (oldViewProps.outlineOffset != newViewProps.outlineOffset ||
|
|
181
|
+
oldViewProps.outlineWidth != newViewProps.outlineWidth ||
|
|
182
|
+
oldViewProps.borderRadii != newViewProps.borderRadii ||
|
|
183
|
+
oldViewProps.outlineColor != newViewProps.outlineColor ||
|
|
184
|
+
oldViewProps.outlineStyle != newViewProps.outlineStyle) {
|
|
185
|
+
m_outlinePrimitive->markNeedsUpdate();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
171
189
|
if (m_componentHostingFocusVisual) {
|
|
172
190
|
if (!newViewProps.enableFocusRing) {
|
|
173
191
|
m_componentHostingFocusVisual->hostFocusVisual(false, get_strong());
|
|
@@ -202,8 +220,9 @@ void ComponentView::updateProps(
|
|
|
202
220
|
void ComponentView::updateLayoutMetrics(
|
|
203
221
|
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
204
222
|
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
|
|
223
|
+
updateClippingPath(layoutMetrics, *viewProps());
|
|
224
|
+
|
|
205
225
|
if ((m_flags & ComponentViewFeatures::NativeBorder) == ComponentViewFeatures::NativeBorder) {
|
|
206
|
-
updateClippingPath(layoutMetrics, *viewProps());
|
|
207
226
|
OuterVisual().Size(
|
|
208
227
|
{layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
|
|
209
228
|
layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
|
|
@@ -220,6 +239,9 @@ void ComponentView::updateLayoutMetrics(
|
|
|
220
239
|
if (m_borderPrimitive) {
|
|
221
240
|
m_borderPrimitive->markNeedsUpdate();
|
|
222
241
|
}
|
|
242
|
+
if (m_outlinePrimitive) {
|
|
243
|
+
m_outlinePrimitive->markNeedsUpdate();
|
|
244
|
+
}
|
|
223
245
|
|
|
224
246
|
if (m_componentHostingFocusVisual) {
|
|
225
247
|
m_componentHostingFocusVisual->updateFocusLayoutMetrics();
|
|
@@ -303,6 +325,23 @@ void ComponentView::FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentView
|
|
|
303
325
|
if (m_borderPrimitive) {
|
|
304
326
|
m_borderPrimitive->finalize(m_layoutMetrics, borderMetrics);
|
|
305
327
|
}
|
|
328
|
+
|
|
329
|
+
auto outlineMetrics = outlineBorderMetrics();
|
|
330
|
+
if (!m_outlinePrimitive && BorderPrimitive::requiresBorder(outlineMetrics, theme())) {
|
|
331
|
+
m_outlinePrimitive = std::make_shared<BorderPrimitive>(*this);
|
|
332
|
+
Visual().InsertAt(
|
|
333
|
+
m_outlinePrimitive->RootVisual(),
|
|
334
|
+
(m_backgroundVisual ? 1 : 0) + (m_borderPrimitive ? m_borderPrimitive->numberOfVisuals() : 0));
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (m_outlinePrimitive) {
|
|
338
|
+
auto offset = pixelRoundAndScaleBorderWidth(viewProps()->outlineWidth, m_layoutMetrics.pointScaleFactor) +
|
|
339
|
+
std::round(viewProps()->outlineOffset * m_layoutMetrics.pointScaleFactor);
|
|
340
|
+
m_outlinePrimitive->RootVisual().Offset({-offset, -offset, 0.0f});
|
|
341
|
+
m_outlinePrimitive->RootVisual().RelativeSizeWithOffset({offset * 2, offset * 2}, {1.0f, 1.0f});
|
|
342
|
+
|
|
343
|
+
m_outlinePrimitive->finalize(outlineLayoutMetrics(), outlineMetrics);
|
|
344
|
+
}
|
|
306
345
|
}
|
|
307
346
|
|
|
308
347
|
if (m_componentHostingFocusVisual) {
|
|
@@ -583,6 +622,67 @@ facebook::react::LayoutMetrics ComponentView::focusLayoutMetrics(bool inner) con
|
|
|
583
622
|
return layoutMetrics;
|
|
584
623
|
}
|
|
585
624
|
|
|
625
|
+
facebook::react::LayoutMetrics ComponentView::outlineLayoutMetrics() const noexcept {
|
|
626
|
+
auto &props = *viewProps();
|
|
627
|
+
auto offset = (pixelRoundAndScaleBorderWidth(viewProps()->outlineWidth, m_layoutMetrics.pointScaleFactor) +
|
|
628
|
+
std::round(viewProps()->outlineOffset * m_layoutMetrics.pointScaleFactor)) /
|
|
629
|
+
m_layoutMetrics.pointScaleFactor;
|
|
630
|
+
facebook::react::LayoutMetrics layoutMetrics = m_layoutMetrics;
|
|
631
|
+
layoutMetrics.frame.origin.x -= offset;
|
|
632
|
+
layoutMetrics.frame.origin.y -= offset;
|
|
633
|
+
layoutMetrics.frame.size.height += offset * 2;
|
|
634
|
+
layoutMetrics.frame.size.width += offset * 2;
|
|
635
|
+
return layoutMetrics;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
facebook::react::BorderMetrics ComponentView::outlineBorderMetrics() const noexcept {
|
|
639
|
+
auto &props = *viewProps();
|
|
640
|
+
|
|
641
|
+
facebook::react::BorderMetrics metrics = BorderPrimitive::resolveAndAlignBorderMetrics(m_layoutMetrics, props);
|
|
642
|
+
metrics.borderColors.bottom = metrics.borderColors.left = metrics.borderColors.right = metrics.borderColors.top =
|
|
643
|
+
props.outlineColor;
|
|
644
|
+
|
|
645
|
+
auto offset = pixelRoundAndScaleBorderWidth(viewProps()->outlineWidth, m_layoutMetrics.pointScaleFactor) +
|
|
646
|
+
std::round(viewProps()->outlineOffset * m_layoutMetrics.pointScaleFactor);
|
|
647
|
+
|
|
648
|
+
if (metrics.borderRadii.bottomLeft.horizontal)
|
|
649
|
+
metrics.borderRadii.bottomLeft.horizontal = std::max(0.0f, metrics.borderRadii.bottomLeft.horizontal + offset);
|
|
650
|
+
if (metrics.borderRadii.bottomLeft.vertical)
|
|
651
|
+
metrics.borderRadii.bottomLeft.vertical = std::max(0.0f, metrics.borderRadii.bottomLeft.vertical + offset);
|
|
652
|
+
if (metrics.borderRadii.bottomRight.horizontal)
|
|
653
|
+
metrics.borderRadii.bottomRight.horizontal = std::max(0.0f, metrics.borderRadii.bottomRight.horizontal + offset);
|
|
654
|
+
if (metrics.borderRadii.bottomRight.vertical)
|
|
655
|
+
metrics.borderRadii.bottomRight.vertical = std::max(0.0f, metrics.borderRadii.bottomRight.vertical + offset);
|
|
656
|
+
if (metrics.borderRadii.topLeft.horizontal)
|
|
657
|
+
metrics.borderRadii.topLeft.horizontal = std::max(0.0f, metrics.borderRadii.topLeft.horizontal + offset);
|
|
658
|
+
if (metrics.borderRadii.topLeft.vertical)
|
|
659
|
+
metrics.borderRadii.topLeft.vertical = std::max(0.0f, metrics.borderRadii.topLeft.vertical + offset);
|
|
660
|
+
if (metrics.borderRadii.topRight.horizontal)
|
|
661
|
+
metrics.borderRadii.topRight.horizontal = std::max(0.0f, metrics.borderRadii.topRight.horizontal + offset);
|
|
662
|
+
if (metrics.borderRadii.topRight.vertical)
|
|
663
|
+
metrics.borderRadii.topRight.vertical = std::max(0.0f, metrics.borderRadii.topRight.vertical + offset);
|
|
664
|
+
|
|
665
|
+
static_assert(
|
|
666
|
+
facebook::react::BorderStyle::Solid ==
|
|
667
|
+
static_cast<facebook::react::BorderStyle>(facebook::react::OutlineStyle::Solid));
|
|
668
|
+
static_assert(
|
|
669
|
+
facebook::react::BorderStyle::Dotted ==
|
|
670
|
+
static_cast<facebook::react::BorderStyle>(facebook::react::OutlineStyle::Dotted));
|
|
671
|
+
static_assert(
|
|
672
|
+
facebook::react::BorderStyle::Dashed ==
|
|
673
|
+
static_cast<facebook::react::BorderStyle>(facebook::react::OutlineStyle::Dashed));
|
|
674
|
+
assert(
|
|
675
|
+
props.outlineStyle == facebook::react::OutlineStyle::Solid ||
|
|
676
|
+
props.outlineStyle == facebook::react::OutlineStyle::Dotted ||
|
|
677
|
+
props.outlineStyle == facebook::react::OutlineStyle::Dashed);
|
|
678
|
+
metrics.borderStyles.bottom = metrics.borderStyles.left = metrics.borderStyles.right = metrics.borderStyles.top =
|
|
679
|
+
static_cast<facebook::react::BorderStyle>(props.outlineStyle);
|
|
680
|
+
|
|
681
|
+
metrics.borderWidths.bottom = metrics.borderWidths.left = metrics.borderWidths.right = metrics.borderWidths.top =
|
|
682
|
+
pixelRoundAndScaleBorderWidth(viewProps()->outlineWidth, m_layoutMetrics.pointScaleFactor);
|
|
683
|
+
return metrics;
|
|
684
|
+
}
|
|
685
|
+
|
|
586
686
|
facebook::react::BorderMetrics ComponentView::focusBorderMetrics(
|
|
587
687
|
bool inner,
|
|
588
688
|
const facebook::react::LayoutMetrics &layoutMetrics) const noexcept {
|
|
@@ -656,7 +756,7 @@ void ComponentView::hostFocusVisual(bool show, winrt::com_ptr<ComponentView> vie
|
|
|
656
756
|
assert(
|
|
657
757
|
view.get() ==
|
|
658
758
|
this); // When not using lifted comp, focus visuals should always host within their own component
|
|
659
|
-
OuterVisual().InsertAt(m_focusPrimitive->m_focusVisual, 1);
|
|
759
|
+
OuterVisual().InsertAt(m_focusPrimitive->m_focusVisual, (m_backgroundVisual ? 2 : 1));
|
|
660
760
|
}
|
|
661
761
|
}
|
|
662
762
|
|
|
@@ -900,9 +1000,23 @@ void ComponentView::Toggle() noexcept {
|
|
|
900
1000
|
// no-op
|
|
901
1001
|
}
|
|
902
1002
|
|
|
1003
|
+
// This offset ensures that the m_borderPrimitive inserts its layers above the background
|
|
1004
|
+
int32_t ComponentView::borderInsertAtIndex() const noexcept {
|
|
1005
|
+
return m_backgroundVisual ? 1 : 0;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ComponentView::VisualToApplyBackgroundClipTo()
|
|
1009
|
+
const noexcept {
|
|
1010
|
+
return m_backgroundVisual;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
903
1013
|
void ComponentView::updateClippingPath(
|
|
904
1014
|
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
905
1015
|
const facebook::react::ViewProps &viewProps) noexcept {
|
|
1016
|
+
auto clipTarget = VisualToApplyBackgroundClipTo();
|
|
1017
|
+
if (!clipTarget)
|
|
1018
|
+
return;
|
|
1019
|
+
|
|
906
1020
|
auto borderMetrics = BorderPrimitive::resolveAndAlignBorderMetrics(layoutMetrics, viewProps);
|
|
907
1021
|
|
|
908
1022
|
bool hasRoundedCorners = borderMetrics.borderRadii.topLeft.horizontal != 0 ||
|
|
@@ -921,10 +1035,10 @@ void ComponentView::updateClippingPath(
|
|
|
921
1035
|
winrt::com_ptr<ID2D1PathGeometry> pathGeometry = BorderPrimitive::GenerateRoundedRectPathGeometry(
|
|
922
1036
|
m_compContext, borderMetrics.borderRadii, {0, 0, 0, 0}, {0, 0, viewWidth, viewHeight});
|
|
923
1037
|
|
|
924
|
-
|
|
1038
|
+
clipTarget.as<::Microsoft::ReactNative::Composition::Experimental::IVisualInterop>()->SetClippingPath(
|
|
925
1039
|
pathGeometry.get());
|
|
926
1040
|
} else {
|
|
927
|
-
|
|
1041
|
+
clipTarget.as<::Microsoft::ReactNative::Composition::Experimental::IVisualInterop>()->SetClippingPath(nullptr);
|
|
928
1042
|
}
|
|
929
1043
|
}
|
|
930
1044
|
|
|
@@ -936,6 +1050,9 @@ void ComponentView::indexOffsetForBorder(uint32_t &index) const noexcept {
|
|
|
936
1050
|
if (m_borderPrimitive) {
|
|
937
1051
|
index += m_borderPrimitive->numberOfVisuals();
|
|
938
1052
|
}
|
|
1053
|
+
if (m_outlinePrimitive) {
|
|
1054
|
+
index += 1;
|
|
1055
|
+
}
|
|
939
1056
|
}
|
|
940
1057
|
|
|
941
1058
|
void ComponentView::OnRenderingDeviceLost() noexcept {}
|
|
@@ -1086,7 +1203,7 @@ void ViewComponentView::ensureVisual() noexcept {
|
|
|
1086
1203
|
} else {
|
|
1087
1204
|
m_visual = createVisual();
|
|
1088
1205
|
}
|
|
1089
|
-
OuterVisual().InsertAt(m_visual, 0);
|
|
1206
|
+
OuterVisual().InsertAt(m_visual, m_backgroundVisual ? 1 : 0);
|
|
1090
1207
|
}
|
|
1091
1208
|
}
|
|
1092
1209
|
|
|
@@ -1384,7 +1501,7 @@ void ViewComponentView::updateChildrenClippingPath(
|
|
|
1384
1501
|
}
|
|
1385
1502
|
|
|
1386
1503
|
// Insert m_childrenContainer after border visuals in m_visual
|
|
1387
|
-
Visual().InsertAt(m_childrenContainer, borderCount);
|
|
1504
|
+
Visual().InsertAt(m_childrenContainer, (m_backgroundVisual ? 1 : 0) + borderCount);
|
|
1388
1505
|
|
|
1389
1506
|
// Use relative sizing so container automatically tracks parent's size
|
|
1390
1507
|
m_childrenContainer.RelativeSizeWithOffset({0, 0}, {1, 1});
|
|
@@ -111,6 +111,9 @@ struct ComponentView : public ComponentViewT<
|
|
|
111
111
|
bool getAcccessiblityIsReadOnly() noexcept override;
|
|
112
112
|
ToggleState getToggleState() noexcept override;
|
|
113
113
|
void Toggle() noexcept override;
|
|
114
|
+
|
|
115
|
+
int32_t borderInsertAtIndex() const noexcept;
|
|
116
|
+
|
|
114
117
|
virtual winrt::Microsoft::ReactNative::implementation::ClipState getClipState() noexcept;
|
|
115
118
|
|
|
116
119
|
virtual std::pair<facebook::react::Cursor, HCURSOR> cursor() const noexcept;
|
|
@@ -130,6 +133,8 @@ struct ComponentView : public ComponentViewT<
|
|
|
130
133
|
void ThemeChanged(winrt::event_token const &token) noexcept;
|
|
131
134
|
|
|
132
135
|
protected:
|
|
136
|
+
virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual VisualToApplyBackgroundClipTo()
|
|
137
|
+
const noexcept;
|
|
133
138
|
bool anyHitTestHelper(
|
|
134
139
|
facebook::react::Tag &targetTag,
|
|
135
140
|
facebook::react::Point &ptContent,
|
|
@@ -141,6 +146,7 @@ struct ComponentView : public ComponentViewT<
|
|
|
141
146
|
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext m_compContext;
|
|
142
147
|
comp::CompositionPropertySet m_centerPropSet{nullptr};
|
|
143
148
|
facebook::react::SharedViewEventEmitter m_eventEmitter;
|
|
149
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual m_backgroundVisual{nullptr};
|
|
144
150
|
|
|
145
151
|
private:
|
|
146
152
|
void updateFocusLayoutMetrics() noexcept;
|
|
@@ -157,6 +163,9 @@ struct ComponentView : public ComponentViewT<
|
|
|
157
163
|
facebook::react::BorderMetrics focusBorderMetrics(bool inner, const facebook::react::LayoutMetrics &layoutMetrics)
|
|
158
164
|
const noexcept;
|
|
159
165
|
|
|
166
|
+
facebook::react::LayoutMetrics outlineLayoutMetrics() const noexcept;
|
|
167
|
+
facebook::react::BorderMetrics outlineBorderMetrics() const noexcept;
|
|
168
|
+
|
|
160
169
|
virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual visualToHostFocus() noexcept;
|
|
161
170
|
virtual winrt::com_ptr<ComponentView> focusVisualRoot(const facebook::react::Rect &focusRect) noexcept;
|
|
162
171
|
|
|
@@ -168,6 +177,7 @@ struct ComponentView : public ComponentViewT<
|
|
|
168
177
|
winrt::com_ptr<ComponentView>
|
|
169
178
|
m_componentHostingFocusVisual; // The component that we are showing our focus visuals within
|
|
170
179
|
std::shared_ptr<BorderPrimitive> m_borderPrimitive;
|
|
180
|
+
std::shared_ptr<BorderPrimitive> m_outlinePrimitive;
|
|
171
181
|
std::unique_ptr<FocusPrimitive> m_focusPrimitive{nullptr};
|
|
172
182
|
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_outerVisual{nullptr};
|
|
173
183
|
winrt::event<winrt::Windows::Foundation::EventHandler<winrt::IInspectable>> m_themeChangedEvent;
|
|
@@ -237,6 +237,11 @@ void ImageComponentView::onThemeChanged() noexcept {
|
|
|
237
237
|
Super::onThemeChanged();
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ImageComponentView::VisualToApplyBackgroundClipTo()
|
|
241
|
+
const noexcept {
|
|
242
|
+
return Visual();
|
|
243
|
+
}
|
|
244
|
+
|
|
240
245
|
void ImageComponentView::ensureDrawingSurface() noexcept {
|
|
241
246
|
assert(m_reactContext.UIDispatcher().HasThreadAccess());
|
|
242
247
|
|
|
@@ -53,6 +53,8 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ViewComponen
|
|
|
53
53
|
|
|
54
54
|
virtual std::string DefaultControlType() const noexcept;
|
|
55
55
|
static facebook::react::SharedViewProps defaultProps() noexcept;
|
|
56
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual VisualToApplyBackgroundClipTo()
|
|
57
|
+
const noexcept override;
|
|
56
58
|
|
|
57
59
|
ImageComponentView(
|
|
58
60
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
@@ -334,7 +334,9 @@ void ParagraphComponentView::updateVisualBrush() noexcept {
|
|
|
334
334
|
break;
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
|
-
|
|
337
|
+
|
|
338
|
+
if (alignment != m_textLayout->GetTextAlignment())
|
|
339
|
+
winrt::check_hresult(m_textLayout->SetTextAlignment(alignment));
|
|
338
340
|
}
|
|
339
341
|
|
|
340
342
|
requireNewBrush = true;
|
|
@@ -99,6 +99,9 @@ inline ColorComponents colorComponentsFromHostPlatformColor(Color color) {
|
|
|
99
99
|
|
|
100
100
|
// windows
|
|
101
101
|
inline bool hostPlatformColorIsColorMeaningful(Color color) noexcept {
|
|
102
|
+
if (color.m_platformColor.size())
|
|
103
|
+
return true;
|
|
104
|
+
|
|
102
105
|
auto windowsColor = color.AsWindowsColor();
|
|
103
106
|
return windowsColor.A > 0;
|
|
104
107
|
}
|
|
@@ -196,12 +196,7 @@ void WindowsTextLayoutManager::GetTextLayout(
|
|
|
196
196
|
));
|
|
197
197
|
|
|
198
198
|
// Apply max width constraint and ellipsis trimming to ensure consistency with rendering
|
|
199
|
-
|
|
200
|
-
winrt::check_hresult(spTextLayout->GetMetrics(&metrics));
|
|
201
|
-
|
|
202
|
-
if (metrics.width > size.width) {
|
|
203
|
-
spTextLayout->SetMaxWidth(size.width);
|
|
204
|
-
}
|
|
199
|
+
spTextLayout->SetMaxWidth(size.width);
|
|
205
200
|
|
|
206
201
|
// Apply DWRITE_TRIMMING for ellipsizeMode
|
|
207
202
|
DWRITE_TRIMMING trimming = {};
|
|
@@ -396,7 +391,7 @@ void WindowsTextLayoutManager::GetTextLayoutByAdjustingFontSizeToFit(
|
|
|
396
391
|
}
|
|
397
392
|
}
|
|
398
393
|
|
|
399
|
-
// measure entire text (
|
|
394
|
+
// measure entire text (including attachments)
|
|
400
395
|
TextMeasurement TextLayoutManager::measure(
|
|
401
396
|
const AttributedStringBox &attributedStringBox,
|
|
402
397
|
const ParagraphAttributes ¶graphAttributes,
|
|
@@ -32,6 +32,11 @@ namespace Microsoft.ReactNative
|
|
|
32
32
|
"NOTE: TurboModules using JSI directly will not run correctly while using @ReactInstanceSettings.UseWebDebugger")
|
|
33
33
|
void AddTurboModule(String moduleName, ReactModuleProvider moduleProvider);
|
|
34
34
|
|
|
35
|
+
DOC_STRING("Adds a custom native module. See @ReactModuleProvider. This will register the"
|
|
36
|
+
"module as a TurboModule. This module will be created and have init called as soon as the"
|
|
37
|
+
"instance is created, event before the module is accessed from JavaScript.")
|
|
38
|
+
void AddEagerInitTurboModule(String moduleName, ReactModuleProvider moduleProvider);
|
|
39
|
+
|
|
35
40
|
#if !defined(CORE_ABI) && !defined(USE_FABRIC)
|
|
36
41
|
DOC_STRING("Adds a custom view manager. See @ReactViewManagerProvider.")
|
|
37
42
|
void AddViewManager(String viewManagerName, ReactViewManagerProvider viewManagerProvider);
|
|
@@ -637,7 +637,7 @@
|
|
|
637
637
|
<ItemGroup>
|
|
638
638
|
<PackageReference Include="boost" Version="1.84.0.0" />
|
|
639
639
|
<PackageReference Include="Microsoft.Windows.CppWinRT" Version="$(CppWinRTVersion)" PrivateAssets="all" />
|
|
640
|
-
<PackageReference Include="
|
|
640
|
+
<PackageReference Include="$(HermesPackageName)" Version="$(HermesVersion)" />
|
|
641
641
|
<PackageReference Include="$(WinUIPackageName)" Version="$(WinUIPackageVersion)" Condition="'$(OverrideWinUIPackage)'!='true'" />
|
|
642
642
|
<PackageReference Include="$(V8PackageName)" Version="$(V8Version)" Condition="'$(UseV8)' == 'true'" />
|
|
643
643
|
</ItemGroup>
|
|
@@ -349,6 +349,7 @@ void ReactInstanceWin::LoadModules(
|
|
|
349
349
|
registerTurboModule(
|
|
350
350
|
L"FabricUIManagerBinding",
|
|
351
351
|
winrt::Microsoft::ReactNative::MakeModuleProvider<::Microsoft::ReactNative::FabricUIManager>());
|
|
352
|
+
turboModulesProvider->AddEagerInit("FabricUIManagerBinding");
|
|
352
353
|
}
|
|
353
354
|
#endif
|
|
354
355
|
|
|
@@ -357,6 +358,7 @@ void ReactInstanceWin::LoadModules(
|
|
|
357
358
|
L"UIManager",
|
|
358
359
|
// TODO: Use MakeTurboModuleProvider after it satisfies ReactNativeSpecs::UIManagerSpec
|
|
359
360
|
winrt::Microsoft::ReactNative::MakeModuleProvider<::Microsoft::ReactNative::UIManager>());
|
|
361
|
+
turboModulesProvider->AddEagerInit("UIManager");
|
|
360
362
|
#endif
|
|
361
363
|
|
|
362
364
|
#ifndef CORE_ABI
|
|
@@ -59,6 +59,13 @@ void ReactPackageBuilder::AddTurboModule(
|
|
|
59
59
|
m_turboModulesProvider->AddModuleProvider(moduleName, moduleProvider, true);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
void ReactPackageBuilder::AddEagerInitTurboModule(
|
|
63
|
+
hstring const &moduleName,
|
|
64
|
+
ReactModuleProvider const &moduleProvider) noexcept {
|
|
65
|
+
m_turboModulesProvider->AddModuleProvider(moduleName, moduleProvider, true);
|
|
66
|
+
m_turboModulesProvider->AddEagerInit(winrt::to_string(moduleName));
|
|
67
|
+
}
|
|
68
|
+
|
|
62
69
|
#ifdef USE_FABRIC
|
|
63
70
|
void ReactPackageBuilder::AddViewComponent(
|
|
64
71
|
winrt::hstring componentName,
|
|
@@ -43,6 +43,7 @@ struct ReactPackageBuilder : winrt::implements<
|
|
|
43
43
|
void AddViewManager(hstring const &viewManagerName, ReactViewManagerProvider const &viewManagerProvider) noexcept;
|
|
44
44
|
#endif
|
|
45
45
|
void AddTurboModule(hstring const &moduleName, ReactModuleProvider const &moduleProvider) noexcept;
|
|
46
|
+
void AddEagerInitTurboModule(hstring const &moduleName, ReactModuleProvider const &moduleProvider) noexcept;
|
|
46
47
|
|
|
47
48
|
#ifdef USE_FABRIC
|
|
48
49
|
// IReactPackageBuilderFabric
|
|
@@ -494,16 +494,11 @@ std::shared_ptr<facebook::react::TurboModule> TurboModulesProvider::getModule(
|
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
std::vector<std::string> TurboModulesProvider::getEagerInitModuleNames() noexcept {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
it = m_moduleProviders.find("FabricUIManagerBinding");
|
|
503
|
-
if (it != m_moduleProviders.end()) {
|
|
504
|
-
eagerModules.push_back("FabricUIManagerBinding");
|
|
505
|
-
}
|
|
506
|
-
return eagerModules;
|
|
497
|
+
return m_eagerInitModuleNames;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
void TurboModulesProvider::AddEagerInit(std::string moduleName) noexcept {
|
|
501
|
+
m_eagerInitModuleNames.push_back(moduleName);
|
|
507
502
|
}
|
|
508
503
|
|
|
509
504
|
void TurboModulesProvider::SetReactContext(const IReactContext &reactContext) noexcept {
|
|
@@ -26,6 +26,7 @@ class TurboModulesProvider final : public facebook::react::TurboModuleRegistry {
|
|
|
26
26
|
winrt::hstring const &moduleName,
|
|
27
27
|
ReactModuleProvider const &moduleProvider,
|
|
28
28
|
bool overwriteExisting) noexcept;
|
|
29
|
+
void AddEagerInit(std::string moduleName) noexcept;
|
|
29
30
|
std::shared_ptr<facebook::react::LongLivedObjectCollection> const &LongLivedObjectCollection() noexcept;
|
|
30
31
|
|
|
31
32
|
private:
|
|
@@ -33,6 +34,7 @@ class TurboModulesProvider final : public facebook::react::TurboModuleRegistry {
|
|
|
33
34
|
std::shared_ptr<facebook::react::LongLivedObjectCollection> m_longLivedObjectCollection{
|
|
34
35
|
std::make_shared<facebook::react::LongLivedObjectCollection>()};
|
|
35
36
|
std::unordered_map<std::string, ReactModuleProvider> m_moduleProviders;
|
|
37
|
+
std::vector<std::string> m_eagerInitModuleNames;
|
|
36
38
|
IReactContext m_reactContext;
|
|
37
39
|
};
|
|
38
40
|
|
|
@@ -18,7 +18,10 @@ ModuleRegistration::ModuleRegistration(wchar_t const *moduleName) noexcept : m_m
|
|
|
18
18
|
void AddAttributedModules(IReactPackageBuilder const &packageBuilder, bool useTurboModules) noexcept {
|
|
19
19
|
for (auto const *reg = ModuleRegistration::Head(); reg != nullptr; reg = reg->Next()) {
|
|
20
20
|
if (useTurboModules || reg->ShouldRegisterAsTurboModule())
|
|
21
|
-
|
|
21
|
+
if (reg->IsEagerInit())
|
|
22
|
+
packageBuilder.AddEagerInitTurboModule(reg->ModuleName(), reg->MakeModuleProvider());
|
|
23
|
+
else
|
|
24
|
+
packageBuilder.AddTurboModule(reg->ModuleName(), reg->MakeModuleProvider());
|
|
22
25
|
else
|
|
23
26
|
packageBuilder.AddModule(reg->ModuleName(), reg->MakeModuleProvider());
|
|
24
27
|
}
|
|
@@ -31,7 +34,10 @@ bool TryAddAttributedModule(
|
|
|
31
34
|
for (auto const *reg = ModuleRegistration::Head(); reg != nullptr; reg = reg->Next()) {
|
|
32
35
|
if (moduleName == reg->ModuleName()) {
|
|
33
36
|
if (useTurboModule || reg->ShouldRegisterAsTurboModule()) {
|
|
34
|
-
|
|
37
|
+
if (reg->IsEagerInit())
|
|
38
|
+
packageBuilder.AddEagerInitTurboModule(moduleName, reg->MakeModuleProvider());
|
|
39
|
+
else
|
|
40
|
+
packageBuilder.AddTurboModule(moduleName, reg->MakeModuleProvider());
|
|
35
41
|
} else {
|
|
36
42
|
packageBuilder.AddModule(moduleName, reg->MakeModuleProvider());
|
|
37
43
|
}
|
|
@@ -30,10 +30,11 @@ template <typename T>
|
|
|
30
30
|
struct IsReactTurboModule : std::bool_constant<ReactIsReactTurboModuleImpl(static_cast<T *>(nullptr))> {};
|
|
31
31
|
|
|
32
32
|
#define INTERNAL_REACT_MODULE_REGISTRATION_AND_PROVIDER( \
|
|
33
|
-
moduleStruct, moduleName, eventEmitterName, isReactTurboModule)
|
|
33
|
+
moduleStruct, moduleName, eventEmitterName, isReactTurboModule, isEagerInit) \
|
|
34
34
|
struct moduleStruct; \
|
|
35
35
|
\
|
|
36
36
|
constexpr bool ReactIsReactTurboModuleImpl(moduleStruct *) noexcept { return isReactTurboModule; } \
|
|
37
|
+
constexpr bool ReactIsEagerInitTurboModuleImpl(moduleStruct *) noexcept { return isEagerInit; } \
|
|
37
38
|
\
|
|
38
39
|
template <class TDummy> \
|
|
39
40
|
struct moduleStruct##_ModuleRegistration final : winrt::Microsoft::ReactNative::ModuleRegistration { \
|
|
@@ -44,6 +45,7 @@ struct IsReactTurboModule : std::bool_constant<ReactIsReactTurboModuleImpl(stati
|
|
|
44
45
|
} \
|
|
45
46
|
\
|
|
46
47
|
bool ShouldRegisterAsTurboModule() const noexcept override { return isReactTurboModule; } \
|
|
48
|
+
bool IsEagerInit() const noexcept override { return isEagerInit; } \
|
|
47
49
|
\
|
|
48
50
|
static const moduleStruct##_ModuleRegistration Registration; \
|
|
49
51
|
}; \
|
|
@@ -59,7 +61,7 @@ struct IsReactTurboModule : std::bool_constant<ReactIsReactTurboModuleImpl(stati
|
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
#define INTERNAL_REACT_MODULE_3_ARGS(moduleStruct, moduleName, eventEmitterName) \
|
|
62
|
-
INTERNAL_REACT_MODULE_REGISTRATION_AND_PROVIDER(moduleStruct, moduleName, eventEmitterName, false)
|
|
64
|
+
INTERNAL_REACT_MODULE_REGISTRATION_AND_PROVIDER(moduleStruct, moduleName, eventEmitterName, false, false)
|
|
63
65
|
|
|
64
66
|
#define INTERNAL_REACT_MODULE_2_ARGS(moduleStruct, moduleName) \
|
|
65
67
|
INTERNAL_REACT_MODULE_3_ARGS(moduleStruct, moduleName, L"")
|
|
@@ -104,17 +106,27 @@ struct IsReactTurboModule : std::bool_constant<ReactIsReactTurboModuleImpl(stati
|
|
|
104
106
|
|
|
105
107
|
// Register struct as a ReactNative module.
|
|
106
108
|
#define INTERNAL_REACT_TURBO_MODULE_2_ARGS(moduleStruct, moduleName) \
|
|
107
|
-
INTERNAL_REACT_MODULE_REGISTRATION_AND_PROVIDER(moduleStruct, moduleName, L"", true)
|
|
109
|
+
INTERNAL_REACT_MODULE_REGISTRATION_AND_PROVIDER(moduleStruct, moduleName, L"", true, false)
|
|
110
|
+
|
|
111
|
+
#define INTERNAL_REACT_EAGER_TURBO_MODULE_2_ARGS(moduleStruct, moduleName) \
|
|
112
|
+
INTERNAL_REACT_MODULE_REGISTRATION_AND_PROVIDER(moduleStruct, moduleName, L"", true, true)
|
|
108
113
|
|
|
109
114
|
#define INTERNAL_REACT_TURBO_MODULE_1_ARG(moduleStruct) \
|
|
110
115
|
INTERNAL_REACT_TURBO_MODULE_2_ARGS(moduleStruct, L## #moduleStruct)
|
|
111
116
|
|
|
117
|
+
#define INTERNAL_REACT_EAGER_TURBO_MODULE_1_ARG(moduleStruct) \
|
|
118
|
+
INTERNAL_REACT_EAGER_TURBO_MODULE_2_ARGS(moduleStruct, L## #moduleStruct)
|
|
119
|
+
|
|
112
120
|
#define INTERNAL_REACT_TURBO_MODULE(...) \
|
|
113
121
|
INTERNAL_REACT_RECOMPOSER_3((__VA_ARGS__, INTERNAL_REACT_TURBO_MODULE_2_ARGS, INTERNAL_REACT_TURBO_MODULE_1_ARG, ))
|
|
114
122
|
|
|
123
|
+
#define INTERNAL_REACT_EAGER_TURBO_MODULE(...) \
|
|
124
|
+
INTERNAL_REACT_RECOMPOSER_3( \
|
|
125
|
+
(__VA_ARGS__, INTERNAL_REACT_EAGER_TURBO_MODULE_2_ARGS, INTERNAL_REACT_EAGER_TURBO_MODULE_1_ARG, ))
|
|
126
|
+
|
|
115
127
|
// Another version of REACT_MODULE but does not do auto registration
|
|
116
128
|
#define INTERNAL_REACT_TURBO_MODULE_NOREG_2_ARGS(moduleStruct, moduleName) \
|
|
117
|
-
INTERNAL_REACT_MODULE_NO_REGISTRATION_AND_PROVIDER(moduleStruct, moduleName, L"", true)
|
|
129
|
+
INTERNAL_REACT_MODULE_NO_REGISTRATION_AND_PROVIDER(moduleStruct, moduleName, L"", true, false)
|
|
118
130
|
|
|
119
131
|
#define INTERNAL_REACT_TURBO_MODULE_NOREG_1_ARG(moduleStruct) \
|
|
120
132
|
INTERNAL_REACT_TURBO_MODULE_NOREG_2_ARGS(moduleStruct, L## #moduleStruct)
|
|
@@ -153,6 +165,7 @@ struct ModuleRegistration {
|
|
|
153
165
|
|
|
154
166
|
virtual ReactModuleProvider MakeModuleProvider() const noexcept = 0;
|
|
155
167
|
virtual bool ShouldRegisterAsTurboModule() const noexcept = 0;
|
|
168
|
+
virtual bool IsEagerInit() const noexcept = 0;
|
|
156
169
|
|
|
157
170
|
static ModuleRegistration const *Head() noexcept {
|
|
158
171
|
return s_head;
|
|
@@ -47,6 +47,11 @@
|
|
|
47
47
|
#define REACT_TURBO_MODULE(/* moduleStruct, [opt] moduleName */...) \
|
|
48
48
|
INTERNAL_REACT_TURBO_MODULE(__VA_ARGS__)(__VA_ARGS__)
|
|
49
49
|
|
|
50
|
+
// Same as REACT_TURBO_MODULE, but will register using AddEagerInitTurboModule, and this module
|
|
51
|
+
// will be created and init'd on instance creation.
|
|
52
|
+
#define REACT_EAGER_TURBO_MODULE(/* moduleStruct, [opt] moduleName */...) \
|
|
53
|
+
INTERNAL_REACT_EAGER_TURBO_MODULE(__VA_ARGS__)(__VA_ARGS__)
|
|
54
|
+
|
|
50
55
|
// REACT_MODULE_NOREG is REACT_MODULE without auto registration
|
|
51
56
|
// they have the same arguments
|
|
52
57
|
#define REACT_MODULE_NOREG(/* moduleStruct, [opt] moduleName, [opt] eventEmitterName */...) \
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<!-- WinUI package name and version are set by WinUI.props -->
|
|
26
26
|
<PackageReference Include="$(WinUIPackageName)" Version="$(WinUIPackageVersion)" Condition="'$(OverrideWinUIPackage)'!='true'" />
|
|
27
27
|
<!-- Hermes version is set by JSEngine.props -->
|
|
28
|
-
<PackageReference Include="
|
|
28
|
+
<PackageReference Include="$(HermesPackageName)" Version="$(HermesVersion)" Condition="$(UseHermes)" />
|
|
29
29
|
</ItemGroup>
|
|
30
30
|
|
|
31
31
|
<Import Project="$(ReactNativeWindowsDir)PropertySheets\ManagedCodeGen\Microsoft.ReactNative.Managed.CodeGen.targets"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<!-- WinUI package name and version are set by WinUI.props -->
|
|
26
26
|
<PackageReference Include="$(WinUIPackageName)" Version="$(WinUIPackageVersion)" Condition="'$(OverrideWinUIPackage)'!='true'" />
|
|
27
27
|
<!-- Hermes version is set by JSEngine.props -->
|
|
28
|
-
<PackageReference Include="
|
|
28
|
+
<PackageReference Include="$(HermesPackageName)" Version="$(HermesVersion)" Condition="$(UseHermes)" />
|
|
29
29
|
</ItemGroup>
|
|
30
30
|
|
|
31
31
|
<!-- The props file for bundling is not set up to be just defaults, it assumes to be run at the end of the project. -->
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.81.
|
|
13
|
+
<ReactNativeWindowsVersion>0.81.18</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>81</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>18</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
18
|
+
<ReactNativeWindowsCommitId>ffbb7afa1dbc3a60b57a6bca6025d3c0537b569e</ReactNativeWindowsCommitId>
|
|
19
19
|
</PropertyGroup>
|
|
20
20
|
</Project>
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
<UseHermes Condition="'$(UseHermes)' == ''">true</UseHermes>
|
|
8
8
|
<!-- This will be true if (1) the client want to use hermes by setting UseHermes to true OR (2) We are building for UWP where dynamic switching is enabled -->
|
|
9
9
|
<HermesVersion Condition="'$(HermesVersion)' == ''">0.0.0-2511.7001-d7ca19b3</HermesVersion>
|
|
10
|
+
<HermesPackageName Condition="'$(HermesPackageName)' == ''">Microsoft.JavaScript.Hermes</HermesPackageName>
|
|
10
11
|
<HermesPackage Condition="'$(HermesPackage)' == '' And Exists('$(PkgMicrosoft_JavaScript_Hermes)')">$(PkgMicrosoft_JavaScript_Hermes)</HermesPackage>
|
|
11
|
-
<HermesPackage Condition="'$(HermesPackage)' == ''">$(NuGetPackageRoot)
|
|
12
|
+
<HermesPackage Condition="'$(HermesPackage)' == ''">$(NuGetPackageRoot)\$(HermesPackageName)\$(HermesVersion)</HermesPackage>
|
|
12
13
|
<EnableHermesInspectorInReleaseFlavor Condition="'$(EnableHermesInspectorInReleaseFlavor)' == ''">false</EnableHermesInspectorInReleaseFlavor>
|
|
13
14
|
<!-- Disable linking Hermes into the output in cases where we need to fully rely on HermesShim -->
|
|
14
15
|
<HermesNoLink Condition="'$(HermesNoLink)' == '' and '$(Configuration)' == 'Release' and '$(EnableHermesInspectorInReleaseFlavor)' != 'true'">true</HermesNoLink>
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
<!--
|
|
6
6
|
Internal versions are typically only located at: https://microsoft.visualstudio.com/DefaultCollection/ProjectReunion/_artifacts/feed/Project.Reunion.nuget.internal/NuGet/Microsoft.WindowsAppSDK/versions
|
|
7
7
|
For local testing of internal versions, modify WinUI3ExperimentalVersion, and comment out the additional nuget source in NuGet.Config
|
|
8
|
-
When this version is updated, be sure to update the default for the enableInternalFeed parameter of /.ado/templates/enable-experimental-winui3.yml
|
|
8
|
+
When this version is updated, be sure to update the default for the enableInternalFeed parameter of /.ado/templates/enable-experimental-winui3.yml
|
|
9
9
|
-->
|
|
10
|
-
<WinUI3ExperimentalVersion Condition="'$(WinUI3ExperimentalVersion)'==''">1.
|
|
10
|
+
<WinUI3ExperimentalVersion Condition="'$(WinUI3ExperimentalVersion)'==''">1.8.251106002</WinUI3ExperimentalVersion>
|
|
11
11
|
<!-- This value is also used by the CLI, see /packages/@react-native-windows/cli/.../autolinkWindows.ts -->
|
|
12
12
|
<WinUI3Version Condition="'$(WinUI3Version)'=='' AND '$(UseExperimentalWinUI3)'=='true'">$(WinUI3ExperimentalVersion)</WinUI3Version>
|
|
13
|
-
<WinUI3Version Condition="'$(WinUI3Version)'==''">1.
|
|
13
|
+
<WinUI3Version Condition="'$(WinUI3Version)'==''">1.8.251106002</WinUI3Version>
|
|
14
14
|
<!-- This is needed to prevent build errors with WinAppSDK >= 1.7 trying to double build WindowsAppRuntimeAutoInitializer.cpp -->
|
|
15
15
|
<WindowsAppSdkAutoInitialize Condition="'$(WindowsAppSdkAutoInitialize)'=='' And $([MSBuild]::VersionGreaterThan('$(WinUI3Version)', '1.7.0'))">false</WindowsAppSdkAutoInitialize>
|
|
16
16
|
</PropertyGroup>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
<#
|
|
5
|
+
.SYNOPSIS
|
|
6
|
+
Downloads a file from a URI with retry logic.
|
|
7
|
+
|
|
8
|
+
.PARAMETER Uri
|
|
9
|
+
The URI to download from.
|
|
10
|
+
|
|
11
|
+
.PARAMETER OutFile
|
|
12
|
+
The output file path.
|
|
13
|
+
|
|
14
|
+
.PARAMETER MaxRetries
|
|
15
|
+
Maximum number of download attempts. Default is 3.
|
|
16
|
+
#>
|
|
17
|
+
param(
|
|
18
|
+
[Parameter(Mandatory)]
|
|
19
|
+
[string]$Uri,
|
|
20
|
+
|
|
21
|
+
[Parameter(Mandatory)]
|
|
22
|
+
[string]$OutFile,
|
|
23
|
+
|
|
24
|
+
[int]$MaxRetries = 3
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
Set-StrictMode -Version Latest
|
|
28
|
+
$ErrorActionPreference = 'Stop'
|
|
29
|
+
|
|
30
|
+
for ($i = 1; $i -le $MaxRetries; $i++) {
|
|
31
|
+
try {
|
|
32
|
+
Write-Host "Downloading $OutFile (attempt $i of $MaxRetries)"
|
|
33
|
+
Invoke-WebRequest -Uri $Uri -OutFile $OutFile
|
|
34
|
+
return
|
|
35
|
+
} catch {
|
|
36
|
+
Write-Host "Attempt $i failed: $_"
|
|
37
|
+
if ($i -eq $MaxRetries) { throw }
|
|
38
|
+
Start-Sleep -Seconds (5 * $i)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -336,6 +336,8 @@
|
|
|
336
336
|
<ClCompile Include="$(MSBuildThisFileDirectory)Inspector\ReactInspectorPackagerConnectionDelegate.cpp">
|
|
337
337
|
<Filter>Inspector</Filter>
|
|
338
338
|
</ClCompile>
|
|
339
|
+
<ClCompile Include="$(ReactNativeDir)\ReactCommon\cxxreact\Instance.cpp" />
|
|
340
|
+
<ClCompile Include="$(ReactNativeDir)\ReactCommon\cxxreact\JSExecutor.cpp" />
|
|
339
341
|
</ItemGroup>
|
|
340
342
|
<ItemGroup>
|
|
341
343
|
<Filter Include="Source Files">
|