Skip to content

Commit 5957d0a

Browse files
authored
Stop disabling warning 4244 because BinSkim fails if it sees one (#14258)
## Description This PR removes all instances where we ignore warning 4244 (loss of data when casting double to int) because BinSkim won't let us pass compliance when that happens. ### Type of Change - Bug fix (non-breaking change which fixes an issue) ### Why Compliance, fix publish, see above. Closes #14251 ### What See above. ## Screenshots N/A ## Testing N/A ## Changelog Should this change be included in the release notes: _yes_ Stop disabling warning 4244 because BinSkim fails if it sees one
1 parent a8a7c00 commit 5957d0a

File tree

6 files changed

+375
-3
lines changed

6 files changed

+375
-3
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Stop disabling warning 4244 because BinSkim fails if it sees one",
4+
"packageName": "react-native-windows",
5+
"email": "jthysell@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

vnext/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "CompositionViewComponentView.h"
1414

1515
#pragma warning(push)
16-
#pragma warning(disable : 4244 4305)
16+
#pragma warning(disable : 4305)
1717
#include <react/renderer/components/view/ViewProps.h>
1818
#pragma warning(pop)
1919
#include "Composition.ContentIslandComponentView.g.h"

vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "ImageResponseImage.h"
1818

1919
#pragma warning(push)
20-
#pragma warning(disable : 4244 4305)
20+
#pragma warning(disable : 4305)
2121
#include <react/renderer/components/view/ViewProps.h>
2222
#pragma warning(pop)
2323
#include "Composition.ImageComponentView.g.h"
Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
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 "NativeDOM.h"
9+
#include <react/renderer/components/root/RootShadowNode.h>
10+
#include <react/renderer/dom/DOM.h>
11+
#include <react/renderer/uimanager/PointerEventsProcessor.h>
12+
#include <react/renderer/uimanager/UIManagerBinding.h>
13+
14+
#ifdef RN_DISABLE_OSS_PLUGIN_HEADER
15+
#include "Plugins.h"
16+
#endif
17+
18+
std::shared_ptr<facebook::react::TurboModule> NativeDOMModuleProvider(
19+
std::shared_ptr<facebook::react::CallInvoker> jsInvoker) {
20+
return std::make_shared<facebook::react::NativeDOM>(std::move(jsInvoker));
21+
}
22+
23+
namespace facebook::react {
24+
25+
#pragma mark - Private helpers
26+
27+
static RootShadowNode::Shared getCurrentShadowTreeRevision(
28+
facebook::jsi::Runtime& runtime,
29+
SurfaceId surfaceId) {
30+
auto& uiManager =
31+
facebook::react::UIManagerBinding::getBinding(runtime)->getUIManager();
32+
auto shadowTreeRevisionProvider = uiManager.getShadowTreeRevisionProvider();
33+
return shadowTreeRevisionProvider->getCurrentRevision(surfaceId);
34+
}
35+
36+
static facebook::react::PointerEventsProcessor&
37+
getPointerEventsProcessorFromRuntime(facebook::jsi::Runtime& runtime) {
38+
return facebook::react::UIManagerBinding::getBinding(runtime)
39+
->getPointerEventsProcessor();
40+
}
41+
42+
static std::vector<facebook::jsi::Value>
43+
getArrayOfInstanceHandlesFromShadowNodes(
44+
const ShadowNode::ListOfShared& nodes,
45+
facebook::jsi::Runtime& runtime) {
46+
// JSI doesn't support adding elements to an array after creation,
47+
// so we need to accumulate the values in a vector and then create
48+
// the array when we know the size.
49+
std::vector<facebook::jsi::Value> nonNullInstanceHandles;
50+
nonNullInstanceHandles.reserve(nodes.size());
51+
for (const auto& shadowNode : nodes) {
52+
auto instanceHandle = (*shadowNode).getInstanceHandle(runtime);
53+
if (!instanceHandle.isNull()) {
54+
nonNullInstanceHandles.push_back(std::move(instanceHandle));
55+
}
56+
}
57+
58+
return nonNullInstanceHandles;
59+
}
60+
61+
#pragma mark - NativeDOM
62+
63+
NativeDOM::NativeDOM(std::shared_ptr<CallInvoker> jsInvoker)
64+
: NativeDOMCxxSpec(std::move(jsInvoker)) {}
65+
66+
jsi::Value NativeDOM::getParentNode(
67+
jsi::Runtime& rt,
68+
jsi::Value shadowNodeValue) {
69+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
70+
auto currentRevision =
71+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
72+
if (currentRevision == nullptr) {
73+
return jsi::Value::undefined();
74+
}
75+
76+
auto parentShadowNode = dom::getParentNode(currentRevision, *shadowNode);
77+
if (parentShadowNode == nullptr) {
78+
return jsi::Value::undefined();
79+
}
80+
81+
return parentShadowNode->getInstanceHandle(rt);
82+
}
83+
84+
std::vector<jsi::Value> NativeDOM::getChildNodes(
85+
jsi::Runtime& rt,
86+
jsi::Value shadowNodeValue) {
87+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
88+
auto currentRevision =
89+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
90+
if (currentRevision == nullptr) {
91+
return std::vector<jsi::Value>{};
92+
}
93+
94+
auto childNodes = dom::getChildNodes(currentRevision, *shadowNode);
95+
return getArrayOfInstanceHandlesFromShadowNodes(childNodes, rt);
96+
}
97+
98+
bool NativeDOM::isConnected(jsi::Runtime& rt, jsi::Value shadowNodeValue) {
99+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
100+
auto currentRevision =
101+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
102+
if (currentRevision == nullptr) {
103+
return false;
104+
}
105+
106+
return dom::isConnected(currentRevision, *shadowNode);
107+
}
108+
109+
double NativeDOM::compareDocumentPosition(
110+
jsi::Runtime& rt,
111+
jsi::Value shadowNodeValue,
112+
jsi::Value otherShadowNodeValue) {
113+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
114+
auto otherShadowNode = shadowNodeFromValue(rt, otherShadowNodeValue);
115+
auto currentRevision =
116+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
117+
if (otherShadowNode == nullptr || currentRevision == nullptr) {
118+
return 0;
119+
}
120+
121+
return dom::compareDocumentPosition(
122+
currentRevision, *shadowNode, *otherShadowNode);
123+
}
124+
125+
std::string NativeDOM::getTextContent(
126+
jsi::Runtime& rt,
127+
jsi::Value shadowNodeValue) {
128+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
129+
auto currentRevision =
130+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
131+
if (currentRevision == nullptr) {
132+
return "";
133+
}
134+
135+
return dom::getTextContent(currentRevision, *shadowNode);
136+
}
137+
138+
std::tuple<
139+
/* x: */ double,
140+
/* y: */ double,
141+
/* width: */ double,
142+
/* height: */ double>
143+
NativeDOM::getBoundingClientRect(
144+
jsi::Runtime& rt,
145+
jsi::Value shadowNodeValue,
146+
bool includeTransform) {
147+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
148+
auto currentRevision =
149+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
150+
if (currentRevision == nullptr) {
151+
return {0, 0, 0, 0};
152+
}
153+
154+
auto domRect = dom::getBoundingClientRect(
155+
currentRevision, *shadowNode, includeTransform);
156+
157+
return std::tuple{domRect.x, domRect.y, domRect.width, domRect.height};
158+
}
159+
160+
std::tuple<
161+
/* offsetParent: */ jsi::Value,
162+
/* top: */ double,
163+
/* left: */ double>
164+
NativeDOM::getOffset(jsi::Runtime& rt, jsi::Value shadowNodeValue) {
165+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
166+
auto currentRevision =
167+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
168+
if (currentRevision == nullptr) {
169+
return {jsi::Value::undefined(), 0, 0};
170+
}
171+
172+
auto domOffset = dom::getOffset(currentRevision, *shadowNode);
173+
174+
return std::tuple{
175+
domOffset.offsetParent == nullptr
176+
? jsi::Value::undefined()
177+
: domOffset.offsetParent->getInstanceHandle(rt),
178+
domOffset.top,
179+
domOffset.left};
180+
}
181+
182+
std::tuple</* scrollLeft: */ double, /* scrollTop: */ double>
183+
NativeDOM::getScrollPosition(jsi::Runtime& rt, jsi::Value shadowNodeValue) {
184+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
185+
auto currentRevision =
186+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
187+
if (currentRevision == nullptr) {
188+
return {0, 0};
189+
}
190+
191+
auto domPoint = dom::getScrollPosition(currentRevision, *shadowNode);
192+
return std::tuple{domPoint.x, domPoint.y};
193+
}
194+
195+
std::tuple</* scrollWidth: */ int, /* scrollHeight */ int>
196+
NativeDOM::getScrollSize(jsi::Runtime& rt, jsi::Value shadowNodeValue) {
197+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
198+
auto currentRevision =
199+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
200+
if (currentRevision == nullptr) {
201+
return {0, 0};
202+
}
203+
204+
auto scrollSize = dom::getScrollSize(currentRevision, *shadowNode);
205+
return std::tuple{scrollSize.width, scrollSize.height};
206+
}
207+
208+
std::tuple</* width: */ int, /* height: */ int> NativeDOM::getInnerSize(
209+
jsi::Runtime& rt,
210+
jsi::Value shadowNodeValue) {
211+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
212+
auto currentRevision =
213+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
214+
if (currentRevision == nullptr) {
215+
return {0, 0};
216+
}
217+
218+
auto innerSize = dom::getInnerSize(currentRevision, *shadowNode);
219+
return std::tuple{innerSize.width, innerSize.height};
220+
}
221+
222+
std::tuple<
223+
/* topWidth: */ int,
224+
/* rightWidth: */ int,
225+
/* bottomWidth: */ int,
226+
/* leftWidth: */ int>
227+
NativeDOM::getBorderWidth(jsi::Runtime& rt, jsi::Value shadowNodeValue) {
228+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
229+
auto currentRevision =
230+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
231+
if (currentRevision == nullptr) {
232+
return {0, 0, 0, 0};
233+
}
234+
235+
auto borderWidth = dom::getBorderWidth(currentRevision, *shadowNode);
236+
return std::tuple{
237+
borderWidth.top, borderWidth.right, borderWidth.bottom, borderWidth.left};
238+
}
239+
240+
std::string NativeDOM::getTagName(
241+
jsi::Runtime& rt,
242+
jsi::Value shadowNodeValue) {
243+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
244+
return dom::getTagName(*shadowNode);
245+
}
246+
247+
#pragma mark - Pointer events
248+
249+
bool NativeDOM::hasPointerCapture(
250+
jsi::Runtime& rt,
251+
jsi::Value shadowNodeValue,
252+
double pointerId) {
253+
bool isCapturing = getPointerEventsProcessorFromRuntime(rt).hasPointerCapture(
254+
// [Windows] Cast to fix https://github.com/microsoft/react-native-windows/issues/14251
255+
static_cast<PointerIdentifier>(pointerId), shadowNodeFromValue(rt, shadowNodeValue).get());
256+
return isCapturing;
257+
}
258+
259+
void NativeDOM::setPointerCapture(
260+
jsi::Runtime& rt,
261+
jsi::Value shadowNodeValue,
262+
double pointerId) {
263+
getPointerEventsProcessorFromRuntime(rt).setPointerCapture(
264+
// [Windows] Cast to fix https://github.com/microsoft/react-native-windows/issues/14251
265+
static_cast<PointerIdentifier>(pointerId), shadowNodeFromValue(rt, shadowNodeValue));
266+
}
267+
268+
void NativeDOM::releasePointerCapture(
269+
jsi::Runtime& rt,
270+
jsi::Value shadowNodeValue,
271+
double pointerId) {
272+
getPointerEventsProcessorFromRuntime(rt).releasePointerCapture(
273+
// [Windows] Cast to fix https://github.com/microsoft/react-native-windows/issues/14251
274+
static_cast<PointerIdentifier>(pointerId), shadowNodeFromValue(rt, shadowNodeValue).get());
275+
}
276+
277+
#pragma mark - Legacy RN layout APIs
278+
279+
void NativeDOM::measure(
280+
jsi::Runtime& rt,
281+
jsi::Value shadowNodeValue,
282+
jsi::Function callback) {
283+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
284+
auto currentRevision =
285+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
286+
if (currentRevision == nullptr) {
287+
callback.call(rt, {0, 0, 0, 0, 0, 0});
288+
return;
289+
}
290+
291+
auto measureRect = dom::measure(currentRevision, *shadowNode);
292+
293+
callback.call(
294+
rt,
295+
{jsi::Value{rt, measureRect.x},
296+
jsi::Value{rt, measureRect.y},
297+
jsi::Value{rt, measureRect.width},
298+
jsi::Value{rt, measureRect.height},
299+
jsi::Value{rt, measureRect.pageX},
300+
jsi::Value{rt, measureRect.pageY}});
301+
}
302+
303+
void NativeDOM::measureInWindow(
304+
jsi::Runtime& rt,
305+
jsi::Value shadowNodeValue,
306+
jsi::Function callback) {
307+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
308+
auto currentRevision =
309+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
310+
if (currentRevision == nullptr) {
311+
callback.call(rt, {0, 0, 0, 0});
312+
return;
313+
}
314+
315+
auto rect = dom::measureInWindow(currentRevision, *shadowNode);
316+
callback.call(
317+
rt,
318+
{jsi::Value{rt, rect.x},
319+
jsi::Value{rt, rect.y},
320+
jsi::Value{rt, rect.width},
321+
jsi::Value{rt, rect.height}});
322+
}
323+
324+
void NativeDOM::measureLayout(
325+
jsi::Runtime& rt,
326+
jsi::Value shadowNodeValue,
327+
jsi::Value relativeToShadowNodeValue,
328+
jsi::Function onFail,
329+
jsi::Function onSuccess) {
330+
auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
331+
auto relativeToShadowNode =
332+
shadowNodeFromValue(rt, relativeToShadowNodeValue);
333+
auto currentRevision =
334+
getCurrentShadowTreeRevision(rt, shadowNode->getSurfaceId());
335+
if (currentRevision == nullptr) {
336+
onFail.call(rt);
337+
return;
338+
}
339+
340+
auto maybeRect =
341+
dom::measureLayout(currentRevision, *shadowNode, *relativeToShadowNode);
342+
343+
if (!maybeRect) {
344+
onFail.call(rt);
345+
return;
346+
}
347+
348+
auto rect = maybeRect.value();
349+
350+
onSuccess.call(
351+
rt,
352+
{jsi::Value{rt, rect.x},
353+
jsi::Value{rt, rect.y},
354+
jsi::Value{rt, rect.width},
355+
jsi::Value{rt, rect.height}});
356+
}
357+
358+
} // namespace facebook::react

vnext/Shared/Shared.vcxitems

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@
555555
<!-- Uncomment this when we move to a newer JSI -->
556556
<!-- <CLCompile Include="$(ReactNativeDir)\ReactCommon\react\nativemodule\microtasks\NativeMicrotasks.cpp" /> -->
557557
<CLCompile Include="$(ReactNativeDir)\ReactCommon\react\nativemodule\featureflags\NativeReactNativeFeatureFlags.cpp" />
558-
<CLCompile Include="$(ReactNativeDir)\ReactCommon\react\nativemodule\dom\NativeDOM.cpp" DisableSpecificWarnings="4244;4715;%(DisableSpecificWarnings)" />
558+
<CLCompile Include="$(ReactNativeDir)\ReactCommon\react\nativemodule\dom\NativeDOM.cpp" DisableSpecificWarnings="4715;%(DisableSpecificWarnings)" />
559559
<CLCompile Include="$(ReactNativeDir)\ReactCommon\react\nativemodule\idlecallbacks\NativeIdleCallbacks.cpp" />
560560
<ClCompile Include="$(ReactNativeDir)\ReactCommon\react\renderer\attributedstring\AttributedString.cpp" />
561561
<ClCompile Include="$(ReactNativeDir)\ReactCommon\react\renderer\attributedstring\AttributedStringBox.cpp" DisableSpecificWarnings="4715;%(DisableSpecificWarnings)" />

0 commit comments

Comments
 (0)