react-native-windows 0.77.3 → 0.77.5
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/Button.windows.js +3 -0
- package/Libraries/Components/Pressable/Pressable.windows.js +3 -0
- package/Libraries/Components/ScrollView/ScrollView.windows.js +1920 -0
- package/Libraries/Components/TextInput/TextInput.windows.js +3 -0
- package/Libraries/Components/Touchable/TouchableBounce.windows.js +2 -0
- package/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js +2 -0
- package/Libraries/Components/Touchable/TouchableOpacity.windows.js +2 -0
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +2 -0
- package/Libraries/Components/View/View.windows.js +3 -0
- package/Libraries/Components/View/ViewAccessibility.d.ts +7 -2
- package/Libraries/Components/View/ViewAccessibility.windows.js +1 -0
- package/Libraries/Components/View/ViewPropTypes.windows.js +1 -0
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Core/setUpDeveloperTools.js +2 -3
- package/Libraries/Image/Image.windows.js +2 -0
- package/Libraries/Text/Text.windows.js +4 -0
- package/Libraries/Text/TextProps.windows.js +1 -0
- package/Libraries/Utilities/HMRClient.js +0 -28
- package/Libraries/Utilities/HMRClientProdShim.js +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +374 -21
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +21 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.cpp +115 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.h +41 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.cpp +298 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.h +59 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +1 -2
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +24 -2
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +5 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +14 -10
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +3 -2
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h +1 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h +4 -0
- package/Shared/Networking/WinRTWebSocketResource.cpp +369 -7
- package/Shared/Networking/WinRTWebSocketResource.h +118 -0
- package/Shared/Shared.vcxitems +6 -0
- package/Shared/Shared.vcxitems.filters +8 -0
- package/package.json +9 -9
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#include "pch.h"
|
|
2
2
|
#include "CompositionDynamicAutomationProvider.h"
|
|
3
3
|
#include <Fabric/ComponentView.h>
|
|
4
|
+
#include <Fabric/Composition/CompositionTextRangeProvider.h>
|
|
5
|
+
#include <Fabric/Composition/ParagraphComponentView.h>
|
|
6
|
+
#include <Fabric/Composition/ScrollViewComponentView.h>
|
|
4
7
|
#include <Fabric/Composition/SwitchComponentView.h>
|
|
5
8
|
#include <Fabric/Composition/TextInput/WindowsTextInputComponentView.h>
|
|
6
9
|
#include <Unicode.h>
|
|
@@ -25,6 +28,13 @@ CompositionDynamicAutomationProvider::CompositionDynamicAutomationProvider(
|
|
|
25
28
|
if (props->accessibilityState.has_value() && props->accessibilityState->selected.has_value()) {
|
|
26
29
|
AddSelectionItemsToContainer(this);
|
|
27
30
|
}
|
|
31
|
+
|
|
32
|
+
if (strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() ||
|
|
33
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>()) {
|
|
34
|
+
m_textProvider = winrt::make<CompositionTextProvider>(
|
|
35
|
+
strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>(), this)
|
|
36
|
+
.try_as<ITextProvider2>();
|
|
37
|
+
}
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
HRESULT __stdcall CompositionDynamicAutomationProvider::Navigate(
|
|
@@ -141,8 +151,12 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_ProviderOptions(Prov
|
|
|
141
151
|
return S_OK;
|
|
142
152
|
}
|
|
143
153
|
|
|
144
|
-
bool
|
|
145
|
-
return
|
|
154
|
+
bool accessibilityValueHasTextValue(const facebook::react::AccessibilityValue &value) {
|
|
155
|
+
return value.text.has_value();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
bool accessibilityValueHasNumericValue(const facebook::react::AccessibilityValue &value) {
|
|
159
|
+
return (value.min.has_value() && value.max.has_value() && value.now.has_value());
|
|
146
160
|
}
|
|
147
161
|
|
|
148
162
|
bool expandableControl(const facebook::react::SharedViewProps props) {
|
|
@@ -202,9 +216,22 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
|
|
|
202
216
|
AddRef();
|
|
203
217
|
}
|
|
204
218
|
|
|
219
|
+
if (patternId == UIA_ScrollPatternId &&
|
|
220
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>()) {
|
|
221
|
+
*pRetVal = static_cast<IScrollProvider *>(this);
|
|
222
|
+
AddRef();
|
|
223
|
+
}
|
|
224
|
+
|
|
205
225
|
if (patternId == UIA_ValuePatternId &&
|
|
206
|
-
(strongView
|
|
207
|
-
|
|
226
|
+
((strongView
|
|
227
|
+
.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() &&
|
|
228
|
+
!accessibilityValueHasNumericValue(props->accessibilityValue)) ||
|
|
229
|
+
accessibilityValueHasTextValue(props->accessibilityValue))) {
|
|
230
|
+
*pRetVal = static_cast<IValueProvider *>(this);
|
|
231
|
+
AddRef();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (patternId == UIA_RangeValuePatternId && accessibilityValueHasNumericValue(props->accessibilityValue)) {
|
|
208
235
|
*pRetVal = static_cast<IValueProvider *>(this);
|
|
209
236
|
AddRef();
|
|
210
237
|
}
|
|
@@ -233,10 +260,21 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
|
|
|
233
260
|
AddRef();
|
|
234
261
|
}
|
|
235
262
|
|
|
263
|
+
if (patternId == UIA_TextPatternId &&
|
|
264
|
+
(strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() ||
|
|
265
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>())) {
|
|
266
|
+
m_textProvider.as<IUnknown>().copy_to(pRetVal);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (patternId == UIA_TextPattern2Id &&
|
|
270
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>()) {
|
|
271
|
+
m_textProvider.as<IUnknown>().copy_to(pRetVal);
|
|
272
|
+
}
|
|
273
|
+
|
|
236
274
|
return S_OK;
|
|
237
275
|
}
|
|
238
276
|
|
|
239
|
-
long
|
|
277
|
+
long GetControlTypeFromString(const std::string &role) noexcept {
|
|
240
278
|
if (role == "adjustable") {
|
|
241
279
|
return UIA_SliderControlTypeId;
|
|
242
280
|
} else if (role == "group" || role == "search" || role == "radiogroup" || role == "timer" || role.empty()) {
|
|
@@ -294,11 +332,103 @@ long GetControlType(const std::string &role) noexcept {
|
|
|
294
332
|
return UIA_TreeControlTypeId;
|
|
295
333
|
} else if (role == "treeitem") {
|
|
296
334
|
return UIA_TreeItemControlTypeId;
|
|
335
|
+
} else if (role == "pane") {
|
|
336
|
+
return UIA_PaneControlTypeId;
|
|
297
337
|
}
|
|
298
338
|
assert(false);
|
|
299
339
|
return UIA_GroupControlTypeId;
|
|
300
340
|
}
|
|
301
341
|
|
|
342
|
+
long GetControlTypeFromRole(const facebook::react::Role &role) noexcept {
|
|
343
|
+
switch (role) {
|
|
344
|
+
case facebook::react::Role::Alert:
|
|
345
|
+
return UIA_TextControlTypeId;
|
|
346
|
+
case facebook::react::Role::Application:
|
|
347
|
+
return UIA_WindowControlTypeId;
|
|
348
|
+
case facebook::react::Role::Button:
|
|
349
|
+
return UIA_ButtonControlTypeId;
|
|
350
|
+
case facebook::react::Role::Checkbox:
|
|
351
|
+
return UIA_CheckBoxControlTypeId;
|
|
352
|
+
case facebook::react::Role::Columnheader:
|
|
353
|
+
return UIA_HeaderControlTypeId;
|
|
354
|
+
case facebook::react::Role::Combobox:
|
|
355
|
+
return UIA_ComboBoxControlTypeId;
|
|
356
|
+
case facebook::react::Role::Document:
|
|
357
|
+
return UIA_DocumentControlTypeId;
|
|
358
|
+
case facebook::react::Role::Grid:
|
|
359
|
+
return UIA_GroupControlTypeId;
|
|
360
|
+
case facebook::react::Role::Group:
|
|
361
|
+
return UIA_GroupControlTypeId;
|
|
362
|
+
case facebook::react::Role::Heading:
|
|
363
|
+
return UIA_TextControlTypeId;
|
|
364
|
+
case facebook::react::Role::Img:
|
|
365
|
+
return UIA_ImageControlTypeId;
|
|
366
|
+
case facebook::react::Role::Link:
|
|
367
|
+
return UIA_HyperlinkControlTypeId;
|
|
368
|
+
case facebook::react::Role::List:
|
|
369
|
+
return UIA_ListControlTypeId;
|
|
370
|
+
case facebook::react::Role::Listitem:
|
|
371
|
+
return UIA_ListItemControlTypeId;
|
|
372
|
+
case facebook::react::Role::Menu:
|
|
373
|
+
return UIA_MenuControlTypeId;
|
|
374
|
+
case facebook::react::Role::Menubar:
|
|
375
|
+
return UIA_MenuBarControlTypeId;
|
|
376
|
+
case facebook::react::Role::Menuitem:
|
|
377
|
+
return UIA_MenuItemControlTypeId;
|
|
378
|
+
case facebook::react::Role::None:
|
|
379
|
+
return UIA_GroupControlTypeId;
|
|
380
|
+
case facebook::react::Role::Presentation:
|
|
381
|
+
return UIA_GroupControlTypeId;
|
|
382
|
+
case facebook::react::Role::Progressbar:
|
|
383
|
+
return UIA_ProgressBarControlTypeId;
|
|
384
|
+
case facebook::react::Role::Radio:
|
|
385
|
+
return UIA_RadioButtonControlTypeId;
|
|
386
|
+
case facebook::react::Role::Radiogroup:
|
|
387
|
+
return UIA_GroupControlTypeId;
|
|
388
|
+
case facebook::react::Role::Rowgroup:
|
|
389
|
+
return UIA_GroupControlTypeId;
|
|
390
|
+
case facebook::react::Role::Rowheader:
|
|
391
|
+
return UIA_HeaderControlTypeId;
|
|
392
|
+
case facebook::react::Role::Scrollbar:
|
|
393
|
+
return UIA_ScrollBarControlTypeId;
|
|
394
|
+
case facebook::react::Role::Searchbox:
|
|
395
|
+
return UIA_EditControlTypeId;
|
|
396
|
+
case facebook::react::Role::Separator:
|
|
397
|
+
return UIA_SeparatorControlTypeId;
|
|
398
|
+
case facebook::react::Role::Slider:
|
|
399
|
+
return UIA_SliderControlTypeId;
|
|
400
|
+
case facebook::react::Role::Spinbutton:
|
|
401
|
+
return UIA_SpinnerControlTypeId;
|
|
402
|
+
case facebook::react::Role::Status:
|
|
403
|
+
return UIA_StatusBarControlTypeId;
|
|
404
|
+
case facebook::react::Role::Summary:
|
|
405
|
+
return UIA_GroupControlTypeId;
|
|
406
|
+
case facebook::react::Role::Switch:
|
|
407
|
+
return UIA_ButtonControlTypeId;
|
|
408
|
+
case facebook::react::Role::Tab:
|
|
409
|
+
return UIA_TabItemControlTypeId;
|
|
410
|
+
case facebook::react::Role::Table:
|
|
411
|
+
return UIA_TableControlTypeId;
|
|
412
|
+
case facebook::react::Role::Tablist:
|
|
413
|
+
return UIA_TabControlTypeId;
|
|
414
|
+
case facebook::react::Role::Tabpanel:
|
|
415
|
+
return UIA_TabControlTypeId;
|
|
416
|
+
case facebook::react::Role::Timer:
|
|
417
|
+
return UIA_ButtonControlTypeId;
|
|
418
|
+
case facebook::react::Role::Toolbar:
|
|
419
|
+
return UIA_ToolBarControlTypeId;
|
|
420
|
+
case facebook::react::Role::Tooltip:
|
|
421
|
+
return UIA_ToolTipControlTypeId;
|
|
422
|
+
case facebook::react::Role::Tree:
|
|
423
|
+
return UIA_TreeControlTypeId;
|
|
424
|
+
case facebook::react::Role::Treegrid:
|
|
425
|
+
return UIA_TreeControlTypeId;
|
|
426
|
+
case facebook::react::Role::Treeitem:
|
|
427
|
+
return UIA_TreeItemControlTypeId;
|
|
428
|
+
}
|
|
429
|
+
return UIA_GroupControlTypeId;
|
|
430
|
+
}
|
|
431
|
+
|
|
302
432
|
HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERTYID propertyId, VARIANT *pRetVal) {
|
|
303
433
|
if (pRetVal == nullptr)
|
|
304
434
|
return E_POINTER;
|
|
@@ -324,8 +454,10 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
|
|
|
324
454
|
switch (propertyId) {
|
|
325
455
|
case UIA_ControlTypePropertyId: {
|
|
326
456
|
pRetVal->vt = VT_I4;
|
|
327
|
-
|
|
328
|
-
|
|
457
|
+
pRetVal->lVal = props->role == facebook::react::Role::None ? props->accessibilityRole.empty()
|
|
458
|
+
? GetControlTypeFromString(compositionView->DefaultControlType())
|
|
459
|
+
: GetControlTypeFromString(props->accessibilityRole)
|
|
460
|
+
: GetControlTypeFromRole(props->role);
|
|
329
461
|
break;
|
|
330
462
|
}
|
|
331
463
|
case UIA_AutomationIdPropertyId: {
|
|
@@ -365,12 +497,18 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
|
|
|
365
497
|
}
|
|
366
498
|
case UIA_IsContentElementPropertyId: {
|
|
367
499
|
pRetVal->vt = VT_BOOL;
|
|
368
|
-
pRetVal->boolVal =
|
|
500
|
+
pRetVal->boolVal =
|
|
501
|
+
(props->accessible && (props->accessibilityRole != "none" || props->role != facebook::react::Role::None))
|
|
502
|
+
? VARIANT_TRUE
|
|
503
|
+
: VARIANT_FALSE;
|
|
369
504
|
break;
|
|
370
505
|
}
|
|
371
506
|
case UIA_IsControlElementPropertyId: {
|
|
372
507
|
pRetVal->vt = VT_BOOL;
|
|
373
|
-
pRetVal->boolVal =
|
|
508
|
+
pRetVal->boolVal =
|
|
509
|
+
(props->accessible && (props->accessibilityRole != "none" || props->role != facebook::react::Role::None))
|
|
510
|
+
? VARIANT_TRUE
|
|
511
|
+
: VARIANT_FALSE;
|
|
374
512
|
break;
|
|
375
513
|
}
|
|
376
514
|
case UIA_IsOffscreenPropertyId: {
|
|
@@ -461,6 +599,156 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::ScrollIntoView() {
|
|
|
461
599
|
return S_OK;
|
|
462
600
|
}
|
|
463
601
|
|
|
602
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_HorizontalScrollPercent(double *pRetVal) {
|
|
603
|
+
BOOL horizontallyScrollable;
|
|
604
|
+
auto hr = get_HorizontallyScrollable(&horizontallyScrollable);
|
|
605
|
+
if (!SUCCEEDED(hr)) {
|
|
606
|
+
return hr;
|
|
607
|
+
}
|
|
608
|
+
if (!horizontallyScrollable) {
|
|
609
|
+
*pRetVal = UIA_ScrollPatternNoScroll;
|
|
610
|
+
} else {
|
|
611
|
+
auto strongView = m_view.view();
|
|
612
|
+
auto scrollComponentView =
|
|
613
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
614
|
+
*pRetVal = scrollComponentView->getScrollPositionX();
|
|
615
|
+
}
|
|
616
|
+
return S_OK;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_VerticalScrollPercent(double *pRetVal) {
|
|
620
|
+
BOOL verticallyScrollable;
|
|
621
|
+
auto hr = get_VerticallyScrollable(&verticallyScrollable);
|
|
622
|
+
if (!SUCCEEDED(hr)) {
|
|
623
|
+
return hr;
|
|
624
|
+
}
|
|
625
|
+
if (!verticallyScrollable) {
|
|
626
|
+
*pRetVal = UIA_ScrollPatternNoScroll;
|
|
627
|
+
} else {
|
|
628
|
+
auto strongView = m_view.view();
|
|
629
|
+
auto scrollComponentView =
|
|
630
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
631
|
+
*pRetVal = scrollComponentView->getScrollPositionY();
|
|
632
|
+
}
|
|
633
|
+
return S_OK;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_HorizontalViewSize(double *pRetVal) {
|
|
637
|
+
BOOL horizontallyScrollable;
|
|
638
|
+
auto hr = get_HorizontallyScrollable(&horizontallyScrollable);
|
|
639
|
+
if (!SUCCEEDED(hr)) {
|
|
640
|
+
return hr;
|
|
641
|
+
}
|
|
642
|
+
if (!horizontallyScrollable) {
|
|
643
|
+
*pRetVal = 100;
|
|
644
|
+
} else {
|
|
645
|
+
auto strongView = m_view.view();
|
|
646
|
+
auto scrollComponentView =
|
|
647
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
648
|
+
*pRetVal = scrollComponentView->getHorizontalSize();
|
|
649
|
+
}
|
|
650
|
+
return S_OK;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_VerticalViewSize(double *pRetVal) {
|
|
654
|
+
BOOL verticallyScrollable;
|
|
655
|
+
auto hr = get_VerticallyScrollable(&verticallyScrollable);
|
|
656
|
+
if (!SUCCEEDED(hr)) {
|
|
657
|
+
return hr;
|
|
658
|
+
}
|
|
659
|
+
if (!verticallyScrollable) {
|
|
660
|
+
*pRetVal = 100;
|
|
661
|
+
} else {
|
|
662
|
+
auto strongView = m_view.view();
|
|
663
|
+
auto scrollComponentView =
|
|
664
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
665
|
+
*pRetVal = scrollComponentView->getVerticalSize();
|
|
666
|
+
}
|
|
667
|
+
return S_OK;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_HorizontallyScrollable(BOOL *pRetVal) {
|
|
671
|
+
if (pRetVal == nullptr)
|
|
672
|
+
return E_POINTER;
|
|
673
|
+
auto strongView = m_view.view();
|
|
674
|
+
|
|
675
|
+
if (!strongView)
|
|
676
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
677
|
+
|
|
678
|
+
auto props = std::static_pointer_cast<const facebook::react::ScrollViewProps>(
|
|
679
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
680
|
+
if (props == nullptr)
|
|
681
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
682
|
+
*pRetVal = (props->horizontal && props->scrollEnabled);
|
|
683
|
+
return S_OK;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_VerticallyScrollable(BOOL *pRetVal) {
|
|
687
|
+
if (pRetVal == nullptr)
|
|
688
|
+
return E_POINTER;
|
|
689
|
+
auto strongView = m_view.view();
|
|
690
|
+
|
|
691
|
+
if (!strongView)
|
|
692
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
693
|
+
|
|
694
|
+
auto props = std::static_pointer_cast<const facebook::react::ScrollViewProps>(
|
|
695
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
696
|
+
if (props == nullptr)
|
|
697
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
698
|
+
*pRetVal = (!props->horizontal && props->scrollEnabled);
|
|
699
|
+
return S_OK;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::Scroll(
|
|
703
|
+
ScrollAmount horizontalAmount,
|
|
704
|
+
ScrollAmount verticalAmount) {
|
|
705
|
+
DispatchAccessibilityAction(m_view, "scroll");
|
|
706
|
+
auto strongView = m_view.view();
|
|
707
|
+
auto scrollComponentView =
|
|
708
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
709
|
+
BOOL verticallyScrollable;
|
|
710
|
+
BOOL horizontallyScrollable;
|
|
711
|
+
float vertical = 0.0f;
|
|
712
|
+
float horizontal = 0.0f;
|
|
713
|
+
auto hr = get_VerticallyScrollable(&verticallyScrollable);
|
|
714
|
+
if (!SUCCEEDED(hr)) {
|
|
715
|
+
return hr;
|
|
716
|
+
}
|
|
717
|
+
if (verticallyScrollable) {
|
|
718
|
+
if (verticalAmount == ScrollAmount_LargeIncrement) {
|
|
719
|
+
scrollComponentView->pageDown(true);
|
|
720
|
+
} else if (verticalAmount == ScrollAmount_LargeDecrement) {
|
|
721
|
+
scrollComponentView->pageUp(true);
|
|
722
|
+
} else if (verticalAmount == ScrollAmount_SmallIncrement) {
|
|
723
|
+
scrollComponentView->lineDown(true);
|
|
724
|
+
} else if (verticalAmount == ScrollAmount_SmallDecrement) {
|
|
725
|
+
scrollComponentView->lineUp(true);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
hr = get_HorizontallyScrollable(&horizontallyScrollable);
|
|
729
|
+
if (!SUCCEEDED(hr)) {
|
|
730
|
+
return hr;
|
|
731
|
+
}
|
|
732
|
+
if (horizontallyScrollable) {
|
|
733
|
+
if (horizontalAmount == ScrollAmount_LargeIncrement) {
|
|
734
|
+
scrollComponentView->pageDown(true);
|
|
735
|
+
} else if (horizontalAmount == ScrollAmount_LargeDecrement) {
|
|
736
|
+
scrollComponentView->pageUp(true);
|
|
737
|
+
} else if (horizontalAmount == ScrollAmount_SmallIncrement) {
|
|
738
|
+
scrollComponentView->lineRight(true);
|
|
739
|
+
} else if (horizontalAmount == ScrollAmount_SmallDecrement) {
|
|
740
|
+
scrollComponentView->lineLeft(true);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return S_OK;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::SetScrollPercent(
|
|
747
|
+
double horiztonalPercent,
|
|
748
|
+
double verticalPercent) {
|
|
749
|
+
return S_OK;
|
|
750
|
+
}
|
|
751
|
+
|
|
464
752
|
BSTR StringToBSTR(const std::string &str) {
|
|
465
753
|
// Calculate the required BSTR size in bytes
|
|
466
754
|
int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
|
|
@@ -485,6 +773,8 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::SetValue(LPCWSTR val) {
|
|
|
485
773
|
|
|
486
774
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)
|
|
487
775
|
->setAcccessiblityValue(winrt::to_string(val));
|
|
776
|
+
// TODO: Edit once/if onAccessibilityAction props supports returning UIA event data. See
|
|
777
|
+
// https://github.com/react-native-community/discussions-and-proposals/issues/843.
|
|
488
778
|
DispatchAccessibilityAction(m_view, "setValue");
|
|
489
779
|
return S_OK;
|
|
490
780
|
}
|
|
@@ -515,23 +805,86 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_IsReadOnly(BOOL *pRe
|
|
|
515
805
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
516
806
|
if (props == nullptr)
|
|
517
807
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
// Control is using default control type. Use default IsReadOnly value.
|
|
521
|
-
*pRetVal = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)
|
|
522
|
-
->getAcccessiblityIsReadOnly();
|
|
523
|
-
} else if (
|
|
524
|
-
accessibilityRole == "textinput" || accessibilityRole == "searchbox" || accessibilityRole == "adjustable" ||
|
|
525
|
-
accessibilityRole == "spinbutton" || accessibilityRole == "combobox") {
|
|
526
|
-
// Control is using customized control type which should not be IsReadOnly for value pattern.
|
|
527
|
-
*pRetVal = false;
|
|
808
|
+
if (props->accessibilityState.has_value() && props->accessibilityState->readOnly.has_value()) {
|
|
809
|
+
*pRetVal = props->accessibilityState->readOnly.value();
|
|
528
810
|
} else {
|
|
529
|
-
//
|
|
530
|
-
*pRetVal =
|
|
811
|
+
// Use default IsReadOnly value.
|
|
812
|
+
*pRetVal = false;
|
|
531
813
|
}
|
|
532
814
|
return S_OK;
|
|
533
815
|
}
|
|
534
816
|
|
|
817
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_LargeChange(double *pRetVal) {
|
|
818
|
+
// no-op
|
|
819
|
+
return S_OK;
|
|
820
|
+
}
|
|
821
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_Maximum(double *pRetVal) {
|
|
822
|
+
if (pRetVal == nullptr)
|
|
823
|
+
return E_POINTER;
|
|
824
|
+
auto strongView = m_view.view();
|
|
825
|
+
|
|
826
|
+
if (!strongView)
|
|
827
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
828
|
+
|
|
829
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
830
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
831
|
+
|
|
832
|
+
if (props == nullptr)
|
|
833
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
834
|
+
|
|
835
|
+
*pRetVal = props->accessibilityValue.max.value();
|
|
836
|
+
return S_OK;
|
|
837
|
+
}
|
|
838
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_Minimum(double *pRetVal) {
|
|
839
|
+
if (pRetVal == nullptr)
|
|
840
|
+
return E_POINTER;
|
|
841
|
+
auto strongView = m_view.view();
|
|
842
|
+
|
|
843
|
+
if (!strongView)
|
|
844
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
845
|
+
|
|
846
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
847
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
848
|
+
|
|
849
|
+
if (props == nullptr)
|
|
850
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
851
|
+
|
|
852
|
+
*pRetVal = props->accessibilityValue.min.value();
|
|
853
|
+
return S_OK;
|
|
854
|
+
}
|
|
855
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_SmallChange(double *pRetVal) {
|
|
856
|
+
// no-op
|
|
857
|
+
return S_OK;
|
|
858
|
+
}
|
|
859
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_Value(double *pRetVal) {
|
|
860
|
+
if (pRetVal == nullptr)
|
|
861
|
+
return E_POINTER;
|
|
862
|
+
auto strongView = m_view.view();
|
|
863
|
+
|
|
864
|
+
if (!strongView)
|
|
865
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
866
|
+
|
|
867
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
868
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
869
|
+
|
|
870
|
+
if (props == nullptr)
|
|
871
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
872
|
+
|
|
873
|
+
*pRetVal = props->accessibilityValue.now.value();
|
|
874
|
+
return S_OK;
|
|
875
|
+
}
|
|
876
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::SetValue(double val) {
|
|
877
|
+
auto strongView = m_view.view();
|
|
878
|
+
|
|
879
|
+
if (!strongView)
|
|
880
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
881
|
+
|
|
882
|
+
// TODO: Edit once/if onAccessibilityAction props supports returning UIA event data. See
|
|
883
|
+
// https://github.com/react-native-community/discussions-and-proposals/issues/843.
|
|
884
|
+
DispatchAccessibilityAction(m_view, "setValue");
|
|
885
|
+
return S_OK;
|
|
886
|
+
}
|
|
887
|
+
|
|
535
888
|
HRESULT __stdcall CompositionDynamicAutomationProvider::get_ToggleState(ToggleState *pRetVal) {
|
|
536
889
|
if (pRetVal == nullptr)
|
|
537
890
|
return E_POINTER;
|
|
@@ -15,7 +15,9 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
|
|
|
15
15
|
IRawElementProviderSimple,
|
|
16
16
|
IInvokeProvider,
|
|
17
17
|
IScrollItemProvider,
|
|
18
|
+
IScrollProvider,
|
|
18
19
|
IValueProvider,
|
|
20
|
+
IRangeValueProvider,
|
|
19
21
|
IToggleProvider,
|
|
20
22
|
IExpandCollapseProvider,
|
|
21
23
|
ISelectionProvider,
|
|
@@ -45,11 +47,29 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
|
|
|
45
47
|
// inherited via IScrollItemProvider
|
|
46
48
|
HRESULT __stdcall ScrollIntoView() override;
|
|
47
49
|
|
|
50
|
+
// inherited via IScrollProvider
|
|
51
|
+
HRESULT __stdcall get_HorizontalScrollPercent(double *pRetVal) override;
|
|
52
|
+
HRESULT __stdcall get_VerticalScrollPercent(double *pRetVal) override;
|
|
53
|
+
HRESULT __stdcall get_HorizontalViewSize(double *pRetVal) override;
|
|
54
|
+
HRESULT __stdcall get_VerticalViewSize(double *pRetVal) override;
|
|
55
|
+
HRESULT __stdcall get_HorizontallyScrollable(BOOL *pRetVal) override;
|
|
56
|
+
HRESULT __stdcall get_VerticallyScrollable(BOOL *pRetVal) override;
|
|
57
|
+
HRESULT __stdcall Scroll(ScrollAmount horizontalAmount, ScrollAmount verticalAmount) override;
|
|
58
|
+
HRESULT __stdcall SetScrollPercent(double horiztonalPercent, double verticalPercent) override;
|
|
59
|
+
|
|
48
60
|
// inherited via IValueProvider
|
|
49
61
|
virtual HRESULT __stdcall SetValue(LPCWSTR val) override;
|
|
50
62
|
virtual HRESULT __stdcall get_Value(BSTR *pRetVal) override;
|
|
51
63
|
virtual HRESULT __stdcall get_IsReadOnly(BOOL *pRetVal) override;
|
|
52
64
|
|
|
65
|
+
// inherited via IRangeValueProvider
|
|
66
|
+
virtual HRESULT __stdcall get_LargeChange(double *pRetVal) override;
|
|
67
|
+
virtual HRESULT __stdcall get_Maximum(double *pRetVal) override;
|
|
68
|
+
virtual HRESULT __stdcall get_Minimum(double *pRetVal) override;
|
|
69
|
+
virtual HRESULT __stdcall get_SmallChange(double *pRetVal) override;
|
|
70
|
+
virtual HRESULT __stdcall get_Value(double *pRetVal) override;
|
|
71
|
+
virtual HRESULT __stdcall SetValue(double val) override;
|
|
72
|
+
|
|
53
73
|
// inherited via IToggleProvider
|
|
54
74
|
virtual HRESULT __stdcall get_ToggleState(ToggleState *pRetVal) override;
|
|
55
75
|
virtual HRESULT __stdcall Toggle() override;
|
|
@@ -76,6 +96,7 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
|
|
|
76
96
|
|
|
77
97
|
private:
|
|
78
98
|
::Microsoft::ReactNative::ReactTaggedView m_view;
|
|
99
|
+
winrt::com_ptr<ITextProvider2> m_textProvider;
|
|
79
100
|
std::vector<winrt::com_ptr<IRawElementProviderSimple>> m_selectionItems;
|
|
80
101
|
};
|
|
81
102
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#include "pch.h"
|
|
2
|
+
#include <Fabric/ComponentView.h>
|
|
3
|
+
#include <Fabric/Composition/ParagraphComponentView.h>
|
|
4
|
+
#include <Fabric/Composition/TextInput/WindowsTextInputComponentView.h>
|
|
5
|
+
#include <Unicode.h>
|
|
6
|
+
#include "CompositionTextRangeProvider.h"
|
|
7
|
+
#include "RootComponentView.h"
|
|
8
|
+
#include "UiaHelpers.h"
|
|
9
|
+
|
|
10
|
+
namespace winrt::Microsoft::ReactNative::implementation {
|
|
11
|
+
|
|
12
|
+
CompositionTextProvider::CompositionTextProvider(
|
|
13
|
+
const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView,
|
|
14
|
+
CompositionDynamicAutomationProvider *parentProvider) noexcept
|
|
15
|
+
: m_view{componentView} {
|
|
16
|
+
m_parentProvider.copy_from(parentProvider);
|
|
17
|
+
EnsureTextRangeProvider();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
void CompositionTextProvider::EnsureTextRangeProvider() {
|
|
21
|
+
auto strongView = m_view.view();
|
|
22
|
+
|
|
23
|
+
if (!strongView)
|
|
24
|
+
return;
|
|
25
|
+
|
|
26
|
+
if (!m_textRangeProvider) {
|
|
27
|
+
m_textRangeProvider =
|
|
28
|
+
winrt::make<CompositionTextRangeProvider>(
|
|
29
|
+
strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>(), m_parentProvider.get())
|
|
30
|
+
.try_as<ITextRangeProvider>();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
HRESULT __stdcall CompositionTextProvider::get_DocumentRange(ITextRangeProvider **pRetVal) {
|
|
35
|
+
if (pRetVal == nullptr)
|
|
36
|
+
return E_POINTER;
|
|
37
|
+
auto strongView = m_view.view();
|
|
38
|
+
|
|
39
|
+
if (!strongView)
|
|
40
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
41
|
+
|
|
42
|
+
if (m_textRangeProvider == nullptr)
|
|
43
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
44
|
+
|
|
45
|
+
m_textRangeProvider.copy_to(pRetVal);
|
|
46
|
+
return S_OK;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
HRESULT __stdcall CompositionTextProvider::get_SupportedTextSelection(SupportedTextSelection *pRetVal) {
|
|
50
|
+
if (pRetVal == nullptr)
|
|
51
|
+
return E_POINTER;
|
|
52
|
+
auto strongView = m_view.view();
|
|
53
|
+
|
|
54
|
+
if (!strongView)
|
|
55
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
56
|
+
|
|
57
|
+
if (strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>()) {
|
|
58
|
+
*pRetVal = SupportedTextSelection_Single;
|
|
59
|
+
} else if (
|
|
60
|
+
auto textView =
|
|
61
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>()) {
|
|
62
|
+
auto props = std::static_pointer_cast<const facebook::react::ParagraphProps>(textView->props());
|
|
63
|
+
if (props == nullptr)
|
|
64
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
65
|
+
*pRetVal = props->isSelectable ? SupportedTextSelection_Single : SupportedTextSelection_None;
|
|
66
|
+
} else {
|
|
67
|
+
*pRetVal = SupportedTextSelection_None;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return S_OK;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
HRESULT __stdcall CompositionTextProvider::GetSelection(SAFEARRAY **pRetVal) {
|
|
74
|
+
// no-op
|
|
75
|
+
*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 0);
|
|
76
|
+
return S_OK;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
HRESULT __stdcall CompositionTextProvider::GetVisibleRanges(SAFEARRAY **pRetVal) {
|
|
80
|
+
*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1);
|
|
81
|
+
if (m_textRangeProvider == nullptr)
|
|
82
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
83
|
+
LONG pos = 0;
|
|
84
|
+
return SafeArrayPutElement(*pRetVal, &pos, m_textRangeProvider.get());
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
HRESULT __stdcall CompositionTextProvider::RangeFromChild(
|
|
88
|
+
IRawElementProviderSimple *childElement,
|
|
89
|
+
ITextRangeProvider **pRetVal) {
|
|
90
|
+
// no-op
|
|
91
|
+
*pRetVal = nullptr;
|
|
92
|
+
return S_OK;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
HRESULT __stdcall CompositionTextProvider::RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal) {
|
|
96
|
+
// no-op
|
|
97
|
+
if (m_textRangeProvider == nullptr)
|
|
98
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
99
|
+
m_textRangeProvider.copy_to(pRetVal);
|
|
100
|
+
return S_OK;
|
|
101
|
+
}
|
|
102
|
+
HRESULT __stdcall CompositionTextProvider::GetCaretRange(BOOL *isActive, ITextRangeProvider **pRetVal) {
|
|
103
|
+
// no-op
|
|
104
|
+
*pRetVal = nullptr;
|
|
105
|
+
return S_OK;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
HRESULT __stdcall CompositionTextProvider::RangeFromAnnotation(
|
|
109
|
+
IRawElementProviderSimple *annotationElement,
|
|
110
|
+
ITextRangeProvider **pRetVal) {
|
|
111
|
+
// no-op
|
|
112
|
+
*pRetVal = nullptr;
|
|
113
|
+
return S_OK;
|
|
114
|
+
}
|
|
115
|
+
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <Fabric/Composition/CompositionDynamicAutomationProvider.h>
|
|
4
|
+
#include <Fabric/Composition/CompositionViewComponentView.h>
|
|
5
|
+
#include <Fabric/ReactTaggedView.h>
|
|
6
|
+
#include <UIAutomation.h>
|
|
7
|
+
#include <inspectable.h>
|
|
8
|
+
#include <uiautomationcore.h>
|
|
9
|
+
|
|
10
|
+
namespace winrt::Microsoft::ReactNative::implementation {
|
|
11
|
+
|
|
12
|
+
class CompositionTextProvider : public winrt::implements<CompositionTextProvider, ITextProvider, ITextProvider2> {
|
|
13
|
+
public:
|
|
14
|
+
CompositionTextProvider(
|
|
15
|
+
const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView,
|
|
16
|
+
CompositionDynamicAutomationProvider *parentProvider) noexcept;
|
|
17
|
+
|
|
18
|
+
// inherited via ITextProvider
|
|
19
|
+
virtual HRESULT __stdcall get_DocumentRange(ITextRangeProvider **pRetVal) override;
|
|
20
|
+
virtual HRESULT __stdcall get_SupportedTextSelection(SupportedTextSelection *pRetVal) override;
|
|
21
|
+
virtual HRESULT __stdcall GetSelection(SAFEARRAY **pRetVal) override;
|
|
22
|
+
virtual HRESULT __stdcall GetVisibleRanges(SAFEARRAY **pRetVal) override;
|
|
23
|
+
virtual HRESULT __stdcall RangeFromChild(IRawElementProviderSimple *childElement, ITextRangeProvider **pRetVal)
|
|
24
|
+
override;
|
|
25
|
+
virtual HRESULT __stdcall RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal) override;
|
|
26
|
+
|
|
27
|
+
// inherited via ITextProvider2
|
|
28
|
+
virtual HRESULT __stdcall GetCaretRange(BOOL *isActive, ITextRangeProvider **pRetVal) override;
|
|
29
|
+
virtual HRESULT __stdcall RangeFromAnnotation(
|
|
30
|
+
IRawElementProviderSimple *annotationElement,
|
|
31
|
+
ITextRangeProvider **pRetVal) override;
|
|
32
|
+
|
|
33
|
+
void EnsureTextRangeProvider();
|
|
34
|
+
|
|
35
|
+
private:
|
|
36
|
+
::Microsoft::ReactNative::ReactTaggedView m_view;
|
|
37
|
+
winrt::com_ptr<ITextRangeProvider> m_textRangeProvider;
|
|
38
|
+
winrt::com_ptr<CompositionDynamicAutomationProvider> m_parentProvider;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
} // namespace winrt::Microsoft::ReactNative::implementation
|