AX: Need AccessibilityObjects for nodes without renderers in canvas subtree
[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 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     AccessibilityObject* getOrCreate(Node*);
74
75     // used for objects without backing elements
76     AccessibilityObject* getOrCreate(AccessibilityRole);
77     
78     // will only return the AccessibilityObject if it already exists
79     AccessibilityObject* get(RenderObject*);
80     AccessibilityObject* get(Widget*);
81     AccessibilityObject* get(Node*);
82     
83     void remove(RenderObject*);
84     void remove(Node*);
85     void remove(Widget*);
86     void remove(AXID);
87
88     void detachWrapper(AccessibilityObject*);
89     void attachWrapper(AccessibilityObject*);
90     void childrenChanged(RenderObject*);
91     void checkedStateChanged(RenderObject*);
92     void selectedChildrenChanged(RenderObject*);
93     // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
94     void contentChanged(RenderObject*);
95     
96     void handleActiveDescendantChanged(RenderObject*);
97     void handleAriaRoleChanged(RenderObject*);
98     void handleFocusedUIElementChanged(RenderObject* oldFocusedRenderer, RenderObject* newFocusedRenderer);
99     void handleScrolledToAnchor(const Node* anchorNode);
100     void handleAriaExpandedChange(RenderObject*);
101     void handleScrollbarUpdate(ScrollView*);
102
103 #if HAVE(ACCESSIBILITY)
104     static void enableAccessibility() { gAccessibilityEnabled = true; }
105     // Enhanced user interface accessibility can be toggled by the assistive technology.
106     static void setEnhancedUserInterfaceAccessibility(bool flag) { gAccessibilityEnhancedUserInterfaceEnabled = flag; }
107     
108     static bool accessibilityEnabled() { return gAccessibilityEnabled; }
109     static bool accessibilityEnhancedUserInterfaceEnabled() { return gAccessibilityEnhancedUserInterfaceEnabled; }
110 #else
111     static void enableAccessibility() { }
112     static void setEnhancedUserInterfaceAccessibility(bool flag) { }
113     static bool accessibilityEnabled() { return false; }
114     static bool accessibilityEnhancedUserInterfaceEnabled() { return false; }
115 #endif
116
117     void removeAXID(AccessibilityObject*);
118     bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); }
119
120     Element* rootAXEditableElement(Node*);
121     const Element* rootAXEditableElement(const Node*);
122     bool nodeIsTextControl(const Node*);
123
124     AXID platformGenerateAXID() const;
125     AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id).get(); }
126
127     // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
128     void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
129     void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
130     bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
131     
132     // Text marker utilities.
133     void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
134     VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
135
136     enum AXNotification {
137         AXActiveDescendantChanged,
138         AXAutocorrectionOccured,
139         AXCheckedStateChanged,
140         AXChildrenChanged,
141         AXFocusedUIElementChanged,
142         AXLayoutComplete,
143         AXLoadComplete,
144         AXSelectedChildrenChanged,
145         AXSelectedTextChanged,
146         AXValueChanged,
147         AXScrolledToAnchor,
148         AXLiveRegionChanged,
149         AXMenuListItemSelected,
150         AXMenuListValueChanged,
151         AXRowCountChanged,
152         AXRowCollapsed,
153         AXRowExpanded,
154         AXInvalidStatusChanged,
155     };
156
157     void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously);
158     void postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously);
159
160     enum AXTextChange {
161         AXTextInserted,
162         AXTextDeleted,
163     };
164
165     void nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned offset, const String&);
166
167     enum AXLoadingEvent {
168         AXLoadingStarted,
169         AXLoadingReloaded,
170         AXLoadingFailed,
171         AXLoadingFinished
172     };
173
174     void frameLoadingEventNotification(Frame*, AXLoadingEvent);
175
176     bool nodeHasRole(Node*, const AtomicString& role);
177
178 protected:
179     void postPlatformNotification(AccessibilityObject*, AXNotification);
180     void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned offset, const String&);
181     void frameLoadingEventPlatformNotification(AccessibilityObject*, AXLoadingEvent);
182
183 private:
184     Document* m_document;
185     HashMap<AXID, RefPtr<AccessibilityObject> > m_objects;
186     HashMap<RenderObject*, AXID> m_renderObjectMapping;
187     HashMap<Widget*, AXID> m_widgetObjectMapping;
188     HashMap<Node*, AXID> m_nodeObjectMapping;
189     HashSet<Node*> m_textMarkerNodes;
190     static bool gAccessibilityEnabled;
191     static bool gAccessibilityEnhancedUserInterfaceEnabled;
192     
193     HashSet<AXID> m_idsInUse;
194     
195     Timer<AXObjectCache> m_notificationPostTimer;
196     Vector<pair<RefPtr<AccessibilityObject>, AXNotification> > m_notificationsToPost;
197     void notificationPostTimerFired(Timer<AXObjectCache>*);
198     
199     static AccessibilityObject* focusedImageMapUIElement(HTMLAreaElement*);
200     
201     AXID getAXID(AccessibilityObject*);
202 };
203
204 bool nodeHasRole(Node*, const String& role);
205
206 #if !HAVE(ACCESSIBILITY)
207 inline AXObjectCache::AXObjectCache(const Document* doc) : m_document(const_cast<Document*>(doc)), m_notificationPostTimer(this, 0) { }
208 inline AXObjectCache::~AXObjectCache() { }
209 inline AccessibilityObject* AXObjectCache::focusedUIElementForPage(const Page*) { return 0; }
210 inline AccessibilityObject* AXObjectCache::get(RenderObject*) { return 0; }
211 inline AccessibilityObject* AXObjectCache::get(Node*) { return 0; }
212 inline AccessibilityObject* AXObjectCache::get(Widget*) { return 0; }
213 inline AccessibilityObject* AXObjectCache::getOrCreate(AccessibilityRole) { return 0; }
214 inline AccessibilityObject* AXObjectCache::getOrCreate(RenderObject*) { return 0; }
215 inline AccessibilityObject* AXObjectCache::getOrCreate(Node*) { return 0; }
216 inline AccessibilityObject* AXObjectCache::getOrCreate(Widget*) { return 0; }
217 inline AccessibilityObject* AXObjectCache::rootObject() { return 0; }
218 inline AccessibilityObject* AXObjectCache::rootObjectForFrame(Frame*) { return 0; }
219 inline Element* AXObjectCache::rootAXEditableElement(Node*) { return 0; }
220 inline bool nodeHasRole(Node*, const String&) { return false; }
221 inline const Element* AXObjectCache::rootAXEditableElement(const Node*) { return 0; }
222 inline void AXObjectCache::attachWrapper(AccessibilityObject*) { }
223 inline void AXObjectCache::checkedStateChanged(RenderObject*) { }
224 inline void AXObjectCache::childrenChanged(RenderObject*) { }
225 inline void AXObjectCache::contentChanged(RenderObject*) { }
226 inline void AXObjectCache::detachWrapper(AccessibilityObject*) { }
227 inline void AXObjectCache::frameLoadingEventNotification(Frame*, AXLoadingEvent) { }
228 inline void AXObjectCache::frameLoadingEventPlatformNotification(AccessibilityObject*, AXLoadingEvent) { }
229 inline void AXObjectCache::handleActiveDescendantChanged(RenderObject*) { }
230 inline void AXObjectCache::handleAriaExpandedChange(RenderObject*) { }
231 inline void AXObjectCache::handleAriaRoleChanged(RenderObject*) { }
232 inline void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) { }
233 inline void AXObjectCache::handleScrollbarUpdate(ScrollView*) { }
234 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { }
235 inline void AXObjectCache::nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned, const String&) { }
236 inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, const String&) { }
237 inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType) { }
238 inline void AXObjectCache::postNotification(RenderObject*, AXNotification, bool postToElement, PostType) { }
239 inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { }
240 inline void AXObjectCache::remove(AXID) { }
241 inline void AXObjectCache::remove(RenderObject*) { }
242 inline void AXObjectCache::remove(Node*) { }
243 inline void AXObjectCache::remove(Widget*) { }
244 inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { }
245 #endif
246
247 }
248
249 #endif