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
23namespace content {
24class BrowserAccessibilityManager;
25#if defined(OS_WIN)
26class BrowserAccessibilityWin;
27#elif defined(TOOLKIT_GTK)
28class 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////////////////////////////////////////////////////////////////////////////////
43class 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