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 "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 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 
    324 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 
    353 bool WebAccessibilityObject::performDefaultAction() const
    354 {
    355     if (!m_private)
    356         return false;
    357 
    358     m_private->updateBackingStore();
    359     return m_private->performDefaultAction();
    360 }
    361 
    362 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 
    371 WebString WebAccessibilityObject::stringValue() const
    372 {
    373     if (!m_private)
    374         return WebString();
    375 
    376     m_private->updateBackingStore();
    377     return m_private->stringValue();
    378 }
    379 
    380 WebString WebAccessibilityObject::title() const
    381 {
    382     if (!m_private)
    383         return WebString();
    384 
    385     m_private->updateBackingStore();
    386     return m_private->title();
    387 }
    388 
    389 WebAccessibilityObject::WebAccessibilityObject(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
    390     : m_private(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef()))
    391 {
    392 }
    393 
    394 WebAccessibilityObject& WebAccessibilityObject::operator=(const WTF::PassRefPtr<WebCore::AccessibilityObject>& object)
    395 {
    396     assign(static_cast<WebAccessibilityObjectPrivate*>(object.releaseRef()));
    397     return *this;
    398 }
    399 
    400 WebAccessibilityObject::operator WTF::PassRefPtr<WebCore::AccessibilityObject>() const
    401 {
    402     return PassRefPtr<WebCore::AccessibilityObject>(const_cast<WebAccessibilityObjectPrivate*>(m_private));
    403 }
    404 
    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