OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2008 Nuanti Ltd. | |
3 * Copyright (C) 2009 Jan Alonzo | |
4 * Copyright (C) 2010, 2011, 2012 Igalia S.L. | |
5 * | |
6 * Portions from Mozilla a11y, copyright as follows: | |
7 * | |
8 * The Original Code is mozilla.org code. | |
9 * | |
10 * The Initial Developer of the Original Code is | |
11 * Sun Microsystems, Inc. | |
12 * Portions created by the Initial Developer are Copyright (C) 2002 | |
13 * the Initial Developer. All Rights Reserved. | |
14 * | |
15 * This library is free software; you can redistribute it and/or | |
16 * modify it under the terms of the GNU Library General Public | |
17 * License as published by the Free Software Foundation; either | |
18 * version 2 of the License, or (at your option) any later version. | |
19 * | |
20 * This library is distributed in the hope that it will be useful, | |
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
23 * Library General Public License for more details. | |
24 * | |
25 * You should have received a copy of the GNU Library General Public License | |
26 * along with this library; see the file COPYING.LIB. If not, write to | |
27 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
28 * Boston, MA 02110-1301, USA. | |
29 */ | |
30 | |
31 #include "config.h" | |
32 #include "WebKitAccessibleInterfaceSelection.h" | |
33 | |
34 #if HAVE(ACCESSIBILITY) | |
35 | |
36 #include "AccessibilityListBox.h" | |
37 #include "AccessibilityObject.h" | |
38 #include "HTMLSelectElement.h" | |
39 #include "RenderObject.h" | |
40 #include "WebKitAccessibleWrapperAtk.h" | |
41 | |
42 using namespace WebCore; | |
43 | |
44 static AccessibilityObject* core(AtkSelection* selection) | |
45 { | |
46 if (!WEBKIT_IS_ACCESSIBLE(selection)) | |
47 return 0; | |
48 | |
49 return webkitAccessibleGetAccessibilityObject(WEBKIT_ACCESSIBLE(selection)); | |
50 } | |
51 | |
52 static AccessibilityObject* listObjectForSelection(AtkSelection* selection) | |
53 { | |
54 AccessibilityObject* coreSelection = core(selection); | |
55 | |
56 // Only list boxes and menu lists supported so far. | |
57 if (!coreSelection->isListBox() && !coreSelection->isMenuList()) | |
58 return 0; | |
59 | |
60 // For list boxes the list object is just itself. | |
61 if (coreSelection->isListBox()) | |
62 return coreSelection; | |
63 | |
64 // For menu lists we need to return the first accessible child, | |
65 // with role MenuListPopupRole, since that's the one holding the list | |
66 // of items with role MenuListOptionRole. | |
67 AccessibilityObject::AccessibilityChildrenVector children = coreSelection->c
hildren(); | |
68 if (!children.size()) | |
69 return 0; | |
70 | |
71 AccessibilityObject* listObject = children.at(0).get(); | |
72 if (!listObject->isMenuListPopup()) | |
73 return 0; | |
74 | |
75 return listObject; | |
76 } | |
77 | |
78 static AccessibilityObject* optionFromList(AtkSelection* selection, gint index) | |
79 { | |
80 AccessibilityObject* coreSelection = core(selection); | |
81 if (!coreSelection || index < 0) | |
82 return 0; | |
83 | |
84 // Need to select the proper list object depending on the type. | |
85 AccessibilityObject* listObject = listObjectForSelection(selection); | |
86 if (!listObject) | |
87 return 0; | |
88 | |
89 AccessibilityObject::AccessibilityChildrenVector options = listObject->child
ren(); | |
90 if (index < static_cast<gint>(options.size())) | |
91 return options.at(index).get(); | |
92 | |
93 return 0; | |
94 } | |
95 | |
96 static AccessibilityObject* optionFromSelection(AtkSelection* selection, gint in
dex) | |
97 { | |
98 // i is the ith selection as opposed to the ith child. | |
99 | |
100 AccessibilityObject* coreSelection = core(selection); | |
101 if (!coreSelection || !coreSelection->isAccessibilityRenderObject() || index
< 0) | |
102 return 0; | |
103 | |
104 AccessibilityObject::AccessibilityChildrenVector selectedItems; | |
105 if (coreSelection->isListBox()) | |
106 coreSelection->selectedChildren(selectedItems); | |
107 else if (coreSelection->isMenuList()) { | |
108 RenderObject* renderer = coreSelection->renderer(); | |
109 if (!renderer) | |
110 return 0; | |
111 | |
112 HTMLSelectElement* selectNode = toHTMLSelectElement(renderer->node()); | |
113 int selectedIndex = selectNode->selectedIndex(); | |
114 const Vector<HTMLElement*> listItems = selectNode->listItems(); | |
115 | |
116 if (selectedIndex < 0 || selectedIndex >= static_cast<int>(listItems.siz
e())) | |
117 return 0; | |
118 | |
119 return optionFromList(selection, selectedIndex); | |
120 } | |
121 | |
122 if (index < static_cast<gint>(selectedItems.size())) | |
123 return selectedItems.at(index).get(); | |
124 | |
125 return 0; | |
126 } | |
127 | |
128 static gboolean webkitAccessibleSelectionAddSelection(AtkSelection* selection, g
int index) | |
129 { | |
130 AccessibilityObject* coreSelection = core(selection); | |
131 if (!coreSelection) | |
132 return FALSE; | |
133 | |
134 AccessibilityObject* option = optionFromList(selection, index); | |
135 if (option && (coreSelection->isListBox() || coreSelection->isMenuList())) { | |
136 option->setSelected(true); | |
137 return option->isSelected(); | |
138 } | |
139 | |
140 return FALSE; | |
141 } | |
142 | |
143 static gboolean webkitAccessibleSelectionClearSelection(AtkSelection* selection) | |
144 { | |
145 AccessibilityObject* coreSelection = core(selection); | |
146 if (!coreSelection) | |
147 return FALSE; | |
148 | |
149 AccessibilityObject::AccessibilityChildrenVector selectedItems; | |
150 if (coreSelection->isListBox() || coreSelection->isMenuList()) { | |
151 // Set the list of selected items to an empty list; then verify that it
worked. | |
152 AccessibilityListBox* listBox = static_cast<AccessibilityListBox*>(coreS
election); | |
153 listBox->setSelectedChildren(selectedItems); | |
154 listBox->selectedChildren(selectedItems); | |
155 return !selectedItems.size(); | |
156 } | |
157 return FALSE; | |
158 } | |
159 | |
160 static AtkObject* webkitAccessibleSelectionRefSelection(AtkSelection* selection,
gint index) | |
161 { | |
162 AccessibilityObject* option = optionFromSelection(selection, index); | |
163 if (option) { | |
164 AtkObject* child = option->wrapper(); | |
165 g_object_ref(child); | |
166 return child; | |
167 } | |
168 | |
169 return 0; | |
170 } | |
171 | |
172 static gint webkitAccessibleSelectionGetSelectionCount(AtkSelection* selection) | |
173 { | |
174 AccessibilityObject* coreSelection = core(selection); | |
175 if (!coreSelection || !coreSelection->isAccessibilityRenderObject()) | |
176 return 0; | |
177 | |
178 if (coreSelection->isListBox()) { | |
179 AccessibilityObject::AccessibilityChildrenVector selectedItems; | |
180 coreSelection->selectedChildren(selectedItems); | |
181 return static_cast<gint>(selectedItems.size()); | |
182 } | |
183 | |
184 if (coreSelection->isMenuList()) { | |
185 RenderObject* renderer = coreSelection->renderer(); | |
186 if (!renderer) | |
187 return 0; | |
188 | |
189 int selectedIndex = toHTMLSelectElement(renderer->node())->selectedIndex
(); | |
190 return selectedIndex >= 0 && selectedIndex < static_cast<int>(toHTMLSele
ctElement(renderer->node())->listItems().size()); | |
191 } | |
192 | |
193 return 0; | |
194 } | |
195 | |
196 static gboolean webkitAccessibleSelectionIsChildSelected(AtkSelection* selection
, gint index) | |
197 { | |
198 AccessibilityObject* coreSelection = core(selection); | |
199 if (!coreSelection) | |
200 return 0; | |
201 | |
202 AccessibilityObject* option = optionFromList(selection, index); | |
203 if (option && (coreSelection->isListBox() || coreSelection->isMenuList())) | |
204 return option->isSelected(); | |
205 | |
206 return FALSE; | |
207 } | |
208 | |
209 static gboolean webkitAccessibleSelectionRemoveSelection(AtkSelection* selection
, gint index) | |
210 { | |
211 AccessibilityObject* coreSelection = core(selection); | |
212 if (!coreSelection) | |
213 return 0; | |
214 | |
215 // TODO: This is only getting called if i == 0. What is preventing the rest? | |
216 AccessibilityObject* option = optionFromSelection(selection, index); | |
217 if (option && (coreSelection->isListBox() || coreSelection->isMenuList())) { | |
218 option->setSelected(false); | |
219 return !option->isSelected(); | |
220 } | |
221 | |
222 return FALSE; | |
223 } | |
224 | |
225 static gboolean webkitAccessibleSelectionSelectAllSelection(AtkSelection* select
ion) | |
226 { | |
227 AccessibilityObject* coreSelection = core(selection); | |
228 if (!coreSelection || !coreSelection->isMultiSelectable()) | |
229 return FALSE; | |
230 | |
231 AccessibilityObject::AccessibilityChildrenVector children = coreSelection->c
hildren(); | |
232 if (coreSelection->isListBox()) { | |
233 AccessibilityListBox* listBox = static_cast<AccessibilityListBox*>(coreS
election); | |
234 listBox->setSelectedChildren(children); | |
235 AccessibilityObject::AccessibilityChildrenVector selectedItems; | |
236 listBox->selectedChildren(selectedItems); | |
237 return selectedItems.size() == children.size(); | |
238 } | |
239 | |
240 return FALSE; | |
241 } | |
242 | |
243 void webkitAccessibleSelectionInterfaceInit(AtkSelectionIface* iface) | |
244 { | |
245 iface->add_selection = webkitAccessibleSelectionAddSelection; | |
246 iface->clear_selection = webkitAccessibleSelectionClearSelection; | |
247 iface->ref_selection = webkitAccessibleSelectionRefSelection; | |
248 iface->get_selection_count = webkitAccessibleSelectionGetSelectionCount; | |
249 iface->is_child_selected = webkitAccessibleSelectionIsChildSelected; | |
250 iface->remove_selection = webkitAccessibleSelectionRemoveSelection; | |
251 iface->select_all_selection = webkitAccessibleSelectionSelectAllSelection; | |
252 } | |
253 | |
254 #endif | |
OLD | NEW |