Refactoring of the custom allocation framework
[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 #ifdef __OBJC__
38 @class WebCoreTextMarker;
39 #else
40 class WebCoreTextMarker;
41 #endif
42
43 namespace WebCore {
44
45 class Document;
46 class HTMLAreaElement;
47 class Node;
48 class Page;
49 class RenderObject;
50 class ScrollView;
51 class VisiblePosition;
52 class Widget;
53
54 struct TextMarkerData {
55     AXID axID;
56     Node* node;
57     int offset;
58     EAffinity affinity;
59 };
60
61 enum PostType { PostSynchronously, PostAsynchronously };
62
63 class AXObjectCache {
64     WTF_MAKE_NONCOPYABLE(AXObjectCache); WTF_MAKE_FAST_ALLOCATED;
65 public:
66     AXObjectCache(const Document*);
67     ~AXObjectCache();
68
69     static AccessibilityObject* focusedUIElementForPage(const Page*);
70
71     AccessibilityObject* rootObject();
72     
73     // For AX objects with elements that back them.
74     AccessibilityObject* getOrCreate(RenderObject*);
75     AccessibilityObject* getOrCreate(Widget*);
76
77     // used for objects without backing elements
78     AccessibilityObject* getOrCreate(AccessibilityRole);
79     
80     // will only return the AccessibilityObject if it already exists
81     AccessibilityObject* get(RenderObject*);
82     
83     void remove(RenderObject*);
84     void remove(Widget*);
85     void remove(AXID);
86
87     void detachWrapper(AccessibilityObject*);
88     void attachWrapper(AccessibilityObject*);
89     void childrenChanged(RenderObject*);
90     void selectedChildrenChanged(RenderObject*);
91     // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
92     void contentChanged(RenderObject*);
93     
94     void handleActiveDescendantChanged(RenderObject*);
95     void handleAriaRoleChanged(RenderObject*);
96     void handleFocusedUIElementChanged(RenderObject* oldFocusedRenderer, RenderObject* newFocusedRenderer);
97     void handleScrolledToAnchor(const Node* anchorNode);
98     void handleAriaExpandedChange(RenderObject*);
99     void handleScrollbarUpdate(ScrollView*);
100     
101     static void enableAccessibility() { gAccessibilityEnabled = true; }
102     static void enableEnhancedUserInterfaceAccessibility() { gAccessibilityEnhancedUserInterfaceEnabled = true; }
103     
104     static bool accessibilityEnabled() { return gAccessibilityEnabled; }
105     static bool accessibilityEnhancedUserInterfaceEnabled() { return gAccessibilityEnhancedUserInterfaceEnabled; }
106
107     void removeAXID(AccessibilityObject*);
108     bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); }
109     AXID platformGenerateAXID() const;
110     AccessibilityObject* objectFromAXID(AXID id) const { return m_objects.get(id).get(); }
111
112     // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
113     void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
114     void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
115     bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
116     
117     // Text marker utilities.
118     void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
119     VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
120
121     enum AXNotification {
122         AXActiveDescendantChanged,
123         AXCheckedStateChanged,
124         AXChildrenChanged,
125         AXFocusedUIElementChanged,
126         AXLayoutComplete,
127         AXLoadComplete,
128         AXSelectedChildrenChanged,
129         AXSelectedTextChanged,
130         AXValueChanged,
131         AXScrolledToAnchor,
132         AXLiveRegionChanged,
133         AXMenuListValueChanged,
134         AXRowCountChanged,
135         AXRowCollapsed,
136         AXRowExpanded,
137         AXInvalidStatusChanged,
138     };
139
140     void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously);
141     void postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously);
142
143     enum AXTextChange {
144         AXTextInserted,
145         AXTextDeleted,
146     };
147
148     void nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned offset, unsigned count);
149
150     bool nodeHasRole(Node*, const AtomicString& role);
151
152 protected:
153     void postPlatformNotification(AccessibilityObject*, AXNotification);
154     void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned offset, unsigned count);
155
156 private:
157     Document* m_document;
158     HashMap<AXID, RefPtr<AccessibilityObject> > m_objects;
159     HashMap<RenderObject*, AXID> m_renderObjectMapping;
160     HashMap<Widget*, AXID> m_widgetObjectMapping;
161     HashSet<Node*> m_textMarkerNodes;
162     static bool gAccessibilityEnabled;
163     static bool gAccessibilityEnhancedUserInterfaceEnabled;
164     
165     HashSet<AXID> m_idsInUse;
166     
167     Timer<AXObjectCache> m_notificationPostTimer;
168     Vector<pair<RefPtr<AccessibilityObject>, AXNotification> > m_notificationsToPost;
169     void notificationPostTimerFired(Timer<AXObjectCache>*);
170     
171     static AccessibilityObject* focusedImageMapUIElement(HTMLAreaElement*);
172     
173     AXID getAXID(AccessibilityObject*);
174     AccessibilityObject* get(Widget*);
175 };
176
177 bool nodeHasRole(Node*, const String& role);
178
179 #if !HAVE(ACCESSIBILITY)
180 inline void AXObjectCache::handleActiveDescendantChanged(RenderObject*) { }
181 inline void AXObjectCache::handleAriaRoleChanged(RenderObject*) { }
182 inline void AXObjectCache::detachWrapper(AccessibilityObject*) { }
183 inline void AXObjectCache::attachWrapper(AccessibilityObject*) { }
184 inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { }
185 inline void AXObjectCache::postNotification(RenderObject*, AXNotification, bool postToElement, PostType) { }
186 inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType) { }
187 inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { }
188 inline void AXObjectCache::nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned, unsigned) { }
189 inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) { }
190 inline void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) { }
191 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { }
192 inline void AXObjectCache::contentChanged(RenderObject*) { }
193 inline void AXObjectCache::handleAriaExpandedChange(RenderObject*) { }
194 inline void AXObjectCache::handleScrollbarUpdate(ScrollView*) { }
195 #endif
196
197 }
198
199 #endif