Home | History | Annotate | Download | only in accessibility
      1 /*
      2  * Copyright (C) 2011 Apple 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
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "AccessibilityScrollView.h"
     28 
     29 #include "AXObjectCache.h"
     30 #include "AccessibilityScrollbar.h"
     31 #include "FrameView.h"
     32 #include "HTMLFrameOwnerElement.h"
     33 #include "RenderPart.h"
     34 #include "ScrollView.h"
     35 #include "Widget.h"
     36 
     37 namespace WebCore {
     38 
     39 AccessibilityScrollView::AccessibilityScrollView(ScrollView* view)
     40     : m_scrollView(view)
     41 {
     42 }
     43 
     44 PassRefPtr<AccessibilityScrollView> AccessibilityScrollView::create(ScrollView* view)
     45 {
     46     return adoptRef(new AccessibilityScrollView(view));
     47 }
     48 
     49 AccessibilityObject* AccessibilityScrollView::scrollBar(AccessibilityOrientation orientation) const
     50 {
     51     switch (orientation) {
     52     case AccessibilityOrientationVertical:
     53         return m_verticalScrollbar ? m_verticalScrollbar.get() : 0;
     54     case AccessibilityOrientationHorizontal:
     55         return m_horizontalScrollbar ? m_horizontalScrollbar.get() : 0;
     56     }
     57 
     58     return 0;
     59 }
     60 
     61 const AccessibilityObject::AccessibilityChildrenVector& AccessibilityScrollView::children()
     62 {
     63     if (!m_haveChildren)
     64         addChildren();
     65     return m_children;
     66 }
     67 
     68 // If this is WebKit1 then the native scroll view needs to return the
     69 // AX information (because there are no scroll bar children in the ScrollView object in WK1).
     70 // In WebKit2, the ScrollView object will return the AX information (because there are no platform widgets).
     71 bool AccessibilityScrollView::isAttachment() const
     72 {
     73     return m_scrollView->platformWidget();
     74 }
     75 
     76 Widget* AccessibilityScrollView::widgetForAttachmentView() const
     77 {
     78     return m_scrollView.get();
     79 }
     80 
     81 void AccessibilityScrollView::updateChildrenIfNecessary()
     82 {
     83     if (m_scrollView->horizontalScrollbar() && !m_horizontalScrollbar)
     84         m_horizontalScrollbar = addChildScrollbar(m_scrollView->horizontalScrollbar());
     85     else if (!m_scrollView->horizontalScrollbar() && m_horizontalScrollbar) {
     86         removeChildScrollbar(m_horizontalScrollbar.get());
     87         m_horizontalScrollbar = 0;
     88     }
     89 
     90     if (m_scrollView->verticalScrollbar() && !m_verticalScrollbar)
     91         m_verticalScrollbar = addChildScrollbar(m_scrollView->verticalScrollbar());
     92     else if (!m_scrollView->verticalScrollbar() && m_verticalScrollbar) {
     93         removeChildScrollbar(m_verticalScrollbar.get());
     94         m_verticalScrollbar = 0;
     95     }
     96 }
     97 
     98 void AccessibilityScrollView::removeChildScrollbar(AccessibilityObject* scrollbar)
     99 {
    100     size_t pos = m_children.find(scrollbar);
    101     if (pos != WTF::notFound)
    102         m_children.remove(pos);
    103 }
    104 
    105 AccessibilityScrollbar* AccessibilityScrollView::addChildScrollbar(Scrollbar* scrollbar)
    106 {
    107     if (!scrollbar)
    108         return 0;
    109 
    110     AccessibilityScrollbar* scrollBarObject = static_cast<AccessibilityScrollbar*>(axObjectCache()->getOrCreate(scrollbar));
    111     scrollBarObject->setParent(this);
    112     m_children.append(scrollBarObject);
    113     return scrollBarObject;
    114 }
    115 
    116 void AccessibilityScrollView::addChildren()
    117 {
    118     ASSERT(!m_haveChildren);
    119     m_haveChildren = true;
    120 
    121     AccessibilityObject* webArea = webAreaObject();
    122     if (webArea)
    123         m_children.append(webArea);
    124 
    125     updateChildrenIfNecessary();
    126 }
    127 
    128 AccessibilityObject* AccessibilityScrollView::webAreaObject() const
    129 {
    130     if (!m_scrollView->isFrameView())
    131         return 0;
    132 
    133     Document* doc = static_cast<FrameView*>(m_scrollView.get())->frame()->document();
    134     if (!doc || !doc->renderer())
    135         return 0;
    136 
    137     return axObjectCache()->getOrCreate(doc->renderer());
    138 }
    139 
    140 AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const IntPoint& point) const
    141 {
    142     AccessibilityObject* webArea = webAreaObject();
    143     if (!webArea)
    144         return 0;
    145 
    146     if (m_horizontalScrollbar && m_horizontalScrollbar->elementRect().contains(point))
    147         return m_horizontalScrollbar.get();
    148     if (m_verticalScrollbar && m_verticalScrollbar->elementRect().contains(point))
    149         return m_verticalScrollbar.get();
    150 
    151     return webArea->accessibilityHitTest(point);
    152 }
    153 
    154 IntRect AccessibilityScrollView::elementRect() const
    155 {
    156     return m_scrollView->frameRect();
    157 }
    158 
    159 FrameView* AccessibilityScrollView::documentFrameView() const
    160 {
    161     if (!m_scrollView->isFrameView())
    162         return 0;
    163 
    164     return static_cast<FrameView*>(m_scrollView.get());
    165 }
    166 
    167 AccessibilityObject* AccessibilityScrollView::parentObject() const
    168 {
    169     if (!m_scrollView->isFrameView())
    170         return 0;
    171 
    172     HTMLFrameOwnerElement* owner = static_cast<FrameView*>(m_scrollView.get())->frame()->ownerElement();
    173     if (owner && owner->renderPart())
    174         return axObjectCache()->getOrCreate(owner->renderPart()->parent());
    175 
    176     return 0;
    177 }
    178 
    179 } // namespace WebCore
    180