Home | History | Annotate | Download | only in accessibility
      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 "core/accessibility/AXObject.h"
     30 #include "core/rendering/RenderText.h"
     31 #include "platform/Timer.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 AbstractInlineTextBox;
     40 class Document;
     41 class HTMLAreaElement;
     42 class Node;
     43 class Page;
     44 class RenderObject;
     45 class ScrollView;
     46 class VisiblePosition;
     47 class Widget;
     48 
     49 struct TextMarkerData {
     50     AXID axID;
     51     Node* node;
     52     int offset;
     53     EAffinity affinity;
     54 };
     55 
     56 class AXComputedObjectAttributeCache {
     57 public:
     58     static PassOwnPtr<AXComputedObjectAttributeCache> create() { return adoptPtr(new AXComputedObjectAttributeCache()); }
     59 
     60     AXObjectInclusion getIgnored(AXID) const;
     61     void setIgnored(AXID, AXObjectInclusion);
     62 
     63     void clear();
     64 
     65 private:
     66     AXComputedObjectAttributeCache() { }
     67 
     68     struct CachedAXObjectAttributes {
     69         CachedAXObjectAttributes() : ignored(DefaultBehavior) { }
     70 
     71         AXObjectInclusion ignored;
     72     };
     73 
     74     HashMap<AXID, CachedAXObjectAttributes> m_idMapping;
     75 };
     76 
     77 enum PostType { PostSynchronously, PostAsynchronously };
     78 
     79 class AXObjectCache {
     80     WTF_MAKE_NONCOPYABLE(AXObjectCache); WTF_MAKE_FAST_ALLOCATED;
     81 public:
     82     explicit AXObjectCache(Document&);
     83     ~AXObjectCache();
     84 
     85     static AXObject* focusedUIElementForPage(const Page*);
     86 
     87     // Returns the root object for the entire document.
     88     AXObject* rootObject();
     89 
     90     // For AX objects with elements that back them.
     91     AXObject* getOrCreate(RenderObject*);
     92     AXObject* getOrCreate(Widget*);
     93     AXObject* getOrCreate(Node*);
     94     AXObject* getOrCreate(AbstractInlineTextBox*);
     95 
     96     // used for objects without backing elements
     97     AXObject* getOrCreate(AccessibilityRole);
     98 
     99     // will only return the AXObject if it already exists
    100     AXObject* get(RenderObject*);
    101     AXObject* get(Widget*);
    102     AXObject* get(Node*);
    103     AXObject* get(AbstractInlineTextBox*);
    104 
    105     void remove(RenderObject*);
    106     void remove(Node*);
    107     void remove(Widget*);
    108     void remove(AbstractInlineTextBox*);
    109     void remove(AXID);
    110 
    111     void clearWeakMembers(Visitor*);
    112 
    113     void detachWrapper(AXObject*);
    114     void attachWrapper(AXObject*);
    115     void childrenChanged(Node*);
    116     void childrenChanged(RenderObject*);
    117     void childrenChanged(AXObject*);
    118     void checkedStateChanged(Node*);
    119     void selectedChildrenChanged(Node*);
    120     void selectedChildrenChanged(RenderObject*);
    121     void selectionChanged(Node*);
    122     // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
    123     void textChanged(Node*);
    124     void textChanged(RenderObject*);
    125     // Called when a node has just been attached, so we can make sure we have the right subclass of AXObject.
    126     void updateCacheAfterNodeIsAttached(Node*);
    127 
    128     void handleActiveDescendantChanged(Node*);
    129     void handleAriaRoleChanged(Node*);
    130     void handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
    131     void handleScrolledToAnchor(const Node* anchorNode);
    132     void handleAriaExpandedChange(Node*);
    133 
    134     // Called when scroll bars are added / removed (as the view resizes).
    135     void handleScrollbarUpdate(ScrollView*);
    136 
    137     void handleLayoutComplete(RenderObject*);
    138 
    139     // Called when the scroll offset changes.
    140     void handleScrollPositionChanged(ScrollView*);
    141     void handleScrollPositionChanged(RenderObject*);
    142 
    143     void handleAttributeChanged(const QualifiedName& attrName, Element*);
    144     void recomputeIsIgnored(RenderObject* renderer);
    145 
    146     void inlineTextBoxesUpdated(RenderObject* renderer);
    147 
    148     static void enableAccessibility() { gAccessibilityEnabled = true; }
    149     static bool accessibilityEnabled() { return gAccessibilityEnabled; }
    150     static void setInlineTextBoxAccessibility(bool flag) { gInlineTextBoxAccessibility = flag; }
    151     static bool inlineTextBoxAccessibility() { return gInlineTextBoxAccessibility; }
    152 
    153     void removeAXID(AXObject*);
    154     bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); }
    155 
    156     Element* rootAXEditableElement(Node*);
    157     const Element* rootAXEditableElement(const Node*);
    158     bool nodeIsTextControl(const Node*);
    159 
    160     AXID platformGenerateAXID() const;
    161     AXObject* objectFromAXID(AXID id) const { return m_objects.get(id); }
    162 
    163     enum AXNotification {
    164         AXActiveDescendantChanged,
    165         AXAlert,
    166         AXAriaAttributeChanged,
    167         AXAutocorrectionOccured,
    168         AXBlur,
    169         AXCheckedStateChanged,
    170         AXChildrenChanged,
    171         AXFocusedUIElementChanged,
    172         AXHide,
    173         AXInvalidStatusChanged,
    174         AXLayoutComplete,
    175         AXLiveRegionChanged,
    176         AXLoadComplete,
    177         AXLocationChanged,
    178         AXMenuListItemSelected,
    179         AXMenuListValueChanged,
    180         AXRowCollapsed,
    181         AXRowCountChanged,
    182         AXRowExpanded,
    183         AXScrollPositionChanged,
    184         AXScrolledToAnchor,
    185         AXSelectedChildrenChanged,
    186         AXSelectedTextChanged,
    187         AXShow,
    188         AXTextChanged,
    189         AXTextInserted,
    190         AXTextRemoved,
    191         AXValueChanged
    192     };
    193 
    194     void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously);
    195     void postNotification(Node*, AXNotification, bool postToElement, PostType = PostAsynchronously);
    196     void postNotification(AXObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously);
    197 
    198     bool nodeHasRole(Node*, const AtomicString& role);
    199 
    200     AXComputedObjectAttributeCache* computedObjectAttributeCache() { return m_computedObjectAttributeCache.get(); }
    201 
    202 protected:
    203     void postPlatformNotification(AXObject*, AXNotification);
    204     void textChanged(AXObject*);
    205     void labelChanged(Element*);
    206 
    207     // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
    208     void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
    209     void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
    210     bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
    211 
    212 private:
    213     Document& m_document;
    214     HashMap<AXID, RefPtr<AXObject> > m_objects;
    215     HashMap<RenderObject*, AXID> m_renderObjectMapping;
    216     HashMap<Widget*, AXID> m_widgetObjectMapping;
    217     HashMap<Node*, AXID> m_nodeObjectMapping;
    218     HashMap<AbstractInlineTextBox*, AXID> m_inlineTextBoxObjectMapping;
    219     HashSet<Node*> m_textMarkerNodes;
    220     OwnPtr<AXComputedObjectAttributeCache> m_computedObjectAttributeCache;
    221     static bool gAccessibilityEnabled;
    222     static bool gInlineTextBoxAccessibility;
    223 
    224     HashSet<AXID> m_idsInUse;
    225 
    226     Timer<AXObjectCache> m_notificationPostTimer;
    227     Vector<pair<RefPtr<AXObject>, AXNotification> > m_notificationsToPost;
    228     void notificationPostTimerFired(Timer<AXObjectCache>*);
    229 
    230     static AXObject* focusedImageMapUIElement(HTMLAreaElement*);
    231 
    232     AXID getAXID(AXObject*);
    233 };
    234 
    235 bool nodeHasRole(Node*, const String& role);
    236 // This will let you know if aria-hidden was explicitly set to false.
    237 bool isNodeAriaVisible(Node*);
    238 
    239 }
    240 
    241 #endif
    242