| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/accessibility/browser_accessibility.h" | 5 #include "content/browser/accessibility/browser_accessibility.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "content/browser/accessibility/browser_accessibility_manager.h" | 11 #include "content/browser/accessibility/browser_accessibility_manager.h" |
| 12 #include "content/common/accessibility_messages.h" | 12 #include "content/common/accessibility_messages.h" |
| 13 | 13 |
| 14 namespace content { | 14 namespace content { |
| 15 | 15 |
| 16 #if !defined(OS_MACOSX) && \ | 16 #if !defined(OS_MACOSX) && \ |
| 17 !defined(OS_WIN) && \ | 17 !defined(OS_WIN) && \ |
| 18 !defined(TOOLKIT_GTK) && \ | 18 !defined(TOOLKIT_GTK) && \ |
| 19 !defined(OS_ANDROID) | 19 !defined(OS_ANDROID) |
| 20 // We have subclassess of BrowserAccessibility on Mac, Linux/GTK, | 20 // We have subclassess of BrowserAccessibility on Mac, Linux/GTK, |
| 21 // and Win. For any other platform, instantiate the base class. | 21 // and Win. For any other platform, instantiate the base class. |
| 22 // static | 22 // static |
| 23 BrowserAccessibility* BrowserAccessibility::Create() { | 23 BrowserAccessibility* BrowserAccessibility::Create() { |
| 24 return new BrowserAccessibility(); | 24 return new BrowserAccessibility(); |
| 25 } | 25 } |
| 26 #endif | 26 #endif |
| 27 | 27 |
| 28 BrowserAccessibility::BrowserAccessibility() | 28 BrowserAccessibility::BrowserAccessibility() |
| 29 : manager_(NULL), | 29 : manager_(NULL), |
| 30 parent_(NULL), | 30 deprecated_parent_(NULL), |
| 31 index_in_parent_(0), | 31 deprecated_index_in_parent_(0), |
| 32 renderer_id_(0), | |
| 33 role_(0), | |
| 34 state_(0), | |
| 35 instance_active_(false) { | 32 instance_active_(false) { |
| 33 data_.id = 0; |
| 34 data_.role = ui::AX_ROLE_UNKNOWN; |
| 35 data_.state = 0; |
| 36 } | 36 } |
| 37 | 37 |
| 38 BrowserAccessibility::~BrowserAccessibility() { | 38 BrowserAccessibility::~BrowserAccessibility() { |
| 39 } | 39 } |
| 40 | 40 |
| 41 bool BrowserAccessibility::PlatformIsLeaf() const { | 41 bool BrowserAccessibility::PlatformIsLeaf() const { |
| 42 if (child_count() == 0) | 42 if (InternalChildCount() == 0) |
| 43 return true; | 43 return true; |
| 44 | 44 |
| 45 // All of these roles may have children that we use as internal | 45 // All of these roles may have children that we use as internal |
| 46 // implementation details, but we want to expose them as leaves | 46 // implementation details, but we want to expose them as leaves |
| 47 // to platform accessibility APIs. | 47 // to platform accessibility APIs. |
| 48 switch (role_) { | 48 switch (GetRole()) { |
| 49 case ui::AX_ROLE_EDITABLE_TEXT: | 49 case ui::AX_ROLE_EDITABLE_TEXT: |
| 50 case ui::AX_ROLE_SLIDER: | 50 case ui::AX_ROLE_SLIDER: |
| 51 case ui::AX_ROLE_STATIC_TEXT: | 51 case ui::AX_ROLE_STATIC_TEXT: |
| 52 case ui::AX_ROLE_TEXT_AREA: | 52 case ui::AX_ROLE_TEXT_AREA: |
| 53 case ui::AX_ROLE_TEXT_FIELD: | 53 case ui::AX_ROLE_TEXT_FIELD: |
| 54 return true; | 54 return true; |
| 55 default: | 55 default: |
| 56 return false; | 56 return false; |
| 57 } | 57 } |
| 58 } | 58 } |
| 59 | 59 |
| 60 uint32 BrowserAccessibility::PlatformChildCount() const { | 60 uint32 BrowserAccessibility::PlatformChildCount() const { |
| 61 return PlatformIsLeaf() ? 0 : children_.size(); | 61 return PlatformIsLeaf() ? 0 : InternalChildCount(); |
| 62 } | 62 } |
| 63 | 63 |
| 64 void BrowserAccessibility::DetachTree( | 64 void BrowserAccessibility::DetachTree( |
| 65 std::vector<BrowserAccessibility*>* nodes) { | 65 std::vector<BrowserAccessibility*>* nodes) { |
| 66 nodes->push_back(this); | 66 nodes->push_back(this); |
| 67 for (size_t i = 0; i < children_.size(); ++i) | 67 for (size_t i = 0; i < InternalChildCount(); ++i) |
| 68 children_[i]->DetachTree(nodes); | 68 InternalGetChild(i)->DetachTree(nodes); |
| 69 children_.clear(); | 69 deprecated_children_.clear(); |
| 70 parent_ = NULL; | 70 deprecated_parent_ = NULL; |
| 71 } | 71 } |
| 72 | 72 |
| 73 void BrowserAccessibility::InitializeTreeStructure( | 73 void BrowserAccessibility::InitializeTreeStructure( |
| 74 BrowserAccessibilityManager* manager, | 74 BrowserAccessibilityManager* manager, |
| 75 BrowserAccessibility* parent, | 75 BrowserAccessibility* parent, |
| 76 int32 renderer_id, | 76 int32 id, |
| 77 int32 index_in_parent) { | 77 int32 index_in_parent) { |
| 78 manager_ = manager; | 78 manager_ = manager; |
| 79 parent_ = parent; | 79 deprecated_parent_ = parent; |
| 80 renderer_id_ = renderer_id; | 80 data_.id = id; |
| 81 index_in_parent_ = index_in_parent; | 81 deprecated_index_in_parent_ = index_in_parent; |
| 82 } | 82 } |
| 83 | 83 |
| 84 void BrowserAccessibility::InitializeData(const ui::AXNodeData& src) { | 84 void BrowserAccessibility::InitializeData(const ui::AXNodeData& src) { |
| 85 DCHECK_EQ(renderer_id_, src.id); | 85 DCHECK_EQ(data_.id, src.id); |
| 86 role_ = src.role; | 86 data_ = src; |
| 87 state_ = src.state; | |
| 88 string_attributes_ = src.string_attributes; | |
| 89 int_attributes_ = src.int_attributes; | |
| 90 float_attributes_ = src.float_attributes; | |
| 91 bool_attributes_ = src.bool_attributes; | |
| 92 intlist_attributes_ = src.intlist_attributes; | |
| 93 html_attributes_ = src.html_attributes; | |
| 94 location_ = src.location; | |
| 95 instance_active_ = true; | 87 instance_active_ = true; |
| 96 | 88 |
| 97 GetStringAttribute(ui::AX_ATTR_NAME, &name_); | 89 GetStringAttribute(ui::AX_ATTR_NAME, &name_); |
| 98 GetStringAttribute(ui::AX_ATTR_VALUE, &value_); | 90 GetStringAttribute(ui::AX_ATTR_VALUE, &value_); |
| 99 | 91 |
| 100 PreInitialize(); | 92 PreInitialize(); |
| 101 } | 93 } |
| 102 | 94 |
| 103 bool BrowserAccessibility::IsNative() const { | 95 bool BrowserAccessibility::IsNative() const { |
| 104 return false; | 96 return false; |
| 105 } | 97 } |
| 106 | 98 |
| 107 void BrowserAccessibility::SwapChildren( | 99 void BrowserAccessibility::SwapChildren( |
| 108 std::vector<BrowserAccessibility*>& children) { | 100 std::vector<BrowserAccessibility*>& children) { |
| 109 children.swap(children_); | 101 children.swap(deprecated_children_); |
| 110 } | 102 } |
| 111 | 103 |
| 112 void BrowserAccessibility::UpdateParent(BrowserAccessibility* parent, | 104 void BrowserAccessibility::UpdateParent(BrowserAccessibility* parent, |
| 113 int index_in_parent) { | 105 int index_in_parent) { |
| 114 parent_ = parent; | 106 deprecated_parent_ = parent; |
| 115 index_in_parent_ = index_in_parent; | 107 deprecated_index_in_parent_ = index_in_parent; |
| 116 } | 108 } |
| 117 | 109 |
| 118 void BrowserAccessibility::SetLocation(const gfx::Rect& new_location) { | 110 void BrowserAccessibility::SetLocation(const gfx::Rect& new_location) { |
| 119 location_ = new_location; | 111 data_.location = new_location; |
| 120 } | 112 } |
| 121 | 113 |
| 122 bool BrowserAccessibility::IsDescendantOf( | 114 bool BrowserAccessibility::IsDescendantOf( |
| 123 BrowserAccessibility* ancestor) { | 115 BrowserAccessibility* ancestor) { |
| 124 if (this == ancestor) { | 116 if (this == ancestor) { |
| 125 return true; | 117 return true; |
| 126 } else if (parent_) { | 118 } else if (GetParent()) { |
| 127 return parent_->IsDescendantOf(ancestor); | 119 return GetParent()->IsDescendantOf(ancestor); |
| 128 } | 120 } |
| 129 | 121 |
| 130 return false; | 122 return false; |
| 131 } | 123 } |
| 132 | 124 |
| 133 BrowserAccessibility* BrowserAccessibility::PlatformGetChild( | 125 BrowserAccessibility* BrowserAccessibility::PlatformGetChild( |
| 134 uint32 child_index) const { | 126 uint32 child_index) const { |
| 135 DCHECK(child_index < children_.size()); | 127 DCHECK(child_index < InternalChildCount()); |
| 136 return children_[child_index]; | 128 return InternalGetChild(child_index); |
| 137 } | 129 } |
| 138 | 130 |
| 139 BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { | 131 BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { |
| 140 if (parent_ && index_in_parent_ > 0) | 132 if (GetParent() && GetIndexInParent() > 0) |
| 141 return parent_->children_[index_in_parent_ - 1]; | 133 return GetParent()->InternalGetChild(GetIndexInParent() - 1); |
| 142 | 134 |
| 143 return NULL; | 135 return NULL; |
| 144 } | 136 } |
| 145 | 137 |
| 146 BrowserAccessibility* BrowserAccessibility::GetNextSibling() { | 138 BrowserAccessibility* BrowserAccessibility::GetNextSibling() { |
| 147 if (parent_ && | 139 if (GetParent() && |
| 148 index_in_parent_ >= 0 && | 140 GetIndexInParent() >= 0 && |
| 149 index_in_parent_ < static_cast<int>(parent_->children_.size() - 1)) { | 141 GetIndexInParent() < static_cast<int>(GetParent()->InternalChildCount() -
1)) { |
| 150 return parent_->children_[index_in_parent_ + 1]; | 142 return GetParent()->InternalGetChild(GetIndexInParent() + 1); |
| 151 } | 143 } |
| 152 | 144 |
| 153 return NULL; | 145 return NULL; |
| 154 } | 146 } |
| 155 | 147 |
| 156 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { | 148 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { |
| 157 gfx::Rect bounds = location_; | 149 gfx::Rect bounds = GetLocation(); |
| 158 | 150 |
| 159 // Walk up the parent chain. Every time we encounter a Web Area, offset | 151 // Walk up the parent chain. Every time we encounter a Web Area, offset |
| 160 // based on the scroll bars and then offset based on the origin of that | 152 // based on the scroll bars and then offset based on the origin of that |
| 161 // nested web area. | 153 // nested web area. |
| 162 BrowserAccessibility* parent = parent_; | 154 BrowserAccessibility* parent = GetParent(); |
| 163 bool need_to_offset_web_area = | 155 bool need_to_offset_web_area = |
| 164 (role_ == ui::AX_ROLE_WEB_AREA || | 156 (GetRole() == ui::AX_ROLE_WEB_AREA || |
| 165 role_ == ui::AX_ROLE_ROOT_WEB_AREA); | 157 GetRole() == ui::AX_ROLE_ROOT_WEB_AREA); |
| 166 while (parent) { | 158 while (parent) { |
| 167 if (need_to_offset_web_area && | 159 if (need_to_offset_web_area && |
| 168 parent->location().width() > 0 && | 160 parent->GetLocation().width() > 0 && |
| 169 parent->location().height() > 0) { | 161 parent->GetLocation().height() > 0) { |
| 170 bounds.Offset(parent->location().x(), parent->location().y()); | 162 bounds.Offset(parent->GetLocation().x(), parent->GetLocation().y()); |
| 171 need_to_offset_web_area = false; | 163 need_to_offset_web_area = false; |
| 172 } | 164 } |
| 173 | 165 |
| 174 // On some platforms, we don't want to take the root scroll offsets | 166 // On some platforms, we don't want to take the root scroll offsets |
| 175 // into account. | 167 // into account. |
| 176 if (parent->role() == ui::AX_ROLE_ROOT_WEB_AREA && | 168 if (parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && |
| 177 !manager()->UseRootScrollOffsetsWhenComputingBounds()) { | 169 !manager()->UseRootScrollOffsetsWhenComputingBounds()) { |
| 178 break; | 170 break; |
| 179 } | 171 } |
| 180 | 172 |
| 181 if (parent->role() == ui::AX_ROLE_WEB_AREA || | 173 if (parent->GetRole() == ui::AX_ROLE_WEB_AREA || |
| 182 parent->role() == ui::AX_ROLE_ROOT_WEB_AREA) { | 174 parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA) { |
| 183 int sx = 0; | 175 int sx = 0; |
| 184 int sy = 0; | 176 int sy = 0; |
| 185 if (parent->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && | 177 if (parent->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && |
| 186 parent->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { | 178 parent->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { |
| 187 bounds.Offset(-sx, -sy); | 179 bounds.Offset(-sx, -sy); |
| 188 } | 180 } |
| 189 need_to_offset_web_area = true; | 181 need_to_offset_web_area = true; |
| 190 } | 182 } |
| 191 parent = parent->parent(); | 183 parent = parent->GetParent(); |
| 192 } | 184 } |
| 193 | 185 |
| 194 return bounds; | 186 return bounds; |
| 195 } | 187 } |
| 196 | 188 |
| 197 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { | 189 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { |
| 198 gfx::Rect bounds = GetLocalBoundsRect(); | 190 gfx::Rect bounds = GetLocalBoundsRect(); |
| 199 | 191 |
| 200 // Adjust the bounds by the top left corner of the containing view's bounds | 192 // Adjust the bounds by the top left corner of the containing view's bounds |
| 201 // in screen coordinates. | 193 // in screen coordinates. |
| 202 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); | 194 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); |
| 203 | 195 |
| 204 return bounds; | 196 return bounds; |
| 205 } | 197 } |
| 206 | 198 |
| 207 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) | 199 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) |
| 208 const { | 200 const { |
| 209 if (role() != ui::AX_ROLE_STATIC_TEXT) { | 201 if (GetRole() != ui::AX_ROLE_STATIC_TEXT) { |
| 210 // Apply recursively to all static text descendants. For example, if | 202 // Apply recursively to all static text descendants. For example, if |
| 211 // you call it on a div with two text node children, it just calls | 203 // you call it on a div with two text node children, it just calls |
| 212 // GetLocalBoundsForRange on each of the two children (adjusting | 204 // GetLocalBoundsForRange on each of the two children (adjusting |
| 213 // |start| for each one) and unions the resulting rects. | 205 // |start| for each one) and unions the resulting rects. |
| 214 gfx::Rect bounds; | 206 gfx::Rect bounds; |
| 215 for (size_t i = 0; i < children_.size(); ++i) { | 207 for (size_t i = 0; i < InternalChildCount(); ++i) { |
| 216 BrowserAccessibility* child = children_[i]; | 208 BrowserAccessibility* child = InternalGetChild(i); |
| 217 int child_len = child->GetStaticTextLenRecursive(); | 209 int child_len = child->GetStaticTextLenRecursive(); |
| 218 if (start < child_len && start + len > 0) { | 210 if (start < child_len && start + len > 0) { |
| 219 gfx::Rect child_rect = child->GetLocalBoundsForRange(start, len); | 211 gfx::Rect child_rect = child->GetLocalBoundsForRange(start, len); |
| 220 bounds.Union(child_rect); | 212 bounds.Union(child_rect); |
| 221 } | 213 } |
| 222 start -= child_len; | 214 start -= child_len; |
| 223 } | 215 } |
| 224 return bounds; | 216 return bounds; |
| 225 } | 217 } |
| 226 | 218 |
| 227 int end = start + len; | 219 int end = start + len; |
| 228 int child_start = 0; | 220 int child_start = 0; |
| 229 int child_end = 0; | 221 int child_end = 0; |
| 230 | 222 |
| 231 gfx::Rect bounds; | 223 gfx::Rect bounds; |
| 232 for (size_t i = 0; i < children_.size() && child_end < start + len; ++i) { | 224 for (size_t i = 0; i < InternalChildCount() && child_end < start + len; ++i) { |
| 233 BrowserAccessibility* child = children_[i]; | 225 BrowserAccessibility* child = InternalGetChild(i); |
| 234 DCHECK_EQ(child->role(), ui::AX_ROLE_INLINE_TEXT_BOX); | 226 DCHECK_EQ(child->GetRole(), ui::AX_ROLE_INLINE_TEXT_BOX); |
| 235 std::string child_text; | 227 std::string child_text; |
| 236 child->GetStringAttribute(ui::AX_ATTR_VALUE, &child_text); | 228 child->GetStringAttribute(ui::AX_ATTR_VALUE, &child_text); |
| 237 int child_len = static_cast<int>(child_text.size()); | 229 int child_len = static_cast<int>(child_text.size()); |
| 238 child_start = child_end; | 230 child_start = child_end; |
| 239 child_end += child_len; | 231 child_end += child_len; |
| 240 | 232 |
| 241 if (child_end < start) | 233 if (child_end < start) |
| 242 continue; | 234 continue; |
| 243 | 235 |
| 244 int overlap_start = std::max(start, child_start); | 236 int overlap_start = std::max(start, child_start); |
| 245 int overlap_end = std::min(end, child_end); | 237 int overlap_end = std::min(end, child_end); |
| 246 | 238 |
| 247 int local_start = overlap_start - child_start; | 239 int local_start = overlap_start - child_start; |
| 248 int local_end = overlap_end - child_start; | 240 int local_end = overlap_end - child_start; |
| 249 | 241 |
| 250 gfx::Rect child_rect = child->location(); | 242 gfx::Rect child_rect = child->GetLocation(); |
| 251 int text_direction = child->GetIntAttribute( | 243 int text_direction = child->GetIntAttribute( |
| 252 ui::AX_ATTR_TEXT_DIRECTION); | 244 ui::AX_ATTR_TEXT_DIRECTION); |
| 253 const std::vector<int32>& character_offsets = child->GetIntListAttribute( | 245 const std::vector<int32>& character_offsets = child->GetIntListAttribute( |
| 254 ui::AX_ATTR_CHARACTER_OFFSETS); | 246 ui::AX_ATTR_CHARACTER_OFFSETS); |
| 255 int start_pixel_offset = | 247 int start_pixel_offset = |
| 256 local_start > 0 ? character_offsets[local_start - 1] : 0; | 248 local_start > 0 ? character_offsets[local_start - 1] : 0; |
| 257 int end_pixel_offset = | 249 int end_pixel_offset = |
| 258 local_end > 0 ? character_offsets[local_end - 1] : 0; | 250 local_end > 0 ? character_offsets[local_end - 1] : 0; |
| 259 | 251 |
| 260 gfx::Rect child_overlap_rect; | 252 gfx::Rect child_overlap_rect; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 | 313 |
| 322 // Walk the children recursively looking for the BrowserAccessibility that | 314 // Walk the children recursively looking for the BrowserAccessibility that |
| 323 // most tightly encloses the specified point. Walk backwards so that in | 315 // most tightly encloses the specified point. Walk backwards so that in |
| 324 // the absence of any other information, we assume the object that occurs | 316 // the absence of any other information, we assume the object that occurs |
| 325 // later in the tree is on top of one that comes before it. | 317 // later in the tree is on top of one that comes before it. |
| 326 for (int i = static_cast<int>(PlatformChildCount()) - 1; i >= 0; --i) { | 318 for (int i = static_cast<int>(PlatformChildCount()) - 1; i >= 0; --i) { |
| 327 BrowserAccessibility* child = PlatformGetChild(i); | 319 BrowserAccessibility* child = PlatformGetChild(i); |
| 328 | 320 |
| 329 // Skip table columns because cells are only contained in rows, | 321 // Skip table columns because cells are only contained in rows, |
| 330 // not columns. | 322 // not columns. |
| 331 if (child->role() == ui::AX_ROLE_COLUMN) | 323 if (child->GetRole() == ui::AX_ROLE_COLUMN) |
| 332 continue; | 324 continue; |
| 333 | 325 |
| 334 if (child->GetGlobalBoundsRect().Contains(point)) { | 326 if (child->GetGlobalBoundsRect().Contains(point)) { |
| 335 BrowserAccessibility* result = child->BrowserAccessibilityForPoint(point); | 327 BrowserAccessibility* result = child->BrowserAccessibilityForPoint(point); |
| 336 if (result == child && !child_result) | 328 if (result == child && !child_result) |
| 337 child_result = result; | 329 child_result = result; |
| 338 if (result != child && !descendant_result) | 330 if (result != child && !descendant_result) |
| 339 descendant_result = result; | 331 descendant_result = result; |
| 340 } | 332 } |
| 341 | 333 |
| 342 if (child_result && descendant_result) | 334 if (child_result && descendant_result) |
| 343 break; | 335 break; |
| 344 } | 336 } |
| 345 | 337 |
| 346 // Explanation of logic: it's possible that this point overlaps more than | 338 // Explanation of logic: it's possible that this point overlaps more than |
| 347 // one child of this object. If so, as a heuristic we prefer if the point | 339 // one child of this object. If so, as a heuristic we prefer if the point |
| 348 // overlaps a descendant of one of the two children and not the other. | 340 // overlaps a descendant of one of the two children and not the other. |
| 349 // As an example, suppose you have two rows of buttons - the buttons don't | 341 // As an example, suppose you have two rows of buttons - the buttons don't |
| 350 // overlap, but the rows do. Without this heuristic, we'd greedily only | 342 // overlap, but the rows do. Without this heuristic, we'd greedily only |
| 351 // consider one of the containers. | 343 // consider one of the containers. |
| 352 if (descendant_result) | 344 if (descendant_result) |
| 353 return descendant_result; | 345 return descendant_result; |
| 354 if (child_result) | 346 if (child_result) |
| 355 return child_result; | 347 return child_result; |
| 356 | 348 |
| 357 return this; | 349 return this; |
| 358 } | 350 } |
| 359 | 351 |
| 360 void BrowserAccessibility::Destroy() { | 352 void BrowserAccessibility::Destroy() { |
| 361 for (std::vector<BrowserAccessibility*>::iterator iter = children_.begin(); | 353 for (uint32 i = 0; i < InternalChildCount(); i++) |
| 362 iter != children_.end(); | 354 InternalGetChild(i)->Destroy(); |
| 363 ++iter) { | 355 deprecated_children_.clear(); |
| 364 (*iter)->Destroy(); | |
| 365 } | |
| 366 children_.clear(); | |
| 367 | 356 |
| 368 // Allow the object to fire a TextRemoved notification. | 357 // Allow the object to fire a TextRemoved notification. |
| 369 name_.clear(); | 358 name_.clear(); |
| 370 value_.clear(); | 359 value_.clear(); |
| 371 PostInitialize(); | 360 PostInitialize(); |
| 372 | 361 |
| 373 manager_->NotifyAccessibilityEvent(ui::AX_EVENT_HIDE, this); | 362 manager_->NotifyAccessibilityEvent(ui::AX_EVENT_HIDE, this); |
| 374 | 363 |
| 375 instance_active_ = false; | 364 instance_active_ = false; |
| 376 manager_->RemoveNode(this); | 365 manager_->RemoveNode(this); |
| 377 NativeReleaseReference(); | 366 NativeReleaseReference(); |
| 378 } | 367 } |
| 379 | 368 |
| 380 void BrowserAccessibility::NativeReleaseReference() { | 369 void BrowserAccessibility::NativeReleaseReference() { |
| 381 delete this; | 370 delete this; |
| 382 } | 371 } |
| 383 | 372 |
| 384 bool BrowserAccessibility::HasBoolAttribute( | 373 bool BrowserAccessibility::HasBoolAttribute( |
| 385 ui::AXBoolAttribute attribute) const { | 374 ui::AXBoolAttribute attribute) const { |
| 386 for (size_t i = 0; i < bool_attributes_.size(); ++i) { | 375 for (size_t i = 0; i < data_.bool_attributes.size(); ++i) { |
| 387 if (bool_attributes_[i].first == attribute) | 376 if (data_.bool_attributes[i].first == attribute) |
| 388 return true; | 377 return true; |
| 389 } | 378 } |
| 390 | 379 |
| 391 return false; | 380 return false; |
| 392 } | 381 } |
| 393 | 382 |
| 394 | 383 |
| 395 bool BrowserAccessibility::GetBoolAttribute( | 384 bool BrowserAccessibility::GetBoolAttribute( |
| 396 ui::AXBoolAttribute attribute) const { | 385 ui::AXBoolAttribute attribute) const { |
| 397 for (size_t i = 0; i < bool_attributes_.size(); ++i) { | 386 for (size_t i = 0; i < data_.bool_attributes.size(); ++i) { |
| 398 if (bool_attributes_[i].first == attribute) | 387 if (data_.bool_attributes[i].first == attribute) |
| 399 return bool_attributes_[i].second; | 388 return data_.bool_attributes[i].second; |
| 400 } | 389 } |
| 401 | 390 |
| 402 return false; | 391 return false; |
| 403 } | 392 } |
| 404 | 393 |
| 405 bool BrowserAccessibility::GetBoolAttribute( | 394 bool BrowserAccessibility::GetBoolAttribute( |
| 406 ui::AXBoolAttribute attribute, bool* value) const { | 395 ui::AXBoolAttribute attribute, bool* value) const { |
| 407 for (size_t i = 0; i < bool_attributes_.size(); ++i) { | 396 for (size_t i = 0; i < data_.bool_attributes.size(); ++i) { |
| 408 if (bool_attributes_[i].first == attribute) { | 397 if (data_.bool_attributes[i].first == attribute) { |
| 409 *value = bool_attributes_[i].second; | 398 *value = data_.bool_attributes[i].second; |
| 410 return true; | 399 return true; |
| 411 } | 400 } |
| 412 } | 401 } |
| 413 | 402 |
| 414 return false; | 403 return false; |
| 415 } | 404 } |
| 416 | 405 |
| 417 bool BrowserAccessibility::HasFloatAttribute( | 406 bool BrowserAccessibility::HasFloatAttribute( |
| 418 ui::AXFloatAttribute attribute) const { | 407 ui::AXFloatAttribute attribute) const { |
| 419 for (size_t i = 0; i < float_attributes_.size(); ++i) { | 408 for (size_t i = 0; i < data_.float_attributes.size(); ++i) { |
| 420 if (float_attributes_[i].first == attribute) | 409 if (data_.float_attributes[i].first == attribute) |
| 421 return true; | 410 return true; |
| 422 } | 411 } |
| 423 | 412 |
| 424 return false; | 413 return false; |
| 425 } | 414 } |
| 426 | 415 |
| 427 float BrowserAccessibility::GetFloatAttribute( | 416 float BrowserAccessibility::GetFloatAttribute( |
| 428 ui::AXFloatAttribute attribute) const { | 417 ui::AXFloatAttribute attribute) const { |
| 429 for (size_t i = 0; i < float_attributes_.size(); ++i) { | 418 for (size_t i = 0; i < data_.float_attributes.size(); ++i) { |
| 430 if (float_attributes_[i].first == attribute) | 419 if (data_.float_attributes[i].first == attribute) |
| 431 return float_attributes_[i].second; | 420 return data_.float_attributes[i].second; |
| 432 } | 421 } |
| 433 | 422 |
| 434 return 0.0; | 423 return 0.0; |
| 435 } | 424 } |
| 436 | 425 |
| 437 bool BrowserAccessibility::GetFloatAttribute( | 426 bool BrowserAccessibility::GetFloatAttribute( |
| 438 ui::AXFloatAttribute attribute, float* value) const { | 427 ui::AXFloatAttribute attribute, float* value) const { |
| 439 for (size_t i = 0; i < float_attributes_.size(); ++i) { | 428 for (size_t i = 0; i < data_.float_attributes.size(); ++i) { |
| 440 if (float_attributes_[i].first == attribute) { | 429 if (data_.float_attributes[i].first == attribute) { |
| 441 *value = float_attributes_[i].second; | 430 *value = data_.float_attributes[i].second; |
| 442 return true; | 431 return true; |
| 443 } | 432 } |
| 444 } | 433 } |
| 445 | 434 |
| 446 return false; | 435 return false; |
| 447 } | 436 } |
| 448 | 437 |
| 449 bool BrowserAccessibility::HasIntAttribute( | 438 bool BrowserAccessibility::HasIntAttribute( |
| 450 ui::AXIntAttribute attribute) const { | 439 ui::AXIntAttribute attribute) const { |
| 451 for (size_t i = 0; i < int_attributes_.size(); ++i) { | 440 for (size_t i = 0; i < data_.int_attributes.size(); ++i) { |
| 452 if (int_attributes_[i].first == attribute) | 441 if (data_.int_attributes[i].first == attribute) |
| 453 return true; | 442 return true; |
| 454 } | 443 } |
| 455 | 444 |
| 456 return false; | 445 return false; |
| 457 } | 446 } |
| 458 | 447 |
| 459 int BrowserAccessibility::GetIntAttribute(ui::AXIntAttribute attribute) const { | 448 int BrowserAccessibility::GetIntAttribute(ui::AXIntAttribute attribute) const { |
| 460 for (size_t i = 0; i < int_attributes_.size(); ++i) { | 449 for (size_t i = 0; i < data_.int_attributes.size(); ++i) { |
| 461 if (int_attributes_[i].first == attribute) | 450 if (data_.int_attributes[i].first == attribute) |
| 462 return int_attributes_[i].second; | 451 return data_.int_attributes[i].second; |
| 463 } | 452 } |
| 464 | 453 |
| 465 return 0; | 454 return 0; |
| 466 } | 455 } |
| 467 | 456 |
| 468 bool BrowserAccessibility::GetIntAttribute( | 457 bool BrowserAccessibility::GetIntAttribute( |
| 469 ui::AXIntAttribute attribute, int* value) const { | 458 ui::AXIntAttribute attribute, int* value) const { |
| 470 for (size_t i = 0; i < int_attributes_.size(); ++i) { | 459 for (size_t i = 0; i < data_.int_attributes.size(); ++i) { |
| 471 if (int_attributes_[i].first == attribute) { | 460 if (data_.int_attributes[i].first == attribute) { |
| 472 *value = int_attributes_[i].second; | 461 *value = data_.int_attributes[i].second; |
| 473 return true; | 462 return true; |
| 474 } | 463 } |
| 475 } | 464 } |
| 476 | 465 |
| 477 return false; | 466 return false; |
| 478 } | 467 } |
| 479 | 468 |
| 480 bool BrowserAccessibility::HasStringAttribute( | 469 bool BrowserAccessibility::HasStringAttribute( |
| 481 ui::AXStringAttribute attribute) const { | 470 ui::AXStringAttribute attribute) const { |
| 482 for (size_t i = 0; i < string_attributes_.size(); ++i) { | 471 for (size_t i = 0; i < data_.string_attributes.size(); ++i) { |
| 483 if (string_attributes_[i].first == attribute) | 472 if (data_.string_attributes[i].first == attribute) |
| 484 return true; | 473 return true; |
| 485 } | 474 } |
| 486 | 475 |
| 487 return false; | 476 return false; |
| 488 } | 477 } |
| 489 | 478 |
| 490 const std::string& BrowserAccessibility::GetStringAttribute( | 479 const std::string& BrowserAccessibility::GetStringAttribute( |
| 491 ui::AXStringAttribute attribute) const { | 480 ui::AXStringAttribute attribute) const { |
| 492 CR_DEFINE_STATIC_LOCAL(std::string, empty_string, ()); | 481 CR_DEFINE_STATIC_LOCAL(std::string, empty_string, ()); |
| 493 for (size_t i = 0; i < string_attributes_.size(); ++i) { | 482 for (size_t i = 0; i < data_.string_attributes.size(); ++i) { |
| 494 if (string_attributes_[i].first == attribute) | 483 if (data_.string_attributes[i].first == attribute) |
| 495 return string_attributes_[i].second; | 484 return data_.string_attributes[i].second; |
| 496 } | 485 } |
| 497 | 486 |
| 498 return empty_string; | 487 return empty_string; |
| 499 } | 488 } |
| 500 | 489 |
| 501 bool BrowserAccessibility::GetStringAttribute( | 490 bool BrowserAccessibility::GetStringAttribute( |
| 502 ui::AXStringAttribute attribute, std::string* value) const { | 491 ui::AXStringAttribute attribute, std::string* value) const { |
| 503 for (size_t i = 0; i < string_attributes_.size(); ++i) { | 492 for (size_t i = 0; i < data_.string_attributes.size(); ++i) { |
| 504 if (string_attributes_[i].first == attribute) { | 493 if (data_.string_attributes[i].first == attribute) { |
| 505 *value = string_attributes_[i].second; | 494 *value = data_.string_attributes[i].second; |
| 506 return true; | 495 return true; |
| 507 } | 496 } |
| 508 } | 497 } |
| 509 | 498 |
| 510 return false; | 499 return false; |
| 511 } | 500 } |
| 512 | 501 |
| 513 base::string16 BrowserAccessibility::GetString16Attribute( | 502 base::string16 BrowserAccessibility::GetString16Attribute( |
| 514 ui::AXStringAttribute attribute) const { | 503 ui::AXStringAttribute attribute) const { |
| 515 std::string value_utf8; | 504 std::string value_utf8; |
| 516 if (!GetStringAttribute(attribute, &value_utf8)) | 505 if (!GetStringAttribute(attribute, &value_utf8)) |
| 517 return base::string16(); | 506 return base::string16(); |
| 518 return base::UTF8ToUTF16(value_utf8); | 507 return base::UTF8ToUTF16(value_utf8); |
| 519 } | 508 } |
| 520 | 509 |
| 521 bool BrowserAccessibility::GetString16Attribute( | 510 bool BrowserAccessibility::GetString16Attribute( |
| 522 ui::AXStringAttribute attribute, | 511 ui::AXStringAttribute attribute, |
| 523 base::string16* value) const { | 512 base::string16* value) const { |
| 524 std::string value_utf8; | 513 std::string value_utf8; |
| 525 if (!GetStringAttribute(attribute, &value_utf8)) | 514 if (!GetStringAttribute(attribute, &value_utf8)) |
| 526 return false; | 515 return false; |
| 527 *value = base::UTF8ToUTF16(value_utf8); | 516 *value = base::UTF8ToUTF16(value_utf8); |
| 528 return true; | 517 return true; |
| 529 } | 518 } |
| 530 | 519 |
| 531 void BrowserAccessibility::SetStringAttribute( | 520 void BrowserAccessibility::SetStringAttribute( |
| 532 ui::AXStringAttribute attribute, const std::string& value) { | 521 ui::AXStringAttribute attribute, const std::string& value) { |
| 533 for (size_t i = 0; i < string_attributes_.size(); ++i) { | 522 for (size_t i = 0; i < data_.string_attributes.size(); ++i) { |
| 534 if (string_attributes_[i].first == attribute) { | 523 if (data_.string_attributes[i].first == attribute) { |
| 535 string_attributes_[i].second = value; | 524 data_.string_attributes[i].second = value; |
| 536 return; | 525 return; |
| 537 } | 526 } |
| 538 } | 527 } |
| 539 if (!value.empty()) | 528 if (!value.empty()) |
| 540 string_attributes_.push_back(std::make_pair(attribute, value)); | 529 data_.string_attributes.push_back(std::make_pair(attribute, value)); |
| 541 } | 530 } |
| 542 | 531 |
| 543 bool BrowserAccessibility::HasIntListAttribute( | 532 bool BrowserAccessibility::HasIntListAttribute( |
| 544 ui::AXIntListAttribute attribute) const { | 533 ui::AXIntListAttribute attribute) const { |
| 545 for (size_t i = 0; i < intlist_attributes_.size(); ++i) { | 534 for (size_t i = 0; i < data_.intlist_attributes.size(); ++i) { |
| 546 if (intlist_attributes_[i].first == attribute) | 535 if (data_.intlist_attributes[i].first == attribute) |
| 547 return true; | 536 return true; |
| 548 } | 537 } |
| 549 | 538 |
| 550 return false; | 539 return false; |
| 551 } | 540 } |
| 552 | 541 |
| 553 const std::vector<int32>& BrowserAccessibility::GetIntListAttribute( | 542 const std::vector<int32>& BrowserAccessibility::GetIntListAttribute( |
| 554 ui::AXIntListAttribute attribute) const { | 543 ui::AXIntListAttribute attribute) const { |
| 555 CR_DEFINE_STATIC_LOCAL(std::vector<int32>, empty_vector, ()); | 544 CR_DEFINE_STATIC_LOCAL(std::vector<int32>, empty_vector, ()); |
| 556 for (size_t i = 0; i < intlist_attributes_.size(); ++i) { | 545 for (size_t i = 0; i < data_.intlist_attributes.size(); ++i) { |
| 557 if (intlist_attributes_[i].first == attribute) | 546 if (data_.intlist_attributes[i].first == attribute) |
| 558 return intlist_attributes_[i].second; | 547 return data_.intlist_attributes[i].second; |
| 559 } | 548 } |
| 560 | 549 |
| 561 return empty_vector; | 550 return empty_vector; |
| 562 } | 551 } |
| 563 | 552 |
| 564 bool BrowserAccessibility::GetIntListAttribute( | 553 bool BrowserAccessibility::GetIntListAttribute( |
| 565 ui::AXIntListAttribute attribute, | 554 ui::AXIntListAttribute attribute, |
| 566 std::vector<int32>* value) const { | 555 std::vector<int32>* value) const { |
| 567 for (size_t i = 0; i < intlist_attributes_.size(); ++i) { | 556 for (size_t i = 0; i < data_.intlist_attributes.size(); ++i) { |
| 568 if (intlist_attributes_[i].first == attribute) { | 557 if (data_.intlist_attributes[i].first == attribute) { |
| 569 *value = intlist_attributes_[i].second; | 558 *value = data_.intlist_attributes[i].second; |
| 570 return true; | 559 return true; |
| 571 } | 560 } |
| 572 } | 561 } |
| 573 | 562 |
| 574 return false; | 563 return false; |
| 575 } | 564 } |
| 576 | 565 |
| 577 bool BrowserAccessibility::GetHtmlAttribute( | 566 bool BrowserAccessibility::GetHtmlAttribute( |
| 578 const char* html_attr, std::string* value) const { | 567 const char* html_attr, std::string* value) const { |
| 579 for (size_t i = 0; i < html_attributes_.size(); ++i) { | 568 for (size_t i = 0; i < GetHtmlAttributes().size(); ++i) { |
| 580 const std::string& attr = html_attributes_[i].first; | 569 const std::string& attr = GetHtmlAttributes()[i].first; |
| 581 if (LowerCaseEqualsASCII(attr, html_attr)) { | 570 if (LowerCaseEqualsASCII(attr, html_attr)) { |
| 582 *value = html_attributes_[i].second; | 571 *value = GetHtmlAttributes()[i].second; |
| 583 return true; | 572 return true; |
| 584 } | 573 } |
| 585 } | 574 } |
| 586 | 575 |
| 587 return false; | 576 return false; |
| 588 } | 577 } |
| 589 | 578 |
| 590 bool BrowserAccessibility::GetHtmlAttribute( | 579 bool BrowserAccessibility::GetHtmlAttribute( |
| 591 const char* html_attr, base::string16* value) const { | 580 const char* html_attr, base::string16* value) const { |
| 592 std::string value_utf8; | 581 std::string value_utf8; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 615 if (EqualsASCII(value, "true")) | 604 if (EqualsASCII(value, "true")) |
| 616 return true; | 605 return true; |
| 617 | 606 |
| 618 if (EqualsASCII(value, "mixed")) | 607 if (EqualsASCII(value, "mixed")) |
| 619 *is_mixed = true; | 608 *is_mixed = true; |
| 620 | 609 |
| 621 return false; // Not set | 610 return false; // Not set |
| 622 } | 611 } |
| 623 | 612 |
| 624 bool BrowserAccessibility::HasState(ui::AXState state_enum) const { | 613 bool BrowserAccessibility::HasState(ui::AXState state_enum) const { |
| 625 return (state_ >> state_enum) & 1; | 614 return (GetState() >> state_enum) & 1; |
| 626 } | 615 } |
| 627 | 616 |
| 628 bool BrowserAccessibility::IsEditableText() const { | 617 bool BrowserAccessibility::IsEditableText() const { |
| 629 // These roles don't have readonly set, but they're not editable text. | 618 // These roles don't have readonly set, but they're not editable text. |
| 630 if (role_ == ui::AX_ROLE_SCROLL_AREA || | 619 if (GetRole() == ui::AX_ROLE_SCROLL_AREA || |
| 631 role_ == ui::AX_ROLE_COLUMN || | 620 GetRole() == ui::AX_ROLE_COLUMN || |
| 632 role_ == ui::AX_ROLE_TABLE_HEADER_CONTAINER) { | 621 GetRole() == ui::AX_ROLE_TABLE_HEADER_CONTAINER) { |
| 633 return false; | 622 return false; |
| 634 } | 623 } |
| 635 | 624 |
| 636 // Note: WebAXStateReadonly being false means it's either a text control, | 625 // Note: WebAXStateReadonly being false means it's either a text control, |
| 637 // or contenteditable. We also check for editable text roles to cover | 626 // or contenteditable. We also check for editable text roles to cover |
| 638 // another element that has role=textbox set on it. | 627 // another element that has role=textbox set on it. |
| 639 return (!HasState(ui::AX_STATE_READ_ONLY) || | 628 return (!HasState(ui::AX_STATE_READ_ONLY) || |
| 640 role_ == ui::AX_ROLE_TEXT_FIELD || | 629 GetRole() == ui::AX_ROLE_TEXT_FIELD || |
| 641 role_ == ui::AX_ROLE_TEXT_AREA); | 630 GetRole() == ui::AX_ROLE_TEXT_AREA); |
| 642 } | 631 } |
| 643 | 632 |
| 644 std::string BrowserAccessibility::GetTextRecursive() const { | 633 std::string BrowserAccessibility::GetTextRecursive() const { |
| 645 if (!name_.empty()) { | 634 if (!name_.empty()) { |
| 646 return name_; | 635 return name_; |
| 647 } | 636 } |
| 648 | 637 |
| 649 std::string result; | 638 std::string result; |
| 650 for (uint32 i = 0; i < PlatformChildCount(); ++i) | 639 for (uint32 i = 0; i < PlatformChildCount(); ++i) |
| 651 result += PlatformGetChild(i)->GetTextRecursive(); | 640 result += PlatformGetChild(i)->GetTextRecursive(); |
| 652 return result; | 641 return result; |
| 653 } | 642 } |
| 654 | 643 |
| 655 int BrowserAccessibility::GetStaticTextLenRecursive() const { | 644 int BrowserAccessibility::GetStaticTextLenRecursive() const { |
| 656 if (role_ == ui::AX_ROLE_STATIC_TEXT) | 645 if (GetRole() == ui::AX_ROLE_STATIC_TEXT) |
| 657 return static_cast<int>(GetStringAttribute(ui::AX_ATTR_VALUE).size()); | 646 return static_cast<int>(GetStringAttribute(ui::AX_ATTR_VALUE).size()); |
| 658 | 647 |
| 659 int len = 0; | 648 int len = 0; |
| 660 for (size_t i = 0; i < children_.size(); ++i) | 649 for (size_t i = 0; i < InternalChildCount(); ++i) |
| 661 len += children_[i]->GetStaticTextLenRecursive(); | 650 len += InternalGetChild(i)->GetStaticTextLenRecursive(); |
| 662 return len; | 651 return len; |
| 663 } | 652 } |
| 664 | 653 |
| 665 } // namespace content | 654 } // namespace content |
| OLD | NEW |