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