Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Unified Diff: Source/core/accessibility/AXObject.cpp

Issue 661183002: Fix case where accessible scrollToMakeVisible didn't work. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix test expectation Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « LayoutTests/accessibility/scroll-to-make-visible-nested-2-expected.txt ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/accessibility/AXObject.cpp
diff --git a/Source/core/accessibility/AXObject.cpp b/Source/core/accessibility/AXObject.cpp
index c296ddfbda8c8dcc53211a281e49abb716bcb372..fdc942a5c53ca2774b7c5a8f44d26726cba6bf35 100644
--- a/Source/core/accessibility/AXObject.cpp
+++ b/Source/core/accessibility/AXObject.cpp
@@ -654,23 +654,47 @@ void AXObject::scrollToMakeVisible() const
// logic is the same. The goal is to compute the best scroll offset
// in order to make an object visible within a viewport.
//
+// If the object is already fully visible, returns the same scroll
+// offset.
+//
// In case the whole object cannot fit, you can specify a
// subfocus - a smaller region within the object that should
// be prioritized. If the whole object can fit, the subfocus is
// ignored.
//
-// Example: the viewport is scrolled to the right just enough
-// that the object is in view.
+// If possible, the object and subfocus are centered within the
+// viewport.
+//
+// Example 1: the object is already visible, so nothing happens.
+// +----------Viewport---------+
+// +---Object---+
+// +--SubFocus--+
+//
+// Example 2: the object is not fully visible, so it's centered
+// within the viewport.
// Before:
// +----------Viewport---------+
// +---Object---+
// +--SubFocus--+
//
// After:
-// +----------Viewport---------+
+// +----------Viewport---------+
// +---Object---+
// +--SubFocus--+
//
+// Example 3: the object is larger than the viewport, so the
+// viewport moves to show as much of the object as possible,
+// while also trying to center the subfocus.
+// Before:
+// +----------Viewport---------+
+// +---------------Object--------------+
+// +-SubFocus-+
+//
+// After:
+// +----------Viewport---------+
+// +---------------Object--------------+
+// +-SubFocus-+
+//
// When constraints cannot be fully satisfied, the min
// (left/top) position takes precedence over the max (right/bottom).
//
@@ -681,8 +705,9 @@ static int computeBestScrollOffset(int currentScrollOffset, int subfocusMin, int
{
int viewportSize = viewportMax - viewportMin;
- // If the focus size is larger than the viewport size, shrink it in the
- // direction of subfocus.
+ // If the object size is larger than the viewport size, consider
+ // only a portion that's as large as the viewport, centering on
+ // the subfocus as much as possible.
if (objectMax - objectMin > viewportSize) {
// Subfocus must be within focus:
subfocusMin = std::max(subfocusMin, objectMin);
@@ -692,12 +717,12 @@ static int computeBestScrollOffset(int currentScrollOffset, int subfocusMin, int
if (subfocusMax - subfocusMin > viewportSize)
subfocusMax = subfocusMin + viewportSize;
- if (subfocusMin + viewportSize > objectMax) {
- objectMin = objectMax - viewportSize;
- } else {
- objectMin = subfocusMin;
- objectMax = subfocusMin + viewportSize;
- }
+ // Compute the size of an object centered on the subfocus, the size of the viewport.
+ int centeredObjectMin = (subfocusMin + subfocusMax - viewportSize) / 2;
+ int centeredObjectMax = centeredObjectMin + viewportSize;
+
+ objectMin = std::max(objectMin, centeredObjectMin);
+ objectMax = std::min(objectMax, centeredObjectMax);
}
// Exit now if the focus is already within the viewport.
@@ -705,18 +730,8 @@ static int computeBestScrollOffset(int currentScrollOffset, int subfocusMin, int
&& objectMax - currentScrollOffset <= viewportMax)
return currentScrollOffset;
- // Scroll left if we're too far to the right.
- if (objectMax - currentScrollOffset > viewportMax)
- return objectMax - viewportMax;
-
- // Scroll right if we're too far to the left.
- if (objectMin - currentScrollOffset < viewportMin)
- return objectMin - viewportMin;
-
- ASSERT_NOT_REACHED();
-
- // This shouldn't happen.
- return currentScrollOffset;
+ // Center the object in the viewport.
+ return (objectMin + objectMax - viewportMin - viewportMax) / 2;
}
void AXObject::scrollToMakeVisibleWithSubFocus(const IntRect& subfocus) const
@@ -750,9 +765,16 @@ void AXObject::scrollToMakeVisibleWithSubFocus(const IntRect& subfocus) const
scrollParent->scrollTo(IntPoint(desiredX, desiredY));
+ // Convert the subfocus into the coordinates of the scroll parent.
+ IntRect newSubfocus = subfocus;
+ IntRect newElementRect = pixelSnappedIntRect(elementRect());
+ IntRect scrollParentRect = pixelSnappedIntRect(scrollParent->elementRect());
+ newSubfocus.move(newElementRect.x(), newElementRect.y());
+ newSubfocus.move(-scrollParentRect.x(), -scrollParentRect.y());
+
// Recursively make sure the scroll parent itself is visible.
if (scrollParent->parentObject())
- scrollParent->scrollToMakeVisible();
+ scrollParent->scrollToMakeVisibleWithSubFocus(newSubfocus);
}
void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const
« no previous file with comments | « LayoutTests/accessibility/scroll-to-make-visible-nested-2-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698