Commit 9df5f8fd authored by dmazzoni's avatar dmazzoni Committed by Commit bot

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}
parent fb12824b
......@@ -186,43 +186,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 {
......@@ -252,7 +216,7 @@ gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len)
}
start -= child_len;
}
return bounds;
return ElementBoundsToLocalBounds(bounds);
}
int end = start + len;
......@@ -329,7 +293,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)
......@@ -711,4 +675,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
......@@ -267,6 +267,11 @@ class CONTENT_EXPORT BrowserAccessibility {
// bounds offsets.
BrowserAccessibility* GetParentForBoundsCalculation() const;
// 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);
};
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment