react-native-windows 0.78.1 → 0.78.3
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/Directory.Build.props +2 -2
- package/Folly/TEMP_UntilFollyUpdate/json.cpp +4 -0
- package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.cpp +23 -15
- package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +5 -5
- package/Folly/cgmanifest.json +1 -1
- package/Libraries/Components/ScrollView/ScrollView.windows.js +1920 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +282 -6
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +12 -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/ScrollViewComponentView.cpp +24 -2
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +5 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +14 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +3 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/WebView2.props +2 -1
- package/PropertySheets/WinUI.props +5 -2
- package/Shared/Shared.vcxitems +6 -0
- package/Shared/Shared.vcxitems.filters +8 -0
- package/package.json +5 -5
|
@@ -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(
|
|
@@ -204,6 +214,12 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
|
|
|
204
214
|
AddRef();
|
|
205
215
|
}
|
|
206
216
|
|
|
217
|
+
if (patternId == UIA_ScrollPatternId &&
|
|
218
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>()) {
|
|
219
|
+
*pRetVal = static_cast<IScrollProvider *>(this);
|
|
220
|
+
AddRef();
|
|
221
|
+
}
|
|
222
|
+
|
|
207
223
|
if (patternId == UIA_ValuePatternId &&
|
|
208
224
|
((strongView
|
|
209
225
|
.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() &&
|
|
@@ -242,10 +258,21 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
|
|
|
242
258
|
AddRef();
|
|
243
259
|
}
|
|
244
260
|
|
|
261
|
+
if (patternId == UIA_TextPatternId &&
|
|
262
|
+
(strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() ||
|
|
263
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>())) {
|
|
264
|
+
m_textProvider.as<IUnknown>().copy_to(pRetVal);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (patternId == UIA_TextPattern2Id &&
|
|
268
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>()) {
|
|
269
|
+
m_textProvider.as<IUnknown>().copy_to(pRetVal);
|
|
270
|
+
}
|
|
271
|
+
|
|
245
272
|
return S_OK;
|
|
246
273
|
}
|
|
247
274
|
|
|
248
|
-
long
|
|
275
|
+
long GetControlTypeFromString(const std::string &role) noexcept {
|
|
249
276
|
if (role == "adjustable") {
|
|
250
277
|
return UIA_SliderControlTypeId;
|
|
251
278
|
} else if (role == "group" || role == "search" || role == "radiogroup" || role == "timer" || role.empty()) {
|
|
@@ -303,11 +330,103 @@ long GetControlType(const std::string &role) noexcept {
|
|
|
303
330
|
return UIA_TreeControlTypeId;
|
|
304
331
|
} else if (role == "treeitem") {
|
|
305
332
|
return UIA_TreeItemControlTypeId;
|
|
333
|
+
} else if (role == "pane") {
|
|
334
|
+
return UIA_PaneControlTypeId;
|
|
306
335
|
}
|
|
307
336
|
assert(false);
|
|
308
337
|
return UIA_GroupControlTypeId;
|
|
309
338
|
}
|
|
310
339
|
|
|
340
|
+
long GetControlTypeFromRole(const facebook::react::Role &role) noexcept {
|
|
341
|
+
switch (role) {
|
|
342
|
+
case facebook::react::Role::Alert:
|
|
343
|
+
return UIA_TextControlTypeId;
|
|
344
|
+
case facebook::react::Role::Application:
|
|
345
|
+
return UIA_WindowControlTypeId;
|
|
346
|
+
case facebook::react::Role::Button:
|
|
347
|
+
return UIA_ButtonControlTypeId;
|
|
348
|
+
case facebook::react::Role::Checkbox:
|
|
349
|
+
return UIA_CheckBoxControlTypeId;
|
|
350
|
+
case facebook::react::Role::Columnheader:
|
|
351
|
+
return UIA_HeaderControlTypeId;
|
|
352
|
+
case facebook::react::Role::Combobox:
|
|
353
|
+
return UIA_ComboBoxControlTypeId;
|
|
354
|
+
case facebook::react::Role::Document:
|
|
355
|
+
return UIA_DocumentControlTypeId;
|
|
356
|
+
case facebook::react::Role::Grid:
|
|
357
|
+
return UIA_GroupControlTypeId;
|
|
358
|
+
case facebook::react::Role::Group:
|
|
359
|
+
return UIA_GroupControlTypeId;
|
|
360
|
+
case facebook::react::Role::Heading:
|
|
361
|
+
return UIA_TextControlTypeId;
|
|
362
|
+
case facebook::react::Role::Img:
|
|
363
|
+
return UIA_ImageControlTypeId;
|
|
364
|
+
case facebook::react::Role::Link:
|
|
365
|
+
return UIA_HyperlinkControlTypeId;
|
|
366
|
+
case facebook::react::Role::List:
|
|
367
|
+
return UIA_ListControlTypeId;
|
|
368
|
+
case facebook::react::Role::Listitem:
|
|
369
|
+
return UIA_ListItemControlTypeId;
|
|
370
|
+
case facebook::react::Role::Menu:
|
|
371
|
+
return UIA_MenuControlTypeId;
|
|
372
|
+
case facebook::react::Role::Menubar:
|
|
373
|
+
return UIA_MenuBarControlTypeId;
|
|
374
|
+
case facebook::react::Role::Menuitem:
|
|
375
|
+
return UIA_MenuItemControlTypeId;
|
|
376
|
+
case facebook::react::Role::None:
|
|
377
|
+
return UIA_GroupControlTypeId;
|
|
378
|
+
case facebook::react::Role::Presentation:
|
|
379
|
+
return UIA_GroupControlTypeId;
|
|
380
|
+
case facebook::react::Role::Progressbar:
|
|
381
|
+
return UIA_ProgressBarControlTypeId;
|
|
382
|
+
case facebook::react::Role::Radio:
|
|
383
|
+
return UIA_RadioButtonControlTypeId;
|
|
384
|
+
case facebook::react::Role::Radiogroup:
|
|
385
|
+
return UIA_GroupControlTypeId;
|
|
386
|
+
case facebook::react::Role::Rowgroup:
|
|
387
|
+
return UIA_GroupControlTypeId;
|
|
388
|
+
case facebook::react::Role::Rowheader:
|
|
389
|
+
return UIA_HeaderControlTypeId;
|
|
390
|
+
case facebook::react::Role::Scrollbar:
|
|
391
|
+
return UIA_ScrollBarControlTypeId;
|
|
392
|
+
case facebook::react::Role::Searchbox:
|
|
393
|
+
return UIA_EditControlTypeId;
|
|
394
|
+
case facebook::react::Role::Separator:
|
|
395
|
+
return UIA_SeparatorControlTypeId;
|
|
396
|
+
case facebook::react::Role::Slider:
|
|
397
|
+
return UIA_SliderControlTypeId;
|
|
398
|
+
case facebook::react::Role::Spinbutton:
|
|
399
|
+
return UIA_SpinnerControlTypeId;
|
|
400
|
+
case facebook::react::Role::Status:
|
|
401
|
+
return UIA_StatusBarControlTypeId;
|
|
402
|
+
case facebook::react::Role::Summary:
|
|
403
|
+
return UIA_GroupControlTypeId;
|
|
404
|
+
case facebook::react::Role::Switch:
|
|
405
|
+
return UIA_ButtonControlTypeId;
|
|
406
|
+
case facebook::react::Role::Tab:
|
|
407
|
+
return UIA_TabItemControlTypeId;
|
|
408
|
+
case facebook::react::Role::Table:
|
|
409
|
+
return UIA_TableControlTypeId;
|
|
410
|
+
case facebook::react::Role::Tablist:
|
|
411
|
+
return UIA_TabControlTypeId;
|
|
412
|
+
case facebook::react::Role::Tabpanel:
|
|
413
|
+
return UIA_TabControlTypeId;
|
|
414
|
+
case facebook::react::Role::Timer:
|
|
415
|
+
return UIA_ButtonControlTypeId;
|
|
416
|
+
case facebook::react::Role::Toolbar:
|
|
417
|
+
return UIA_ToolBarControlTypeId;
|
|
418
|
+
case facebook::react::Role::Tooltip:
|
|
419
|
+
return UIA_ToolTipControlTypeId;
|
|
420
|
+
case facebook::react::Role::Tree:
|
|
421
|
+
return UIA_TreeControlTypeId;
|
|
422
|
+
case facebook::react::Role::Treegrid:
|
|
423
|
+
return UIA_TreeControlTypeId;
|
|
424
|
+
case facebook::react::Role::Treeitem:
|
|
425
|
+
return UIA_TreeItemControlTypeId;
|
|
426
|
+
}
|
|
427
|
+
return UIA_GroupControlTypeId;
|
|
428
|
+
}
|
|
429
|
+
|
|
311
430
|
HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERTYID propertyId, VARIANT *pRetVal) {
|
|
312
431
|
if (pRetVal == nullptr)
|
|
313
432
|
return E_POINTER;
|
|
@@ -333,8 +452,10 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
|
|
|
333
452
|
switch (propertyId) {
|
|
334
453
|
case UIA_ControlTypePropertyId: {
|
|
335
454
|
pRetVal->vt = VT_I4;
|
|
336
|
-
|
|
337
|
-
|
|
455
|
+
pRetVal->lVal = props->role == facebook::react::Role::None ? props->accessibilityRole.empty()
|
|
456
|
+
? GetControlTypeFromString(compositionView->DefaultControlType())
|
|
457
|
+
: GetControlTypeFromString(props->accessibilityRole)
|
|
458
|
+
: GetControlTypeFromRole(props->role);
|
|
338
459
|
break;
|
|
339
460
|
}
|
|
340
461
|
case UIA_AutomationIdPropertyId: {
|
|
@@ -374,12 +495,18 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
|
|
|
374
495
|
}
|
|
375
496
|
case UIA_IsContentElementPropertyId: {
|
|
376
497
|
pRetVal->vt = VT_BOOL;
|
|
377
|
-
pRetVal->boolVal =
|
|
498
|
+
pRetVal->boolVal =
|
|
499
|
+
(props->accessible && (props->accessibilityRole != "none" || props->role != facebook::react::Role::None))
|
|
500
|
+
? VARIANT_TRUE
|
|
501
|
+
: VARIANT_FALSE;
|
|
378
502
|
break;
|
|
379
503
|
}
|
|
380
504
|
case UIA_IsControlElementPropertyId: {
|
|
381
505
|
pRetVal->vt = VT_BOOL;
|
|
382
|
-
pRetVal->boolVal =
|
|
506
|
+
pRetVal->boolVal =
|
|
507
|
+
(props->accessible && (props->accessibilityRole != "none" || props->role != facebook::react::Role::None))
|
|
508
|
+
? VARIANT_TRUE
|
|
509
|
+
: VARIANT_FALSE;
|
|
383
510
|
break;
|
|
384
511
|
}
|
|
385
512
|
case UIA_IsOffscreenPropertyId: {
|
|
@@ -470,6 +597,156 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::ScrollIntoView() {
|
|
|
470
597
|
return S_OK;
|
|
471
598
|
}
|
|
472
599
|
|
|
600
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_HorizontalScrollPercent(double *pRetVal) {
|
|
601
|
+
BOOL horizontallyScrollable;
|
|
602
|
+
auto hr = get_HorizontallyScrollable(&horizontallyScrollable);
|
|
603
|
+
if (!SUCCEEDED(hr)) {
|
|
604
|
+
return hr;
|
|
605
|
+
}
|
|
606
|
+
if (!horizontallyScrollable) {
|
|
607
|
+
*pRetVal = UIA_ScrollPatternNoScroll;
|
|
608
|
+
} else {
|
|
609
|
+
auto strongView = m_view.view();
|
|
610
|
+
auto scrollComponentView =
|
|
611
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
612
|
+
*pRetVal = scrollComponentView->getScrollPositionX();
|
|
613
|
+
}
|
|
614
|
+
return S_OK;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_VerticalScrollPercent(double *pRetVal) {
|
|
618
|
+
BOOL verticallyScrollable;
|
|
619
|
+
auto hr = get_VerticallyScrollable(&verticallyScrollable);
|
|
620
|
+
if (!SUCCEEDED(hr)) {
|
|
621
|
+
return hr;
|
|
622
|
+
}
|
|
623
|
+
if (!verticallyScrollable) {
|
|
624
|
+
*pRetVal = UIA_ScrollPatternNoScroll;
|
|
625
|
+
} else {
|
|
626
|
+
auto strongView = m_view.view();
|
|
627
|
+
auto scrollComponentView =
|
|
628
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
629
|
+
*pRetVal = scrollComponentView->getScrollPositionY();
|
|
630
|
+
}
|
|
631
|
+
return S_OK;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_HorizontalViewSize(double *pRetVal) {
|
|
635
|
+
BOOL horizontallyScrollable;
|
|
636
|
+
auto hr = get_HorizontallyScrollable(&horizontallyScrollable);
|
|
637
|
+
if (!SUCCEEDED(hr)) {
|
|
638
|
+
return hr;
|
|
639
|
+
}
|
|
640
|
+
if (!horizontallyScrollable) {
|
|
641
|
+
*pRetVal = 100;
|
|
642
|
+
} else {
|
|
643
|
+
auto strongView = m_view.view();
|
|
644
|
+
auto scrollComponentView =
|
|
645
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
646
|
+
*pRetVal = scrollComponentView->getHorizontalSize();
|
|
647
|
+
}
|
|
648
|
+
return S_OK;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_VerticalViewSize(double *pRetVal) {
|
|
652
|
+
BOOL verticallyScrollable;
|
|
653
|
+
auto hr = get_VerticallyScrollable(&verticallyScrollable);
|
|
654
|
+
if (!SUCCEEDED(hr)) {
|
|
655
|
+
return hr;
|
|
656
|
+
}
|
|
657
|
+
if (!verticallyScrollable) {
|
|
658
|
+
*pRetVal = 100;
|
|
659
|
+
} else {
|
|
660
|
+
auto strongView = m_view.view();
|
|
661
|
+
auto scrollComponentView =
|
|
662
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
663
|
+
*pRetVal = scrollComponentView->getVerticalSize();
|
|
664
|
+
}
|
|
665
|
+
return S_OK;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_HorizontallyScrollable(BOOL *pRetVal) {
|
|
669
|
+
if (pRetVal == nullptr)
|
|
670
|
+
return E_POINTER;
|
|
671
|
+
auto strongView = m_view.view();
|
|
672
|
+
|
|
673
|
+
if (!strongView)
|
|
674
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
675
|
+
|
|
676
|
+
auto props = std::static_pointer_cast<const facebook::react::ScrollViewProps>(
|
|
677
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
678
|
+
if (props == nullptr)
|
|
679
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
680
|
+
*pRetVal = (props->horizontal && props->scrollEnabled);
|
|
681
|
+
return S_OK;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_VerticallyScrollable(BOOL *pRetVal) {
|
|
685
|
+
if (pRetVal == nullptr)
|
|
686
|
+
return E_POINTER;
|
|
687
|
+
auto strongView = m_view.view();
|
|
688
|
+
|
|
689
|
+
if (!strongView)
|
|
690
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
691
|
+
|
|
692
|
+
auto props = std::static_pointer_cast<const facebook::react::ScrollViewProps>(
|
|
693
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
694
|
+
if (props == nullptr)
|
|
695
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
696
|
+
*pRetVal = (!props->horizontal && props->scrollEnabled);
|
|
697
|
+
return S_OK;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::Scroll(
|
|
701
|
+
ScrollAmount horizontalAmount,
|
|
702
|
+
ScrollAmount verticalAmount) {
|
|
703
|
+
DispatchAccessibilityAction(m_view, "scroll");
|
|
704
|
+
auto strongView = m_view.view();
|
|
705
|
+
auto scrollComponentView =
|
|
706
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ScrollViewComponentView>();
|
|
707
|
+
BOOL verticallyScrollable;
|
|
708
|
+
BOOL horizontallyScrollable;
|
|
709
|
+
float vertical = 0.0f;
|
|
710
|
+
float horizontal = 0.0f;
|
|
711
|
+
auto hr = get_VerticallyScrollable(&verticallyScrollable);
|
|
712
|
+
if (!SUCCEEDED(hr)) {
|
|
713
|
+
return hr;
|
|
714
|
+
}
|
|
715
|
+
if (verticallyScrollable) {
|
|
716
|
+
if (verticalAmount == ScrollAmount_LargeIncrement) {
|
|
717
|
+
scrollComponentView->pageDown(true);
|
|
718
|
+
} else if (verticalAmount == ScrollAmount_LargeDecrement) {
|
|
719
|
+
scrollComponentView->pageUp(true);
|
|
720
|
+
} else if (verticalAmount == ScrollAmount_SmallIncrement) {
|
|
721
|
+
scrollComponentView->lineDown(true);
|
|
722
|
+
} else if (verticalAmount == ScrollAmount_SmallDecrement) {
|
|
723
|
+
scrollComponentView->lineUp(true);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
hr = get_HorizontallyScrollable(&horizontallyScrollable);
|
|
727
|
+
if (!SUCCEEDED(hr)) {
|
|
728
|
+
return hr;
|
|
729
|
+
}
|
|
730
|
+
if (horizontallyScrollable) {
|
|
731
|
+
if (horizontalAmount == ScrollAmount_LargeIncrement) {
|
|
732
|
+
scrollComponentView->pageDown(true);
|
|
733
|
+
} else if (horizontalAmount == ScrollAmount_LargeDecrement) {
|
|
734
|
+
scrollComponentView->pageUp(true);
|
|
735
|
+
} else if (horizontalAmount == ScrollAmount_SmallIncrement) {
|
|
736
|
+
scrollComponentView->lineRight(true);
|
|
737
|
+
} else if (horizontalAmount == ScrollAmount_SmallDecrement) {
|
|
738
|
+
scrollComponentView->lineLeft(true);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
return S_OK;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::SetScrollPercent(
|
|
745
|
+
double horiztonalPercent,
|
|
746
|
+
double verticalPercent) {
|
|
747
|
+
return S_OK;
|
|
748
|
+
}
|
|
749
|
+
|
|
473
750
|
BSTR StringToBSTR(const std::string &str) {
|
|
474
751
|
// Calculate the required BSTR size in bytes
|
|
475
752
|
int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
|
|
@@ -526,7 +803,6 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_IsReadOnly(BOOL *pRe
|
|
|
526
803
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
527
804
|
if (props == nullptr)
|
|
528
805
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
529
|
-
auto accessibilityRole = props->accessibilityRole;
|
|
530
806
|
if (props->accessibilityState.has_value() && props->accessibilityState->readOnly.has_value()) {
|
|
531
807
|
*pRetVal = props->accessibilityState->readOnly.value();
|
|
532
808
|
} else {
|
|
@@ -15,6 +15,7 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
|
|
|
15
15
|
IRawElementProviderSimple,
|
|
16
16
|
IInvokeProvider,
|
|
17
17
|
IScrollItemProvider,
|
|
18
|
+
IScrollProvider,
|
|
18
19
|
IValueProvider,
|
|
19
20
|
IRangeValueProvider,
|
|
20
21
|
IToggleProvider,
|
|
@@ -46,6 +47,16 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
|
|
|
46
47
|
// inherited via IScrollItemProvider
|
|
47
48
|
HRESULT __stdcall ScrollIntoView() override;
|
|
48
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
|
+
|
|
49
60
|
// inherited via IValueProvider
|
|
50
61
|
virtual HRESULT __stdcall SetValue(LPCWSTR val) override;
|
|
51
62
|
virtual HRESULT __stdcall get_Value(BSTR *pRetVal) override;
|
|
@@ -85,6 +96,7 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
|
|
|
85
96
|
|
|
86
97
|
private:
|
|
87
98
|
::Microsoft::ReactNative::ReactTaggedView m_view;
|
|
99
|
+
winrt::com_ptr<ITextProvider2> m_textProvider;
|
|
88
100
|
std::vector<winrt::com_ptr<IRawElementProviderSimple>> m_selectionItems;
|
|
89
101
|
};
|
|
90
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
|