summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/accessibility/browser_accessibility.cc48
-rw-r--r--content/browser/accessibility/browser_accessibility.h4
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_unittest.cc93
-rw-r--r--content/browser/accessibility/browser_accessibility_win.cc6
-rw-r--r--content/renderer/accessibility/accessibility_node_serializer.cc10
5 files changed, 143 insertions, 18 deletions
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 223cd8d..8429664 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -44,7 +44,22 @@ BrowserAccessibility::~BrowserAccessibility() {
}
bool BrowserAccessibility::PlatformIsLeaf() const {
- return role_ == blink::WebAXRoleStaticText || child_count() == 0;
+ if (child_count() == 0)
+ return true;
+
+ // All of these roles may have children that we use as internal
+ // implementation details, but we want to expose them as leaves
+ // to platform accessibility APIs.
+ switch (role_) {
+ case blink::WebAXRoleEditableText:
+ case blink::WebAXRoleSlider:
+ case blink::WebAXRoleStaticText:
+ case blink::WebAXRoleTextArea:
+ case blink::WebAXRoleTextField:
+ return true;
+ default:
+ return false;
+ }
}
uint32 BrowserAccessibility::PlatformChildCount() const {
@@ -196,7 +211,24 @@ gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const {
gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len)
const {
- DCHECK_EQ(role_, blink::WebAXRoleStaticText);
+ if (role_ != blink::WebAXRoleStaticText) {
+ // Apply recursively to all static text descendants. For example, if
+ // you call it on a div with two text node children, it just calls
+ // GetLocalBoundsForRange on each of the two children (adjusting
+ // |start| for each one) and unions the resulting rects.
+ gfx::Rect bounds;
+ for (size_t i = 0; i < children_.size(); ++i) {
+ BrowserAccessibility* child = children_[i];
+ int child_len = child->GetStaticTextLenRecursive();
+ if (start < child_len && start + len > 0) {
+ gfx::Rect child_rect = child->GetLocalBoundsForRange(start, len);
+ bounds.Union(child_rect);
+ }
+ start -= child_len;
+ }
+ return bounds;
+ }
+
int end = start + len;
int child_start = 0;
int child_end = 0;
@@ -586,4 +618,16 @@ std::string BrowserAccessibility::GetTextRecursive() const {
return result;
}
+int BrowserAccessibility::GetStaticTextLenRecursive() const {
+ if (role_ == blink::WebAXRoleStaticText) {
+ return static_cast<int>(
+ GetStringAttribute(AccessibilityNodeData::ATTR_VALUE).size());
+ }
+
+ int len = 0;
+ for (size_t i = 0; i < children_.size(); ++i)
+ len += children_[i]->GetStaticTextLenRecursive();
+ return len;
+}
+
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index 1258803..781ccff 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -282,6 +282,10 @@ class CONTENT_EXPORT BrowserAccessibility {
BrowserAccessibility* parent_;
private:
+ // Return the sum of the lengths of all static text descendants,
+ // including this object if it's static text.
+ int GetStaticTextLenRecursive() const;
+
// The index of this within its parent object.
int32 index_in_parent_;
diff --git a/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
index b0d4836..e427b9e 100644
--- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -692,6 +692,11 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRange) {
// Test range that's beyond the text.
EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(),
static_text_accessible->GetLocalBoundsForRange(-1, 999).ToString());
+
+ // Test that we can call bounds for range on the parent element, too,
+ // and it still works.
+ EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(),
+ root_accessible->GetLocalBoundsForRange(0, 13).ToString());
}
TEST(BrowserAccessibilityManagerTest, BoundsForRangeBiDi) {
@@ -776,4 +781,92 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRangeBiDi) {
static_text_accessible->GetLocalBoundsForRange(2, 2).ToString());
}
+TEST(BrowserAccessibilityManagerTest, BoundsForRangeOnParentElement) {
+ AccessibilityNodeData root;
+ root.id = 1;
+ root.role = blink::WebAXRoleRootWebArea;
+ root.child_ids.push_back(2);
+
+ AccessibilityNodeData div;
+ div.id = 2;
+ div.role = blink::WebAXRoleDiv;
+ div.location = gfx::Rect(100, 100, 100, 20);
+ div.child_ids.push_back(3);
+ div.child_ids.push_back(4);
+ div.child_ids.push_back(5);
+
+ AccessibilityNodeData static_text1;
+ static_text1.id = 3;
+ static_text1.SetValue("AB");
+ static_text1.role = blink::WebAXRoleStaticText;
+ static_text1.location = gfx::Rect(100, 100, 40, 20);
+ static_text1.child_ids.push_back(6);
+
+ AccessibilityNodeData img;
+ img.id = 4;
+ img.role = blink::WebAXRoleImage;
+ img.location = gfx::Rect(140, 100, 20, 20);
+
+ AccessibilityNodeData static_text2;
+ static_text2.id = 5;
+ static_text2.SetValue("CD");
+ static_text2.role = blink::WebAXRoleStaticText;
+ static_text2.location = gfx::Rect(160, 100, 40, 20);
+ static_text2.child_ids.push_back(7);
+
+ AccessibilityNodeData inline_text1;
+ inline_text1.id = 6;
+ inline_text1.SetValue("AB");
+ inline_text1.role = blink::WebAXRoleInlineTextBox;
+ inline_text1.location = gfx::Rect(100, 100, 40, 20);
+ inline_text1.AddIntAttribute(AccessibilityNodeData::ATTR_TEXT_DIRECTION,
+ blink::WebAXTextDirectionLR);
+ std::vector<int32> character_offsets1;
+ character_offsets1.push_back(20); // 0
+ character_offsets1.push_back(40); // 1
+ inline_text1.AddIntListAttribute(
+ AccessibilityNodeData::ATTR_CHARACTER_OFFSETS, character_offsets1);
+
+ AccessibilityNodeData inline_text2;
+ inline_text2.id = 7;
+ inline_text2.SetValue("CD");
+ inline_text2.role = blink::WebAXRoleInlineTextBox;
+ inline_text2.location = gfx::Rect(160, 100, 40, 20);
+ inline_text2.AddIntAttribute(AccessibilityNodeData::ATTR_TEXT_DIRECTION,
+ blink::WebAXTextDirectionLR);
+ std::vector<int32> character_offsets2;
+ character_offsets2.push_back(20); // 0
+ character_offsets2.push_back(40); // 1
+ inline_text2.AddIntListAttribute(
+ AccessibilityNodeData::ATTR_CHARACTER_OFFSETS, character_offsets2);
+
+ scoped_ptr<BrowserAccessibilityManager> manager(
+ BrowserAccessibilityManager::Create(
+ root,
+ NULL,
+ new CountedBrowserAccessibilityFactory()));
+ manager->UpdateNodesForTesting(
+ div, static_text1, img, static_text2, inline_text1, inline_text2);
+
+ BrowserAccessibility* root_accessible = manager->GetRoot();
+
+ EXPECT_EQ(gfx::Rect(100, 100, 20, 20).ToString(),
+ root_accessible->GetLocalBoundsForRange(0, 1).ToString());
+
+ EXPECT_EQ(gfx::Rect(100, 100, 40, 20).ToString(),
+ root_accessible->GetLocalBoundsForRange(0, 2).ToString());
+
+ EXPECT_EQ(gfx::Rect(100, 100, 80, 20).ToString(),
+ root_accessible->GetLocalBoundsForRange(0, 3).ToString());
+
+ EXPECT_EQ(gfx::Rect(120, 100, 60, 20).ToString(),
+ root_accessible->GetLocalBoundsForRange(1, 2).ToString());
+
+ EXPECT_EQ(gfx::Rect(120, 100, 80, 20).ToString(),
+ root_accessible->GetLocalBoundsForRange(1, 3).ToString());
+
+ EXPECT_EQ(gfx::Rect(100, 100, 100, 20).ToString(),
+ root_accessible->GetLocalBoundsForRange(0, 4).ToString());
+}
+
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index 2c01503..f3520da 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -1933,9 +1933,6 @@ STDMETHODIMP BrowserAccessibilityWin::get_characterExtents(
if (offset < 0 || offset > static_cast<LONG>(text_str.size()))
return E_INVALIDARG;
- if (blink_role() != blink::WebAXRoleStaticText)
- return E_FAIL;
-
gfx::Rect character_bounds;
if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) {
character_bounds = GetGlobalBoundsForRange(offset, 1);
@@ -2722,9 +2719,6 @@ STDMETHODIMP BrowserAccessibilityWin::get_unclippedSubstringBounds(
return E_INVALIDARG;
}
- if (blink_role() != blink::WebAXRoleStaticText)
- return E_FAIL;
-
gfx::Rect bounds = GetGlobalBoundsForRange(
start_index, end_index - start_index);
*out_x = bounds.x();
diff --git a/content/renderer/accessibility/accessibility_node_serializer.cc b/content/renderer/accessibility/accessibility_node_serializer.cc
index 39fa245..db79307 100644
--- a/content/renderer/accessibility/accessibility_node_serializer.cc
+++ b/content/renderer/accessibility/accessibility_node_serializer.cc
@@ -465,16 +465,6 @@ void SerializeAccessibilityNode(
bool ShouldIncludeChildNode(
const WebAXObject& parent,
const WebAXObject& child) {
- switch(parent.role()) {
- case blink::WebAXRoleSlider:
- case blink::WebAXRoleEditableText:
- case blink::WebAXRoleTextArea:
- case blink::WebAXRoleTextField:
- return false;
- default:
- break;
- }
-
// The child may be invalid due to issues in webkit accessibility code.
// Don't add children that are invalid thus preventing a crash.
// https://bugs.webkit.org/show_bug.cgi?id=44149