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