• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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