66 {};
67#define COM_OBJECT_VALIDATE_2_ARGS(arg1, arg2) \
68 if (!GetDelegate()) \
69 return E_FAIL; \
70 if (!arg1) \
71 return E_INVALIDARG; \
72 *arg1 = {}; \
73 if (!arg2) \
74 return E_INVALIDARG; \
75 *arg2 = {};
76#define COM_OBJECT_VALIDATE_3_ARGS(arg1, arg2, arg3) \
77 if (!GetDelegate()) \
78 return E_FAIL; \
79 if (!arg1) \
80 return E_INVALIDARG; \
81 *arg1 = {}; \
82 if (!arg2) \
83 return E_INVALIDARG; \
84 *arg2 = {}; \
85 if (!arg3) \
86 return E_INVALIDARG; \
87 *arg3 = {};
88#define COM_OBJECT_VALIDATE_4_ARGS(arg1, arg2, arg3, arg4) \
89 if (!GetDelegate()) \
90 return E_FAIL; \
91 if (!arg1) \
92 return E_INVALIDARG; \
93 *arg1 = {}; \
94 if (!arg2) \
95 return E_INVALIDARG; \
96 *arg2 = {}; \
97 if (!arg3) \
98 return E_INVALIDARG; \
99 *arg3 = {}; \
100 if (!arg4) \
101 return E_INVALIDARG; \
102 *arg4 = {};
103#define COM_OBJECT_VALIDATE_5_ARGS(arg1, arg2, arg3, arg4, arg5) \
104 if (!GetDelegate()) \
105 return E_FAIL; \
106 if (!arg1) \
107 return E_INVALIDARG; \
108 *arg1 = {}; \
109 if (!arg2) \
110 return E_INVALIDARG; \
111 *arg2 = {}; \
112 if (!arg3) \
113 return E_INVALIDARG; \
114 *arg3 = {}; \
115 if (!arg4) \
116 return E_INVALIDARG; \
117 *arg4 = {}; \
118 if (!arg5) \
119 return E_INVALIDARG; \
120 *arg5 = {};
121#define COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target) \
122 if (!GetDelegate()) \
123 return E_FAIL; \
124 target = GetTargetFromChildID(var_id); \
125 if (!target) \
126 return E_INVALIDARG; \
127 if (!target->GetDelegate()) \
128 return E_INVALIDARG;
129#define COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, arg, target) \
130 if (!GetDelegate()) \
131 return E_FAIL; \
132 if (!arg) \
133 return E_INVALIDARG; \
134 *arg = {}; \
135 target = GetTargetFromChildID(var_id); \
136 if (!target) \
137 return E_INVALIDARG; \
138 if (!target->GetDelegate()) \
139 return E_INVALIDARG;
140#define COM_OBJECT_VALIDATE_VAR_ID_2_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \
141 target) \
142 if (!GetDelegate()) \
143 return E_FAIL; \
144 if (!arg1) \
145 return E_INVALIDARG; \
146 *arg1 = {}; \
147 if (!arg2) \
148 return E_INVALIDARG; \
149 *arg2 = {}; \
150 target = GetTargetFromChildID(var_id); \
151 if (!target) \
152 return E_INVALIDARG; \
153 if (!target->GetDelegate()) \
154 return E_INVALIDARG;
155#define COM_OBJECT_VALIDATE_VAR_ID_3_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \
156 arg3, target) \
157 if (!GetDelegate()) \
158 return E_FAIL; \
159 if (!arg1) \
160 return E_INVALIDARG; \
161 *arg1 = {}; \
162 if (!arg2) \
163 return E_INVALIDARG; \
164 *arg2 = {}; \
165 if (!arg3) \
166 return E_INVALIDARG; \
167 *arg3 = {}; \
168 target = GetTargetFromChildID(var_id); \
169 if (!target) \
170 return E_INVALIDARG; \
171 if (!target->GetDelegate()) \
172 return E_INVALIDARG;
173#define COM_OBJECT_VALIDATE_VAR_ID_4_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \
174 arg3, arg4, target) \
175 if (!GetDelegate()) \
176 return E_FAIL; \
177 if (!arg1) \
178 return E_INVALIDARG; \
179 *arg1 = {}; \
180 if (!arg2) \
181 return E_INVALIDARG; \
182 *arg2 = {}; \
183 if (!arg3) \
184 return E_INVALIDARG; \
185 *arg3 = {}; \
186 if (!arg4) \
187 return E_INVALIDARG; \
188 *arg4 = {}; \
189 target = GetTargetFromChildID(var_id); \
190 if (!target) \
191 return E_INVALIDARG; \
192 if (!target->GetDelegate()) \
193 return E_INVALIDARG;
194
196
197namespace {
198
199typedef std::unordered_set<AXPlatformNodeWin*> AXPlatformNodeWinSet;
200
201
202
203constexpr int kLargeChangeScaleFactor = 10;
204
205
206
207
208constexpr float kSmallScrollIncrement = 40.0f;
209
210
211constexpr wchar_t kUIADLLFilename[] = L"uiautomationcore.dll";
212
213void AppendTextToString(std::u16string extra_text, std::u16string* string) {
214 if (extra_text.empty())
215 return;
216
217 if (string->empty()) {
218 *string = extra_text;
219 return;
220 }
221
222 *string += std::u16string(u". ") + extra_text;
223}
224
225
226
227template <typename T>
228void PatternProvider(AXPlatformNodeWin* node, IUnknown** result) {
229 node->AddRef();
230 *result = static_cast<T*>(node);
231}
232
233}
234
235void AXPlatformNodeWin::AddAttributeToList(
const char*
name,
236 const char* value,
237 PlatformAttributeList* attributes) {
238 std::string str_value =
value;
239 SanitizeStringAttribute(str_value, &str_value);
242}
243
244
245
246
249
250
251
252
253
254
256
258
259 CComObject<AXPlatformNodeWin>*
instance =
nullptr;
260 HRESULT hr = CComObject<AXPlatformNodeWin>::CreateInstance(&
instance);
265}
266
267
271 return nullptr;
272 Microsoft::WRL::ComPtr<AXPlatformNodeWin> ax_platform_node;
273 accessible->QueryInterface(IID_PPV_ARGS(&ax_platform_node));
274 return ax_platform_node.Get();
275}
276
277
278
279
280
281AXPlatformNodeWin::AXPlatformNodeWin() {}
282
283AXPlatformNodeWin::~AXPlatformNodeWin() {}
284
285void AXPlatformNodeWin::Init(AXPlatformNodeDelegate* delegate) {
287}
288
289
290void AXPlatformNodeWin::SanitizeStringAttributeForUIAAriaProperty(
291 const std::u16string&
input,
292 std::u16string* output) {
294
295
296
300}
301
302void AXPlatformNodeWin::StringAttributeToUIAAriaProperty(
303 std::vector<std::u16string>& properties,
305 const char* uia_aria_property) {
306 std::u16string
value;
307 if (GetString16Attribute(attribute, &value)) {
308 SanitizeStringAttributeForUIAAriaProperty(value, &value);
310 }
311}
312
313void AXPlatformNodeWin::BoolAttributeToUIAAriaProperty(
314 std::vector<std::u16string>& properties,
316 const char* uia_aria_property) {
318 if (GetBoolAttribute(attribute, &value)) {
320 (value ? u"true" : u"false"));
321 }
322}
323
324void AXPlatformNodeWin::IntAttributeToUIAAriaProperty(
325 std::vector<std::u16string>& properties,
327 const char* uia_aria_property) {
329 if (GetIntAttribute(attribute, &value)) {
332 }
333}
334
335void AXPlatformNodeWin::FloatAttributeToUIAAriaProperty(
336 std::vector<std::u16string>& properties,
338 const char* uia_aria_property) {
340 if (GetFloatAttribute(attribute, &value)) {
343 }
344}
345
346void AXPlatformNodeWin::StateToUIAAriaProperty(
347 std::vector<std::u16string>& properties,
349 const char* uia_aria_property) {
350 const AXNodeData&
data = GetData();
353 (value ? u"true" : u"false"));
354}
355
356void AXPlatformNodeWin::HtmlAttributeToUIAAriaProperty(
357 std::vector<std::u16string>& properties,
358 const char* html_attribute_name,
359 const char* uia_aria_property) {
360 std::u16string html_attribute_value;
361 if (GetData().GetHtmlAttribute(html_attribute_name, &html_attribute_value)) {
362 SanitizeStringAttributeForUIAAriaProperty(html_attribute_value,
363 &html_attribute_value);
365 html_attribute_value);
366 }
367}
368
369std::vector<AXPlatformNodeWin*>
370AXPlatformNodeWin::CreatePlatformNodeVectorFromRelationIdVector(
371 std::vector<int32_t>& relation_id_list) {
372 std::vector<AXPlatformNodeWin*> platform_node_list;
373
374 for (int32_t id : relation_id_list) {
375 AXPlatformNode* platform_node = GetDelegate()->GetFromNodeID(id);
376 if (IsValidUiaRelationTarget(platform_node)) {
377 platform_node_list.push_back(
378 static_cast<AXPlatformNodeWin*>(platform_node));
379 }
380 }
381
382 return platform_node_list;
383}
384
385SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsSafeArray(
386 std::vector<AXPlatformNodeWin*>& platform_node_list) {
387 if (platform_node_list.empty())
388 return nullptr;
389
390 SAFEARRAY* uia_array =
391 SafeArrayCreateVector(VT_UNKNOWN, 0, platform_node_list.size());
393
394 for (AXPlatformNodeWin* platform_node : platform_node_list) {
395
396
397
398 BASE_DCHECK(IsValidUiaRelationTarget(platform_node));
399 SafeArrayPutElement(uia_array, &
i,
400 static_cast<IRawElementProviderSimple*>(platform_node));
402 }
403
404 return uia_array;
405}
406
407SAFEARRAY* AXPlatformNodeWin::CreateUIAControllerForArray() {
408 std::vector<int32_t> relation_id_list =
410
411 std::vector<AXPlatformNodeWin*> platform_node_list =
412 CreatePlatformNodeVectorFromRelationIdVector(relation_id_list);
413
415 AXPlatformNodeWin* view_popup_node_win = static_cast<AXPlatformNodeWin*>(
417
418 if (IsValidUiaRelationTarget(view_popup_node_win))
419 platform_node_list.push_back(view_popup_node_win);
420 }
421
422 return CreateUIAElementsSafeArray(platform_node_list);
423}
424
425SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsArrayForRelation(
427 std::vector<int32_t> relation_id_list = GetIntListAttribute(attribute);
428
429 std::vector<AXPlatformNodeWin*> platform_node_list =
430 CreatePlatformNodeVectorFromRelationIdVector(relation_id_list);
431
432 return CreateUIAElementsSafeArray(platform_node_list);
433}
434
435SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsArrayForReverseRelation(
437 std::set<AXPlatformNode*> reverse_relations =
438 GetDelegate()->GetReverseRelations(attribute);
439
440 std::vector<int32_t> id_list;
441 std::transform(
442 reverse_relations.cbegin(), reverse_relations.cend(),
443 std::back_inserter(id_list), [](AXPlatformNode* platform_node) {
444 return static_cast<AXPlatformNodeWin*>(platform_node)->GetData().id;
445 });
446
447 std::vector<AXPlatformNodeWin*> platform_node_list =
448 CreatePlatformNodeVectorFromRelationIdVector(id_list);
449
450 return CreateUIAElementsSafeArray(platform_node_list);
451}
452
453SAFEARRAY* AXPlatformNodeWin::CreateClickablePointArray() {
454 SAFEARRAY* clickable_point_array = SafeArrayCreateVector(VT_R8, 0, 2);
458 .CenterPoint();
459
460 double* double_array;
461 SafeArrayAccessData(clickable_point_array,
462 reinterpret_cast<void**>(&double_array));
463 double_array[0] =
center.x();
464 double_array[1] =
center.y();
465 SafeArrayUnaccessData(clickable_point_array);
466
467 return clickable_point_array;
468}
469
471 const ScrollAmount horizontal_amount,
472 const ScrollAmount vertical_amount) const {
473 if (!GetDelegate() || !IsScrollable())
474 return {};
475
476 const gfx::Rect bounds = GetDelegate()->GetBoundsRect(
478 const int large_horizontal_change = bounds.
width();
479 const int large_vertical_change = bounds.
height();
480
481 const HWND hwnd = GetDelegate()->GetTargetForNativeAccessibilityEvent();
484 const int small_change =
486
491
494
495 switch (horizontal_amount) {
496 case ScrollAmount_LargeDecrement:
497 x -= large_horizontal_change;
498 break;
499 case ScrollAmount_LargeIncrement:
500 x += large_horizontal_change;
501 break;
502 case ScrollAmount_NoAmount:
503 break;
504 case ScrollAmount_SmallDecrement:
506 break;
507 case ScrollAmount_SmallIncrement:
509 break;
510 }
511 x = std::min(
x, x_max);
512 x = std::max(
x, x_min);
513
514 switch (vertical_amount) {
515 case ScrollAmount_LargeDecrement:
516 y -= large_vertical_change;
517 break;
518 case ScrollAmount_LargeIncrement:
519 y += large_vertical_change;
520 break;
521 case ScrollAmount_NoAmount:
522 break;
523 case ScrollAmount_SmallDecrement:
525 break;
526 case ScrollAmount_SmallIncrement:
528 break;
529 }
530 y = std::min(
y, y_max);
531 y = std::max(
y, y_min);
532
534}
535
536
537
538
539
540void AXPlatformNodeWin::Dispose() {
541 Release();
542}
543
544void AXPlatformNodeWin::Destroy() {
545 RemoveAlertTarget();
546
547
548
550}
551
552
553
554
555
557 return this;
558}
559
562
563
565
566
567
568 auto* parent =
569 static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(GetParent()));
570 int role = MSAARole();
571 if (role == ROLE_SYSTEM_MENUITEM) {
573 } else if (role == ROLE_SYSTEM_LISTITEM) {
574 if (AXPlatformNodeBase* container = GetSelectionContainer()) {
575 const AXNodeData&
data = container->GetData();
578 GetDelegate()->GetFocus() == GetNativeViewAccessible()) {
580 }
581 }
582 } else if (parent) {
583 int parent_role = parent->MSAARole();
584 if (parent_role == ROLE_SYSTEM_MENUPOPUP ||
585 parent_role == ROLE_SYSTEM_LIST) {
587 }
588 }
589 }
590
592
593
594
595
596 if (!GetDelegate()->IsWebContent())
597 UpdateComputedHypertext();
598 }
599
600 if (std::optional<DWORD> native_event = MojoEventToMSAAEvent(
event_type)) {
601 HWND hwnd = GetDelegate()->GetTargetForNativeAccessibilityEvent();
602 if (!hwnd)
603 return;
604
605 ::NotifyWinEvent((*native_event), hwnd, OBJID_CLIENT, -GetUniqueId());
606 }
607
608 if (std::optional<PROPERTYID> uia_property =
610
612 ::VariantInit(old_value.
Receive());
614 ::VariantInit(new_value.
Receive());
615 GetPropertyValueImpl((*uia_property), new_value.
Receive());
616 ::UiaRaiseAutomationPropertyChangedEvent(this, (*uia_property), old_value,
617 new_value);
618 }
619
620 if (std::optional<EVENTID> uia_event = MojoEventToUIAEvent(
event_type))
621 ::UiaRaiseAutomationEvent(this, (*uia_event));
622
623
625 AddAlertTarget();
626}
627
628bool AXPlatformNodeWin::HasActiveComposition() const {
629 return active_composition_range_.end() > active_composition_range_.start();
630}
631
632gfx::Range AXPlatformNodeWin::GetActiveCompositionOffsets()
const {
633 return active_composition_range_;
634}
635
636void AXPlatformNodeWin::OnActiveComposition(
638 const std::u16string& active_composition_text,
639 bool is_composition_committed) {
640
641
642
643 active_composition_range_ = range;
644
645 FireUiaTextEditTextChangedEvent(range, active_composition_text,
646 is_composition_committed);
647}
648
649void AXPlatformNodeWin::FireUiaTextEditTextChangedEvent(
651 const std::u16string& active_composition_text,
652 bool is_composition_committed) {
653
654
655 using UiaRaiseTextEditTextChangedEventFunction = HRESULT(
WINAPI*)(
656 IRawElementProviderSimple*, TextEditChangeType, SAFEARRAY*);
657 UiaRaiseTextEditTextChangedEventFunction text_edit_text_changed_func =
658 reinterpret_cast<UiaRaiseTextEditTextChangedEventFunction>(
659 ::GetProcAddress(GetModuleHandleW(kUIADLLFilename),
660 "UiaRaiseTextEditTextChangedEvent"));
661 if (!text_edit_text_changed_func) {
662 return;
663 }
664
665 TextEditChangeType text_edit_change_type =
666 is_composition_committed ? TextEditChangeType_CompositionFinalized
667 : TextEditChangeType_Composition;
668
669
671 (wchar_t*)active_composition_text.data());
673 ::SafeArrayCreateVector(VT_BSTR , 0 ,
674 1 ));
675 if (!changed_data.Get()) {
676 return;
677 }
678
680 HRESULT hr =
681 SafeArrayPutElement(changed_data.Get(), &index, composition_text.Get());
682
684 return;
685 } else {
686
687 text_edit_text_changed_func(this, text_edit_change_type,
688 changed_data.Release());
689 }
690}
691
692bool AXPlatformNodeWin::IsValidUiaRelationTarget(
693 AXPlatformNode* ax_platform_node) {
694 if (!ax_platform_node)
695 return false;
696 if (!ax_platform_node->GetDelegate())
697 return false;
698
699
700 if (!ax_platform_node->GetDelegate()->GetTargetForNativeAccessibilityEvent())
701 return false;
702
703 return true;
704}
705
706
707
708
709
710IFACEMETHODIMP AXPlatformNodeWin::accHitTest(
LONG screen_physical_pixel_x,
711 LONG screen_physical_pixel_y,
712 VARIANT* child) {
714
715 gfx::Point point(screen_physical_pixel_x, screen_physical_pixel_y);
716 if (!GetDelegate()
720
721 child->vt = VT_EMPTY;
722 return S_FALSE;
723 }
724
725 AXPlatformNode* current_result = this;
726 while (true) {
728 current_result->GetDelegate()->HitTestSync(screen_physical_pixel_x,
729 screen_physical_pixel_y);
730 if (!hit_child) {
731 child->vt = VT_EMPTY;
732 return S_FALSE;
733 }
734
735 AXPlatformNode* hit_child_node =
737 if (!hit_child_node)
738 break;
739
740
741 if (hit_child_node == current_result)
742 break;
743
744
745
746
747
748
749
750
751
752
753
754
755
756 bool is_descendant = hit_child_node->IsDescendantOf(current_result);
757 bool is_same_hwnd =
758 hit_child_node->GetDelegate()->GetTargetForNativeAccessibilityEvent() ==
759 current_result->GetDelegate()->GetTargetForNativeAccessibilityEvent();
760 if (!is_descendant && is_same_hwnd)
761 break;
762
763
764
765
766
767 current_result = hit_child_node;
768 }
769
770 if (current_result == this) {
771
772
773
774
775 child->vt = VT_I4;
776 child->lVal = CHILDID_SELF;
777 return S_OK;
778 }
779
780 child->vt = VT_DISPATCH;
781 child->pdispVal = static_cast<AXPlatformNodeWin*>(current_result);
782
783 child->pdispVal->AddRef();
784 return S_OK;
785}
786
787IFACEMETHODIMP AXPlatformNodeWin::accDoDefaultAction(VARIANT var_id) {
788 AXPlatformNodeWin*
target;
792
793 if (
target->GetDelegate()->AccessibilityPerformAction(data))
794 return S_OK;
795 return E_FAIL;
796}
797
798IFACEMETHODIMP AXPlatformNodeWin::accLocation(
LONG* physical_pixel_left,
799 LONG* physical_pixel_top,
802 VARIANT var_id) {
803 AXPlatformNodeWin*
target;
806
810 *physical_pixel_left = bounds.
x();
811 *physical_pixel_top = bounds.
y();
814
816 return S_FALSE;
817
818 return S_OK;
819}
820
821IFACEMETHODIMP AXPlatformNodeWin::accNavigate(
LONG nav_dir,
822 VARIANT start,
824 AXPlatformNodeWin*
target;
827 if ((nav_dir == NAVDIR_FIRSTCHILD || nav_dir == NAVDIR_LASTCHILD) &&
828 V_VT(&start) == VT_I4 && V_I4(&start) != CHILDID_SELF) {
829
830 return E_INVALIDARG;
831 }
832
834 switch (nav_dir) {
835 case NAVDIR_FIRSTCHILD:
836 if (GetDelegate()->GetChildCount() > 0)
837 result = GetDelegate()->GetFirstChild();
838 break;
839
840 case NAVDIR_LASTCHILD:
841 if (GetDelegate()->GetChildCount() > 0)
842 result = GetDelegate()->GetLastChild();
843 break;
844
845 case NAVDIR_NEXT: {
846 AXPlatformNodeBase* next =
target->GetNextSibling();
847 if (next)
848 result = next->GetNativeViewAccessible();
849 break;
850 }
851
852 case NAVDIR_PREVIOUS: {
853 AXPlatformNodeBase* previous =
target->GetPreviousSibling();
854 if (previous)
855 result = previous->GetNativeViewAccessible();
856 break;
857 }
858
859 case NAVDIR_DOWN: {
860
861 if (!GetTableRow() || !GetTableRowSpan() || !GetTableColumn())
862 return E_NOTIMPL;
863
864 AXPlatformNodeBase* next =
target->GetTableCell(
865 *GetTableRow() + *GetTableRowSpan(), *GetTableColumn());
866 if (!next)
867 return S_OK;
868
869 result = next->GetNativeViewAccessible();
870 break;
871 }
872
873 case NAVDIR_UP: {
874
875 if (!GetTableRow() || !GetTableColumn())
876 return E_NOTIMPL;
877
878 AXPlatformNodeBase* next =
879 target->GetTableCell(*GetTableRow() - 1, *GetTableColumn());
880 if (!next)
881 return S_OK;
882
883 result = next->GetNativeViewAccessible();
884 break;
885 }
886
887 case NAVDIR_LEFT: {
888
889 if (!GetTableRow() || !GetTableColumn())
890 return E_NOTIMPL;
891
892 AXPlatformNodeBase* next =
893 target->GetTableCell(*GetTableRow(), *GetTableColumn() - 1);
894 if (!next)
895 return S_OK;
896
897 result = next->GetNativeViewAccessible();
898 break;
899 }
900
901 case NAVDIR_RIGHT: {
902
903
904 if (!GetTableRow() || !GetTableColumn() || !GetTableColumnSpan())
905 return E_NOTIMPL;
906
907 AXPlatformNodeBase* next =
target->GetTableCell(
908 *GetTableRow(), *GetTableColumn() + *GetTableColumnSpan());
909 if (!next)
910 return S_OK;
911
912 result = next->GetNativeViewAccessible();
913 break;
914 }
915 }
916
917 if (!result)
918 return S_FALSE;
919
920 end->vt = VT_DISPATCH;
921 end->pdispVal = result;
922
923 end->pdispVal->AddRef();
924
925 return S_OK;
926}
927
928IFACEMETHODIMP AXPlatformNodeWin::get_accChild(VARIANT var_child,
929 IDispatch** disp_child) {
930 *disp_child = nullptr;
931 AXPlatformNodeWin*
target;
933
935 (*disp_child)->AddRef();
936 return S_OK;
937}
938
939IFACEMETHODIMP AXPlatformNodeWin::get_accChildCount(
LONG* child_count) {
941 *child_count = GetDelegate()->GetChildCount();
942 return S_OK;
943}
944
945IFACEMETHODIMP AXPlatformNodeWin::get_accDefaultAction(VARIANT var_id,
946 BSTR* def_action) {
947 AXPlatformNodeWin*
target;
950
954 *def_action = nullptr;
955 return S_FALSE;
956 }
957
958
959
962 if (action_verb.empty()) {
963 *def_action = nullptr;
964 return S_FALSE;
965 }
966
969 return S_OK;
970}
971
972IFACEMETHODIMP AXPlatformNodeWin::get_accDescription(VARIANT var_id,
973 BSTR* desc) {
974 AXPlatformNodeWin*
target;
976
977 return target->GetStringAttributeAsBstr(
979}
980
981IFACEMETHODIMP AXPlatformNodeWin::get_accFocus(VARIANT* focus_child) {
984 if (focus_accessible == this) {
985 focus_child->vt = VT_I4;
986 focus_child->lVal = CHILDID_SELF;
987 } else if (focus_accessible) {
988 Microsoft::WRL::ComPtr<IDispatch> focus_idispatch;
990 focus_accessible->QueryInterface(IID_PPV_ARGS(&focus_idispatch)))) {
991 focus_child->vt = VT_EMPTY;
992 return E_FAIL;
993 }
994
995 focus_child->vt = VT_DISPATCH;
996 focus_child->pdispVal = focus_idispatch.Detach();
997 } else {
998 focus_child->vt = VT_EMPTY;
999 }
1000
1001 return S_OK;
1002}
1003
1004IFACEMETHODIMP AXPlatformNodeWin::get_accKeyboardShortcut(VARIANT var_id,
1005 BSTR* acc_key) {
1006 AXPlatformNodeWin*
target;
1008
1009 return target->GetStringAttributeAsBstr(
1011}
1012
1013IFACEMETHODIMP AXPlatformNodeWin::get_accName(VARIANT var_id, BSTR* name_bstr) {
1014 AXPlatformNodeWin*
target;
1016
1017 if (!IsNameExposed())
1018 return S_FALSE;
1019
1021 std::u16string
name =
target->GetNameAsString16();
1022
1023
1024 const std::u16string tooltip =
1026 if (!tooltip.empty()) {
1027 AppendTextToString(tooltip, &
name);
1028 }
1029
1030 auto status = GetData().GetImageAnnotationStatus();
1031 switch (status) {
1036 break;
1037
1043 AppendTextToString(
1044 GetDelegate()->GetLocalizedStringForImageAnnotationStatus(status),
1046 break;
1047
1049 AppendTextToString(
1052 break;
1053 }
1054
1055 if (
name.empty() && !has_name)
1056 return S_FALSE;
1057
1059 return S_OK;
1060}
1061
1062IFACEMETHODIMP AXPlatformNodeWin::get_accParent(IDispatch** disp_parent) {
1064 *disp_parent = GetParent();
1065 if (*disp_parent) {
1066 (*disp_parent)->AddRef();
1067 return S_OK;
1068 }
1069 IRawElementProviderFragmentRoot* root;
1070 if (
SUCCEEDED(get_FragmentRoot(&root))) {
1072 if (
SUCCEEDED(root->QueryInterface(IID_PPV_ARGS(&parent)))) {
1073 if (parent && parent != GetNativeViewAccessible()) {
1074 *disp_parent = parent;
1075 parent->AddRef();
1076 return S_OK;
1077 }
1078 }
1079 }
1080 return S_FALSE;
1081}
1082
1083IFACEMETHODIMP AXPlatformNodeWin::get_accRole(VARIANT var_id, VARIANT* role) {
1084 AXPlatformNodeWin*
target;
1086
1087 role->vt = VT_I4;
1088 role->lVal =
target->MSAARole();
1089 return S_OK;
1090}
1091
1092IFACEMETHODIMP AXPlatformNodeWin::get_accState(VARIANT var_id, VARIANT* state) {
1093 AXPlatformNodeWin*
target;
1095 state->vt = VT_I4;
1096 state->lVal =
target->MSAAState();
1097 return S_OK;
1098}
1099
1100IFACEMETHODIMP AXPlatformNodeWin::get_accHelp(VARIANT var_id, BSTR* help) {
1102 return S_FALSE;
1103}
1104
1105IFACEMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) {
1106 AXPlatformNodeWin*
target;
1109 return S_OK;
1110}
1111
1112IFACEMETHODIMP AXPlatformNodeWin::put_accValue(VARIANT var_id, BSTR new_value) {
1113 AXPlatformNodeWin*
target;
1115 if (!new_value)
1116 return E_INVALIDARG;
1117
1118 std::u16string new_value_utf16((char16_t*)new_value);
1122 if (
target->GetDelegate()->AccessibilityPerformAction(data))
1123 return S_OK;
1124 return E_FAIL;
1125}
1126
1127IFACEMETHODIMP AXPlatformNodeWin::get_accSelection(VARIANT* selected) {
1129 std::vector<Microsoft::WRL::ComPtr<IDispatch>> selected_nodes;
1130 for (
int i = 0;
i < GetDelegate()->GetChildCount(); ++
i) {
1131 auto* node = static_cast<AXPlatformNodeWin*>(
1132 FromNativeViewAccessible(GetDelegate()->ChildAtIndex(
i)));
1133 if (node &&
1135 Microsoft::WRL::ComPtr<IDispatch> node_idispatch;
1136 if (
SUCCEEDED(node->QueryInterface(IID_PPV_ARGS(&node_idispatch))))
1137 selected_nodes.push_back(node_idispatch);
1138 }
1139 }
1140
1141 if (selected_nodes.empty()) {
1142 selected->vt = VT_EMPTY;
1143 return S_OK;
1144 }
1145
1146 if (selected_nodes.size() == 1) {
1147 selected->vt = VT_DISPATCH;
1148 selected->pdispVal = selected_nodes[0].Detach();
1149 return S_OK;
1150 }
1151
1152
1153 LONG selected_count =
static_cast<LONG>(selected_nodes.size());
1154 Microsoft::WRL::ComPtr<base::win::EnumVariant> enum_variant =
1155 Microsoft::WRL::Make<base::win::EnumVariant>(selected_count);
1156 for (
LONG i = 0;
i < selected_count; ++
i) {
1157 enum_variant->ItemAt(
i)->vt = VT_DISPATCH;
1158 enum_variant->ItemAt(
i)->pdispVal = selected_nodes[
i].Detach();
1159 }
1160 selected->vt = VT_UNKNOWN;
1161 return enum_variant.CopyTo(IID_PPV_ARGS(&V_UNKNOWN(selected)));
1162}
1163
1164IFACEMETHODIMP AXPlatformNodeWin::accSelect(
LONG flagsSelect, VARIANT var_id) {
1165 AXPlatformNodeWin*
target;
1167
1168 if (flagsSelect & SELFLAG_TAKEFOCUS) {
1169 AXActionData action_data;
1171 target->GetDelegate()->AccessibilityPerformAction(action_data);
1172 return S_OK;
1173 }
1174
1175 return S_FALSE;
1176}
1177
1178IFACEMETHODIMP AXPlatformNodeWin::get_accHelpTopic(BSTR* help_file,
1179 VARIANT var_id,
1181 AXPlatformNodeWin*
target;
1184 if (help_file) {
1185 *help_file = nullptr;
1186 }
1187 if (topic_id) {
1188 *topic_id =
static_cast<LONG>(-1);
1189 }
1190 return E_NOTIMPL;
1191}
1192
1193IFACEMETHODIMP AXPlatformNodeWin::put_accName(VARIANT var_id, BSTR put_name) {
1194
1195
1196 return E_NOTIMPL;
1197}
1198
1199
1200
1201
1202
1203IFACEMETHODIMP AXPlatformNodeWin::GetObjectForChild(
LONG child_id,
1204 IAccessibleEx** result) {
1205
1207 *result = nullptr;
1208 return S_OK;
1209}
1210
1211IFACEMETHODIMP AXPlatformNodeWin::GetIAccessiblePair(IAccessible**
accessible,
1215 (*accessible)->AddRef();
1216 *child_id = CHILDID_SELF;
1217 return S_OK;
1218}
1219
1220
1221IFACEMETHODIMP
1222AXPlatformNodeWin::ConvertReturnedElement(IRawElementProviderSimple* element,
1223 IAccessibleEx** acc) {
1224 return E_NOTIMPL;
1225}
1226
1227
1228
1229
1230
1231IFACEMETHODIMP AXPlatformNodeWin::Collapse() {
1234 return UIA_E_ELEMENTNOTAVAILABLE;
1235
1237 return UIA_E_INVALIDOPERATION;
1238
1239 AXActionData action_data;
1241 if (GetDelegate()->AccessibilityPerformAction(action_data))
1242 return S_OK;
1243 return E_FAIL;
1244}
1245
1246IFACEMETHODIMP AXPlatformNodeWin::Expand() {
1249 return UIA_E_ELEMENTNOTAVAILABLE;
1250
1252 return UIA_E_INVALIDOPERATION;
1253
1254 AXActionData action_data;
1256 if (GetDelegate()->AccessibilityPerformAction(action_data))
1257 return S_OK;
1258 return E_FAIL;
1259}
1260
1261ExpandCollapseState AXPlatformNodeWin::ComputeExpandCollapseState() const {
1262 const AXNodeData&
data = GetData();
1263
1264
1265
1266
1267
1268 if (
data.IsMenuButton()) {
1269 if (
data.IsButtonPressed())
1270 return ExpandCollapseState_Expanded;
1271 return ExpandCollapseState_Collapsed;
1272 }
1273
1275 return ExpandCollapseState_Expanded;
1277 return ExpandCollapseState_Collapsed;
1278 } else {
1279 return ExpandCollapseState_LeafNode;
1280 }
1281}
1282
1283IFACEMETHODIMP AXPlatformNodeWin::get_ExpandCollapseState(
1284 ExpandCollapseState* result) {
1286
1287 *result = ComputeExpandCollapseState();
1288
1289 return S_OK;
1290}
1291
1292
1293
1294
1295
1296IFACEMETHODIMP AXPlatformNodeWin::get_Column(int* result) {
1298 std::optional<int> column = GetTableColumn();
1299 if (!column)
1300 return E_FAIL;
1301 *result = *column;
1302 return S_OK;
1303}
1304
1305IFACEMETHODIMP AXPlatformNodeWin::get_ColumnSpan(int* result) {
1307 std::optional<int> column_span = GetTableColumnSpan();
1308 if (!column_span)
1309 return E_FAIL;
1310 *result = *column_span;
1311 return S_OK;
1312}
1313
1314IFACEMETHODIMP AXPlatformNodeWin::get_ContainingGrid(
1315 IRawElementProviderSimple** result) {
1317
1318 AXPlatformNodeBase* table = GetTable();
1319 if (!table)
1320 return E_FAIL;
1321
1322 auto* node_win = static_cast<AXPlatformNodeWin*>(table);
1323 node_win->AddRef();
1324 *result = static_cast<IRawElementProviderSimple*>(node_win);
1325 return S_OK;
1326}
1327
1328IFACEMETHODIMP AXPlatformNodeWin::get_Row(int* result) {
1330 std::optional<int> row = GetTableRow();
1331 if (!row)
1332 return E_FAIL;
1333 *result = *row;
1334 return S_OK;
1335}
1336
1337IFACEMETHODIMP AXPlatformNodeWin::get_RowSpan(int* result) {
1339 std::optional<int> row_span = GetTableRowSpan();
1340 if (!row_span)
1341 return E_FAIL;
1342 *result = *row_span;
1343 return S_OK;
1344}
1345
1346
1347
1348
1349
1350IFACEMETHODIMP AXPlatformNodeWin::GetItem(int row,
1351 int column,
1352 IRawElementProviderSimple** result) {
1354
1355 AXPlatformNodeBase* cell = GetTableCell(row, column);
1356 if (!cell)
1357 return E_INVALIDARG;
1358
1359 auto* node_win = static_cast<AXPlatformNodeWin*>(cell);
1360 node_win->AddRef();
1361 *result = static_cast<IRawElementProviderSimple*>(node_win);
1362 return S_OK;
1363}
1364
1365IFACEMETHODIMP AXPlatformNodeWin::get_RowCount(int* result) {
1367
1368 std::optional<int> row_count = GetTableAriaRowCount();
1369 if (!row_count)
1370 row_count = GetTableRowCount();
1371
1373 return E_UNEXPECTED;
1374 *result = *row_count;
1375 return S_OK;
1376}
1377
1378IFACEMETHODIMP AXPlatformNodeWin::get_ColumnCount(int* result) {
1380
1381 std::optional<int> column_count = GetTableAriaColumnCount();
1382 if (!column_count)
1383 column_count = GetTableColumnCount();
1384
1385 if (!column_count ||
1387 return E_UNEXPECTED;
1388 }
1389 *result = *column_count;
1390 return S_OK;
1391}
1392
1393
1394
1395
1396
1397IFACEMETHODIMP AXPlatformNodeWin::Invoke() {
1399
1401 return UIA_E_ELEMENTNOTENABLED;
1402
1403 AXActionData action_data;
1405 GetDelegate()->AccessibilityPerformAction(action_data);
1406
1407 return S_OK;
1408}
1409
1410
1411
1412
1413
1414IFACEMETHODIMP AXPlatformNodeWin::ScrollIntoView() {
1418
1419 AXActionData action_data;
1420 action_data.target_node_id = GetData().id;
1421 action_data.target_rect = r;
1422 action_data.horizontal_scroll_alignment =
1424 action_data.vertical_scroll_alignment =
1426 action_data.scroll_behavior =
1428 if (GetDelegate()->AccessibilityPerformAction(action_data))
1429 return S_OK;
1430 return E_FAIL;
1431}
1432
1433
1434
1435
1436
1437IFACEMETHODIMP AXPlatformNodeWin::Scroll(ScrollAmount horizontal_amount,
1438 ScrollAmount vertical_amount) {
1440 if (!IsScrollable())
1441 return E_FAIL;
1442
1443 AXActionData action_data;
1444 action_data.target_node_id = GetData().id;
1447 CalculateUIAScrollPoint(horizontal_amount, vertical_amount));
1448 if (GetDelegate()->AccessibilityPerformAction(action_data))
1449 return S_OK;
1450 return E_FAIL;
1451}
1452
1453IFACEMETHODIMP AXPlatformNodeWin::SetScrollPercent(double horizontal_percent,
1454 double vertical_percent) {
1456 if (!IsScrollable())
1457 return E_FAIL;
1458
1468
1469 AXActionData action_data;
1470 action_data.target_node_id = GetData().id;
1472 action_data.target_point = scroll_to;
1473 if (GetDelegate()->AccessibilityPerformAction(action_data))
1474 return S_OK;
1475 return E_FAIL;
1476}
1477
1478IFACEMETHODIMP AXPlatformNodeWin::get_HorizontallyScrollable(
BOOL* result) {
1480 *result = IsHorizontallyScrollable();
1481 return S_OK;
1482}
1483
1484IFACEMETHODIMP AXPlatformNodeWin::get_HorizontalScrollPercent(double* result) {
1486 *result = GetHorizontalScrollPercent();
1487 return S_OK;
1488}
1489
1490
1491
1492IFACEMETHODIMP AXPlatformNodeWin::get_HorizontalViewSize(double* result) {
1494 if (!IsHorizontallyScrollable()) {
1495 *result = 100.;
1496 return S_OK;
1497 }
1498
1499 gfx::RectF clipped_bounds(GetDelegate()->GetBoundsRect(
1503 float total_width = clipped_bounds.width() + x_max - x_min;
1504 BASE_DCHECK(clipped_bounds.width() <= total_width);
1505 *result = 100.0 * clipped_bounds.width() / total_width;
1506 return S_OK;
1507}
1508
1509IFACEMETHODIMP AXPlatformNodeWin::get_VerticallyScrollable(
BOOL* result) {
1511 *result = IsVerticallyScrollable();
1512 return S_OK;
1513}
1514
1515IFACEMETHODIMP AXPlatformNodeWin::get_VerticalScrollPercent(double* result) {
1517 *result = GetVerticalScrollPercent();
1518 return S_OK;
1519}
1520
1521
1522
1523IFACEMETHODIMP AXPlatformNodeWin::get_VerticalViewSize(double* result) {
1525 if (!IsVerticallyScrollable()) {
1526 *result = 100.0;
1527 return S_OK;
1528 }
1529
1530 gfx::RectF clipped_bounds(GetDelegate()->GetBoundsRect(
1534 float total_height = clipped_bounds.height() + y_max - y_min;
1535 BASE_DCHECK(clipped_bounds.height() <= total_height);
1536 *result = 100.0 * clipped_bounds.height() / total_height;
1537 return S_OK;
1538}
1539
1540
1541
1542
1543
1544HRESULT AXPlatformNodeWin::ISelectionItemProviderSetSelected(
1545 bool selected) const {
1548 return UIA_E_ELEMENTNOTENABLED;
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565 if (selected == ISelectionItemProviderIsSelected() &&
1567 return S_OK;
1568
1571 if (GetDelegate()->AccessibilityPerformAction(data))
1572 return S_OK;
1573 return UIA_E_INVALIDOPERATION;
1574}
1575
1576bool AXPlatformNodeWin::ISelectionItemProviderIsSelected() const {
1577
1578
1579
1583
1584
1585
1586
1588}
1589
1590IFACEMETHODIMP AXPlatformNodeWin::AddToSelection() {
1591 return ISelectionItemProviderSetSelected(true);
1592}
1593
1594IFACEMETHODIMP AXPlatformNodeWin::RemoveFromSelection() {
1595 return ISelectionItemProviderSetSelected(false);
1596}
1597
1598IFACEMETHODIMP AXPlatformNodeWin::Select() {
1599 return ISelectionItemProviderSetSelected(true);
1600}
1601
1602IFACEMETHODIMP AXPlatformNodeWin::get_IsSelected(
BOOL* result) {
1604 *result = ISelectionItemProviderIsSelected();
1605 return S_OK;
1606}
1607
1608IFACEMETHODIMP AXPlatformNodeWin::get_SelectionContainer(
1609 IRawElementProviderSimple** result) {
1611
1612 auto* node_win = static_cast<AXPlatformNodeWin*>(GetSelectionContainer());
1613 if (!node_win)
1614 return E_FAIL;
1615
1616 node_win->AddRef();
1617 *result = static_cast<IRawElementProviderSimple*>(node_win);
1618 return S_OK;
1619}
1620
1621
1622
1623
1624
1625IFACEMETHODIMP AXPlatformNodeWin::GetSelection(SAFEARRAY** result) {
1627
1628 std::vector<AXPlatformNodeBase*> selected_children;
1629 int max_items = GetMaxSelectableItems();
1630 if (max_items)
1631 GetSelectedItems(max_items, &selected_children);
1632
1633 LONG selected_children_count = selected_children.size();
1634 *result = SafeArrayCreateVector(VT_UNKNOWN, 0, selected_children_count);
1635 if (!*result)
1636 return E_OUTOFMEMORY;
1637
1638 for (
LONG i = 0;
i < selected_children_count; ++
i) {
1639 AXPlatformNodeWin* children =
1640 static_cast<AXPlatformNodeWin*
>(selected_children[
i]);
1641 HRESULT hr = SafeArrayPutElement(
1642 *result, &
i,
static_cast<IRawElementProviderSimple*
>(children));
1644 SafeArrayDestroy(*result);
1645 *result = nullptr;
1646 return hr;
1647 }
1648 }
1649 return S_OK;
1650}
1651
1652IFACEMETHODIMP AXPlatformNodeWin::get_CanSelectMultiple(
BOOL* result) {
1655 return S_OK;
1656}
1657
1658IFACEMETHODIMP AXPlatformNodeWin::get_IsSelectionRequired(
BOOL* result) {
1661 return S_OK;
1662}
1663
1664
1665
1666
1667
1668IFACEMETHODIMP AXPlatformNodeWin::GetColumnHeaderItems(SAFEARRAY** result) {
1670
1671 std::optional<int> column = GetTableColumn();
1672 if (!column)
1673 return E_FAIL;
1674
1675 std::vector<int32_t> column_header_ids =
1676 GetDelegate()->GetColHeaderNodeIds(*column);
1677
1678 std::vector<AXPlatformNodeWin*> platform_node_list =
1679 CreatePlatformNodeVectorFromRelationIdVector(column_header_ids);
1680
1681 *result = CreateUIAElementsSafeArray(platform_node_list);
1682 return S_OK;
1683}
1684
1685IFACEMETHODIMP AXPlatformNodeWin::GetRowHeaderItems(SAFEARRAY** result) {
1687
1688 std::optional<int> row = GetTableRow();
1689 if (!row)
1690 return E_FAIL;
1691
1692 std::vector<int32_t> row_header_ids =
1693 GetDelegate()->GetRowHeaderNodeIds(*row);
1694
1695 std::vector<AXPlatformNodeWin*> platform_node_list =
1696 CreatePlatformNodeVectorFromRelationIdVector(row_header_ids);
1697
1698 *result = CreateUIAElementsSafeArray(platform_node_list);
1699 return S_OK;
1700}
1701
1702
1703
1704
1705
1706IFACEMETHODIMP AXPlatformNodeWin::GetColumnHeaders(SAFEARRAY** result) {
1708
1709 std::vector<int32_t> column_header_ids = GetDelegate()->GetColHeaderNodeIds();
1710
1711 std::vector<AXPlatformNodeWin*> platform_node_list =
1712 CreatePlatformNodeVectorFromRelationIdVector(column_header_ids);
1713
1714 *result = CreateUIAElementsSafeArray(platform_node_list);
1715 return S_OK;
1716}
1717
1718IFACEMETHODIMP AXPlatformNodeWin::GetRowHeaders(SAFEARRAY** result) {
1720
1721 std::vector<int32_t> row_header_ids = GetDelegate()->GetRowHeaderNodeIds();
1722
1723 std::vector<AXPlatformNodeWin*> platform_node_list =
1724 CreatePlatformNodeVectorFromRelationIdVector(row_header_ids);
1725
1726 *result = CreateUIAElementsSafeArray(platform_node_list);
1727 return S_OK;
1728}
1729
1730IFACEMETHODIMP AXPlatformNodeWin::get_RowOrColumnMajor(
1731 RowOrColumnMajor* result) {
1733
1734
1735
1736 *result = RowOrColumnMajor_RowMajor;
1737 return S_OK;
1738}
1739
1740
1741
1742
1743
1744IFACEMETHODIMP AXPlatformNodeWin::Toggle() {
1746 AXActionData action_data;
1748
1749 if (GetDelegate()->AccessibilityPerformAction(action_data))
1750 return S_OK;
1751 return E_FAIL;
1752}
1753
1754IFACEMETHODIMP AXPlatformNodeWin::get_ToggleState(ToggleState* result) {
1756 const auto checked_state = GetData().GetCheckedState();
1758 *result = ToggleState_On;
1760 *result = ToggleState_Indeterminate;
1761 } else {
1762 *result = ToggleState_Off;
1763 }
1764 return S_OK;
1765}
1766
1767
1768
1769
1770
1771IFACEMETHODIMP AXPlatformNodeWin::SetValue(LPCWSTR value) {
1773 if (!value)
1774 return E_INVALIDARG;
1775
1776 if (GetData().IsReadOnlyOrDisabled())
1777 return UIA_E_ELEMENTNOTENABLED;
1778
1782 if (GetDelegate()->AccessibilityPerformAction(data))
1783 return S_OK;
1784 return E_FAIL;
1785}
1786
1787IFACEMETHODIMP AXPlatformNodeWin::get_IsReadOnly(
BOOL* result) {
1789 *result = GetData().IsReadOnlyOrDisabled();
1790 return S_OK;
1791}
1792
1793IFACEMETHODIMP AXPlatformNodeWin::get_Value(BSTR* result) {
1795 *result = GetValueAttributeAsBstr(this);
1796 return S_OK;
1797}
1798
1799
1800
1801
1802
1803IFACEMETHODIMP AXPlatformNodeWin::SetVisualState(
1804 WindowVisualState window_visual_state) {
1806 return UIA_E_NOTSUPPORTED;
1807}
1808
1809IFACEMETHODIMP AXPlatformNodeWin::Close() {
1811 return UIA_E_NOTSUPPORTED;
1812}
1813
1814IFACEMETHODIMP AXPlatformNodeWin::WaitForInputIdle(int milliseconds,
1817 return UIA_E_NOTSUPPORTED;
1818}
1819
1820IFACEMETHODIMP AXPlatformNodeWin::get_CanMaximize(
BOOL* result) {
1822 return UIA_E_NOTSUPPORTED;
1823}
1824
1825IFACEMETHODIMP AXPlatformNodeWin::get_CanMinimize(
BOOL* result) {
1827 return UIA_E_NOTSUPPORTED;
1828}
1829
1830IFACEMETHODIMP AXPlatformNodeWin::get_IsModal(
BOOL* result) {
1832
1834
1835 return S_OK;
1836}
1837
1838IFACEMETHODIMP AXPlatformNodeWin::get_WindowVisualState(
1839 WindowVisualState* result) {
1841 return UIA_E_NOTSUPPORTED;
1842}
1843
1844IFACEMETHODIMP AXPlatformNodeWin::get_WindowInteractionState(
1845 WindowInteractionState* result) {
1847 return UIA_E_NOTSUPPORTED;
1848}
1849
1850IFACEMETHODIMP AXPlatformNodeWin::get_IsTopmost(
BOOL* result) {
1852 return UIA_E_NOTSUPPORTED;
1853}
1854
1855
1856
1857
1858
1859IFACEMETHODIMP AXPlatformNodeWin::SetValue(double value) {
1864 if (GetDelegate()->AccessibilityPerformAction(data))
1865 return S_OK;
1866 return E_FAIL;
1867}
1868
1869IFACEMETHODIMP AXPlatformNodeWin::get_LargeChange(double* result) {
1871 float attribute;
1873 &attribute)) {
1874 *result = attribute * kLargeChangeScaleFactor;
1875 return S_OK;
1876 }
1877 return E_FAIL;
1878}
1879
1880IFACEMETHODIMP AXPlatformNodeWin::get_Maximum(double* result) {
1882 float attribute;
1884 &attribute)) {
1885 *result = attribute;
1886 return S_OK;
1887 }
1888 return E_FAIL;
1889}
1890
1891IFACEMETHODIMP AXPlatformNodeWin::get_Minimum(double* result) {
1893 float attribute;
1895 &attribute)) {
1896 *result = attribute;
1897 return S_OK;
1898 }
1899 return E_FAIL;
1900}
1901
1902IFACEMETHODIMP AXPlatformNodeWin::get_SmallChange(double* result) {
1904 float attribute;
1906 &attribute)) {
1907 *result = attribute;
1908 return S_OK;
1909 }
1910 return E_FAIL;
1911}
1912
1913IFACEMETHODIMP AXPlatformNodeWin::get_Value(double* result) {
1915 float attribute;
1917 &attribute)) {
1918 *result = attribute;
1919 return S_OK;
1920 }
1921 return E_FAIL;
1922}
1923
1924
1925
1926
1927
1928IFACEMETHODIMP AXPlatformNodeWin::Navigate(
1929 NavigateDirection direction,
1930 IRawElementProviderFragment** element_provider) {
1932
1933 *element_provider = nullptr;
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1983 switch (direction) {
1984 case NavigateDirection_Parent: {
1985
1986
1987 AXFragmentRootWin* fragment_root =
1990 neighbor = fragment_root->GetNativeViewAccessible();
1991 } else {
1992 neighbor = GetParent();
1993 }
1994 } break;
1995
1996 case NavigateDirection_FirstChild:
1997 if (GetChildCount() > 0)
1998 neighbor = GetFirstChild()->GetNativeViewAccessible();
1999 break;
2000
2001 case NavigateDirection_LastChild:
2002 if (GetChildCount() > 0)
2003 neighbor = GetLastChild()->GetNativeViewAccessible();
2004 break;
2005
2006 case NavigateDirection_NextSibling:
2007
2009 GetNativeViewAccessible()) == nullptr) {
2010 AXPlatformNodeBase* neighbor_node = GetNextSibling();
2011 if (neighbor_node)
2012 neighbor = neighbor_node->GetNativeViewAccessible();
2013 }
2014 break;
2015
2016 case NavigateDirection_PreviousSibling:
2017
2019 GetNativeViewAccessible()) == nullptr) {
2020 AXPlatformNodeBase* neighbor_node = GetPreviousSibling();
2021 if (neighbor_node)
2022 neighbor = neighbor_node->GetNativeViewAccessible();
2023 }
2024 break;
2025
2026 default:
2028 break;
2029 }
2030
2031 if (neighbor) {
2032 if (direction != NavigateDirection_Parent) {
2033
2034
2035 AXFragmentRootWin* fragment_root =
2037 if (
BASE_UNLIKELY(fragment_root && fragment_root != GetDelegate()))
2038 neighbor = fragment_root->GetNativeViewAccessible();
2039 }
2040 neighbor->QueryInterface(IID_PPV_ARGS(element_provider));
2041 }
2042
2043 return S_OK;
2044}
2045
2046void AXPlatformNodeWin::GetRuntimeIdArray(
2047 AXPlatformNodeWin::RuntimeIdArray& runtime_id) {
2048 runtime_id[0] = UiaAppendRuntimeId;
2049 runtime_id[1] = GetUniqueId();
2050}
2051
2052IFACEMETHODIMP AXPlatformNodeWin::GetRuntimeId(SAFEARRAY** runtime_id) {
2054
2055 RuntimeIdArray id_array;
2056 GetRuntimeIdArray(id_array);
2057 *runtime_id = ::SafeArrayCreateVector(VT_I4, 0, id_array.size());
2058
2059 int* array_data = nullptr;
2060 ::SafeArrayAccessData(*runtime_id, reinterpret_cast<void**>(&array_data));
2061
2062 size_t runtime_id_byte_count = id_array.size() * sizeof(int);
2063 memcpy_s(array_data, runtime_id_byte_count, id_array.data(),
2064 runtime_id_byte_count);
2065
2066 ::SafeArrayUnaccessData(*runtime_id);
2067
2068 return S_OK;
2069}
2070
2071IFACEMETHODIMP AXPlatformNodeWin::get_BoundingRectangle(
2072 UiaRect* screen_physical_pixel_bounds) {
2074
2078 screen_physical_pixel_bounds->left = bounds.
x();
2079 screen_physical_pixel_bounds->top = bounds.
y();
2080 screen_physical_pixel_bounds->width = bounds.
width();
2081 screen_physical_pixel_bounds->height = bounds.
height();
2082 return S_OK;
2083}
2084
2085IFACEMETHODIMP AXPlatformNodeWin::GetEmbeddedFragmentRoots(
2086 SAFEARRAY** embedded_fragment_roots) {
2088
2089 *embedded_fragment_roots = nullptr;
2090 return S_OK;
2091}
2092
2093IFACEMETHODIMP AXPlatformNodeWin::SetFocus() {
2095
2096 AXActionData action_data;
2098 delegate_->AccessibilityPerformAction(action_data);
2099 return S_OK;
2100}
2101
2102IFACEMETHODIMP AXPlatformNodeWin::get_FragmentRoot(
2103 IRawElementProviderFragmentRoot** fragment_root) {
2105
2106 gfx::AcceleratedWidget widget =
2107 delegate_->GetTargetForNativeAccessibilityEvent();
2108 if (widget) {
2109 AXFragmentRootWin* root =
2111 if (root != nullptr) {
2112 root->GetNativeViewAccessible()->QueryInterface(
2113 IID_PPV_ARGS(fragment_root));
2115 return S_OK;
2116 }
2117 }
2118
2119 *fragment_root = nullptr;
2120 return UIA_E_ELEMENTNOTAVAILABLE;
2121}
2122
2123
2124
2125
2126
2127IFACEMETHODIMP AXPlatformNodeWin::GetPatternProvider(PATTERNID pattern_id,
2128 IUnknown** result) {
2129 return GetPatternProviderImpl(pattern_id, result);
2130}
2131
2132HRESULT AXPlatformNodeWin::GetPatternProviderImpl(PATTERNID pattern_id,
2133 IUnknown** result) {
2135
2136 *result = nullptr;
2137
2138 PatternProviderFactoryMethod factory_method =
2139 GetPatternProviderFactoryMethod(pattern_id);
2140 if (factory_method)
2141 (*factory_method)(this, result);
2142
2143 return S_OK;
2144}
2145
2146IFACEMETHODIMP AXPlatformNodeWin::GetPropertyValue(PROPERTYID property_id,
2147 VARIANT* result) {
2148 return GetPropertyValueImpl(property_id, result);
2149}
2150
2151HRESULT AXPlatformNodeWin::GetPropertyValueImpl(PROPERTYID property_id,
2152 VARIANT* result) {
2154
2155 result->vt = VT_EMPTY;
2156
2157 int int_attribute;
2158 const AXNodeData&
data = GetData();
2159
2160
2161 switch (property_id) {
2162 case UIA_AriaPropertiesPropertyId:
2163 result->vt = VT_BSTR;
2164 result->bstrVal = ::SysAllocString(
2166 break;
2167
2168 case UIA_AriaRolePropertyId:
2169 result->vt = VT_BSTR;
2170 result->bstrVal =
2172 break;
2173
2174 case UIA_AutomationIdPropertyId:
2175 V_VT(result) = VT_BSTR;
2176 V_BSTR(result) = ::SysAllocString(
2178 break;
2179
2180 case UIA_ClassNamePropertyId:
2181 result->vt = VT_BSTR;
2183 &result->bstrVal);
2184 break;
2185
2186 case UIA_ClickablePointPropertyId:
2187 result->vt = VT_ARRAY | VT_R8;
2188 result->parray = CreateClickablePointArray();
2189 break;
2190
2191 case UIA_ControllerForPropertyId:
2192 result->vt = VT_ARRAY | VT_UNKNOWN;
2193 result->parray = CreateUIAControllerForArray();
2194 break;
2195
2196 case UIA_ControlTypePropertyId:
2197 result->vt = VT_I4;
2198 result->lVal = ComputeUIAControlType();
2199 break;
2200
2201 case UIA_CulturePropertyId: {
2202 std::optional<LCID> lcid = GetCultureAttributeAsLCID();
2203 if (!lcid)
2204 return E_FAIL;
2205 result->vt = VT_I4;
2206 result->lVal = lcid.value();
2207 break;
2208 }
2209
2210 case UIA_DescribedByPropertyId:
2211 result->vt = VT_ARRAY | VT_UNKNOWN;
2212 result->parray = CreateUIAElementsArrayForRelation(
2214 break;
2215
2216 case UIA_FlowsFromPropertyId:
2217 V_VT(result) = VT_ARRAY | VT_UNKNOWN;
2218 V_ARRAY(result) = CreateUIAElementsArrayForReverseRelation(
2220 break;
2221
2222 case UIA_FlowsToPropertyId:
2223 result->vt = VT_ARRAY | VT_UNKNOWN;
2224 result->parray = CreateUIAElementsArrayForRelation(
2226 break;
2227
2228 case UIA_FrameworkIdPropertyId:
2229 V_VT(result) = VT_BSTR;
2230 V_BSTR(result) = SysAllocString(FRAMEWORK_ID);
2231 break;
2232
2233 case UIA_HasKeyboardFocusPropertyId:
2234 result->vt = VT_BOOL;
2235 result->boolVal = (
delegate_->GetFocus() == GetNativeViewAccessible())
2236 ? VARIANT_TRUE
2237 : VARIANT_FALSE;
2238 break;
2239
2240 case UIA_FullDescriptionPropertyId:
2241 result->vt = VT_BSTR;
2243 &result->bstrVal);
2244 break;
2245
2246 case UIA_HelpTextPropertyId:
2248 V_VT(result) = VT_BSTR;
2250 &V_BSTR(result));
2253 V_VT(result) = VT_BSTR;
2254 GetNameAsBstr(&V_BSTR(result));
2256 V_VT(result) = VT_BSTR;
2258 &V_BSTR(result));
2259 }
2260 break;
2261
2262 case UIA_IsContentElementPropertyId:
2263 case UIA_IsControlElementPropertyId:
2264 result->vt = VT_BOOL;
2265 result->boolVal = IsUIAControl() ? VARIANT_TRUE : VARIANT_FALSE;
2266 break;
2267
2268 case UIA_IsDataValidForFormPropertyId:
2270 &int_attribute)) {
2271 result->vt = VT_BOOL;
2272 result->boolVal =
2274 ? VARIANT_TRUE
2275 : VARIANT_FALSE;
2276 }
2277 break;
2278
2279 case UIA_IsDialogPropertyId:
2280 result->vt = VT_BOOL;
2281 result->boolVal =
IsDialog(
data.role) ? VARIANT_TRUE : VARIANT_FALSE;
2282 break;
2283
2284 case UIA_IsKeyboardFocusablePropertyId:
2285 result->vt = VT_BOOL;
2286 result->boolVal =
2287 ShouldNodeHaveFocusableState(data) ? VARIANT_TRUE : VARIANT_FALSE;
2288 break;
2289
2290 case UIA_IsOffscreenPropertyId:
2291 result->vt = VT_BOOL;
2292 result->boolVal =
2293 GetDelegate()->IsOffscreen() ? VARIANT_TRUE : VARIANT_FALSE;
2294 break;
2295
2296 case UIA_IsRequiredForFormPropertyId:
2297 result->vt = VT_BOOL;
2299 result->boolVal = VARIANT_TRUE;
2300 } else {
2301 result->boolVal = VARIANT_FALSE;
2302 }
2303 break;
2304
2305 case UIA_ItemStatusPropertyId: {
2306
2307
2308
2309 int32_t sort_direction;
2312 &sort_direction)) {
2316 break;
2318 V_VT(result) = VT_BSTR;
2319 V_BSTR(result) = SysAllocString(L"ascending");
2320 break;
2322 V_VT(result) = VT_BSTR;
2323 V_BSTR(result) = SysAllocString(L"descending");
2324 break;
2326 V_VT(result) = VT_BSTR;
2327 V_BSTR(result) = SysAllocString(L"other");
2328 break;
2329 }
2330 }
2331 break;
2332 }
2333
2334 case UIA_LabeledByPropertyId:
2335 if (AXPlatformNodeWin* node = ComputeUIALabeledBy()) {
2336 result->vt = VT_UNKNOWN;
2337 result->punkVal = node->GetNativeViewAccessible();
2338 result->punkVal->AddRef();
2339 }
2340 break;
2341
2342 case UIA_LocalizedControlTypePropertyId: {
2343 std::u16string localized_control_type = GetRoleDescription();
2344 if (!localized_control_type.empty()) {
2345 result->vt = VT_BSTR;
2346 result->bstrVal = ::SysAllocString(
2348 }
2349
2350
2351
2352
2353 } break;
2354
2355 case UIA_NamePropertyId:
2356 if (IsNameExposed()) {
2357 result->vt = VT_BSTR;
2358 GetNameAsBstr(&result->bstrVal);
2359 }
2360 break;
2361
2362 case UIA_OrientationPropertyId:
2367
2368
2369 }
2371 result->vt = VT_I4;
2372 result->intVal = OrientationType_Horizontal;
2373 }
2375 result->vt = VT_I4;
2376 result->intVal = OrientationType_Vertical;
2377 }
2378 } else {
2379 result->vt = VT_I4;
2380 result->intVal = OrientationType_None;
2381 }
2382 break;
2383
2384 case UIA_IsEnabledPropertyId:
2385 V_VT(result) = VT_BOOL;
2386 switch (
data.GetRestriction()) {
2388 V_BOOL(result) = VARIANT_FALSE;
2389 break;
2390
2393 V_BOOL(result) = VARIANT_TRUE;
2394 break;
2395 }
2396 break;
2397
2398 case UIA_IsPasswordPropertyId:
2399 result->vt = VT_BOOL;
2401 ? VARIANT_TRUE
2402 : VARIANT_FALSE;
2403 break;
2404
2405 case UIA_AcceleratorKeyPropertyId:
2407 result->vt = VT_BSTR;
2409 &result->bstrVal);
2410 }
2411 break;
2412
2413 case UIA_AccessKeyPropertyId:
2415 result->vt = VT_BSTR;
2417 &result->bstrVal);
2418 }
2419 break;
2420
2421 case UIA_IsPeripheralPropertyId:
2422 result->vt = VT_BOOL;
2423 result->boolVal = VARIANT_FALSE;
2424 break;
2425
2426 case UIA_LevelPropertyId:
2428 &int_attribute)) {
2429 result->vt = VT_I4;
2430 result->intVal = int_attribute;
2431 }
2432 break;
2433
2434 case UIA_LiveSettingPropertyId: {
2435 result->vt = VT_I4;
2436 result->intVal = LiveSetting::Off;
2437
2438 std::string string_attribute;
2440 &string_attribute)) {
2441 if (string_attribute == "polite")
2442 result->intVal = LiveSetting::Polite;
2443 else if (string_attribute == "assertive")
2444 result->intVal = LiveSetting::Assertive;
2445 }
2446 break;
2447 }
2448
2449 case UIA_OptimizeForVisualContentPropertyId:
2450 result->vt = VT_BOOL;
2451 result->boolVal = VARIANT_FALSE;
2452 break;
2453
2454 case UIA_PositionInSetPropertyId: {
2455 std::optional<int> pos_in_set = GetPosInSet();
2456 if (pos_in_set) {
2457 result->vt = VT_I4;
2458 result->intVal = *pos_in_set;
2459 }
2460 } break;
2461
2462 case UIA_ScrollHorizontalScrollPercentPropertyId: {
2463 V_VT(result) = VT_R8;
2464 V_R8(result) = GetHorizontalScrollPercent();
2465 break;
2466 }
2467
2468 case UIA_ScrollVerticalScrollPercentPropertyId: {
2469 V_VT(result) = VT_R8;
2470 V_R8(result) = GetVerticalScrollPercent();
2471 break;
2472 }
2473
2474 case UIA_SizeOfSetPropertyId: {
2475 std::optional<int> set_size = GetSetSize();
2476 if (set_size) {
2477 result->vt = VT_I4;
2478 result->intVal = *set_size;
2479 }
2480 break;
2481 }
2482
2483 case UIA_LandmarkTypePropertyId: {
2484 std::optional<LONG> landmark_type = ComputeUIALandmarkType();
2485 if (landmark_type) {
2486 result->vt = VT_I4;
2487 result->intVal = landmark_type.value();
2488 }
2489 break;
2490 }
2491
2492 case UIA_LocalizedLandmarkTypePropertyId: {
2493 std::u16string localized_landmark_type =
2494 GetDelegate()->GetLocalizedStringForLandmarkType();
2495 if (!localized_landmark_type.empty()) {
2496 result->vt = VT_BSTR;
2497 result->bstrVal = ::SysAllocString(
2499 }
2500 break;
2501 }
2502
2503 case UIA_ExpandCollapseExpandCollapseStatePropertyId:
2504 result->vt = VT_I4;
2505 result->intVal = static_cast<int>(ComputeExpandCollapseState());
2506 break;
2507
2508 case UIA_ToggleToggleStatePropertyId: {
2509 ToggleState state;
2510 get_ToggleState(&state);
2511 result->vt = VT_I4;
2512 result->lVal = state;
2513 break;
2514 }
2515
2516 case UIA_ValueValuePropertyId:
2517 result->vt = VT_BSTR;
2518 result->bstrVal = GetValueAttributeAsBstr(this);
2519 break;
2520
2521
2522 case UIA_AnnotationObjectsPropertyId:
2523 case UIA_AnnotationTypesPropertyId:
2524 case UIA_CenterPointPropertyId:
2525 case UIA_FillColorPropertyId:
2526 case UIA_FillTypePropertyId:
2527 case UIA_HeadingLevelPropertyId:
2528 case UIA_ItemTypePropertyId:
2529 case UIA_OutlineColorPropertyId:
2530 case UIA_OutlineThicknessPropertyId:
2531 case UIA_RotationPropertyId:
2532 case UIA_SizePropertyId:
2533 case UIA_VisualEffectsPropertyId:
2534 break;
2535
2536
2537 case UIA_BoundingRectanglePropertyId:
2538 case UIA_NativeWindowHandlePropertyId:
2539 case UIA_ProcessIdPropertyId:
2540 case UIA_ProviderDescriptionPropertyId:
2541 case UIA_RuntimeIdPropertyId:
2542 break;
2543 }
2544
2545
2546 if (property_id ==
2548
2549
2550
2551
2552
2553
2554
2555 result->vt = VT_BSTR;
2556 result->bstrVal = ::SysAllocString(
2558 }
2559
2560 return S_OK;
2561}
2562
2563IFACEMETHODIMP AXPlatformNodeWin::get_ProviderOptions(ProviderOptions* ret) {
2565
2566 *ret = ProviderOptions_ServerSideProvider | ProviderOptions_UseComThreading |
2567 ProviderOptions_RefuseNonClientSupport |
2568 ProviderOptions_HasNativeIAccessible;
2569 return S_OK;
2570}
2571
2572IFACEMETHODIMP AXPlatformNodeWin::get_HostRawElementProvider(
2573 IRawElementProviderSimple** provider) {
2575
2576 *provider = nullptr;
2577 return S_OK;
2578}
2579
2580
2581
2582
2583
2584IFACEMETHODIMP AXPlatformNodeWin::ShowContextMenu() {
2586
2587 AXActionData action_data;
2589 delegate_->AccessibilityPerformAction(action_data);
2590 return S_OK;
2591}
2592
2593
2594
2595
2596
2597IFACEMETHODIMP AXPlatformNodeWin::QueryService(
REFGUID guidService,
2598 REFIID riid,
2599 void** object) {
2601
2602 if (guidService == IID_IAccessible || (guidService == IID_IAccessibleEx &&
delegate_->IsIAccessibleExEnabled())) {
2603 return QueryInterface(riid, object);
2604 }
2605
2606
2607
2608
2609 *object = nullptr;
2610 return E_FAIL;
2611}
2612
2613
2614
2615
2616
2617
2618STDMETHODIMP AXPlatformNodeWin::InternalQueryInterface(
2619 void* this_ptr,
2620 const _ATL_INTMAP_ENTRY* entries,
2621 REFIID riid,
2622 void** object) {
2623 if (!object)
2624 return E_INVALIDARG;
2625 *object = nullptr;
2627 reinterpret_cast<AXPlatformNodeWin*>(this_ptr);
2629
2630 return CComObjectRootBase::InternalQueryInterface(this_ptr, entries, riid,
2631 object);
2632}
2633
2634HRESULT AXPlatformNodeWin::GetTextAttributeValue(
2635 TEXTATTRIBUTEID attribute_id,
2636 const std::optional<int>& start_offset,
2637 const std::optional<int>& end_offset,
2639 BASE_DCHECK(!start_offset || start_offset.value() >= 0);
2640 BASE_DCHECK(!end_offset || end_offset.value() >= 0);
2641
2642 switch (attribute_id) {
2643 case UIA_AnnotationTypesAttributeId:
2644 return GetAnnotationTypesAttribute(start_offset, end_offset, result);
2645 case UIA_BackgroundColorAttributeId:
2648 break;
2649 case UIA_BulletStyleAttributeId:
2650 result->
Insert<VT_I4>(ComputeUIABulletStyle());
2651 break;
2652 case UIA_CultureAttributeId: {
2653 std::optional<LCID> lcid = GetCultureAttributeAsLCID();
2654 if (!lcid)
2655 return E_FAIL;
2656 result->
Insert<VT_I4>(lcid.value());
2657 break;
2658 }
2659 case UIA_FontNameAttributeId:
2660 result->
Insert<VT_BSTR>(GetFontNameAttributeAsBSTR());
2661 break;
2662 case UIA_FontSizeAttributeId: {
2663 std::optional<float> font_size_in_points = GetFontSizeInPoints();
2664 if (font_size_in_points) {
2665 result->
Insert<VT_R8>(*font_size_in_points);
2666 }
2667 break;
2668 }
2669 case UIA_FontWeightAttributeId:
2672 break;
2673 case UIA_ForegroundColorAttributeId:
2676 break;
2677 case UIA_IsHiddenAttributeId:
2678 result->
Insert<VT_BOOL>(IsInvisibleOrIgnored());
2679 break;
2680 case UIA_IsItalicAttributeId:
2683 break;
2684 case UIA_IsReadOnlyAttributeId:
2685
2686 if (IsPlaceholderText()) {
2687 AXPlatformNodeWin* parent_platform_node =
2688 static_cast<AXPlatformNodeWin*>(
2689 FromNativeViewAccessible(GetParent()));
2690 return parent_platform_node->GetTextAttributeValue(
2691 attribute_id, start_offset, end_offset, result);
2692 }
2693 result->
Insert<VT_BOOL>(GetData().IsReadOnlyOrDisabled());
2694 break;
2695 case UIA_IsSubscriptAttributeId:
2696 result->
Insert<VT_BOOL>(GetData().GetTextPosition() ==
2698 break;
2699 case UIA_IsSuperscriptAttributeId:
2700 result->
Insert<VT_BOOL>(GetData().GetTextPosition() ==
2702 break;
2703 case UIA_OverlineStyleAttributeId:
2704 result->
Insert<VT_I4>(GetUIATextDecorationStyle(
2706 break;
2707 case UIA_StrikethroughStyleAttributeId:
2708 result->
Insert<VT_I4>(GetUIATextDecorationStyle(
2710 break;
2711 case UIA_StyleNameAttributeId:
2712 result->
Insert<VT_BSTR>(GetStyleNameAttributeAsBSTR());
2713 break;
2714 case UIA_StyleIdAttributeId:
2715 result->
Insert<VT_I4>(ComputeUIAStyleId());
2716 break;
2717 case UIA_HorizontalTextAlignmentAttributeId: {
2718 std::optional<HorizontalTextAlignment> horizontal_text_alignment =
2719 AXTextAlignToUIAHorizontalTextAlignment(GetData().GetTextAlign());
2720 if (horizontal_text_alignment)
2721 result->
Insert<VT_I4>(*horizontal_text_alignment);
2722 break;
2723 }
2724 case UIA_UnderlineStyleAttributeId:
2725 result->
Insert<VT_I4>(GetUIATextDecorationStyle(
2727 break;
2728 case UIA_TextFlowDirectionsAttributeId:
2730 TextDirectionToFlowDirections(GetData().GetTextDirection()));
2731 break;
2732 default: {
2733 Microsoft::WRL::ComPtr<IUnknown> not_supported_value;
2734 HRESULT hr = ::UiaGetReservedNotSupportedValue(¬_supported_value);
2736 result->
Insert<VT_UNKNOWN>(not_supported_value.Get());
2737 return hr;
2738 } break;
2739 }
2740
2741 return S_OK;
2742}
2743
2744HRESULT AXPlatformNodeWin::GetAnnotationTypesAttribute(
2745 const std::optional<int>& start_offset,
2746 const std::optional<int>& end_offset,
2749
2750 MarkerTypeRangeResult grammar_result = MarkerTypeRangeResult::kNone;
2751 MarkerTypeRangeResult spelling_result = MarkerTypeRangeResult::kNone;
2752
2753 if (
IsText() || IsPlainTextField()) {
2754 grammar_result = GetMarkerTypeFromRange(start_offset, end_offset,
2756 spelling_result = GetMarkerTypeFromRange(start_offset, end_offset,
2758 }
2759
2760 if (grammar_result == MarkerTypeRangeResult::kMixed ||
2761 spelling_result == MarkerTypeRangeResult::kMixed) {
2762 Microsoft::WRL::ComPtr<IUnknown> mixed_attribute_value;
2763 HRESULT hr = ::UiaGetReservedMixedAttributeValue(&mixed_attribute_value);
2765 result->
Insert<VT_UNKNOWN>(mixed_attribute_value.Get());
2766 return hr;
2767 }
2768
2769 if (spelling_result == MarkerTypeRangeResult::kMatch)
2770 result->
Insert<VT_I4>(AnnotationType_SpellingError);
2771 if (grammar_result == MarkerTypeRangeResult::kMatch)
2772 result->
Insert<VT_I4>(AnnotationType_GrammarError);
2773
2774 return S_OK;
2775}
2776
2777std::optional<LCID> AXPlatformNodeWin::GetCultureAttributeAsLCID() const {
2778 const std::u16string language =
2780 const LCID lcid =
2781 LocaleNameToLCID((wchar_t*)language.c_str(), LOCALE_ALLOW_NEUTRAL_NAMES);
2782 if (!lcid)
2783 return std::nullopt;
2784
2785 return lcid;
2786}
2787
2788COLORREF AXPlatformNodeWin::GetIntAttributeAsCOLORREF(
2790 uint32_t color = GetIntAttribute(attribute);
2791
2792 return (_byteswap_ulong(color) >> 8);
2793}
2794
2795BulletStyle AXPlatformNodeWin::ComputeUIABulletStyle() const {
2796
2797
2798
2799
2800 const AXPlatformNodeBase* current_node = this;
2801 while (current_node &&
2803 current_node = FromNativeViewAccessible(current_node->GetParent());
2804 }
2805
2807 current_node ? current_node->GetData().GetListStyle()
2809
2810 switch (list_style) {
2812 return BulletStyle::BulletStyle_None;
2814 return BulletStyle::BulletStyle_HollowRoundBullet;
2816 return BulletStyle::BulletStyle_FilledRoundBullet;
2818 return BulletStyle::BulletStyle_Other;
2821 return BulletStyle::BulletStyle_None;
2823 return BulletStyle::BulletStyle_FilledSquareBullet;
2824 }
2825}
2826
2827LONG AXPlatformNodeWin::ComputeUIAStyleId()
const {
2828 const AXPlatformNodeBase* current_node = this;
2829 do {
2830 switch (current_node->GetData().role) {
2832 return AXHierarchicalLevelToUIAStyleId(current_node->GetIntAttribute(
2835 return AXListStyleToUIAStyleId(current_node->GetData().GetListStyle());
2837 return StyleId_Custom;
2839 return StyleId_Quote;
2840 default:
2841 break;
2842 }
2843 current_node = FromNativeViewAccessible(current_node->GetParent());
2844 } while (current_node);
2845
2846 return StyleId_Normal;
2847}
2848
2849
2850std::optional<HorizontalTextAlignment>
2851AXPlatformNodeWin::AXTextAlignToUIAHorizontalTextAlignment(
2853 switch (text_align) {
2855 return std::nullopt;
2857 return HorizontalTextAlignment_Left;
2859 return HorizontalTextAlignment_Right;
2861 return HorizontalTextAlignment_Centered;
2863 return HorizontalTextAlignment_Justified;
2864 }
2865}
2866
2867
2868LONG AXPlatformNodeWin::AXHierarchicalLevelToUIAStyleId(
2869 int32_t hierarchical_level) {
2870 switch (hierarchical_level) {
2871 case 0:
2872 return StyleId_Normal;
2873 case 1:
2874 return StyleId_Heading1;
2875 case 2:
2876 return StyleId_Heading2;
2877 case 3:
2878 return StyleId_Heading3;
2879 case 4:
2880 return StyleId_Heading4;
2881 case 5:
2882 return StyleId_Heading5;
2883 case 6:
2884 return StyleId_Heading6;
2885 case 7:
2886 return StyleId_Heading7;
2887 case 8:
2888 return StyleId_Heading8;
2889 case 9:
2890 return StyleId_Heading9;
2891 default:
2892 return StyleId_Custom;
2893 }
2894}
2895
2896
2897LONG AXPlatformNodeWin::AXListStyleToUIAStyleId(
2899 switch (list_style) {
2901 return StyleId_Normal;
2906 return StyleId_BulletedList;
2909 return StyleId_NumberedList;
2910 }
2911}
2912
2913
2914FlowDirections AXPlatformNodeWin::TextDirectionToFlowDirections(
2918 return FlowDirections::FlowDirections_Default;
2920 return FlowDirections::FlowDirections_Default;
2922 return FlowDirections::FlowDirections_RightToLeft;
2924 return FlowDirections::FlowDirections_Vertical;
2926 return FlowDirections::FlowDirections_BottomToTop;
2927 }
2928}
2929
2930
2931void AXPlatformNodeWin::AggregateRangesForMarkerType(
2932 AXPlatformNodeBase* node,
2934 int offset_ranges_amount,
2935 std::vector<std::pair<int, int>>* ranges) {
2937 const std::vector<int32_t>& marker_types =
2939 const std::vector<int>& marker_starts =
2941 const std::vector<int>& marker_ends =
2943
2944 for (
size_t i = 0;
i < marker_types.size(); ++
i) {
2946 continue;
2947
2948 const int marker_start = marker_starts[
i] + offset_ranges_amount;
2949 const int marker_end = marker_ends[
i] + offset_ranges_amount;
2950 ranges->emplace_back(std::make_pair(marker_start, marker_end));
2951 }
2952}
2953
2954AXPlatformNodeWin::MarkerTypeRangeResult
2955AXPlatformNodeWin::GetMarkerTypeFromRange(
2956 const std::optional<int>& start_offset,
2957 const std::optional<int>& end_offset,
2960 std::vector<std::pair<int, int>> relevant_ranges;
2961
2963 AggregateRangesForMarkerType(this, marker_type, 0,
2964 &relevant_ranges);
2965 } else if (IsPlainTextField()) {
2966 int offset_ranges_amount = 0;
2967 for (AXPlatformNodeBase* static_text = GetFirstTextOnlyDescendant();
2968 static_text; static_text = static_text->GetNextSibling()) {
2969 const int child_offset_ranges_amount = offset_ranges_amount;
2970 if (start_offset || end_offset) {
2971
2972 if (end_offset && child_offset_ranges_amount > end_offset.value())
2973 break;
2974
2975
2976 offset_ranges_amount += static_text->GetHypertext().length();
2977 if (start_offset && offset_ranges_amount < start_offset.value())
2978 continue;
2979 }
2980
2981 AggregateRangesForMarkerType(static_text, marker_type,
2982 child_offset_ranges_amount,
2983 &relevant_ranges);
2984 }
2985 }
2986
2987
2988 const auto sort_ranges_by_start_offset = [](const std::pair<int, int>& a,
2989 const std::pair<int, int>&
b) {
2990 return a.first <
b.first;
2991 };
2992 std::sort(relevant_ranges.begin(), relevant_ranges.end(),
2993 sort_ranges_by_start_offset);
2994
2995
2996 std::optional<std::pair<int, int>> contiguous_range;
2997 for (const std::pair<int, int>& range : relevant_ranges) {
2998 if (end_offset && range.first > end_offset.value())
2999 break;
3000 if (start_offset && range.second < start_offset.value())
3001 continue;
3002
3003 if (!contiguous_range) {
3004 contiguous_range = range;
3005 continue;
3006 }
3007
3008
3009 if ((range.first - contiguous_range->second) > 1)
3010 return MarkerTypeRangeResult::kMixed;
3011
3012
3013 contiguous_range->second = std::max(contiguous_range->second, range.second);
3014 }
3015
3016
3017 if (!contiguous_range)
3018 return MarkerTypeRangeResult::kNone;
3019
3020
3021
3022 if (!start_offset && contiguous_range->first > 0)
3023 return MarkerTypeRangeResult::kMixed;
3024
3025 if (!end_offset && contiguous_range->second < GetHypertext().
length())
3026 return MarkerTypeRangeResult::kMixed;
3027
3028 if (start_offset && start_offset.value() < contiguous_range->first)
3029 return MarkerTypeRangeResult::kMixed;
3030
3031 if (end_offset && end_offset.value() > contiguous_range->second)
3032 return MarkerTypeRangeResult::kMixed;
3033
3034
3035 return MarkerTypeRangeResult::kMatch;
3036}
3037
3038
3039
3040bool AXPlatformNodeWin::IsPatternProviderSupported(PATTERNID pattern_id) {
3041 return GetPatternProviderFactoryMethod(pattern_id);
3042}
3043
3044
3045
3046
3047int AXPlatformNodeWin::MSAARole() {
3048
3049
3050
3051 if (IsWebAreaForPresentationalIframe())
3052 return ROLE_SYSTEM_GROUPING;
3053
3054 switch (GetData().role) {
3056 return ROLE_SYSTEM_ALERT;
3057
3059 return ROLE_SYSTEM_DIALOG;
3060
3062 return ROLE_SYSTEM_LINK;
3063
3066 return ROLE_SYSTEM_GROUPING;
3067
3069 return ROLE_SYSTEM_APPLICATION;
3070
3072 return ROLE_SYSTEM_DOCUMENT;
3073
3075 return ROLE_SYSTEM_GROUPING;
3076
3079 return ROLE_SYSTEM_GROUPING;
3080
3082 return ROLE_SYSTEM_GROUPING;
3083
3085 return ROLE_SYSTEM_PUSHBUTTON;
3086
3088 return ROLE_SYSTEM_GRAPHIC;
3089
3091 return ROLE_SYSTEM_TEXT;
3092
3094 return ROLE_SYSTEM_CARET;
3095
3097 return ROLE_SYSTEM_CELL;
3098
3100 return ROLE_SYSTEM_CHECKBUTTON;
3101
3103 return ROLE_SYSTEM_PANE;
3104
3106 return ROLE_SYSTEM_TEXT;
3107
3109 return ROLE_SYSTEM_COLUMN;
3110
3112 return ROLE_SYSTEM_COLUMNHEADER;
3113
3116 return ROLE_SYSTEM_COMBOBOX;
3117
3119 return ROLE_SYSTEM_GROUPING;
3120
3123 return ROLE_SYSTEM_GROUPING;
3124
3127 return ROLE_SYSTEM_GROUPING;
3128
3131 return ROLE_SYSTEM_DROPLIST;
3132
3134 return ROLE_SYSTEM_GROUPING;
3135
3137 return ROLE_SYSTEM_TEXT;
3138
3140 return ROLE_SYSTEM_LIST;
3141
3143 return ROLE_SYSTEM_LISTITEM;
3144
3146 return ROLE_SYSTEM_PANE;
3147
3149 return ROLE_SYSTEM_GROUPING;
3150
3152 return ROLE_SYSTEM_DIALOG;
3153
3155 return ROLE_SYSTEM_PUSHBUTTON;
3156
3158 return ROLE_SYSTEM_LIST;
3159
3161 return ROLE_SYSTEM_GRAPHIC;
3162
3167 return ROLE_SYSTEM_LINK;
3168
3172 return ROLE_SYSTEM_LISTITEM;
3173
3175 return ROLE_SYSTEM_SEPARATOR;
3176
3207 return ROLE_SYSTEM_GROUPING;
3208
3212 return ROLE_SYSTEM_DOCUMENT;
3213
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224 if (GetDelegate()->GetChildCount()) {
3225 return ROLE_SYSTEM_GROUPING;
3226 } else {
3227 return ROLE_SYSTEM_CLIENT;
3228 }
3229
3231 return ROLE_SYSTEM_GROUPING;
3232
3234 return ROLE_SYSTEM_GROUPING;
3235
3237 return ROLE_SYSTEM_GROUPING;
3238
3241 return ROLE_SYSTEM_GROUPING;
3242
3244 return ROLE_SYSTEM_GROUPING;
3245
3247 return ROLE_SYSTEM_GROUPING;
3248
3250 return ROLE_SYSTEM_DOCUMENT;
3251
3253 return ROLE_SYSTEM_PANE;
3254
3256 return ROLE_SYSTEM_GRAPHIC;
3257
3259 return ROLE_SYSTEM_TABLE;
3260
3262 return ROLE_SYSTEM_GROUPING;
3263
3265 return ROLE_SYSTEM_GROUPING;
3266
3268 return ROLE_SYSTEM_DOCUMENT;
3269
3271 return ROLE_SYSTEM_GROUPING;
3272
3275 return ROLE_SYSTEM_GRAPHIC;
3276
3278 return ROLE_SYSTEM_GROUPING;
3279
3281 return ROLE_SYSTEM_STATICTEXT;
3282
3285 return ROLE_SYSTEM_TEXT;
3286
3288 return ROLE_SYSTEM_TABLE;
3289
3291 return ROLE_SYSTEM_CELL;
3292
3294 return ROLE_SYSTEM_ROW;
3295
3297 return ROLE_SYSTEM_LINK;
3298
3300 return ROLE_SYSTEM_LIST;
3301
3303 return ROLE_SYSTEM_LIST;
3304
3306 return ROLE_SYSTEM_LISTITEM;
3307
3309 return ROLE_SYSTEM_LIST;
3310
3312 return ROLE_SYSTEM_LISTITEM;
3313
3315 if (!GetDelegate()->GetChildCount()) {
3316
3317
3318
3319
3320 return ROLE_SYSTEM_STATICTEXT;
3321 }
3322 return ROLE_SYSTEM_GROUPING;
3323
3325 return ROLE_SYSTEM_GROUPING;
3326
3328 return ROLE_SYSTEM_GROUPING;
3329
3331 return ROLE_SYSTEM_GROUPING;
3332
3334 return ROLE_SYSTEM_ANIMATION;
3335
3337 return ROLE_SYSTEM_EQUATION;
3338
3340 return ROLE_SYSTEM_MENUPOPUP;
3341
3343 return ROLE_SYSTEM_MENUBAR;
3344
3348 return ROLE_SYSTEM_MENUITEM;
3349
3351 return ROLE_SYSTEM_LIST;
3352
3354 return ROLE_SYSTEM_LISTITEM;
3355
3357 return ROLE_SYSTEM_PROGRESSBAR;
3358
3360 return ROLE_SYSTEM_GROUPING;
3361
3363 return ROLE_SYSTEM_GROUPING;
3364
3366 return ROLE_SYSTEM_GROUPING;
3367
3369 return ROLE_SYSTEM_PUSHBUTTON;
3370
3372
3373 if (GetDelegate()->GetChildCount()) {
3374 return ROLE_SYSTEM_GROUPING;
3375 } else {
3376 return ROLE_SYSTEM_CLIENT;
3377 }
3378
3380 std::string html_tag =
3382 if (html_tag == "select")
3383 return ROLE_SYSTEM_COMBOBOX;
3384 return ROLE_SYSTEM_BUTTONMENU;
3385 }
3386
3388 return ROLE_SYSTEM_PUSHBUTTON;
3389
3391 return ROLE_SYSTEM_TEXT;
3392
3394 return ROLE_SYSTEM_PROGRESSBAR;
3395
3397 return ROLE_SYSTEM_RADIOBUTTON;
3398
3400 return ROLE_SYSTEM_GROUPING;
3401
3403 return ROLE_SYSTEM_PANE;
3404
3406
3407
3408 return IsInTreeGrid() ? ROLE_SYSTEM_OUTLINEITEM : ROLE_SYSTEM_ROW;
3409 }
3410
3412 return ROLE_SYSTEM_GROUPING;
3413
3415 return ROLE_SYSTEM_ROWHEADER;
3416
3418 return ROLE_SYSTEM_TEXT;
3419
3421 if (GetNameAsString16().empty()) {
3422
3423 return ROLE_SYSTEM_GROUPING;
3424 }
3425
3426 return ROLE_SYSTEM_PANE;
3427 }
3428
3430 return ROLE_SYSTEM_SCROLLBAR;
3431
3433 return ROLE_SYSTEM_PANE;
3434
3436 return ROLE_SYSTEM_GROUPING;
3437
3439 return ROLE_SYSTEM_SLIDER;
3440
3442 return ROLE_SYSTEM_SLIDER;
3443
3445 return ROLE_SYSTEM_SPINBUTTON;
3446
3448 return ROLE_SYSTEM_CHECKBUTTON;
3449
3452 return ROLE_SYSTEM_STATICTEXT;
3453
3455 return ROLE_SYSTEM_STATUSBAR;
3456
3458 return ROLE_SYSTEM_SEPARATOR;
3459
3461 return ROLE_SYSTEM_GRAPHIC;
3462
3464 return ROLE_SYSTEM_PAGETAB;
3465
3467 return ROLE_SYSTEM_TABLE;
3468
3470 return ROLE_SYSTEM_GROUPING;
3471
3473 return ROLE_SYSTEM_PAGETABLIST;
3474
3476 return ROLE_SYSTEM_PROPERTYPAGE;
3477
3479 return ROLE_SYSTEM_LISTITEM;
3480
3482 return ROLE_SYSTEM_TITLEBAR;
3483
3485 return ROLE_SYSTEM_CHECKBUTTON;
3486
3489 return ROLE_SYSTEM_TEXT;
3490
3492 return ROLE_SYSTEM_COMBOBOX;
3493
3499 return ROLE_SYSTEM_TEXT;
3500
3502 return ROLE_SYSTEM_CLOCK;
3503
3505 return ROLE_SYSTEM_TOOLBAR;
3506
3508 return ROLE_SYSTEM_TOOLTIP;
3509
3511 return ROLE_SYSTEM_OUTLINE;
3512
3514 return ROLE_SYSTEM_OUTLINE;
3515
3517 return ROLE_SYSTEM_OUTLINEITEM;
3518
3520 return ROLE_SYSTEM_WHITESPACE;
3521
3523 return ROLE_SYSTEM_GROUPING;
3524
3526 return ROLE_SYSTEM_CLIENT;
3527
3530
3531
3532
3533
3534 return ROLE_SYSTEM_PANE;
3535
3542 return ROLE_SYSTEM_PANE;
3543 }
3544
3546 return ROLE_SYSTEM_GROUPING;
3547}
3548
3549bool AXPlatformNodeWin::IsWebAreaForPresentationalIframe() {
3552 return false;
3553 }
3554
3555 AXPlatformNodeBase* parent = FromNativeViewAccessible(GetParent());
3556 if (!parent)
3557 return false;
3558
3560}
3561
3562std::u16string AXPlatformNodeWin::UIAAriaRole() {
3563
3564
3565
3566 if (IsWebAreaForPresentationalIframe())
3567 return u"group";
3568
3569 switch (GetData().role) {
3571 return u"alert";
3572
3574
3575
3576
3577
3578 return u"alert";
3579
3581 return u"link";
3582
3585 return u"group";
3586
3588 return u"application";
3589
3591 return u"article";
3592
3594 return u"group";
3595
3598 return u"banner";
3599
3601 return u"group";
3602
3604 return u"button";
3605
3607 return u"img";
3608
3610 return u"description";
3611
3613 return u"region";
3614
3616 return u"gridcell";
3617
3619 return u"code";
3620
3622 return u"checkbox";
3623
3625 return u"region";
3626
3628 return u"textbox";
3629
3631 return u"region";
3632
3634 return u"columnheader";
3635
3638 return u"combobox";
3639
3641 return u"complementary";
3642
3645 return u"group";
3646
3649 return u"contentinfo";
3650
3653 return u"textbox";
3654
3656 return u"definition";
3657
3659 return u"description";
3660
3662 return u"list";
3663
3665 return u"listitem";
3666
3668 return u"document";
3669
3671 return u"group";
3672
3674 return u"dialog";
3675
3677 return u"button";
3678
3680 return u"directory";
3681
3683 return u"img";
3684
3689 return u"link";
3690
3694 return u"listitem";
3695
3697 return u"separator";
3698
3729 return u"group";
3730
3734 return u"document";
3735
3737 if (GetDelegate()->GetChildCount()) {
3738 return u"group";
3739 } else {
3740 return u"document";
3741 }
3742
3744 return u"emphasis";
3745
3747 return u"group";
3748
3750 return u"description";
3751
3753 return u"group";
3754
3757 return u"group";
3758
3760 return u"form";
3761
3763 return u"group";
3764
3766 return u"document";
3767
3769 return u"region";
3770
3772 return u"img";
3773
3775 return u"grid";
3776
3778 return u"group";
3779
3781 return u"heading";
3782
3784 return u"document";
3785
3787 return u"group";
3788
3790 return u"img";
3791
3793 return u"document";
3794
3796
3797 return u"group";
3798
3800 return u"group";
3801
3803 return u"textbox";
3804
3806 return u"group";
3807
3810 return u"description";
3811
3813 return u"grid";
3814
3816 return u"gridcell";
3817
3819 return u"row";
3820
3822 return u"link";
3823
3825 return u"list";
3826
3828 return u"listbox";
3829
3831 return u"option";
3832
3834 return u"listview";
3835
3837 return u"listitem";
3838
3840 if (!GetDelegate()->GetChildCount()) {
3841
3842
3843
3844
3845 return u"description";
3846 }
3847 return u"group";
3848
3850 return u"log";
3851
3853 return u"main";
3854
3856 return u"description";
3857
3859 return u"marquee";
3860
3862 return u"group";
3863
3865 return u"menu";
3866
3868 return u"menubar";
3869
3871 return u"menuitem";
3872
3874 return u"menuitemcheckbox";
3875
3877 return u"menuitemradio";
3878
3880 return u"list";
3881
3883 return u"listitem";
3884
3886 return u"progressbar";
3887
3889 return u"navigation";
3890
3892 return u"note";
3893
3895 return u"group";
3896
3898 return u"button";
3899
3901 if (GetDelegate()->GetChildCount()) {
3902 return u"group";
3903 } else {
3904 return u"document";
3905 }
3906
3908 std::string html_tag =
3910 if (html_tag == "select")
3911 return u"combobox";
3912 return u"button";
3913 }
3914
3916 return u"button";
3917
3919 return u"region";
3920
3922 return u"progressbar";
3923
3925 return u"radio";
3926
3928 return u"radiogroup";
3929
3931 return u"region";
3932
3934
3935
3936 return IsInTreeGrid() ? u"treeitem" : u"row";
3937 }
3938
3940 return u"rowgroup";
3941
3943 return u"rowheader";
3944
3946 return u"region";
3947
3949 if (GetNameAsString16().empty()) {
3950
3951 return u"group";
3952 }
3953
3954 return u"region";
3955 }
3956
3958 return u"scrollbar";
3959
3961 return u"region";
3962
3964 return u"search";
3965
3967 return u"slider";
3968
3970 return u"slider";
3971
3973 return u"spinbutton";
3974
3976 return u"strong";
3977
3979 return u"switch";
3980
3983 return u"description";
3984
3986 return u"status";
3987
3989 return u"separator";
3990
3992 return u"img";
3993
3995 return u"tab";
3996
3998 return u"grid";
3999
4001 return u"group";
4002
4004 return u"tablist";
4005
4007 return u"tabpanel";
4008
4010 return u"listitem";
4011
4013 return u"document";
4014
4016 return u"button";
4017
4019 return u"textbox";
4020
4022 return u"searchbox";
4023
4025 return u"combobox";
4026
4028 return u"description";
4029
4031 return u"time";
4032
4034 return u"timer";
4035
4037 return u"toolbar";
4038
4040 return u"tooltip";
4041
4043 return u"tree";
4044
4046 return u"treegrid";
4047
4049 return u"treeitem";
4050
4052 return u"separator";
4053
4055 return u"group";
4056
4058 return u"document";
4059
4066 return u"region";
4067 }
4068
4070 return u"document";
4071}
4072
4073std::u16string AXPlatformNodeWin::ComputeUIAProperties() {
4074 std::vector<std::u16string> properties;
4075 const AXNodeData&
data = GetData();
4076
4077 BoolAttributeToUIAAriaProperty(
4080 "busy");
4081
4082 switch (
data.GetCheckedState()) {
4084 break;
4087 properties.emplace_back(u"pressed=false");
4089
4090
4091
4092 properties.emplace_back(u"pressed=false");
4093 properties.emplace_back(u"checked=false");
4094 } else {
4095 properties.emplace_back(u"checked=false");
4096 }
4097 break;
4100 properties.emplace_back(u"pressed=true");
4102
4103
4104
4105 properties.emplace_back(u"pressed=true");
4106 properties.emplace_back(u"checked=true");
4107 } else {
4108 properties.emplace_back(u"checked=true");
4109 }
4110 break;
4113 properties.emplace_back(u"pressed=mixed");
4115
4117 } else {
4118 properties.emplace_back(u"checked=mixed");
4119 }
4120 break;
4121 }
4122
4126 properties.push_back(u"disabled=true");
4127 } else {
4128
4129
4130
4131
4132 if (GetData().IsReadOnlyOrDisabled())
4133 properties.push_back(u"readonly=true");
4134 }
4135
4136
4138 properties.push_back(u"dropeffect=" +
4140 }
4143 "grabbed");
4144
4148 break;
4150 properties.push_back(u"haspopup=true");
4151 break;
4153 properties.push_back(u"haspopup=menu");
4154 break;
4156 properties.push_back(u"haspopup=listbox");
4157 break;
4159 properties.push_back(u"haspopup=tree");
4160 break;
4162 properties.push_back(u"haspopup=grid");
4163 break;
4165 properties.push_back(u"haspopup=dialog");
4166 break;
4167 }
4168
4169 if (IsInvisibleOrIgnored())
4170 properties.push_back(u"hidden=true");
4171
4175 properties.push_back(u"invalid=true");
4176 }
4177
4178 IntAttributeToUIAAriaProperty(
4180 StringAttributeToUIAAriaProperty(
4184 "multiselectable");
4186 "posinset");
4187 StringAttributeToUIAAriaProperty(
4190 BoolAttributeToUIAAriaProperty(
4193 "setsize");
4194
4195 int32_t sort_direction;
4198 &sort_direction)) {
4201 break;
4203 properties.push_back(u"sort=none");
4204 break;
4206 properties.push_back(u"sort=ascending");
4207 break;
4209 properties.push_back(u"sort=descending");
4210 break;
4212 properties.push_back(u"sort=other");
4213 break;
4214 }
4215 }
4216
4217 if (
data.IsRangeValueSupported()) {
4218 FloatAttributeToUIAAriaProperty(
4220 FloatAttributeToUIAAriaProperty(
4222 StringAttributeToUIAAriaProperty(
4224
4225 std::u16string value_now = GetRangeValueText();
4226 SanitizeStringAttributeForUIAAriaProperty(value_now, &value_now);
4227 if (!value_now.empty())
4228 properties.push_back(u"valuenow=" + value_now);
4229 }
4230
4232 return result;
4233}
4234
4235LONG AXPlatformNodeWin::ComputeUIAControlType() {
4236
4237
4238
4239 if (IsWebAreaForPresentationalIframe())
4240 return UIA_GroupControlTypeId;
4241
4242 switch (GetData().role) {
4244 return UIA_TextControlTypeId;
4245
4247
4248
4249
4250
4251 return UIA_TextControlTypeId;
4252
4254 return UIA_HyperlinkControlTypeId;
4255
4258 return ROLE_SYSTEM_GROUPING;
4259
4261 return UIA_PaneControlTypeId;
4262
4264 return UIA_GroupControlTypeId;
4265
4267 return UIA_GroupControlTypeId;
4268
4271 return UIA_GroupControlTypeId;
4272
4274 return UIA_GroupControlTypeId;
4275
4277 return UIA_ButtonControlTypeId;
4278
4280 return UIA_ImageControlTypeId;
4281
4283 return UIA_TextControlTypeId;
4284
4286 return UIA_PaneControlTypeId;
4287
4289 return UIA_DataItemControlTypeId;
4290
4292 return UIA_CheckBoxControlTypeId;
4293
4295 return UIA_PaneControlTypeId;
4296
4298 return UIA_TextControlTypeId;
4299
4301 return UIA_ButtonControlTypeId;
4302
4304 return UIA_PaneControlTypeId;
4305
4307 return UIA_DataItemControlTypeId;
4308
4311 return UIA_ComboBoxControlTypeId;
4312
4314 return UIA_GroupControlTypeId;
4315
4318 return UIA_GroupControlTypeId;
4319
4322 return UIA_GroupControlTypeId;
4323
4326 return UIA_EditControlTypeId;
4327
4329 return UIA_GroupControlTypeId;
4330
4332 return UIA_TextControlTypeId;
4333
4335 return UIA_ListControlTypeId;
4336
4338 return UIA_ListItemControlTypeId;
4339
4341 return UIA_DocumentControlTypeId;
4342
4344 return UIA_GroupControlTypeId;
4345
4347 return UIA_PaneControlTypeId;
4348
4350 return UIA_ButtonControlTypeId;
4351
4353 return UIA_ListControlTypeId;
4354
4356 return UIA_ImageControlTypeId;
4357
4362 return UIA_HyperlinkControlTypeId;
4363
4367 return UIA_ListItemControlTypeId;
4368
4370 return UIA_SeparatorControlTypeId;
4371
4402 return UIA_GroupControlTypeId;
4403
4407 return UIA_DocumentControlTypeId;
4408
4410 return UIA_PaneControlTypeId;
4411
4413 return UIA_TextControlTypeId;
4414
4416 return UIA_GroupControlTypeId;
4417
4419 return UIA_TextControlTypeId;
4420
4422 return UIA_GroupControlTypeId;
4423
4426 return UIA_GroupControlTypeId;
4427
4429 return UIA_GroupControlTypeId;
4430
4432 return UIA_GroupControlTypeId;
4433
4435 return UIA_DocumentControlTypeId;
4436
4438 return UIA_PaneControlTypeId;
4439
4441 return UIA_ImageControlTypeId;
4442
4444 return UIA_DataGridControlTypeId;
4445
4447 return UIA_GroupControlTypeId;
4448
4450 return UIA_TextControlTypeId;
4451
4453 return UIA_DocumentControlTypeId;
4454
4456 return UIA_GroupControlTypeId;
4457
4459 return UIA_ImageControlTypeId;
4460
4462 return UIA_DocumentControlTypeId;
4463
4465 return UIA_GroupControlTypeId;
4466
4468 return UIA_DocumentControlTypeId;
4469
4472 return UIA_TextControlTypeId;
4473
4475 return UIA_TableControlTypeId;
4476
4478 return UIA_DataItemControlTypeId;
4479
4481 return UIA_DataItemControlTypeId;
4482
4484 return UIA_HyperlinkControlTypeId;
4485
4487 return UIA_ListControlTypeId;
4488
4490 return UIA_ListControlTypeId;
4491
4493 return UIA_ListItemControlTypeId;
4494
4496 return UIA_DataGridControlTypeId;
4497
4499 return UIA_ListItemControlTypeId;
4500
4502 if (!GetDelegate()->GetChildCount()) {
4503
4504
4505
4506
4507 return UIA_TextControlTypeId;
4508 }
4509 return UIA_GroupControlTypeId;
4510
4512 return UIA_GroupControlTypeId;
4513
4515 return UIA_GroupControlTypeId;
4516
4518 return UIA_TextControlTypeId;
4519
4521 return UIA_TextControlTypeId;
4522
4524 return UIA_GroupControlTypeId;
4525
4527 return UIA_MenuControlTypeId;
4528
4530 return UIA_MenuBarControlTypeId;
4531
4533 return UIA_MenuItemControlTypeId;
4534
4536 return UIA_CheckBoxControlTypeId;
4537
4539 return UIA_RadioButtonControlTypeId;
4540
4542 return UIA_ListControlTypeId;
4543
4545 return UIA_ListItemControlTypeId;
4546
4548 return UIA_ProgressBarControlTypeId;
4549
4551 return UIA_GroupControlTypeId;
4552
4554 return UIA_GroupControlTypeId;
4555
4557 return UIA_GroupControlTypeId;
4558
4560 return UIA_CustomControlTypeId;
4561
4563 if (GetDelegate()->GetChildCount()) {
4564 return UIA_GroupControlTypeId;
4565 } else {
4566 return UIA_DocumentControlTypeId;
4567 }
4568
4570 std::string html_tag =
4572 if (html_tag == "select")
4573 return UIA_ComboBoxControlTypeId;
4574 return UIA_ButtonControlTypeId;
4575 }
4576
4578 return UIA_ButtonControlTypeId;
4579
4581 return UIA_PaneControlTypeId;
4582
4584 return UIA_ProgressBarControlTypeId;
4585
4587 return UIA_RadioButtonControlTypeId;
4588
4590 return UIA_GroupControlTypeId;
4591
4593 return UIA_GroupControlTypeId;
4594
4596
4597
4598 return IsInTreeGrid() ? UIA_TreeItemControlTypeId
4599 : UIA_DataItemControlTypeId;
4600 }
4601
4603 return UIA_GroupControlTypeId;
4604
4606 return UIA_DataItemControlTypeId;
4607
4609 return UIA_PaneControlTypeId;
4610
4612 return UIA_GroupControlTypeId;
4613
4615 return UIA_ScrollBarControlTypeId;
4616
4618 return UIA_PaneControlTypeId;
4619
4621 return UIA_GroupControlTypeId;
4622
4624 return UIA_SliderControlTypeId;
4625
4627 return UIA_SliderControlTypeId;
4628
4630 return UIA_SpinnerControlTypeId;
4631
4633 return UIA_ButtonControlTypeId;
4634
4637 return UIA_TextControlTypeId;
4638
4640 return UIA_StatusBarControlTypeId;
4641
4643 return UIA_TextControlTypeId;
4644
4646 return UIA_SeparatorControlTypeId;
4647
4649 return UIA_ImageControlTypeId;
4650
4652 return UIA_TabItemControlTypeId;
4653
4655 return UIA_TableControlTypeId;
4656
4658 return UIA_GroupControlTypeId;
4659
4661 return UIA_TabControlTypeId;
4662
4664 return UIA_PaneControlTypeId;
4665
4667 return UIA_ListItemControlTypeId;
4668
4670 return UIA_DocumentControlTypeId;
4671
4673 return UIA_ButtonControlTypeId;
4674
4677 return UIA_EditControlTypeId;
4678
4680 return UIA_ComboBoxControlTypeId;
4681
4684 return UIA_TextControlTypeId;
4685
4687 return UIA_PaneControlTypeId;
4688
4690 return UIA_ToolBarControlTypeId;
4691
4693 return UIA_ToolTipControlTypeId;
4694
4696 return UIA_TreeControlTypeId;
4697
4699 return UIA_DataGridControlTypeId;
4700
4702 return UIA_TreeItemControlTypeId;
4703
4705 return UIA_SeparatorControlTypeId;
4706
4708 return UIA_GroupControlTypeId;
4709
4711 return UIA_DocumentControlTypeId;
4712
4721 return UIA_PaneControlTypeId;
4722 }
4723
4725 return UIA_DocumentControlTypeId;
4726}
4727
4728AXPlatformNodeWin* AXPlatformNodeWin::ComputeUIALabeledBy() {
4729
4730 if (!CanHaveUIALabeledBy())
4731 return nullptr;
4732
4733
4734
4735 for (int32_t id : GetData().GetIntListAttribute(
4737 auto* node_win =
4738 static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(id));
4739 if (!node_win)
4740 continue;
4741
4742
4743 if (IsValidUiaRelationTarget(node_win) &&
4745 return node_win;
4746 }
4747
4748
4749 for (auto iter = node_win->GetDelegate()->ChildrenBegin();
4750 *iter != *node_win->GetDelegate()->ChildrenEnd(); ++(*iter)) {
4751 AXPlatformNodeWin* child = static_cast<AXPlatformNodeWin*>(
4753 iter->GetNativeViewAccessible()));
4754 if (IsValidUiaRelationTarget(child) &&
4756 return child;
4757 }
4758 }
4759 }
4760
4761 return nullptr;
4762}
4763
4764bool AXPlatformNodeWin::CanHaveUIALabeledBy() {
4765
4766
4767
4768
4769 switch (ComputeUIAControlType()) {
4770 case UIA_ButtonControlTypeId:
4771 case UIA_CheckBoxControlTypeId:
4772 case UIA_DataItemControlTypeId:
4773 case UIA_MenuControlTypeId:
4774 case UIA_MenuBarControlTypeId:
4775 case UIA_RadioButtonControlTypeId:
4776 case UIA_ScrollBarControlTypeId:
4777 case UIA_SeparatorControlTypeId:
4778 case UIA_StatusBarControlTypeId:
4779 case UIA_TabItemControlTypeId:
4780 case UIA_TextControlTypeId:
4781 case UIA_ToolBarControlTypeId:
4782 case UIA_ToolTipControlTypeId:
4783 case UIA_TreeItemControlTypeId:
4784 return false;
4785 default:
4786 return true;
4787 }
4788}
4789
4790bool AXPlatformNodeWin::IsNameExposed() const {
4791 const AXNodeData&
data = GetData();
4792 switch (
data.role) {
4794 return !GetDelegate()->GetChildCount();
4795 default:
4796 return true;
4797 }
4798}
4799
4800bool AXPlatformNodeWin::IsUIAControl() const {
4801
4802
4803
4804
4805 if (GetDelegate()->IsWebContent()) {
4806
4807 if (IsInvisibleOrIgnored())
4808 return false;
4809
4811
4812
4813
4814
4815
4816 auto* parent = FromNativeViewAccessible(GetDelegate()->GetParent());
4817 while (parent) {
4818 const AXNodeData&
data = parent->GetData();
4820 return false;
4821 switch (
data.role) {
4843 return false;
4844 default:
4845 break;
4846 }
4847 parent = FromNativeViewAccessible(parent->GetParent());
4848 }
4849 }
4850
4851 const AXNodeData&
data = GetData();
4852
4853
4854
4857 return true;
4858 }
4860
4861
4863 data.GetNameFrom() ==
4865 return false;
4866 }
4867 return true;
4868 }
4869 switch (
data.role) {
4886 return true;
4887 default:
4888 break;
4889 }
4890
4891
4892
4893
4896 GetNameAsString16().empty() &&
4898 .empty() &&
4900 return false;
4901 }
4902
4903 return true;
4904 }
4905
4906 const AXNodeData&
data = GetData();
4910}
4911
4912std::optional<LONG> AXPlatformNodeWin::ComputeUIALandmarkType() const {
4913 const AXNodeData&
data = GetData();
4914 switch (
data.role) {
4920 return UIA_CustomLandmarkTypeId;
4921
4923
4924
4925
4926
4927
4928
4929
4930
4933 return UIA_FormLandmarkTypeId;
4934 }
4935 return {};
4936
4938 return UIA_MainLandmarkTypeId;
4939
4941 return UIA_NavigationLandmarkTypeId;
4942
4944 return UIA_SearchLandmarkTypeId;
4945
4949 return UIA_CustomLandmarkTypeId;
4951
4952 default:
4953 return {};
4954 }
4955}
4956
4957bool AXPlatformNodeWin::IsInaccessibleDueToAncestor() const {
4958 AXPlatformNodeWin* parent = static_cast<AXPlatformNodeWin*>(
4960 while (parent) {
4961 if (parent->ShouldHideChildrenForUIA())
4962 return true;
4963 parent = static_cast<AXPlatformNodeWin*>(
4964 FromNativeViewAccessible(parent->GetParent()));
4965 }
4966 return false;
4967}
4968
4969bool AXPlatformNodeWin::ShouldHideChildrenForUIA() const {
4970 if (IsPlainTextField())
4971 return true;
4972
4973 auto role = GetData().role;
4975 return true;
4976
4977 switch (role) {
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4989
4990 if (GetChildCount() == 1) {
4991 AXPlatformNodeBase* only_child = GetFirstChild();
4992 return only_child && only_child->IsText();
4993 }
4994 return false;
4996 return true;
4997 default:
4998 return false;
4999 }
5000}
5001
5002std::u16string AXPlatformNodeWin::GetValue() const {
5004
5005
5006
5007
5008
5009
5010 if (
value.empty() && (MSAAState() & STATE_SYSTEM_LINKED))
5012
5014}
5015
5016bool AXPlatformNodeWin::IsPlatformCheckable() const {
5018 return false;
5019
5021}
5022
5023bool AXPlatformNodeWin::ShouldNodeHaveFocusableState(
5024 const AXNodeData& data) const {
5025 switch (
data.role) {
5029 return true;
5030
5032 AXPlatformNodeBase* parent = FromNativeViewAccessible(GetParent());
5034 }
5035
5037 return false;
5038
5042 return true;
5043 break;
5044
5045 default:
5046 break;
5047 }
5048
5050}
5051
5052int AXPlatformNodeWin::MSAAState() const {
5053 const AXNodeData&
data = GetData();
5054 int msaa_state = 0;
5055
5056
5057
5058
5060 msaa_state |= STATE_SYSTEM_BUSY;
5061
5063 msaa_state |= STATE_SYSTEM_COLLAPSED;
5064
5066 msaa_state |= STATE_SYSTEM_DEFAULT;
5067
5068
5069
5071 msaa_state |= STATE_SYSTEM_EXPANDED;
5072
5073 if (ShouldNodeHaveFocusableState(data))
5074 msaa_state |= STATE_SYSTEM_FOCUSABLE;
5075
5076
5078 msaa_state |= STATE_SYSTEM_HASPOPUP;
5079
5080
5081
5083
5084
5085
5086 if (GetDelegate()->ShouldIgnoreHoveredStateForTesting())
5087 msaa_state |= STATE_SYSTEM_HOTTRACKED;
5088 }
5089
5090
5091
5092 if (IsInvisibleOrIgnored())
5093 msaa_state |= STATE_SYSTEM_INVISIBLE;
5094
5096 msaa_state |= STATE_SYSTEM_LINKED;
5097
5098
5099
5101 msaa_state |= STATE_SYSTEM_EXTSELECTABLE;
5102 msaa_state |= STATE_SYSTEM_MULTISELECTABLE;
5103 }
5104
5105 if (GetDelegate()->IsOffscreen())
5106 msaa_state |= STATE_SYSTEM_OFFSCREEN;
5107
5109 msaa_state |= STATE_SYSTEM_PROTECTED;
5110
5111
5112
5113
5114 if (
data.IsSelectable())
5115 msaa_state |= STATE_SYSTEM_SELECTABLE;
5116
5118 msaa_state |= STATE_SYSTEM_SELECTED;
5119
5120
5121
5123 msaa_state |= STATE_SYSTEM_TRAVERSED;
5124
5125
5126
5127
5128
5129 switch (
data.GetCheckedState()) {
5132 break;
5135 msaa_state |= STATE_SYSTEM_PRESSED;
5137
5138
5139
5140 msaa_state |= STATE_SYSTEM_PRESSED | STATE_SYSTEM_CHECKED;
5141 } else {
5142 msaa_state |= STATE_SYSTEM_CHECKED;
5143 }
5144 break;
5146 msaa_state |= STATE_SYSTEM_MIXED;
5147 break;
5148 }
5149
5152 switch (restriction) {
5154 msaa_state |= STATE_SYSTEM_UNAVAILABLE;
5155 break;
5157 msaa_state |= STATE_SYSTEM_READONLY;
5158 break;
5159 default:
5160
5161
5162
5163
5166 msaa_state |= STATE_SYSTEM_READONLY;
5167 }
5168 break;
5169 }
5170
5171
5172
5173
5176 msaa_state |= STATE_SYSTEM_UNAVAILABLE;
5177 }
5178
5179
5180
5181
5183 if (focus == const_cast<AXPlatformNodeWin*>(this)->GetNativeViewAccessible())
5184 msaa_state |= STATE_SYSTEM_FOCUSED;
5185
5186
5187
5190 AXPlatformNodeBase* container = FromNativeViewAccessible(GetParent());
5191 if (container && container->GetParent() == focus) {
5192 AXNodeData container_data = container->GetData();
5196 msaa_state |= STATE_SYSTEM_FOCUSED;
5197 }
5198 }
5199 }
5200
5201
5202
5203
5204
5205
5206
5209 msaa_state |= STATE_SYSTEM_FOCUSED;
5210 }
5211
5212
5214 msaa_state |= STATE_SYSTEM_LINKED;
5215
5216
5219 msaa_state |= STATE_SYSTEM_MIXED;
5220
5221 return msaa_state;
5222}
5223
5224
5225std::optional<DWORD> AXPlatformNodeWin::MojoEventToMSAAEvent(
5227 switch (event) {
5229 return EVENT_SYSTEM_ALERT;
5233 return EVENT_OBJECT_STATECHANGE;
5236 return EVENT_OBJECT_FOCUS;
5238 return EVENT_OBJECT_LIVEREGIONCHANGED;
5240 return EVENT_SYSTEM_MENUSTART;
5242 return EVENT_SYSTEM_MENUEND;
5244 return EVENT_SYSTEM_MENUPOPUPSTART;
5246 return EVENT_SYSTEM_MENUPOPUPEND;
5248 return EVENT_OBJECT_SELECTION;
5250 return EVENT_OBJECT_SELECTIONADD;
5252 return EVENT_OBJECT_SELECTIONREMOVE;
5254 return EVENT_OBJECT_NAMECHANGE;
5256 return EVENT_OBJECT_HIDE;
5258 return EVENT_OBJECT_SHOW;
5260 return EVENT_OBJECT_VALUECHANGE;
5262 return EVENT_OBJECT_TEXTSELECTIONCHANGED;
5263 default:
5264 return std::nullopt;
5265 }
5266}
5267
5268
5269std::optional<EVENTID> AXPlatformNodeWin::MojoEventToUIAEvent(
5271 switch (event) {
5273 return UIA_SystemAlertEventId;
5275 return UIA_Text_TextChangedEventId;
5279 return UIA_AutomationFocusChangedEventId;
5281 return UIA_LiveRegionChangedEventId;
5283 return UIA_SelectionItem_ElementSelectedEventId;
5285 return UIA_SelectionItem_ElementAddedToSelectionEventId;
5287 return UIA_SelectionItem_ElementRemovedFromSelectionEventId;
5289 return UIA_ToolTipClosedEventId;
5291 return UIA_ToolTipOpenedEventId;
5292 default:
5293 return std::nullopt;
5294 }
5295}
5296
5297std::optional<PROPERTYID> AXPlatformNodeWin::MojoEventToUIAProperty(
5299 switch (event) {
5301 return UIA_ControllerForPropertyId;
5303 return UIA_ToggleToggleStatePropertyId;
5306 return UIA_ExpandCollapseExpandCollapseStatePropertyId;
5310 return UIA_SelectionItemIsSelectedPropertyId;
5313 return UIA_ToggleToggleStatePropertyId;
5314 }
5315 return std::nullopt;
5316 default:
5317 return std::nullopt;
5318 }
5319}
5320
5321
5322BSTR AXPlatformNodeWin::GetValueAttributeAsBstr(AXPlatformNodeWin*
target) {
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332 std::u16string result;
5333
5334
5335
5336
5338
5339 unsigned int color = static_cast<unsigned int>(
5341
5342
5343 unsigned int red = (((color) >> 16) & 0xFF);
5344 unsigned int green = (((color) >> 8) & 0xFF);
5345 unsigned int blue = (((color) >> 0) & 0xFF);
5346 std::u16string value_text;
5353 }
5354
5355
5356
5357
5364 }
5365
5366
5367
5368
5374 }
5375
5376
5377
5378
5379
5381 if (result.empty() &&
target->GetData().IsRangeValueSupported()) {
5382 float fval;
5384 &fval)) {
5389 }
5390 }
5391
5392 if (result.empty() &&
target->IsRichTextField())
5393 result =
target->GetInnerText();
5394
5398}
5399
5400HRESULT AXPlatformNodeWin::GetStringAttributeAsBstr(
5402 BSTR* value_bstr) const {
5403 std::u16string str;
5404
5405 if (!GetString16Attribute(attribute, &str))
5406 return S_FALSE;
5407
5410
5411 return S_OK;
5412}
5413
5414HRESULT AXPlatformNodeWin::GetNameAsBstr(BSTR* value_bstr) const {
5415 std::u16string str = GetNameAsString16();
5418 return S_OK;
5419}
5420
5421
5422
5423void AXPlatformNodeWin::AddAlertTarget() {}
5424
5425void AXPlatformNodeWin::RemoveAlertTarget() {}
5426
5427AXPlatformNodeWin* AXPlatformNodeWin::GetTargetFromChildID(
5428 const VARIANT& var_id) {
5429 if (V_VT(&var_id) != VT_I4)
5430 return nullptr;
5431
5432 LONG child_id = V_I4(&var_id);
5433 if (child_id == CHILDID_SELF)
5434 return this;
5435
5436 if (child_id >= 1 && child_id <= GetDelegate()->GetChildCount()) {
5437
5438
5439 AXPlatformNodeBase*
base =
5440 FromNativeViewAccessible(GetDelegate()->ChildAtIndex(child_id - 1));
5441 return static_cast<AXPlatformNodeWin*
>(
base);
5442 }
5443
5444 if (child_id >= 0)
5445 return nullptr;
5446
5447
5448 AXPlatformNode* node = GetFromUniqueId(-child_id);
5449 if (!node)
5450 return nullptr;
5451
5452 AXPlatformNodeBase*
base =
5453 FromNativeViewAccessible(node->GetNativeViewAccessible());
5454 if (
base && !
base->IsDescendantOf(
this))
5456
5457 return static_cast<AXPlatformNodeWin*
>(
base);
5458}
5459
5460bool AXPlatformNodeWin::IsInTreeGrid() {
5461 AXPlatformNodeBase* container = FromNativeViewAccessible(GetParent());
5462
5463
5465 container = FromNativeViewAccessible(container->GetParent());
5466
5467 if (!container)
5468 return false;
5469
5471}
5472
5473HRESULT AXPlatformNodeWin::AllocateComArrayFromVector(
5474 std::vector<LONG>& results,
5481
5482 auto count = std::min((
LONG)results.size(), max);
5483 *n_selected = count;
5484 *selected =
static_cast<LONG*
>(CoTaskMemAlloc(
sizeof(
LONG) * count));
5485
5486 for (
LONG i = 0;
i < count;
i++)
5487 (*selected)[
i] = results[
i];
5488 return S_OK;
5489}
5490
5491bool AXPlatformNodeWin::IsPlaceholderText() const {
5493 return false;
5494 AXPlatformNodeWin* parent =
5495 static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(GetParent()));
5496
5498 return parent->IsTextField() &&
5500}
5501
5502double AXPlatformNodeWin::GetHorizontalScrollPercent() {
5503 if (!IsHorizontallyScrollable())
5504 return UIA_ScrollPatternNoScroll;
5505
5509 return 100.0 * (
x - x_min) / (x_max - x_min);
5510}
5511
5512double AXPlatformNodeWin::GetVerticalScrollPercent() {
5513 if (!IsVerticallyScrollable())
5514 return UIA_ScrollPatternNoScroll;
5515
5519 return 100.0 * (
y - y_min) / (y_max - y_min);
5520}
5521
5522BSTR AXPlatformNodeWin::GetFontNameAttributeAsBSTR() const {
5523 const std::u16string string =
5525
5527}
5528
5529BSTR AXPlatformNodeWin::GetStyleNameAttributeAsBSTR() const {
5530 std::u16string style_name =
5531 GetDelegate()->GetStyleNameAttributeAsLocalizedString();
5532
5534}
5535
5536TextDecorationLineStyle AXPlatformNodeWin::GetUIATextDecorationStyle(
5540 GetIntAttribute(int_attribute));
5541
5542 switch (text_decoration_style) {
5544 return TextDecorationLineStyle::TextDecorationLineStyle_None;
5546 return TextDecorationLineStyle::TextDecorationLineStyle_Dot;
5548 return TextDecorationLineStyle::TextDecorationLineStyle_Dash;
5550 return TextDecorationLineStyle::TextDecorationLineStyle_Single;
5552 return TextDecorationLineStyle::TextDecorationLineStyle_Double;
5554 return TextDecorationLineStyle::TextDecorationLineStyle_Wavy;
5555 }
5556}
5557
5558
5559
5560AXPlatformNodeWin::PatternProviderFactoryMethod
5561AXPlatformNodeWin::GetPatternProviderFactoryMethod(PATTERNID pattern_id) {
5562 const AXNodeData&
data = GetData();
5563
5564 switch (pattern_id) {
5565 case UIA_ExpandCollapsePatternId:
5566 if (
data.SupportsExpandCollapse()) {
5567 return &PatternProvider<IExpandCollapseProvider>;
5568 }
5569 break;
5570
5571 case UIA_GridPatternId:
5573 return &PatternProvider<IGridProvider>;
5574 }
5575 break;
5576
5577 case UIA_GridItemPatternId:
5579 return &PatternProvider<IGridItemProvider>;
5580 }
5581 break;
5582
5583 case UIA_InvokePatternId:
5584 if (
data.IsInvocable()) {
5585 return &PatternProvider<IInvokeProvider>;
5586 }
5587 break;
5588
5589 case UIA_RangeValuePatternId:
5590 if (
data.IsRangeValueSupported()) {
5591 return &PatternProvider<IRangeValueProvider>;
5592 }
5593 break;
5594
5595 case UIA_ScrollPatternId:
5596 if (IsScrollable()) {
5597 return &PatternProvider<IScrollProvider>;
5598 }
5599 break;
5600
5601 case UIA_ScrollItemPatternId:
5602 return &PatternProvider<IScrollItemProvider>;
5603 break;
5604
5605 case UIA_SelectionItemPatternId:
5606 if (IsSelectionItemSupported()) {
5607 return &PatternProvider<ISelectionItemProvider>;
5608 }
5609 break;
5610
5611 case UIA_SelectionPatternId:
5613 return &PatternProvider<ISelectionProvider>;
5614 }
5615 break;
5616
5617 case UIA_TablePatternId:
5618
5619
5620
5621
5623 std::optional<bool> table_has_headers =
5624 GetDelegate()->GetTableHasColumnOrRowHeaderNode();
5625 if (table_has_headers.has_value() && table_has_headers.value()) {
5626 return &PatternProvider<ITableProvider>;
5627 }
5628 }
5629 break;
5630
5631 case UIA_TableItemPatternId:
5632
5633
5634
5635
5636
5638 std::optional<bool> table_has_headers =
5639 GetDelegate()->GetTableHasColumnOrRowHeaderNode();
5640 if (table_has_headers.has_value() && table_has_headers.value()) {
5641 return &PatternProvider<ITableItemProvider>;
5642 }
5643 }
5644 break;
5645
5646 case UIA_TextEditPatternId:
5647 case UIA_TextPatternId:
5648 if (
IsText() || IsTextField() ||
5650 return &AXPlatformNodeTextProviderWin::CreateIUnknown;
5651 }
5652 break;
5653
5654 case UIA_TogglePatternId:
5656 return &PatternProvider<IToggleProvider>;
5657 }
5658 break;
5659
5660 case UIA_ValuePatternId:
5662 return &PatternProvider<IValueProvider>;
5663 }
5664 break;
5665
5666 case UIA_WindowPatternId:
5668 return &PatternProvider<IWindowProvider>;
5669 }
5670 break;
5671
5672
5673 case UIA_AnnotationPatternId:
5674 case UIA_CustomNavigationPatternId:
5675 case UIA_DockPatternId:
5676 case UIA_DragPatternId:
5677 case UIA_DropTargetPatternId:
5678 case UIA_ItemContainerPatternId:
5679 case UIA_MultipleViewPatternId:
5680 case UIA_ObjectModelPatternId:
5681 case UIA_SpreadsheetPatternId:
5682 case UIA_SpreadsheetItemPatternId:
5683 case UIA_StylesPatternId:
5684 case UIA_SynchronizedInputPatternId:
5685 case UIA_TextPattern2Id:
5686 case UIA_TransformPatternId:
5687 case UIA_TransformPattern2Id:
5688 case UIA_VirtualizedItemPatternId:
5689 break;
5690
5691
5692 case UIA_LegacyIAccessiblePatternId:
5693 break;
5694 }
5695 return nullptr;
5696}
5697
5698void AXPlatformNodeWin::FireLiveRegionChangeRecursive() {
5700 if (HasStringAttribute(live_status_attr) &&
5701 GetStringAttribute(live_status_attr) != "off") {
5703 ::UiaRaiseAutomationEvent(this, UIA_LiveRegionChangedEventId);
5704 return;
5705 }
5706
5707 for (int index = 0; index < GetChildCount(); ++index) {
5708 auto* child = static_cast<AXPlatformNodeWin*>(
5709 FromNativeViewAccessible(ChildAtIndex(index)));
5710
5711
5712
5713
5714 if (child->GetDelegate()->IsWebContent())
5715 child->FireLiveRegionChangeRecursive();
5716 }
5717}
5718
5719AXPlatformNodeWin* AXPlatformNodeWin::GetLowestAccessibleElement() {
5720 if (!IsInaccessibleDueToAncestor())
5721 return this;
5722
5723 AXPlatformNodeWin* parent = static_cast<AXPlatformNodeWin*>(
5725 while (parent) {
5726 if (parent->ShouldHideChildrenForUIA())
5727 return parent;
5728 parent = static_cast<AXPlatformNodeWin*>(
5730 }
5731
5733 return nullptr;
5734}
5735
5736AXPlatformNodeWin* AXPlatformNodeWin::GetFirstTextOnlyDescendant() {
5737 for (auto* child = static_cast<AXPlatformNodeWin*>(GetFirstChild()); child;
5738 child = static_cast<AXPlatformNodeWin*>(child->GetNextSibling())) {
5739 if (child->IsText())
5740 return child;
5741 if (AXPlatformNodeWin* descendant = child->GetFirstTextOnlyDescendant())
5742 return descendant;
5743 }
5744 return nullptr;
5745}
5746
5747bool AXPlatformNodeWin::IsDescendantOf(AXPlatformNode* ancestor) const {
5748 if (!ancestor) {
5749 return false;
5750 }
5751
5753 return true;
5754 }
5755
5756
5757
5758 IRawElementProviderFragmentRoot* root;
5760 const_cast<AXPlatformNodeWin*>(this)->get_FragmentRoot(&root))) {
5761 AXPlatformNodeWin* root_win;
5762 if (
SUCCEEDED(root->QueryInterface(__uuidof(AXPlatformNodeWin),
5763 reinterpret_cast<void**>(&root_win)))) {
5764 return ancestor == static_cast<AXPlatformNode*>(root_win);
5765 }
5766 }
5767
5768 return false;
5769}
5770
5771}
ax::mojom::Event event_type
void Insert(typename internal::VariantUtil< ExpectedVartype >::Type value)
constexpr int height() const
Vector2d OffsetFromOrigin() const
constexpr int width() const
static AXFragmentRootWin * GetForAcceleratedWidget(gfx::AcceleratedWidget widget)
static AXFragmentRootWin * GetFragmentRootParentOf(gfx::NativeViewAccessible accessible)
static constexpr uint32_t kScreenReader
static constexpr uint32_t kHTML
static const UiaRegistrarWin & GetInstance()
FlViewAccessible * accessible
const char FlTextDirection text_direction
@ kPdfActionableHighlight
@ kAttributeExplicitlyEmpty
const int32_t kUnknownAriaColumnOrRowCount
@ kDocumentSelectionChanged
@ kSilentlyEligibleForAnnotation
@ kAnnotationProcessFailed
@ kIneligibleForAnnotation
@ kWillNotAnnotateDueToScheme
@ kTextStrikethroughStyle
float GetScaleFactorForHWND(HWND hwnd)
std::string UTF16ToUTF8(std::u16string src)
void ReplaceChars(std::string in, std::string from, std::string to, std::string *out)
std::u16string UTF8ToUTF16(std::string src)
std::u16string ASCIIToUTF16(std::string src)
std::string JoinString(std::vector< std::string > tokens, std::string delimiter)
Dst ClampRound(Src value)
bool Contains(const Container &container, const Value &value)
std::string NumberToString(int32_t number)
std::u16string NumberToString16(float number)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
std::u16string WideStringToUtf16(const std::wstring_view str)
std::wstring Utf16ToWideString(const std::u16string_view str)
Point PointAtOffsetFromOrigin(const Vector2d &offset_from_origin)
Rect ToEnclosingRect(const RectF &r)
UnimplementedNativeViewAccessible * NativeViewAccessible
void CreateATLModuleIfNeeded()
bool IsImage(const ax::mojom::Role role)
const uint32_t kScreenReaderAndHTMLAccessibilityModes
bool IsValuePatternSupported(AXPlatformNodeDelegate *delegate)
bool IsContainerWithSelectableChildren(const ax::mojom::Role role)
bool IsControl(const ax::mojom::Role role)
bool IsReadOnlySupported(const ax::mojom::Role role)
const char * ToString(ax::mojom::Event event)
bool IsCellOrTableHeader(const ax::mojom::Role role)
bool HasPresentationalChildren(const ax::mojom::Role role)
bool IsMenuItem(ax::mojom::Role role)
bool IsTableLike(const ax::mojom::Role role)
bool SupportsOrientation(const ax::mojom::Role role)
bool IsTableHeader(ax::mojom::Role role)
bool SupportsToggle(const ax::mojom::Role role)
bool ShouldHaveReadonlyStateByDefault(const ax::mojom::Role role)
bool IsList(const ax::mojom::Role role)
bool IsDialog(const ax::mojom::Role role)
std::optional< int32_t > GetActivePopupAxUniqueId()
bool IsText(ax::mojom::Role role)
#define BASE_DCHECK(condition)
#define BASE_UNREACHABLE()