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