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
270 if (!accessible)
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));
401 ++i;
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
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
564 if (
event_type == ax::mojom::Event::kSelection) {
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
591 if (
event_type == ax::mojom::Event::kValueChanged) {
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,
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
833 IAccessible*
result =
nullptr;
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();
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());
867 return S_OK;
868
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());
881 return S_OK;
882
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);
895 return S_OK;
896
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());
910 return S_OK;
911
913 break;
914 }
915 }
916
918 return S_FALSE;
919
920 end->vt = VT_DISPATCH;
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;
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::Collapse() {
1206 return UIA_E_ELEMENTNOTAVAILABLE;
1207
1209 return UIA_E_INVALIDOPERATION;
1210
1211 AXActionData action_data;
1213 if (GetDelegate()->AccessibilityPerformAction(action_data))
1214 return S_OK;
1215 return E_FAIL;
1216}
1217
1218IFACEMETHODIMP AXPlatformNodeWin::Expand() {
1221 return UIA_E_ELEMENTNOTAVAILABLE;
1222
1224 return UIA_E_INVALIDOPERATION;
1225
1226 AXActionData action_data;
1228 if (GetDelegate()->AccessibilityPerformAction(action_data))
1229 return S_OK;
1230 return E_FAIL;
1231}
1232
1233ExpandCollapseState AXPlatformNodeWin::ComputeExpandCollapseState() const {
1234 const AXNodeData&
data = GetData();
1235
1236
1237
1238
1239
1240 if (
data.IsMenuButton()) {
1241 if (
data.IsButtonPressed())
1242 return ExpandCollapseState_Expanded;
1243 return ExpandCollapseState_Collapsed;
1244 }
1245
1247 return ExpandCollapseState_Expanded;
1249 return ExpandCollapseState_Collapsed;
1250 } else {
1251 return ExpandCollapseState_LeafNode;
1252 }
1253}
1254
1255IFACEMETHODIMP AXPlatformNodeWin::get_ExpandCollapseState(
1256 ExpandCollapseState*
result) {
1258
1259 *
result = ComputeExpandCollapseState();
1260
1261 return S_OK;
1262}
1263
1264
1265
1266
1267
1268IFACEMETHODIMP AXPlatformNodeWin::get_Column(
int*
result) {
1270 std::optional<int> column = GetTableColumn();
1271 if (!column)
1272 return E_FAIL;
1274 return S_OK;
1275}
1276
1277IFACEMETHODIMP AXPlatformNodeWin::get_ColumnSpan(
int*
result) {
1279 std::optional<int> column_span = GetTableColumnSpan();
1280 if (!column_span)
1281 return E_FAIL;
1283 return S_OK;
1284}
1285
1286IFACEMETHODIMP AXPlatformNodeWin::get_ContainingGrid(
1287 IRawElementProviderSimple**
result) {
1289
1290 AXPlatformNodeBase*
table = GetTable();
1292 return E_FAIL;
1293
1294 auto* node_win =
static_cast<AXPlatformNodeWin*
>(
table);
1295 node_win->AddRef();
1296 *
result =
static_cast<IRawElementProviderSimple*
>(node_win);
1297 return S_OK;
1298}
1299
1300IFACEMETHODIMP AXPlatformNodeWin::get_Row(
int*
result) {
1302 std::optional<int> row = GetTableRow();
1303 if (!row)
1304 return E_FAIL;
1306 return S_OK;
1307}
1308
1309IFACEMETHODIMP AXPlatformNodeWin::get_RowSpan(
int*
result) {
1311 std::optional<int> row_span = GetTableRowSpan();
1312 if (!row_span)
1313 return E_FAIL;
1315 return S_OK;
1316}
1317
1318
1319
1320
1321
1322IFACEMETHODIMP AXPlatformNodeWin::GetItem(int row,
1323 int column,
1324 IRawElementProviderSimple**
result) {
1326
1327 AXPlatformNodeBase* cell = GetTableCell(row, column);
1328 if (!cell)
1329 return E_INVALIDARG;
1330
1331 auto* node_win = static_cast<AXPlatformNodeWin*>(cell);
1332 node_win->AddRef();
1333 *
result =
static_cast<IRawElementProviderSimple*
>(node_win);
1334 return S_OK;
1335}
1336
1337IFACEMETHODIMP AXPlatformNodeWin::get_RowCount(
int*
result) {
1339
1340 std::optional<int> row_count = GetTableAriaRowCount();
1341 if (!row_count)
1342 row_count = GetTableRowCount();
1343
1345 return E_UNEXPECTED;
1347 return S_OK;
1348}
1349
1350IFACEMETHODIMP AXPlatformNodeWin::get_ColumnCount(
int*
result) {
1352
1353 std::optional<int> column_count = GetTableAriaColumnCount();
1354 if (!column_count)
1355 column_count = GetTableColumnCount();
1356
1357 if (!column_count ||
1359 return E_UNEXPECTED;
1360 }
1362 return S_OK;
1363}
1364
1365
1366
1367
1368
1369IFACEMETHODIMP AXPlatformNodeWin::Invoke() {
1371
1373 return UIA_E_ELEMENTNOTENABLED;
1374
1375 AXActionData action_data;
1377 GetDelegate()->AccessibilityPerformAction(action_data);
1378
1379 return S_OK;
1380}
1381
1382
1383
1384
1385
1386IFACEMETHODIMP AXPlatformNodeWin::ScrollIntoView() {
1390
1391 AXActionData action_data;
1392 action_data.target_node_id = GetData().id;
1393 action_data.target_rect = r;
1394 action_data.horizontal_scroll_alignment =
1396 action_data.vertical_scroll_alignment =
1398 action_data.scroll_behavior =
1400 if (GetDelegate()->AccessibilityPerformAction(action_data))
1401 return S_OK;
1402 return E_FAIL;
1403}
1404
1405
1406
1407
1408
1409IFACEMETHODIMP AXPlatformNodeWin::Scroll(ScrollAmount horizontal_amount,
1410 ScrollAmount vertical_amount) {
1412 if (!IsScrollable())
1413 return E_FAIL;
1414
1415 AXActionData action_data;
1416 action_data.target_node_id = GetData().id;
1419 CalculateUIAScrollPoint(horizontal_amount, vertical_amount));
1420 if (GetDelegate()->AccessibilityPerformAction(action_data))
1421 return S_OK;
1422 return E_FAIL;
1423}
1424
1425IFACEMETHODIMP AXPlatformNodeWin::SetScrollPercent(double horizontal_percent,
1426 double vertical_percent) {
1428 if (!IsScrollable())
1429 return E_FAIL;
1430
1440
1441 AXActionData action_data;
1442 action_data.target_node_id = GetData().id;
1444 action_data.target_point = scroll_to;
1445 if (GetDelegate()->AccessibilityPerformAction(action_data))
1446 return S_OK;
1447 return E_FAIL;
1448}
1449
1450IFACEMETHODIMP AXPlatformNodeWin::get_HorizontallyScrollable(
BOOL*
result) {
1452 *
result = IsHorizontallyScrollable();
1453 return S_OK;
1454}
1455
1456IFACEMETHODIMP AXPlatformNodeWin::get_HorizontalScrollPercent(
double*
result) {
1458 *
result = GetHorizontalScrollPercent();
1459 return S_OK;
1460}
1461
1462
1463
1464IFACEMETHODIMP AXPlatformNodeWin::get_HorizontalViewSize(
double*
result) {
1466 if (!IsHorizontallyScrollable()) {
1468 return S_OK;
1469 }
1470
1471 gfx::RectF clipped_bounds(GetDelegate()->GetBoundsRect(
1475 float total_width = clipped_bounds.width() + x_max - x_min;
1476 BASE_DCHECK(clipped_bounds.width() <= total_width);
1477 *
result = 100.0 * clipped_bounds.width() / total_width;
1478 return S_OK;
1479}
1480
1481IFACEMETHODIMP AXPlatformNodeWin::get_VerticallyScrollable(
BOOL*
result) {
1483 *
result = IsVerticallyScrollable();
1484 return S_OK;
1485}
1486
1487IFACEMETHODIMP AXPlatformNodeWin::get_VerticalScrollPercent(
double*
result) {
1489 *
result = GetVerticalScrollPercent();
1490 return S_OK;
1491}
1492
1493
1494
1495IFACEMETHODIMP AXPlatformNodeWin::get_VerticalViewSize(
double*
result) {
1497 if (!IsVerticallyScrollable()) {
1499 return S_OK;
1500 }
1501
1502 gfx::RectF clipped_bounds(GetDelegate()->GetBoundsRect(
1506 float total_height = clipped_bounds.height() + y_max - y_min;
1507 BASE_DCHECK(clipped_bounds.height() <= total_height);
1508 *
result = 100.0 * clipped_bounds.height() / total_height;
1509 return S_OK;
1510}
1511
1512
1513
1514
1515
1516HRESULT AXPlatformNodeWin::ISelectionItemProviderSetSelected(
1517 bool selected) const {
1520 return UIA_E_ELEMENTNOTENABLED;
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537 if (selected == ISelectionItemProviderIsSelected() &&
1539 return S_OK;
1540
1543 if (GetDelegate()->AccessibilityPerformAction(data))
1544 return S_OK;
1545 return UIA_E_INVALIDOPERATION;
1546}
1547
1548bool AXPlatformNodeWin::ISelectionItemProviderIsSelected() const {
1549
1550
1551
1555
1556
1557
1558
1560}
1561
1562IFACEMETHODIMP AXPlatformNodeWin::AddToSelection() {
1563 return ISelectionItemProviderSetSelected(true);
1564}
1565
1566IFACEMETHODIMP AXPlatformNodeWin::RemoveFromSelection() {
1567 return ISelectionItemProviderSetSelected(false);
1568}
1569
1570IFACEMETHODIMP AXPlatformNodeWin::Select() {
1571 return ISelectionItemProviderSetSelected(true);
1572}
1573
1574IFACEMETHODIMP AXPlatformNodeWin::get_IsSelected(
BOOL*
result) {
1576 *
result = ISelectionItemProviderIsSelected();
1577 return S_OK;
1578}
1579
1580IFACEMETHODIMP AXPlatformNodeWin::get_SelectionContainer(
1581 IRawElementProviderSimple**
result) {
1583
1584 auto* node_win = static_cast<AXPlatformNodeWin*>(GetSelectionContainer());
1585 if (!node_win)
1586 return E_FAIL;
1587
1588 node_win->AddRef();
1589 *
result =
static_cast<IRawElementProviderSimple*
>(node_win);
1590 return S_OK;
1591}
1592
1593
1594
1595
1596
1597IFACEMETHODIMP AXPlatformNodeWin::GetSelection(SAFEARRAY**
result) {
1599
1600 std::vector<AXPlatformNodeBase*> selected_children;
1601 int max_items = GetMaxSelectableItems();
1602 if (max_items)
1603 GetSelectedItems(max_items, &selected_children);
1604
1605 LONG selected_children_count = selected_children.size();
1606 *
result = SafeArrayCreateVector(VT_UNKNOWN, 0, selected_children_count);
1608 return E_OUTOFMEMORY;
1609
1610 for (
LONG i = 0; i < selected_children_count; ++i) {
1611 AXPlatformNodeWin* children =
1612 static_cast<AXPlatformNodeWin*>(selected_children[i]);
1613 HRESULT hr = SafeArrayPutElement(
1614 *
result, &i,
static_cast<IRawElementProviderSimple*
>(children));
1616 SafeArrayDestroy(*
result);
1618 return hr;
1619 }
1620 }
1621 return S_OK;
1622}
1623
1624IFACEMETHODIMP AXPlatformNodeWin::get_CanSelectMultiple(
BOOL*
result) {
1627 return S_OK;
1628}
1629
1630IFACEMETHODIMP AXPlatformNodeWin::get_IsSelectionRequired(
BOOL*
result) {
1633 return S_OK;
1634}
1635
1636
1637
1638
1639
1640IFACEMETHODIMP AXPlatformNodeWin::GetColumnHeaderItems(SAFEARRAY**
result) {
1642
1643 std::optional<int> column = GetTableColumn();
1644 if (!column)
1645 return E_FAIL;
1646
1647 std::vector<int32_t> column_header_ids =
1648 GetDelegate()->GetColHeaderNodeIds(*column);
1649
1650 std::vector<AXPlatformNodeWin*> platform_node_list =
1651 CreatePlatformNodeVectorFromRelationIdVector(column_header_ids);
1652
1653 *
result = CreateUIAElementsSafeArray(platform_node_list);
1654 return S_OK;
1655}
1656
1657IFACEMETHODIMP AXPlatformNodeWin::GetRowHeaderItems(SAFEARRAY**
result) {
1659
1660 std::optional<int> row = GetTableRow();
1661 if (!row)
1662 return E_FAIL;
1663
1664 std::vector<int32_t> row_header_ids =
1665 GetDelegate()->GetRowHeaderNodeIds(*row);
1666
1667 std::vector<AXPlatformNodeWin*> platform_node_list =
1668 CreatePlatformNodeVectorFromRelationIdVector(row_header_ids);
1669
1670 *
result = CreateUIAElementsSafeArray(platform_node_list);
1671 return S_OK;
1672}
1673
1674
1675
1676
1677
1678IFACEMETHODIMP AXPlatformNodeWin::GetColumnHeaders(SAFEARRAY**
result) {
1680
1681 std::vector<int32_t> column_header_ids = GetDelegate()->GetColHeaderNodeIds();
1682
1683 std::vector<AXPlatformNodeWin*> platform_node_list =
1684 CreatePlatformNodeVectorFromRelationIdVector(column_header_ids);
1685
1686 *
result = CreateUIAElementsSafeArray(platform_node_list);
1687 return S_OK;
1688}
1689
1690IFACEMETHODIMP AXPlatformNodeWin::GetRowHeaders(SAFEARRAY**
result) {
1692
1693 std::vector<int32_t> row_header_ids = GetDelegate()->GetRowHeaderNodeIds();
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
1702IFACEMETHODIMP AXPlatformNodeWin::get_RowOrColumnMajor(
1703 RowOrColumnMajor*
result) {
1705
1706
1707
1708 *
result = RowOrColumnMajor_RowMajor;
1709 return S_OK;
1710}
1711
1712
1713
1714
1715
1716IFACEMETHODIMP AXPlatformNodeWin::Toggle() {
1718 AXActionData action_data;
1720
1721 if (GetDelegate()->AccessibilityPerformAction(action_data))
1722 return S_OK;
1723 return E_FAIL;
1724}
1725
1726IFACEMETHODIMP AXPlatformNodeWin::get_ToggleState(ToggleState*
result) {
1728 const auto checked_state = GetData().GetCheckedState();
1730 *
result = ToggleState_On;
1732 *
result = ToggleState_Indeterminate;
1733 } else {
1734 *
result = ToggleState_Off;
1735 }
1736 return S_OK;
1737}
1738
1739
1740
1741
1742
1743IFACEMETHODIMP AXPlatformNodeWin::SetValue(LPCWSTR value) {
1745 if (!value)
1746 return E_INVALIDARG;
1747
1748 if (GetData().IsReadOnlyOrDisabled())
1749 return UIA_E_ELEMENTNOTENABLED;
1750
1754 if (GetDelegate()->AccessibilityPerformAction(data))
1755 return S_OK;
1756 return E_FAIL;
1757}
1758
1759IFACEMETHODIMP AXPlatformNodeWin::get_IsReadOnly(
BOOL*
result) {
1761 *
result = GetData().IsReadOnlyOrDisabled();
1762 return S_OK;
1763}
1764
1765IFACEMETHODIMP AXPlatformNodeWin::get_Value(BSTR*
result) {
1767 *
result = GetValueAttributeAsBstr(
this);
1768 return S_OK;
1769}
1770
1771
1772
1773
1774
1775IFACEMETHODIMP AXPlatformNodeWin::SetVisualState(
1776 WindowVisualState window_visual_state) {
1778 return UIA_E_NOTSUPPORTED;
1779}
1780
1781IFACEMETHODIMP AXPlatformNodeWin::Close() {
1783 return UIA_E_NOTSUPPORTED;
1784}
1785
1786IFACEMETHODIMP AXPlatformNodeWin::WaitForInputIdle(int milliseconds,
1789 return UIA_E_NOTSUPPORTED;
1790}
1791
1792IFACEMETHODIMP AXPlatformNodeWin::get_CanMaximize(
BOOL*
result) {
1794 return UIA_E_NOTSUPPORTED;
1795}
1796
1797IFACEMETHODIMP AXPlatformNodeWin::get_CanMinimize(
BOOL*
result) {
1799 return UIA_E_NOTSUPPORTED;
1800}
1801
1802IFACEMETHODIMP AXPlatformNodeWin::get_IsModal(
BOOL*
result) {
1804
1806
1807 return S_OK;
1808}
1809
1810IFACEMETHODIMP AXPlatformNodeWin::get_WindowVisualState(
1811 WindowVisualState*
result) {
1813 return UIA_E_NOTSUPPORTED;
1814}
1815
1816IFACEMETHODIMP AXPlatformNodeWin::get_WindowInteractionState(
1817 WindowInteractionState*
result) {
1819 return UIA_E_NOTSUPPORTED;
1820}
1821
1822IFACEMETHODIMP AXPlatformNodeWin::get_IsTopmost(
BOOL*
result) {
1824 return UIA_E_NOTSUPPORTED;
1825}
1826
1827
1828
1829
1830
1831IFACEMETHODIMP AXPlatformNodeWin::SetValue(double value) {
1836 if (GetDelegate()->AccessibilityPerformAction(data))
1837 return S_OK;
1838 return E_FAIL;
1839}
1840
1841IFACEMETHODIMP AXPlatformNodeWin::get_LargeChange(
double*
result) {
1843 float attribute;
1845 &attribute)) {
1846 *
result = attribute * kLargeChangeScaleFactor;
1847 return S_OK;
1848 }
1849 return E_FAIL;
1850}
1851
1852IFACEMETHODIMP AXPlatformNodeWin::get_Maximum(
double*
result) {
1854 float attribute;
1856 &attribute)) {
1858 return S_OK;
1859 }
1860 return E_FAIL;
1861}
1862
1863IFACEMETHODIMP AXPlatformNodeWin::get_Minimum(
double*
result) {
1865 float attribute;
1867 &attribute)) {
1869 return S_OK;
1870 }
1871 return E_FAIL;
1872}
1873
1874IFACEMETHODIMP AXPlatformNodeWin::get_SmallChange(
double*
result) {
1876 float attribute;
1878 &attribute)) {
1880 return S_OK;
1881 }
1882 return E_FAIL;
1883}
1884
1885IFACEMETHODIMP AXPlatformNodeWin::get_Value(
double*
result) {
1887 float attribute;
1889 &attribute)) {
1891 return S_OK;
1892 }
1893 return E_FAIL;
1894}
1895
1896
1897
1898
1899
1900IFACEMETHODIMP AXPlatformNodeWin::Navigate(
1901 NavigateDirection direction,
1902 IRawElementProviderFragment** element_provider) {
1904
1905 *element_provider = nullptr;
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1955 switch (direction) {
1956 case NavigateDirection_Parent: {
1957
1958
1959 AXFragmentRootWin* fragment_root =
1962 neighbor = fragment_root->GetNativeViewAccessible();
1963 } else {
1964 neighbor = GetParent();
1965 }
1966 } break;
1967
1968 case NavigateDirection_FirstChild:
1969 if (GetChildCount() > 0)
1970 neighbor = GetFirstChild()->GetNativeViewAccessible();
1971 break;
1972
1973 case NavigateDirection_LastChild:
1974 if (GetChildCount() > 0)
1975 neighbor = GetLastChild()->GetNativeViewAccessible();
1976 break;
1977
1978 case NavigateDirection_NextSibling:
1979
1981 GetNativeViewAccessible()) == nullptr) {
1982 AXPlatformNodeBase* neighbor_node = GetNextSibling();
1983 if (neighbor_node)
1984 neighbor = neighbor_node->GetNativeViewAccessible();
1985 }
1986 break;
1987
1988 case NavigateDirection_PreviousSibling:
1989
1991 GetNativeViewAccessible()) == nullptr) {
1992 AXPlatformNodeBase* neighbor_node = GetPreviousSibling();
1993 if (neighbor_node)
1994 neighbor = neighbor_node->GetNativeViewAccessible();
1995 }
1996 break;
1997
1998 default:
2000 break;
2001 }
2002
2003 if (neighbor) {
2004 if (direction != NavigateDirection_Parent) {
2005
2006
2007 AXFragmentRootWin* fragment_root =
2009 if (
BASE_UNLIKELY(fragment_root && fragment_root != GetDelegate()))
2010 neighbor = fragment_root->GetNativeViewAccessible();
2011 }
2012 neighbor->QueryInterface(IID_PPV_ARGS(element_provider));
2013 }
2014
2015 return S_OK;
2016}
2017
2018void AXPlatformNodeWin::GetRuntimeIdArray(
2019 AXPlatformNodeWin::RuntimeIdArray& runtime_id) {
2020 runtime_id[0] = UiaAppendRuntimeId;
2021 runtime_id[1] = GetUniqueId();
2022}
2023
2024IFACEMETHODIMP AXPlatformNodeWin::GetRuntimeId(SAFEARRAY** runtime_id) {
2026
2027 RuntimeIdArray id_array;
2028 GetRuntimeIdArray(id_array);
2029 *runtime_id = ::SafeArrayCreateVector(VT_I4, 0, id_array.size());
2030
2031 int* array_data = nullptr;
2032 ::SafeArrayAccessData(*runtime_id, reinterpret_cast<void**>(&array_data));
2033
2034 size_t runtime_id_byte_count = id_array.size() *
sizeof(
int);
2035 memcpy_s(array_data, runtime_id_byte_count, id_array.data(),
2036 runtime_id_byte_count);
2037
2038 ::SafeArrayUnaccessData(*runtime_id);
2039
2040 return S_OK;
2041}
2042
2043IFACEMETHODIMP AXPlatformNodeWin::get_BoundingRectangle(
2044 UiaRect* screen_physical_pixel_bounds) {
2046
2050 screen_physical_pixel_bounds->left =
bounds.x();
2051 screen_physical_pixel_bounds->top =
bounds.y();
2052 screen_physical_pixel_bounds->width =
bounds.width();
2053 screen_physical_pixel_bounds->height =
bounds.height();
2054 return S_OK;
2055}
2056
2057IFACEMETHODIMP AXPlatformNodeWin::GetEmbeddedFragmentRoots(
2058 SAFEARRAY** embedded_fragment_roots) {
2060
2061 *embedded_fragment_roots = nullptr;
2062 return S_OK;
2063}
2064
2065IFACEMETHODIMP AXPlatformNodeWin::SetFocus() {
2067
2068 AXActionData action_data;
2070 delegate_->AccessibilityPerformAction(action_data);
2071 return S_OK;
2072}
2073
2074IFACEMETHODIMP AXPlatformNodeWin::get_FragmentRoot(
2075 IRawElementProviderFragmentRoot** fragment_root) {
2077
2078 gfx::AcceleratedWidget widget =
2079 delegate_->GetTargetForNativeAccessibilityEvent();
2080 if (widget) {
2081 AXFragmentRootWin*
root =
2083 if (root != nullptr) {
2084 root->GetNativeViewAccessible()->QueryInterface(
2085 IID_PPV_ARGS(fragment_root));
2087 return S_OK;
2088 }
2089 }
2090
2091 *fragment_root = nullptr;
2092 return UIA_E_ELEMENTNOTAVAILABLE;
2093}
2094
2095
2096
2097
2098
2099IFACEMETHODIMP AXPlatformNodeWin::GetPatternProvider(PATTERNID pattern_id,
2101 return GetPatternProviderImpl(pattern_id,
result);
2102}
2103
2104HRESULT AXPlatformNodeWin::GetPatternProviderImpl(PATTERNID pattern_id,
2107
2109
2110 PatternProviderFactoryMethod factory_method =
2111 GetPatternProviderFactoryMethod(pattern_id);
2112 if (factory_method)
2113 (*factory_method)(
this,
result);
2114
2115 return S_OK;
2116}
2117
2118IFACEMETHODIMP AXPlatformNodeWin::GetPropertyValue(PROPERTYID property_id,
2120 return GetPropertyValueImpl(property_id,
result);
2121}
2122
2123HRESULT AXPlatformNodeWin::GetPropertyValueImpl(PROPERTYID property_id,
2126
2128
2129 int int_attribute;
2130 const AXNodeData&
data = GetData();
2131
2132
2133 switch (property_id) {
2134 case UIA_AriaPropertiesPropertyId:
2136 result->bstrVal = ::SysAllocString(
2138 break;
2139
2140 case UIA_AriaRolePropertyId:
2144 break;
2145
2146 case UIA_AutomationIdPropertyId:
2148 V_BSTR(
result) = ::SysAllocString(
2150 break;
2151
2152 case UIA_ClassNamePropertyId:
2156 break;
2157
2158 case UIA_ClickablePointPropertyId:
2159 result->vt = VT_ARRAY | VT_R8;
2160 result->parray = CreateClickablePointArray();
2161 break;
2162
2163 case UIA_ControllerForPropertyId:
2164 result->vt = VT_ARRAY | VT_UNKNOWN;
2165 result->parray = CreateUIAControllerForArray();
2166 break;
2167
2168 case UIA_ControlTypePropertyId:
2170 result->lVal = ComputeUIAControlType();
2171 break;
2172
2173 case UIA_CulturePropertyId: {
2174 std::optional<LCID> lcid = GetCultureAttributeAsLCID();
2175 if (!lcid)
2176 return E_FAIL;
2178 result->lVal = lcid.value();
2179 break;
2180 }
2181
2182 case UIA_DescribedByPropertyId:
2183 result->vt = VT_ARRAY | VT_UNKNOWN;
2184 result->parray = CreateUIAElementsArrayForRelation(
2186 break;
2187
2188 case UIA_FlowsFromPropertyId:
2189 V_VT(
result) = VT_ARRAY | VT_UNKNOWN;
2190 V_ARRAY(
result) = CreateUIAElementsArrayForReverseRelation(
2192 break;
2193
2194 case UIA_FlowsToPropertyId:
2195 result->vt = VT_ARRAY | VT_UNKNOWN;
2196 result->parray = CreateUIAElementsArrayForRelation(
2198 break;
2199
2200 case UIA_FrameworkIdPropertyId:
2202 V_BSTR(
result) = SysAllocString(FRAMEWORK_ID);
2203 break;
2204
2205 case UIA_HasKeyboardFocusPropertyId:
2207 result->boolVal = (
delegate_->GetFocus() == GetNativeViewAccessible())
2208 ? VARIANT_TRUE
2209 : VARIANT_FALSE;
2210 break;
2211
2212 case UIA_FullDescriptionPropertyId:
2216 break;
2217
2218 case UIA_HelpTextPropertyId:
2226 GetNameAsBstr(&V_BSTR(
result));
2231 }
2232 break;
2233
2234 case UIA_IsContentElementPropertyId:
2235 case UIA_IsControlElementPropertyId:
2237 result->boolVal = IsUIAControl() ? VARIANT_TRUE : VARIANT_FALSE;
2238 break;
2239
2240 case UIA_IsDataValidForFormPropertyId:
2242 &int_attribute)) {
2246 ? VARIANT_TRUE
2247 : VARIANT_FALSE;
2248 }
2249 break;
2250
2251 case UIA_IsDialogPropertyId:
2254 break;
2255
2256 case UIA_IsKeyboardFocusablePropertyId:
2259 ShouldNodeHaveFocusableState(data) ? VARIANT_TRUE : VARIANT_FALSE;
2260 break;
2261
2262 case UIA_IsOffscreenPropertyId:
2265 GetDelegate()->IsOffscreen() ? VARIANT_TRUE : VARIANT_FALSE;
2266 break;
2267
2268 case UIA_IsRequiredForFormPropertyId:
2271 result->boolVal = VARIANT_TRUE;
2272 } else {
2273 result->boolVal = VARIANT_FALSE;
2274 }
2275 break;
2276
2277 case UIA_ItemStatusPropertyId: {
2278
2279
2280
2281 int32_t sort_direction;
2284 &sort_direction)) {
2288 break;
2291 V_BSTR(
result) = SysAllocString(L
"ascending");
2292 break;
2295 V_BSTR(
result) = SysAllocString(L
"descending");
2296 break;
2299 V_BSTR(
result) = SysAllocString(L
"other");
2300 break;
2301 }
2302 }
2303 break;
2304 }
2305
2306 case UIA_LabeledByPropertyId:
2307 if (AXPlatformNodeWin* node = ComputeUIALabeledBy()) {
2309 result->punkVal = node->GetNativeViewAccessible();
2310 result->punkVal->AddRef();
2311 }
2312 break;
2313
2314 case UIA_LocalizedControlTypePropertyId: {
2315 std::u16string localized_control_type = GetRoleDescription();
2316 if (!localized_control_type.empty()) {
2318 result->bstrVal = ::SysAllocString(
2320 }
2321
2322
2323
2324
2325 } break;
2326
2327 case UIA_NamePropertyId:
2328 if (IsNameExposed()) {
2330 GetNameAsBstr(&
result->bstrVal);
2331 }
2332 break;
2333
2334 case UIA_OrientationPropertyId:
2339
2340
2341 }
2344 result->intVal = OrientationType_Horizontal;
2345 }
2348 result->intVal = OrientationType_Vertical;
2349 }
2350 } else {
2352 result->intVal = OrientationType_None;
2353 }
2354 break;
2355
2356 case UIA_IsEnabledPropertyId:
2358 switch (
data.GetRestriction()) {
2360 V_BOOL(
result) = VARIANT_FALSE;
2361 break;
2362
2365 V_BOOL(
result) = VARIANT_TRUE;
2366 break;
2367 }
2368 break;
2369
2370 case UIA_IsPasswordPropertyId:
2373 ? VARIANT_TRUE
2374 : VARIANT_FALSE;
2375 break;
2376
2377 case UIA_AcceleratorKeyPropertyId:
2382 }
2383 break;
2384
2385 case UIA_AccessKeyPropertyId:
2390 }
2391 break;
2392
2393 case UIA_IsPeripheralPropertyId:
2395 result->boolVal = VARIANT_FALSE;
2396 break;
2397
2398 case UIA_LevelPropertyId:
2400 &int_attribute)) {
2402 result->intVal = int_attribute;
2403 }
2404 break;
2405
2406 case UIA_LiveSettingPropertyId: {
2408 result->intVal = LiveSetting::Off;
2409
2410 std::string string_attribute;
2412 &string_attribute)) {
2413 if (string_attribute == "polite")
2414 result->intVal = LiveSetting::Polite;
2415 else if (string_attribute == "assertive")
2416 result->intVal = LiveSetting::Assertive;
2417 }
2418 break;
2419 }
2420
2421 case UIA_OptimizeForVisualContentPropertyId:
2423 result->boolVal = VARIANT_FALSE;
2424 break;
2425
2426 case UIA_PositionInSetPropertyId: {
2427 std::optional<int> pos_in_set = GetPosInSet();
2428 if (pos_in_set) {
2430 result->intVal = *pos_in_set;
2431 }
2432 } break;
2433
2434 case UIA_ScrollHorizontalScrollPercentPropertyId: {
2436 V_R8(
result) = GetHorizontalScrollPercent();
2437 break;
2438 }
2439
2440 case UIA_ScrollVerticalScrollPercentPropertyId: {
2442 V_R8(
result) = GetVerticalScrollPercent();
2443 break;
2444 }
2445
2446 case UIA_SizeOfSetPropertyId: {
2447 std::optional<int> set_size = GetSetSize();
2448 if (set_size) {
2450 result->intVal = *set_size;
2451 }
2452 break;
2453 }
2454
2455 case UIA_LandmarkTypePropertyId: {
2456 std::optional<LONG> landmark_type = ComputeUIALandmarkType();
2457 if (landmark_type) {
2459 result->intVal = landmark_type.value();
2460 }
2461 break;
2462 }
2463
2464 case UIA_LocalizedLandmarkTypePropertyId: {
2465 std::u16string localized_landmark_type =
2466 GetDelegate()->GetLocalizedStringForLandmarkType();
2467 if (!localized_landmark_type.empty()) {
2469 result->bstrVal = ::SysAllocString(
2471 }
2472 break;
2473 }
2474
2475 case UIA_ExpandCollapseExpandCollapseStatePropertyId:
2477 result->intVal =
static_cast<int>(ComputeExpandCollapseState());
2478 break;
2479
2480 case UIA_ToggleToggleStatePropertyId: {
2482 get_ToggleState(&
state);
2485 break;
2486 }
2487
2488 case UIA_ValueValuePropertyId:
2490 result->bstrVal = GetValueAttributeAsBstr(
this);
2491 break;
2492
2493
2494 case UIA_AnnotationObjectsPropertyId:
2495 case UIA_AnnotationTypesPropertyId:
2496 case UIA_CenterPointPropertyId:
2497 case UIA_FillColorPropertyId:
2498 case UIA_FillTypePropertyId:
2499 case UIA_HeadingLevelPropertyId:
2500 case UIA_ItemTypePropertyId:
2501 case UIA_OutlineColorPropertyId:
2502 case UIA_OutlineThicknessPropertyId:
2503 case UIA_RotationPropertyId:
2504 case UIA_SizePropertyId:
2505 case UIA_VisualEffectsPropertyId:
2506 break;
2507
2508
2509 case UIA_BoundingRectanglePropertyId:
2510 case UIA_NativeWindowHandlePropertyId:
2511 case UIA_ProcessIdPropertyId:
2512 case UIA_ProviderDescriptionPropertyId:
2513 case UIA_RuntimeIdPropertyId:
2514 break;
2515 }
2516
2517
2518 if (property_id ==
2520
2521
2522
2523
2524
2525
2526
2528 result->bstrVal = ::SysAllocString(
2530 }
2531
2532 return S_OK;
2533}
2534
2535IFACEMETHODIMP AXPlatformNodeWin::get_ProviderOptions(ProviderOptions* ret) {
2537
2538 *ret = ProviderOptions_ServerSideProvider | ProviderOptions_UseComThreading |
2539 ProviderOptions_RefuseNonClientSupport |
2540 ProviderOptions_HasNativeIAccessible;
2541 return S_OK;
2542}
2543
2544IFACEMETHODIMP AXPlatformNodeWin::get_HostRawElementProvider(
2545 IRawElementProviderSimple** provider) {
2547
2548 *provider = nullptr;
2549 return S_OK;
2550}
2551
2552
2553
2554
2555
2556IFACEMETHODIMP AXPlatformNodeWin::ShowContextMenu() {
2558
2559 AXActionData action_data;
2561 delegate_->AccessibilityPerformAction(action_data);
2562 return S_OK;
2563}
2564
2565
2566
2567
2568
2569IFACEMETHODIMP AXPlatformNodeWin::QueryService(
REFGUID guidService,
2570 REFIID riid,
2571 void** object) {
2573
2574 if (guidService == IID_IAccessible) {
2575 return QueryInterface(riid, object);
2576 }
2577
2578
2579
2580
2581 *object = nullptr;
2582 return E_FAIL;
2583}
2584
2585
2586
2587
2588
2589
2590STDMETHODIMP AXPlatformNodeWin::InternalQueryInterface(
2591 void* this_ptr,
2592 const _ATL_INTMAP_ENTRY* entries,
2593 REFIID riid,
2594 void** object) {
2595 if (!object)
2596 return E_INVALIDARG;
2597 *object = nullptr;
2598 AXPlatformNodeWin* accessible =
2599 reinterpret_cast<AXPlatformNodeWin*>(this_ptr);
2601
2602 return CComObjectRootBase::InternalQueryInterface(this_ptr, entries, riid,
2603 object);
2604}
2605
2606HRESULT AXPlatformNodeWin::GetTextAttributeValue(
2607 TEXTATTRIBUTEID attribute_id,
2608 const std::optional<int>& start_offset,
2609 const std::optional<int>& end_offset,
2611 BASE_DCHECK(!start_offset || start_offset.value() >= 0);
2612 BASE_DCHECK(!end_offset || end_offset.value() >= 0);
2613
2614 switch (attribute_id) {
2615 case UIA_AnnotationTypesAttributeId:
2616 return GetAnnotationTypesAttribute(start_offset, end_offset,
result);
2617 case UIA_BackgroundColorAttributeId:
2620 break;
2621 case UIA_BulletStyleAttributeId:
2622 result->Insert<VT_I4>(ComputeUIABulletStyle());
2623 break;
2624 case UIA_CultureAttributeId: {
2625 std::optional<LCID> lcid = GetCultureAttributeAsLCID();
2626 if (!lcid)
2627 return E_FAIL;
2628 result->Insert<VT_I4>(lcid.value());
2629 break;
2630 }
2631 case UIA_FontNameAttributeId:
2632 result->Insert<VT_BSTR>(GetFontNameAttributeAsBSTR());
2633 break;
2634 case UIA_FontSizeAttributeId: {
2635 std::optional<float> font_size_in_points = GetFontSizeInPoints();
2636 if (font_size_in_points) {
2637 result->Insert<VT_R8>(*font_size_in_points);
2638 }
2639 break;
2640 }
2641 case UIA_FontWeightAttributeId:
2644 break;
2645 case UIA_ForegroundColorAttributeId:
2648 break;
2649 case UIA_IsHiddenAttributeId:
2650 result->Insert<VT_BOOL>(IsInvisibleOrIgnored());
2651 break;
2652 case UIA_IsItalicAttributeId:
2655 break;
2656 case UIA_IsReadOnlyAttributeId:
2657
2658 if (IsPlaceholderText()) {
2659 AXPlatformNodeWin* parent_platform_node =
2660 static_cast<AXPlatformNodeWin*>(
2661 FromNativeViewAccessible(GetParent()));
2662 return parent_platform_node->GetTextAttributeValue(
2663 attribute_id, start_offset, end_offset,
result);
2664 }
2665 result->Insert<VT_BOOL>(GetData().IsReadOnlyOrDisabled());
2666 break;
2667 case UIA_IsSubscriptAttributeId:
2668 result->Insert<VT_BOOL>(GetData().GetTextPosition() ==
2670 break;
2671 case UIA_IsSuperscriptAttributeId:
2672 result->Insert<VT_BOOL>(GetData().GetTextPosition() ==
2674 break;
2675 case UIA_OverlineStyleAttributeId:
2676 result->Insert<VT_I4>(GetUIATextDecorationStyle(
2678 break;
2679 case UIA_StrikethroughStyleAttributeId:
2680 result->Insert<VT_I4>(GetUIATextDecorationStyle(
2682 break;
2683 case UIA_StyleNameAttributeId:
2684 result->Insert<VT_BSTR>(GetStyleNameAttributeAsBSTR());
2685 break;
2686 case UIA_StyleIdAttributeId:
2687 result->Insert<VT_I4>(ComputeUIAStyleId());
2688 break;
2689 case UIA_HorizontalTextAlignmentAttributeId: {
2690 std::optional<HorizontalTextAlignment> horizontal_text_alignment =
2691 AXTextAlignToUIAHorizontalTextAlignment(GetData().GetTextAlign());
2692 if (horizontal_text_alignment)
2693 result->Insert<VT_I4>(*horizontal_text_alignment);
2694 break;
2695 }
2696 case UIA_UnderlineStyleAttributeId:
2697 result->Insert<VT_I4>(GetUIATextDecorationStyle(
2699 break;
2700 case UIA_TextFlowDirectionsAttributeId:
2702 TextDirectionToFlowDirections(GetData().GetTextDirection()));
2703 break;
2704 default: {
2705 Microsoft::WRL::ComPtr<IUnknown> not_supported_value;
2706 HRESULT hr = ::UiaGetReservedNotSupportedValue(¬_supported_value);
2708 result->Insert<VT_UNKNOWN>(not_supported_value.Get());
2709 return hr;
2710 } break;
2711 }
2712
2713 return S_OK;
2714}
2715
2716HRESULT AXPlatformNodeWin::GetAnnotationTypesAttribute(
2717 const std::optional<int>& start_offset,
2718 const std::optional<int>& end_offset,
2721
2722 MarkerTypeRangeResult grammar_result = MarkerTypeRangeResult::kNone;
2723 MarkerTypeRangeResult spelling_result = MarkerTypeRangeResult::kNone;
2724
2725 if (
IsText() || IsPlainTextField()) {
2726 grammar_result = GetMarkerTypeFromRange(start_offset, end_offset,
2728 spelling_result = GetMarkerTypeFromRange(start_offset, end_offset,
2730 }
2731
2732 if (grammar_result == MarkerTypeRangeResult::kMixed ||
2733 spelling_result == MarkerTypeRangeResult::kMixed) {
2734 Microsoft::WRL::ComPtr<IUnknown> mixed_attribute_value;
2735 HRESULT hr = ::UiaGetReservedMixedAttributeValue(&mixed_attribute_value);
2737 result->Insert<VT_UNKNOWN>(mixed_attribute_value.Get());
2738 return hr;
2739 }
2740
2741 if (spelling_result == MarkerTypeRangeResult::kMatch)
2742 result->Insert<VT_I4>(AnnotationType_SpellingError);
2743 if (grammar_result == MarkerTypeRangeResult::kMatch)
2744 result->Insert<VT_I4>(AnnotationType_GrammarError);
2745
2746 return S_OK;
2747}
2748
2749std::optional<LCID> AXPlatformNodeWin::GetCultureAttributeAsLCID() const {
2750 const std::u16string language =
2752 const LCID lcid =
2753 LocaleNameToLCID((wchar_t*)language.c_str(), LOCALE_ALLOW_NEUTRAL_NAMES);
2754 if (!lcid)
2755 return std::nullopt;
2756
2757 return lcid;
2758}
2759
2760COLORREF AXPlatformNodeWin::GetIntAttributeAsCOLORREF(
2762 uint32_t
color = GetIntAttribute(attribute);
2763
2764 return (_byteswap_ulong(
color) >> 8);
2765}
2766
2767BulletStyle AXPlatformNodeWin::ComputeUIABulletStyle() const {
2768
2769
2770
2771
2772 const AXPlatformNodeBase* current_node = this;
2773 while (current_node &&
2775 current_node = FromNativeViewAccessible(current_node->GetParent());
2776 }
2777
2779 current_node ? current_node->GetData().GetListStyle()
2781
2782 switch (list_style) {
2784 return BulletStyle::BulletStyle_None;
2786 return BulletStyle::BulletStyle_HollowRoundBullet;
2788 return BulletStyle::BulletStyle_FilledRoundBullet;
2790 return BulletStyle::BulletStyle_Other;
2793 return BulletStyle::BulletStyle_None;
2795 return BulletStyle::BulletStyle_FilledSquareBullet;
2796 }
2797}
2798
2799LONG AXPlatformNodeWin::ComputeUIAStyleId()
const {
2800 const AXPlatformNodeBase* current_node = this;
2801 do {
2802 switch (current_node->GetData().role) {
2804 return AXHierarchicalLevelToUIAStyleId(current_node->GetIntAttribute(
2807 return AXListStyleToUIAStyleId(current_node->GetData().GetListStyle());
2809 return StyleId_Custom;
2811 return StyleId_Quote;
2812 default:
2813 break;
2814 }
2815 current_node = FromNativeViewAccessible(current_node->GetParent());
2816 } while (current_node);
2817
2818 return StyleId_Normal;
2819}
2820
2821
2822std::optional<HorizontalTextAlignment>
2823AXPlatformNodeWin::AXTextAlignToUIAHorizontalTextAlignment(
2825 switch (text_align) {
2827 return std::nullopt;
2829 return HorizontalTextAlignment_Left;
2831 return HorizontalTextAlignment_Right;
2833 return HorizontalTextAlignment_Centered;
2835 return HorizontalTextAlignment_Justified;
2836 }
2837}
2838
2839
2840LONG AXPlatformNodeWin::AXHierarchicalLevelToUIAStyleId(
2841 int32_t hierarchical_level) {
2842 switch (hierarchical_level) {
2843 case 0:
2844 return StyleId_Normal;
2845 case 1:
2846 return StyleId_Heading1;
2847 case 2:
2848 return StyleId_Heading2;
2849 case 3:
2850 return StyleId_Heading3;
2851 case 4:
2852 return StyleId_Heading4;
2853 case 5:
2854 return StyleId_Heading5;
2855 case 6:
2856 return StyleId_Heading6;
2857 case 7:
2858 return StyleId_Heading7;
2859 case 8:
2860 return StyleId_Heading8;
2861 case 9:
2862 return StyleId_Heading9;
2863 default:
2864 return StyleId_Custom;
2865 }
2866}
2867
2868
2869LONG AXPlatformNodeWin::AXListStyleToUIAStyleId(
2871 switch (list_style) {
2873 return StyleId_Normal;
2878 return StyleId_BulletedList;
2881 return StyleId_NumberedList;
2882 }
2883}
2884
2885
2886FlowDirections AXPlatformNodeWin::TextDirectionToFlowDirections(
2888 switch (text_direction) {
2890 return FlowDirections::FlowDirections_Default;
2892 return FlowDirections::FlowDirections_Default;
2894 return FlowDirections::FlowDirections_RightToLeft;
2896 return FlowDirections::FlowDirections_Vertical;
2898 return FlowDirections::FlowDirections_BottomToTop;
2899 }
2900}
2901
2902
2903void AXPlatformNodeWin::AggregateRangesForMarkerType(
2904 AXPlatformNodeBase* node,
2906 int offset_ranges_amount,
2907 std::vector<std::pair<int, int>>* ranges) {
2909 const std::vector<int32_t>& marker_types =
2911 const std::vector<int>& marker_starts =
2913 const std::vector<int>& marker_ends =
2915
2916 for (size_t i = 0; i < marker_types.size(); ++i) {
2918 continue;
2919
2920 const int marker_start = marker_starts[i] + offset_ranges_amount;
2921 const int marker_end = marker_ends[i] + offset_ranges_amount;
2922 ranges->emplace_back(std::make_pair(marker_start, marker_end));
2923 }
2924}
2925
2926AXPlatformNodeWin::MarkerTypeRangeResult
2927AXPlatformNodeWin::GetMarkerTypeFromRange(
2928 const std::optional<int>& start_offset,
2929 const std::optional<int>& end_offset,
2932 std::vector<std::pair<int, int>> relevant_ranges;
2933
2935 AggregateRangesForMarkerType(this, marker_type, 0,
2936 &relevant_ranges);
2937 } else if (IsPlainTextField()) {
2938 int offset_ranges_amount = 0;
2939 for (AXPlatformNodeBase* static_text = GetFirstTextOnlyDescendant();
2940 static_text; static_text = static_text->GetNextSibling()) {
2941 const int child_offset_ranges_amount = offset_ranges_amount;
2942 if (start_offset || end_offset) {
2943
2944 if (end_offset && child_offset_ranges_amount > end_offset.value())
2945 break;
2946
2947
2948 offset_ranges_amount += static_text->GetHypertext().length();
2949 if (start_offset && offset_ranges_amount < start_offset.value())
2950 continue;
2951 }
2952
2953 AggregateRangesForMarkerType(static_text, marker_type,
2954 child_offset_ranges_amount,
2955 &relevant_ranges);
2956 }
2957 }
2958
2959
2960 const auto sort_ranges_by_start_offset = [](
const std::pair<int, int>&
a,
2961 const std::pair<int, int>&
b) {
2962 return a.first <
b.first;
2963 };
2964 std::sort(relevant_ranges.begin(), relevant_ranges.end(),
2965 sort_ranges_by_start_offset);
2966
2967
2968 std::optional<std::pair<int, int>> contiguous_range;
2969 for (const std::pair<int, int>& range : relevant_ranges) {
2970 if (end_offset && range.first > end_offset.value())
2971 break;
2972 if (start_offset && range.second < start_offset.value())
2973 continue;
2974
2975 if (!contiguous_range) {
2976 contiguous_range = range;
2977 continue;
2978 }
2979
2980
2981 if ((range.first - contiguous_range->second) > 1)
2982 return MarkerTypeRangeResult::kMixed;
2983
2984
2985 contiguous_range->second = std::max(contiguous_range->second, range.second);
2986 }
2987
2988
2989 if (!contiguous_range)
2990 return MarkerTypeRangeResult::kNone;
2991
2992
2993
2994 if (!start_offset && contiguous_range->first > 0)
2995 return MarkerTypeRangeResult::kMixed;
2996
2997 if (!end_offset && contiguous_range->second < GetHypertext().
length())
2998 return MarkerTypeRangeResult::kMixed;
2999
3000 if (start_offset && start_offset.value() < contiguous_range->first)
3001 return MarkerTypeRangeResult::kMixed;
3002
3003 if (end_offset && end_offset.value() > contiguous_range->second)
3004 return MarkerTypeRangeResult::kMixed;
3005
3006
3007 return MarkerTypeRangeResult::kMatch;
3008}
3009
3010
3011
3012bool AXPlatformNodeWin::IsPatternProviderSupported(PATTERNID pattern_id) {
3013 return GetPatternProviderFactoryMethod(pattern_id);
3014}
3015
3016
3017
3018
3019int AXPlatformNodeWin::MSAARole() {
3020
3021
3022
3023 if (IsWebAreaForPresentationalIframe())
3024 return ROLE_SYSTEM_GROUPING;
3025
3026 switch (GetData().role) {
3028 return ROLE_SYSTEM_ALERT;
3029
3031 return ROLE_SYSTEM_DIALOG;
3032
3034 return ROLE_SYSTEM_LINK;
3035
3038 return ROLE_SYSTEM_GROUPING;
3039
3041 return ROLE_SYSTEM_APPLICATION;
3042
3044 return ROLE_SYSTEM_DOCUMENT;
3045
3047 return ROLE_SYSTEM_GROUPING;
3048
3051 return ROLE_SYSTEM_GROUPING;
3052
3054 return ROLE_SYSTEM_GROUPING;
3055
3057 return ROLE_SYSTEM_PUSHBUTTON;
3058
3060 return ROLE_SYSTEM_GRAPHIC;
3061
3063 return ROLE_SYSTEM_TEXT;
3064
3066 return ROLE_SYSTEM_CARET;
3067
3069 return ROLE_SYSTEM_CELL;
3070
3072 return ROLE_SYSTEM_CHECKBUTTON;
3073
3075 return ROLE_SYSTEM_PANE;
3076
3078 return ROLE_SYSTEM_TEXT;
3079
3081 return ROLE_SYSTEM_COLUMN;
3082
3084 return ROLE_SYSTEM_COLUMNHEADER;
3085
3088 return ROLE_SYSTEM_COMBOBOX;
3089
3091 return ROLE_SYSTEM_GROUPING;
3092
3095 return ROLE_SYSTEM_GROUPING;
3096
3099 return ROLE_SYSTEM_GROUPING;
3100
3103 return ROLE_SYSTEM_DROPLIST;
3104
3106 return ROLE_SYSTEM_GROUPING;
3107
3109 return ROLE_SYSTEM_TEXT;
3110
3112 return ROLE_SYSTEM_LIST;
3113
3115 return ROLE_SYSTEM_LISTITEM;
3116
3118 return ROLE_SYSTEM_PANE;
3119
3121 return ROLE_SYSTEM_GROUPING;
3122
3124 return ROLE_SYSTEM_DIALOG;
3125
3127 return ROLE_SYSTEM_PUSHBUTTON;
3128
3130 return ROLE_SYSTEM_LIST;
3131
3133 return ROLE_SYSTEM_GRAPHIC;
3134
3139 return ROLE_SYSTEM_LINK;
3140
3144 return ROLE_SYSTEM_LISTITEM;
3145
3147 return ROLE_SYSTEM_SEPARATOR;
3148
3179 return ROLE_SYSTEM_GROUPING;
3180
3184 return ROLE_SYSTEM_DOCUMENT;
3185
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196 if (GetDelegate()->GetChildCount()) {
3197 return ROLE_SYSTEM_GROUPING;
3198 } else {
3199 return ROLE_SYSTEM_CLIENT;
3200 }
3201
3203 return ROLE_SYSTEM_GROUPING;
3204
3206 return ROLE_SYSTEM_GROUPING;
3207
3209 return ROLE_SYSTEM_GROUPING;
3210
3213 return ROLE_SYSTEM_GROUPING;
3214
3216 return ROLE_SYSTEM_GROUPING;
3217
3219 return ROLE_SYSTEM_GROUPING;
3220
3222 return ROLE_SYSTEM_DOCUMENT;
3223
3225 return ROLE_SYSTEM_PANE;
3226
3228 return ROLE_SYSTEM_GRAPHIC;
3229
3231 return ROLE_SYSTEM_TABLE;
3232
3234 return ROLE_SYSTEM_GROUPING;
3235
3237 return ROLE_SYSTEM_GROUPING;
3238
3240 return ROLE_SYSTEM_DOCUMENT;
3241
3243 return ROLE_SYSTEM_GROUPING;
3244
3247 return ROLE_SYSTEM_GRAPHIC;
3248
3250 return ROLE_SYSTEM_GROUPING;
3251
3253 return ROLE_SYSTEM_STATICTEXT;
3254
3257 return ROLE_SYSTEM_TEXT;
3258
3260 return ROLE_SYSTEM_TABLE;
3261
3263 return ROLE_SYSTEM_CELL;
3264
3266 return ROLE_SYSTEM_ROW;
3267
3269 return ROLE_SYSTEM_LINK;
3270
3272 return ROLE_SYSTEM_LIST;
3273
3275 return ROLE_SYSTEM_LIST;
3276
3278 return ROLE_SYSTEM_LISTITEM;
3279
3281 return ROLE_SYSTEM_LIST;
3282
3284 return ROLE_SYSTEM_LISTITEM;
3285
3287 if (!GetDelegate()->GetChildCount()) {
3288
3289
3290
3291
3292 return ROLE_SYSTEM_STATICTEXT;
3293 }
3294 return ROLE_SYSTEM_GROUPING;
3295
3297 return ROLE_SYSTEM_GROUPING;
3298
3300 return ROLE_SYSTEM_GROUPING;
3301
3303 return ROLE_SYSTEM_GROUPING;
3304
3306 return ROLE_SYSTEM_ANIMATION;
3307
3309 return ROLE_SYSTEM_EQUATION;
3310
3312 return ROLE_SYSTEM_MENUPOPUP;
3313
3315 return ROLE_SYSTEM_MENUBAR;
3316
3320 return ROLE_SYSTEM_MENUITEM;
3321
3323 return ROLE_SYSTEM_LIST;
3324
3326 return ROLE_SYSTEM_LISTITEM;
3327
3329 return ROLE_SYSTEM_PROGRESSBAR;
3330
3332 return ROLE_SYSTEM_GROUPING;
3333
3335 return ROLE_SYSTEM_GROUPING;
3336
3338 return ROLE_SYSTEM_GROUPING;
3339
3341 return ROLE_SYSTEM_PUSHBUTTON;
3342
3344
3345 if (GetDelegate()->GetChildCount()) {
3346 return ROLE_SYSTEM_GROUPING;
3347 } else {
3348 return ROLE_SYSTEM_CLIENT;
3349 }
3350
3352 std::string html_tag =
3354 if (html_tag == "select")
3355 return ROLE_SYSTEM_COMBOBOX;
3356 return ROLE_SYSTEM_BUTTONMENU;
3357 }
3358
3360 return ROLE_SYSTEM_PUSHBUTTON;
3361
3363 return ROLE_SYSTEM_TEXT;
3364
3366 return ROLE_SYSTEM_PROGRESSBAR;
3367
3369 return ROLE_SYSTEM_RADIOBUTTON;
3370
3372 return ROLE_SYSTEM_GROUPING;
3373
3375 return ROLE_SYSTEM_PANE;
3376
3378
3379
3380 return IsInTreeGrid() ? ROLE_SYSTEM_OUTLINEITEM : ROLE_SYSTEM_ROW;
3381 }
3382
3384 return ROLE_SYSTEM_GROUPING;
3385
3387 return ROLE_SYSTEM_ROWHEADER;
3388
3390 return ROLE_SYSTEM_TEXT;
3391
3393 if (GetNameAsString16().
empty()) {
3394
3395 return ROLE_SYSTEM_GROUPING;
3396 }
3397
3398 return ROLE_SYSTEM_PANE;
3399 }
3400
3402 return ROLE_SYSTEM_SCROLLBAR;
3403
3405 return ROLE_SYSTEM_PANE;
3406
3408 return ROLE_SYSTEM_GROUPING;
3409
3411 return ROLE_SYSTEM_SLIDER;
3412
3414 return ROLE_SYSTEM_SLIDER;
3415
3417 return ROLE_SYSTEM_SPINBUTTON;
3418
3420 return ROLE_SYSTEM_CHECKBUTTON;
3421
3424 return ROLE_SYSTEM_STATICTEXT;
3425
3427 return ROLE_SYSTEM_STATUSBAR;
3428
3430 return ROLE_SYSTEM_SEPARATOR;
3431
3433 return ROLE_SYSTEM_GRAPHIC;
3434
3436 return ROLE_SYSTEM_PAGETAB;
3437
3439 return ROLE_SYSTEM_TABLE;
3440
3442 return ROLE_SYSTEM_GROUPING;
3443
3445 return ROLE_SYSTEM_PAGETABLIST;
3446
3448 return ROLE_SYSTEM_PROPERTYPAGE;
3449
3451 return ROLE_SYSTEM_LISTITEM;
3452
3454 return ROLE_SYSTEM_TITLEBAR;
3455
3457 return ROLE_SYSTEM_CHECKBUTTON;
3458
3461 return ROLE_SYSTEM_TEXT;
3462
3464 return ROLE_SYSTEM_COMBOBOX;
3465
3471 return ROLE_SYSTEM_TEXT;
3472
3474 return ROLE_SYSTEM_CLOCK;
3475
3477 return ROLE_SYSTEM_TOOLBAR;
3478
3480 return ROLE_SYSTEM_TOOLTIP;
3481
3483 return ROLE_SYSTEM_OUTLINE;
3484
3486 return ROLE_SYSTEM_OUTLINE;
3487
3489 return ROLE_SYSTEM_OUTLINEITEM;
3490
3492 return ROLE_SYSTEM_WHITESPACE;
3493
3495 return ROLE_SYSTEM_GROUPING;
3496
3498 return ROLE_SYSTEM_CLIENT;
3499
3502
3503
3504
3505
3506 return ROLE_SYSTEM_PANE;
3507
3514 return ROLE_SYSTEM_PANE;
3515 }
3516
3518 return ROLE_SYSTEM_GROUPING;
3519}
3520
3521bool AXPlatformNodeWin::IsWebAreaForPresentationalIframe() {
3524 return false;
3525 }
3526
3527 AXPlatformNodeBase* parent = FromNativeViewAccessible(GetParent());
3528 if (!parent)
3529 return false;
3530
3532}
3533
3534std::u16string AXPlatformNodeWin::UIAAriaRole() {
3535
3536
3537
3538 if (IsWebAreaForPresentationalIframe())
3539 return u"group";
3540
3541 switch (GetData().role) {
3543 return u"alert";
3544
3546
3547
3548
3549
3550 return u"alert";
3551
3553 return u"link";
3554
3557 return u"group";
3558
3560 return u"application";
3561
3563 return u"article";
3564
3566 return u"group";
3567
3570 return u"banner";
3571
3573 return u"group";
3574
3576 return u"button";
3577
3579 return u"img";
3580
3582 return u"description";
3583
3585 return u"region";
3586
3588 return u"gridcell";
3589
3591 return u"code";
3592
3594 return u"checkbox";
3595
3597 return u"region";
3598
3600 return u"textbox";
3601
3603 return u"region";
3604
3606 return u"columnheader";
3607
3610 return u"combobox";
3611
3613 return u"complementary";
3614
3617 return u"group";
3618
3621 return u"contentinfo";
3622
3625 return u"textbox";
3626
3628 return u"definition";
3629
3631 return u"description";
3632
3634 return u"list";
3635
3637 return u"listitem";
3638
3640 return u"document";
3641
3643 return u"group";
3644
3646 return u"dialog";
3647
3649 return u"button";
3650
3652 return u"directory";
3653
3655 return u"img";
3656
3661 return u"link";
3662
3666 return u"listitem";
3667
3669 return u"separator";
3670
3701 return u"group";
3702
3706 return u"document";
3707
3709 if (GetDelegate()->GetChildCount()) {
3710 return u"group";
3711 } else {
3712 return u"document";
3713 }
3714
3716 return u"emphasis";
3717
3719 return u"group";
3720
3722 return u"description";
3723
3725 return u"group";
3726
3729 return u"group";
3730
3732 return u"form";
3733
3735 return u"group";
3736
3738 return u"document";
3739
3741 return u"region";
3742
3744 return u"img";
3745
3747 return u"grid";
3748
3750 return u"group";
3751
3753 return u"heading";
3754
3756 return u"document";
3757
3759 return u"group";
3760
3762 return u"img";
3763
3765 return u"document";
3766
3768
3769 return u"group";
3770
3772 return u"group";
3773
3775 return u"textbox";
3776
3778 return u"group";
3779
3782 return u"description";
3783
3785 return u"grid";
3786
3788 return u"gridcell";
3789
3791 return u"row";
3792
3794 return u"link";
3795
3797 return u"list";
3798
3800 return u"listbox";
3801
3803 return u"option";
3804
3806 return u"listview";
3807
3809 return u"listitem";
3810
3812 if (!GetDelegate()->GetChildCount()) {
3813
3814
3815
3816
3817 return u"description";
3818 }
3819 return u"group";
3820
3822 return u"log";
3823
3825 return u"main";
3826
3828 return u"description";
3829
3831 return u"marquee";
3832
3834 return u"group";
3835
3837 return u"menu";
3838
3840 return u"menubar";
3841
3843 return u"menuitem";
3844
3846 return u"menuitemcheckbox";
3847
3849 return u"menuitemradio";
3850
3852 return u"list";
3853
3855 return u"listitem";
3856
3858 return u"progressbar";
3859
3861 return u"navigation";
3862
3864 return u"note";
3865
3867 return u"group";
3868
3870 return u"button";
3871
3873 if (GetDelegate()->GetChildCount()) {
3874 return u"group";
3875 } else {
3876 return u"document";
3877 }
3878
3880 std::string html_tag =
3882 if (html_tag == "select")
3883 return u"combobox";
3884 return u"button";
3885 }
3886
3888 return u"button";
3889
3891 return u"region";
3892
3894 return u"progressbar";
3895
3897 return u"radio";
3898
3900 return u"radiogroup";
3901
3903 return u"region";
3904
3906
3907
3908 return IsInTreeGrid() ? u"treeitem" : u"row";
3909 }
3910
3912 return u"rowgroup";
3913
3915 return u"rowheader";
3916
3918 return u"region";
3919
3921 if (GetNameAsString16().
empty()) {
3922
3923 return u"group";
3924 }
3925
3926 return u"region";
3927 }
3928
3930 return u"scrollbar";
3931
3933 return u"region";
3934
3936 return u"search";
3937
3939 return u"slider";
3940
3942 return u"slider";
3943
3945 return u"spinbutton";
3946
3948 return u"strong";
3949
3951 return u"switch";
3952
3955 return u"description";
3956
3958 return u"status";
3959
3961 return u"separator";
3962
3964 return u"img";
3965
3967 return u"tab";
3968
3970 return u"grid";
3971
3973 return u"group";
3974
3976 return u"tablist";
3977
3979 return u"tabpanel";
3980
3982 return u"listitem";
3983
3985 return u"document";
3986
3988 return u"button";
3989
3991 return u"textbox";
3992
3994 return u"searchbox";
3995
3997 return u"combobox";
3998
4000 return u"description";
4001
4003 return u"time";
4004
4006 return u"timer";
4007
4009 return u"toolbar";
4010
4012 return u"tooltip";
4013
4015 return u"tree";
4016
4018 return u"treegrid";
4019
4021 return u"treeitem";
4022
4024 return u"separator";
4025
4027 return u"group";
4028
4030 return u"document";
4031
4038 return u"region";
4039 }
4040
4042 return u"document";
4043}
4044
4045std::u16string AXPlatformNodeWin::ComputeUIAProperties() {
4046 std::vector<std::u16string> properties;
4047 const AXNodeData&
data = GetData();
4048
4049 BoolAttributeToUIAAriaProperty(
4052 "busy");
4053
4054 switch (
data.GetCheckedState()) {
4056 break;
4059 properties.emplace_back(u"pressed=false");
4061
4062
4063
4064 properties.emplace_back(u"pressed=false");
4065 properties.emplace_back(u"checked=false");
4066 } else {
4067 properties.emplace_back(u"checked=false");
4068 }
4069 break;
4072 properties.emplace_back(u"pressed=true");
4074
4075
4076
4077 properties.emplace_back(u"pressed=true");
4078 properties.emplace_back(u"checked=true");
4079 } else {
4080 properties.emplace_back(u"checked=true");
4081 }
4082 break;
4085 properties.emplace_back(u"pressed=mixed");
4087
4089 } else {
4090 properties.emplace_back(u"checked=mixed");
4091 }
4092 break;
4093 }
4094
4098 properties.push_back(u"disabled=true");
4099 } else {
4100
4101
4102
4103
4104 if (GetData().IsReadOnlyOrDisabled())
4105 properties.push_back(u"readonly=true");
4106 }
4107
4108
4110 properties.push_back(u"dropeffect=" +
4112 }
4115 "grabbed");
4116
4120 break;
4122 properties.push_back(u"haspopup=true");
4123 break;
4125 properties.push_back(u"haspopup=menu");
4126 break;
4128 properties.push_back(u"haspopup=listbox");
4129 break;
4131 properties.push_back(u"haspopup=tree");
4132 break;
4134 properties.push_back(u"haspopup=grid");
4135 break;
4137 properties.push_back(u"haspopup=dialog");
4138 break;
4139 }
4140
4141 if (IsInvisibleOrIgnored())
4142 properties.push_back(u"hidden=true");
4143
4147 properties.push_back(u"invalid=true");
4148 }
4149
4150 IntAttributeToUIAAriaProperty(
4152 StringAttributeToUIAAriaProperty(
4156 "multiselectable");
4158 "posinset");
4159 StringAttributeToUIAAriaProperty(
4162 BoolAttributeToUIAAriaProperty(
4165 "setsize");
4166
4167 int32_t sort_direction;
4170 &sort_direction)) {
4173 break;
4175 properties.push_back(u"sort=none");
4176 break;
4178 properties.push_back(u"sort=ascending");
4179 break;
4181 properties.push_back(u"sort=descending");
4182 break;
4184 properties.push_back(u"sort=other");
4185 break;
4186 }
4187 }
4188
4189 if (
data.IsRangeValueSupported()) {
4190 FloatAttributeToUIAAriaProperty(
4192 FloatAttributeToUIAAriaProperty(
4194 StringAttributeToUIAAriaProperty(
4196
4197 std::u16string value_now = GetRangeValueText();
4198 SanitizeStringAttributeForUIAAriaProperty(value_now, &value_now);
4199 if (!value_now.empty())
4200 properties.push_back(u"valuenow=" + value_now);
4201 }
4202
4205}
4206
4207LONG AXPlatformNodeWin::ComputeUIAControlType() {
4208
4209
4210
4211 if (IsWebAreaForPresentationalIframe())
4212 return UIA_GroupControlTypeId;
4213
4214 switch (GetData().role) {
4216 return UIA_TextControlTypeId;
4217
4219
4220
4221
4222
4223 return UIA_TextControlTypeId;
4224
4226 return UIA_HyperlinkControlTypeId;
4227
4230 return ROLE_SYSTEM_GROUPING;
4231
4233 return UIA_PaneControlTypeId;
4234
4236 return UIA_GroupControlTypeId;
4237
4239 return UIA_GroupControlTypeId;
4240
4243 return UIA_GroupControlTypeId;
4244
4246 return UIA_GroupControlTypeId;
4247
4249 return UIA_ButtonControlTypeId;
4250
4252 return UIA_ImageControlTypeId;
4253
4255 return UIA_TextControlTypeId;
4256
4258 return UIA_PaneControlTypeId;
4259
4261 return UIA_DataItemControlTypeId;
4262
4264 return UIA_CheckBoxControlTypeId;
4265
4267 return UIA_PaneControlTypeId;
4268
4270 return UIA_TextControlTypeId;
4271
4273 return UIA_ButtonControlTypeId;
4274
4276 return UIA_PaneControlTypeId;
4277
4279 return UIA_DataItemControlTypeId;
4280
4283 return UIA_ComboBoxControlTypeId;
4284
4286 return UIA_GroupControlTypeId;
4287
4290 return UIA_GroupControlTypeId;
4291
4294 return UIA_GroupControlTypeId;
4295
4298 return UIA_EditControlTypeId;
4299
4301 return UIA_GroupControlTypeId;
4302
4304 return UIA_TextControlTypeId;
4305
4307 return UIA_ListControlTypeId;
4308
4310 return UIA_ListItemControlTypeId;
4311
4313 return UIA_DocumentControlTypeId;
4314
4316 return UIA_GroupControlTypeId;
4317
4319 return UIA_PaneControlTypeId;
4320
4322 return UIA_ButtonControlTypeId;
4323
4325 return UIA_ListControlTypeId;
4326
4328 return UIA_ImageControlTypeId;
4329
4334 return UIA_HyperlinkControlTypeId;
4335
4339 return UIA_ListItemControlTypeId;
4340
4342 return UIA_SeparatorControlTypeId;
4343
4374 return UIA_GroupControlTypeId;
4375
4379 return UIA_DocumentControlTypeId;
4380
4382 return UIA_PaneControlTypeId;
4383
4385 return UIA_TextControlTypeId;
4386
4388 return UIA_GroupControlTypeId;
4389
4391 return UIA_TextControlTypeId;
4392
4394 return UIA_GroupControlTypeId;
4395
4398 return UIA_GroupControlTypeId;
4399
4401 return UIA_GroupControlTypeId;
4402
4404 return UIA_GroupControlTypeId;
4405
4407 return UIA_DocumentControlTypeId;
4408
4410 return UIA_PaneControlTypeId;
4411
4413 return UIA_ImageControlTypeId;
4414
4416 return UIA_DataGridControlTypeId;
4417
4419 return UIA_GroupControlTypeId;
4420
4422 return UIA_TextControlTypeId;
4423
4425 return UIA_DocumentControlTypeId;
4426
4428 return UIA_GroupControlTypeId;
4429
4431 return UIA_ImageControlTypeId;
4432
4434 return UIA_DocumentControlTypeId;
4435
4437 return UIA_GroupControlTypeId;
4438
4440 return UIA_DocumentControlTypeId;
4441
4444 return UIA_TextControlTypeId;
4445
4447 return UIA_TableControlTypeId;
4448
4450 return UIA_DataItemControlTypeId;
4451
4453 return UIA_DataItemControlTypeId;
4454
4456 return UIA_HyperlinkControlTypeId;
4457
4459 return UIA_ListControlTypeId;
4460
4462 return UIA_ListControlTypeId;
4463
4465 return UIA_ListItemControlTypeId;
4466
4468 return UIA_DataGridControlTypeId;
4469
4471 return UIA_ListItemControlTypeId;
4472
4474 if (!GetDelegate()->GetChildCount()) {
4475
4476
4477
4478
4479 return UIA_TextControlTypeId;
4480 }
4481 return UIA_GroupControlTypeId;
4482
4484 return UIA_GroupControlTypeId;
4485
4487 return UIA_GroupControlTypeId;
4488
4490 return UIA_TextControlTypeId;
4491
4493 return UIA_TextControlTypeId;
4494
4496 return UIA_GroupControlTypeId;
4497
4499 return UIA_MenuControlTypeId;
4500
4502 return UIA_MenuBarControlTypeId;
4503
4505 return UIA_MenuItemControlTypeId;
4506
4508 return UIA_CheckBoxControlTypeId;
4509
4511 return UIA_RadioButtonControlTypeId;
4512
4514 return UIA_ListControlTypeId;
4515
4517 return UIA_ListItemControlTypeId;
4518
4520 return UIA_ProgressBarControlTypeId;
4521
4523 return UIA_GroupControlTypeId;
4524
4526 return UIA_GroupControlTypeId;
4527
4529 return UIA_GroupControlTypeId;
4530
4532 return UIA_CustomControlTypeId;
4533
4535 if (GetDelegate()->GetChildCount()) {
4536 return UIA_GroupControlTypeId;
4537 } else {
4538 return UIA_DocumentControlTypeId;
4539 }
4540
4542 std::string html_tag =
4544 if (html_tag == "select")
4545 return UIA_ComboBoxControlTypeId;
4546 return UIA_ButtonControlTypeId;
4547 }
4548
4550 return UIA_ButtonControlTypeId;
4551
4553 return UIA_PaneControlTypeId;
4554
4556 return UIA_ProgressBarControlTypeId;
4557
4559 return UIA_RadioButtonControlTypeId;
4560
4562 return UIA_GroupControlTypeId;
4563
4565 return UIA_GroupControlTypeId;
4566
4568
4569
4570 return IsInTreeGrid() ? UIA_TreeItemControlTypeId
4571 : UIA_DataItemControlTypeId;
4572 }
4573
4575 return UIA_GroupControlTypeId;
4576
4578 return UIA_DataItemControlTypeId;
4579
4581 return UIA_PaneControlTypeId;
4582
4584 return UIA_GroupControlTypeId;
4585
4587 return UIA_ScrollBarControlTypeId;
4588
4590 return UIA_PaneControlTypeId;
4591
4593 return UIA_GroupControlTypeId;
4594
4596 return UIA_SliderControlTypeId;
4597
4599 return UIA_SliderControlTypeId;
4600
4602 return UIA_SpinnerControlTypeId;
4603
4605 return UIA_ButtonControlTypeId;
4606
4609 return UIA_TextControlTypeId;
4610
4612 return UIA_StatusBarControlTypeId;
4613
4615 return UIA_TextControlTypeId;
4616
4618 return UIA_SeparatorControlTypeId;
4619
4621 return UIA_ImageControlTypeId;
4622
4624 return UIA_TabItemControlTypeId;
4625
4627 return UIA_TableControlTypeId;
4628
4630 return UIA_GroupControlTypeId;
4631
4633 return UIA_TabControlTypeId;
4634
4636 return UIA_PaneControlTypeId;
4637
4639 return UIA_ListItemControlTypeId;
4640
4642 return UIA_DocumentControlTypeId;
4643
4645 return UIA_ButtonControlTypeId;
4646
4649 return UIA_EditControlTypeId;
4650
4652 return UIA_ComboBoxControlTypeId;
4653
4656 return UIA_TextControlTypeId;
4657
4659 return UIA_PaneControlTypeId;
4660
4662 return UIA_ToolBarControlTypeId;
4663
4665 return UIA_ToolTipControlTypeId;
4666
4668 return UIA_TreeControlTypeId;
4669
4671 return UIA_DataGridControlTypeId;
4672
4674 return UIA_TreeItemControlTypeId;
4675
4677 return UIA_SeparatorControlTypeId;
4678
4680 return UIA_GroupControlTypeId;
4681
4683 return UIA_DocumentControlTypeId;
4684
4693 return UIA_PaneControlTypeId;
4694 }
4695
4697 return UIA_DocumentControlTypeId;
4698}
4699
4700AXPlatformNodeWin* AXPlatformNodeWin::ComputeUIALabeledBy() {
4701
4702 if (!CanHaveUIALabeledBy())
4703 return nullptr;
4704
4705
4706
4707 for (int32_t id : GetData().GetIntListAttribute(
4709 auto* node_win =
4710 static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(id));
4711 if (!node_win)
4712 continue;
4713
4714
4715 if (IsValidUiaRelationTarget(node_win) &&
4717 return node_win;
4718 }
4719
4720
4721 for (auto iter = node_win->GetDelegate()->ChildrenBegin();
4722 *iter != *node_win->GetDelegate()->ChildrenEnd(); ++(*iter)) {
4723 AXPlatformNodeWin* child = static_cast<AXPlatformNodeWin*>(
4725 iter->GetNativeViewAccessible()));
4726 if (IsValidUiaRelationTarget(child) &&
4728 return child;
4729 }
4730 }
4731 }
4732
4733 return nullptr;
4734}
4735
4736bool AXPlatformNodeWin::CanHaveUIALabeledBy() {
4737
4738
4739
4740
4741 switch (ComputeUIAControlType()) {
4742 case UIA_ButtonControlTypeId:
4743 case UIA_CheckBoxControlTypeId:
4744 case UIA_DataItemControlTypeId:
4745 case UIA_MenuControlTypeId:
4746 case UIA_MenuBarControlTypeId:
4747 case UIA_RadioButtonControlTypeId:
4748 case UIA_ScrollBarControlTypeId:
4749 case UIA_SeparatorControlTypeId:
4750 case UIA_StatusBarControlTypeId:
4751 case UIA_TabItemControlTypeId:
4752 case UIA_TextControlTypeId:
4753 case UIA_ToolBarControlTypeId:
4754 case UIA_ToolTipControlTypeId:
4755 case UIA_TreeItemControlTypeId:
4756 return false;
4757 default:
4758 return true;
4759 }
4760}
4761
4762bool AXPlatformNodeWin::IsNameExposed() const {
4763 const AXNodeData&
data = GetData();
4764 switch (
data.role) {
4766 return !GetDelegate()->GetChildCount();
4767 default:
4768 return true;
4769 }
4770}
4771
4772bool AXPlatformNodeWin::IsUIAControl() const {
4773
4774
4775
4776
4777 if (GetDelegate()->IsWebContent()) {
4778
4779 if (IsInvisibleOrIgnored())
4780 return false;
4781
4783
4784
4785
4786
4787
4788 auto* parent = FromNativeViewAccessible(GetDelegate()->GetParent());
4789 while (parent) {
4790 const AXNodeData&
data = parent->GetData();
4792 return false;
4793 switch (
data.role) {
4815 return false;
4816 default:
4817 break;
4818 }
4819 parent = FromNativeViewAccessible(parent->GetParent());
4820 }
4821 }
4822
4823 const AXNodeData&
data = GetData();
4824
4825
4826
4829 return true;
4830 }
4832
4833
4835 data.GetNameFrom() ==
4837 return false;
4838 }
4839 return true;
4840 }
4841 switch (
data.role) {
4858 return true;
4859 default:
4860 break;
4861 }
4862
4863
4864
4865
4868 GetNameAsString16().
empty() &&
4870 .empty() &&
4872 return false;
4873 }
4874
4875 return true;
4876 }
4877
4878 const AXNodeData&
data = GetData();
4882}
4883
4884std::optional<LONG> AXPlatformNodeWin::ComputeUIALandmarkType() const {
4885 const AXNodeData&
data = GetData();
4886 switch (
data.role) {
4892 return UIA_CustomLandmarkTypeId;
4893
4895
4896
4897
4898
4899
4900
4901
4902
4905 return UIA_FormLandmarkTypeId;
4906 }
4907 return {};
4908
4910 return UIA_MainLandmarkTypeId;
4911
4913 return UIA_NavigationLandmarkTypeId;
4914
4916 return UIA_SearchLandmarkTypeId;
4917
4921 return UIA_CustomLandmarkTypeId;
4923
4924 default:
4925 return {};
4926 }
4927}
4928
4929bool AXPlatformNodeWin::IsInaccessibleDueToAncestor() const {
4930 AXPlatformNodeWin* parent = static_cast<AXPlatformNodeWin*>(
4932 while (parent) {
4933 if (parent->ShouldHideChildrenForUIA())
4934 return true;
4935 parent = static_cast<AXPlatformNodeWin*>(
4936 FromNativeViewAccessible(parent->GetParent()));
4937 }
4938 return false;
4939}
4940
4941bool AXPlatformNodeWin::ShouldHideChildrenForUIA() const {
4942 if (IsPlainTextField())
4943 return true;
4944
4945 auto role = GetData().role;
4947 return true;
4948
4949 switch (role) {
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4961
4962 if (GetChildCount() == 1) {
4963 AXPlatformNodeBase* only_child = GetFirstChild();
4964 return only_child && only_child->IsText();
4965 }
4966 return false;
4968 return true;
4969 default:
4970 return false;
4971 }
4972}
4973
4974std::u16string AXPlatformNodeWin::GetValue() const {
4976
4977
4978
4979
4980
4981
4982 if (
value.empty() && (MSAAState() & STATE_SYSTEM_LINKED))
4984
4986}
4987
4988bool AXPlatformNodeWin::IsPlatformCheckable() const {
4990 return false;
4991
4993}
4994
4995bool AXPlatformNodeWin::ShouldNodeHaveFocusableState(
4996 const AXNodeData& data) const {
4997 switch (
data.role) {
5001 return true;
5002
5004 AXPlatformNodeBase* parent = FromNativeViewAccessible(GetParent());
5006 }
5007
5009 return false;
5010
5014 return true;
5015 break;
5016
5017 default:
5018 break;
5019 }
5020
5022}
5023
5024int AXPlatformNodeWin::MSAAState() const {
5025 const AXNodeData&
data = GetData();
5026 int msaa_state = 0;
5027
5028
5029
5030
5032 msaa_state |= STATE_SYSTEM_BUSY;
5033
5035 msaa_state |= STATE_SYSTEM_COLLAPSED;
5036
5038 msaa_state |= STATE_SYSTEM_DEFAULT;
5039
5040
5041
5043 msaa_state |= STATE_SYSTEM_EXPANDED;
5044
5045 if (ShouldNodeHaveFocusableState(data))
5046 msaa_state |= STATE_SYSTEM_FOCUSABLE;
5047
5048
5050 msaa_state |= STATE_SYSTEM_HASPOPUP;
5051
5052
5053
5055
5056
5057
5058 if (GetDelegate()->ShouldIgnoreHoveredStateForTesting())
5059 msaa_state |= STATE_SYSTEM_HOTTRACKED;
5060 }
5061
5062
5063
5064 if (IsInvisibleOrIgnored())
5065 msaa_state |= STATE_SYSTEM_INVISIBLE;
5066
5068 msaa_state |= STATE_SYSTEM_LINKED;
5069
5070
5071
5073 msaa_state |= STATE_SYSTEM_EXTSELECTABLE;
5074 msaa_state |= STATE_SYSTEM_MULTISELECTABLE;
5075 }
5076
5077 if (GetDelegate()->IsOffscreen())
5078 msaa_state |= STATE_SYSTEM_OFFSCREEN;
5079
5081 msaa_state |= STATE_SYSTEM_PROTECTED;
5082
5083
5084
5085
5086 if (
data.IsSelectable())
5087 msaa_state |= STATE_SYSTEM_SELECTABLE;
5088
5090 msaa_state |= STATE_SYSTEM_SELECTED;
5091
5092
5093
5095 msaa_state |= STATE_SYSTEM_TRAVERSED;
5096
5097
5098
5099
5100
5101 switch (
data.GetCheckedState()) {
5104 break;
5107 msaa_state |= STATE_SYSTEM_PRESSED;
5109
5110
5111
5112 msaa_state |= STATE_SYSTEM_PRESSED | STATE_SYSTEM_CHECKED;
5113 } else {
5114 msaa_state |= STATE_SYSTEM_CHECKED;
5115 }
5116 break;
5118 msaa_state |= STATE_SYSTEM_MIXED;
5119 break;
5120 }
5121
5124 switch (restriction) {
5126 msaa_state |= STATE_SYSTEM_UNAVAILABLE;
5127 break;
5129 msaa_state |= STATE_SYSTEM_READONLY;
5130 break;
5131 default:
5132
5133
5134
5135
5138 msaa_state |= STATE_SYSTEM_READONLY;
5139 }
5140 break;
5141 }
5142
5143
5144
5145
5148 msaa_state |= STATE_SYSTEM_UNAVAILABLE;
5149 }
5150
5151
5152
5153
5155 if (focus == const_cast<AXPlatformNodeWin*>(this)->GetNativeViewAccessible())
5156 msaa_state |= STATE_SYSTEM_FOCUSED;
5157
5158
5159
5162 AXPlatformNodeBase* container = FromNativeViewAccessible(GetParent());
5163 if (container && container->GetParent() == focus) {
5164 AXNodeData container_data = container->GetData();
5168 msaa_state |= STATE_SYSTEM_FOCUSED;
5169 }
5170 }
5171 }
5172
5173
5174
5175
5176
5177
5178
5181 msaa_state |= STATE_SYSTEM_FOCUSED;
5182 }
5183
5184
5186 msaa_state |= STATE_SYSTEM_LINKED;
5187
5188
5191 msaa_state |= STATE_SYSTEM_MIXED;
5192
5193 return msaa_state;
5194}
5195
5196
5197std::optional<DWORD> AXPlatformNodeWin::MojoEventToMSAAEvent(
5200 case ax::mojom::Event::kAlert:
5201 return EVENT_SYSTEM_ALERT;
5202 case ax::mojom::Event::kCheckedStateChanged:
5203 case ax::mojom::Event::kExpandedChanged:
5204 case ax::mojom::Event::kStateChanged:
5205 return EVENT_OBJECT_STATECHANGE;
5206 case ax::mojom::Event::kFocus:
5207 case ax::mojom::Event::kFocusContext:
5208 return EVENT_OBJECT_FOCUS;
5209 case ax::mojom::Event::kLiveRegionChanged:
5210 return EVENT_OBJECT_LIVEREGIONCHANGED;
5211 case ax::mojom::Event::kMenuStart:
5212 return EVENT_SYSTEM_MENUSTART;
5213 case ax::mojom::Event::kMenuEnd:
5214 return EVENT_SYSTEM_MENUEND;
5215 case ax::mojom::Event::kMenuPopupStart:
5216 return EVENT_SYSTEM_MENUPOPUPSTART;
5217 case ax::mojom::Event::kMenuPopupEnd:
5218 return EVENT_SYSTEM_MENUPOPUPEND;
5219 case ax::mojom::Event::kSelection:
5220 return EVENT_OBJECT_SELECTION;
5221 case ax::mojom::Event::kSelectionAdd:
5222 return EVENT_OBJECT_SELECTIONADD;
5223 case ax::mojom::Event::kSelectionRemove:
5224 return EVENT_OBJECT_SELECTIONREMOVE;
5225 case ax::mojom::Event::kTextChanged:
5226 return EVENT_OBJECT_NAMECHANGE;
5227 case ax::mojom::Event::kTooltipClosed:
5228 return EVENT_OBJECT_HIDE;
5229 case ax::mojom::Event::kTooltipOpened:
5230 return EVENT_OBJECT_SHOW;
5231 case ax::mojom::Event::kValueChanged:
5232 return EVENT_OBJECT_VALUECHANGE;
5233 case ax::mojom::Event::kDocumentSelectionChanged:
5234 return EVENT_OBJECT_TEXTSELECTIONCHANGED;
5235 default:
5236 return std::nullopt;
5237 }
5238}
5239
5240
5241std::optional<EVENTID> AXPlatformNodeWin::MojoEventToUIAEvent(
5244 case ax::mojom::Event::kAlert:
5245 return UIA_SystemAlertEventId;
5246 case ax::mojom::Event::kDocumentSelectionChanged:
5247 return UIA_Text_TextChangedEventId;
5248 case ax::mojom::Event::kFocus:
5249 case ax::mojom::Event::kFocusContext:
5250 case ax::mojom::Event::kFocusAfterMenuClose:
5251 return UIA_AutomationFocusChangedEventId;
5252 case ax::mojom::Event::kLiveRegionChanged:
5253 return UIA_LiveRegionChangedEventId;
5254 case ax::mojom::Event::kSelection:
5255 return UIA_SelectionItem_ElementSelectedEventId;
5256 case ax::mojom::Event::kSelectionAdd:
5257 return UIA_SelectionItem_ElementAddedToSelectionEventId;
5258 case ax::mojom::Event::kSelectionRemove:
5259 return UIA_SelectionItem_ElementRemovedFromSelectionEventId;
5260 case ax::mojom::Event::kTooltipClosed:
5261 return UIA_ToolTipClosedEventId;
5262 case ax::mojom::Event::kTooltipOpened:
5263 return UIA_ToolTipOpenedEventId;
5264 default:
5265 return std::nullopt;
5266 }
5267}
5268
5269std::optional<PROPERTYID> AXPlatformNodeWin::MojoEventToUIAProperty(
5272 case ax::mojom::Event::kControlsChanged:
5273 return UIA_ControllerForPropertyId;
5274 case ax::mojom::Event::kCheckedStateChanged:
5275 return UIA_ToggleToggleStatePropertyId;
5276 case ax::mojom::Event::kRowCollapsed:
5277 case ax::mojom::Event::kRowExpanded:
5278 return UIA_ExpandCollapseExpandCollapseStatePropertyId;
5279 case ax::mojom::Event::kSelection:
5280 case ax::mojom::Event::kSelectionAdd:
5281 case ax::mojom::Event::kSelectionRemove:
5282 return UIA_SelectionItemIsSelectedPropertyId;
5283 case ax::mojom::Event::kValueChanged:
5285 return UIA_ToggleToggleStatePropertyId;
5286 }
5287 return std::nullopt;
5288 default:
5289 return std::nullopt;
5290 }
5291}
5292
5293
5294BSTR AXPlatformNodeWin::GetValueAttributeAsBstr(AXPlatformNodeWin*
target) {
5295
5296
5297
5298
5299
5300
5301
5302
5303
5305
5306
5307
5308
5310
5311 unsigned int color =
static_cast<unsigned int>(
5313
5314
5315 unsigned int red = (((
color) >> 16) & 0xFF);
5316 unsigned int green = (((
color) >> 8) & 0xFF);
5317 unsigned int blue = (((
color) >> 0) & 0xFF);
5318 std::u16string value_text;
5325 }
5326
5327
5328
5329
5336 }
5337
5338
5339
5340
5346 }
5347
5348
5349
5350
5351
5353 if (
result.empty() &&
target->GetData().IsRangeValueSupported()) {
5354 float fval;
5356 &fval)) {
5361 }
5362 }
5363
5366
5370}
5371
5372HRESULT AXPlatformNodeWin::GetStringAttributeAsBstr(
5374 BSTR* value_bstr) const {
5375 std::u16string str;
5376
5377 if (!GetString16Attribute(attribute, &str))
5378 return S_FALSE;
5379
5382
5383 return S_OK;
5384}
5385
5386HRESULT AXPlatformNodeWin::GetNameAsBstr(BSTR* value_bstr) const {
5387 std::u16string str = GetNameAsString16();
5390 return S_OK;
5391}
5392
5393
5394
5395void AXPlatformNodeWin::AddAlertTarget() {}
5396
5397void AXPlatformNodeWin::RemoveAlertTarget() {}
5398
5399AXPlatformNodeWin* AXPlatformNodeWin::GetTargetFromChildID(
5400 const VARIANT& var_id) {
5401 if (V_VT(&var_id) != VT_I4)
5402 return nullptr;
5403
5404 LONG child_id = V_I4(&var_id);
5405 if (child_id == CHILDID_SELF)
5406 return this;
5407
5408 if (child_id >= 1 && child_id <= GetDelegate()->GetChildCount()) {
5409
5410
5411 AXPlatformNodeBase*
base =
5412 FromNativeViewAccessible(GetDelegate()->ChildAtIndex(child_id - 1));
5413 return static_cast<AXPlatformNodeWin*
>(
base);
5414 }
5415
5416 if (child_id >= 0)
5417 return nullptr;
5418
5419
5420 AXPlatformNode* node = GetFromUniqueId(-child_id);
5421 if (!node)
5422 return nullptr;
5423
5424 AXPlatformNodeBase*
base =
5425 FromNativeViewAccessible(node->GetNativeViewAccessible());
5426 if (
base && !
base->IsDescendantOf(
this))
5428
5429 return static_cast<AXPlatformNodeWin*
>(
base);
5430}
5431
5432bool AXPlatformNodeWin::IsInTreeGrid() {
5433 AXPlatformNodeBase* container = FromNativeViewAccessible(GetParent());
5434
5435
5437 container = FromNativeViewAccessible(container->GetParent());
5438
5439 if (!container)
5440 return false;
5441
5443}
5444
5445HRESULT AXPlatformNodeWin::AllocateComArrayFromVector(
5446 std::vector<LONG>& results,
5453
5455 *n_selected =
count;
5456 *selected =
static_cast<LONG*
>(CoTaskMemAlloc(
sizeof(
LONG) *
count));
5457
5459 (*selected)[i] = results[i];
5460 return S_OK;
5461}
5462
5463bool AXPlatformNodeWin::IsPlaceholderText() const {
5465 return false;
5466 AXPlatformNodeWin* parent =
5467 static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(GetParent()));
5468
5470 return parent->IsTextField() &&
5472}
5473
5474double AXPlatformNodeWin::GetHorizontalScrollPercent() {
5475 if (!IsHorizontallyScrollable())
5476 return UIA_ScrollPatternNoScroll;
5477
5481 return 100.0 * (
x - x_min) / (x_max - x_min);
5482}
5483
5484double AXPlatformNodeWin::GetVerticalScrollPercent() {
5485 if (!IsVerticallyScrollable())
5486 return UIA_ScrollPatternNoScroll;
5487
5491 return 100.0 * (
y - y_min) / (y_max - y_min);
5492}
5493
5494BSTR AXPlatformNodeWin::GetFontNameAttributeAsBSTR() const {
5495 const std::u16string string =
5497
5499}
5500
5501BSTR AXPlatformNodeWin::GetStyleNameAttributeAsBSTR() const {
5502 std::u16string style_name =
5503 GetDelegate()->GetStyleNameAttributeAsLocalizedString();
5504
5506}
5507
5508TextDecorationLineStyle AXPlatformNodeWin::GetUIATextDecorationStyle(
5512 GetIntAttribute(int_attribute));
5513
5514 switch (text_decoration_style) {
5516 return TextDecorationLineStyle::TextDecorationLineStyle_None;
5518 return TextDecorationLineStyle::TextDecorationLineStyle_Dot;
5520 return TextDecorationLineStyle::TextDecorationLineStyle_Dash;
5522 return TextDecorationLineStyle::TextDecorationLineStyle_Single;
5524 return TextDecorationLineStyle::TextDecorationLineStyle_Double;
5526 return TextDecorationLineStyle::TextDecorationLineStyle_Wavy;
5527 }
5528}
5529
5530
5531
5532AXPlatformNodeWin::PatternProviderFactoryMethod
5533AXPlatformNodeWin::GetPatternProviderFactoryMethod(PATTERNID pattern_id) {
5534 const AXNodeData&
data = GetData();
5535
5536 switch (pattern_id) {
5537 case UIA_ExpandCollapsePatternId:
5538 if (
data.SupportsExpandCollapse()) {
5539 return &PatternProvider<IExpandCollapseProvider>;
5540 }
5541 break;
5542
5543 case UIA_GridPatternId:
5545 return &PatternProvider<IGridProvider>;
5546 }
5547 break;
5548
5549 case UIA_GridItemPatternId:
5551 return &PatternProvider<IGridItemProvider>;
5552 }
5553 break;
5554
5555 case UIA_InvokePatternId:
5556 if (
data.IsInvocable()) {
5557 return &PatternProvider<IInvokeProvider>;
5558 }
5559 break;
5560
5561 case UIA_RangeValuePatternId:
5562 if (
data.IsRangeValueSupported()) {
5563 return &PatternProvider<IRangeValueProvider>;
5564 }
5565 break;
5566
5567 case UIA_ScrollPatternId:
5568 if (IsScrollable()) {
5569 return &PatternProvider<IScrollProvider>;
5570 }
5571 break;
5572
5573 case UIA_ScrollItemPatternId:
5574 return &PatternProvider<IScrollItemProvider>;
5575 break;
5576
5577 case UIA_SelectionItemPatternId:
5578 if (IsSelectionItemSupported()) {
5579 return &PatternProvider<ISelectionItemProvider>;
5580 }
5581 break;
5582
5583 case UIA_SelectionPatternId:
5585 return &PatternProvider<ISelectionProvider>;
5586 }
5587 break;
5588
5589 case UIA_TablePatternId:
5590
5591
5592
5593
5595 std::optional<bool> table_has_headers =
5596 GetDelegate()->GetTableHasColumnOrRowHeaderNode();
5597 if (table_has_headers.has_value() && table_has_headers.value()) {
5598 return &PatternProvider<ITableProvider>;
5599 }
5600 }
5601 break;
5602
5603 case UIA_TableItemPatternId:
5604
5605
5606
5607
5608
5610 std::optional<bool> table_has_headers =
5611 GetDelegate()->GetTableHasColumnOrRowHeaderNode();
5612 if (table_has_headers.has_value() && table_has_headers.value()) {
5613 return &PatternProvider<ITableItemProvider>;
5614 }
5615 }
5616 break;
5617
5618 case UIA_TextEditPatternId:
5619 case UIA_TextPatternId:
5620 if (
IsText() || IsTextField() ||
5622 return &AXPlatformNodeTextProviderWin::CreateIUnknown;
5623 }
5624 break;
5625
5626 case UIA_TogglePatternId:
5628 return &PatternProvider<IToggleProvider>;
5629 }
5630 break;
5631
5632 case UIA_ValuePatternId:
5634 return &PatternProvider<IValueProvider>;
5635 }
5636 break;
5637
5638 case UIA_WindowPatternId:
5640 return &PatternProvider<IWindowProvider>;
5641 }
5642 break;
5643
5644
5645 case UIA_AnnotationPatternId:
5646 case UIA_CustomNavigationPatternId:
5647 case UIA_DockPatternId:
5648 case UIA_DragPatternId:
5649 case UIA_DropTargetPatternId:
5650 case UIA_ItemContainerPatternId:
5651 case UIA_MultipleViewPatternId:
5652 case UIA_ObjectModelPatternId:
5653 case UIA_SpreadsheetPatternId:
5654 case UIA_SpreadsheetItemPatternId:
5655 case UIA_StylesPatternId:
5656 case UIA_SynchronizedInputPatternId:
5657 case UIA_TextPattern2Id:
5658 case UIA_TransformPatternId:
5659 case UIA_TransformPattern2Id:
5660 case UIA_VirtualizedItemPatternId:
5661 break;
5662
5663
5664 case UIA_LegacyIAccessiblePatternId:
5665 break;
5666 }
5667 return nullptr;
5668}
5669
5670void AXPlatformNodeWin::FireLiveRegionChangeRecursive() {
5672 if (HasStringAttribute(live_status_attr) &&
5673 GetStringAttribute(live_status_attr) != "off") {
5675 ::UiaRaiseAutomationEvent(this, UIA_LiveRegionChangedEventId);
5676 return;
5677 }
5678
5679 for (int index = 0; index < GetChildCount(); ++index) {
5680 auto* child = static_cast<AXPlatformNodeWin*>(
5681 FromNativeViewAccessible(ChildAtIndex(index)));
5682
5683
5684
5685
5686 if (child->GetDelegate()->IsWebContent())
5687 child->FireLiveRegionChangeRecursive();
5688 }
5689}
5690
5691AXPlatformNodeWin* AXPlatformNodeWin::GetLowestAccessibleElement() {
5692 if (!IsInaccessibleDueToAncestor())
5693 return this;
5694
5695 AXPlatformNodeWin* parent = static_cast<AXPlatformNodeWin*>(
5697 while (parent) {
5698 if (parent->ShouldHideChildrenForUIA())
5699 return parent;
5700 parent = static_cast<AXPlatformNodeWin*>(
5702 }
5703
5705 return nullptr;
5706}
5707
5708AXPlatformNodeWin* AXPlatformNodeWin::GetFirstTextOnlyDescendant() {
5709 for (auto* child = static_cast<AXPlatformNodeWin*>(GetFirstChild()); child;
5710 child = static_cast<AXPlatformNodeWin*>(child->GetNextSibling())) {
5711 if (child->IsText())
5712 return child;
5713 if (AXPlatformNodeWin* descendant = child->GetFirstTextOnlyDescendant())
5714 return descendant;
5715 }
5716 return nullptr;
5717}
5718
5719bool AXPlatformNodeWin::IsDescendantOf(AXPlatformNode* ancestor) const {
5720 if (!ancestor) {
5721 return false;
5722 }
5723
5725 return true;
5726 }
5727
5728
5729
5730 IRawElementProviderFragmentRoot*
root;
5732 const_cast<AXPlatformNodeWin*>(this)->get_FragmentRoot(&root))) {
5733 AXPlatformNodeWin* root_win;
5734 if (
SUCCEEDED(
root->QueryInterface(__uuidof(AXPlatformNodeWin),
5735 reinterpret_cast<void**>(&root_win)))) {
5736 return ancestor == static_cast<AXPlatformNode*>(root_win);
5737 }
5738 }
5739
5740 return false;
5741}
5742
5743}
static float next(float f)
static SkScalar center(float pos0, float pos1)
ax::mojom::Event event_type
Type::kYUV Type::kRGBA() int(0.7 *637)
Vector2d OffsetFromOrigin() 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()
EMSCRIPTEN_KEEPALIVE void empty()
static float max(float r, float g, float b)
Optional< SkRect > bounds
@ kPdfActionableHighlight
@ kAttributeExplicitlyEmpty
const int32_t kUnknownAriaColumnOrRowCount
@ 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()