react-native-windows 0.83.0-preview.4 → 0.83.2
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/unicode.cpp +36 -0
- package/Common/unicode.h +8 -0
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +6 -4
- package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +80 -0
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.h +17 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.cpp +1 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +3 -2
- package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +3 -0
- package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +33 -25
- package/Microsoft.ReactNative/Utils/LocalBundleReader.h +5 -3
- package/Microsoft.ReactNative/Utils/UwpScriptStore.cpp +2 -2
- package/Microsoft.ReactNative/Utils/UwpScriptStore.h +3 -2
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +16 -0
- package/Microsoft.ReactNative.Managed/Microsoft.ReactNative.Managed.csproj +3 -3
- package/Microsoft.ReactNative.Managed.CodeGen/Microsoft.ReactNative.Managed.CodeGen.csproj +10 -10
- package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Debug.pubxml +1 -1
- package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Release.pubxml +1 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/React.Cpp.props +4 -3
- package/PropertySheets/WinUI.props +2 -2
- package/Scripts/JustMyXaml.ps1 +8 -8
- package/Scripts/UnitTest.ps1 +3 -1
- package/Scripts/creaternwapp.cmd +12 -2
- package/Scripts/creaternwlib.cmd +12 -2
- package/Scripts/rnw-dependencies.ps1 +15 -16
- package/Shared/DevSupportManager.cpp +55 -48
- package/Shared/DevSupportManager.h +0 -1
- package/Shared/Modules/IWebSocketModuleContentHandler.h +15 -0
- package/Shared/Modules/WebSocketModule.cpp +8 -3
- package/Shared/Networking/DefaultBlobResource.cpp +37 -0
- package/Shared/Networking/DefaultBlobResource.h +12 -0
- package/Shared/Networking/WinRTWebSocketResource.h +5 -1
- package/just-task.js +13 -2
- package/package.json +6 -6
- package/templates/cpp-app/windows/MyApp/MyApp.vcxproj +1 -1
- package/templates/cpp-lib/windows/MyLib/MyLib.vcxproj +1 -1
package/Common/unicode.cpp
CHANGED
|
@@ -93,6 +93,42 @@ std::wstring Utf8ToUtf16(const std::string &utf8) {
|
|
|
93
93
|
return Utf8ToUtf16(utf8.c_str(), utf8.length());
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
size_t Utf8ToUtf16Length(const char *utf8, size_t utf8Len) {
|
|
97
|
+
if (utf8Len == 0) {
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (utf8Len > static_cast<size_t>((std::numeric_limits<int>::max)())) {
|
|
102
|
+
throw std::overflow_error("Length of input string to Utf8ToUtf16Length() must fit into an int.");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const int utf8Length = static_cast<int>(utf8Len);
|
|
106
|
+
|
|
107
|
+
constexpr DWORD flags = 0;
|
|
108
|
+
|
|
109
|
+
const int utf16Length = ::MultiByteToWideChar(
|
|
110
|
+
CP_UTF8, // Source string is in UTF-8.
|
|
111
|
+
flags, // Conversion flags.
|
|
112
|
+
utf8, // Source UTF-8 string pointer.
|
|
113
|
+
utf8Length, // Length of the source UTF-8 string, in chars.
|
|
114
|
+
nullptr, // Do not convert, just request the size.
|
|
115
|
+
0 // Request size of destination buffer, in wchar_ts.
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
if (utf16Length == 0) {
|
|
119
|
+
throw UnicodeConversionException(
|
|
120
|
+
"Cannot get result string length when converting from UTF-8 to UTF-16 "
|
|
121
|
+
"(MultiByteToWideChar failed).",
|
|
122
|
+
GetLastError());
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return static_cast<size_t>(utf16Length);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
size_t Utf8ToUtf16Length(const std::string &utf8) {
|
|
129
|
+
return Utf8ToUtf16Length(utf8.c_str(), utf8.length());
|
|
130
|
+
}
|
|
131
|
+
|
|
96
132
|
#if _HAS_CXX17
|
|
97
133
|
std::wstring Utf8ToUtf16(const std::string_view &utf8) {
|
|
98
134
|
return Utf8ToUtf16(utf8.data(), utf8.length());
|
package/Common/unicode.h
CHANGED
|
@@ -55,6 +55,14 @@ class UnicodeConversionException : public std::runtime_error {
|
|
|
55
55
|
/* (4) */ std::wstring Utf8ToUtf16(const std::string_view &utf8);
|
|
56
56
|
#endif
|
|
57
57
|
|
|
58
|
+
// The following functions return the length of the UTF-16 string that would
|
|
59
|
+
// result from converting the input UTF-8 string, without actually performing
|
|
60
|
+
// the conversion or allocating a temporary std::wstring. This is useful in
|
|
61
|
+
// hot paths where only the length is needed (e.g. DirectWrite text ranges).
|
|
62
|
+
//
|
|
63
|
+
size_t Utf8ToUtf16Length(const char *utf8, size_t utf8Len);
|
|
64
|
+
size_t Utf8ToUtf16Length(const std::string &utf8);
|
|
65
|
+
|
|
58
66
|
// The following functions convert UTF-16BE strings to UTF-8 strings. Their
|
|
59
67
|
// behaviors mirror those of the above Utf8ToUtf16 functions.
|
|
60
68
|
//
|
|
@@ -153,11 +153,12 @@ facebook::react::SharedViewEventEmitter ParagraphComponentView::eventEmitterAtPo
|
|
|
153
153
|
uint32_t textPosition = metrics.textPosition;
|
|
154
154
|
|
|
155
155
|
for (auto fragment : m_attributedStringBox.getValue().getFragments()) {
|
|
156
|
-
|
|
156
|
+
uint32_t utf16Length = static_cast<uint32_t>(::Microsoft::Common::Unicode::Utf8ToUtf16Length(fragment.string));
|
|
157
|
+
if (textPosition < utf16Length) {
|
|
157
158
|
return std::static_pointer_cast<const facebook::react::ViewEventEmitter>(
|
|
158
159
|
fragment.parentShadowView.eventEmitter);
|
|
159
160
|
}
|
|
160
|
-
textPosition -=
|
|
161
|
+
textPosition -= utf16Length;
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
}
|
|
@@ -210,10 +211,11 @@ bool ParagraphComponentView::IsTextSelectableAtPoint(facebook::react::Point pt)
|
|
|
210
211
|
|
|
211
212
|
// Finds which fragment contains this text position
|
|
212
213
|
for (auto fragment : m_attributedStringBox.getValue().getFragments()) {
|
|
213
|
-
|
|
214
|
+
uint32_t utf16Length = static_cast<uint32_t>(::Microsoft::Common::Unicode::Utf8ToUtf16Length(fragment.string));
|
|
215
|
+
if (textPosition < utf16Length) {
|
|
214
216
|
return true;
|
|
215
217
|
}
|
|
216
|
-
textPosition -=
|
|
218
|
+
textPosition -= utf16Length;
|
|
217
219
|
}
|
|
218
220
|
}
|
|
219
221
|
}
|
|
@@ -66,7 +66,7 @@ void RenderText(
|
|
|
66
66
|
unsigned int position = 0;
|
|
67
67
|
unsigned int length = 0;
|
|
68
68
|
for (auto fragment : attributedString.getFragments()) {
|
|
69
|
-
length = static_cast<UINT32>(fragment.string
|
|
69
|
+
length = static_cast<UINT32>(::Microsoft::Common::Unicode::Utf8ToUtf16Length(fragment.string));
|
|
70
70
|
DWRITE_TEXT_RANGE range = {position, length};
|
|
71
71
|
if (fragment.textAttributes.foregroundColor &&
|
|
72
72
|
(fragment.textAttributes.foregroundColor != textAttributes.foregroundColor) ||
|
|
@@ -169,12 +169,22 @@ TooltipTracker::TooltipTracker(
|
|
|
169
169
|
view.PointerEntered({this, &TooltipTracker::OnPointerEntered});
|
|
170
170
|
view.PointerExited({this, &TooltipTracker::OnPointerExited});
|
|
171
171
|
view.PointerMoved({this, &TooltipTracker::OnPointerMoved});
|
|
172
|
+
view.GotFocus({this, &TooltipTracker::OnGotFocus});
|
|
173
|
+
view.LostFocus({this, &TooltipTracker::OnLostFocus});
|
|
172
174
|
view.Unmounted({this, &TooltipTracker::OnUnmounted});
|
|
173
175
|
}
|
|
174
176
|
|
|
175
177
|
TooltipTracker::~TooltipTracker() {
|
|
176
178
|
DestroyTimer();
|
|
177
179
|
DestroyTooltip();
|
|
180
|
+
m_outer->NotifyDismiss(this);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
void TooltipTracker::DismissForExternalRequest() noexcept {
|
|
184
|
+
// Service is already updating its active slot; do not call back into it.
|
|
185
|
+
m_focusTooltip = false;
|
|
186
|
+
DestroyTimer();
|
|
187
|
+
DestroyTooltip();
|
|
178
188
|
}
|
|
179
189
|
|
|
180
190
|
facebook::react::Tag TooltipTracker::Tag() const noexcept {
|
|
@@ -192,6 +202,9 @@ void TooltipTracker::OnPointerEntered(
|
|
|
192
202
|
auto pp = args.GetCurrentPoint(-1);
|
|
193
203
|
m_pos = pp.Position();
|
|
194
204
|
|
|
205
|
+
// Claim the single tooltip slot, dismissing any other tracker's pending or visible tooltip.
|
|
206
|
+
m_outer->NotifyShow(this);
|
|
207
|
+
|
|
195
208
|
m_timer = winrt::Microsoft::ReactNative::Timer::Create(m_properties.Handle());
|
|
196
209
|
m_timer.Interval(std::chrono::milliseconds(toolTipTimeToShowMs));
|
|
197
210
|
m_timer.Tick({this, &TooltipTracker::OnTick});
|
|
@@ -225,6 +238,56 @@ void TooltipTracker::OnPointerExited(
|
|
|
225
238
|
return;
|
|
226
239
|
DestroyTimer();
|
|
227
240
|
DestroyTooltip();
|
|
241
|
+
m_outer->NotifyDismiss(this);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
void TooltipTracker::OnGotFocus(
|
|
245
|
+
const winrt::Windows::Foundation::IInspectable & /*sender*/,
|
|
246
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs & /*args*/) noexcept {
|
|
247
|
+
// Skip if a mouse-driven tooltip or its dwell timer is already in flight on this view.
|
|
248
|
+
if (m_hwndTip || m_timer) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
auto view = m_view.view();
|
|
253
|
+
if (!view) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
auto viewCompView = view.try_as<winrt::Microsoft::ReactNative::Composition::ViewComponentView>();
|
|
258
|
+
if (!viewCompView) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
auto selfView =
|
|
262
|
+
winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::ViewComponentView>(viewCompView);
|
|
263
|
+
RECT rc = selfView->getClientRect();
|
|
264
|
+
auto scaleFactor = view.LayoutMetrics().PointScaleFactor;
|
|
265
|
+
if (scaleFactor <= 0) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Anchor in DIPs at the horizontal center of the view's top edge; ShowTooltip re-applies scaleFactor.
|
|
270
|
+
m_pos = {static_cast<float>(rc.left + rc.right) / 2.0f / scaleFactor, static_cast<float>(rc.top) / scaleFactor};
|
|
271
|
+
|
|
272
|
+
m_focusTooltip = true;
|
|
273
|
+
// Claim the single tooltip slot, dismissing any other tracker's pending or visible tooltip.
|
|
274
|
+
m_outer->NotifyShow(this);
|
|
275
|
+
m_timer = winrt::Microsoft::ReactNative::Timer::Create(m_properties.Handle());
|
|
276
|
+
m_timer.Interval(std::chrono::milliseconds(toolTipTimeToShowMs));
|
|
277
|
+
m_timer.Tick({this, &TooltipTracker::OnTick});
|
|
278
|
+
m_timer.Start();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
void TooltipTracker::OnLostFocus(
|
|
282
|
+
const winrt::Windows::Foundation::IInspectable & /*sender*/,
|
|
283
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs & /*args*/) noexcept {
|
|
284
|
+
if (!m_focusTooltip) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
m_focusTooltip = false;
|
|
288
|
+
DestroyTimer();
|
|
289
|
+
DestroyTooltip();
|
|
290
|
+
m_outer->NotifyDismiss(this);
|
|
228
291
|
}
|
|
229
292
|
|
|
230
293
|
void TooltipTracker::OnUnmounted(
|
|
@@ -232,6 +295,7 @@ void TooltipTracker::OnUnmounted(
|
|
|
232
295
|
const winrt::Microsoft::ReactNative::ComponentView &) noexcept {
|
|
233
296
|
DestroyTimer();
|
|
234
297
|
DestroyTooltip();
|
|
298
|
+
m_outer->NotifyDismiss(this);
|
|
235
299
|
}
|
|
236
300
|
|
|
237
301
|
void TooltipTracker::ShowTooltip(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
|
|
@@ -326,6 +390,22 @@ void TooltipService::StopTracking(const winrt::Microsoft::ReactNative::Component
|
|
|
326
390
|
}
|
|
327
391
|
}
|
|
328
392
|
|
|
393
|
+
void TooltipService::NotifyShow(TooltipTracker *tracker) noexcept {
|
|
394
|
+
if (m_activeTracker == tracker) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (m_activeTracker) {
|
|
398
|
+
m_activeTracker->DismissForExternalRequest();
|
|
399
|
+
}
|
|
400
|
+
m_activeTracker = tracker;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
void TooltipService::NotifyDismiss(TooltipTracker *tracker) noexcept {
|
|
404
|
+
if (m_activeTracker == tracker) {
|
|
405
|
+
m_activeTracker = nullptr;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
329
409
|
static const ReactPropertyId<winrt::Microsoft::ReactNative::ReactNonAbiValue<std::shared_ptr<TooltipService>>>
|
|
330
410
|
&TooltipServicePropertyId() noexcept {
|
|
331
411
|
static const ReactPropertyId<winrt::Microsoft::ReactNative::ReactNonAbiValue<std::shared_ptr<TooltipService>>> prop{
|
|
@@ -27,6 +27,12 @@ struct TooltipTracker {
|
|
|
27
27
|
void OnPointerExited(
|
|
28
28
|
const winrt::Windows::Foundation::IInspectable &sender,
|
|
29
29
|
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept;
|
|
30
|
+
void OnGotFocus(
|
|
31
|
+
const winrt::Windows::Foundation::IInspectable &sender,
|
|
32
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept;
|
|
33
|
+
void OnLostFocus(
|
|
34
|
+
const winrt::Windows::Foundation::IInspectable &sender,
|
|
35
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept;
|
|
30
36
|
void OnTick(
|
|
31
37
|
const winrt::Windows::Foundation::IInspectable &,
|
|
32
38
|
const winrt::Windows::Foundation::IInspectable &) noexcept;
|
|
@@ -36,6 +42,10 @@ struct TooltipTracker {
|
|
|
36
42
|
|
|
37
43
|
facebook::react::Tag Tag() const noexcept;
|
|
38
44
|
|
|
45
|
+
// Cancel pending dwell timer and close any visible tooltip popup; used by the service when another tracker takes
|
|
46
|
+
// over.
|
|
47
|
+
void DismissForExternalRequest() noexcept;
|
|
48
|
+
|
|
39
49
|
private:
|
|
40
50
|
void ShowTooltip(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
41
51
|
void DestroyTimer() noexcept;
|
|
@@ -46,6 +56,7 @@ struct TooltipTracker {
|
|
|
46
56
|
::Microsoft::ReactNative::ReactTaggedView m_view;
|
|
47
57
|
winrt::Microsoft::ReactNative::ITimer m_timer;
|
|
48
58
|
HWND m_hwndTip{nullptr};
|
|
59
|
+
bool m_focusTooltip{false};
|
|
49
60
|
winrt::Microsoft::ReactNative::ReactPropertyBag m_properties;
|
|
50
61
|
};
|
|
51
62
|
|
|
@@ -54,12 +65,18 @@ struct TooltipService {
|
|
|
54
65
|
void StartTracking(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
55
66
|
void StopTracking(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
56
67
|
|
|
68
|
+
// Enforce "only one tooltip visible at a time": dismisses the previously active tracker, if any.
|
|
69
|
+
void NotifyShow(TooltipTracker *tracker) noexcept;
|
|
70
|
+
// Clears the active-tracker slot if it still points at `tracker`.
|
|
71
|
+
void NotifyDismiss(TooltipTracker *tracker) noexcept;
|
|
72
|
+
|
|
57
73
|
static std::shared_ptr<TooltipService> GetCurrent(
|
|
58
74
|
const winrt::Microsoft::ReactNative::ReactPropertyBag &properties) noexcept;
|
|
59
75
|
|
|
60
76
|
private:
|
|
61
77
|
std::vector<std::shared_ptr<TooltipTracker>> m_enteredTrackers;
|
|
62
78
|
std::vector<std::shared_ptr<TooltipTracker>> m_trackers;
|
|
79
|
+
TooltipTracker *m_activeTracker{nullptr};
|
|
63
80
|
winrt::Microsoft::ReactNative::ReactPropertyBag m_properties;
|
|
64
81
|
};
|
|
65
82
|
|
|
@@ -267,7 +267,7 @@ void WindowsTextLayoutManager::GetTextLayout(
|
|
|
267
267
|
attachments.push_back(attachment);
|
|
268
268
|
position += 1;
|
|
269
269
|
} else {
|
|
270
|
-
unsigned int length = static_cast<UINT32>(fragment.string
|
|
270
|
+
unsigned int length = static_cast<UINT32>(Microsoft::Common::Unicode::Utf8ToUtf16Length(fragment.string));
|
|
271
271
|
DWRITE_TEXT_RANGE range = {position, length};
|
|
272
272
|
TextAttributes attributes = fragment.textAttributes;
|
|
273
273
|
DWRITE_FONT_STYLE fragmentStyle = DWRITE_FONT_STYLE_NORMAL;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<ProjectName>Microsoft.ReactNative</ProjectName>
|
|
11
11
|
<RootNamespace>Microsoft.ReactNative</RootNamespace>
|
|
12
12
|
<DefaultLanguage>en-US</DefaultLanguage>
|
|
13
|
-
<MinimumVisualStudioVersion>
|
|
13
|
+
<MinimumVisualStudioVersion>18.0</MinimumVisualStudioVersion>
|
|
14
14
|
<AppContainerApplication>true</AppContainerApplication>
|
|
15
15
|
<ApplicationType>Windows Store</ApplicationType>
|
|
16
16
|
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
|
@@ -96,7 +96,8 @@
|
|
|
96
96
|
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
|
97
97
|
<ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
|
|
98
98
|
<WarningLevel>Level4</WarningLevel>
|
|
99
|
-
<AdditionalOptions
|
|
99
|
+
<AdditionalOptions>%(AdditionalOptions) /bigobj /ZH:SHA_256</AdditionalOptions>
|
|
100
|
+
<AdditionalOptions Condition="$(PlatformToolsetVersion)<145">%(AdditionalOptions) /await</AdditionalOptions>
|
|
100
101
|
<AdditionalIncludeDirectories>
|
|
101
102
|
$(FmtDir)\include;
|
|
102
103
|
$(ReactNativeWindowsDir)Microsoft.ReactNative;
|
|
@@ -3,6 +3,7 @@ import "ReactNativeHost.idl";
|
|
|
3
3
|
import "ReactNativeIsland.idl";
|
|
4
4
|
import "ReactInstanceSettings.idl";
|
|
5
5
|
import "IReactPackageProvider.idl";
|
|
6
|
+
import "ReactNativeWindow.idl";
|
|
6
7
|
|
|
7
8
|
#include "DocString.h"
|
|
8
9
|
|
|
@@ -14,6 +15,8 @@ namespace Microsoft.ReactNative {
|
|
|
14
15
|
// Properties
|
|
15
16
|
Microsoft.UI.Windowing.AppWindow AppWindow {get;};
|
|
16
17
|
|
|
18
|
+
ReactNativeWindow ReactNativeWindow {get;};
|
|
19
|
+
|
|
17
20
|
ReactNativeHost ReactNativeHost {get;};
|
|
18
21
|
|
|
19
22
|
ReactViewOptions ReactViewOptions {get;};
|
|
@@ -54,7 +54,29 @@ std::string GetBundleFromEmbeddedResource(const winrt::Windows::Foundation::Uri
|
|
|
54
54
|
return std::string(start, start + size);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
namespace {
|
|
58
|
+
|
|
59
|
+
std::string BufferToString(const winrt::Windows::Storage::Streams::IBuffer &buffer) {
|
|
60
|
+
std::string result(buffer.Length(), '\0');
|
|
61
|
+
if (!result.empty()) {
|
|
62
|
+
auto reader = winrt::Windows::Storage::Streams::DataReader::FromBuffer(buffer);
|
|
63
|
+
reader.ReadBytes(winrt::array_view<uint8_t>{
|
|
64
|
+
reinterpret_cast<uint8_t *>(&result[0]), reinterpret_cast<uint8_t *>(&result[result.length()])});
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
winrt::Windows::Storage::Streams::IBuffer BytesToBuffer(const void *data, uint32_t size) {
|
|
70
|
+
winrt::Windows::Storage::Streams::DataWriter writer;
|
|
71
|
+
auto bytes = static_cast<const uint8_t *>(data);
|
|
72
|
+
writer.WriteBytes(winrt::array_view<const uint8_t>(bytes, bytes + size));
|
|
73
|
+
return writer.DetachBuffer();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
} // namespace
|
|
77
|
+
|
|
78
|
+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IBuffer>
|
|
79
|
+
LocalBundleReader::LoadBundleAsync(const std::wstring bundleUri) {
|
|
58
80
|
try {
|
|
59
81
|
co_await winrt::resume_background();
|
|
60
82
|
|
|
@@ -66,41 +88,26 @@ std::future<std::string> LocalBundleReader::LoadBundleAsync(const std::wstring b
|
|
|
66
88
|
file = co_await winrt::Windows::Storage::StorageFile::GetFileFromApplicationUriAsync(uri);
|
|
67
89
|
} else if (bundleUri.starts_with(L"resource://")) {
|
|
68
90
|
winrt::Windows::Foundation::Uri uri(bundleUri);
|
|
69
|
-
|
|
91
|
+
auto bytes = GetBundleFromEmbeddedResource(uri);
|
|
92
|
+
co_return BytesToBuffer(bytes.data(), static_cast<uint32_t>(bytes.size()));
|
|
70
93
|
} else {
|
|
71
94
|
file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(bundleUri);
|
|
72
95
|
}
|
|
73
96
|
|
|
74
|
-
|
|
75
|
-
// roundtrip.
|
|
76
|
-
auto fileBuffer{co_await winrt::Windows::Storage::FileIO::ReadBufferAsync(file)};
|
|
77
|
-
auto dataReader{winrt::Windows::Storage::Streams::DataReader::FromBuffer(fileBuffer)};
|
|
78
|
-
|
|
79
|
-
// No need to use length + 1, STL guarantees that string storage is null-terminated.
|
|
80
|
-
std::string script(fileBuffer.Length(), '\0');
|
|
81
|
-
|
|
82
|
-
// Construct the array_view to slice into the first fileBuffer.Length bytes.
|
|
83
|
-
// DataReader.ReadBytes will read as many bytes as are present in the
|
|
84
|
-
// array_view. The backing string has fileBuffer.Length() + 1 bytes, without
|
|
85
|
-
// an explicit end it will read 1 byte to many and throw.
|
|
86
|
-
dataReader.ReadBytes(winrt::array_view<uint8_t>{
|
|
87
|
-
reinterpret_cast<uint8_t *>(&script[0]), reinterpret_cast<uint8_t *>(&script[script.length()])});
|
|
88
|
-
dataReader.Close();
|
|
89
|
-
|
|
90
|
-
co_return script;
|
|
97
|
+
co_return co_await winrt::Windows::Storage::FileIO::ReadBufferAsync(file);
|
|
91
98
|
}
|
|
92
99
|
// RuntimeScheduler only handles std::exception or jsi::JSError
|
|
93
|
-
catch (winrt::hresult_error const &
|
|
94
|
-
throw
|
|
100
|
+
catch (winrt::hresult_error const &) {
|
|
101
|
+
throw;
|
|
95
102
|
}
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
std::string LocalBundleReader::LoadBundle(const std::wstring &bundlePath) {
|
|
99
|
-
return LoadBundleAsync(bundlePath).get();
|
|
106
|
+
return BufferToString(LoadBundleAsync(bundlePath).get());
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
StorageFileBigString::StorageFileBigString(const std::wstring &path) {
|
|
103
|
-
|
|
110
|
+
m_pendingLoad = LocalBundleReader::LoadBundleAsync(path);
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
bool StorageFileBigString::isAscii() const {
|
|
@@ -118,8 +125,9 @@ size_t StorageFileBigString::size() const {
|
|
|
118
125
|
}
|
|
119
126
|
|
|
120
127
|
void StorageFileBigString::ensure() const {
|
|
121
|
-
if (
|
|
122
|
-
m_string =
|
|
128
|
+
if (m_pendingLoad) {
|
|
129
|
+
m_string = BufferToString(m_pendingLoad.get());
|
|
130
|
+
m_pendingLoad = nullptr;
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
133
|
|
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
#pragma once
|
|
5
5
|
#include <cxxreact/JSBigString.h>
|
|
6
|
-
#include <
|
|
6
|
+
#include <winrt/Windows.Foundation.h>
|
|
7
|
+
#include <winrt/Windows.Storage.Streams.h>
|
|
7
8
|
#include <string>
|
|
8
9
|
|
|
9
10
|
namespace Microsoft::ReactNative {
|
|
10
11
|
|
|
11
12
|
class LocalBundleReader {
|
|
12
13
|
public:
|
|
13
|
-
static
|
|
14
|
+
static winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IBuffer> LoadBundleAsync(
|
|
15
|
+
const std::wstring bundlePath);
|
|
14
16
|
static std::string LoadBundle(const std::wstring &bundlePath);
|
|
15
17
|
};
|
|
16
18
|
|
|
@@ -24,7 +26,7 @@ class StorageFileBigString : public facebook::react::JSBigString {
|
|
|
24
26
|
void ensure() const;
|
|
25
27
|
|
|
26
28
|
private:
|
|
27
|
-
mutable
|
|
29
|
+
mutable winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IBuffer> m_pendingLoad;
|
|
28
30
|
mutable std::string m_string;
|
|
29
31
|
};
|
|
30
32
|
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
#include <winrt/Windows.Foundation.h>
|
|
5
5
|
#include <winrt/Windows.Storage.FileProperties.h>
|
|
6
6
|
#include <winrt/Windows.Storage.h>
|
|
7
|
-
#include <future>
|
|
8
7
|
#include "Unicode.h"
|
|
9
8
|
|
|
10
9
|
namespace winrt {
|
|
@@ -43,7 +42,8 @@ facebook::jsi::ScriptVersion_t UwpScriptStore::getScriptVersion(const std::strin
|
|
|
43
42
|
return version;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
|
|
45
|
+
winrt::Windows::Foundation::IAsyncOperation<facebook::jsi::ScriptVersion_t> UwpScriptStore::getScriptVersionAsync(
|
|
46
|
+
const std::string &bundleUri) {
|
|
47
47
|
co_await winrt::resume_background();
|
|
48
48
|
|
|
49
49
|
const winrt::hstring fileUrl(Microsoft::Common::Unicode::Utf8ToUtf16("ms-appx:///Bundle/" + bundleUri + ".bundle"));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
#include <JSI/ScriptStore.h>
|
|
3
|
-
#include <
|
|
3
|
+
#include <winrt/Windows.Foundation.h>
|
|
4
4
|
|
|
5
5
|
namespace Microsoft::ReactNative {
|
|
6
6
|
|
|
@@ -16,7 +16,8 @@ class UwpScriptStore : public facebook::jsi::ScriptStore {
|
|
|
16
16
|
static facebook::jsi::ScriptVersion_t GetFileVersion(const std::wstring &filePath);
|
|
17
17
|
|
|
18
18
|
private:
|
|
19
|
-
|
|
19
|
+
winrt::Windows::Foundation::IAsyncOperation<facebook::jsi::ScriptVersion_t> getScriptVersionAsync(
|
|
20
|
+
const std::string &bundleUri);
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
} // namespace Microsoft::ReactNative
|
|
@@ -158,6 +158,22 @@
|
|
|
158
158
|
</ClCompile>
|
|
159
159
|
<ClCompile Include="$(NodeApiJsiSrcDir)NodeApiJsiRuntime.cpp">
|
|
160
160
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
161
|
+
<!--
|
|
162
|
+
Workaround for a Visual Studio 2026 (v145) C++ optimizer bug. With
|
|
163
|
+
optimizations on, this translation unit is miscompiled such that the
|
|
164
|
+
pointer-value-scope teardown in NodeApiJsiRuntime hands Hermes a stale
|
|
165
|
+
napi_value, crashing in hermes!JSProxy::defineOwnProperty (via
|
|
166
|
+
napi_create_reference) during rapid UI updates - e.g. the
|
|
167
|
+
e2e-test-app-fabric visitAllPages test. Building this file without
|
|
168
|
+
optimization (verified equivalent to `#pragma optimize("", off)`)
|
|
169
|
+
avoids it. We must also opt out of /GL here so the disabled
|
|
170
|
+
optimization survives link-time code generation. NodeApiJsiRuntime.cpp
|
|
171
|
+
is externally provided, so the workaround lives here rather than in the
|
|
172
|
+
source. Scoped to v145+ (the bug does not reproduce on v143); remove
|
|
173
|
+
when the compiler bug is fixed.
|
|
174
|
+
-->
|
|
175
|
+
<Optimization Condition="$(PlatformToolsetVersion)>=145">Disabled</Optimization>
|
|
176
|
+
<WholeProgramOptimization Condition="$(PlatformToolsetVersion)>=145">false</WholeProgramOptimization>
|
|
161
177
|
</ClCompile>
|
|
162
178
|
</ItemGroup>
|
|
163
179
|
<ItemGroup Condition="'$(BuildMSRNCxxNodeApiJsiLoader)' != 'false'">
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
|
16
16
|
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.22621.0</TargetPlatformVersion>
|
|
17
17
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
|
18
|
-
<MinimumVisualStudioVersion>
|
|
18
|
+
<MinimumVisualStudioVersion>18.0</MinimumVisualStudioVersion>
|
|
19
19
|
<FileAlignment>512</FileAlignment>
|
|
20
20
|
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
|
21
21
|
<DocumentationFile>bin\$(Platform)\$(Configuration)\Microsoft.ReactNative.Managed.XML</DocumentationFile>
|
|
@@ -150,8 +150,8 @@
|
|
|
150
150
|
</ItemGroup>
|
|
151
151
|
</When>
|
|
152
152
|
</Choose>
|
|
153
|
-
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '
|
|
154
|
-
<VisualStudioVersion>
|
|
153
|
+
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '18.0' ">
|
|
154
|
+
<VisualStudioVersion>18.0</VisualStudioVersion>
|
|
155
155
|
</PropertyGroup>
|
|
156
156
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
|
157
157
|
<Target Name="Deploy" />
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<PropertyGroup>
|
|
4
4
|
<OutputType>Exe</OutputType>
|
|
5
5
|
|
|
6
|
-
<TargetFramework>
|
|
6
|
+
<TargetFramework>net10.0</TargetFramework>
|
|
7
7
|
<Platforms>x64;x86;ARM64</Platforms>
|
|
8
8
|
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
|
9
9
|
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.3.1" />
|
|
32
32
|
<PackageReference Include="RuntimeContracts" Version="0.3.0" />
|
|
33
33
|
|
|
34
|
-
<!--
|
|
35
|
-
NuGet decides to pull in packages with issues. There is no seeming way to diagnose why NuGet is pulling in those versions.
|
|
34
|
+
<!--
|
|
35
|
+
NuGet decides to pull in packages with issues. There is no seeming way to diagnose why NuGet is pulling in those versions.
|
|
36
36
|
Running restore with -Verbosity Detailed and environment variables:
|
|
37
37
|
* NUGET_RESTORE_MSBUILD_ARGS=/bl:c:\temp\nuget.binlog
|
|
38
38
|
* NUGET_RESTORE_MSBUILD_VERBOSITY=diag
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
<PackageReference Include="System.Private.Uri" Version="4.3.2" />
|
|
43
43
|
</ItemGroup>
|
|
44
44
|
|
|
45
|
-
<!--
|
|
45
|
+
<!--
|
|
46
46
|
This target is used to ensure the tool is deployed and can be used from source.
|
|
47
47
|
It will return all deployed files so the caller can implement incrementality properly
|
|
48
48
|
-->
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
</ItemGroup>
|
|
54
54
|
</Target>
|
|
55
55
|
|
|
56
|
-
<!--
|
|
56
|
+
<!--
|
|
57
57
|
This target returns the location of the deployed executable.
|
|
58
58
|
-->
|
|
59
59
|
<Target Name="GetPublishedToolPath" DependsOnTargets="PublishTool" Returns="@(_PublishedToolExecutable)">
|
|
@@ -62,13 +62,13 @@
|
|
|
62
62
|
</ItemGroup>
|
|
63
63
|
</Target>
|
|
64
64
|
|
|
65
|
-
<!--
|
|
65
|
+
<!--
|
|
66
66
|
This is used during the PR build to ensure we have the artifacts published during the build.
|
|
67
67
|
-->
|
|
68
|
-
<Target
|
|
69
|
-
Name="PublishToolDuringBuild"
|
|
70
|
-
DependsOnTargets="Publish"
|
|
71
|
-
AfterTargets="Build"
|
|
68
|
+
<Target
|
|
69
|
+
Name="PublishToolDuringBuild"
|
|
70
|
+
DependsOnTargets="Publish"
|
|
71
|
+
AfterTargets="Build"
|
|
72
72
|
Condition="'$(PublishToolDuringBuild)' == 'true'">
|
|
73
73
|
</Target>
|
|
74
74
|
|
package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Debug.pubxml
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<PublishProtocol>FileSystem</PublishProtocol>
|
|
7
7
|
<Configuration>Debug</Configuration>
|
|
8
8
|
<Platform>x64</Platform>
|
|
9
|
-
<TargetFramework>
|
|
9
|
+
<TargetFramework>net10.0</TargetFramework>
|
|
10
10
|
<PublishDir>$(OutDir)publish</PublishDir>
|
|
11
11
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
|
12
12
|
<SelfContained>true</SelfContained>
|
package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Release.pubxml
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<PublishProtocol>FileSystem</PublishProtocol>
|
|
7
7
|
<Configuration>Release</Configuration>
|
|
8
8
|
<Platform>x64</Platform>
|
|
9
|
-
<TargetFramework>
|
|
9
|
+
<TargetFramework>net10.0</TargetFramework>
|
|
10
10
|
<PublishDir>$(OutDir)publish</PublishDir>
|
|
11
11
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
|
12
12
|
<SelfContained>true</SelfContained>
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.83.
|
|
13
|
+
<ReactNativeWindowsVersion>0.83.2</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>83</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>2</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
18
|
+
<ReactNativeWindowsCommitId>83f78a8cf0b1226d7a9b78a1b18538e91cfd82c2</ReactNativeWindowsCommitId>
|
|
19
19
|
</PropertyGroup>
|
|
20
20
|
</Project>
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
|
|
44
44
|
<PropertyGroup Label="ExternalDependencies">
|
|
45
45
|
<!-- Google Test Adapter -->
|
|
46
|
-
<!--
|
|
47
|
-
<Force-Enable-Microsoft-googletest-v140-windesktop-msvcstl-static-rt-dyn>
|
|
46
|
+
<!-- If ApplicationType is set, adapter include paths won't be set for MSVC 14.0 (v140) or later -->
|
|
47
|
+
<Force-Enable-Microsoft-googletest-v140-windesktop-msvcstl-static-rt-dyn>true</Force-Enable-Microsoft-googletest-v140-windesktop-msvcstl-static-rt-dyn>
|
|
48
48
|
</PropertyGroup>
|
|
49
49
|
|
|
50
50
|
<!--
|
|
@@ -136,7 +136,8 @@
|
|
|
136
136
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
137
137
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
|
138
138
|
<ShowIncludes Condition="'$(ShowIncludes)'=='true'">true</ShowIncludes>
|
|
139
|
-
<AdditionalOptions>/utf-8 %(AdditionalOptions)
|
|
139
|
+
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
|
140
|
+
<AdditionalOptions Condition="$(PlatformToolsetVersion)<145">%(AdditionalOptions) /await</AdditionalOptions>
|
|
140
141
|
<ControlFlowGuard>Guard</ControlFlowGuard>
|
|
141
142
|
<SpectreMitigation>Spectre</SpectreMitigation>
|
|
142
143
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
3
3
|
<PropertyGroup Label="WinUI3 versioning">
|
|
4
4
|
|
|
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
8
|
When this version is updated, be sure to update the default for the enableInternalFeed parameter of /.ado/templates/enable-experimental-winui3.yml
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<WinUI3ExperimentalVersion Condition="'$(WinUI3ExperimentalVersion)'==''">2.0.0-experimental3</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.8.
|
|
13
|
+
<WinUI3Version Condition="'$(WinUI3Version)'==''">1.8.260508005</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>
|