| Index: content/browser/accessibility/browser_accessibility.cc
|
| ===================================================================
|
| --- content/browser/accessibility/browser_accessibility.cc (revision 112818)
|
| +++ content/browser/accessibility/browser_accessibility.cc (working copy)
|
| @@ -163,6 +163,92 @@
|
| return this;
|
| }
|
|
|
| +void BrowserAccessibility::ScrollToMakeVisible(const gfx::Rect& subfocus,
|
| + const gfx::Rect& focus,
|
| + const gfx::Rect& viewport) {
|
| + int scroll_x = 0;
|
| + int scroll_x_min = 0;
|
| + int scroll_x_max = 0;
|
| + int scroll_y = 0;
|
| + int scroll_y_min = 0;
|
| + int scroll_y_max = 0;
|
| + if (!GetIntAttribute(WebAccessibility::ATTR_SCROLL_X, &scroll_x) ||
|
| + !GetIntAttribute(WebAccessibility::ATTR_SCROLL_X_MIN, &scroll_x_min) ||
|
| + !GetIntAttribute(WebAccessibility::ATTR_SCROLL_X_MAX, &scroll_x_max) ||
|
| + !GetIntAttribute(WebAccessibility::ATTR_SCROLL_Y, &scroll_y) ||
|
| + !GetIntAttribute(WebAccessibility::ATTR_SCROLL_Y_MIN, &scroll_y_min) ||
|
| + !GetIntAttribute(WebAccessibility::ATTR_SCROLL_Y_MAX, &scroll_y_max)) {
|
| + return;
|
| + }
|
| +
|
| + gfx::Rect final_viewport(0, 0, location_.width(), location_.height());
|
| + final_viewport.Intersect(viewport);
|
| +
|
| + int new_scroll_x = ComputeBestScrollOffset(
|
| + scroll_x,
|
| + subfocus.x(), subfocus.right(),
|
| + focus.x(), focus.right(),
|
| + final_viewport.x(), final_viewport.right());
|
| + new_scroll_x = std::max(new_scroll_x, scroll_x_min);
|
| + new_scroll_x = std::min(new_scroll_x, scroll_x_max);
|
| +
|
| + int new_scroll_y = ComputeBestScrollOffset(
|
| + scroll_y,
|
| + subfocus.y(), subfocus.bottom(),
|
| + focus.y(), focus.bottom(),
|
| + final_viewport.y(), final_viewport.bottom());
|
| + new_scroll_y = std::max(new_scroll_y, scroll_y_min);
|
| + new_scroll_y = std::min(new_scroll_y, scroll_y_max);
|
| +
|
| + manager_->ChangeScrollPosition(*this, new_scroll_x, new_scroll_y);
|
| +}
|
| +
|
| +// static
|
| +int BrowserAccessibility::ComputeBestScrollOffset(
|
| + int current_scroll_offset,
|
| + int subfocus_min, int subfocus_max,
|
| + int focus_min, int focus_max,
|
| + int viewport_min, int viewport_max) {
|
| + int viewport_size = viewport_max - viewport_min;
|
| +
|
| + // If the focus size is larger than the viewport size, shrink it in the
|
| + // direction of subfocus.
|
| + if (focus_max - focus_min > viewport_size) {
|
| + // Subfocus must be within focus:
|
| + subfocus_min = std::max(subfocus_min, focus_min);
|
| + subfocus_max = std::min(subfocus_max, focus_max);
|
| +
|
| + // Subfocus must be no larger than the viewport size; favor top/left.
|
| + if (subfocus_max - subfocus_min > viewport_size)
|
| + subfocus_max = subfocus_min + viewport_size;
|
| +
|
| + if (subfocus_min + viewport_size > focus_max) {
|
| + focus_min = focus_max - viewport_size;
|
| + } else {
|
| + focus_min = subfocus_min;
|
| + focus_max = subfocus_min + viewport_size;
|
| + }
|
| + }
|
| +
|
| + // Exit now if the focus is already within the viewport.
|
| + if (focus_min - current_scroll_offset >= viewport_min &&
|
| + focus_max - current_scroll_offset <= viewport_max) {
|
| + return current_scroll_offset;
|
| + }
|
| +
|
| + // Scroll left if we're too far to the right.
|
| + if (focus_max - current_scroll_offset > viewport_max)
|
| + return focus_max - viewport_max;
|
| +
|
| + // Scroll right if we're too far to the left.
|
| + if (focus_min - current_scroll_offset < viewport_min)
|
| + return focus_min - viewport_min;
|
| +
|
| + // This shouldn't happen.
|
| + NOTREACHED();
|
| + return current_scroll_offset;
|
| +}
|
| +
|
| void BrowserAccessibility::InternalAddReference() {
|
| ref_count_++;
|
| }
|
|
|