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 37 namespace WebCore { 38 39 class Document; 40 class HTMLAreaElement; 41 class Node; 42 class Page; 43 class RenderObject; 44 class ScrollView; 45 class VisiblePosition; 46 class Widget; 47 48 struct TextMarkerData { 49 AXID axID; 50 Node* node; 51 int offset; 52 EAffinity affinity; 53 }; 54 55 enum PostType { PostSynchronously, PostAsynchronously }; 56 57 class AXObjectCache { 58 WTF_MAKE_NONCOPYABLE(AXObjectCache); WTF_MAKE_FAST_ALLOCATED; 59 public: 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 // Enhanced user interface accessibility can be toggled by the assistive technology. 100 static void setEnhancedUserInterfaceAccessibility(bool flag) { gAccessibilityEnhancedUserInterfaceEnabled = flag; } 101 102 static bool accessibilityEnabled() { return gAccessibilityEnabled; } 103 static bool accessibilityEnhancedUserInterfaceEnabled() { return gAccessibilityEnhancedUserInterfaceEnabled; } 104 105 void removeAXID(AccessibilityObject*); 106 bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); } 107 AXID platformGenerateAXID() const; 108 AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id).get(); } 109 110 // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid. 111 void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); } 112 void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); } 113 bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); } 114 115 // Text marker utilities. 116 void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&); 117 VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&); 118 119 enum AXNotification { 120 AXActiveDescendantChanged, 121 AXAutocorrectionOccured, 122 AXCheckedStateChanged, 123 AXChildrenChanged, 124 AXFocusedUIElementChanged, 125 AXLayoutComplete, 126 AXLoadComplete, 127 AXSelectedChildrenChanged, 128 AXSelectedTextChanged, 129 AXValueChanged, 130 AXScrolledToAnchor, 131 AXLiveRegionChanged, 132 AXMenuListValueChanged, 133 AXRowCountChanged, 134 AXRowCollapsed, 135 AXRowExpanded, 136 AXInvalidStatusChanged, 137 }; 138 139 void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously); 140 void postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously); 141 142 enum AXTextChange { 143 AXTextInserted, 144 AXTextDeleted, 145 }; 146 147 void nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned offset, unsigned count); 148 149 bool nodeHasRole(Node*, const AtomicString& role); 150 151 protected: 152 void postPlatformNotification(AccessibilityObject*, AXNotification); 153 void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned offset, unsigned count); 154 155 private: 156 Document* m_document; 157 HashMap<AXID, RefPtr<AccessibilityObject> > m_objects; 158 HashMap<RenderObject*, AXID> m_renderObjectMapping; 159 HashMap<Widget*, AXID> m_widgetObjectMapping; 160 HashSet<Node*> m_textMarkerNodes; 161 static bool gAccessibilityEnabled; 162 static bool gAccessibilityEnhancedUserInterfaceEnabled; 163 164 HashSet<AXID> m_idsInUse; 165 166 Timer<AXObjectCache> m_notificationPostTimer; 167 Vector<pair<RefPtr<AccessibilityObject>, AXNotification> > m_notificationsToPost; 168 void notificationPostTimerFired(Timer<AXObjectCache>*); 169 170 static AccessibilityObject* focusedImageMapUIElement(HTMLAreaElement*); 171 172 AXID getAXID(AccessibilityObject*); 173 AccessibilityObject* get(Widget*); 174 }; 175 176 bool nodeHasRole(Node*, const String& role); 177 178 #if !HAVE(ACCESSIBILITY) 179 inline void AXObjectCache::handleActiveDescendantChanged(RenderObject*) { } 180 inline void AXObjectCache::handleAriaRoleChanged(RenderObject*) { } 181 inline void AXObjectCache::detachWrapper(AccessibilityObject*) { } 182 inline void AXObjectCache::attachWrapper(AccessibilityObject*) { } 183 inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { } 184 inline void AXObjectCache::postNotification(RenderObject*, AXNotification, bool postToElement, PostType) { } 185 inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType) { } 186 inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { } 187 inline void AXObjectCache::nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned, unsigned) { } 188 inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) { } 189 inline void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) { } 190 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { } 191 inline void AXObjectCache::contentChanged(RenderObject*) { } 192 inline void AXObjectCache::handleAriaExpandedChange(RenderObject*) { } 193 inline void AXObjectCache::handleScrollbarUpdate(ScrollView*) { } 194 #endif 195 196 } 197 198 #endif 199