• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #include "chrome/browser/accessibility/browser_accessibility.h"
6 
7 #include "base/logging.h"
8 #include "base/string_number_conversions.h"
9 #include "chrome/browser/accessibility/browser_accessibility_manager.h"
10 
11 #if defined(OS_LINUX)
12 // There's no OS-specific implementation of BrowserAccessibilityManager
13 // on Linux, so just instantiate the base class.
14 // static
Create()15 BrowserAccessibility* BrowserAccessibility::Create() {
16   return new BrowserAccessibility();
17 }
18 #endif
19 
BrowserAccessibility()20 BrowserAccessibility::BrowserAccessibility()
21     : manager_(NULL),
22       parent_(NULL),
23       child_id_(0),
24       index_in_parent_(0),
25       renderer_id_(0),
26       ref_count_(1),
27       role_(0),
28       state_(0),
29       instance_active_(false) {
30 }
31 
~BrowserAccessibility()32 BrowserAccessibility::~BrowserAccessibility() {
33 }
34 
ReplaceChild(BrowserAccessibility * old_acc,BrowserAccessibility * new_acc)35 void BrowserAccessibility::ReplaceChild(
36     BrowserAccessibility* old_acc, BrowserAccessibility* new_acc) {
37   DCHECK_EQ(children_[old_acc->index_in_parent_], old_acc);
38 
39   old_acc = children_[old_acc->index_in_parent_];
40   children_[old_acc->index_in_parent_] = new_acc;
41 }
42 
Initialize(BrowserAccessibilityManager * manager,BrowserAccessibility * parent,int32 child_id,int32 index_in_parent,const webkit_glue::WebAccessibility & src)43 void BrowserAccessibility::Initialize(
44     BrowserAccessibilityManager* manager,
45     BrowserAccessibility* parent,
46     int32 child_id,
47     int32 index_in_parent,
48     const webkit_glue::WebAccessibility& src) {
49   manager_ = manager;
50   parent_ = parent;
51   child_id_ = child_id;
52   index_in_parent_ = index_in_parent;
53 
54   renderer_id_ = src.id;
55   name_ = src.name;
56   value_ = src.value;
57   attributes_ = src.attributes;
58   html_attributes_ = src.html_attributes;
59   location_ = src.location;
60   role_ = src.role;
61   state_ = src.state;
62   indirect_child_ids_ = src.indirect_child_ids;
63 
64   Initialize();
65 }
66 
Initialize()67 void BrowserAccessibility::Initialize() {
68   instance_active_ = true;
69 }
70 
AddChild(BrowserAccessibility * child)71 void BrowserAccessibility::AddChild(BrowserAccessibility* child) {
72   children_.push_back(child);
73 }
74 
DetachTree(std::vector<BrowserAccessibility * > * nodes)75 void BrowserAccessibility::DetachTree(
76     std::vector<BrowserAccessibility*>* nodes) {
77   nodes->push_back(this);
78   for (size_t i = 0; i < children_.size(); i++)
79     children_[i]->DetachTree(nodes);
80   children_.clear();
81   parent_ = NULL;
82 }
83 
UpdateParent(BrowserAccessibility * parent,int index_in_parent)84 void BrowserAccessibility::UpdateParent(BrowserAccessibility* parent,
85                                         int index_in_parent) {
86   parent_ = parent;
87   index_in_parent_ = index_in_parent;
88 }
89 
IsDescendantOf(BrowserAccessibility * ancestor)90 bool BrowserAccessibility::IsDescendantOf(
91     BrowserAccessibility* ancestor) {
92   if (this == ancestor) {
93     return true;
94   } else if (parent_) {
95     return parent_->IsDescendantOf(ancestor);
96   }
97 
98   return false;
99 }
100 
GetChild(uint32 child_index)101 BrowserAccessibility* BrowserAccessibility::GetChild(uint32 child_index) {
102   DCHECK(child_index < children_.size());
103   return children_[child_index];
104 }
105 
GetPreviousSibling()106 BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() {
107   if (parent_ && index_in_parent_ > 0)
108     return parent_->children_[index_in_parent_ - 1];
109 
110   return NULL;
111 }
112 
GetNextSibling()113 BrowserAccessibility* BrowserAccessibility::GetNextSibling() {
114   if (parent_ &&
115       index_in_parent_ >= 0 &&
116       index_in_parent_ < static_cast<int>(parent_->children_.size() - 1)) {
117     return parent_->children_[index_in_parent_ + 1];
118   }
119 
120   return NULL;
121 }
122 
GetBoundsRect()123 gfx::Rect BrowserAccessibility::GetBoundsRect() {
124   gfx::Rect bounds = location_;
125 
126   // Adjust the bounds by the top left corner of the containing view's bounds
127   // in screen coordinates.
128   gfx::Point top_left = manager_->GetViewBounds().origin();
129   bounds.Offset(top_left);
130 
131   // Adjust top left position by the root document's scroll offset.
132   BrowserAccessibility* root = manager_->GetRoot();
133   int scroll_x = 0;
134   int scroll_y = 0;
135   root->GetAttributeAsInt(
136     WebAccessibility::ATTR_DOC_SCROLLX, &scroll_x);
137   root->GetAttributeAsInt(
138     WebAccessibility::ATTR_DOC_SCROLLY, &scroll_y);
139   bounds.Offset(-scroll_x, -scroll_y);
140 
141   return bounds;
142 }
143 
BrowserAccessibilityForPoint(const gfx::Point & point)144 BrowserAccessibility* BrowserAccessibility::BrowserAccessibilityForPoint(
145     const gfx::Point& point) {
146   // Walk the children recursively looking for the BrowserAccessibility that
147   // most tightly encloses the specified point.
148   for (int i = children_.size() - 1; i >= 0; --i) {
149     BrowserAccessibility* child = children_[i];
150     if (child->GetBoundsRect().Contains(point))
151       return child->BrowserAccessibilityForPoint(point);
152   }
153   return this;
154 }
155 
InternalAddReference()156 void BrowserAccessibility::InternalAddReference() {
157   ref_count_++;
158 }
159 
InternalReleaseReference(bool recursive)160 void BrowserAccessibility::InternalReleaseReference(bool recursive) {
161   DCHECK_GT(ref_count_, 0);
162 
163   if (recursive || ref_count_ == 1) {
164     for (std::vector<BrowserAccessibility*>::iterator iter = children_.begin();
165          iter != children_.end();
166          ++iter) {
167       (*iter)->InternalReleaseReference(true);
168     }
169   }
170 
171   ref_count_--;
172   if (ref_count_ == 0) {
173     instance_active_ = false;
174     children_.clear();
175     manager_->Remove(child_id_, renderer_id_);
176     NativeReleaseReference();
177   }
178 }
179 
NativeReleaseReference()180 void BrowserAccessibility::NativeReleaseReference() {
181   delete this;
182 }
183 
HasAttribute(WebAccessibility::Attribute attribute)184 bool BrowserAccessibility::HasAttribute(
185     WebAccessibility::Attribute attribute) {
186   return (attributes_.find(attribute) != attributes_.end());
187 }
188 
GetAttribute(WebAccessibility::Attribute attribute,string16 * value)189 bool BrowserAccessibility::GetAttribute(
190     WebAccessibility::Attribute attribute, string16* value) {
191   std::map<int32, string16>::iterator iter = attributes_.find(attribute);
192   if (iter != attributes_.end()) {
193     *value = iter->second;
194     return true;
195   }
196 
197   return false;
198 }
199 
GetAttributeAsInt(WebAccessibility::Attribute attribute,int * value_int)200 bool BrowserAccessibility::GetAttributeAsInt(
201     WebAccessibility::Attribute attribute, int* value_int) {
202   string16 value_str;
203 
204   if (!GetAttribute(attribute, &value_str))
205     return false;
206 
207   if (!base::StringToInt(value_str, value_int))
208     return false;
209 
210   return true;
211 }
212