|
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/. */ |
|
6 |
|
7 #include "XULSelectControlAccessible.h" |
|
8 |
|
9 #include "nsAccessibilityService.h" |
|
10 #include "DocAccessible.h" |
|
11 |
|
12 #include "nsIDOMXULContainerElement.h" |
|
13 #include "nsIDOMXULSelectCntrlItemEl.h" |
|
14 #include "nsIDOMXULMultSelectCntrlEl.h" |
|
15 #include "nsIDOMKeyEvent.h" |
|
16 #include "nsIDOMElement.h" |
|
17 #include "nsIDOMXULElement.h" |
|
18 #include "nsIMutableArray.h" |
|
19 #include "nsIServiceManager.h" |
|
20 |
|
21 #include "mozilla/dom/Element.h" |
|
22 |
|
23 using namespace mozilla; |
|
24 using namespace mozilla::a11y; |
|
25 |
|
26 //////////////////////////////////////////////////////////////////////////////// |
|
27 // XULSelectControlAccessible |
|
28 //////////////////////////////////////////////////////////////////////////////// |
|
29 |
|
30 XULSelectControlAccessible:: |
|
31 XULSelectControlAccessible(nsIContent* aContent, DocAccessible* aDoc) : |
|
32 AccessibleWrap(aContent, aDoc) |
|
33 { |
|
34 mGenericTypes |= eSelect; |
|
35 mSelectControl = do_QueryInterface(aContent); |
|
36 } |
|
37 |
|
38 //////////////////////////////////////////////////////////////////////////////// |
|
39 // XULSelectControlAccessible: Accessible |
|
40 |
|
41 void |
|
42 XULSelectControlAccessible::Shutdown() |
|
43 { |
|
44 mSelectControl = nullptr; |
|
45 AccessibleWrap::Shutdown(); |
|
46 } |
|
47 |
|
48 //////////////////////////////////////////////////////////////////////////////// |
|
49 // XULSelectControlAccessible: SelectAccessible |
|
50 |
|
51 already_AddRefed<nsIArray> |
|
52 XULSelectControlAccessible::SelectedItems() |
|
53 { |
|
54 nsCOMPtr<nsIMutableArray> selectedItems = |
|
55 do_CreateInstance(NS_ARRAY_CONTRACTID); |
|
56 if (!selectedItems || !mDoc) |
|
57 return nullptr; |
|
58 |
|
59 // For XUL multi-select control |
|
60 nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect = |
|
61 do_QueryInterface(mSelectControl); |
|
62 if (xulMultiSelect) { |
|
63 int32_t length = 0; |
|
64 xulMultiSelect->GetSelectedCount(&length); |
|
65 for (int32_t index = 0; index < length; index++) { |
|
66 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm; |
|
67 xulMultiSelect->MultiGetSelectedItem(index, getter_AddRefs(itemElm)); |
|
68 nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm)); |
|
69 Accessible* item = mDoc->GetAccessible(itemNode); |
|
70 if (item) |
|
71 selectedItems->AppendElement(static_cast<nsIAccessible*>(item), |
|
72 false); |
|
73 } |
|
74 } else { // Single select? |
|
75 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm; |
|
76 mSelectControl->GetSelectedItem(getter_AddRefs(itemElm)); |
|
77 nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm)); |
|
78 if (itemNode) { |
|
79 Accessible* item = mDoc->GetAccessible(itemNode); |
|
80 if (item) |
|
81 selectedItems->AppendElement(static_cast<nsIAccessible*>(item), |
|
82 false); |
|
83 } |
|
84 } |
|
85 |
|
86 return selectedItems.forget(); |
|
87 } |
|
88 |
|
89 Accessible* |
|
90 XULSelectControlAccessible::GetSelectedItem(uint32_t aIndex) |
|
91 { |
|
92 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = |
|
93 do_QueryInterface(mSelectControl); |
|
94 |
|
95 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm; |
|
96 if (multiSelectControl) |
|
97 multiSelectControl->MultiGetSelectedItem(aIndex, getter_AddRefs(itemElm)); |
|
98 else if (aIndex == 0) |
|
99 mSelectControl->GetSelectedItem(getter_AddRefs(itemElm)); |
|
100 |
|
101 nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm)); |
|
102 return itemNode && mDoc ? mDoc->GetAccessible(itemNode) : nullptr; |
|
103 } |
|
104 |
|
105 uint32_t |
|
106 XULSelectControlAccessible::SelectedItemCount() |
|
107 { |
|
108 // For XUL multi-select control |
|
109 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = |
|
110 do_QueryInterface(mSelectControl); |
|
111 if (multiSelectControl) { |
|
112 int32_t count = 0; |
|
113 multiSelectControl->GetSelectedCount(&count); |
|
114 return count; |
|
115 } |
|
116 |
|
117 // For XUL single-select control/menulist |
|
118 int32_t index; |
|
119 mSelectControl->GetSelectedIndex(&index); |
|
120 return (index >= 0) ? 1 : 0; |
|
121 } |
|
122 |
|
123 bool |
|
124 XULSelectControlAccessible::AddItemToSelection(uint32_t aIndex) |
|
125 { |
|
126 Accessible* item = GetChildAt(aIndex); |
|
127 if (!item) |
|
128 return false; |
|
129 |
|
130 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm = |
|
131 do_QueryInterface(item->GetContent()); |
|
132 if (!itemElm) |
|
133 return false; |
|
134 |
|
135 bool isItemSelected = false; |
|
136 itemElm->GetSelected(&isItemSelected); |
|
137 if (isItemSelected) |
|
138 return true; |
|
139 |
|
140 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = |
|
141 do_QueryInterface(mSelectControl); |
|
142 |
|
143 if (multiSelectControl) |
|
144 multiSelectControl->AddItemToSelection(itemElm); |
|
145 else |
|
146 mSelectControl->SetSelectedItem(itemElm); |
|
147 |
|
148 return true; |
|
149 } |
|
150 |
|
151 bool |
|
152 XULSelectControlAccessible::RemoveItemFromSelection(uint32_t aIndex) |
|
153 { |
|
154 Accessible* item = GetChildAt(aIndex); |
|
155 if (!item) |
|
156 return false; |
|
157 |
|
158 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm = |
|
159 do_QueryInterface(item->GetContent()); |
|
160 if (!itemElm) |
|
161 return false; |
|
162 |
|
163 bool isItemSelected = false; |
|
164 itemElm->GetSelected(&isItemSelected); |
|
165 if (!isItemSelected) |
|
166 return true; |
|
167 |
|
168 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = |
|
169 do_QueryInterface(mSelectControl); |
|
170 |
|
171 if (multiSelectControl) |
|
172 multiSelectControl->RemoveItemFromSelection(itemElm); |
|
173 else |
|
174 mSelectControl->SetSelectedItem(nullptr); |
|
175 |
|
176 return true; |
|
177 } |
|
178 |
|
179 bool |
|
180 XULSelectControlAccessible::IsItemSelected(uint32_t aIndex) |
|
181 { |
|
182 Accessible* item = GetChildAt(aIndex); |
|
183 if (!item) |
|
184 return false; |
|
185 |
|
186 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm = |
|
187 do_QueryInterface(item->GetContent()); |
|
188 if (!itemElm) |
|
189 return false; |
|
190 |
|
191 bool isItemSelected = false; |
|
192 itemElm->GetSelected(&isItemSelected); |
|
193 return isItemSelected; |
|
194 } |
|
195 |
|
196 bool |
|
197 XULSelectControlAccessible::UnselectAll() |
|
198 { |
|
199 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = |
|
200 do_QueryInterface(mSelectControl); |
|
201 multiSelectControl ? |
|
202 multiSelectControl->ClearSelection() : mSelectControl->SetSelectedIndex(-1); |
|
203 |
|
204 return true; |
|
205 } |
|
206 |
|
207 bool |
|
208 XULSelectControlAccessible::SelectAll() |
|
209 { |
|
210 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = |
|
211 do_QueryInterface(mSelectControl); |
|
212 if (multiSelectControl) { |
|
213 multiSelectControl->SelectAll(); |
|
214 return true; |
|
215 } |
|
216 |
|
217 // otherwise, don't support this method |
|
218 return false; |
|
219 } |
|
220 |
|
221 //////////////////////////////////////////////////////////////////////////////// |
|
222 // XULSelectControlAccessible: Widgets |
|
223 |
|
224 Accessible* |
|
225 XULSelectControlAccessible::CurrentItem() |
|
226 { |
|
227 if (!mSelectControl) |
|
228 return nullptr; |
|
229 |
|
230 nsCOMPtr<nsIDOMXULSelectControlItemElement> currentItemElm; |
|
231 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = |
|
232 do_QueryInterface(mSelectControl); |
|
233 if (multiSelectControl) |
|
234 multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm)); |
|
235 else |
|
236 mSelectControl->GetSelectedItem(getter_AddRefs(currentItemElm)); |
|
237 |
|
238 nsCOMPtr<nsINode> DOMNode; |
|
239 if (currentItemElm) |
|
240 DOMNode = do_QueryInterface(currentItemElm); |
|
241 |
|
242 if (DOMNode) { |
|
243 DocAccessible* document = Document(); |
|
244 if (document) |
|
245 return document->GetAccessible(DOMNode); |
|
246 } |
|
247 |
|
248 return nullptr; |
|
249 } |
|
250 |
|
251 void |
|
252 XULSelectControlAccessible::SetCurrentItem(Accessible* aItem) |
|
253 { |
|
254 if (!mSelectControl) |
|
255 return; |
|
256 |
|
257 nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm = |
|
258 do_QueryInterface(aItem->GetContent()); |
|
259 nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = |
|
260 do_QueryInterface(mSelectControl); |
|
261 if (multiSelectControl) |
|
262 multiSelectControl->SetCurrentItem(itemElm); |
|
263 else |
|
264 mSelectControl->SetSelectedItem(itemElm); |
|
265 } |