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