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 "base/strings/string_split.h"
15#include "build/build_config.h"
16#include "content/common/content_export.h"
17#include "third_party/WebKit/public/web/WebAXEnums.h"
18#include "ui/accessibility/ax_node.h"
19#include "ui/accessibility/ax_node_data.h"
20
21#if defined(OS_MACOSX) && __OBJC__
22@class BrowserAccessibilityCocoa;
23#endif
24
25namespace content {
26class BrowserAccessibilityManager;
27#if defined(OS_WIN)
28class BrowserAccessibilityWin;
29#endif
30
31////////////////////////////////////////////////////////////////////////////////
32//
33// BrowserAccessibility
34//
35// A BrowserAccessibility object represents one node in the accessibility
36// tree on the browser side. It exactly corresponds to one WebAXObject from
37// Blink. It's owned by a BrowserAccessibilityManager.
38//
39// There are subclasses of BrowserAccessibility for each platform where
40// we implement native accessibility APIs. This base class is used occasionally
41// for tests.
42//
43////////////////////////////////////////////////////////////////////////////////
44class CONTENT_EXPORT BrowserAccessibility {
45 public:
46  // Creates a platform specific BrowserAccessibility. Ownership passes to the
47  // caller.
48  static BrowserAccessibility* Create();
49
50  virtual ~BrowserAccessibility();
51
52  // Called only once, immediately after construction. The constructor doesn't
53  // take any arguments because in the Windows subclass we use a special
54  // function to construct a COM object.
55  virtual void Init(BrowserAccessibilityManager* manager, ui::AXNode* node);
56
57  // Called after the object is first initialized and again every time
58  // its data changes.
59  virtual void OnDataChanged();
60
61  // Called after an atomic update to the tree finished and this object
62  // was created or changed in this update.
63  virtual void OnUpdateFinished() {}
64
65  // Returns true if this is a native platform-specific object, vs a
66  // cross-platform generic object.
67  virtual bool IsNative() const;
68
69  // Called when the location changed.
70  virtual void OnLocationChanged() {}
71
72  // Return true if this object is equal to or a descendant of |ancestor|.
73  bool IsDescendantOf(BrowserAccessibility* ancestor);
74
75  // Returns true if this is a leaf node on this platform, meaning any
76  // children should not be exposed to this platform's native accessibility
77  // layer. Each platform subclass should implement this itself.
78  // The definition of a leaf may vary depending on the platform,
79  // but a leaf node should never have children that are focusable or
80  // that might send notifications.
81  virtual bool PlatformIsLeaf() const;
82
83  // Returns the number of children of this object, or 0 if PlatformIsLeaf()
84  // returns true.
85  uint32 PlatformChildCount() const;
86
87  // Return a pointer to the child at the given index, or NULL for an
88  // invalid index. Returns NULL if PlatformIsLeaf() returns true.
89  BrowserAccessibility* PlatformGetChild(uint32 child_index) const;
90
91  // Return the previous sibling of this object, or NULL if it's the first
92  // child of its parent.
93  BrowserAccessibility* GetPreviousSibling();
94
95  // Return the next sibling of this object, or NULL if it's the last child
96  // of its parent.
97  BrowserAccessibility* GetNextSibling();
98
99  // Returns the bounds of this object in coordinates relative to the
100  // top-left corner of the overall web area.
101  gfx::Rect GetLocalBoundsRect() const;
102
103  // Returns the bounds of this object in screen coordinates.
104  gfx::Rect GetGlobalBoundsRect() const;
105
106  // Returns the bounds of the given range in coordinates relative to the
107  // top-left corner of the overall web area. Only valid when the
108  // role is WebAXRoleStaticText.
109  gfx::Rect GetLocalBoundsForRange(int start, int len) const;
110
111  // Same as GetLocalBoundsForRange, in screen coordinates. Only valid when
112  // the role is WebAXRoleStaticText.
113  gfx::Rect GetGlobalBoundsForRange(int start, int len) const;
114
115  // Returns the deepest descendant that contains the specified point
116  // (in global screen coordinates).
117  BrowserAccessibility* BrowserAccessibilityForPoint(const gfx::Point& point);
118
119  // Marks this object for deletion, releases our reference to it, and
120  // nulls out the pointer to the underlying AXNode.  May not delete
121  // the object immediately due to reference counting.
122  //
123  // Reference counting is used on some platforms because the
124  // operating system may hold onto a reference to a BrowserAccessibility
125  // object even after we're through with it. When a BrowserAccessibility
126  // has had Destroy() called but its reference count is not yet zero,
127  // instance_active() returns false and queries on this object return failure.
128  virtual void Destroy();
129
130  // Subclasses should override this to support platform reference counting.
131  virtual void NativeAddReference() { }
132
133  // Subclasses should override this to support platform reference counting.
134  virtual void NativeReleaseReference();
135
136  //
137  // Accessors
138  //
139
140  BrowserAccessibilityManager* manager() const { return manager_; }
141  bool instance_active() const { return node_ != NULL; }
142  ui::AXNode* node() const { return node_; }
143  const std::string& name() const { return name_; }
144  const std::string& value() const { return value_; }
145  void set_name(const std::string& name) { name_ = name; }
146  void set_value(const std::string& value) { value_ = value; }
147
148  // These access the internal accessibility tree, which doesn't necessarily
149  // reflect the accessibility tree that should be exposed on each platform.
150  // Use PlatformChildCount and PlatformGetChild to implement platform
151  // accessibility APIs.
152  uint32 InternalChildCount() const;
153  BrowserAccessibility* InternalGetChild(uint32 child_index) const;
154
155  BrowserAccessibility* GetParent() const;
156  int32 GetIndexInParent() const;
157
158  int32 GetId() const;
159  const ui::AXNodeData& GetData() const;
160  gfx::Rect GetLocation() const;
161  int32 GetRole() const;
162  int32 GetState() const;
163
164  typedef base::StringPairs HtmlAttributes;
165  const HtmlAttributes& GetHtmlAttributes() const;
166
167#if defined(OS_MACOSX) && __OBJC__
168  BrowserAccessibilityCocoa* ToBrowserAccessibilityCocoa();
169#elif defined(OS_WIN)
170  BrowserAccessibilityWin* ToBrowserAccessibilityWin();
171#endif
172
173  // Accessing accessibility attributes:
174  //
175  // There are dozens of possible attributes for an accessibility node,
176  // but only a few tend to apply to any one object, so we store them
177  // in sparse arrays of <attribute id, attribute value> pairs, organized
178  // by type (bool, int, float, string, int list).
179  //
180  // There are three accessors for each type of attribute: one that returns
181  // true if the attribute is present and false if not, one that takes a
182  // pointer argument and returns true if the attribute is present (if you
183  // need to distinguish between the default value and a missing attribute),
184  // and another that returns the default value for that type if the
185  // attribute is not present. In addition, strings can be returned as
186  // either std::string or base::string16, for convenience.
187
188  bool HasBoolAttribute(ui::AXBoolAttribute attr) const;
189  bool GetBoolAttribute(ui::AXBoolAttribute attr) const;
190  bool GetBoolAttribute(ui::AXBoolAttribute attr, bool* value) const;
191
192  bool HasFloatAttribute(ui::AXFloatAttribute attr) const;
193  float GetFloatAttribute(ui::AXFloatAttribute attr) const;
194  bool GetFloatAttribute(ui::AXFloatAttribute attr, float* value) const;
195
196  bool HasIntAttribute(ui::AXIntAttribute attribute) const;
197  int GetIntAttribute(ui::AXIntAttribute attribute) const;
198  bool GetIntAttribute(ui::AXIntAttribute attribute, int* value) const;
199
200  bool HasStringAttribute(
201      ui::AXStringAttribute attribute) const;
202  const std::string& GetStringAttribute(ui::AXStringAttribute attribute) const;
203  bool GetStringAttribute(ui::AXStringAttribute attribute,
204                          std::string* value) const;
205
206  bool GetString16Attribute(ui::AXStringAttribute attribute,
207                            base::string16* value) const;
208  base::string16 GetString16Attribute(
209      ui::AXStringAttribute attribute) const;
210
211  bool HasIntListAttribute(ui::AXIntListAttribute attribute) const;
212  const std::vector<int32>& GetIntListAttribute(
213      ui::AXIntListAttribute attribute) const;
214  bool GetIntListAttribute(ui::AXIntListAttribute attribute,
215                           std::vector<int32>* value) const;
216
217  void SetStringAttribute(ui::AXStringAttribute attribute,
218                          const std::string& value);
219
220  // Retrieve the value of a html attribute from the attribute map and
221  // returns true if found.
222  bool GetHtmlAttribute(const char* attr, base::string16* value) const;
223  bool GetHtmlAttribute(const char* attr, std::string* value) const;
224
225  // Utility method to handle special cases for ARIA booleans, tristates and
226  // booleans which have a "mixed" state.
227  //
228  // Warning: the term "Tristate" is used loosely by the spec and here,
229  // as some attributes support a 4th state.
230  //
231  // The following attributes are appropriate to use with this method:
232  // aria-selected  (selectable)
233  // aria-grabbed   (grabbable)
234  // aria-expanded  (expandable)
235  // aria-pressed   (toggleable/pressable) -- supports 4th "mixed" state
236  // aria-checked   (checkable) -- supports 4th "mixed state"
237  bool GetAriaTristate(const char* attr_name,
238                       bool* is_defined,
239                       bool* is_mixed) const;
240
241  // Returns true if the bit corresponding to the given state enum is 1.
242  bool HasState(ui::AXState state_enum) const;
243
244  // Returns true if this node is an editable text field of any kind.
245  bool IsEditableText() const;
246
247  // Append the text from this node and its children.
248  std::string GetTextRecursive() const;
249
250 protected:
251  BrowserAccessibility();
252
253  // The manager of this tree of accessibility objects.
254  BrowserAccessibilityManager* manager_;
255
256  // The underlying node.
257  ui::AXNode* node_;
258
259 private:
260  // Return the sum of the lengths of all static text descendants,
261  // including this object if it's static text.
262  int GetStaticTextLenRecursive() const;
263
264  std::string name_;
265  std::string value_;
266
267  DISALLOW_COPY_AND_ASSIGN(BrowserAccessibility);
268};
269
270}  // namespace content
271
272#endif  // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_H_
273