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