diff options
author | Dominic Mazzoni <dmazzoni@chromium.org> | 2015-02-13 09:04:57 -0800 |
---|---|---|
committer | Dominic Mazzoni <dmazzoni@chromium.org> | 2015-02-13 17:06:31 +0000 |
commit | b18f8fb6d3ddba24a5a177792be2cb6fdabd142a (patch) | |
tree | 7317829d8e8c56c4cc1f6e1e99a70ee88f1ccd05 | |
parent | 4e6cd5d33c6707862467c153b7ff8c1a1ccc70a9 (diff) | |
download | chromium_src-b18f8fb6d3ddba24a5a177792be2cb6fdabd142a.zip chromium_src-b18f8fb6d3ddba24a5a177792be2cb6fdabd142a.tar.gz chromium_src-b18f8fb6d3ddba24a5a177792be2cb6fdabd142a.tar.bz2 |
Merge to M41: Accessibility BoundsForRange needs to take scroll offsets into account.
BUG=454995
Review URL: https://codereview.chromium.org/895233002
Cr-Commit-Position: refs/heads/master@{#314518}
(cherry picked from commit 9df5f8fdb80c94fd459000f8208cc352680963e8)
Review URL: https://codereview.chromium.org/920123003
Cr-Commit-Position: refs/branch-heads/2272@{#289}
Cr-Branched-From: 827a380cfdb31aa54c8d56e63ce2c3fd8c3ba4d4-refs/heads/master@{#310958}
3 files changed, 96 insertions, 39 deletions
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 66bd947..8f9a7e3 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc @@ -180,43 +180,7 @@ BrowserAccessibility::GetHtmlAttributes() const { gfx::Rect BrowserAccessibility::GetLocalBoundsRect() const { gfx::Rect bounds = GetLocation(); - - // Walk up the parent chain. Every time we encounter a Web Area, offset - // based on the scroll bars and then offset based on the origin of that - // nested web area. - BrowserAccessibility* parent = GetParentForBoundsCalculation(); - bool need_to_offset_web_area = - (GetRole() == ui::AX_ROLE_WEB_AREA || - GetRole() == ui::AX_ROLE_ROOT_WEB_AREA); - while (parent) { - if (need_to_offset_web_area && - parent->GetLocation().width() > 0 && - parent->GetLocation().height() > 0) { - bounds.Offset(parent->GetLocation().x(), parent->GetLocation().y()); - need_to_offset_web_area = false; - } - - // On some platforms, we don't want to take the root scroll offsets - // into account. - if (parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && - !manager()->UseRootScrollOffsetsWhenComputingBounds()) { - break; - } - - if (parent->GetRole() == ui::AX_ROLE_WEB_AREA || - parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA) { - int sx = 0; - int sy = 0; - if (parent->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && - parent->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { - bounds.Offset(-sx, -sy); - } - need_to_offset_web_area = true; - } - parent = parent->GetParentForBoundsCalculation(); - } - - return bounds; + return ElementBoundsToLocalBounds(bounds); } gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const { @@ -246,7 +210,7 @@ gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) } start -= child_len; } - return bounds; + return ElementBoundsToLocalBounds(bounds); } int end = start + len; @@ -323,7 +287,7 @@ gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) bounds.Union(child_overlap_rect); } - return bounds; + return ElementBoundsToLocalBounds(bounds); } gfx::Rect BrowserAccessibility::GetGlobalBoundsForRange(int start, int len) @@ -731,4 +695,44 @@ BrowserAccessibility* BrowserAccessibility::GetParentForBoundsCalculation() return manager_->delegate()->AccessibilityGetParentFrame(); } +gfx::Rect BrowserAccessibility::ElementBoundsToLocalBounds(gfx::Rect bounds) + const { + // Walk up the parent chain. Every time we encounter a Web Area, offset + // based on the scroll bars and then offset based on the origin of that + // nested web area. + BrowserAccessibility* parent = GetParentForBoundsCalculation(); + bool need_to_offset_web_area = + (GetRole() == ui::AX_ROLE_WEB_AREA || + GetRole() == ui::AX_ROLE_ROOT_WEB_AREA); + while (parent) { + if (need_to_offset_web_area && + parent->GetLocation().width() > 0 && + parent->GetLocation().height() > 0) { + bounds.Offset(parent->GetLocation().x(), parent->GetLocation().y()); + need_to_offset_web_area = false; + } + + // On some platforms, we don't want to take the root scroll offsets + // into account. + if (parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA && + !manager()->UseRootScrollOffsetsWhenComputingBounds()) { + break; + } + + if (parent->GetRole() == ui::AX_ROLE_WEB_AREA || + parent->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA) { + int sx = 0; + int sy = 0; + if (parent->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && + parent->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { + bounds.Offset(-sx, -sy); + } + need_to_offset_web_area = true; + } + parent = parent->GetParentForBoundsCalculation(); + } + + return bounds; +} + } // namespace content diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index 64811bd..429375f 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h @@ -272,6 +272,11 @@ class CONTENT_EXPORT BrowserAccessibility { std::string name_; std::string value_; + // Convert the bounding rectangle of an element (which is relative to + // its nearest scrollable ancestor) to local bounds (which are relative + // to the top of the web accessibility tree). + gfx::Rect ElementBoundsToLocalBounds(gfx::Rect bounds) const; + DISALLOW_COPY_AND_ASSIGN(BrowserAccessibility); }; diff --git a/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc index d0ca4bb..1b83161 100644 --- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc @@ -798,6 +798,54 @@ TEST(BrowserAccessibilityManagerTest, BoundsForRangeBiDi) { static_text_accessible->GetLocalBoundsForRange(2, 2).ToString()); } +TEST(BrowserAccessibilityManagerTest, BoundsForRangeScrolledWindow) { + ui::AXNodeData root; + root.id = 1; + root.role = ui::AX_ROLE_ROOT_WEB_AREA; + root.AddIntAttribute(ui::AX_ATTR_SCROLL_X, 25); + root.AddIntAttribute(ui::AX_ATTR_SCROLL_Y, 50); + + ui::AXNodeData static_text; + static_text.id = 2; + static_text.SetValue("ABC"); + static_text.role = ui::AX_ROLE_STATIC_TEXT; + static_text.location = gfx::Rect(100, 100, 16, 9); + root.child_ids.push_back(2); + + ui::AXNodeData inline_text; + inline_text.id = 3; + inline_text.SetValue("ABC"); + inline_text.role = ui::AX_ROLE_INLINE_TEXT_BOX; + inline_text.location = gfx::Rect(100, 100, 16, 9); + inline_text.AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION, + ui::AX_TEXT_DIRECTION_LR); + std::vector<int32> character_offsets1; + character_offsets1.push_back(6); // 0 + character_offsets1.push_back(11); // 1 + character_offsets1.push_back(16); // 2 + inline_text.AddIntListAttribute( + ui::AX_ATTR_CHARACTER_OFFSETS, character_offsets1); + static_text.child_ids.push_back(3); + + scoped_ptr<BrowserAccessibilityManager> manager( + BrowserAccessibilityManager::Create( + MakeAXTreeUpdate(root, static_text, inline_text), + NULL, + new CountedBrowserAccessibilityFactory())); + + BrowserAccessibility* root_accessible = manager->GetRoot(); + BrowserAccessibility* static_text_accessible = + root_accessible->PlatformGetChild(0); + + if (manager->UseRootScrollOffsetsWhenComputingBounds()) { + EXPECT_EQ(gfx::Rect(75, 50, 16, 9).ToString(), + static_text_accessible->GetLocalBoundsForRange(0, 3).ToString()); + } else { + EXPECT_EQ(gfx::Rect(100, 100, 16, 9).ToString(), + static_text_accessible->GetLocalBoundsForRange(0, 3).ToString()); + } +} + #if defined(OS_WIN) #define MAYBE_BoundsForRangeOnParentElement \ DISABLED_BoundsForRangeOnParentElement |