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