diff options
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 |