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(const 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 detachWrapper(AXObject*);
    112     void attachWrapper(AXObject*);
    113     void childrenChanged(Node*);
    114     void childrenChanged(RenderObject*);
    115     void childrenChanged(AXObject*);
    116     void checkedStateChanged(Node*);
    117     void selectedChildrenChanged(Node*);
    118     void selectedChildrenChanged(RenderObject*);
    119     void selectionChanged(Node*);
    120     // Called by a node when text or a text equivalent (e.g. alt) attribute is changed.
    121     void textChanged(Node*);
    122     void textChanged(RenderObject*);
    123     // Called when a node has just been attached, so we can make sure we have the right subclass of AXObject.
    124     void updateCacheAfterNodeIsAttached(Node*);
    125 
    126     void handleActiveDescendantChanged(Node*);
    127     void handleAriaRoleChanged(Node*);
    128     void handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
    129     void handleScrolledToAnchor(const Node* anchorNode);
    130     void handleAriaExpandedChange(Node*);
    131     void handleScrollbarUpdate(ScrollView*);
    132 
    133     void handleAttributeChanged(const QualifiedName& attrName, Element*);
    134     void recomputeIsIgnored(RenderObject* renderer);
    135 
    136     static void enableAccessibility() { gAccessibilityEnabled = true; }
    137     static bool accessibilityEnabled() { return gAccessibilityEnabled; }
    138     static void setInlineTextBoxAccessibility(bool flag) { gInlineTextBoxAccessibility = flag; }
    139     static bool inlineTextBoxAccessibility() { return gInlineTextBoxAccessibility; }
    140 
    141     void removeAXID(AXObject*);
    142     bool isIDinUse(AXID id) const { return m_idsInUse.contains(id); }
    143 
    144     Element* rootAXEditableElement(Node*);
    145     const Element* rootAXEditableElement(const Node*);
    146     bool nodeIsTextControl(const Node*);
    147 
    148     AXID platformGenerateAXID() const;
    149     AXObject* objectFromAXID(AXID id) const { return m_objects.get(id); }
    150 
    151     // Text marker utilities.
    152     void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
    153     VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
    154 
    155     enum AXNotification {
    156         AXActiveDescendantChanged,
    157         AXAlert,
    158         AXAriaAttributeChanged,
    159         AXAutocorrectionOccured,
    160         AXBlur,
    161         AXCheckedStateChanged,
    162         AXChildrenChanged,
    163         AXFocusedUIElementChanged,
    164         AXHide,
    165         AXInvalidStatusChanged,
    166         AXLayoutComplete,
    167         AXLiveRegionChanged,
    168         AXLoadComplete,
    169         AXLocationChanged,
    170         AXMenuListItemSelected,
    171         AXMenuListValueChanged,
    172         AXRowCollapsed,
    173         AXRowCountChanged,
    174         AXRowExpanded,
    175         AXScrolledToAnchor,
    176         AXSelectedChildrenChanged,
    177         AXSelectedTextChanged,
    178         AXShow,
    179         AXTextChanged,
    180         AXTextInserted,
    181         AXTextRemoved,
    182         AXValueChanged
    183     };
    184 
    185     void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously);
    186     void postNotification(Node*, AXNotification, bool postToElement, PostType = PostAsynchronously);
    187     void postNotification(AXObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously);
    188 
    189     bool nodeHasRole(Node*, const AtomicString& role);
    190 
    191     void startCachingComputedObjectAttributesUntilTreeMutates();
    192     void stopCachingComputedObjectAttributes();
    193 
    194     AXComputedObjectAttributeCache* computedObjectAttributeCache() { return m_computedObjectAttributeCache.get(); }
    195 
    196 protected:
    197     void postPlatformNotification(AXObject*, AXNotification);
    198     void textChanged(AXObject*);
    199     void labelChanged(Element*);
    200 
    201     // This is a weak reference cache for knowing if Nodes used by TextMarkers are valid.
    202     void setNodeInUse(Node* n) { m_textMarkerNodes.add(n); }
    203     void removeNodeForUse(Node* n) { m_textMarkerNodes.remove(n); }
    204     bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
    205 
    206 private:
    207     Document* m_document;
    208     HashMap<AXID, RefPtr<AXObject> > m_objects;
    209     HashMap<RenderObject*, AXID> m_renderObjectMapping;
    210     HashMap<Widget*, AXID> m_widgetObjectMapping;
    211     HashMap<Node*, AXID> m_nodeObjectMapping;
    212     HashMap<AbstractInlineTextBox*, AXID> m_inlineTextBoxObjectMapping;
    213     HashSet<Node*> m_textMarkerNodes;
    214     OwnPtr<AXComputedObjectAttributeCache> m_computedObjectAttributeCache;
    215     static bool gAccessibilityEnabled;
    216     static bool gInlineTextBoxAccessibility;
    217 
    218     HashSet<AXID> m_idsInUse;
    219 
    220     Timer<AXObjectCache> m_notificationPostTimer;
    221     Vector<pair<RefPtr<AXObject>, AXNotification> > m_notificationsToPost;
    222     void notificationPostTimerFired(Timer<AXObjectCache>*);
    223 
    224     static AXObject* focusedImageMapUIElement(HTMLAreaElement*);
    225 
    226     AXID getAXID(AXObject*);
    227 };
    228 
    229 bool nodeHasRole(Node*, const String& role);
    230 // This will let you know if aria-hidden was explicitly set to false.
    231 bool isNodeAriaVisible(Node*);
    232 
    233 }
    234 
    235 #endif
    236