Bug 1890277: part 4) Add CSPParser support for the `trusted-types` directive, guarded...
[gecko.git] / accessible / xul / XULSelectControlAccessible.cpp
blob006d1daf896a5e1218b507d107f0d2f255979a7e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "XULSelectControlAccessible.h"
9 #include "nsAccessibilityService.h"
10 #include "DocAccessible.h"
12 #include "nsIDOMXULSelectCntrlItemEl.h"
13 #include "nsIDOMXULMultSelectCntrlEl.h"
15 #include "mozilla/dom/Element.h"
16 #include "mozilla/dom/KeyboardEventBinding.h"
18 using namespace mozilla;
19 using namespace mozilla::a11y;
21 ////////////////////////////////////////////////////////////////////////////////
22 // XULSelectControlAccessible
23 ////////////////////////////////////////////////////////////////////////////////
25 XULSelectControlAccessible::XULSelectControlAccessible(nsIContent* aContent,
26 DocAccessible* aDoc)
27 : AccessibleWrap(aContent, aDoc) {
28 mGenericTypes |= eSelect;
29 mSelectControl = aContent->AsElement();
32 ////////////////////////////////////////////////////////////////////////////////
33 // XULSelectControlAccessible: LocalAccessible
35 void XULSelectControlAccessible::Shutdown() {
36 mSelectControl = nullptr;
37 AccessibleWrap::Shutdown();
40 ////////////////////////////////////////////////////////////////////////////////
41 // XULSelectControlAccessible: SelectAccessible
43 void XULSelectControlAccessible::SelectedItems(nsTArray<Accessible*>* aItems) {
44 // For XUL multi-select control
45 nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
46 mSelectControl->AsXULMultiSelectControl();
47 if (xulMultiSelect) {
48 int32_t length = 0;
49 xulMultiSelect->GetSelectedCount(&length);
50 for (int32_t index = 0; index < length; index++) {
51 RefPtr<dom::Element> element;
52 xulMultiSelect->MultiGetSelectedItem(index, getter_AddRefs(element));
53 LocalAccessible* item = mDoc->GetAccessible(element);
54 if (item) aItems->AppendElement(item);
56 } else { // Single select?
57 nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
58 mSelectControl->AsXULSelectControl();
59 RefPtr<dom::Element> element;
60 selectControl->GetSelectedItem(getter_AddRefs(element));
61 if (element) {
62 LocalAccessible* item = mDoc->GetAccessible(element);
63 if (item) aItems->AppendElement(item);
68 Accessible* XULSelectControlAccessible::GetSelectedItem(uint32_t aIndex) {
69 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
70 mSelectControl->AsXULMultiSelectControl();
72 RefPtr<dom::Element> element;
73 if (multiSelectControl) {
74 multiSelectControl->MultiGetSelectedItem(aIndex, getter_AddRefs(element));
75 } else if (aIndex == 0) {
76 nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
77 mSelectControl->AsXULSelectControl();
78 if (selectControl) {
79 selectControl->GetSelectedItem(getter_AddRefs(element));
83 return element && mDoc ? mDoc->GetAccessible(element) : nullptr;
86 uint32_t XULSelectControlAccessible::SelectedItemCount() {
87 // For XUL multi-select control
88 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
89 mSelectControl->AsXULMultiSelectControl();
90 if (multiSelectControl) {
91 int32_t count = 0;
92 multiSelectControl->GetSelectedCount(&count);
93 return count;
96 // For XUL single-select control/menulist
97 nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
98 mSelectControl->AsXULSelectControl();
99 if (selectControl) {
100 int32_t index = -1;
101 selectControl->GetSelectedIndex(&index);
102 return (index >= 0) ? 1 : 0;
105 return 0;
108 bool XULSelectControlAccessible::AddItemToSelection(uint32_t aIndex) {
109 LocalAccessible* item = LocalChildAt(aIndex);
110 if (!item || !item->GetContent()) return false;
112 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
113 item->GetContent()->AsElement()->AsXULSelectControlItem();
114 if (!itemElm) return false;
116 bool isItemSelected = false;
117 itemElm->GetSelected(&isItemSelected);
118 if (isItemSelected) return true;
120 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
121 mSelectControl->AsXULMultiSelectControl();
123 if (multiSelectControl) {
124 multiSelectControl->AddItemToSelection(itemElm);
125 } else {
126 nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
127 mSelectControl->AsXULSelectControl();
128 if (selectControl) {
129 selectControl->SetSelectedItem(item->Elm());
133 return true;
136 bool XULSelectControlAccessible::RemoveItemFromSelection(uint32_t aIndex) {
137 LocalAccessible* item = LocalChildAt(aIndex);
138 if (!item || !item->GetContent()) return false;
140 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
141 item->GetContent()->AsElement()->AsXULSelectControlItem();
142 if (!itemElm) return false;
144 bool isItemSelected = false;
145 itemElm->GetSelected(&isItemSelected);
146 if (!isItemSelected) return true;
148 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
149 mSelectControl->AsXULMultiSelectControl();
151 if (multiSelectControl) {
152 multiSelectControl->RemoveItemFromSelection(itemElm);
153 } else {
154 nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
155 mSelectControl->AsXULSelectControl();
156 if (selectControl) {
157 selectControl->SetSelectedItem(nullptr);
161 return true;
164 bool XULSelectControlAccessible::IsItemSelected(uint32_t aIndex) {
165 LocalAccessible* item = LocalChildAt(aIndex);
166 if (!item || !item->GetContent()) return false;
168 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
169 item->GetContent()->AsElement()->AsXULSelectControlItem();
170 if (!itemElm) return false;
172 bool isItemSelected = false;
173 itemElm->GetSelected(&isItemSelected);
174 return isItemSelected;
177 bool XULSelectControlAccessible::UnselectAll() {
178 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
179 mSelectControl->AsXULMultiSelectControl();
180 if (multiSelectControl) {
181 multiSelectControl->ClearSelection();
182 } else {
183 nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
184 mSelectControl->AsXULSelectControl();
185 if (selectControl) {
186 selectControl->SetSelectedIndex(-1);
190 return true;
193 bool XULSelectControlAccessible::SelectAll() {
194 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
195 mSelectControl->AsXULMultiSelectControl();
196 if (multiSelectControl) {
197 multiSelectControl->SelectAll();
198 return true;
201 // otherwise, don't support this method
202 return false;
205 ////////////////////////////////////////////////////////////////////////////////
206 // XULSelectControlAccessible: Widgets
208 LocalAccessible* XULSelectControlAccessible::CurrentItem() const {
209 // aria-activedescendant should override.
210 LocalAccessible* current = AccessibleWrap::CurrentItem();
211 if (current) {
212 return current;
215 if (!mSelectControl) return nullptr;
217 RefPtr<dom::Element> currentItemElm;
218 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
219 mSelectControl->AsXULMultiSelectControl();
220 if (multiSelectControl) {
221 multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm));
222 } else {
223 nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
224 mSelectControl->AsXULSelectControl();
225 if (selectControl) {
226 selectControl->GetSelectedItem(getter_AddRefs(currentItemElm));
230 if (currentItemElm) {
231 DocAccessible* document = Document();
232 if (document) return document->GetAccessible(currentItemElm);
235 return nullptr;
238 void XULSelectControlAccessible::SetCurrentItem(const LocalAccessible* aItem) {
239 if (!mSelectControl) return;
241 nsCOMPtr<dom::Element> itemElm = aItem->Elm();
242 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
243 itemElm->AsXULMultiSelectControl();
244 if (multiSelectControl) {
245 multiSelectControl->SetCurrentItem(itemElm);
246 } else {
247 nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
248 mSelectControl->AsXULSelectControl();
249 if (selectControl) {
250 selectControl->SetSelectedItem(itemElm);