react-native-windows 0.81.2 → 0.81.4
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/Libraries/Components/Pressable/Pressable.d.ts +8 -0
- package/Libraries/Components/Pressable/Pressable.windows.js +21 -2
- package/Microsoft.ReactNative/ABIViewManager.cpp +12 -1
- package/Microsoft.ReactNative/CompositionSwitcher.idl +16 -9
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +26 -0
- package/Microsoft.ReactNative/Fabric/ComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.cpp +2 -5
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.h +1 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +15 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +65 -32
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +9 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +8 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.cpp +4 -7
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.h +1 -5
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.cpp +68 -53
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.h +1 -5
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +98 -15
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +10 -3
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +73 -10
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +11 -1
- package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +3 -2
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +609 -4
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +63 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +8 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +53 -2
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +8 -1
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +3 -1
- package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +6 -0
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +36 -14
- package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/ReactTaggedView.h +1 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.h +2 -1
- package/Microsoft.ReactNative/IReactViewComponentBuilder.idl +8 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -0
- package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +41 -15
- package/Microsoft.ReactNative/Utils/IcuUtils.cpp +84 -0
- package/Microsoft.ReactNative/Utils/IcuUtils.h +42 -0
- package/Microsoft.ReactNative.Cxx/StructInfo.h +8 -1
- package/Mso/src/dispatchQueue/queueService.cpp +3 -1
- package/Mso/src/dispatchQueue/uiScheduler_winrt.cpp +2 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Networking/OriginPolicyHttpFilter.cpp +2 -1
- package/Shared/Shared.vcxitems +1 -0
- package/Shared/Shared.vcxitems.filters +1 -0
- package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +14 -0
- package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +34 -20
- package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +14 -0
- package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +14 -0
- package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +18 -4
- package/codegen/react/components/rnwcore/AndroidSwitch.g.h +18 -4
- package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +14 -0
- package/codegen/react/components/rnwcore/InputAccessory.g.h +14 -0
- package/codegen/react/components/rnwcore/ModalHostView.g.h +32 -18
- package/codegen/react/components/rnwcore/PullToRefreshView.g.h +18 -4
- package/codegen/react/components/rnwcore/SafeAreaView.g.h +14 -0
- package/codegen/react/components/rnwcore/Switch.g.h +18 -4
- package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +14 -0
- package/codegen/react/components/rnwcore/VirtualView.g.h +48 -6
- package/package.json +3 -3
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#include <react/renderer/components/text/ParagraphProps.h>
|
|
13
13
|
#include <windows.ui.composition.interop.h>
|
|
14
14
|
#include <winrt/Windows.UI.Composition.h>
|
|
15
|
+
#include <chrono>
|
|
15
16
|
#include "CompositionHelpers.h"
|
|
16
17
|
#include "CompositionViewComponentView.h"
|
|
17
18
|
|
|
@@ -48,6 +49,33 @@ struct ParagraphComponentView : ParagraphComponentViewT<ParagraphComponentView,
|
|
|
48
49
|
static facebook::react::SharedViewProps defaultProps() noexcept;
|
|
49
50
|
const facebook::react::ParagraphProps ¶graphProps() const noexcept;
|
|
50
51
|
|
|
52
|
+
facebook::react::Tag hitTest(
|
|
53
|
+
facebook::react::Point pt,
|
|
54
|
+
facebook::react::Point &localPt,
|
|
55
|
+
bool ignorePointerEvents = false) const noexcept override;
|
|
56
|
+
|
|
57
|
+
// Returns true when text is selectable
|
|
58
|
+
bool focusable() const noexcept override;
|
|
59
|
+
|
|
60
|
+
// Returns I-beam cursor for selectable text
|
|
61
|
+
std::pair<facebook::react::Cursor, HCURSOR> cursor() const noexcept override;
|
|
62
|
+
|
|
63
|
+
// Called when losing focus, when another text starts selection, or when clicking outside text bounds.
|
|
64
|
+
void ClearSelection() noexcept;
|
|
65
|
+
|
|
66
|
+
// Text selection pointer event handlers
|
|
67
|
+
void OnPointerPressed(
|
|
68
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept override;
|
|
69
|
+
void OnPointerMoved(
|
|
70
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept override;
|
|
71
|
+
void OnPointerReleased(
|
|
72
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept override;
|
|
73
|
+
void OnPointerCaptureLost() noexcept override;
|
|
74
|
+
void onLostFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
|
|
75
|
+
|
|
76
|
+
// Keyboard event handler for copy
|
|
77
|
+
void OnKeyDown(const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
|
|
78
|
+
|
|
51
79
|
ParagraphComponentView(
|
|
52
80
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
53
81
|
facebook::react::Tag tag,
|
|
@@ -56,7 +84,29 @@ struct ParagraphComponentView : ParagraphComponentViewT<ParagraphComponentView,
|
|
|
56
84
|
private:
|
|
57
85
|
void updateVisualBrush() noexcept;
|
|
58
86
|
void DrawText() noexcept;
|
|
87
|
+
void DrawSelectionHighlight(
|
|
88
|
+
ID2D1RenderTarget &renderTarget,
|
|
89
|
+
float offsetX,
|
|
90
|
+
float offsetY,
|
|
91
|
+
float pointScaleFactor) noexcept;
|
|
59
92
|
void updateTextAlignment(const std::optional<facebook::react::TextAlignment> &fbAlignment) noexcept;
|
|
93
|
+
bool IsTextSelectableAtPoint(facebook::react::Point pt) noexcept;
|
|
94
|
+
std::optional<int32_t> GetTextPositionAtPoint(facebook::react::Point pt) noexcept;
|
|
95
|
+
std::optional<int32_t> GetClampedTextPosition(facebook::react::Point pt) noexcept;
|
|
96
|
+
std::string GetSelectedText() const noexcept;
|
|
97
|
+
|
|
98
|
+
// Copies currently selected text to the system clipboard
|
|
99
|
+
void CopySelectionToClipboard() noexcept;
|
|
100
|
+
|
|
101
|
+
// Selects the word at the given character position
|
|
102
|
+
void SelectWordAtPosition(int32_t charPosition) noexcept;
|
|
103
|
+
std::pair<int32_t, int32_t> GetWordBoundariesAtPosition(int32_t charPosition) noexcept;
|
|
104
|
+
|
|
105
|
+
// Shows a context menu with Copy/Select All options on right-click
|
|
106
|
+
void ShowContextMenu() noexcept;
|
|
107
|
+
|
|
108
|
+
// m_selectionStart <= m_selectionEnd
|
|
109
|
+
void SetSelection(int32_t start, int32_t end) noexcept;
|
|
60
110
|
|
|
61
111
|
winrt::com_ptr<::IDWriteTextLayout> m_textLayout;
|
|
62
112
|
facebook::react::AttributedStringBox m_attributedStringBox;
|
|
@@ -64,6 +114,19 @@ struct ParagraphComponentView : ParagraphComponentViewT<ParagraphComponentView,
|
|
|
64
114
|
|
|
65
115
|
bool m_requireRedraw{true};
|
|
66
116
|
winrt::Microsoft::ReactNative::Composition::Experimental::IDrawingSurfaceBrush m_drawingSurface;
|
|
117
|
+
|
|
118
|
+
std::optional<int32_t> m_selectionStart;
|
|
119
|
+
std::optional<int32_t> m_selectionEnd;
|
|
120
|
+
bool m_isSelecting{false};
|
|
121
|
+
|
|
122
|
+
// Double click + drag selection
|
|
123
|
+
bool m_isWordSelecting{false};
|
|
124
|
+
int32_t m_wordAnchorStart{0};
|
|
125
|
+
int32_t m_wordAnchorEnd{0};
|
|
126
|
+
|
|
127
|
+
// Double-click detection
|
|
128
|
+
std::chrono::steady_clock::time_point m_lastClickTime{};
|
|
129
|
+
std::optional<int32_t> m_lastClickPosition;
|
|
67
130
|
};
|
|
68
131
|
|
|
69
132
|
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -227,6 +227,14 @@ void ReactCompositionViewComponentBuilder::SetUnmountChildComponentViewHandler(
|
|
|
227
227
|
m_unmountChildComponentViewHandler = impl;
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
void ReactCompositionViewComponentBuilder::SetCreateAutomationPeerHandler(CreateAutomationPeerDelegate impl) noexcept {
|
|
231
|
+
m_createAutomationPeerHandler = impl;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const CreateAutomationPeerDelegate &ReactCompositionViewComponentBuilder::CreateAutomationPeerHandler() const noexcept {
|
|
235
|
+
return m_createAutomationPeerHandler;
|
|
236
|
+
}
|
|
237
|
+
|
|
230
238
|
const UnmountChildComponentViewDelegate &ReactCompositionViewComponentBuilder::UnmountChildComponentViewHandler()
|
|
231
239
|
const noexcept {
|
|
232
240
|
return m_unmountChildComponentViewHandler;
|
|
@@ -39,6 +39,7 @@ struct ReactCompositionViewComponentBuilder
|
|
|
39
39
|
void SetUpdateEventEmitterHandler(UpdateEventEmitterDelegate impl) noexcept;
|
|
40
40
|
void SetMountChildComponentViewHandler(MountChildComponentViewDelegate impl) noexcept;
|
|
41
41
|
void SetUnmountChildComponentViewHandler(UnmountChildComponentViewDelegate impl) noexcept;
|
|
42
|
+
void SetCreateAutomationPeerHandler(CreateAutomationPeerDelegate impl) noexcept;
|
|
42
43
|
|
|
43
44
|
public: // Composition::IReactCompositionViewComponentBuilder
|
|
44
45
|
void SetViewComponentViewInitializer(const ViewComponentViewInitializer &initializer) noexcept;
|
|
@@ -77,6 +78,7 @@ struct ReactCompositionViewComponentBuilder
|
|
|
77
78
|
const CreateVisualDelegate &CreateVisualHandler() const noexcept;
|
|
78
79
|
const winrt::Microsoft::ReactNative::Composition::Experimental::IVisualToMountChildrenIntoDelegate &
|
|
79
80
|
VisualToMountChildrenIntoHandler() const noexcept;
|
|
81
|
+
const CreateAutomationPeerDelegate &CreateAutomationPeerHandler() const noexcept;
|
|
80
82
|
|
|
81
83
|
private:
|
|
82
84
|
void InitializeComponentView(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
@@ -103,6 +105,7 @@ struct ReactCompositionViewComponentBuilder
|
|
|
103
105
|
winrt::Microsoft::ReactNative::UpdateEventEmitterDelegate m_updateEventEmitterHandler;
|
|
104
106
|
winrt::Microsoft::ReactNative::MountChildComponentViewDelegate m_mountChildComponentViewHandler;
|
|
105
107
|
winrt::Microsoft::ReactNative::UnmountChildComponentViewDelegate m_unmountChildComponentViewHandler;
|
|
108
|
+
winrt::Microsoft::ReactNative::CreateAutomationPeerDelegate m_createAutomationPeerHandler;
|
|
106
109
|
|
|
107
110
|
winrt::Microsoft::ReactNative::Composition::CreateVisualDelegate m_createVisualHandler;
|
|
108
111
|
winrt::Microsoft::ReactNative::Composition::Experimental::IVisualToMountChildrenIntoDelegate
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
#include <Fabric/FabricUIManagerModule.h>
|
|
10
10
|
#include <winrt/Microsoft.UI.Input.h>
|
|
11
|
+
#include "CompositionDynamicAutomationProvider.h"
|
|
11
12
|
#include "CompositionRootAutomationProvider.h"
|
|
13
|
+
#include "ContentIslandComponentView.h"
|
|
14
|
+
#include "ParagraphComponentView.h"
|
|
12
15
|
#include "ReactNativeIsland.h"
|
|
13
16
|
#include "Theme.h"
|
|
14
17
|
|
|
@@ -275,7 +278,7 @@ facebook::react::Point RootComponentView::getClientOffset() const noexcept {
|
|
|
275
278
|
return {};
|
|
276
279
|
}
|
|
277
280
|
|
|
278
|
-
winrt::
|
|
281
|
+
winrt::IUnknown RootComponentView::UiaProviderFromPoint(const POINT &ptPixels, const POINT &ptScreen) noexcept {
|
|
279
282
|
facebook::react::Point ptDips{
|
|
280
283
|
static_cast<facebook::react::Float>(ptPixels.x) / m_layoutMetrics.pointScaleFactor,
|
|
281
284
|
static_cast<facebook::react::Float>(ptPixels.y) / m_layoutMetrics.pointScaleFactor};
|
|
@@ -295,7 +298,41 @@ winrt::IInspectable RootComponentView::UiaProviderFromPoint(const POINT &ptPixel
|
|
|
295
298
|
if (view == nullptr)
|
|
296
299
|
return nullptr;
|
|
297
300
|
|
|
298
|
-
|
|
301
|
+
auto uiaProvider =
|
|
302
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view)->EnsureUiaProvider();
|
|
303
|
+
|
|
304
|
+
if (auto contentIsland =
|
|
305
|
+
view.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ContentIslandComponentView>()) {
|
|
306
|
+
if (contentIsland->InnerAutomationProvider()) {
|
|
307
|
+
if (auto childProvider = contentIsland->InnerAutomationProvider()->TryGetChildSiteLinkAutomationProvider()) {
|
|
308
|
+
// ChildProvider is the the automation provider from the ChildSiteLink. In the case of WinUI, this
|
|
309
|
+
// is a pointer to WinUI's internal CUIAHostWindow object.
|
|
310
|
+
// It seems odd, but even though this node doesn't behave as a fragment root in our case (the real fragment root
|
|
311
|
+
// is the RootComponentView's UIA provider), we still use its IRawElementProviderFragmentRoot -- just so
|
|
312
|
+
// we can do the ElementProviderFromPoint call. (this was recommended by the team who did the initial
|
|
313
|
+
// architecture work).
|
|
314
|
+
if (auto fragmentRoot = childProvider.try_as<IRawElementProviderFragmentRoot>()) {
|
|
315
|
+
com_ptr<IRawElementProviderFragment> frag;
|
|
316
|
+
// WinUI then does its own hitTest inside the XAML tree.
|
|
317
|
+
fragmentRoot->ElementProviderFromPoint(
|
|
318
|
+
ptScreen
|
|
319
|
+
.x, // Note since we're going through IRawElementProviderFragment the coordinates are in screen space.
|
|
320
|
+
ptScreen.y,
|
|
321
|
+
frag.put());
|
|
322
|
+
// We return the specific child provider(frag) when hosted XAML has an element
|
|
323
|
+
// under the cursor. This satisfies the UIA "element at point" contract and exposes
|
|
324
|
+
// the control’s patterns/properties. If the hosted tree finds nothing, we fall back
|
|
325
|
+
// to the RNW container’s provider (uiaProvider) to keep the island accessible.
|
|
326
|
+
// (A Microsoft_UI_Xaml!CUIAWrapper object)
|
|
327
|
+
if (frag) {
|
|
328
|
+
return frag.as<winrt::IUnknown>();
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return uiaProvider;
|
|
299
336
|
}
|
|
300
337
|
|
|
301
338
|
float RootComponentView::FontSizeMultiplier() const noexcept {
|
|
@@ -349,4 +386,18 @@ HWND RootComponentView::GetHwndForParenting() noexcept {
|
|
|
349
386
|
return base_type::GetHwndForParenting();
|
|
350
387
|
}
|
|
351
388
|
|
|
389
|
+
void RootComponentView::ClearCurrentTextSelection() noexcept {
|
|
390
|
+
if (auto view = m_viewWithTextSelection.view()) {
|
|
391
|
+
if (auto paragraphView = view.try_as<ParagraphComponentView>()) {
|
|
392
|
+
paragraphView->ClearSelection();
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
m_viewWithTextSelection =
|
|
396
|
+
::Microsoft::ReactNative::ReactTaggedView{winrt::Microsoft::ReactNative::ComponentView{nullptr}};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
void RootComponentView::SetViewWithTextSelection(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
|
|
400
|
+
m_viewWithTextSelection = ::Microsoft::ReactNative::ReactTaggedView{view};
|
|
401
|
+
}
|
|
402
|
+
|
|
352
403
|
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#pragma once
|
|
6
6
|
|
|
7
7
|
#include <Fabric/ComponentView.h>
|
|
8
|
+
#include <Fabric/ReactTaggedView.h>
|
|
8
9
|
#include <Microsoft.ReactNative.Cxx/ReactContext.h>
|
|
9
10
|
|
|
10
11
|
#include "CompositionViewComponentView.h"
|
|
@@ -64,7 +65,7 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
|
|
|
64
65
|
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
65
66
|
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
|
|
66
67
|
|
|
67
|
-
winrt::Windows::Foundation::
|
|
68
|
+
winrt::Windows::Foundation::IUnknown UiaProviderFromPoint(const POINT &ptPixels, const POINT &ptScreen) noexcept;
|
|
68
69
|
|
|
69
70
|
RootComponentView(
|
|
70
71
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
@@ -86,6 +87,9 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
|
|
|
86
87
|
|
|
87
88
|
HWND GetHwndForParenting() noexcept override;
|
|
88
89
|
|
|
90
|
+
void ClearCurrentTextSelection() noexcept;
|
|
91
|
+
void SetViewWithTextSelection(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
92
|
+
|
|
89
93
|
private:
|
|
90
94
|
// should this be a ReactTaggedView? - It shouldn't actually matter since if the view is going away it should always
|
|
91
95
|
// be clearing its focus But being a reactTaggedView might make it easier to identify cases where that isn't
|
|
@@ -94,6 +98,9 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
|
|
|
94
98
|
winrt::weak_ref<winrt::Microsoft::ReactNative::ReactNativeIsland> m_wkRootView{nullptr};
|
|
95
99
|
winrt::weak_ref<winrt::Microsoft::ReactNative::Composition::PortalComponentView> m_wkPortal{nullptr};
|
|
96
100
|
bool m_visualAddedToIsland{false};
|
|
101
|
+
|
|
102
|
+
::Microsoft::ReactNative::ReactTaggedView m_viewWithTextSelection{
|
|
103
|
+
winrt::Microsoft::ReactNative::ComponentView{nullptr}};
|
|
97
104
|
};
|
|
98
105
|
|
|
99
106
|
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
#include "WindowsTextInputComponentView.h"
|
|
7
7
|
|
|
8
8
|
#include <AutoDraw.h>
|
|
9
|
-
#include <Fabric/Composition/CompositionDynamicAutomationProvider.h>
|
|
10
9
|
#include <Fabric/Composition/UiaHelpers.h>
|
|
11
10
|
#include <Fabric/platform/react/renderer/graphics/PlatformColorUtils.h>
|
|
12
11
|
#include <Utils/ThemeUtils.h>
|
|
@@ -1782,6 +1781,9 @@ WindowsTextInputComponentView::createVisual() noexcept {
|
|
|
1782
1781
|
LRESULT res;
|
|
1783
1782
|
winrt::check_hresult(m_textServices->TxSendMessage(EM_SETTEXTMODE, TM_PLAINTEXT, 0, &res));
|
|
1784
1783
|
|
|
1784
|
+
// Enable TSF support
|
|
1785
|
+
winrt::check_hresult(m_textServices->TxSendMessage(EM_SETEDITSTYLE, SES_USECTF, SES_USECTF, nullptr));
|
|
1786
|
+
|
|
1785
1787
|
m_caretVisual = m_compContext.CreateCaretVisual();
|
|
1786
1788
|
visual.InsertAt(m_caretVisual.InnerVisual(), 0);
|
|
1787
1789
|
m_caretVisual.IsVisible(false);
|
|
@@ -174,6 +174,12 @@ bool Theme::TryGetPlatformColor(const std::string &platformColor, winrt::Windows
|
|
|
174
174
|
return true;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
if (platformColor == "Highlight@40" && TryGetPlatformColor("Highlight", color)) {
|
|
178
|
+
color.A = static_cast<uint8_t>(static_cast<float>(color.A) * 0.4f);
|
|
179
|
+
m_colorCache[platformColor] = std::make_pair(true, color);
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
|
|
177
183
|
auto uiColor = s_uiColorTypes.find(platformColor);
|
|
178
184
|
if (uiColor != s_uiColorTypes.end()) {
|
|
179
185
|
auto uiSettings{winrt::Windows::UI::ViewManagement::UISettings()};
|
|
@@ -267,7 +267,7 @@ void TooltipTracker::ShowTooltip(const winrt::Microsoft::ReactNative::ComponentV
|
|
|
267
267
|
static_cast<int>((tm.width + tooltipHorizontalPadding + tooltipHorizontalPadding) * scaleFactor);
|
|
268
268
|
tooltipData->height = static_cast<int>((tm.height + tooltipTopPadding + tooltipBottomPadding) * scaleFactor);
|
|
269
269
|
|
|
270
|
-
POINT pt = {static_cast<LONG>(m_pos.X), static_cast<LONG>(m_pos.Y)};
|
|
270
|
+
POINT pt = {static_cast<LONG>(m_pos.X * scaleFactor), static_cast<LONG>(m_pos.Y * scaleFactor)};
|
|
271
271
|
ClientToScreen(parentHwnd, &pt);
|
|
272
272
|
|
|
273
273
|
RegisterTooltipWndClass();
|
|
@@ -48,7 +48,8 @@ HRESULT UiaNavigateHelper(
|
|
|
48
48
|
uint32_t index = children.Size() - 1;
|
|
49
49
|
do {
|
|
50
50
|
auto child = children.GetAt(index).as<winrt::Microsoft::ReactNative::implementation::ComponentView>();
|
|
51
|
-
|
|
51
|
+
uiaProvider = child->EnsureUiaProvider();
|
|
52
|
+
if (uiaProvider) {
|
|
52
53
|
break;
|
|
53
54
|
}
|
|
54
55
|
} while (index-- != 0);
|
|
@@ -60,7 +61,8 @@ HRESULT UiaNavigateHelper(
|
|
|
60
61
|
uint32_t index = 0;
|
|
61
62
|
do {
|
|
62
63
|
auto child = children.GetAt(index).as<winrt::Microsoft::ReactNative::implementation::ComponentView>();
|
|
63
|
-
|
|
64
|
+
uiaProvider = child->EnsureUiaProvider();
|
|
65
|
+
if (uiaProvider) {
|
|
64
66
|
break;
|
|
65
67
|
}
|
|
66
68
|
} while (++index != children.Size());
|
|
@@ -74,7 +76,8 @@ HRESULT UiaNavigateHelper(
|
|
|
74
76
|
|
|
75
77
|
while (++it != children.end()) {
|
|
76
78
|
auto nextchild = (*it).as<winrt::Microsoft::ReactNative::implementation::ComponentView>();
|
|
77
|
-
|
|
79
|
+
uiaProvider = nextchild->EnsureUiaProvider();
|
|
80
|
+
if (uiaProvider) {
|
|
78
81
|
break;
|
|
79
82
|
}
|
|
80
83
|
}
|
|
@@ -91,7 +94,8 @@ HRESULT UiaNavigateHelper(
|
|
|
91
94
|
do {
|
|
92
95
|
it--;
|
|
93
96
|
auto prevchild = (*it).as<winrt::Microsoft::ReactNative::implementation::ComponentView>();
|
|
94
|
-
|
|
97
|
+
uiaProvider = prevchild->EnsureUiaProvider();
|
|
98
|
+
if (uiaProvider) {
|
|
95
99
|
break;
|
|
96
100
|
}
|
|
97
101
|
} while (it != children.begin());
|
|
@@ -513,27 +517,45 @@ ExpandCollapseState GetExpandCollapseState(const bool &expanded) noexcept {
|
|
|
513
517
|
}
|
|
514
518
|
|
|
515
519
|
void AddSelectionItemsToContainer(CompositionDynamicAutomationProvider *provider) noexcept {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
if (!selectionContainer)
|
|
520
|
+
auto selectionContainerView = provider->GetSelectionContainer();
|
|
521
|
+
if (!selectionContainerView)
|
|
519
522
|
return;
|
|
520
|
-
|
|
523
|
+
|
|
524
|
+
auto selectionContainerCompView =
|
|
525
|
+
selectionContainerView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ComponentView>();
|
|
526
|
+
if (!selectionContainerCompView)
|
|
527
|
+
return;
|
|
528
|
+
|
|
529
|
+
selectionContainerCompView->EnsureUiaProvider();
|
|
530
|
+
|
|
531
|
+
if (!selectionContainerCompView->InnerAutomationProvider())
|
|
532
|
+
return;
|
|
533
|
+
|
|
521
534
|
auto simpleProvider = static_cast<IRawElementProviderSimple *>(provider);
|
|
522
535
|
winrt::com_ptr<IRawElementProviderSimple> simpleProviderPtr;
|
|
523
536
|
simpleProviderPtr.copy_from(simpleProvider);
|
|
524
|
-
|
|
537
|
+
selectionContainerCompView->InnerAutomationProvider()->AddToSelectionItems(simpleProviderPtr);
|
|
525
538
|
}
|
|
526
539
|
|
|
527
540
|
void RemoveSelectionItemsFromContainer(CompositionDynamicAutomationProvider *provider) noexcept {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (!selectionContainer)
|
|
541
|
+
auto selectionContainerView = provider->GetSelectionContainer();
|
|
542
|
+
if (!selectionContainerView)
|
|
531
543
|
return;
|
|
532
|
-
|
|
544
|
+
|
|
545
|
+
auto selectionContainerCompView =
|
|
546
|
+
selectionContainerView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ComponentView>();
|
|
547
|
+
if (!selectionContainerCompView)
|
|
548
|
+
return;
|
|
549
|
+
|
|
550
|
+
selectionContainerCompView->EnsureUiaProvider();
|
|
551
|
+
|
|
552
|
+
if (!selectionContainerCompView->InnerAutomationProvider())
|
|
553
|
+
return;
|
|
554
|
+
|
|
533
555
|
auto simpleProvider = static_cast<IRawElementProviderSimple *>(provider);
|
|
534
556
|
winrt::com_ptr<IRawElementProviderSimple> simpleProviderPtr;
|
|
535
557
|
simpleProviderPtr.copy_from(simpleProvider);
|
|
536
|
-
|
|
558
|
+
selectionContainerCompView->InnerAutomationProvider()->RemoveFromSelectionItems(simpleProviderPtr);
|
|
537
559
|
}
|
|
538
560
|
|
|
539
561
|
ToggleState GetToggleState(const std::optional<facebook::react::AccessibilityState> &state) noexcept {
|
|
@@ -16,7 +16,7 @@ namespace Microsoft::ReactNative {
|
|
|
16
16
|
*/
|
|
17
17
|
struct ReactTaggedView {
|
|
18
18
|
ReactTaggedView(const winrt::Microsoft::ReactNative::ComponentView &componentView)
|
|
19
|
-
: m_view(componentView), m_tag(componentView.Tag()) {}
|
|
19
|
+
: m_view(componentView), m_tag(componentView ? componentView.Tag() : -1) {}
|
|
20
20
|
|
|
21
21
|
winrt::Microsoft::ReactNative::ComponentView view() noexcept {
|
|
22
22
|
if (!m_view) {
|
|
@@ -56,8 +56,9 @@ class WindowsTextLayoutManager : public TextLayoutManager {
|
|
|
56
56
|
TextMeasurement::Attachments &attachments,
|
|
57
57
|
float minimumFontScale) noexcept;
|
|
58
58
|
|
|
59
|
-
private:
|
|
60
59
|
static winrt::hstring GetTransformedText(const AttributedStringBox &attributedStringBox);
|
|
60
|
+
|
|
61
|
+
private:
|
|
61
62
|
static void GetTextLayout(
|
|
62
63
|
const AttributedStringBox &attributedStringBox,
|
|
63
64
|
const ParagraphAttributes ¶graphAttributes,
|
|
@@ -54,6 +54,10 @@ namespace Microsoft.ReactNative
|
|
|
54
54
|
Boolean Handled;
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
+
runtimeclass CreateAutomationPeerArgs {
|
|
58
|
+
Object DefaultAutomationPeer { get; };
|
|
59
|
+
};
|
|
60
|
+
|
|
57
61
|
[experimental]
|
|
58
62
|
DOC_STRING("A delegate that creates a @IComponentProps object for an instance of @ViewProps. See @IReactViewComponentBuilder.SetCreateProps")
|
|
59
63
|
delegate IComponentProps ViewPropsFactory(ViewProps props, IComponentProps cloneFrom);
|
|
@@ -95,6 +99,9 @@ namespace Microsoft.ReactNative
|
|
|
95
99
|
[experimental]
|
|
96
100
|
delegate void UnmountChildComponentViewDelegate(ComponentView source, UnmountChildComponentViewArgs args);
|
|
97
101
|
|
|
102
|
+
[experimental]
|
|
103
|
+
delegate Object CreateAutomationPeerDelegate(ComponentView source, CreateAutomationPeerArgs args);
|
|
104
|
+
|
|
98
105
|
[experimental]
|
|
99
106
|
runtimeclass EventEmitter {
|
|
100
107
|
void DispatchEvent(String eventName, JSValueArgWriter args);
|
|
@@ -124,6 +131,7 @@ namespace Microsoft.ReactNative
|
|
|
124
131
|
void SetUpdateEventEmitterHandler(UpdateEventEmitterDelegate impl);
|
|
125
132
|
void SetMountChildComponentViewHandler(MountChildComponentViewDelegate impl);
|
|
126
133
|
void SetUnmountChildComponentViewHandler(UnmountChildComponentViewDelegate impl);
|
|
134
|
+
void SetCreateAutomationPeerHandler(CreateAutomationPeerDelegate impl);
|
|
127
135
|
};
|
|
128
136
|
|
|
129
137
|
// [exclusiveto(ShadowNode)]
|
|
@@ -313,6 +313,7 @@
|
|
|
313
313
|
<ClInclude Include="Utils\TransformableText.h" />
|
|
314
314
|
<ClInclude Include="Utils\UwpPreparedScriptStore.h" />
|
|
315
315
|
<ClInclude Include="Utils\UwpScriptStore.h" />
|
|
316
|
+
<ClInclude Include="Utils\IcuUtils.h" />
|
|
316
317
|
<ClInclude Include="Utils\ValueUtils.h" />
|
|
317
318
|
<ClInclude Include="Utils\XamlIslandUtils.h" />
|
|
318
319
|
<ClInclude Include="Utils\XamlUtils.h" />
|
|
@@ -30,20 +30,33 @@ using namespace xaml::Media::Imaging;
|
|
|
30
30
|
|
|
31
31
|
namespace Microsoft::ReactNative {
|
|
32
32
|
|
|
33
|
+
static const char *ERROR_INVALID_URI = "E_INVALID_URI";
|
|
34
|
+
static const char *ERROR_GET_SIZE_FAILURE = "E_GET_SIZE_FAILURE";
|
|
35
|
+
|
|
33
36
|
winrt::fire_and_forget GetImageSizeAsync(
|
|
34
37
|
const winrt::Microsoft::ReactNative::IReactPropertyBag &properties,
|
|
35
38
|
std::string uriString,
|
|
36
39
|
winrt::Microsoft::ReactNative::JSValue &&headers,
|
|
37
40
|
Mso::Functor<void(int32_t width, int32_t height)> successCallback,
|
|
38
|
-
Mso::Functor<void()> errorCallback
|
|
41
|
+
Mso::Functor<void(const char *errorCode, std::string errorMessage)> errorCallback
|
|
39
42
|
#ifdef USE_FABRIC
|
|
40
43
|
,
|
|
41
44
|
bool useFabric
|
|
42
45
|
#endif // USE_FABRIC
|
|
43
46
|
) {
|
|
44
47
|
bool succeeded{false};
|
|
48
|
+
const char *errorCode = ERROR_GET_SIZE_FAILURE;
|
|
49
|
+
std::string errorMessage;
|
|
45
50
|
|
|
46
51
|
try {
|
|
52
|
+
// Validate URI is not empty
|
|
53
|
+
if (uriString.empty()) {
|
|
54
|
+
errorCode = ERROR_INVALID_URI;
|
|
55
|
+
errorMessage = "Cannot get the size of an image for an empty URI";
|
|
56
|
+
errorCallback(errorCode, errorMessage);
|
|
57
|
+
co_return;
|
|
58
|
+
}
|
|
59
|
+
|
|
47
60
|
ReactImageSource source;
|
|
48
61
|
source.uri = uriString;
|
|
49
62
|
if (!headers.IsNull()) {
|
|
@@ -56,9 +69,10 @@ winrt::fire_and_forget GetImageSizeAsync(
|
|
|
56
69
|
winrt::hstring scheme{uri.SchemeName()};
|
|
57
70
|
bool needsDownload = (scheme == L"http") || (scheme == L"https");
|
|
58
71
|
bool inlineData = scheme == L"data";
|
|
72
|
+
bool isLocalFile = (scheme == L"file") || (scheme == L"ms-appx") || (scheme == L"ms-appdata");
|
|
59
73
|
|
|
60
74
|
winrt::IRandomAccessStream memoryStream;
|
|
61
|
-
if (needsDownload) {
|
|
75
|
+
if (needsDownload || isLocalFile) {
|
|
62
76
|
memoryStream = co_await GetImageStreamAsync(properties, source);
|
|
63
77
|
} else if (inlineData) {
|
|
64
78
|
memoryStream = co_await GetImageInlineDataAsync(source);
|
|
@@ -77,23 +91,31 @@ winrt::fire_and_forget GetImageSizeAsync(
|
|
|
77
91
|
}
|
|
78
92
|
#ifdef USE_FABRIC
|
|
79
93
|
} else {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
if (memoryStream) { // Added nullcheck to prevent app from crashing if value is uninitialized
|
|
95
|
+
auto result = wicBitmapSourceFromStream(memoryStream);
|
|
96
|
+
if (!std::get<std::shared_ptr<facebook::react::ImageErrorInfo>>(result)) {
|
|
97
|
+
auto imagingFactory = std::get<winrt::com_ptr<IWICImagingFactory>>(result);
|
|
98
|
+
auto wicBmpSource = std::get<winrt::com_ptr<IWICBitmapSource>>(result);
|
|
99
|
+
UINT width, height;
|
|
100
|
+
if (SUCCEEDED(wicBmpSource->GetSize(&width, &height))) {
|
|
101
|
+
successCallback(width, height);
|
|
102
|
+
succeeded = true;
|
|
103
|
+
}
|
|
88
104
|
}
|
|
89
105
|
}
|
|
90
106
|
}
|
|
91
107
|
#endif // USE_FABRIC
|
|
92
|
-
} catch (winrt::hresult_error const &) {
|
|
108
|
+
} catch (winrt::hresult_error const &e) {
|
|
109
|
+
errorMessage = "Failed to get image size: " + Microsoft::Common::Unicode::Utf16ToUtf8(std::wstring(e.message())) +
|
|
110
|
+
" for URI: " + uriString;
|
|
93
111
|
}
|
|
94
112
|
|
|
95
|
-
if (!succeeded)
|
|
96
|
-
|
|
113
|
+
if (!succeeded) {
|
|
114
|
+
if (errorMessage.empty()) {
|
|
115
|
+
errorMessage = "Failed to get image size for URI: " + uriString;
|
|
116
|
+
}
|
|
117
|
+
errorCallback(errorCode, errorMessage);
|
|
118
|
+
}
|
|
97
119
|
|
|
98
120
|
co_return;
|
|
99
121
|
}
|
|
@@ -112,7 +134,9 @@ void ImageLoader::getSize(std::string uri, React::ReactPromise<std::vector<doubl
|
|
|
112
134
|
[result](double width, double height) noexcept {
|
|
113
135
|
result.Resolve(std::vector<double>{width, height});
|
|
114
136
|
},
|
|
115
|
-
[result]() noexcept {
|
|
137
|
+
[result](const char *errorCode, std::string errorMessage) noexcept {
|
|
138
|
+
result.Reject(React::ReactError{errorCode, errorMessage});
|
|
139
|
+
}
|
|
116
140
|
#ifdef USE_FABRIC
|
|
117
141
|
,
|
|
118
142
|
IsFabricEnabled(context.Properties().Handle())
|
|
@@ -137,7 +161,9 @@ void ImageLoader::getSizeWithHeaders(
|
|
|
137
161
|
[result](double width, double height) noexcept {
|
|
138
162
|
result.Resolve(Microsoft::ReactNativeSpecs::ImageLoaderIOSSpec_getSizeWithHeaders_returnType{width, height});
|
|
139
163
|
},
|
|
140
|
-
[result]() noexcept {
|
|
164
|
+
[result](const char *errorCode, std::string errorMessage) noexcept {
|
|
165
|
+
result.Reject(React::ReactError{errorCode, errorMessage});
|
|
166
|
+
}
|
|
141
167
|
#ifdef USE_FABRIC
|
|
142
168
|
,
|
|
143
169
|
IsFabricEnabled(context.Properties().Handle())
|