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