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
reset()49 void WebAccessibilityObject::reset()
50 {
51 assign(0);
52 }
53
assign(const WebKit::WebAccessibilityObject & other)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
accessibilityDescription() const62 WebString WebAccessibilityObject::accessibilityDescription() const
63 {
64 if (!m_private)
65 return WebString();
66
67 m_private->updateBackingStore();
68 return m_private->accessibilityDescription();
69 }
70
actionVerb() const71 WebString WebAccessibilityObject::actionVerb() const
72 {
73 if (!m_private)
74 return WebString();
75
76 m_private->updateBackingStore();
77 return m_private->actionVerb();
78 }
79
canSetFocusAttribute() const80 bool WebAccessibilityObject::canSetFocusAttribute() const
81 {
82 if (!m_private)
83 return false;
84
85 m_private->updateBackingStore();
86 return m_private->canSetFocusAttribute();
87 }
88
canSetValueAttribute() const89 bool WebAccessibilityObject::canSetValueAttribute() const
90 {
91 if (!m_private)
92 return false;
93
94 m_private->updateBackingStore();
95 return m_private->canSetValueAttribute();
96 }
97
childCount() const98 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
childAt(unsigned index) const107 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
firstChild() const119 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
focusedChild() const128 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
lastChild() const141 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
nextSibling() const151 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
parentObject() const160 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
previousSibling() const170 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
isAnchor() const179 bool WebAccessibilityObject::isAnchor() const
180 {
181 if (!m_private)
182 return 0;
183
184 m_private->updateBackingStore();
185 return m_private->isAnchor();
186 }
187
isChecked() const188 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
isFocused() const198 bool WebAccessibilityObject::isFocused() const
199 {
200 if (!m_private)
201 return 0;
202
203 m_private->updateBackingStore();
204 return m_private->isFocused();
205 }
206
isEnabled() const207 bool WebAccessibilityObject::isEnabled() const
208 {
209 if (!m_private)
210 return 0;
211
212 m_private->updateBackingStore();
213 return m_private->isEnabled();
214 }
215
isHovered() const216 bool WebAccessibilityObject::isHovered() const
217 {
218 if (!m_private)
219 return 0;
220
221 m_private->updateBackingStore();
222 return m_private->isHovered();
223 }
224
isIndeterminate() const225 bool WebAccessibilityObject::isIndeterminate() const
226 {
227 if (!m_private)
228 return 0;
229
230 m_private->updateBackingStore();
231 return m_private->isIndeterminate();
232 }
233
isMultiSelectable() const234 bool WebAccessibilityObject::isMultiSelectable() const
235 {
236 if (!m_private)
237 return 0;
238
239 m_private->updateBackingStore();
240 return m_private->isMultiSelectable();
241 }
242
isOffScreen() const243 bool WebAccessibilityObject::isOffScreen() const
244 {
245 if (!m_private)
246 return 0;
247
248 m_private->updateBackingStore();
249 return m_private->isOffScreen();
250 }
251
isPasswordField() const252 bool WebAccessibilityObject::isPasswordField() const
253 {
254 if (!m_private)
255 return 0;
256
257 m_private->updateBackingStore();
258 return m_private->isPasswordField();
259 }
260
isPressed() const261 bool WebAccessibilityObject::isPressed() const
262 {
263 if (!m_private)
264 return 0;
265
266 m_private->updateBackingStore();
267 return m_private->isPressed();
268 }
269
isReadOnly() const270 bool WebAccessibilityObject::isReadOnly() const
271 {
272 if (!m_private)
273 return 0;
274
275 m_private->updateBackingStore();
276 return m_private->isReadOnly();
277 }
278
isVisited() const279 bool WebAccessibilityObject::isVisited() const
280 {
281 if (!m_private)
282 return 0;
283
284 m_private->updateBackingStore();
285 return m_private->isVisited();
286 }
287
boundingBoxRect() const288 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
helpText() const297 WebString WebAccessibilityObject::helpText() const
298 {
299 if (!m_private)
300 return WebString();
301
302 m_private->updateBackingStore();
303 return m_private->helpText();
304 }
305
hitTest(const WebPoint & point) const306 WebAccessibilityObject WebAccessibilityObject::hitTest(const WebPoint& point) const
307 {
308 if (!m_private)
309 return WebAccessibilityObject();
310
311 m_private->updateBackingStore();
312 IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
313 RefPtr<AccessibilityObject> hit = m_private->doAccessibilityHitTest(contentsPoint);
314
315 if (hit.get())
316 return WebAccessibilityObject(hit);
317
318 if (m_private->boundingBoxRect().contains(contentsPoint))
319 return *this;
320
321 return WebAccessibilityObject();
322 }
323
keyboardShortcut() const324 WebString WebAccessibilityObject::keyboardShortcut() const
325 {
326 if (!m_private)
327 return WebString();
328
329 m_private->updateBackingStore();
330 String accessKey = m_private->accessKey();
331 if (accessKey.isNull())
332 return WebString();
333
334 static String modifierString;
335 if (modifierString.isNull()) {
336 unsigned modifiers = EventHandler::accessKeyModifiers();
337 // Follow the same order as Mozilla MSAA implementation:
338 // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
339 // should not be localized and defines the separator as "+".
340 if (modifiers & PlatformKeyboardEvent::CtrlKey)
341 modifierString += "Ctrl+";
342 if (modifiers & PlatformKeyboardEvent::AltKey)
343 modifierString += "Alt+";
344 if (modifiers & PlatformKeyboardEvent::ShiftKey)
345 modifierString += "Shift+";
346 if (modifiers & PlatformKeyboardEvent::MetaKey)
347 modifierString += "Win+";
348 }
349
350 return modifierString + accessKey;
351 }
352
performDefaultAction() const353 bool WebAccessibilityObject::performDefaultAction() const
354 {
355 if (!m_private)
356 return false;
357
358 m_private->updateBackingStore();
359 return m_private->performDefaultAction();
360 }
361
roleValue() const362 WebAccessibilityRole WebAccessibilityObject::roleValue() const
363 {
364 if (!m_private)
365 return WebKit::WebAccessibilityRoleUnknown;
366
367 m_private->updateBackingStore();
368 return static_cast<WebAccessibilityRole>(m_private->roleValue());
369 }
370
stringValue() const371 WebString WebAccessibilityObject::stringValue() const
372 {
373 if (!m_private)
374 return WebString();
375
376 m_private->updateBackingStore();
377 return m_private->stringValue();
378 }
379
title() const380 WebString WebAccessibilityObject::title() const
381 {
382 if (!m_private)
383 return WebString();
384
385 m_private->updateBackingStore();
386 return m_private->title();
387 }
388
WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject> & object)389 WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
390 : m_private(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef()))
391 {
392 }
393
operator =(const WTF::PassRefPtr<WebCore::AccessibilityObject> & object)394 WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
395 {
396 assign(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef()));
397 return *this;
398 }
399
operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const400 WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const
401 {
402 return PassRefPtr<WebCore::AccessibilityObject>(const_cast<WebAccessibilityObjectPrivate*>(m_private));
403 }
404
assign(WebAccessibilityObjectPrivate * p)405 void WebAccessibilityObject::assign(WebAccessibilityObjectPrivate* p)
406 {
407 // p is already ref'd for us by the caller
408 if (m_private)
409 m_private->deref();
410 m_private = p;
411 }
412
413 } // namespace WebKit
414