react-native-windows 0.0.0-canary.618 → 0.0.0-canary.620

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.
@@ -12,6 +12,7 @@
12
12
  #include <winrt/Windows.UI.Composition.h>
13
13
  #include "CompositionContextHelper.h"
14
14
  #include "CompositionHelpers.h"
15
+ #include "RootComponentView.h"
15
16
  #include "d2d1helper.h"
16
17
 
17
18
  namespace Microsoft::ReactNative {
@@ -38,6 +39,13 @@ const std::vector<IComponentView *> &CompositionBaseComponentView::children() co
38
39
  }
39
40
 
40
41
  void CompositionBaseComponentView::parent(IComponentView *parent) noexcept {
42
+ if (!parent) {
43
+ auto root = rootComponentView();
44
+ if (root->GetFocusedComponent() == this) {
45
+ root->SetFocusedComponent(nullptr); // TODO need move focus logic - where should focus go?
46
+ }
47
+ }
48
+
41
49
  m_parent = parent;
42
50
  }
43
51
 
@@ -60,9 +68,13 @@ bool CompositionBaseComponentView::runOnChildren(bool forward, Mso::Functor<bool
60
68
  return false;
61
69
  }
62
70
 
63
- void CompositionBaseComponentView::onFocusLost() noexcept {}
71
+ void CompositionBaseComponentView::onFocusLost() noexcept {
72
+ m_eventEmitter->onBlur();
73
+ }
64
74
 
65
- void CompositionBaseComponentView::onFocusGained() noexcept {}
75
+ void CompositionBaseComponentView::onFocusGained() noexcept {
76
+ m_eventEmitter->onFocus();
77
+ }
66
78
 
67
79
  void CompositionBaseComponentView::updateEventEmitter(
68
80
  facebook::react::EventEmitter::Shared const &eventEmitter) noexcept {
@@ -971,9 +983,8 @@ void CompositionBaseComponentView::updateBorderLayoutMetrics(
971
983
  Visual().as<Composition::IVisualInterop>()->SetClippingPath(pathGeometry.get());
972
984
  }
973
985
 
974
- if (m_needsBorderUpdate || m_layoutMetrics != layoutMetrics) {
975
- m_needsBorderUpdate = false;
976
- UpdateSpecialBorderLayers(layoutMetrics, viewProps);
986
+ if (m_layoutMetrics != layoutMetrics) {
987
+ m_needsBorderUpdate = true;
977
988
  }
978
989
  }
979
990
 
@@ -1219,7 +1230,12 @@ void CompositionViewComponentView::updateLayoutMetrics(
1219
1230
  });
1220
1231
  }
1221
1232
 
1222
- void CompositionViewComponentView::finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept {}
1233
+ void CompositionViewComponentView::finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept {
1234
+ if (m_needsBorderUpdate) {
1235
+ m_needsBorderUpdate = false;
1236
+ UpdateSpecialBorderLayers(m_layoutMetrics, *m_props);
1237
+ }
1238
+ }
1223
1239
 
1224
1240
  void CompositionViewComponentView::prepareForRecycle() noexcept {}
1225
1241
  facebook::react::Props::Shared CompositionViewComponentView::props() noexcept {
@@ -558,14 +558,6 @@ WindowsTextInputComponentView::supplementalComponentDescriptorProviders() noexce
558
558
  return {};
559
559
  }
560
560
 
561
- void WindowsTextInputComponentView::parent(IComponentView *parent) noexcept {
562
- if (!parent && rootComponentView()->GetFocusedComponent() == this) {
563
- rootComponentView()->SetFocusedComponent(nullptr); // TODO need move focus logic - where should focus go?
564
- }
565
-
566
- Super::parent(parent);
567
- }
568
-
569
561
  void WindowsTextInputComponentView::mountChildComponentView(
570
562
  IComponentView &childComponentView,
571
563
  uint32_t index) noexcept {
@@ -46,7 +46,6 @@ struct WindowsTextInputComponentView : CompositionBaseComponentView {
46
46
  void handleCommand(std::string const &commandName, folly::dynamic const &arg) noexcept override;
47
47
  int64_t sendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept override;
48
48
  facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override;
49
- void parent(IComponentView *parent) noexcept override;
50
49
  void OnRenderingDeviceLost() noexcept override;
51
50
  winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override;
52
51
  void onFocusLost() noexcept override;
@@ -5,6 +5,8 @@
5
5
  #include "ImageUtils.h"
6
6
 
7
7
  #include <Shared/cdebug.h>
8
+ #include <Utils/CppWinrtLessExceptions.h>
9
+ #include <windows.Web.Http.h>
8
10
  #include <winrt/Windows.Security.Cryptography.h>
9
11
  #include <winrt/Windows.Web.Http.Headers.h>
10
12
  #include <winrt/Windows.Web.Http.h>
@@ -24,7 +26,10 @@ winrt::IAsyncOperation<winrt::IRandomAccessStream> GetImageStreamAsync(ReactImag
24
26
  auto httpMethod{
25
27
  source.method.empty() ? winrt::HttpMethod::Get() : winrt::HttpMethod{winrt::to_hstring(source.method)}};
26
28
 
27
- winrt::Uri uri{winrt::to_hstring(source.uri)};
29
+ winrt::Uri uri = UriTryCreate(winrt::to_hstring(source.uri));
30
+ if (!uri) {
31
+ co_return nullptr;
32
+ }
28
33
  winrt::HttpRequestMessage request{httpMethod, uri};
29
34
 
30
35
  if (!source.headers.empty()) {
@@ -39,14 +44,56 @@ winrt::IAsyncOperation<winrt::IRandomAccessStream> GetImageStreamAsync(ReactImag
39
44
  }
40
45
 
41
46
  winrt::HttpClient httpClient;
42
- winrt::HttpResponseMessage response{co_await httpClient.SendRequestAsync(request)};
47
+ auto httpClientAbi = reinterpret_cast<ABI::Windows::Web::Http::IHttpClient *>(winrt::get_abi(httpClient));
48
+
49
+ winrt::Windows::Foundation::IAsyncOperationWithProgress<
50
+ winrt::Windows::Web::Http::HttpResponseMessage,
51
+ winrt::Windows::Web::Http::HttpProgress>
52
+ asyncRequest{nullptr};
53
+
54
+ if (FAILED(httpClientAbi->SendRequestAsync(
55
+ reinterpret_cast<ABI::Windows::Web::Http::IHttpRequestMessage *>(winrt::get_abi(request)),
56
+ reinterpret_cast<
57
+ ABI::Windows::Foundation::
58
+ __FIAsyncOperationWithProgress_2_Windows__CWeb__CHttp__CHttpResponseMessage_Windows__CWeb__CHttp__CHttpProgress_t
59
+ **>(winrt::put_abi(asyncRequest))))) {
60
+ co_return nullptr;
61
+ }
62
+
63
+ if (!asyncRequest) {
64
+ co_return nullptr;
65
+ }
66
+
67
+ co_await lessthrow_await_adapter<winrt::Windows::Foundation::IAsyncOperationWithProgress<
68
+ winrt::Windows::Web::Http::HttpResponseMessage,
69
+ winrt::Windows::Web::Http::HttpProgress>>{asyncRequest};
70
+
71
+ if (FAILED(asyncRequest.ErrorCode())) {
72
+ co_return nullptr;
73
+ }
74
+
75
+ winrt::HttpResponseMessage response{asyncRequest.GetResults()};
43
76
 
44
77
  if (response && response.StatusCode() == winrt::HttpStatusCode::Ok) {
45
- winrt::IInputStream inputStream{co_await response.Content().ReadAsInputStreamAsync()};
78
+ auto asyncRead = response.Content().ReadAsInputStreamAsync();
79
+ co_await lessthrow_await_adapter<winrt::Windows::Foundation::IAsyncOperationWithProgress<
80
+ winrt::Windows::Storage::Streams::IInputStream,
81
+ uint64_t>>{asyncRead};
82
+ if (FAILED(asyncRead.ErrorCode())) {
83
+ co_return nullptr;
84
+ }
85
+
86
+ winrt::IInputStream inputStream{asyncRead.GetResults()};
46
87
  winrt::InMemoryRandomAccessStream memoryStream;
47
- co_await winrt::RandomAccessStream::CopyAsync(inputStream, memoryStream);
48
- memoryStream.Seek(0);
49
88
 
89
+ auto asyncCopy = winrt::RandomAccessStream::CopyAsync(inputStream, memoryStream);
90
+ co_await lessthrow_await_adapter<winrt::Windows::Foundation::IAsyncOperationWithProgress<uint64_t, uint64_t>>{
91
+ asyncCopy};
92
+ if (FAILED(asyncCopy.ErrorCode())) {
93
+ co_return nullptr;
94
+ }
95
+
96
+ memoryStream.Seek(0);
50
97
  co_return memoryStream;
51
98
  }
52
99
  } catch (winrt::hresult_error const &e) {
@@ -91,4 +138,20 @@ winrt::IAsyncOperation<winrt::IRandomAccessStream> GetImageMemoryStreamAsync(Rea
91
138
  }
92
139
  }
93
140
 
94
- } // namespace Microsoft::ReactNative
141
+ // C# provides System.Uri.TryCreate, but no native equivalent seems to exist
142
+ winrt::Uri UriTryCreate(winrt::param::hstring const &uri) {
143
+ auto factory = winrt::
144
+ get_activation_factory<winrt::Windows::Foundation::Uri, winrt::Windows::Foundation::IUriRuntimeClassFactory>();
145
+ auto abiFactory = static_cast<ABI::Windows::Foundation::IUriRuntimeClassFactory *>(winrt::get_abi(factory));
146
+
147
+ const winrt::hstring &localUri = uri;
148
+ winrt::Windows::Foundation::Uri returnValue{nullptr};
149
+ if (FAILED(abiFactory->CreateUri(
150
+ static_cast<HSTRING>(winrt::get_abi(localUri)),
151
+ reinterpret_cast<ABI::Windows::Foundation::IUriRuntimeClass **>(winrt::put_abi(returnValue))))) {
152
+ return winrt::Windows::Foundation::Uri{nullptr};
153
+ }
154
+ return returnValue;
155
+ }
156
+
157
+ } // namespace Microsoft::ReactNative
@@ -32,4 +32,6 @@ winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IR
32
32
  winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IRandomAccessStream>
33
33
  GetImageInlineDataAsync(ReactImageSource source);
34
34
 
35
- } // namespace Microsoft::ReactNative
35
+ winrt::Windows::Foundation::Uri UriTryCreate(winrt::param::hstring const &uri);
36
+
37
+ } // namespace Microsoft::ReactNative
@@ -7,6 +7,7 @@
7
7
  #include <UI.Xaml.Markup.h>
8
8
  #include <UI.Xaml.Media.h>
9
9
  #include <Utils/ValueUtils.h>
10
+ #include <windows.foundation.h>
10
11
  #include <winrt/Windows.UI.ViewManagement.h>
11
12
  #include "Unicode.h"
12
13
  #include "XamlUtils.h"
@@ -313,15 +314,6 @@ REACTWINDOWS_API_(winrt::TimeSpan) TimeSpanFromMs(double ms) {
313
314
  return dur;
314
315
  }
315
316
 
316
- // C# provides System.Uri.TryCreate, but no native equivalent seems to exist
317
- winrt::Uri UriTryCreate(winrt::param::hstring const &uri) {
318
- try {
319
- return winrt::Uri(uri);
320
- } catch (...) {
321
- return winrt::Uri(nullptr);
322
- }
323
- }
324
-
325
317
  bool IsValidOptionalColorValue(const winrt::Microsoft::ReactNative::JSValue &v) {
326
318
  return v.Type() == winrt::Microsoft::ReactNative::JSValueType::Null || IsValidColorValue(v);
327
319
  }
@@ -56,8 +56,6 @@ IsValidColorValue(const winrt::Microsoft::ReactNative::JSValue &v);
56
56
  REACTWINDOWS_API_(winrt::Windows::Foundation::TimeSpan)
57
57
  TimeSpanFromMs(double ms);
58
58
 
59
- winrt::Uri UriTryCreate(winrt::param::hstring const &uri);
60
-
61
59
  winrt::Windows::UI::Color ColorFromNumber(DWORD argb) noexcept;
62
60
 
63
61
  bool IsValidOptionalColorValue(const winrt::Microsoft::ReactNative::JSValue &v);
@@ -12,7 +12,6 @@
12
12
  #include <winrt/Windows.Web.Http.Headers.h>
13
13
  #include <winrt/Windows.Web.Http.h>
14
14
 
15
- #include <Utils/ValueUtils.h>
16
15
  #include <Views/DynamicAutomationPeer.h>
17
16
  #include "Unicode.h"
18
17
  #include "XamlView.h"
@@ -376,6 +376,7 @@ void ViewViewManager::GetNativeProps(const winrt::Microsoft::ReactNative::IJSVal
376
376
  winrt::Microsoft::ReactNative::WriteProperty(writer, L"focusable", L"boolean");
377
377
  winrt::Microsoft::ReactNative::WriteProperty(writer, L"enableFocusRing", L"boolean");
378
378
  winrt::Microsoft::ReactNative::WriteProperty(writer, L"tabIndex", L"number");
379
+ winrt::Microsoft::ReactNative::WriteProperty(writer, L"collapsable", L"boolean");
379
380
  }
380
381
 
381
382
  bool ViewViewManager::UpdateProperty(
@@ -10,7 +10,7 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.0.0-canary.618</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.0.0-canary.620</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>0</ReactNativeWindowsMinor>
16
16
  <ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
@@ -0,0 +1,127 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include "ViewEventEmitter.h"
9
+
10
+ namespace facebook::react {
11
+
12
+ #pragma mark - Accessibility
13
+
14
+ void ViewEventEmitter::onAccessibilityAction(std::string const &name) const {
15
+ dispatchEvent("accessibilityAction", [name](jsi::Runtime &runtime) {
16
+ auto payload = jsi::Object(runtime);
17
+ payload.setProperty(runtime, "actionName", name);
18
+ return payload;
19
+ });
20
+ }
21
+
22
+ void ViewEventEmitter::onAccessibilityTap() const {
23
+ dispatchEvent("accessibilityTap");
24
+ }
25
+
26
+ void ViewEventEmitter::onAccessibilityMagicTap() const {
27
+ dispatchEvent("magicTap");
28
+ }
29
+
30
+ void ViewEventEmitter::onAccessibilityEscape() const {
31
+ dispatchEvent("accessibilityEscape");
32
+ }
33
+
34
+ #pragma mark - Layout
35
+
36
+ void ViewEventEmitter::onLayout(const LayoutMetrics &layoutMetrics) const {
37
+ // A copy of a shared pointer (`layoutEventState_`) establishes shared
38
+ // ownership that will be captured by lambda.
39
+ auto layoutEventState = layoutEventState_;
40
+
41
+ // Dispatched `frame` values to JavaScript thread are throttled here.
42
+ // Basic ideas:
43
+ // - Scheduling a lambda with some value that already was dispatched, does
44
+ // nothing.
45
+ // - If some lambda is already in flight, we don't schedule another;
46
+ // - When a lambda is being executed on the JavaScript thread, the *most
47
+ // recent* `frame` value is used (not the value that was current at the
48
+ // moment of scheduling the lambda).
49
+ //
50
+ // This implies the following caveats:
51
+ // - Some events can be skipped;
52
+ // - When values change rapidly, even events with different values
53
+ // can be skipped (only the very last will be delivered).
54
+ // - Ordering is preserved.
55
+
56
+ {
57
+ std::lock_guard<std::mutex> guard(layoutEventState->mutex);
58
+
59
+ // If a *particular* `frame` was already dispatched to the JavaScript side,
60
+ // no other work is required.
61
+ if (layoutEventState->frame == layoutMetrics.frame &&
62
+ layoutEventState->wasDispatched) {
63
+ return;
64
+ }
65
+
66
+ // If the *particular* `frame` was not already dispatched *or*
67
+ // some *other* `frame` was dispatched before,
68
+ // we need to schedule the dispatching.
69
+ layoutEventState->wasDispatched = false;
70
+ layoutEventState->frame = layoutMetrics.frame;
71
+
72
+ // Something is already in flight, dispatching another event is not
73
+ // required.
74
+ if (layoutEventState->isDispatching) {
75
+ return;
76
+ }
77
+
78
+ layoutEventState->isDispatching = true;
79
+ }
80
+
81
+ dispatchEvent(
82
+ "layout",
83
+ [layoutEventState](jsi::Runtime &runtime) {
84
+ auto frame = Rect{};
85
+
86
+ {
87
+ std::lock_guard<std::mutex> guard(layoutEventState->mutex);
88
+
89
+ layoutEventState->isDispatching = false;
90
+
91
+ // If some *particular* `frame` was already dispatched before,
92
+ // and since then there were no other new values of the `frame`
93
+ // observed, do nothing.
94
+ if (layoutEventState->wasDispatched) {
95
+ return jsi::Value::null();
96
+ }
97
+
98
+ frame = layoutEventState->frame;
99
+
100
+ // If some *particular* `frame` was *not* already dispatched before,
101
+ // it's time to dispatch it and mark as dispatched.
102
+ layoutEventState->wasDispatched = true;
103
+ }
104
+
105
+ auto layout = jsi::Object(runtime);
106
+ layout.setProperty(runtime, "x", frame.origin.x);
107
+ layout.setProperty(runtime, "y", frame.origin.y);
108
+ layout.setProperty(runtime, "width", frame.size.width);
109
+ layout.setProperty(runtime, "height", frame.size.height);
110
+ auto payload = jsi::Object(runtime);
111
+ payload.setProperty(runtime, "layout", std::move(layout));
112
+ return jsi::Value(std::move(payload));
113
+ },
114
+ EventPriority::AsynchronousUnbatched);
115
+ }
116
+
117
+ // [Windows]
118
+ void ViewEventEmitter::onFocus() const {
119
+ dispatchEvent("focus");
120
+ }
121
+
122
+ // [Windows]
123
+ void ViewEventEmitter::onBlur() const {
124
+ dispatchEvent("blur");
125
+ }
126
+
127
+ } // namespace facebook::react
@@ -0,0 +1,82 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include <memory>
11
+ #include <mutex>
12
+
13
+ #include <react/renderer/core/LayoutMetrics.h>
14
+ #include <react/renderer/core/ReactPrimitives.h>
15
+
16
+ #include "TouchEventEmitter.h"
17
+
18
+ namespace facebook {
19
+ namespace react {
20
+
21
+ struct FocusEvent {
22
+ int target;
23
+ };
24
+
25
+ class ViewEventEmitter;
26
+
27
+ using SharedViewEventEmitter = std::shared_ptr<const ViewEventEmitter>;
28
+
29
+ class ViewEventEmitter : public TouchEventEmitter {
30
+ public:
31
+ using TouchEventEmitter::TouchEventEmitter;
32
+
33
+ #pragma mark - Accessibility
34
+
35
+ void onAccessibilityAction(std::string const &name) const;
36
+ void onAccessibilityTap() const;
37
+ void onAccessibilityMagicTap() const;
38
+ void onAccessibilityEscape() const;
39
+
40
+ #pragma mark - Layout
41
+
42
+ void onLayout(const LayoutMetrics &layoutMetrics) const;
43
+
44
+ #pragma mark - NativeHostPlatform
45
+
46
+ void onFocus() const; // [Windows]
47
+ void onBlur() const; // [Windows]
48
+
49
+ private:
50
+ /*
51
+ * Contains the most recent `frame` and a `mutex` protecting access to it.
52
+ */
53
+ struct LayoutEventState {
54
+ /*
55
+ * Protects an access to other fields of the struct.
56
+ */
57
+ std::mutex mutex;
58
+
59
+ /*
60
+ * Last dispatched `frame` value or value that's being dispatched right now.
61
+ */
62
+ Rect frame{};
63
+
64
+ /*
65
+ * Indicates that the `frame` value was already dispatched (and dispatching
66
+ * of the *same* value is not needed).
67
+ */
68
+ bool wasDispatched{false};
69
+
70
+ /*
71
+ * Indicates that some lambda is already being dispatching (and dispatching
72
+ * another one is not needed).
73
+ */
74
+ bool isDispatching{false};
75
+ };
76
+
77
+ mutable std::shared_ptr<LayoutEventState> layoutEventState_{
78
+ std::make_shared<LayoutEventState>()};
79
+ };
80
+
81
+ } // namespace react
82
+ } // namespace facebook
@@ -283,6 +283,19 @@ ViewProps::ViewProps(
283
283
  return; \
284
284
  }
285
285
 
286
+ // [Windows]
287
+ #define HOST_PLATFORM_VIEW_EVENT_CASE(eventType) \
288
+ case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \
289
+ const auto offset = HostPlatformViewEvents::Offset::eventType; \
290
+ HostPlatformViewEvents defaultViewEvents{}; \
291
+ bool res = defaultViewEvents[offset]; \
292
+ if (value.hasValue()) { \
293
+ fromRawValue(context, value, res); \
294
+ } \
295
+ platformEvents[offset] = res; \
296
+ return; \
297
+ }
298
+
286
299
  void ViewProps::setProp(
287
300
  const PropsParserContext &context,
288
301
  RawPropsPropNameHash hash,
@@ -339,6 +352,8 @@ void ViewProps::setProp(
339
352
  VIEW_EVENT_CASE(TouchCancel);
340
353
  VIEW_EVENT_CASE(MouseEnter); // [Windows]
341
354
  VIEW_EVENT_CASE(MouseLeave); // [Windows]
355
+ HOST_PLATFORM_VIEW_EVENT_CASE(Focus); // [Windows]
356
+ HOST_PLATFORM_VIEW_EVENT_CASE(Blur); // [Windows]
342
357
 
343
358
  #ifdef ANDROID
344
359
  RAW_SET_PROP_SWITCH_CASE_BASIC(elevation, {});
@@ -77,6 +77,8 @@ class ViewProps : public YogaStylableProps, public AccessibilityProps {
77
77
 
78
78
  ViewEvents events{};
79
79
 
80
+ HostPlatformViewEvents platformEvents{}; // [Windows]
81
+
80
82
  bool collapsable{true};
81
83
 
82
84
  bool removeClippedSubviews{false};
@@ -56,6 +56,8 @@ void ViewShadowNode::initialize() noexcept {
56
56
  viewProps.importantForAccessibility != ImportantForAccessibility::Auto ||
57
57
  viewProps.removeClippedSubviews;
58
58
 
59
+ formsStackingContext = formsStackingContext || viewProps.platformEvents.bits.any(); // [Windows]
60
+
59
61
  #ifdef ANDROID
60
62
  formsStackingContext = formsStackingContext || viewProps.elevation != 0;
61
63
  #endif
@@ -82,6 +82,33 @@ inline static bool operator!=(ViewEvents const &lhs, ViewEvents const &rhs) {
82
82
  return lhs.bits != rhs.bits;
83
83
  }
84
84
 
85
+ // [Windows]
86
+ struct HostPlatformViewEvents {
87
+ std::bitset<32> bits{};
88
+
89
+ enum class Offset : std::size_t {
90
+ Focus = 0,
91
+ Blur = 1,
92
+ };
93
+
94
+ constexpr bool operator[](const Offset offset) const {
95
+ return bits[static_cast<std::size_t>(offset)];
96
+ }
97
+
98
+ std::bitset<32>::reference operator[](const Offset offset) {
99
+ return bits[static_cast<std::size_t>(offset)];
100
+ }
101
+ };
102
+
103
+
104
+ inline static bool operator==(HostPlatformViewEvents const &lhs, HostPlatformViewEvents const &rhs) {
105
+ return lhs.bits == rhs.bits;
106
+ }
107
+
108
+ inline static bool operator!=(HostPlatformViewEvents const &lhs, HostPlatformViewEvents const &rhs) {
109
+ return lhs.bits != rhs.bits;
110
+ }
111
+
85
112
  enum class BackfaceVisibility : uint8_t { Auto, Visible, Hidden };
86
113
 
87
114
  enum class BorderCurve : uint8_t { Circular, Continuous };
@@ -11,6 +11,8 @@
11
11
  #include <dispatchQueue/dispatchQueue.h>
12
12
 
13
13
  // Windows API
14
+ #include <windows.Networking.Sockets.h>
15
+ #include <windows.Storage.Streams.h>
14
16
  #include <winrt/Windows.Foundation.Collections.h>
15
17
  #include <winrt/Windows.Security.Cryptography.h>
16
18
 
@@ -203,7 +205,7 @@ fire_and_forget WinRTWebSocketResource::PerformWrite(string &&message, bool isBi
203
205
  }
204
206
 
205
207
  try {
206
- size_t length;
208
+ size_t length = 0;
207
209
  string messageLocal;
208
210
  bool isBinaryLocal;
209
211
  {
@@ -216,8 +218,10 @@ fire_and_forget WinRTWebSocketResource::PerformWrite(string &&message, bool isBi
216
218
  self->m_socket.Control().MessageType(SocketMessageType::Binary);
217
219
 
218
220
  auto buffer = CryptographicBuffer::DecodeFromBase64String(winrt::to_hstring(messageLocal));
219
- length = buffer.Length();
220
- self->m_writer.WriteBuffer(buffer);
221
+ if (buffer) {
222
+ length = buffer.Length();
223
+ self->m_writer.WriteBuffer(buffer);
224
+ }
221
225
  } else {
222
226
  self->m_socket.Control().MessageType(SocketMessageType::Utf8);
223
227
 
@@ -292,49 +296,59 @@ void WinRTWebSocketResource::Synchronize() noexcept {
292
296
  #pragma region IWebSocketResource
293
297
 
294
298
  void WinRTWebSocketResource::Connect(string &&url, const Protocols &protocols, const Options &options) noexcept {
295
- m_socket.MessageReceived(
296
- [self = shared_from_this()](IWebSocket const &sender, IMessageWebSocketMessageReceivedEventArgs const &args) {
297
- try {
298
- string response;
299
- IDataReader reader = args.GetDataReader();
300
- auto len = reader.UnconsumedBufferLength();
301
- if (args.MessageType() == SocketMessageType::Utf8) {
302
- reader.UnicodeEncoding(UnicodeEncoding::Utf8);
303
- vector<uint8_t> data(len);
304
- reader.ReadBytes(data);
305
-
306
- response = string(CheckedReinterpretCast<char *>(data.data()), data.size());
307
- } else {
308
- auto buffer = reader.ReadBuffer(len);
309
- winrt::hstring data = CryptographicBuffer::EncodeToBase64String(buffer);
310
-
311
- response = winrt::to_string(std::wstring_view(data));
312
- }
313
-
314
- if (self->m_readHandler) {
315
- self->m_readHandler(response.length(), response, args.MessageType() == SocketMessageType::Binary);
316
- }
317
- } catch (hresult_error const &e) {
318
- if (self->m_errorHandler) {
319
- string errorMessage;
320
- ErrorType errorType;
321
- // See
322
- // https://docs.microsoft.com/uwp/api/windows.networking.sockets.messagewebsocketmessagereceivedeventargs.getdatareader?view=winrt-19041#remarks
323
- if (e.code() == WININET_E_CONNECTION_ABORTED) {
324
- errorMessage = "[0x80072EFE] Underlying TCP connection suddenly terminated";
325
- errorType = ErrorType::Connection;
326
- self->m_errorHandler({errorMessage, errorType});
327
-
328
- // Note: We are not clear whether all read-related errors should close the socket.
329
- self->Close(CloseCode::BadPayload, std::move(errorMessage));
330
- } else {
331
- errorMessage = Utilities::HResultToString(e);
332
- errorType = ErrorType::Receive;
333
- self->m_errorHandler({errorMessage, errorType});
334
- }
335
- }
299
+ m_socket.MessageReceived([self = shared_from_this()](
300
+ IWebSocket const &sender, IMessageWebSocketMessageReceivedEventArgs const &args) {
301
+ try {
302
+ string response;
303
+
304
+ IDataReader reader{nullptr};
305
+ // Use ABI version to avoid throwing exceptions on expected code paths
306
+ HRESULT hr =
307
+ reinterpret_cast<ABI::Windows::Networking::Sockets::IMessageWebSocketMessageReceivedEventArgs *>(
308
+ winrt::get_abi(args))
309
+ ->GetDataReader(reinterpret_cast<ABI::Windows::Storage::Streams::IDataReader **>(winrt::put_abi(reader)));
310
+
311
+ if (FAILED(hr)) {
312
+ // See
313
+ // https://docs.microsoft.com/uwp/api/windows.networking.sockets.messagewebsocketmessagereceivedeventargs.getdatareader?view=winrt-19041#remarks
314
+ if (hr == WININET_E_CONNECTION_ABORTED) {
315
+ string errorMessage{"[0x80072EFE] Underlying TCP connection suddenly terminated"};
316
+ self->m_errorHandler({errorMessage, ErrorType::Connection});
317
+ // Note: We are not clear whether all read-related errors should close the socket.
318
+ self->Close(CloseCode::BadPayload, std::move(errorMessage));
319
+ } else {
320
+ self->m_errorHandler({Utilities::HResultToString(hr), ErrorType::Receive});
336
321
  }
337
- });
322
+ return;
323
+ }
324
+
325
+ auto len = reader.UnconsumedBufferLength();
326
+ if (args.MessageType() == SocketMessageType::Utf8) {
327
+ reader.UnicodeEncoding(UnicodeEncoding::Utf8);
328
+ vector<uint8_t> data(len);
329
+ reader.ReadBytes(data);
330
+
331
+ response = string(CheckedReinterpretCast<char *>(data.data()), data.size());
332
+ } else {
333
+ auto buffer = reader.ReadBuffer(len);
334
+ winrt::hstring data = CryptographicBuffer::EncodeToBase64String(buffer);
335
+
336
+ response = winrt::to_string(std::wstring_view(data));
337
+ }
338
+
339
+ if (self->m_readHandler) {
340
+ self->m_readHandler(response.length(), response, args.MessageType() == SocketMessageType::Binary);
341
+ }
342
+ } catch (hresult_error const &e) {
343
+ if (self->m_errorHandler) {
344
+ string errorMessage;
345
+ ErrorType errorType;
346
+ errorMessage = Utilities::HResultToString(e);
347
+ errorType = ErrorType::Receive;
348
+ self->m_errorHandler({errorMessage, errorType});
349
+ }
350
+ }
351
+ });
338
352
 
339
353
  m_readyState = ReadyState::Connecting;
340
354
 
package/generate.js CHANGED
@@ -7,4 +7,9 @@
7
7
 
8
8
  // This file provides a stable entry-point to call the generator for this
9
9
  // version of react-native-windows.
10
- module.exports = require('@react-native-windows/cli').generateWindows;
10
+
11
+ try {
12
+ module.exports = require('@react-native-windows/cli').generateWindows;
13
+ } catch (e) {
14
+ console.error('Failure during generate ', e);
15
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.0.0-canary.618",
3
+ "version": "0.0.0-canary.620",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "@react-native-community/cli": "10.0.0",
27
27
  "@react-native-community/cli-platform-android": "10.0.0",
28
28
  "@react-native-community/cli-platform-ios": "10.0.0",
29
- "@react-native-windows/cli": "0.0.0-canary.163",
29
+ "@react-native-windows/cli": "0.0.0-canary.164",
30
30
  "@react-native/assets": "1.0.0",
31
31
  "@react-native/assets-registry": "^0.72.0",
32
32
  "@react-native/codegen": "^0.72.1",
@@ -61,7 +61,7 @@
61
61
  "ws": "^6.2.2"
62
62
  },
63
63
  "devDependencies": {
64
- "@react-native-windows/codegen": "0.0.0-canary.51",
64
+ "@react-native-windows/codegen": "0.0.0-canary.52",
65
65
  "@rnw-scripts/babel-react-native-config": "0.0.0",
66
66
  "@rnw-scripts/eslint-config": "1.1.15",
67
67
  "@rnw-scripts/jest-out-of-tree-snapshot-resolver": "^1.1.1",
@@ -79,7 +79,7 @@
79
79
  "prettier": "^2.4.1",
80
80
  "react": "18.2.0",
81
81
  "react-native": "0.0.0-20230201-2114-a0800ffc7",
82
- "react-native-platform-override": "^1.9.1",
82
+ "react-native-platform-override": "^1.9.2",
83
83
  "react-refresh": "^0.4.0",
84
84
  "typescript": "^4.9.5"
85
85
  },