Home | History | Annotate | Download | only in accessibility
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_H_
      6 #define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_H_
      7 
      8 #include <map>
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/strings/string16.h"
     14 #include "build/build_config.h"
     15 #include "content/common/accessibility_node_data.h"
     16 #include "content/common/content_export.h"
     17 #include "third_party/WebKit/public/web/WebAXEnums.h"
     18 
     19 #if defined(OS_MACOSX) && __OBJC__
     20 @class BrowserAccessibilityCocoa;
     21 #endif
     22 
     23 namespace content {
     24 class BrowserAccessibilityManager;
     25 #if defined(OS_WIN)
     26 class BrowserAccessibilityWin;
     27 #elif defined(TOOLKIT_GTK)
     28 class BrowserAccessibilityGtk;
     29 #endif
     30 
     31 ////////////////////////////////////////////////////////////////////////////////
     32 //
     33 // BrowserAccessibility
     34 //
     35 // Class implementing the cross platform interface for the Browser-Renderer
     36 // communication of accessibility information, providing accessibility
     37 // to be used by screen readers and other assistive technology (AT).
     38 //
     39 // An implementation for each platform handles platform specific accessibility
     40 // APIs.
     41 //
     42 ////////////////////////////////////////////////////////////////////////////////
     43 class CONTENT_EXPORT BrowserAccessibility {
     44  public:
     45   // Creates a platform specific BrowserAccessibility. Ownership passes to the
     46   // caller.
     47   static BrowserAccessibility* Create();
     48 
     49   virtual ~BrowserAccessibility();
     50 
     51   // Detach all descendants of this subtree and push all of the node pointers,
     52   // including this node, onto the end of |nodes|.
     53   virtual void DetachTree(std::vector<BrowserAccessibility*>* nodes);
     54 
     55   // Perform platform-specific initialization. This can be called multiple times
     56   // during the lifetime of this instance after the members of this base object
     57   // have been reset with new values from the renderer process.
     58   // Child dependent initialization can be done here.
     59   virtual void PostInitialize() {}
     60 
     61   // Returns true if this is a native platform-specific object, vs a
     62   // cross-platform generic object.
     63   virtual bool IsNative() const;
     64 
     65   // Initialize the tree structure of this object.
     66   void InitializeTreeStructure(
     67       BrowserAccessibilityManager* manager,
     68       BrowserAccessibility* parent,
     69       int32 renderer_id,
     70       int32 index_in_parent);
     71 
     72   // Initialize this object's data.
     73   void InitializeData(const AccessibilityNodeData& src);
     74 
     75   virtual void SwapChildren(std::vector<BrowserAccessibility*>& children);
     76 
     77   // Update the parent and index in parent if this node has been moved.
     78   void UpdateParent(BrowserAccessibility* parent, int index_in_parent);
     79 
     80   // Update this node's location, leaving everything else the same.
     81   virtual void SetLocation(const gfx::Rect& new_location);
     82 
     83   // Return true if this object is equal to or a descendant of |ancestor|.
     84   bool IsDescendantOf(BrowserAccessibility* ancestor);
     85 
     86   // Returns the parent of this object, or NULL if it's the root.
     87   BrowserAccessibility* parent() const { return parent_; }
     88 
     89   // Returns the number of children of this object.
     90   uint32 child_count() const { return children_.size(); }
     91 
     92   // Returns true if this is a leaf node on this platform, meaning any
     93   // children should not be exposed to this platform's native accessibility
     94   // layer. Each platform subclass should implement this itself.
     95   // The definition of a leaf may vary depending on the platform,
     96   // but a leaf node should never have children that are focusable or
     97   // that might send notifications.
     98   virtual bool PlatformIsLeaf() const;
     99 
    100   // Returns the number of children of this object, or 0 if PlatformIsLeaf()
    101   // returns true.
    102   uint32 PlatformChildCount() const;
    103 
    104   // Return a pointer to the child at the given index, or NULL for an
    105   // invalid index. Returns NULL if PlatformIsLeaf() returns true.
    106   BrowserAccessibility* PlatformGetChild(uint32 child_index) const;
    107 
    108   // Return the previous sibling of this object, or NULL if it's the first
    109   // child of its parent.
    110   BrowserAccessibility* GetPreviousSibling();
    111 
    112   // Return the next sibling of this object, or NULL if it's the last child
    113   // of its parent.
    114   BrowserAccessibility* GetNextSibling();
    115 
    116   // Returns the bounds of this object in coordinates relative to the
    117   // top-left corner of the overall web area.
    118   gfx::Rect GetLocalBoundsRect() const;
    119 
    120   // Returns the bounds of this object in screen coordinates.
    121   gfx::Rect GetGlobalBoundsRect() const;
    122 
    123   // Returns the bounds of the given range in coordinates relative to the
    124   // top-left corner of the overall web area. Only valid when the
    125   // role is WebAXRoleStaticText.
    126   gfx::Rect GetLocalBoundsForRange(int start, int len) const;
    127 
    128   // Same as GetLocalBoundsForRange, in screen coordinates. Only valid when
    129   // the role is WebAXRoleStaticText.
    130   gfx::Rect GetGlobalBoundsForRange(int start, int len) const;
    131 
    132   // Returns the deepest descendant that contains the specified point
    133   // (in global screen coordinates).
    134   BrowserAccessibility* BrowserAccessibilityForPoint(const gfx::Point& point);
    135 
    136   // Marks this object for deletion, releases our reference to it, and
    137   // recursively calls Destroy() on its children.  May not delete
    138   // immediately due to reference counting.
    139   //
    140   // Reference counting is used on some platforms because the
    141   // operating system may hold onto a reference to a BrowserAccessibility
    142   // object even after we're through with it. When a BrowserAccessibility
    143   // has had Destroy() called but its reference count is not yet zero,
    144   // queries on this object return failure
    145   virtual void Destroy();
    146 
    147   // Subclasses should override this to support platform reference counting.
    148   virtual void NativeAddReference() { }
    149 
    150   // Subclasses should override this to support platform reference counting.
    151   virtual void NativeReleaseReference();
    152 
    153   //
    154   // Accessors
    155   //
    156 
    157   const std::vector<BrowserAccessibility*>& children() const {
    158     return children_;
    159   }
    160   const std::vector<std::pair<std::string, std::string> >&
    161   html_attributes() const {
    162     return html_attributes_;
    163   }
    164   int32 index_in_parent() const { return index_in_parent_; }
    165   gfx::Rect location() const { return location_; }
    166   BrowserAccessibilityManager* manager() const { return manager_; }
    167   const std::string& name() const { return name_; }
    168   const std::string& value() const { return value_; }
    169   int32 renderer_id() const { return renderer_id_; }
    170   int32 role() const { return role_; }
    171   int32 state() const { return state_; }
    172   bool instance_active() const { return instance_active_; }
    173 
    174   void set_name(const std::string& name) { name_ = name; }
    175   void set_value(const std::string& value) { value_ = value; }
    176 
    177 #if defined(OS_MACOSX) && __OBJC__
    178   BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa();
    179 #elif defined(OS_WIN)
    180   BrowserAccessibilityWin* ToBrowserAccessibilityWin();
    181 #elif defined(TOOLKIT_GTK)
    182   BrowserAccessibilityGtk* ToBrowserAccessibilityGtk();
    183 #endif
    184 
    185   // Accessing accessibility attributes:
    186   //
    187   // There are dozens of possible attributes for an accessibility node,
    188   // but only a few tend to apply to any one object, so we store them
    189   // in sparse arrays of <attribute id, attribute value> pairs, organized
    190   // by type (bool, int, float, string, int list).
    191   //
    192   // There are three accessors for each type of attribute: one that returns
    193   // true if the attribute is present and false if not, one that takes a
    194   // pointer argument and returns true if the attribute is present (if you
    195   // need to distinguish between the default value and a missing attribute),
    196   // and another that returns the default value for that type if the
    197   // attribute is not present. In addition, strings can be returned as
    198   // either std::string or base::string16, for convenience.
    199 
    200   bool HasBoolAttribute(AccessibilityNodeData::BoolAttribute attr) const;
    201   bool GetBoolAttribute(AccessibilityNodeData::BoolAttribute attr) const;
    202   bool GetBoolAttribute(AccessibilityNodeData::BoolAttribute attr,
    203                         bool* value) const;
    204 
    205   bool HasFloatAttribute(AccessibilityNodeData::FloatAttribute attr) const;
    206   float GetFloatAttribute(AccessibilityNodeData::FloatAttribute attr) const;
    207   bool GetFloatAttribute(AccessibilityNodeData::FloatAttribute attr,
    208                          float* value) const;
    209 
    210   bool HasIntAttribute(AccessibilityNodeData::IntAttribute attribute) const;
    211   int GetIntAttribute(AccessibilityNodeData::IntAttribute attribute) const;
    212   bool GetIntAttribute(AccessibilityNodeData::IntAttribute attribute,
    213                        int* value) const;
    214 
    215   bool HasStringAttribute(
    216       AccessibilityNodeData::StringAttribute attribute) const;
    217   const std::string& GetStringAttribute(
    218       AccessibilityNodeData::StringAttribute attribute) const;
    219   bool GetStringAttribute(AccessibilityNodeData::StringAttribute attribute,
    220                           std::string* value) const;
    221 
    222   bool GetString16Attribute(AccessibilityNodeData::StringAttribute attribute,
    223                             base::string16* value) const;
    224   base::string16 GetString16Attribute(
    225       AccessibilityNodeData::StringAttribute attribute) const;
    226 
    227   bool HasIntListAttribute(
    228       AccessibilityNodeData::IntListAttribute attribute) const;
    229   const std::vector<int32>& GetIntListAttribute(
    230       AccessibilityNodeData::IntListAttribute attribute) const;
    231   bool GetIntListAttribute(AccessibilityNodeData::IntListAttribute attribute,
    232                            std::vector<int32>* value) const;
    233 
    234   void SetStringAttribute(
    235       AccessibilityNodeData::StringAttribute attribute,
    236       const std::string& value);
    237 
    238   // Retrieve the value of a html attribute from the attribute map and
    239   // returns true if found.
    240   bool GetHtmlAttribute(const char* attr, base::string16* value) const;
    241   bool GetHtmlAttribute(const char* attr, std::string* value) const;
    242 
    243   // Utility method to handle special cases for ARIA booleans, tristates and
    244   // booleans which have a "mixed" state.
    245   //
    246   // Warning: the term "Tristate" is used loosely by the spec and here,
    247   // as some attributes support a 4th state.
    248   //
    249   // The following attributes are appropriate to use with this method:
    250   // aria-selected  (selectable)
    251   // aria-grabbed   (grabbable)
    252   // aria-expanded  (expandable)
    253   // aria-pressed   (toggleable/pressable) -- supports 4th "mixed" state
    254   // aria-checked   (checkable) -- supports 4th "mixed state"
    255   bool GetAriaTristate(const char* attr_name,
    256                        bool* is_defined,
    257                        bool* is_mixed) const;
    258 
    259   // Returns true if the bit corresponding to the given state enum is 1.
    260   bool HasState(blink::WebAXState state_enum) const;
    261 
    262   // Returns true if this node is an editable text field of any kind.
    263   bool IsEditableText() const;
    264 
    265   // Append the text from this node and its children.
    266   std::string GetTextRecursive() const;
    267 
    268  protected:
    269   // Perform platform specific initialization. This can be called multiple times
    270   // during the lifetime of this instance after the members of this base object
    271   // have been reset with new values from the renderer process.
    272   // Perform child independent initialization in this method.
    273   virtual void PreInitialize() {}
    274 
    275   BrowserAccessibility();
    276 
    277   // The manager of this tree of accessibility objects; needed for
    278   // global operations like focus tracking.
    279   BrowserAccessibilityManager* manager_;
    280 
    281   // The parent of this object, may be NULL if we're the root object.
    282   BrowserAccessibility* parent_;
    283 
    284  private:
    285   // The index of this within its parent object.
    286   int32 index_in_parent_;
    287 
    288   // The ID of this object in the renderer process.
    289   int32 renderer_id_;
    290 
    291   // The children of this object.
    292   std::vector<BrowserAccessibility*> children_;
    293 
    294   // Accessibility metadata from the renderer
    295   std::string name_;
    296   std::string value_;
    297   std::vector<std::pair<
    298       AccessibilityNodeData::BoolAttribute, bool> > bool_attributes_;
    299   std::vector<std::pair<
    300       AccessibilityNodeData::FloatAttribute, float> > float_attributes_;
    301   std::vector<std::pair<
    302       AccessibilityNodeData::IntAttribute, int> > int_attributes_;
    303   std::vector<std::pair<
    304       AccessibilityNodeData::StringAttribute, std::string> > string_attributes_;
    305   std::vector<std::pair<
    306       AccessibilityNodeData::IntListAttribute, std::vector<int32> > >
    307           intlist_attributes_;
    308   std::vector<std::pair<std::string, std::string> > html_attributes_;
    309   int32 role_;
    310   int32 state_;
    311   gfx::Rect location_;
    312 
    313   // BrowserAccessibility objects are reference-counted on some platforms.
    314   // When we're done with this object and it's removed from our accessibility
    315   // tree, a client may still be holding onto a pointer to this object, so
    316   // we mark it as inactive so that calls to any of this object's methods
    317   // immediately return failure.
    318   bool instance_active_;
    319 
    320  private:
    321   DISALLOW_COPY_AND_ASSIGN(BrowserAccessibility);
    322 };
    323 
    324 }  // namespace content
    325 
    326 #endif  // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_H_
    327