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 "core/accessibility/AXObject.h" 30 #include "core/rendering/RenderText.h" 31 #include "platform/Timer.h" 32 #include "wtf/Forward.h" 33 #include "wtf/HashMap.h" 34 #include "wtf/HashSet.h" 35 #include "wtf/RefPtr.h" 36 37 namespace blink { 38 39 class AbstractInlineTextBox; 40 class Document; 41 class HTMLAreaElement; 42 class Node; 43 class Page; 44 class RenderObject; 45 class ScrollView; 46 class Settings; 47 class VisiblePosition; 48 class Widget; 49 50 struct TextMarkerData { 51 AXID axID; 52 Node* node; 53 int offset; 54 EAffinity affinity; 55 }; 56 57 class AXComputedObjectAttributeCache { 58 public: create()59 static PassOwnPtr<AXComputedObjectAttributeCache> create() { return adoptPtr(new AXComputedObjectAttributeCache()); } 60 61 AXObjectInclusion getIgnored(AXID) const; 62 void setIgnored(AXID, AXObjectInclusion); 63 64 void clear(); 65 66 private: AXComputedObjectAttributeCache()67 AXComputedObjectAttributeCache() { } 68 69 struct CachedAXObjectAttributes { CachedAXObjectAttributesCachedAXObjectAttributes70 CachedAXObjectAttributes() : ignored(DefaultBehavior) { } 71 72 AXObjectInclusion ignored; 73 }; 74 75 HashMap<AXID, CachedAXObjectAttributes> m_idMapping; 76 }; 77 78 enum PostType { PostSynchronously, PostAsynchronously }; 79 80 class AXObjectCache { 81 WTF_MAKE_NONCOPYABLE(AXObjectCache); WTF_MAKE_FAST_ALLOCATED; 82 public: 83 explicit AXObjectCache(Document&); 84 ~AXObjectCache(); 85 86 static AXObject* focusedUIElementForPage(const Page*); 87 88 // Returns the root object for the entire document. 89 AXObject* rootObject(); 90 91 // For AX objects with elements that back them. 92 AXObject* getOrCreate(RenderObject*); 93 AXObject* getOrCreate(Widget*); 94 AXObject* getOrCreate(Node*); 95 AXObject* getOrCreate(AbstractInlineTextBox*); 96 97 // used for objects without backing elements 98 AXObject* getOrCreate(AccessibilityRole); 99 100 // will only return the AXObject if it already exists 101 AXObject* get(RenderObject*); 102 AXObject* get(Widget*); 103 AXObject* get(Node*); 104 AXObject* get(AbstractInlineTextBox*); 105 106 void remove(RenderObject*); 107 void remove(Node*); 108 void remove(Widget*); 109 void remove(AbstractInlineTextBox*); 110 void remove(AXID); 111 112 void clearWeakMembers(Visitor*); 113 114 void detachWrapper(AXObject*); 115 void attachWrapper(AXObject*); 116 void childrenChanged(Node*); 117 void childrenChanged(RenderObject*); 118 void childrenChanged(AXObject*); 119 void checkedStateChanged(Node*); 120 void selectedChildrenChanged(Node*); 121 void selectedChildrenChanged(RenderObject*); 122 void selectionChanged(Node*); 123 // Called by a node when text or a text equivalent (e.g. alt) attribute is changed. 124 void textChanged(Node*); 125 void textChanged(RenderObject*); 126 // Called when a node has just been attached, so we can make sure we have the right subclass of AXObject. 127 void updateCacheAfterNodeIsAttached(Node*); 128 129 void handleActiveDescendantChanged(Node*); 130 void handleAriaRoleChanged(Node*); 131 void handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode); 132 void handleScrolledToAnchor(const Node* anchorNode); 133 void handleAriaExpandedChange(Node*); 134 135 // Called when scroll bars are added / removed (as the view resizes). 136 void handleScrollbarUpdate(ScrollView*); 137 138 void handleLayoutComplete(RenderObject*); 139 140 // Called when the scroll offset changes. 141 void handleScrollPositionChanged(ScrollView*); 142 void handleScrollPositionChanged(RenderObject*); 143 144 void handleAttributeChanged(const QualifiedName& attrName, Element*); 145 void recomputeIsIgnored(RenderObject* renderer); 146 147 void inlineTextBoxesUpdated(RenderObject* renderer); 148 149 bool accessibilityEnabled(); 150 bool inlineTextBoxAccessibilityEnabled(); 151 152 void removeAXID(AXObject*); isIDinUse(AXID id)153 bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); } 154 155 Element* rootAXEditableElement(Node*); 156 const Element* rootAXEditableElement(const Node*); 157 bool nodeIsTextControl(const Node*); 158 159 AXID platformGenerateAXID() const; objectFromAXID(AXID id)160 AXObject* objectFromAXID(AXID id) const { return m_objects.get(id); } 161 162 enum AXNotification { 163 AXActiveDescendantChanged, 164 AXAlert, 165 AXAriaAttributeChanged, 166 AXAutocorrectionOccured, 167 AXBlur, 168 AXCheckedStateChanged, 169 AXChildrenChanged, 170 AXFocusedUIElementChanged, 171 AXHide, 172 AXInvalidStatusChanged, 173 AXLayoutComplete, 174 AXLiveRegionChanged, 175 AXLoadComplete, 176 AXLocationChanged, 177 AXMenuListItemSelected, 178 AXMenuListValueChanged, 179 AXRowCollapsed, 180 AXRowCountChanged, 181 AXRowExpanded, 182 AXScrollPositionChanged, 183 AXScrolledToAnchor, 184 AXSelectedChildrenChanged, 185 AXSelectedTextChanged, 186 AXShow, 187 AXTextChanged, 188 AXTextInserted, 189 AXTextRemoved, 190 AXValueChanged 191 }; 192 193 void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously); 194 void postNotification(Node*, AXNotification, bool postToElement, PostType = PostAsynchronously); 195 void postNotification(AXObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously); 196 197 bool nodeHasRole(Node*, const AtomicString& role); 198 199 void setCanvasObjectBounds(Element*, const LayoutRect&); 200 computedObjectAttributeCache()201 AXComputedObjectAttributeCache* computedObjectAttributeCache() { return m_computedObjectAttributeCache.get(); } 202 203 protected: 204 void postPlatformNotification(AXObject*, AXNotification); 205 void textChanged(AXObject*); 206 void labelChanged(Element*); 207 208 // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid. setNodeInUse(Node * n)209 void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); } removeNodeForUse(Node * n)210 void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); } isNodeInUse(Node * n)211 bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); } 212 213 private: 214 Document& m_document; 215 HashMap<AXID, RefPtr<AXObject> > m_objects; 216 HashMap<RenderObject*, AXID> m_renderObjectMapping; 217 HashMap<Widget*, AXID> m_widgetObjectMapping; 218 HashMap<Node*, AXID> m_nodeObjectMapping; 219 HashMap<AbstractInlineTextBox*, AXID> m_inlineTextBoxObjectMapping; 220 HashSet<Node*> m_textMarkerNodes; 221 OwnPtr<AXComputedObjectAttributeCache> m_computedObjectAttributeCache; 222 223 HashSet<AXID> m_idsInUse; 224 225 Timer<AXObjectCache> m_notificationPostTimer; 226 Vector<pair<RefPtr<AXObject>, AXNotification> > m_notificationsToPost; 227 void notificationPostTimerFired(Timer<AXObjectCache>*); 228 229 static AXObject* focusedImageMapUIElement(HTMLAreaElement*); 230 231 AXID getAXID(AXObject*); 232 233 Settings* settings(); 234 }; 235 236 bool nodeHasRole(Node*, const String& role); 237 // This will let you know if aria-hidden was explicitly set to false. 238 bool isNodeAriaVisible(Node*); 239 240 } 241 242 #endif 243