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