|
1 /* |
|
2 * Copyright (C) 2009 Google Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions are |
|
6 * met: |
|
7 * |
|
8 * * Redistributions of source code must retain the above copyright |
|
9 * notice, this list of conditions and the following disclaimer. |
|
10 * * Redistributions in binary form must reproduce the above |
|
11 * copyright notice, this list of conditions and the following disclaimer |
|
12 * in the documentation and/or other materials provided with the |
|
13 * distribution. |
|
14 * * Neither the name of Google Inc. nor the names of its |
|
15 * contributors may be used to endorse or promote products derived from |
|
16 * this software without specific prior written permission. |
|
17 * |
|
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
29 */ |
|
30 |
|
31 #include "config.h" |
|
32 #include "WebAccessibilityObject.h" |
|
33 |
|
34 #include "AccessibilityObject.h" |
|
35 #include "EventHandler.h" |
|
36 #include "FrameView.h" |
|
37 #include "PlatformKeyboardEvent.h" |
|
38 #include "WebPoint.h" |
|
39 #include "WebRect.h" |
|
40 #include "WebString.h" |
|
41 |
|
42 using namespace WebCore; |
|
43 |
|
44 namespace WebKit { |
|
45 |
|
46 class WebAccessibilityObjectPrivate : public WebCore::AccessibilityObject { |
|
47 }; |
|
48 |
|
49 void WebAccessibilityObject::reset() |
|
50 { |
|
51 assign(0); |
|
52 } |
|
53 |
|
54 void WebAccessibilityObject::assign(const WebKit::WebAccessibilityObject& other) |
|
55 { |
|
56 WebAccessibilityObjectPrivate* p = const_cast<WebAccessibilityObjectPrivate*>(other.m_private); |
|
57 if (p) |
|
58 p->ref(); |
|
59 assign(p); |
|
60 } |
|
61 |
|
62 WebString WebAccessibilityObject::accessibilityDescription() const |
|
63 { |
|
64 if (!m_private) |
|
65 return WebString(); |
|
66 |
|
67 m_private->updateBackingStore(); |
|
68 return m_private->accessibilityDescription(); |
|
69 } |
|
70 |
|
71 WebString WebAccessibilityObject::actionVerb() const |
|
72 { |
|
73 if (!m_private) |
|
74 return WebString(); |
|
75 |
|
76 m_private->updateBackingStore(); |
|
77 return m_private->actionVerb(); |
|
78 } |
|
79 |
|
80 bool WebAccessibilityObject::canSetFocusAttribute() const |
|
81 { |
|
82 if (!m_private) |
|
83 return false; |
|
84 |
|
85 m_private->updateBackingStore(); |
|
86 return m_private->canSetFocusAttribute(); |
|
87 } |
|
88 |
|
89 bool WebAccessibilityObject::canSetValueAttribute() const |
|
90 { |
|
91 if (!m_private) |
|
92 return false; |
|
93 |
|
94 m_private->updateBackingStore(); |
|
95 return m_private->canSetValueAttribute(); |
|
96 } |
|
97 |
|
98 unsigned WebAccessibilityObject::childCount() const |
|
99 { |
|
100 if (!m_private) |
|
101 return 0; |
|
102 |
|
103 m_private->updateBackingStore(); |
|
104 return m_private->children().size(); |
|
105 } |
|
106 |
|
107 WebAccessibilityObject WebAccessibilityObject::childAt(unsigned index) const |
|
108 { |
|
109 if (!m_private) |
|
110 return WebAccessibilityObject(); |
|
111 |
|
112 m_private->updateBackingStore(); |
|
113 if (m_private->children().size() <= index) |
|
114 return WebAccessibilityObject(); |
|
115 |
|
116 return WebAccessibilityObject(m_private->children()[index]); |
|
117 } |
|
118 |
|
119 WebAccessibilityObject WebAccessibilityObject::firstChild() const |
|
120 { |
|
121 if (!m_private) |
|
122 return WebAccessibilityObject(); |
|
123 |
|
124 m_private->updateBackingStore(); |
|
125 return WebAccessibilityObject(m_private->firstChild()); |
|
126 } |
|
127 |
|
128 WebAccessibilityObject WebAccessibilityObject::focusedChild() const |
|
129 { |
|
130 if (!m_private) |
|
131 return WebAccessibilityObject(); |
|
132 |
|
133 m_private->updateBackingStore(); |
|
134 RefPtr<AccessibilityObject> focused = m_private->focusedUIElement(); |
|
135 if (m_private == focused.get() || focused->parentObject() == m_private) |
|
136 return WebAccessibilityObject(focused); |
|
137 |
|
138 return WebAccessibilityObject(); |
|
139 } |
|
140 |
|
141 WebAccessibilityObject WebAccessibilityObject::lastChild() const |
|
142 { |
|
143 if (!m_private) |
|
144 return WebAccessibilityObject(); |
|
145 |
|
146 m_private->updateBackingStore(); |
|
147 return WebAccessibilityObject(m_private->lastChild()); |
|
148 } |
|
149 |
|
150 |
|
151 WebAccessibilityObject WebAccessibilityObject::nextSibling() const |
|
152 { |
|
153 if (!m_private) |
|
154 return WebAccessibilityObject(); |
|
155 |
|
156 m_private->updateBackingStore(); |
|
157 return WebAccessibilityObject(m_private->nextSibling()); |
|
158 } |
|
159 |
|
160 WebAccessibilityObject WebAccessibilityObject::parentObject() const |
|
161 { |
|
162 if (!m_private) |
|
163 return WebAccessibilityObject(); |
|
164 |
|
165 m_private->updateBackingStore(); |
|
166 return WebAccessibilityObject(m_private->parentObject()); |
|
167 } |
|
168 |
|
169 |
|
170 WebAccessibilityObject WebAccessibilityObject::previousSibling() const |
|
171 { |
|
172 if (!m_private) |
|
173 return WebAccessibilityObject(); |
|
174 |
|
175 m_private->updateBackingStore(); |
|
176 return WebAccessibilityObject(m_private->previousSibling()); |
|
177 } |
|
178 |
|
179 bool WebAccessibilityObject::isAnchor() const |
|
180 { |
|
181 if (!m_private) |
|
182 return 0; |
|
183 |
|
184 m_private->updateBackingStore(); |
|
185 return m_private->isAnchor(); |
|
186 } |
|
187 |
|
188 bool WebAccessibilityObject::isChecked() const |
|
189 { |
|
190 if (!m_private) |
|
191 return 0; |
|
192 |
|
193 m_private->updateBackingStore(); |
|
194 return m_private->isChecked(); |
|
195 } |
|
196 |
|
197 |
|
198 bool WebAccessibilityObject::isFocused() const |
|
199 { |
|
200 if (!m_private) |
|
201 return 0; |
|
202 |
|
203 m_private->updateBackingStore(); |
|
204 return m_private->isFocused(); |
|
205 } |
|
206 |
|
207 bool WebAccessibilityObject::isEnabled() const |
|
208 { |
|
209 if (!m_private) |
|
210 return 0; |
|
211 |
|
212 m_private->updateBackingStore(); |
|
213 return m_private->isEnabled(); |
|
214 } |
|
215 |
|
216 bool WebAccessibilityObject::isHovered() const |
|
217 { |
|
218 if (!m_private) |
|
219 return 0; |
|
220 |
|
221 m_private->updateBackingStore(); |
|
222 return m_private->isHovered(); |
|
223 } |
|
224 |
|
225 bool WebAccessibilityObject::isIndeterminate() const |
|
226 { |
|
227 if (!m_private) |
|
228 return 0; |
|
229 |
|
230 m_private->updateBackingStore(); |
|
231 return m_private->isIndeterminate(); |
|
232 } |
|
233 |
|
234 bool WebAccessibilityObject::isMultiSelectable() const |
|
235 { |
|
236 if (!m_private) |
|
237 return 0; |
|
238 |
|
239 m_private->updateBackingStore(); |
|
240 return m_private->isMultiSelectable(); |
|
241 } |
|
242 |
|
243 bool WebAccessibilityObject::isOffScreen() const |
|
244 { |
|
245 if (!m_private) |
|
246 return 0; |
|
247 |
|
248 m_private->updateBackingStore(); |
|
249 return m_private->isOffScreen(); |
|
250 } |
|
251 |
|
252 bool WebAccessibilityObject::isPasswordField() const |
|
253 { |
|
254 if (!m_private) |
|
255 return 0; |
|
256 |
|
257 m_private->updateBackingStore(); |
|
258 return m_private->isPasswordField(); |
|
259 } |
|
260 |
|
261 bool WebAccessibilityObject::isPressed() const |
|
262 { |
|
263 if (!m_private) |
|
264 return 0; |
|
265 |
|
266 m_private->updateBackingStore(); |
|
267 return m_private->isPressed(); |
|
268 } |
|
269 |
|
270 bool WebAccessibilityObject::isReadOnly() const |
|
271 { |
|
272 if (!m_private) |
|
273 return 0; |
|
274 |
|
275 m_private->updateBackingStore(); |
|
276 return m_private->isReadOnly(); |
|
277 } |
|
278 |
|
279 bool WebAccessibilityObject::isVisited() const |
|
280 { |
|
281 if (!m_private) |
|
282 return 0; |
|
283 |
|
284 m_private->updateBackingStore(); |
|
285 return m_private->isVisited(); |
|
286 } |
|
287 |
|
288 WebRect WebAccessibilityObject::boundingBoxRect() const |
|
289 { |
|
290 if (!m_private) |
|
291 return WebRect(); |
|
292 |
|
293 m_private->updateBackingStore(); |
|
294 return m_private->documentFrameView()->contentsToWindow(m_private->boundingBoxRect()); |
|
295 } |
|
296 |
|
297 WebString WebAccessibilityObject::helpText() const |
|
298 { |
|
299 if (!m_private) |
|
300 return WebString(); |
|
301 |
|
302 m_private->updateBackingStore(); |
|
303 return m_private->helpText(); |
|
304 } |
|
305 |
|
306 int WebAccessibilityObject::headingLevel() const |
|
307 { |
|
308 if (!m_private) |
|
309 return 0; |
|
310 |
|
311 m_private->updateBackingStore(); |
|
312 return m_private->headingLevel(); |
|
313 } |
|
314 |
|
315 WebAccessibilityObject WebAccessibilityObject::hitTest(const WebPoint& point) const |
|
316 { |
|
317 if (!m_private) |
|
318 return WebAccessibilityObject(); |
|
319 |
|
320 m_private->updateBackingStore(); |
|
321 IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point); |
|
322 RefPtr<AccessibilityObject> hit = m_private->doAccessibilityHitTest(contentsPoint); |
|
323 |
|
324 if (hit.get()) |
|
325 return WebAccessibilityObject(hit); |
|
326 |
|
327 if (m_private->boundingBoxRect().contains(contentsPoint)) |
|
328 return *this; |
|
329 |
|
330 return WebAccessibilityObject(); |
|
331 } |
|
332 |
|
333 WebString WebAccessibilityObject::keyboardShortcut() const |
|
334 { |
|
335 if (!m_private) |
|
336 return WebString(); |
|
337 |
|
338 m_private->updateBackingStore(); |
|
339 String accessKey = m_private->accessKey(); |
|
340 if (accessKey.isNull()) |
|
341 return WebString(); |
|
342 |
|
343 static String modifierString; |
|
344 if (modifierString.isNull()) { |
|
345 unsigned modifiers = EventHandler::accessKeyModifiers(); |
|
346 // Follow the same order as Mozilla MSAA implementation: |
|
347 // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings |
|
348 // should not be localized and defines the separator as "+". |
|
349 if (modifiers & PlatformKeyboardEvent::CtrlKey) |
|
350 modifierString += "Ctrl+"; |
|
351 if (modifiers & PlatformKeyboardEvent::AltKey) |
|
352 modifierString += "Alt+"; |
|
353 if (modifiers & PlatformKeyboardEvent::ShiftKey) |
|
354 modifierString += "Shift+"; |
|
355 if (modifiers & PlatformKeyboardEvent::MetaKey) |
|
356 modifierString += "Win+"; |
|
357 } |
|
358 |
|
359 return modifierString + accessKey; |
|
360 } |
|
361 |
|
362 bool WebAccessibilityObject::performDefaultAction() const |
|
363 { |
|
364 if (!m_private) |
|
365 return false; |
|
366 |
|
367 m_private->updateBackingStore(); |
|
368 return m_private->performDefaultAction(); |
|
369 } |
|
370 |
|
371 WebAccessibilityRole WebAccessibilityObject::roleValue() const |
|
372 { |
|
373 if (!m_private) |
|
374 return WebKit::WebAccessibilityRoleUnknown; |
|
375 |
|
376 m_private->updateBackingStore(); |
|
377 return static_cast<WebAccessibilityRole>(m_private->roleValue()); |
|
378 } |
|
379 |
|
380 void WebAccessibilityObject::setFocused(bool on) const |
|
381 { |
|
382 if (m_private) |
|
383 m_private->setFocused(on); |
|
384 } |
|
385 |
|
386 WebString WebAccessibilityObject::stringValue() const |
|
387 { |
|
388 if (!m_private) |
|
389 return WebString(); |
|
390 |
|
391 m_private->updateBackingStore(); |
|
392 return m_private->stringValue(); |
|
393 } |
|
394 |
|
395 WebString WebAccessibilityObject::title() const |
|
396 { |
|
397 if (!m_private) |
|
398 return WebString(); |
|
399 |
|
400 m_private->updateBackingStore(); |
|
401 return m_private->title(); |
|
402 } |
|
403 |
|
404 WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object) |
|
405 : m_private(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef())) |
|
406 { |
|
407 } |
|
408 |
|
409 WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object) |
|
410 { |
|
411 assign(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef())); |
|
412 return *this; |
|
413 } |
|
414 |
|
415 WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const |
|
416 { |
|
417 return PassRefPtr<WebCore::AccessibilityObject>(const_cast<WebAccessibilityObjectPrivate*>(m_private)); |
|
418 } |
|
419 |
|
420 void WebAccessibilityObject::assign(WebAccessibilityObjectPrivate* p) |
|
421 { |
|
422 // p is already ref'd for us by the caller |
|
423 if (m_private) |
|
424 m_private->deref(); |
|
425 m_private = p; |
|
426 } |
|
427 |
|
428 } // namespace WebKit |