2010-11-23 Sheriff Bot <webkit.review.bot@gmail.com>
[WebKit-https.git] / WebKit / chromium / src / WebAccessibilityObject.cpp
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 "CSSPrimitiveValueMappings.h"
36 #include "Document.h"
37 #include "EventHandler.h"
38 #include "FrameView.h"
39 #include "Node.h"
40 #include "PlatformKeyboardEvent.h"
41 #include "RenderStyle.h"
42 #include "WebDocument.h"
43 #include "WebNode.h"
44 #include "WebPoint.h"
45 #include "WebRect.h"
46 #include "WebString.h"
47
48 using namespace WebCore;
49
50 namespace WebKit {
51
52 class WebAccessibilityObjectPrivate : public WebCore::AccessibilityObject {
53 };
54
55 void WebAccessibilityObject::reset()
56 {
57     assign(0);
58 }
59
60 void WebAccessibilityObject::assign(const WebKit::WebAccessibilityObject& other)
61 {
62     WebAccessibilityObjectPrivate* p = const_cast<WebAccessibilityObjectPrivate*>(other.m_private);
63     if (p)
64         p->ref();
65     assign(p);
66 }
67
68 WebString WebAccessibilityObject::accessibilityDescription() const
69 {
70     if (!m_private)
71         return WebString();
72
73     m_private->updateBackingStore();
74     return m_private->accessibilityDescription();
75 }
76
77 WebString WebAccessibilityObject::actionVerb() const
78 {
79     if (!m_private)
80         return WebString();
81
82     m_private->updateBackingStore();
83     return m_private->actionVerb();
84 }
85
86 bool WebAccessibilityObject::canSetFocusAttribute() const
87 {
88     if (!m_private)
89         return false;
90
91     m_private->updateBackingStore();
92     return m_private->canSetFocusAttribute();
93 }
94
95 bool WebAccessibilityObject::canSetValueAttribute() const
96 {
97     if (!m_private)
98         return false;
99
100     m_private->updateBackingStore();
101     return m_private->canSetValueAttribute();
102 }
103
104 bool WebAccessibilityObject::isValid() const
105 {
106     if (!m_private)
107         return false;
108
109     m_private->updateBackingStore();
110     return m_private->axObjectID();
111 }
112
113 unsigned WebAccessibilityObject::childCount() const
114 {
115     if (!m_private)
116         return 0;
117
118     m_private->updateBackingStore();
119     return m_private->children().size();
120 }
121
122 WebAccessibilityObject WebAccessibilityObject::childAt(unsigned index) const
123 {
124     if (!m_private)
125         return WebAccessibilityObject();
126
127     m_private->updateBackingStore();
128     if (m_private->children().size() <= index)
129         return WebAccessibilityObject();
130
131     return WebAccessibilityObject(m_private->children()[index]);
132 }
133
134 WebAccessibilityObject WebAccessibilityObject::firstChild() const
135 {
136     if (!m_private)
137         return WebAccessibilityObject();
138
139     m_private->updateBackingStore();
140     return WebAccessibilityObject(m_private->firstChild());
141 }
142
143 WebAccessibilityObject WebAccessibilityObject::focusedChild() const
144 {
145     if (!m_private)
146         return WebAccessibilityObject();
147
148     m_private->updateBackingStore();
149     RefPtr<AccessibilityObject> focused = m_private->focusedUIElement();
150     if (m_private == focused.get() || focused->parentObject() == m_private)
151         return WebAccessibilityObject(focused);
152
153     return WebAccessibilityObject();
154 }
155
156 WebAccessibilityObject WebAccessibilityObject::lastChild() const
157 {
158     if (!m_private)
159         return WebAccessibilityObject();
160
161     m_private->updateBackingStore();
162     return WebAccessibilityObject(m_private->lastChild());
163 }
164
165
166 WebAccessibilityObject WebAccessibilityObject::nextSibling() const
167 {
168     if (!m_private)
169         return WebAccessibilityObject();
170
171     m_private->updateBackingStore();
172     return WebAccessibilityObject(m_private->nextSibling());
173 }
174
175 WebAccessibilityObject WebAccessibilityObject::parentObject() const
176 {
177     if (!m_private)
178         return WebAccessibilityObject();
179
180     m_private->updateBackingStore();
181     return WebAccessibilityObject(m_private->parentObject());
182 }
183
184
185 WebAccessibilityObject WebAccessibilityObject::previousSibling() const
186 {
187     if (!m_private)
188         return WebAccessibilityObject();
189
190     m_private->updateBackingStore();
191     return WebAccessibilityObject(m_private->previousSibling());
192 }
193
194 bool WebAccessibilityObject::canSetSelectedAttribute() const
195 {
196     if (!m_private)
197         return 0;
198
199     m_private->updateBackingStore();
200     return m_private->canSetSelectedAttribute();
201 }
202
203 bool WebAccessibilityObject::isAnchor() const
204 {
205     if (!m_private)
206         return 0;
207
208     m_private->updateBackingStore();
209     return m_private->isAnchor();
210 }
211
212 bool WebAccessibilityObject::isChecked() const
213 {
214     if (!m_private)
215         return 0;
216
217     m_private->updateBackingStore();
218     return m_private->isChecked();
219 }
220
221 bool WebAccessibilityObject::isCollapsed() const
222 {
223     if (!m_private)
224         return 0;
225
226     m_private->updateBackingStore();
227     return m_private->isCollapsed();
228 }
229
230
231 bool WebAccessibilityObject::isFocused() const
232 {
233     if (!m_private)
234         return 0;
235
236     m_private->updateBackingStore();
237     return m_private->isFocused();
238 }
239
240 bool WebAccessibilityObject::isEnabled() const
241 {
242     if (!m_private)
243         return 0;
244
245     m_private->updateBackingStore();
246     return m_private->isEnabled();
247 }
248
249 bool WebAccessibilityObject::isHovered() const
250 {
251     if (!m_private)
252         return 0;
253
254     m_private->updateBackingStore();
255     return m_private->isHovered();
256 }
257
258 bool WebAccessibilityObject::isIndeterminate() const
259 {
260     if (!m_private)
261         return 0;
262
263     m_private->updateBackingStore();
264     return m_private->isIndeterminate();
265 }
266
267 bool WebAccessibilityObject::isLinked() const
268 {
269     if (!m_private)
270         return 0;
271
272     m_private->updateBackingStore();
273     return m_private->isLinked();
274 }
275
276 bool WebAccessibilityObject::isMultiSelectable() const
277 {
278     if (!m_private)
279         return 0;
280
281     m_private->updateBackingStore();
282     return m_private->isMultiSelectable();
283 }
284
285 bool WebAccessibilityObject::isOffScreen() const
286 {
287     if (!m_private)
288         return 0;
289
290     m_private->updateBackingStore();
291     return m_private->isOffScreen();
292 }
293
294 bool WebAccessibilityObject::isPasswordField() const
295 {
296     if (!m_private)
297         return 0;
298
299     m_private->updateBackingStore();
300     return m_private->isPasswordField();
301 }
302
303 bool WebAccessibilityObject::isPressed() const
304 {
305     if (!m_private)
306         return 0;
307
308     m_private->updateBackingStore();
309     return m_private->isPressed();
310 }
311
312 bool WebAccessibilityObject::isReadOnly() const
313 {
314     if (!m_private)
315         return 0;
316
317     m_private->updateBackingStore();
318     return m_private->isReadOnly();
319 }
320
321 bool WebAccessibilityObject::isSelected() const
322 {
323     if (!m_private)
324         return 0;
325
326     m_private->updateBackingStore();
327     return m_private->isSelected();
328 }
329
330 bool WebAccessibilityObject::isVisible() const
331 {
332     if (!m_private)
333         return 0;
334
335     m_private->updateBackingStore();
336     return m_private->isVisible();
337 }
338
339 bool WebAccessibilityObject::isVisited() const
340 {
341     if (!m_private)
342         return 0;
343
344     m_private->updateBackingStore();
345     return m_private->isVisited();
346 }
347
348 WebRect WebAccessibilityObject::boundingBoxRect() const
349 {
350     if (!m_private)
351         return WebRect();
352
353     m_private->updateBackingStore();
354     return m_private->boundingBoxRect();
355 }
356
357 WebString WebAccessibilityObject::helpText() const
358 {
359     if (!m_private)
360         return WebString();
361
362     m_private->updateBackingStore();
363     return m_private->helpText();
364 }
365
366 int WebAccessibilityObject::headingLevel() const
367 {
368     if (!m_private)
369         return 0;
370
371     m_private->updateBackingStore();
372     return m_private->headingLevel();
373 }
374
375 WebAccessibilityObject WebAccessibilityObject::hitTest(const WebPoint& point) const
376 {
377     if (!m_private)
378         return WebAccessibilityObject();
379
380     m_private->updateBackingStore();
381     IntPoint contentsPoint = m_private->documentFrameView()->windowToContents(point);
382     RefPtr<AccessibilityObject> hit = m_private->doAccessibilityHitTest(contentsPoint);
383
384     if (hit.get())
385         return WebAccessibilityObject(hit);
386
387     if (m_private->boundingBoxRect().contains(contentsPoint))
388         return *this;
389
390     return WebAccessibilityObject();
391 }
392
393 WebString WebAccessibilityObject::keyboardShortcut() const
394 {
395     if (!m_private)
396         return WebString();
397
398     m_private->updateBackingStore();
399     String accessKey = m_private->accessKey();
400     if (accessKey.isNull())
401         return WebString();
402
403     static String modifierString;
404     if (modifierString.isNull()) {
405         unsigned modifiers = EventHandler::accessKeyModifiers();
406         // Follow the same order as Mozilla MSAA implementation:
407         // Ctrl+Alt+Shift+Meta+key. MSDN states that keyboard shortcut strings
408         // should not be localized and defines the separator as "+".
409         if (modifiers & PlatformKeyboardEvent::CtrlKey)
410             modifierString += "Ctrl+";
411         if (modifiers & PlatformKeyboardEvent::AltKey)
412             modifierString += "Alt+";
413         if (modifiers & PlatformKeyboardEvent::ShiftKey)
414             modifierString += "Shift+";
415         if (modifiers & PlatformKeyboardEvent::MetaKey)
416             modifierString += "Win+";
417     }
418
419     return modifierString + accessKey;
420 }
421
422 bool WebAccessibilityObject::performDefaultAction() const
423 {
424     if (!m_private)
425         return false;
426
427     m_private->updateBackingStore();
428     return m_private->performDefaultAction();
429 }
430
431 WebAccessibilityRole WebAccessibilityObject::roleValue() const
432 {
433     if (!m_private)
434         return WebKit::WebAccessibilityRoleUnknown;
435
436     m_private->updateBackingStore();
437     return static_cast<WebAccessibilityRole>(m_private->roleValue());
438 }
439
440 void WebAccessibilityObject::setFocused(bool on) const
441 {
442     if (m_private)
443         m_private->setFocused(on);
444 }
445
446 WebString WebAccessibilityObject::stringValue() const
447 {
448     if (!m_private)
449         return WebString();
450
451     m_private->updateBackingStore();
452     return m_private->stringValue();
453 }
454
455 WebString WebAccessibilityObject::title() const
456 {
457     if (!m_private)
458         return WebString();
459
460     m_private->updateBackingStore();
461     return m_private->title();
462 }
463
464
465 WebNode WebAccessibilityObject::node() const
466 {
467     if (!m_private)
468         return WebNode();
469
470     m_private->updateBackingStore();
471
472     Node* node = m_private->node();
473     if (!node)
474         return WebNode();
475
476     return WebNode(node);
477 }
478
479 WebDocument WebAccessibilityObject::document() const
480 {
481     if (!m_private)
482         return WebDocument();
483
484     m_private->updateBackingStore();
485
486     Document* document = m_private->document();
487     if (!document)
488         return WebDocument();
489
490     return WebDocument(document);
491 }
492
493 bool WebAccessibilityObject::hasComputedStyle() const
494 {
495     Document* document = m_private->document();
496     if (document)
497         document->updateStyleIfNeeded();
498
499     Node* node = m_private->node();
500     if (!node)
501         return false;
502
503     return node->computedStyle();
504 }
505
506 WebString WebAccessibilityObject::computedStyleDisplay() const
507 {
508     Document* document = m_private->document();
509     if (document)
510         document->updateStyleIfNeeded();
511
512     Node* node = m_private->node();
513     if (!node)
514         return WebString();
515
516     RenderStyle* renderStyle = node->computedStyle();
517     if (!renderStyle)
518         return WebString();
519
520     return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue());
521 }
522
523 WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
524     : m_private(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef()))
525 {
526 }
527
528 WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
529 {
530     assign(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef()));
531     return *this;
532 }
533
534 WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const
535 {
536     return PassRefPtr<WebCore::AccessibilityObject>(const_cast<WebAccessibilityObjectPrivate*>(m_private));
537 }
538
539 void WebAccessibilityObject::assign(WebAccessibilityObjectPrivate* p)
540 {
541     // p is already ref'd for us by the caller
542     if (m_private)
543         m_private->deref();
544     m_private = p;
545 }
546
547 } // namespace WebKit