react-native-windows 0.83.0-preview.1 → 0.83.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.
- package/Common/Common.vcxproj +1 -1
- package/Folly/Folly.vcxproj +1 -1
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/Core/setUpReactDevTools.js +23 -6
- package/Microsoft.ReactNative/ComponentView.idl +9 -1
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -2
- package/Microsoft.ReactNative/Fabric/ComponentView.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +9 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +10 -4
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +31 -8
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +10 -2
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +4 -4
- package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +10 -2
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +4 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +2 -2
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +4 -0
- package/PropertySheets/External/Microsoft.ReactNative.Composition.CppApp.targets +2 -2
- package/PropertySheets/External/Microsoft.ReactNative.Composition.CppLib.targets +2 -2
- 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 +2 -2
- package/PropertySheets/JSEngine.props +2 -1
- package/ReactCommon/ReactCommon.vcxproj +1 -1
- package/Scripts/Tfs/Invoke-WebRequestWithRetry.ps1 +40 -0
- package/Scripts/perf/compare-results.js +68 -12
- package/package.json +15 -15
package/Common/Common.vcxproj
CHANGED
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
</ItemGroup>
|
|
95
95
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
96
96
|
<ItemGroup>
|
|
97
|
-
<PackageReference Include="boost" Version="1.
|
|
97
|
+
<PackageReference Include="boost" Version="1.84.0.0" />
|
|
98
98
|
<PackageReference Include="Microsoft.Windows.CppWinRT" Version="$(CppWinRTVersion)" PrivateAssets="all" />
|
|
99
99
|
</ItemGroup>
|
|
100
100
|
<ImportGroup Label="ExtensionTargets">
|
package/Folly/Folly.vcxproj
CHANGED
|
@@ -362,7 +362,7 @@
|
|
|
362
362
|
<TemporaryFollyPatchFiles Include="$(MSBuildThisFileDirectory)\TEMP_UntilFollyUpdate\**\*.*" />
|
|
363
363
|
</ItemGroup>
|
|
364
364
|
<ItemGroup>
|
|
365
|
-
<PackageReference Include="boost" Version="1.
|
|
365
|
+
<PackageReference Include="boost" Version="1.84.0.0" />
|
|
366
366
|
</ItemGroup>
|
|
367
367
|
<Target Name="Deploy" />
|
|
368
368
|
<!-- Reenable this task if we need to temporarily replace any folly files for fixes, while we wait for PRs to land in folly -->
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
export default class ReactNativeVersion {
|
|
29
29
|
static major: number = 0;
|
|
30
30
|
static minor: number = 83;
|
|
31
|
-
static patch: number =
|
|
32
|
-
static prerelease: string | null =
|
|
31
|
+
static patch: number = 4;
|
|
32
|
+
static prerelease: string | null = null;
|
|
33
33
|
|
|
34
34
|
static getVersionString(): string {
|
|
35
35
|
return `${this.major}.${this.minor}.${this.patch}${this.prerelease != null ? `-${this.prerelease}` : ''}`;
|
|
@@ -146,17 +146,34 @@ if (__DEV__) {
|
|
|
146
146
|
? guessHostFromDevServerUrl(devServer.url)
|
|
147
147
|
: 'localhost';
|
|
148
148
|
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
|
|
149
|
+
// Derive scheme and port from the dev server URL when possible,
|
|
150
|
+
// falling back to ws://host:8097 for local development.
|
|
151
|
+
let wsScheme = 'ws';
|
|
152
|
+
let port = 8097;
|
|
153
|
+
|
|
154
|
+
if (
|
|
152
155
|
// $FlowFixMe[prop-missing]
|
|
153
156
|
// $FlowFixMe[incompatible-use]
|
|
154
157
|
window.__REACT_DEVTOOLS_PORT__ != null
|
|
155
|
-
|
|
156
|
-
|
|
158
|
+
) {
|
|
159
|
+
// $FlowFixMe[prop-missing]
|
|
160
|
+
port = window.__REACT_DEVTOOLS_PORT__;
|
|
161
|
+
} else if (devServer.bundleLoadedFromServer) {
|
|
162
|
+
try {
|
|
163
|
+
const devUrl = new URL(devServer.url);
|
|
164
|
+
if (devUrl.protocol === 'https:') {
|
|
165
|
+
wsScheme = 'wss';
|
|
166
|
+
}
|
|
167
|
+
if (devUrl.port) {
|
|
168
|
+
port = parseInt(devUrl.port, 10);
|
|
169
|
+
} else if (devUrl.protocol === 'https:') {
|
|
170
|
+
port = 443;
|
|
171
|
+
}
|
|
172
|
+
} catch (e) {}
|
|
173
|
+
}
|
|
157
174
|
|
|
158
175
|
const WebSocket = require('../WebSocket/WebSocket').default;
|
|
159
|
-
ws = new WebSocket('
|
|
176
|
+
ws = new WebSocket(wsScheme + '://' + host + ':' + port);
|
|
160
177
|
ws.addEventListener('close', event => {
|
|
161
178
|
isWebSocketOpen = false;
|
|
162
179
|
});
|
|
@@ -43,6 +43,14 @@ namespace Microsoft.ReactNative
|
|
|
43
43
|
Last,
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
+
enum FocusState
|
|
47
|
+
{
|
|
48
|
+
Unfocused = 0,
|
|
49
|
+
Pointer,
|
|
50
|
+
Keyboard,
|
|
51
|
+
Programmatic,
|
|
52
|
+
};
|
|
53
|
+
|
|
46
54
|
[webhosthidden]
|
|
47
55
|
[experimental]
|
|
48
56
|
interface IComponentState
|
|
@@ -99,7 +107,7 @@ namespace Microsoft.ReactNative
|
|
|
99
107
|
LayoutMetrics LayoutMetrics { get; };
|
|
100
108
|
IInspectable UserData;
|
|
101
109
|
|
|
102
|
-
Boolean TryFocus();
|
|
110
|
+
Boolean TryFocus(FocusState focusState);
|
|
103
111
|
|
|
104
112
|
DOC_STRING("Used to handle key down events when this component is focused, or if a child component did not handle the key down")
|
|
105
113
|
event Windows.Foundation.EventHandler<Microsoft.ReactNative.Composition.Input.KeyRoutedEventArgs> KeyDown;
|
|
@@ -283,6 +283,7 @@ void ComponentView::parent(const winrt::Microsoft::ReactNative::ComponentView &p
|
|
|
283
283
|
oldRootView->TrySetFocusedComponent(
|
|
284
284
|
oldParent,
|
|
285
285
|
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
286
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic,
|
|
286
287
|
true /*forceNoSelectionIfCannotMove*/);
|
|
287
288
|
}
|
|
288
289
|
}
|
|
@@ -431,9 +432,10 @@ void ComponentView::GotFocus(winrt::event_token const &token) noexcept {
|
|
|
431
432
|
m_gotFocusEvent.remove(token);
|
|
432
433
|
}
|
|
433
434
|
|
|
434
|
-
bool ComponentView::TryFocus() noexcept {
|
|
435
|
+
bool ComponentView::TryFocus(winrt::Microsoft::ReactNative::FocusState focusState) noexcept {
|
|
435
436
|
if (auto root = rootComponentView()) {
|
|
436
|
-
return root->TrySetFocusedComponent(
|
|
437
|
+
return root->TrySetFocusedComponent(
|
|
438
|
+
*get_strong(), winrt::Microsoft::ReactNative::FocusNavigationDirection::None, focusState);
|
|
437
439
|
}
|
|
438
440
|
|
|
439
441
|
return false;
|
|
@@ -201,7 +201,7 @@ struct ComponentView
|
|
|
201
201
|
|
|
202
202
|
LayoutMetrics LayoutMetrics() const noexcept;
|
|
203
203
|
|
|
204
|
-
bool TryFocus() noexcept;
|
|
204
|
+
bool TryFocus(winrt::Microsoft::ReactNative::FocusState focusState) noexcept;
|
|
205
205
|
|
|
206
206
|
virtual bool focusable() const noexcept;
|
|
207
207
|
virtual facebook::react::SharedViewEventEmitter eventEmitterAtPoint(facebook::react::Point pt) noexcept;
|
|
@@ -608,6 +608,8 @@ int64_t CompositionEventHandler::SendMessage(HWND hwnd, uint32_t msg, uint64_t w
|
|
|
608
608
|
|
|
609
609
|
void CompositionEventHandler::onKeyDown(
|
|
610
610
|
const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept {
|
|
611
|
+
RootComponentView().UseKeyboardForProgrammaticFocus(true);
|
|
612
|
+
|
|
611
613
|
if (auto focusedComponent = RootComponentView().GetFocusedComponent()) {
|
|
612
614
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(focusedComponent)->OnKeyDown(args);
|
|
613
615
|
|
|
@@ -631,7 +633,7 @@ void CompositionEventHandler::onKeyDown(
|
|
|
631
633
|
}
|
|
632
634
|
|
|
633
635
|
if (!fCtrl && args.Key() == winrt::Windows::System::VirtualKey::Tab) {
|
|
634
|
-
if (RootComponentView().TryMoveFocus(!fShift)) {
|
|
636
|
+
if (RootComponentView().TryMoveFocus(!fShift, winrt::Microsoft::ReactNative::FocusState::Keyboard)) {
|
|
635
637
|
args.Handled(true);
|
|
636
638
|
}
|
|
637
639
|
|
|
@@ -641,6 +643,8 @@ void CompositionEventHandler::onKeyDown(
|
|
|
641
643
|
|
|
642
644
|
void CompositionEventHandler::onKeyUp(
|
|
643
645
|
const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept {
|
|
646
|
+
RootComponentView().UseKeyboardForProgrammaticFocus(true);
|
|
647
|
+
|
|
644
648
|
if (auto focusedComponent = RootComponentView().GetFocusedComponent()) {
|
|
645
649
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(focusedComponent)->OnKeyUp(args);
|
|
646
650
|
|
|
@@ -1173,6 +1177,8 @@ void CompositionEventHandler::onPointerPressed(
|
|
|
1173
1177
|
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
|
|
1174
1178
|
namespace Composition = winrt::Microsoft::ReactNative::Composition;
|
|
1175
1179
|
|
|
1180
|
+
RootComponentView().UseKeyboardForProgrammaticFocus(false);
|
|
1181
|
+
|
|
1176
1182
|
// Clears any active text selection when left pointer is pressed
|
|
1177
1183
|
if (pointerPoint.Properties().PointerUpdateKind() != Composition::Input::PointerUpdateKind::RightButtonPressed) {
|
|
1178
1184
|
RootComponentView().ClearCurrentTextSelection();
|
|
@@ -1269,6 +1275,8 @@ void CompositionEventHandler::onPointerReleased(
|
|
|
1269
1275
|
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
|
|
1270
1276
|
int pointerId = pointerPoint.PointerId();
|
|
1271
1277
|
|
|
1278
|
+
RootComponentView().UseKeyboardForProgrammaticFocus(false);
|
|
1279
|
+
|
|
1272
1280
|
auto activeTouch = std::find_if(m_activeTouches.begin(), m_activeTouches.end(), [pointerId](const auto &pair) {
|
|
1273
1281
|
return pair.second.touch.identifier == pointerId;
|
|
1274
1282
|
});
|
|
@@ -373,7 +373,8 @@ void ComponentView::onGotFocus(
|
|
|
373
373
|
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
374
374
|
if (args.OriginalSource() == Tag()) {
|
|
375
375
|
m_eventEmitter->onFocus();
|
|
376
|
-
if (viewProps()->enableFocusRing
|
|
376
|
+
if (viewProps()->enableFocusRing &&
|
|
377
|
+
rootComponentView()->focusState() == winrt::Microsoft::ReactNative::FocusState::Keyboard) {
|
|
377
378
|
facebook::react::Rect focusRect = m_layoutMetrics.frame;
|
|
378
379
|
focusRect.origin.x -= (FOCUS_VISUAL_WIDTH * 2);
|
|
379
380
|
focusRect.origin.y -= (FOCUS_VISUAL_WIDTH * 2);
|
|
@@ -426,15 +427,20 @@ void ComponentView::HandleCommand(const winrt::Microsoft::ReactNative::HandleCom
|
|
|
426
427
|
auto commandName = args.CommandName();
|
|
427
428
|
if (commandName == L"focus") {
|
|
428
429
|
if (auto root = rootComponentView()) {
|
|
429
|
-
root->TrySetFocusedComponent(
|
|
430
|
+
root->TrySetFocusedComponent(
|
|
431
|
+
*get_strong(),
|
|
432
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
433
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
430
434
|
}
|
|
431
435
|
return;
|
|
432
436
|
}
|
|
433
437
|
if (commandName == L"blur") {
|
|
434
438
|
if (auto root = rootComponentView()) {
|
|
435
439
|
root->TrySetFocusedComponent(
|
|
436
|
-
nullptr,
|
|
437
|
-
|
|
440
|
+
nullptr,
|
|
441
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
442
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic); // Todo store this component as
|
|
443
|
+
// previously focused element
|
|
438
444
|
}
|
|
439
445
|
return;
|
|
440
446
|
}
|
|
@@ -82,7 +82,7 @@ void ContentIslandComponentView::ConnectInternal() noexcept {
|
|
|
82
82
|
m_navigationHost.DepartFocusRequested([wkThis = get_weak()](const auto &, const auto &args) {
|
|
83
83
|
if (auto strongThis = wkThis.get()) {
|
|
84
84
|
const bool next = (args.Request().Reason() != winrt::Microsoft::UI::Input::FocusNavigationReason::Last);
|
|
85
|
-
strongThis->rootComponentView()->TryMoveFocus(next);
|
|
85
|
+
strongThis->rootComponentView()->TryMoveFocus(next, winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
86
86
|
args.Result(winrt::Microsoft::UI::Input::FocusNavigationResult::Moved);
|
|
87
87
|
}
|
|
88
88
|
});
|
|
@@ -622,7 +622,10 @@ void ParagraphComponentView::OnPointerPressed(
|
|
|
622
622
|
|
|
623
623
|
// Focuses so we receive onLostFocus when clicking elsewhere
|
|
624
624
|
if (auto root = rootComponentView()) {
|
|
625
|
-
root->TrySetFocusedComponent(
|
|
625
|
+
root->TrySetFocusedComponent(
|
|
626
|
+
*get_strong(),
|
|
627
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
628
|
+
winrt::Microsoft::ReactNative::FocusState::Pointer);
|
|
626
629
|
}
|
|
627
630
|
|
|
628
631
|
args.Handled(true);
|
|
@@ -82,7 +82,8 @@ winrt::Microsoft::ReactNative::ComponentView RootComponentView::GetFocusedCompon
|
|
|
82
82
|
|
|
83
83
|
void RootComponentView::SetFocusedComponent(
|
|
84
84
|
const winrt::Microsoft::ReactNative::ComponentView &value,
|
|
85
|
-
winrt::Microsoft::ReactNative::FocusNavigationDirection direction
|
|
85
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
|
|
86
|
+
winrt::Microsoft::ReactNative::FocusState focusState) noexcept {
|
|
86
87
|
if (m_focusedComponent == value)
|
|
87
88
|
return;
|
|
88
89
|
|
|
@@ -97,11 +98,26 @@ void RootComponentView::SetFocusedComponent(
|
|
|
97
98
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->TrySetFocus();
|
|
98
99
|
}
|
|
99
100
|
m_focusedComponent = value;
|
|
101
|
+
if (focusState == winrt::Microsoft::ReactNative::FocusState::Programmatic) {
|
|
102
|
+
focusState =
|
|
103
|
+
(!m_useKeyboardForProgrammaticFocus || m_focusState == winrt::Microsoft::ReactNative::FocusState::Pointer)
|
|
104
|
+
? winrt::Microsoft::ReactNative::FocusState::Pointer
|
|
105
|
+
: winrt::Microsoft::ReactNative::FocusState::Keyboard;
|
|
106
|
+
}
|
|
107
|
+
m_focusState = focusState;
|
|
100
108
|
auto args = winrt::make<winrt::Microsoft::ReactNative::implementation::GotFocusEventArgs>(value, direction);
|
|
101
109
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(value)->onGotFocus(args);
|
|
102
110
|
}
|
|
103
111
|
}
|
|
104
112
|
|
|
113
|
+
winrt::Microsoft::ReactNative::FocusState RootComponentView::focusState() const noexcept {
|
|
114
|
+
return m_focusState;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
void RootComponentView::UseKeyboardForProgrammaticFocus(bool value) noexcept {
|
|
118
|
+
m_useKeyboardForProgrammaticFocus = value;
|
|
119
|
+
}
|
|
120
|
+
|
|
105
121
|
bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept {
|
|
106
122
|
if (request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::Restore) {
|
|
107
123
|
if (m_focusedComponent)
|
|
@@ -116,7 +132,8 @@ bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::Focus
|
|
|
116
132
|
view,
|
|
117
133
|
request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::First
|
|
118
134
|
? winrt::Microsoft::ReactNative::FocusNavigationDirection::First
|
|
119
|
-
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Last
|
|
135
|
+
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Last,
|
|
136
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
120
137
|
}
|
|
121
138
|
return view != nullptr;
|
|
122
139
|
}
|
|
@@ -124,6 +141,7 @@ bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::Focus
|
|
|
124
141
|
bool RootComponentView::TrySetFocusedComponent(
|
|
125
142
|
const winrt::Microsoft::ReactNative::ComponentView &view,
|
|
126
143
|
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
|
|
144
|
+
winrt::Microsoft::ReactNative::FocusState focusState,
|
|
127
145
|
bool forceNoSelectionIfCannotMove /*= false*/) noexcept {
|
|
128
146
|
auto target = view;
|
|
129
147
|
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(target);
|
|
@@ -157,15 +175,15 @@ bool RootComponentView::TrySetFocusedComponent(
|
|
|
157
175
|
|
|
158
176
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(losingFocusArgs.NewFocusedComponent())
|
|
159
177
|
->rootComponentView()
|
|
160
|
-
->SetFocusedComponent(gettingFocusArgs.NewFocusedComponent(), direction);
|
|
178
|
+
->SetFocusedComponent(gettingFocusArgs.NewFocusedComponent(), direction, focusState);
|
|
161
179
|
} else {
|
|
162
|
-
SetFocusedComponent(nullptr, direction);
|
|
180
|
+
SetFocusedComponent(nullptr, direction, focusState);
|
|
163
181
|
}
|
|
164
182
|
|
|
165
183
|
return true;
|
|
166
184
|
}
|
|
167
185
|
|
|
168
|
-
bool RootComponentView::TryMoveFocus(bool next) noexcept {
|
|
186
|
+
bool RootComponentView::TryMoveFocus(bool next, winrt::Microsoft::ReactNative::FocusState focusState) noexcept {
|
|
169
187
|
if (!m_focusedComponent) {
|
|
170
188
|
return NavigateFocus(winrt::Microsoft::ReactNative::FocusNavigationRequest(
|
|
171
189
|
next ? winrt::Microsoft::ReactNative::FocusNavigationReason::First
|
|
@@ -173,7 +191,8 @@ bool RootComponentView::TryMoveFocus(bool next) noexcept {
|
|
|
173
191
|
}
|
|
174
192
|
|
|
175
193
|
Mso::Functor<bool(const winrt::Microsoft::ReactNative::ComponentView &)> fn =
|
|
176
|
-
[currentlyFocused = m_focusedComponent, next](
|
|
194
|
+
[currentlyFocused = m_focusedComponent, next, focusState](
|
|
195
|
+
const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
|
|
177
196
|
if (view == currentlyFocused)
|
|
178
197
|
return false;
|
|
179
198
|
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view);
|
|
@@ -185,7 +204,8 @@ bool RootComponentView::TryMoveFocus(bool next) noexcept {
|
|
|
185
204
|
->TrySetFocusedComponent(
|
|
186
205
|
view,
|
|
187
206
|
next ? winrt::Microsoft::ReactNative::FocusNavigationDirection::Next
|
|
188
|
-
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous
|
|
207
|
+
: winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous,
|
|
208
|
+
focusState);
|
|
189
209
|
};
|
|
190
210
|
|
|
191
211
|
if (winrt::Microsoft::ReactNative::implementation::walkTree(m_focusedComponent, next, fn)) {
|
|
@@ -249,7 +269,10 @@ void RootComponentView::start(const winrt::Microsoft::ReactNative::ReactNativeIs
|
|
|
249
269
|
}
|
|
250
270
|
|
|
251
271
|
void RootComponentView::stop() noexcept {
|
|
252
|
-
SetFocusedComponent(
|
|
272
|
+
SetFocusedComponent(
|
|
273
|
+
nullptr,
|
|
274
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
275
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
253
276
|
if (m_visualAddedToIsland) {
|
|
254
277
|
if (auto rootView = m_wkRootView.get()) {
|
|
255
278
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)->RemoveRenderedVisual(
|
|
@@ -30,15 +30,17 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
|
|
|
30
30
|
winrt::Microsoft::ReactNative::ComponentView GetFocusedComponent() noexcept;
|
|
31
31
|
void SetFocusedComponent(
|
|
32
32
|
const winrt::Microsoft::ReactNative::ComponentView &value,
|
|
33
|
-
winrt::Microsoft::ReactNative::FocusNavigationDirection direction
|
|
33
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
|
|
34
|
+
winrt::Microsoft::ReactNative::FocusState focusState) noexcept;
|
|
34
35
|
bool TrySetFocusedComponent(
|
|
35
36
|
const winrt::Microsoft::ReactNative::ComponentView &view,
|
|
36
37
|
winrt::Microsoft::ReactNative::FocusNavigationDirection direction,
|
|
38
|
+
winrt::Microsoft::ReactNative::FocusState focusState,
|
|
37
39
|
bool forceNoSelectionIfCannotMove = false) noexcept;
|
|
38
40
|
|
|
39
41
|
bool NavigateFocus(const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept;
|
|
40
42
|
|
|
41
|
-
bool TryMoveFocus(bool next) noexcept;
|
|
43
|
+
bool TryMoveFocus(bool next, winrt::Microsoft::ReactNative::FocusState focusState) noexcept;
|
|
42
44
|
|
|
43
45
|
RootComponentView *rootComponentView() const noexcept override;
|
|
44
46
|
|
|
@@ -90,14 +92,20 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
|
|
|
90
92
|
void ClearCurrentTextSelection() noexcept;
|
|
91
93
|
void SetViewWithTextSelection(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
92
94
|
|
|
95
|
+
winrt::Microsoft::ReactNative::FocusState focusState() const noexcept;
|
|
96
|
+
|
|
97
|
+
void UseKeyboardForProgrammaticFocus(bool value) noexcept;
|
|
98
|
+
|
|
93
99
|
private:
|
|
94
100
|
// should this be a ReactTaggedView? - It shouldn't actually matter since if the view is going away it should always
|
|
95
101
|
// be clearing its focus But being a reactTaggedView might make it easier to identify cases where that isn't
|
|
96
102
|
// happening.
|
|
97
103
|
winrt::Microsoft::ReactNative::ComponentView m_focusedComponent{nullptr};
|
|
104
|
+
winrt::Microsoft::ReactNative::FocusState m_focusState{winrt::Microsoft::ReactNative::FocusState::Unfocused};
|
|
98
105
|
winrt::weak_ref<winrt::Microsoft::ReactNative::ReactNativeIsland> m_wkRootView{nullptr};
|
|
99
106
|
winrt::weak_ref<winrt::Microsoft::ReactNative::Composition::PortalComponentView> m_wkPortal{nullptr};
|
|
100
107
|
bool m_visualAddedToIsland{false};
|
|
108
|
+
bool m_useKeyboardForProgrammaticFocus{true};
|
|
101
109
|
|
|
102
110
|
::Microsoft::ReactNative::ReactTaggedView m_viewWithTextSelection{
|
|
103
111
|
winrt::Microsoft::ReactNative::ComponentView{nullptr}};
|
|
@@ -1023,16 +1023,16 @@ void ScrollViewComponentView::OnKeyDown(
|
|
|
1023
1023
|
args.Handled(pageUp(true));
|
|
1024
1024
|
break;
|
|
1025
1025
|
case winrt::Windows::System::VirtualKey::Up:
|
|
1026
|
-
args.Handled(lineUp(
|
|
1026
|
+
args.Handled(lineUp(false));
|
|
1027
1027
|
break;
|
|
1028
1028
|
case winrt::Windows::System::VirtualKey::Down:
|
|
1029
|
-
args.Handled(lineDown(
|
|
1029
|
+
args.Handled(lineDown(false));
|
|
1030
1030
|
break;
|
|
1031
1031
|
case winrt::Windows::System::VirtualKey::Left:
|
|
1032
|
-
args.Handled(lineLeft(
|
|
1032
|
+
args.Handled(lineLeft(false));
|
|
1033
1033
|
break;
|
|
1034
1034
|
case winrt::Windows::System::VirtualKey::Right:
|
|
1035
|
-
args.Handled(lineRight(
|
|
1035
|
+
args.Handled(lineRight(false));
|
|
1036
1036
|
break;
|
|
1037
1037
|
}
|
|
1038
1038
|
|
|
@@ -271,7 +271,10 @@ void SwitchComponentView::OnPointerPressed(
|
|
|
271
271
|
m_supressAnimationForNextFrame = true;
|
|
272
272
|
|
|
273
273
|
if (auto root = rootComponentView()) {
|
|
274
|
-
root->TrySetFocusedComponent(
|
|
274
|
+
root->TrySetFocusedComponent(
|
|
275
|
+
*get_strong(),
|
|
276
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
277
|
+
winrt::Microsoft::ReactNative::FocusState::Pointer);
|
|
275
278
|
}
|
|
276
279
|
|
|
277
280
|
updateVisuals();
|
package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp
CHANGED
|
@@ -233,7 +233,9 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
|
|
|
233
233
|
winrt::check_hresult(
|
|
234
234
|
m_outer->QueryInterface(winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(view)));
|
|
235
235
|
m_outer->rootComponentView()->TrySetFocusedComponent(
|
|
236
|
-
view,
|
|
236
|
+
view,
|
|
237
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
238
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
237
239
|
// assert(false);
|
|
238
240
|
// TODO focus
|
|
239
241
|
}
|
|
@@ -1469,7 +1471,10 @@ void WindowsTextInputComponentView::onMounted() noexcept {
|
|
|
1469
1471
|
// Handle autoFocus property - focus the component when mounted if autoFocus is true
|
|
1470
1472
|
if (windowsTextInputProps().autoFocus) {
|
|
1471
1473
|
if (auto root = rootComponentView()) {
|
|
1472
|
-
root->TrySetFocusedComponent(
|
|
1474
|
+
root->TrySetFocusedComponent(
|
|
1475
|
+
*get_strong(),
|
|
1476
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
1477
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic);
|
|
1473
1478
|
}
|
|
1474
1479
|
}
|
|
1475
1480
|
}
|
|
@@ -1775,7 +1780,10 @@ void WindowsTextInputComponentView::DrawText() noexcept {
|
|
|
1775
1780
|
}
|
|
1776
1781
|
|
|
1777
1782
|
// TODO keep track of proper invalid rect
|
|
1783
|
+
// Prevent reentrancy: TxDrawD2D may call TxViewChange -> DrawText
|
|
1784
|
+
m_cDrawBlock++;
|
|
1778
1785
|
auto hrDraw = m_textServices->TxDrawD2D(d2dDeviceContext, &rc, nullptr, TXTVIEW_ACTIVE);
|
|
1786
|
+
m_cDrawBlock--;
|
|
1779
1787
|
winrt::check_hresult(hrDraw);
|
|
1780
1788
|
|
|
1781
1789
|
// draw placeholder text if needed
|
|
@@ -141,7 +141,10 @@ HRESULT UiaSetFocusHelper(::Microsoft::ReactNative::ReactTaggedView &view) noexc
|
|
|
141
141
|
if (rootCV == nullptr)
|
|
142
142
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
143
143
|
|
|
144
|
-
return rootCV->TrySetFocusedComponent(
|
|
144
|
+
return rootCV->TrySetFocusedComponent(
|
|
145
|
+
strongView,
|
|
146
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None,
|
|
147
|
+
winrt::Microsoft::ReactNative::FocusState::Programmatic)
|
|
145
148
|
? S_OK
|
|
146
149
|
: E_FAIL;
|
|
147
150
|
}
|
|
@@ -426,9 +426,9 @@
|
|
|
426
426
|
</ProjectReference>
|
|
427
427
|
</ItemGroup>
|
|
428
428
|
<ItemGroup>
|
|
429
|
-
<PackageReference Include="boost" Version="1.
|
|
429
|
+
<PackageReference Include="boost" Version="1.84.0.0" />
|
|
430
430
|
<PackageReference Include="Microsoft.Windows.CppWinRT" Version="$(CppWinRTVersion)" PrivateAssets="all" />
|
|
431
|
-
<PackageReference Include="
|
|
431
|
+
<PackageReference Include="$(HermesPackageName)" Version="$(HermesVersion)" />
|
|
432
432
|
<PackageReference Include="$(WinUIPackageName)" Version="$(WinUIPackageVersion)" Condition="'$(OverrideWinUIPackage)'!='true'" />
|
|
433
433
|
<PackageReference Include="$(V8PackageName)" Version="$(V8Version)" Condition="'$(UseV8)' == 'true'" />
|
|
434
434
|
</ItemGroup>
|
|
@@ -266,6 +266,10 @@ class ReactNativeWindowsFeatureFlags : public facebook::react::ReactNativeFeatur
|
|
|
266
266
|
return true;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
bool enableImperativeFocus() override {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
|
|
269
273
|
bool fuseboxEnabledRelease() override {
|
|
270
274
|
return true; // Enable Fusebox (modern CDP backend) by default for React Native Windows
|
|
271
275
|
}
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppApp.targets" />
|
|
22
22
|
|
|
23
23
|
<ItemGroup>
|
|
24
|
-
<PackageReference Include="boost" Version="1.
|
|
24
|
+
<PackageReference Include="boost" Version="1.84.0.0" />
|
|
25
25
|
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.2-rc" />
|
|
26
26
|
</ItemGroup>
|
|
27
27
|
|
|
28
|
-
</Project>
|
|
28
|
+
</Project>
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Codegen.targets" />
|
|
24
24
|
|
|
25
25
|
<ItemGroup>
|
|
26
|
-
<PackageReference Include="boost" Version="1.
|
|
26
|
+
<PackageReference Include="boost" Version="1.84.0.0" />
|
|
27
27
|
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.2-rc" />
|
|
28
28
|
</ItemGroup>
|
|
29
29
|
|
|
30
|
-
</Project>
|
|
30
|
+
</Project>
|
|
@@ -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)" />
|
|
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)" />
|
|
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.83.0-preview.
|
|
13
|
+
<ReactNativeWindowsVersion>0.83.0-preview.3</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>83</ReactNativeWindowsMinor>
|
|
16
16
|
<ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
18
|
+
<ReactNativeWindowsCommitId>d23bf1e20c21916c5c28bf4d5c781aa58e3999f5</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-2512.22001-bc3d0ed7</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>
|
|
@@ -239,7 +239,7 @@
|
|
|
239
239
|
</ProjectReference>
|
|
240
240
|
</ItemGroup>
|
|
241
241
|
<ItemGroup>
|
|
242
|
-
<PackageReference Include="boost" Version="1.
|
|
242
|
+
<PackageReference Include="boost" Version="1.84.0.0" />
|
|
243
243
|
<PackageReference Include="Microsoft.Windows.CppWinRT" Version="$(CppWinRTVersion)" PrivateAssets="all" />
|
|
244
244
|
</ItemGroup>
|
|
245
245
|
<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
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* node vnext/Scripts/perf/compare-results.js [options]
|
|
11
11
|
*
|
|
12
12
|
* Options:
|
|
13
|
-
* --results <path> Path to CI results JSON (default: .perf-results/results.json)
|
|
13
|
+
* --results <path> Path to CI results JSON (repeatable, default: .perf-results/results.json)
|
|
14
14
|
* --baselines <dir> Path to base branch perf snapshots directory
|
|
15
15
|
* --output <path> Path to write markdown report (default: .perf-results/report.md)
|
|
16
16
|
* --fail-on-regression Exit 1 if regressions found (default: true in CI)
|
|
@@ -25,17 +25,29 @@ const path = require('path');
|
|
|
25
25
|
|
|
26
26
|
function parseArgs() {
|
|
27
27
|
const args = process.argv.slice(2);
|
|
28
|
+
|
|
29
|
+
// Auto-discover results files: JS perf + native perf
|
|
30
|
+
const defaultResults = [
|
|
31
|
+
'.perf-results/results.json',
|
|
32
|
+
'.native-perf-results/results.json',
|
|
33
|
+
].filter(p => fs.existsSync(p));
|
|
34
|
+
|
|
28
35
|
const opts = {
|
|
29
|
-
results:
|
|
36
|
+
results: defaultResults,
|
|
30
37
|
baselines: null, // auto-detect from test file paths
|
|
31
38
|
output: '.perf-results/report.md',
|
|
32
39
|
failOnRegression: !!process.env.CI,
|
|
33
40
|
};
|
|
34
41
|
|
|
42
|
+
let explicitResults = false;
|
|
35
43
|
for (let i = 0; i < args.length; i++) {
|
|
36
44
|
switch (args[i]) {
|
|
37
45
|
case '--results':
|
|
38
|
-
|
|
46
|
+
if (!explicitResults) {
|
|
47
|
+
opts.results = [];
|
|
48
|
+
explicitResults = true;
|
|
49
|
+
}
|
|
50
|
+
opts.results.push(args[++i]);
|
|
39
51
|
break;
|
|
40
52
|
case '--baselines':
|
|
41
53
|
opts.baselines = args[++i];
|
|
@@ -98,6 +110,7 @@ function compareEntry(head, base, threshold) {
|
|
|
98
110
|
: 0;
|
|
99
111
|
|
|
100
112
|
const errors = [];
|
|
113
|
+
const isTrackMode = threshold.mode === 'track';
|
|
101
114
|
|
|
102
115
|
const absoluteDelta = head.medianDuration - base.medianDuration;
|
|
103
116
|
const minAbsoluteDelta =
|
|
@@ -126,8 +139,9 @@ function compareEntry(head, base, threshold) {
|
|
|
126
139
|
head,
|
|
127
140
|
base,
|
|
128
141
|
percentChange,
|
|
129
|
-
passed: errors.length === 0,
|
|
142
|
+
passed: isTrackMode || errors.length === 0,
|
|
130
143
|
errors,
|
|
144
|
+
isTrackMode,
|
|
131
145
|
};
|
|
132
146
|
}
|
|
133
147
|
|
|
@@ -207,6 +221,24 @@ function generateMarkdown(suiteComparisons, ciResults) {
|
|
|
207
221
|
}
|
|
208
222
|
}
|
|
209
223
|
|
|
224
|
+
// Track-mode warnings (not blocking)
|
|
225
|
+
const trackedWarnings = suiteComparisons.flatMap(s =>
|
|
226
|
+
s.results.filter(r => r.isTrackMode && r.errors.length > 0),
|
|
227
|
+
);
|
|
228
|
+
if (trackedWarnings.length > 0) {
|
|
229
|
+
md += '### ⚠️ Tracked (not blocking)\n\n';
|
|
230
|
+
md += '| Scenario | Baseline | Current | Change |\n';
|
|
231
|
+
md += '|----------|----------|---------|--------|\n';
|
|
232
|
+
for (const r of trackedWarnings) {
|
|
233
|
+
const baseline = r.base ? `${r.base.meanDuration.toFixed(2)}ms` : 'N/A';
|
|
234
|
+
const current = r.head ? `${r.head.meanDuration.toFixed(2)}ms` : 'N/A';
|
|
235
|
+
const change =
|
|
236
|
+
r.percentChange != null ? `+${r.percentChange.toFixed(1)}%` : 'N/A';
|
|
237
|
+
md += `| ${r.name} | ${baseline} | ${current} | ${change} |\n`;
|
|
238
|
+
}
|
|
239
|
+
md += '\n';
|
|
240
|
+
}
|
|
241
|
+
|
|
210
242
|
// Passed suites
|
|
211
243
|
const passedSuites = suiteComparisons.filter(s => !s.hasRegressions);
|
|
212
244
|
if (passedSuites.length > 0) {
|
|
@@ -257,17 +289,41 @@ function generateMarkdown(suiteComparisons, ciResults) {
|
|
|
257
289
|
function main() {
|
|
258
290
|
const opts = parseArgs();
|
|
259
291
|
|
|
260
|
-
// 1. Load CI results JSON
|
|
261
|
-
|
|
262
|
-
|
|
292
|
+
// 1. Load CI results JSON (supports multiple --results paths)
|
|
293
|
+
const ciResults = {
|
|
294
|
+
suites: [],
|
|
295
|
+
branch: '',
|
|
296
|
+
commitSha: '',
|
|
297
|
+
timestamp: '',
|
|
298
|
+
summary: {
|
|
299
|
+
totalSuites: 0,
|
|
300
|
+
totalTests: 0,
|
|
301
|
+
passed: 0,
|
|
302
|
+
failed: 0,
|
|
303
|
+
durationMs: 0,
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
const resultsPaths = opts.results.filter(p => fs.existsSync(p));
|
|
307
|
+
if (resultsPaths.length === 0) {
|
|
308
|
+
console.error(`❌ No results files found: ${opts.results.join(', ')}`);
|
|
263
309
|
console.error('Run perf tests with CI=true first: CI=true yarn perf:ci');
|
|
264
310
|
process.exit(1);
|
|
265
311
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
312
|
+
for (const resultsPath of resultsPaths) {
|
|
313
|
+
const partial = JSON.parse(fs.readFileSync(resultsPath, 'utf-8'));
|
|
314
|
+
ciResults.suites.push(...(partial.suites || []));
|
|
315
|
+
ciResults.branch = ciResults.branch || partial.branch;
|
|
316
|
+
ciResults.commitSha = ciResults.commitSha || partial.commitSha;
|
|
317
|
+
ciResults.timestamp = ciResults.timestamp || partial.timestamp;
|
|
318
|
+
ciResults.summary.totalSuites += partial.summary?.totalSuites || 0;
|
|
319
|
+
ciResults.summary.totalTests += partial.summary?.totalTests || 0;
|
|
320
|
+
ciResults.summary.passed += partial.summary?.passed || 0;
|
|
321
|
+
ciResults.summary.failed += partial.summary?.failed || 0;
|
|
322
|
+
ciResults.summary.durationMs += partial.summary?.durationMs || 0;
|
|
323
|
+
console.log(
|
|
324
|
+
`📊 Loaded ${partial.suites.length} suite(s) from ${resultsPath}`,
|
|
325
|
+
);
|
|
326
|
+
}
|
|
271
327
|
|
|
272
328
|
// 2. Compare each suite against its committed baseline
|
|
273
329
|
const suiteComparisons = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-windows",
|
|
3
|
-
"version": "0.83.0-preview.
|
|
3
|
+
"version": "0.83.0-preview.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,16 +26,16 @@
|
|
|
26
26
|
"@react-native-community/cli": "20.0.0",
|
|
27
27
|
"@react-native-community/cli-platform-android": "20.0.0",
|
|
28
28
|
"@react-native-community/cli-platform-ios": "20.0.0",
|
|
29
|
-
"@react-native-windows/cli": "0.83.0-preview.
|
|
29
|
+
"@react-native-windows/cli": "0.83.0-preview.2",
|
|
30
30
|
"@react-native/assets": "1.0.0",
|
|
31
|
-
"@react-native/assets-registry": "0.83.
|
|
32
|
-
"@react-native/codegen": "0.83.
|
|
33
|
-
"@react-native/community-cli-plugin": "0.83.
|
|
34
|
-
"@react-native/gradle-plugin": "0.83.
|
|
35
|
-
"@react-native/js-polyfills": "0.83.
|
|
36
|
-
"@react-native/new-app-screen": "0.83.
|
|
37
|
-
"@react-native/normalize-colors": "0.83.
|
|
38
|
-
"@react-native/virtualized-lists": "0.83.
|
|
31
|
+
"@react-native/assets-registry": "0.83.4",
|
|
32
|
+
"@react-native/codegen": "0.83.4",
|
|
33
|
+
"@react-native/community-cli-plugin": "0.83.4",
|
|
34
|
+
"@react-native/gradle-plugin": "0.83.4",
|
|
35
|
+
"@react-native/js-polyfills": "0.83.4",
|
|
36
|
+
"@react-native/new-app-screen": "0.83.4",
|
|
37
|
+
"@react-native/normalize-colors": "0.83.4",
|
|
38
|
+
"@react-native/virtualized-lists": "0.83.4",
|
|
39
39
|
"abort-controller": "^3.0.0",
|
|
40
40
|
"anser": "^1.4.9",
|
|
41
41
|
"ansi-regex": "^5.0.0",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"event-target-shim": "^5.0.1",
|
|
48
48
|
"flow-enums-runtime": "^0.0.6",
|
|
49
49
|
"glob": "^7.1.1",
|
|
50
|
-
"hermes-compiler": "0.14.
|
|
50
|
+
"hermes-compiler": "0.14.1",
|
|
51
51
|
"invariant": "^2.2.4",
|
|
52
52
|
"jest-environment-node": "^29.7.0",
|
|
53
53
|
"memoize-one": "^5.0.0",
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
"yargs": "^17.6.2"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@react-native-windows/codegen": "0.83.0-preview.
|
|
73
|
-
"@react-native/metro-config": "0.83.
|
|
72
|
+
"@react-native-windows/codegen": "0.83.0-preview.2",
|
|
73
|
+
"@react-native/metro-config": "0.83.4",
|
|
74
74
|
"@rnw-scripts/babel-react-native-config": "0.0.0",
|
|
75
75
|
"@rnw-scripts/eslint-config": "1.2.38",
|
|
76
76
|
"@rnw-scripts/jest-out-of-tree-snapshot-resolver": "^1.1.42",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"just-scripts": "^1.3.3",
|
|
86
86
|
"prettier": "2.8.8",
|
|
87
87
|
"react": "19.2.0",
|
|
88
|
-
"react-native": "0.83.
|
|
88
|
+
"react-native": "0.83.4",
|
|
89
89
|
"react-native-platform-override": "0.83.0-preview.1",
|
|
90
90
|
"react-refresh": "^0.14.0",
|
|
91
91
|
"typescript": "5.0.4"
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"peerDependencies": {
|
|
94
94
|
"@types/react": "^19.1.1",
|
|
95
95
|
"react": "^19.2.0",
|
|
96
|
-
"react-native": "0.83.0
|
|
96
|
+
"react-native": "^0.83.0"
|
|
97
97
|
},
|
|
98
98
|
"beachball": {
|
|
99
99
|
"defaultNpmTag": "preview",
|