| 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" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 renderer_id_(0), | 37 renderer_id_(0), |
| 38 role_(0), | 38 role_(0), |
| 39 state_(0), | 39 state_(0), |
| 40 instance_active_(false) { | 40 instance_active_(false) { |
| 41 } | 41 } |
| 42 | 42 |
| 43 BrowserAccessibility::~BrowserAccessibility() { | 43 BrowserAccessibility::~BrowserAccessibility() { |
| 44 } | 44 } |
| 45 | 45 |
| 46 bool BrowserAccessibility::PlatformIsLeaf() const { | 46 bool BrowserAccessibility::PlatformIsLeaf() const { |
| 47 return role_ == WebKit::WebAXRoleStaticText || child_count() == 0; | 47 return role_ == blink::WebAXRoleStaticText || child_count() == 0; |
| 48 } | 48 } |
| 49 | 49 |
| 50 uint32 BrowserAccessibility::PlatformChildCount() const { | 50 uint32 BrowserAccessibility::PlatformChildCount() const { |
| 51 return PlatformIsLeaf() ? 0 : children_.size(); | 51 return PlatformIsLeaf() ? 0 : children_.size(); |
| 52 } | 52 } |
| 53 | 53 |
| 54 void BrowserAccessibility::DetachTree( | 54 void BrowserAccessibility::DetachTree( |
| 55 std::vector<BrowserAccessibility*>* nodes) { | 55 std::vector<BrowserAccessibility*>* nodes) { |
| 56 nodes->push_back(this); | 56 nodes->push_back(this); |
| 57 for (size_t i = 0; i < children_.size(); ++i) | 57 for (size_t i = 0; i < children_.size(); ++i) |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 } | 144 } |
| 145 | 145 |
| 146 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { | 146 gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { |
| 147 gfx::Rect bounds = location_; | 147 gfx::Rect bounds = location_; |
| 148 | 148 |
| 149 // Walk up the parent chain. Every time we encounter a Web Area, offset | 149 // Walk up the parent chain. Every time we encounter a Web Area, offset |
| 150 // based on the scroll bars and then offset based on the origin of that | 150 // based on the scroll bars and then offset based on the origin of that |
| 151 // nested web area. | 151 // nested web area. |
| 152 BrowserAccessibility* parent = parent_; | 152 BrowserAccessibility* parent = parent_; |
| 153 bool need_to_offset_web_area = | 153 bool need_to_offset_web_area = |
| 154 (role_ == WebKit::WebAXRoleWebArea || | 154 (role_ == blink::WebAXRoleWebArea || |
| 155 role_ == WebKit::WebAXRoleRootWebArea); | 155 role_ == blink::WebAXRoleRootWebArea); |
| 156 while (parent) { | 156 while (parent) { |
| 157 if (need_to_offset_web_area && | 157 if (need_to_offset_web_area && |
| 158 parent->location().width() > 0 && | 158 parent->location().width() > 0 && |
| 159 parent->location().height() > 0) { | 159 parent->location().height() > 0) { |
| 160 bounds.Offset(parent->location().x(), parent->location().y()); | 160 bounds.Offset(parent->location().x(), parent->location().y()); |
| 161 need_to_offset_web_area = false; | 161 need_to_offset_web_area = false; |
| 162 } | 162 } |
| 163 | 163 |
| 164 // On some platforms, we don't want to take the root scroll offsets | 164 // On some platforms, we don't want to take the root scroll offsets |
| 165 // into account. | 165 // into account. |
| 166 if (parent->role() == WebKit::WebAXRoleRootWebArea && | 166 if (parent->role() == blink::WebAXRoleRootWebArea && |
| 167 !manager()->UseRootScrollOffsetsWhenComputingBounds()) { | 167 !manager()->UseRootScrollOffsetsWhenComputingBounds()) { |
| 168 break; | 168 break; |
| 169 } | 169 } |
| 170 | 170 |
| 171 if (parent->role() == WebKit::WebAXRoleWebArea || | 171 if (parent->role() == blink::WebAXRoleWebArea || |
| 172 parent->role() == WebKit::WebAXRoleRootWebArea) { | 172 parent->role() == blink::WebAXRoleRootWebArea) { |
| 173 int sx = 0; | 173 int sx = 0; |
| 174 int sy = 0; | 174 int sy = 0; |
| 175 if (parent->GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_X, &sx) && | 175 if (parent->GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_X, &sx) && |
| 176 parent->GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_Y, &sy)) { | 176 parent->GetIntAttribute(AccessibilityNodeData::ATTR_SCROLL_Y, &sy)) { |
| 177 bounds.Offset(-sx, -sy); | 177 bounds.Offset(-sx, -sy); |
| 178 } | 178 } |
| 179 need_to_offset_web_area = true; | 179 need_to_offset_web_area = true; |
| 180 } | 180 } |
| 181 parent = parent->parent(); | 181 parent = parent->parent(); |
| 182 } | 182 } |
| 183 | 183 |
| 184 return bounds; | 184 return bounds; |
| 185 } | 185 } |
| 186 | 186 |
| 187 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { | 187 gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { |
| 188 gfx::Rect bounds = GetLocalBoundsRect(); | 188 gfx::Rect bounds = GetLocalBoundsRect(); |
| 189 | 189 |
| 190 // Adjust the bounds by the top left corner of the containing view's bounds | 190 // Adjust the bounds by the top left corner of the containing view's bounds |
| 191 // in screen coordinates. | 191 // in screen coordinates. |
| 192 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); | 192 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); |
| 193 | 193 |
| 194 return bounds; | 194 return bounds; |
| 195 } | 195 } |
| 196 | 196 |
| 197 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) | 197 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) |
| 198 const { | 198 const { |
| 199 DCHECK_EQ(role_, WebKit::WebAXRoleStaticText); | 199 DCHECK_EQ(role_, blink::WebAXRoleStaticText); |
| 200 int end = start + len; | 200 int end = start + len; |
| 201 int child_start = 0; | 201 int child_start = 0; |
| 202 int child_end = 0; | 202 int child_end = 0; |
| 203 | 203 |
| 204 gfx::Rect bounds; | 204 gfx::Rect bounds; |
| 205 for (size_t i = 0; i < children_.size() && child_end < start + len; ++i) { | 205 for (size_t i = 0; i < children_.size() && child_end < start + len; ++i) { |
| 206 BrowserAccessibility* child = children_[i]; | 206 BrowserAccessibility* child = children_[i]; |
| 207 DCHECK_EQ(child->role(), WebKit::WebAXRoleInlineTextBox); | 207 DCHECK_EQ(child->role(), blink::WebAXRoleInlineTextBox); |
| 208 std::string child_text; | 208 std::string child_text; |
| 209 child->GetStringAttribute(AccessibilityNodeData::ATTR_VALUE, &child_text); | 209 child->GetStringAttribute(AccessibilityNodeData::ATTR_VALUE, &child_text); |
| 210 int child_len = static_cast<int>(child_text.size()); | 210 int child_len = static_cast<int>(child_text.size()); |
| 211 child_start = child_end; | 211 child_start = child_end; |
| 212 child_end += child_len; | 212 child_end += child_len; |
| 213 | 213 |
| 214 if (child_end < start) | 214 if (child_end < start) |
| 215 continue; | 215 continue; |
| 216 | 216 |
| 217 int overlap_start = std::max(start, child_start); | 217 int overlap_start = std::max(start, child_start); |
| 218 int overlap_end = std::min(end, child_end); | 218 int overlap_end = std::min(end, child_end); |
| 219 | 219 |
| 220 int local_start = overlap_start - child_start; | 220 int local_start = overlap_start - child_start; |
| 221 int local_end = overlap_end - child_start; | 221 int local_end = overlap_end - child_start; |
| 222 | 222 |
| 223 gfx::Rect child_rect = child->location(); | 223 gfx::Rect child_rect = child->location(); |
| 224 int text_direction = child->GetIntAttribute( | 224 int text_direction = child->GetIntAttribute( |
| 225 AccessibilityNodeData::ATTR_TEXT_DIRECTION); | 225 AccessibilityNodeData::ATTR_TEXT_DIRECTION); |
| 226 const std::vector<int32>& character_offsets = child->GetIntListAttribute( | 226 const std::vector<int32>& character_offsets = child->GetIntListAttribute( |
| 227 AccessibilityNodeData::ATTR_CHARACTER_OFFSETS); | 227 AccessibilityNodeData::ATTR_CHARACTER_OFFSETS); |
| 228 int start_pixel_offset = | 228 int start_pixel_offset = |
| 229 local_start > 0 ? character_offsets[local_start - 1] : 0; | 229 local_start > 0 ? character_offsets[local_start - 1] : 0; |
| 230 int end_pixel_offset = | 230 int end_pixel_offset = |
| 231 local_end > 0 ? character_offsets[local_end - 1] : 0; | 231 local_end > 0 ? character_offsets[local_end - 1] : 0; |
| 232 | 232 |
| 233 gfx::Rect child_overlap_rect; | 233 gfx::Rect child_overlap_rect; |
| 234 switch (text_direction) { | 234 switch (text_direction) { |
| 235 case WebKit::WebAXTextDirectionLR: { | 235 case blink::WebAXTextDirectionLR: { |
| 236 int left = child_rect.x() + start_pixel_offset; | 236 int left = child_rect.x() + start_pixel_offset; |
| 237 int right = child_rect.x() + end_pixel_offset; | 237 int right = child_rect.x() + end_pixel_offset; |
| 238 child_overlap_rect = gfx::Rect(left, child_rect.y(), | 238 child_overlap_rect = gfx::Rect(left, child_rect.y(), |
| 239 right - left, child_rect.height()); | 239 right - left, child_rect.height()); |
| 240 break; | 240 break; |
| 241 } | 241 } |
| 242 case WebKit::WebAXTextDirectionRL: { | 242 case blink::WebAXTextDirectionRL: { |
| 243 int right = child_rect.right() - start_pixel_offset; | 243 int right = child_rect.right() - start_pixel_offset; |
| 244 int left = child_rect.right() - end_pixel_offset; | 244 int left = child_rect.right() - end_pixel_offset; |
| 245 child_overlap_rect = gfx::Rect(left, child_rect.y(), | 245 child_overlap_rect = gfx::Rect(left, child_rect.y(), |
| 246 right - left, child_rect.height()); | 246 right - left, child_rect.height()); |
| 247 break; | 247 break; |
| 248 } | 248 } |
| 249 case WebKit::WebAXTextDirectionTB: { | 249 case blink::WebAXTextDirectionTB: { |
| 250 int top = child_rect.y() + start_pixel_offset; | 250 int top = child_rect.y() + start_pixel_offset; |
| 251 int bottom = child_rect.y() + end_pixel_offset; | 251 int bottom = child_rect.y() + end_pixel_offset; |
| 252 child_overlap_rect = gfx::Rect(child_rect.x(), top, | 252 child_overlap_rect = gfx::Rect(child_rect.x(), top, |
| 253 child_rect.width(), bottom - top); | 253 child_rect.width(), bottom - top); |
| 254 break; | 254 break; |
| 255 } | 255 } |
| 256 case WebKit::WebAXTextDirectionBT: { | 256 case blink::WebAXTextDirectionBT: { |
| 257 int bottom = child_rect.bottom() - start_pixel_offset; | 257 int bottom = child_rect.bottom() - start_pixel_offset; |
| 258 int top = child_rect.bottom() - end_pixel_offset; | 258 int top = child_rect.bottom() - end_pixel_offset; |
| 259 child_overlap_rect = gfx::Rect(child_rect.x(), top, | 259 child_overlap_rect = gfx::Rect(child_rect.x(), top, |
| 260 child_rect.width(), bottom - top); | 260 child_rect.width(), bottom - top); |
| 261 break; | 261 break; |
| 262 } | 262 } |
| 263 default: | 263 default: |
| 264 NOTREACHED(); | 264 NOTREACHED(); |
| 265 } | 265 } |
| 266 | 266 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 (*iter)->Destroy(); | 303 (*iter)->Destroy(); |
| 304 } | 304 } |
| 305 children_.clear(); | 305 children_.clear(); |
| 306 | 306 |
| 307 // Allow the object to fire a TextRemoved notification. | 307 // Allow the object to fire a TextRemoved notification. |
| 308 name_.clear(); | 308 name_.clear(); |
| 309 value_.clear(); | 309 value_.clear(); |
| 310 PostInitialize(); | 310 PostInitialize(); |
| 311 | 311 |
| 312 manager_->NotifyAccessibilityEvent( | 312 manager_->NotifyAccessibilityEvent( |
| 313 WebKit::WebAXEventHide, this); | 313 blink::WebAXEventHide, this); |
| 314 | 314 |
| 315 instance_active_ = false; | 315 instance_active_ = false; |
| 316 manager_->RemoveNode(this); | 316 manager_->RemoveNode(this); |
| 317 NativeReleaseReference(); | 317 NativeReleaseReference(); |
| 318 } | 318 } |
| 319 | 319 |
| 320 void BrowserAccessibility::NativeReleaseReference() { | 320 void BrowserAccessibility::NativeReleaseReference() { |
| 321 delete this; | 321 delete this; |
| 322 } | 322 } |
| 323 | 323 |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 | 548 |
| 549 if (EqualsASCII(value, "true")) | 549 if (EqualsASCII(value, "true")) |
| 550 return true; | 550 return true; |
| 551 | 551 |
| 552 if (EqualsASCII(value, "mixed")) | 552 if (EqualsASCII(value, "mixed")) |
| 553 *is_mixed = true; | 553 *is_mixed = true; |
| 554 | 554 |
| 555 return false; // Not set | 555 return false; // Not set |
| 556 } | 556 } |
| 557 | 557 |
| 558 bool BrowserAccessibility::HasState(WebKit::WebAXState state_enum) const { | 558 bool BrowserAccessibility::HasState(blink::WebAXState state_enum) const { |
| 559 return (state_ >> state_enum) & 1; | 559 return (state_ >> state_enum) & 1; |
| 560 } | 560 } |
| 561 | 561 |
| 562 bool BrowserAccessibility::IsEditableText() const { | 562 bool BrowserAccessibility::IsEditableText() const { |
| 563 // These roles don't have readonly set, but they're not editable text. | 563 // These roles don't have readonly set, but they're not editable text. |
| 564 if (role_ == WebKit::WebAXRoleScrollArea || | 564 if (role_ == blink::WebAXRoleScrollArea || |
| 565 role_ == WebKit::WebAXRoleColumn || | 565 role_ == blink::WebAXRoleColumn || |
| 566 role_ == WebKit::WebAXRoleTableHeaderContainer) { | 566 role_ == blink::WebAXRoleTableHeaderContainer) { |
| 567 return false; | 567 return false; |
| 568 } | 568 } |
| 569 | 569 |
| 570 // Note: WebAXStateReadonly being false means it's either a text control, | 570 // Note: WebAXStateReadonly being false means it's either a text control, |
| 571 // or contenteditable. We also check for editable text roles to cover | 571 // or contenteditable. We also check for editable text roles to cover |
| 572 // another element that has role=textbox set on it. | 572 // another element that has role=textbox set on it. |
| 573 return (!HasState(WebKit::WebAXStateReadonly) || | 573 return (!HasState(blink::WebAXStateReadonly) || |
| 574 role_ == WebKit::WebAXRoleTextField || | 574 role_ == blink::WebAXRoleTextField || |
| 575 role_ == WebKit::WebAXRoleTextArea); | 575 role_ == blink::WebAXRoleTextArea); |
| 576 } | 576 } |
| 577 | 577 |
| 578 std::string BrowserAccessibility::GetTextRecursive() const { | 578 std::string BrowserAccessibility::GetTextRecursive() const { |
| 579 if (!name_.empty()) { | 579 if (!name_.empty()) { |
| 580 return name_; | 580 return name_; |
| 581 } | 581 } |
| 582 | 582 |
| 583 std::string result; | 583 std::string result; |
| 584 for (size_t i = 0; i < children_.size(); ++i) | 584 for (size_t i = 0; i < children_.size(); ++i) |
| 585 result += children_[i]->GetTextRecursive(); | 585 result += children_[i]->GetTextRecursive(); |
| 586 return result; | 586 return result; |
| 587 } | 587 } |
| 588 | 588 |
| 589 } // namespace content | 589 } // namespace content |
| OLD | NEW |