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