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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 | 307 |
308 // Adjust the bounds by the top left corner of the containing view's bounds | 308 // Adjust the bounds by the top left corner of the containing view's bounds |
309 // in screen coordinates. | 309 // in screen coordinates. |
310 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); | 310 bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); |
311 | 311 |
312 return bounds; | 312 return bounds; |
313 } | 313 } |
314 | 314 |
315 BrowserAccessibility* BrowserAccessibility::BrowserAccessibilityForPoint( | 315 BrowserAccessibility* BrowserAccessibility::BrowserAccessibilityForPoint( |
316 const gfx::Point& point) { | 316 const gfx::Point& point) { |
| 317 // The best result found that's a child of this object. |
| 318 BrowserAccessibility* child_result = NULL; |
| 319 // The best result that's an indirect descendant like grandchild, etc. |
| 320 BrowserAccessibility* descendant_result = NULL; |
| 321 |
317 // Walk the children recursively looking for the BrowserAccessibility that | 322 // Walk the children recursively looking for the BrowserAccessibility that |
318 // most tightly encloses the specified point. | 323 // most tightly encloses the specified point. Walk backwards so that in |
| 324 // 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. |
319 for (int i = static_cast<int>(PlatformChildCount()) - 1; i >= 0; --i) { | 326 for (int i = static_cast<int>(PlatformChildCount()) - 1; i >= 0; --i) { |
320 BrowserAccessibility* child = PlatformGetChild(i); | 327 BrowserAccessibility* child = PlatformGetChild(i); |
321 | 328 |
322 // Skip table columns because cells are only contained in rows, | 329 // Skip table columns because cells are only contained in rows, |
323 // not columns. | 330 // not columns. |
324 if (child->role() == ui::AX_ROLE_COLUMN) | 331 if (child->role() == ui::AX_ROLE_COLUMN) |
325 continue; | 332 continue; |
326 | 333 |
327 if (child->GetGlobalBoundsRect().Contains(point)) | 334 if (child->GetGlobalBoundsRect().Contains(point)) { |
328 return child->BrowserAccessibilityForPoint(point); | 335 BrowserAccessibility* result = child->BrowserAccessibilityForPoint(point); |
| 336 if (result == child && !child_result) |
| 337 child_result = result; |
| 338 if (result != child && !descendant_result) |
| 339 descendant_result = result; |
| 340 } |
| 341 |
| 342 if (child_result && descendant_result) |
| 343 break; |
329 } | 344 } |
| 345 |
| 346 // 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 |
| 348 // 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 |
| 350 // overlap, but the rows do. Without this heuristic, we'd greedily only |
| 351 // consider one of the containers. |
| 352 if (descendant_result) |
| 353 return descendant_result; |
| 354 if (child_result) |
| 355 return child_result; |
| 356 |
330 return this; | 357 return this; |
331 } | 358 } |
332 | 359 |
333 void BrowserAccessibility::Destroy() { | 360 void BrowserAccessibility::Destroy() { |
334 for (std::vector<BrowserAccessibility*>::iterator iter = children_.begin(); | 361 for (std::vector<BrowserAccessibility*>::iterator iter = children_.begin(); |
335 iter != children_.end(); | 362 iter != children_.end(); |
336 ++iter) { | 363 ++iter) { |
337 (*iter)->Destroy(); | 364 (*iter)->Destroy(); |
338 } | 365 } |
339 children_.clear(); | 366 children_.clear(); |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 if (role_ == ui::AX_ROLE_STATIC_TEXT) | 656 if (role_ == ui::AX_ROLE_STATIC_TEXT) |
630 return static_cast<int>(GetStringAttribute(ui::AX_ATTR_VALUE).size()); | 657 return static_cast<int>(GetStringAttribute(ui::AX_ATTR_VALUE).size()); |
631 | 658 |
632 int len = 0; | 659 int len = 0; |
633 for (size_t i = 0; i < children_.size(); ++i) | 660 for (size_t i = 0; i < children_.size(); ++i) |
634 len += children_[i]->GetStaticTextLenRecursive(); | 661 len += children_[i]->GetStaticTextLenRecursive(); |
635 return len; | 662 return len; |
636 } | 663 } |
637 | 664 |
638 } // namespace content | 665 } // namespace content |
OLD | NEW |