AX: Replace AXObjectCache postNotification method boolean arguments with enum values.
[WebKit-https.git] / Source / WebCore / accessibility / AXObjectCache.h
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 class AXComputedObjectAttributeCache {
56 public:
57     static PassOwnPtr<AXComputedObjectAttributeCache> create() { return adoptPtr(new AXComputedObjectAttributeCache()); }
58
59     AccessibilityObjectInclusion getIgnored(AXID) const;
60     void setIgnored(AXID, AccessibilityObjectInclusion);
61
62 private:
63     AXComputedObjectAttributeCache() { }
64
65     struct CachedAXObjectAttributes {
66         CachedAXObjectAttributes() : ignored(DefaultBehavior) { }
67
68         AccessibilityObjectInclusion ignored;
69     };
70
71     HashMap<AXID, CachedAXObjectAttributes> m_idMapping;
72 };
73
74 enum PostTarget { TargetElement, TargetObservableParent };
75
76 enum PostType { PostSynchronously, PostAsynchronously };
77
78 class AXObjectCache {
79     WTF_MAKE_NONCOPYABLE(AXObjectCache); WTF_MAKE_FAST_ALLOCATED;
80 public:
81     explicit AXObjectCache(Document&);
82     ~AXObjectCache();
83
84     static AccessibilityObject* focusedUIElementForPage(const Page*);
85
86     // Returns the root object for the entire document.
87     AccessibilityObject* rootObject();
88     // Returns the root object for a specific frame.
89     AccessibilityObject* rootObjectForFrame(Frame*);
90     
91     // For AX objects with elements that back them.
92     AccessibilityObject* getOrCreate(RenderObject*);
93     AccessibilityObject* getOrCreate(Widget*);
94     AccessibilityObject* getOrCreate(Node*);
95
96     // used for objects without backing elements
97     AccessibilityObject* getOrCreate(AccessibilityRole);
98     
99     // will only return the AccessibilityObject if it already exists
100     AccessibilityObject* get(RenderObject*);
101     AccessibilityObject* get(Widget*);
102     AccessibilityObject* get(Node*);
103     
104     void remove(RenderObject*);
105     void remove(Node*);
106     void remove(Widget*);
107     void remove(AXID);
108
109     void detachWrapper(AccessibilityObject*);
110     void attachWrapper(AccessibilityObject*);
111     void childrenChanged(Node*);
112     void childrenChanged(RenderObject*);
113     void childrenChanged(AccessibilityObject*);
114     void checkedStateChanged(Node*);
115     void selectedChildrenChanged(Node*);
116     void selectedChildrenChanged(RenderObject*);
117     // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
118     void textChanged(Node*);
119     void textChanged(RenderObject*);
120     // Called when a node has just been attached, so we can make sure we have the right subclass of AccessibilityObject.
121     void updateCacheAfterNodeIsAttached(Node*);
122
123     void handleActiveDescendantChanged(Node*);
124     void handleAriaRoleChanged(Node*);
125     void handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
126     void handleScrolledToAnchor(const Node* anchorNode);
127     void handleAriaExpandedChange(Node*);
128     void handleScrollbarUpdate(ScrollView*);
129
130     void handleAttributeChanged(const QualifiedName& attrName, Element*);
131     void recomputeIsIgnored(RenderObject* renderer);
132
133 #if HAVE(ACCESSIBILITY)
134     static void enableAccessibility() { gAccessibilityEnabled = true; }
135     // Enhanced user interface accessibility can be toggled by the assistive technology.
136     static void setEnhancedUserInterfaceAccessibility(bool flag) { gAccessibilityEnhancedUserInterfaceEnabled = flag; }
137     
138     static bool accessibilityEnabled() { return gAccessibilityEnabled; }
139     static bool accessibilityEnhancedUserInterfaceEnabled() { return gAccessibilityEnhancedUserInterfaceEnabled; }
140 #else
141     static void enableAccessibility() { }
142     static void setEnhancedUserInterfaceAccessibility(bool) { }
143     static bool accessibilityEnabled() { return false; }
144     static bool accessibilityEnhancedUserInterfaceEnabled() { return false; }
145 #endif
146
147     void removeAXID(AccessibilityObject*);
148     bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); }
149
150     Element* rootAXEditableElement(Node*);
151     const Element* rootAXEditableElement(const Node*);
152     bool nodeIsTextControl(const Node*);
153
154     AXID platformGenerateAXID() const;
155     AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id); }
156
157     // Text marker utilities.
158     void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
159     VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
160
161     enum AXNotification {
162         AXActiveDescendantChanged,
163         AXAutocorrectionOccured,
164         AXCheckedStateChanged,
165         AXChildrenChanged,
166         AXFocusedUIElementChanged,
167         AXLayoutComplete,
168         AXLoadComplete,
169         AXSelectedChildrenChanged,
170         AXSelectedTextChanged,
171         AXValueChanged,
172         AXScrolledToAnchor,
173         AXLiveRegionChanged,
174         AXMenuListItemSelected,
175         AXMenuListValueChanged,
176         AXRowCountChanged,
177         AXRowCollapsed,
178         AXRowExpanded,
179         AXInvalidStatusChanged,
180         AXTextChanged,
181         AXAriaAttributeChanged
182     };
183
184     void postNotification(RenderObject*, AXNotification, PostTarget = TargetElement, PostType = PostAsynchronously);
185     void postNotification(Node*, AXNotification, PostTarget = TargetElement, PostType = PostAsynchronously);
186     void postNotification(AccessibilityObject*, Document*, AXNotification, PostTarget = TargetElement, PostType = PostAsynchronously);
187
188     enum AXTextChange {
189         AXTextInserted,
190         AXTextDeleted,
191     };
192
193     void nodeTextChangeNotification(Node*, AXTextChange, unsigned offset, const String&);
194
195     enum AXLoadingEvent {
196         AXLoadingStarted,
197         AXLoadingReloaded,
198         AXLoadingFailed,
199         AXLoadingFinished
200     };
201
202     void frameLoadingEventNotification(Frame*, AXLoadingEvent);
203
204     bool nodeHasRole(Node*, const AtomicString& role);
205     void clearTextMarkerNodesInUse(Document*);
206
207     void startCachingComputedObjectAttributesUntilTreeMutates();
208     void stopCachingComputedObjectAttributes();
209
210     AXComputedObjectAttributeCache* computedObjectAttributeCache() { return m_computedObjectAttributeCache.get(); }
211
212 protected:
213     void postPlatformNotification(AccessibilityObject*, AXNotification);
214     void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned offset, const String&);
215     void frameLoadingEventPlatformNotification(AccessibilityObject*, AXLoadingEvent);
216     void textChanged(AccessibilityObject*);
217     void labelChanged(Element*);
218
219     // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
220     void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
221     void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
222     bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
223
224 private:
225     Document& m_document;
226     HashMap<AXID, RefPtr<AccessibilityObject> > m_objects;
227     HashMap<RenderObject*, AXID> m_renderObjectMapping;
228     HashMap<Widget*, AXID> m_widgetObjectMapping;
229     HashMap<Node*, AXID> m_nodeObjectMapping;
230     HashSet<Node*> m_textMarkerNodes;
231     OwnPtr<AXComputedObjectAttributeCache> m_computedObjectAttributeCache;
232     static bool gAccessibilityEnabled;
233     static bool gAccessibilityEnhancedUserInterfaceEnabled;
234     
235     HashSet<AXID> m_idsInUse;
236     
237     Timer<AXObjectCache> m_notificationPostTimer;
238     Vector<pair<RefPtr<AccessibilityObject>, AXNotification> > m_notificationsToPost;
239     void notificationPostTimerFired(Timer<AXObjectCache>*);
240     
241     static AccessibilityObject* focusedImageMapUIElement(HTMLAreaElement*);
242     
243     AXID getAXID(AccessibilityObject*);
244 };
245
246 class AXAttributeCacheEnabler
247 {
248 public:
249     explicit AXAttributeCacheEnabler(AXObjectCache *cache);
250     ~AXAttributeCacheEnabler();
251     
252 private:
253     AXObjectCache* m_cache;
254 };
255     
256 bool nodeHasRole(Node*, const String& role);
257 // This will let you know if aria-hidden was explicitly set to false.
258 bool isNodeAriaVisible(Node*);
259     
260 #if !HAVE(ACCESSIBILITY)
261 inline AccessibilityObjectInclusion AXComputedObjectAttributeCache::getIgnored(AXID) const { return DefaultBehavior; }
262 inline void AXComputedObjectAttributeCache::setIgnored(AXID, AccessibilityObjectInclusion) { }
263 inline AXObjectCache::AXObjectCache(Document& document) : m_document(document), m_notificationPostTimer(this, 0) { }
264 inline AXObjectCache::~AXObjectCache() { }
265 inline AccessibilityObject* AXObjectCache::focusedUIElementForPage(const Page*) { return 0; }
266 inline AccessibilityObject* AXObjectCache::get(RenderObject*) { return 0; }
267 inline AccessibilityObject* AXObjectCache::get(Node*) { return 0; }
268 inline AccessibilityObject* AXObjectCache::get(Widget*) { return 0; }
269 inline AccessibilityObject* AXObjectCache::getOrCreate(AccessibilityRole) { return 0; }
270 inline AccessibilityObject* AXObjectCache::getOrCreate(RenderObject*) { return 0; }
271 inline AccessibilityObject* AXObjectCache::getOrCreate(Node*) { return 0; }
272 inline AccessibilityObject* AXObjectCache::getOrCreate(Widget*) { return 0; }
273 inline AccessibilityObject* AXObjectCache::rootObject() { return 0; }
274 inline AccessibilityObject* AXObjectCache::rootObjectForFrame(Frame*) { return 0; }
275 inline Element* AXObjectCache::rootAXEditableElement(Node*) { return 0; }
276 inline bool nodeHasRole(Node*, const String&) { return false; }
277 inline void AXObjectCache::startCachingComputedObjectAttributesUntilTreeMutates() { }
278 inline void AXObjectCache::stopCachingComputedObjectAttributes() { }
279 inline bool isNodeAriaVisible(Node*) { return true; }
280 inline const Element* AXObjectCache::rootAXEditableElement(const Node*) { return 0; }
281 inline void AXObjectCache::attachWrapper(AccessibilityObject*) { }
282 inline void AXObjectCache::checkedStateChanged(Node*) { }
283 inline void AXObjectCache::childrenChanged(RenderObject*) { }
284 inline void AXObjectCache::childrenChanged(Node*) { }
285 inline void AXObjectCache::childrenChanged(AccessibilityObject*) { }
286 inline void AXObjectCache::textChanged(RenderObject*) { }
287 inline void AXObjectCache::textChanged(Node*) { }
288 inline void AXObjectCache::textChanged(AccessibilityObject*) { }
289 inline void AXObjectCache::updateCacheAfterNodeIsAttached(Node*) { }
290 inline void AXObjectCache::detachWrapper(AccessibilityObject*) { }
291 inline void AXObjectCache::frameLoadingEventNotification(Frame*, AXLoadingEvent) { }
292 inline void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject*, AXLoadingEvent) { }
293 inline void AXObjectCache::handleActiveDescendantChanged(Node*) { }
294 inline void AXObjectCache::handleAriaExpandedChange(Node*) { }
295 inline void AXObjectCache::handleAriaRoleChanged(Node*) { }
296 inline void AXObjectCache::handleFocusedUIElementChanged(Node*, Node*) { }
297 inline void AXObjectCache::handleScrollbarUpdate(ScrollView*) { }
298 inline void AXObjectCache::handleAttributeChanged(const QualifiedName&, Element*) { }
299 inline void AXObjectCache::recomputeIsIgnored(RenderObject*) { }
300 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { }
301 inline void AXObjectCache::nodeTextChangeNotification(Node*, AXTextChange, unsigned, const String&) { }
302 inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, const String&) { }
303 inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, PostTarget, PostType) { }
304 inline void AXObjectCache::postNotification(RenderObject*, AXNotification, PostTarget, PostType) { }
305 inline void AXObjectCache::postNotification(Node*, AXNotification, PostTarget, PostType) { }
306 inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { }
307 inline void AXObjectCache::remove(AXID) { }
308 inline void AXObjectCache::remove(RenderObject*) { }
309 inline void AXObjectCache::remove(Node*) { }
310 inline void AXObjectCache::remove(Widget*) { }
311 inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { }
312 inline void AXObjectCache::selectedChildrenChanged(Node*) { }
313 #endif
314
315 }
316
317 #endif