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 "Frame.h" 32#include "FrameView.h" 33#include "HTMLFrameOwnerElement.h" 34#include "RenderPart.h" 35#include "ScrollView.h" 36#include "Widget.h" 37 38namespace WebCore { 39 40AccessibilityScrollView::AccessibilityScrollView(ScrollView* view) 41 : m_scrollView(view) 42 , m_childrenDirty(false) 43{ 44} 45 46AccessibilityScrollView::~AccessibilityScrollView() 47{ 48 ASSERT(isDetached()); 49} 50 51void AccessibilityScrollView::detach() 52{ 53 AccessibilityObject::detach(); 54 m_scrollView = 0; 55} 56 57PassRefPtr<AccessibilityScrollView> AccessibilityScrollView::create(ScrollView* view) 58{ 59 return adoptRef(new AccessibilityScrollView(view)); 60} 61 62AccessibilityObject* AccessibilityScrollView::scrollBar(AccessibilityOrientation orientation) 63{ 64 updateScrollbars(); 65 66 switch (orientation) { 67 case AccessibilityOrientationVertical: 68 return m_verticalScrollbar ? m_verticalScrollbar.get() : 0; 69 case AccessibilityOrientationHorizontal: 70 return m_horizontalScrollbar ? m_horizontalScrollbar.get() : 0; 71 } 72 73 return 0; 74} 75 76// If this is WebKit1 then the native scroll view needs to return the 77// AX information (because there are no scroll bar children in the ScrollView object in WK1). 78// In WebKit2, the ScrollView object will return the AX information (because there are no platform widgets). 79bool AccessibilityScrollView::isAttachment() const 80{ 81 return m_scrollView && m_scrollView->platformWidget(); 82} 83 84Widget* AccessibilityScrollView::widgetForAttachmentView() const 85{ 86 return m_scrollView; 87} 88 89bool AccessibilityScrollView::canSetFocusAttribute() const 90{ 91 AccessibilityObject* webArea = webAreaObject(); 92 return webArea && webArea->canSetFocusAttribute(); 93} 94 95bool AccessibilityScrollView::isFocused() const 96{ 97 AccessibilityObject* webArea = webAreaObject(); 98 return webArea && webArea->isFocused(); 99} 100 101void AccessibilityScrollView::setFocused(bool focused) 102{ 103 if (AccessibilityObject* webArea = webAreaObject()) 104 webArea->setFocused(focused); 105} 106 107void AccessibilityScrollView::updateChildrenIfNecessary() 108{ 109 if (m_childrenDirty) 110 clearChildren(); 111 112 if (!m_haveChildren) 113 addChildren(); 114 115 updateScrollbars(); 116} 117 118void AccessibilityScrollView::updateScrollbars() 119{ 120 if (!m_scrollView) 121 return; 122 123 if (m_scrollView->horizontalScrollbar() && !m_horizontalScrollbar) 124 m_horizontalScrollbar = addChildScrollbar(m_scrollView->horizontalScrollbar()); 125 else if (!m_scrollView->horizontalScrollbar() && m_horizontalScrollbar) { 126 removeChildScrollbar(m_horizontalScrollbar.get()); 127 m_horizontalScrollbar = 0; 128 } 129 130 if (m_scrollView->verticalScrollbar() && !m_verticalScrollbar) 131 m_verticalScrollbar = addChildScrollbar(m_scrollView->verticalScrollbar()); 132 else if (!m_scrollView->verticalScrollbar() && m_verticalScrollbar) { 133 removeChildScrollbar(m_verticalScrollbar.get()); 134 m_verticalScrollbar = 0; 135 } 136} 137 138void AccessibilityScrollView::removeChildScrollbar(AccessibilityObject* scrollbar) 139{ 140 size_t pos = m_children.find(scrollbar); 141 if (pos != WTF::notFound) { 142 m_children[pos]->detachFromParent(); 143 m_children.remove(pos); 144 } 145} 146 147AccessibilityScrollbar* AccessibilityScrollView::addChildScrollbar(Scrollbar* scrollbar) 148{ 149 if (!scrollbar) 150 return 0; 151 152 AccessibilityScrollbar* scrollBarObject = static_cast<AccessibilityScrollbar*>(axObjectCache()->getOrCreate(scrollbar)); 153 scrollBarObject->setParent(this); 154 m_children.append(scrollBarObject); 155 return scrollBarObject; 156} 157 158void AccessibilityScrollView::clearChildren() 159{ 160 AccessibilityObject::clearChildren(); 161 m_verticalScrollbar = 0; 162 m_horizontalScrollbar = 0; 163} 164 165bool AccessibilityScrollView::computeAccessibilityIsIgnored() const 166{ 167 AccessibilityObject* webArea = webAreaObject(); 168 if (!webArea) 169 return true; 170 171 return webArea->accessibilityIsIgnored(); 172} 173 174void AccessibilityScrollView::addChildren() 175{ 176 ASSERT(!m_haveChildren); 177 m_haveChildren = true; 178 179 AccessibilityObject* webArea = webAreaObject(); 180 if (webArea && !webArea->accessibilityIsIgnored()) 181 m_children.append(webArea); 182 183 updateScrollbars(); 184} 185 186AccessibilityObject* AccessibilityScrollView::webAreaObject() const 187{ 188 if (!m_scrollView || !m_scrollView->isFrameView()) 189 return 0; 190 191 Document* doc = toFrameView(m_scrollView)->frame()->document(); 192 if (!doc || !doc->renderer()) 193 return 0; 194 195 return axObjectCache()->getOrCreate(doc); 196} 197 198AccessibilityObject* AccessibilityScrollView::accessibilityHitTest(const IntPoint& point) const 199{ 200 AccessibilityObject* webArea = webAreaObject(); 201 if (!webArea) 202 return 0; 203 204 if (m_horizontalScrollbar && m_horizontalScrollbar->elementRect().contains(point)) 205 return m_horizontalScrollbar.get(); 206 if (m_verticalScrollbar && m_verticalScrollbar->elementRect().contains(point)) 207 return m_verticalScrollbar.get(); 208 209 return webArea->accessibilityHitTest(point); 210} 211 212LayoutRect AccessibilityScrollView::elementRect() const 213{ 214 if (!m_scrollView) 215 return LayoutRect(); 216 217 return m_scrollView->frameRect(); 218} 219 220FrameView* AccessibilityScrollView::documentFrameView() const 221{ 222 if (!m_scrollView || !m_scrollView->isFrameView()) 223 return 0; 224 225 return toFrameView(m_scrollView); 226} 227 228AccessibilityObject* AccessibilityScrollView::parentObject() const 229{ 230 if (!m_scrollView || !m_scrollView->isFrameView()) 231 return 0; 232 233 HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame()->ownerElement(); 234 if (owner && owner->renderer()) 235 return axObjectCache()->getOrCreate(owner); 236 237 return 0; 238} 239 240AccessibilityObject* AccessibilityScrollView::parentObjectIfExists() const 241{ 242 if (!m_scrollView || !m_scrollView->isFrameView()) 243 return 0; 244 245 HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame()->ownerElement(); 246 if (owner && owner->renderer()) 247 return axObjectCache()->get(owner); 248 249 return 0; 250} 251 252ScrollableArea* AccessibilityScrollView::getScrollableAreaIfScrollable() const 253{ 254 return m_scrollView; 255} 256 257void AccessibilityScrollView::scrollTo(const IntPoint& point) const 258{ 259 if (m_scrollView) 260 m_scrollView->setScrollPosition(point); 261} 262 263} // namespace WebCore 264