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