AXObjectCache.h revision 81bc750723a18f21cd17d1b173cd2a4dda9cea6e
1/* 2 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 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 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef AXObjectCache_h 27#define AXObjectCache_h 28 29#include "AccessibilityObject.h" 30#include "Timer.h" 31#include <limits.h> 32#include <wtf/Forward.h> 33#include <wtf/HashMap.h> 34#include <wtf/HashSet.h> 35#include <wtf/RefPtr.h> 36 37namespace WebCore { 38 39class Document; 40class HTMLAreaElement; 41class Node; 42class Page; 43class RenderObject; 44class ScrollView; 45class VisiblePosition; 46class Widget; 47 48struct TextMarkerData { 49 AXID axID; 50 Node* node; 51 int offset; 52 EAffinity affinity; 53}; 54 55enum PostType { PostSynchronously, PostAsynchronously }; 56 57class AXObjectCache { 58 WTF_MAKE_NONCOPYABLE(AXObjectCache); WTF_MAKE_FAST_ALLOCATED; 59public: 60 AXObjectCache(const Document*); 61 ~AXObjectCache(); 62 63 static AccessibilityObject* focusedUIElementForPage(const Page*); 64 65 // Returns the root object for the entire document. 66 AccessibilityObject* rootObject(); 67 // Returns the root object for a specific frame. 68 AccessibilityObject* rootObjectForFrame(Frame*); 69 70 // For AX objects with elements that back them. 71 AccessibilityObject* getOrCreate(RenderObject*); 72 AccessibilityObject* getOrCreate(Widget*); 73 74 // used for objects without backing elements 75 AccessibilityObject* getOrCreate(AccessibilityRole); 76 77 // will only return the AccessibilityObject if it already exists 78 AccessibilityObject* get(RenderObject*); 79 80 void remove(RenderObject*); 81 void remove(Widget*); 82 void remove(AXID); 83 84 void detachWrapper(AccessibilityObject*); 85 void attachWrapper(AccessibilityObject*); 86 void childrenChanged(RenderObject*); 87 void selectedChildrenChanged(RenderObject*); 88 // Called by a node when text or a text equivalent (e.g. alt) attribute is changed. 89 void contentChanged(RenderObject*); 90 91 void handleActiveDescendantChanged(RenderObject*); 92 void handleAriaRoleChanged(RenderObject*); 93 void handleFocusedUIElementChanged(RenderObject* oldFocusedRenderer, RenderObject* newFocusedRenderer); 94 void handleScrolledToAnchor(const Node* anchorNode); 95 void handleAriaExpandedChange(RenderObject*); 96 void handleScrollbarUpdate(ScrollView*); 97 98 static void enableAccessibility() { gAccessibilityEnabled = true; } 99 static void enableEnhancedUserInterfaceAccessibility() { gAccessibilityEnhancedUserInterfaceEnabled = true; } 100 101 static bool accessibilityEnabled() { return gAccessibilityEnabled; } 102 static bool accessibilityEnhancedUserInterfaceEnabled() { return gAccessibilityEnhancedUserInterfaceEnabled; } 103 104 void removeAXID(AccessibilityObject*); 105 bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); } 106 AXID platformGenerateAXID() const; 107 AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id).get(); } 108 109 // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid. 110 void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); } 111 void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); } 112 bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); } 113 114 // Text marker utilities. 115 void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&); 116 VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&); 117 118 enum AXNotification { 119 AXActiveDescendantChanged, 120 AXCheckedStateChanged, 121 AXChildrenChanged, 122 AXFocusedUIElementChanged, 123 AXLayoutComplete, 124 AXLoadComplete, 125 AXSelectedChildrenChanged, 126 AXSelectedTextChanged, 127 AXValueChanged, 128 AXScrolledToAnchor, 129 AXLiveRegionChanged, 130 AXMenuListValueChanged, 131 AXRowCountChanged, 132 AXRowCollapsed, 133 AXRowExpanded, 134 AXInvalidStatusChanged, 135 }; 136 137 void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously); 138 void postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously); 139 140 enum AXTextChange { 141 AXTextInserted, 142 AXTextDeleted, 143 }; 144 145 void nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned offset, unsigned count); 146 147 bool nodeHasRole(Node*, const AtomicString& role); 148 149protected: 150 void postPlatformNotification(AccessibilityObject*, AXNotification); 151 void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned offset, unsigned count); 152 153private: 154 Document* m_document; 155 HashMap<AXID, RefPtr<AccessibilityObject> > m_objects; 156 HashMap<RenderObject*, AXID> m_renderObjectMapping; 157 HashMap<Widget*, AXID> m_widgetObjectMapping; 158 HashSet<Node*> m_textMarkerNodes; 159 static bool gAccessibilityEnabled; 160 static bool gAccessibilityEnhancedUserInterfaceEnabled; 161 162 HashSet<AXID> m_idsInUse; 163 164 Timer<AXObjectCache> m_notificationPostTimer; 165 Vector<pair<RefPtr<AccessibilityObject>, AXNotification> > m_notificationsToPost; 166 void notificationPostTimerFired(Timer<AXObjectCache>*); 167 168 static AccessibilityObject* focusedImageMapUIElement(HTMLAreaElement*); 169 170 AXID getAXID(AccessibilityObject*); 171 AccessibilityObject* get(Widget*); 172}; 173 174bool nodeHasRole(Node*, const String& role); 175 176#if !HAVE(ACCESSIBILITY) 177inline void AXObjectCache::handleActiveDescendantChanged(RenderObject*) { } 178inline void AXObjectCache::handleAriaRoleChanged(RenderObject*) { } 179inline void AXObjectCache::detachWrapper(AccessibilityObject*) { } 180inline void AXObjectCache::attachWrapper(AccessibilityObject*) { } 181inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { } 182inline void AXObjectCache::postNotification(RenderObject*, AXNotification, bool postToElement, PostType) { } 183inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType) { } 184inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { } 185inline void AXObjectCache::nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned, unsigned) { } 186inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) { } 187inline void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) { } 188inline void AXObjectCache::handleScrolledToAnchor(const Node*) { } 189inline void AXObjectCache::contentChanged(RenderObject*) { } 190inline void AXObjectCache::handleAriaExpandedChange(RenderObject*) { } 191inline void AXObjectCache::handleScrollbarUpdate(ScrollView*) { } 192#endif 193 194} 195 196#endif 197