diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp b/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp index d28c8e00b2e..d331f1dc07b 100644 --- a/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp +++ b/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp @@ -44,6 +44,8 @@ #include "config.h" #include "core/rendering/ScrollBehavior.h" +#include "platform/geometry/LayoutRect.h" + namespace WebCore { const ScrollAlignment ScrollAlignment::alignCenterIfNeeded = { noScroll, alignCenter, alignToClosestEdge }; @@ -52,4 +54,93 @@ const ScrollAlignment ScrollAlignment::alignCenterAlways = { alignCenter, alignC const ScrollAlignment ScrollAlignment::alignTopAlways = { alignTop, alignTop, alignTop }; const ScrollAlignment ScrollAlignment::alignBottomAlways = { alignBottom, alignBottom, alignBottom }; +#define MIN_INTERSECT_FOR_REVEAL 32 + +LayoutRect ScrollAlignment::getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY) +{ + // Determine the appropriate X behavior. + ScrollBehavior scrollX; + LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height()); + LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width(); + if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL) { + // If the rectangle is fully visible, use the specified visible behavior. + // If the rectangle is partially visible, but over a certain threshold, + // then treat it as fully visible to avoid unnecessary horizontal scrolling + scrollX = getVisibleBehavior(alignX); + } else if (intersectWidth == visibleRect.width()) { + // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work. + scrollX = getVisibleBehavior(alignX); + if (scrollX == alignCenter) + scrollX = noScroll; + } else if (intersectWidth > 0) { + // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior + scrollX = getPartialBehavior(alignX); + } else { + scrollX = getHiddenBehavior(alignX); + } + + if (scrollX == alignToClosestEdge) { + // Closest edge is the right in two cases: + // (1) exposeRect to the right of and smaller than visibleRect + // (2) exposeRect to the left of and larger than visibleRect + if ((exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width()) + || (exposeRect.maxX() < visibleRect.maxX() && exposeRect.width() > visibleRect.width())) { + scrollX = alignRight; + } + } + + // Given the X behavior, compute the X coordinate. + LayoutUnit x; + if (scrollX == noScroll) + x = visibleRect.x(); + else if (scrollX == alignRight) + x = exposeRect.maxX() - visibleRect.width(); + else if (scrollX == alignCenter) + x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2; + else + x = exposeRect.x(); + + // Determine the appropriate Y behavior. + ScrollBehavior scrollY; + LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height()); + LayoutUnit intersectHeight = intersection(visibleRect, exposeRectY).height(); + if (intersectHeight == exposeRect.height()) { + // If the rectangle is fully visible, use the specified visible behavior. + scrollY = getVisibleBehavior(alignY); + } else if (intersectHeight == visibleRect.height()) { + // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work. + scrollY = getVisibleBehavior(alignY); + if (scrollY == alignCenter) + scrollY = noScroll; + } else if (intersectHeight > 0) { + // If the rectangle is partially visible, use the specified partial behavior + scrollY = getPartialBehavior(alignY); + } else { + scrollY = getHiddenBehavior(alignY); + } + + if (scrollY == alignToClosestEdge) { + // Closest edge is the bottom in two cases: + // (1) exposeRect below and smaller than visibleRect + // (2) exposeRect above and larger than visibleRect + if ((exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height()) + || (exposeRect.maxY() < visibleRect.maxY() && exposeRect.height() > visibleRect.height())) { + scrollY = alignBottom; + } + } + + // Given the Y behavior, compute the Y coordinate. + LayoutUnit y; + if (scrollY == noScroll) + y = visibleRect.y(); + else if (scrollY == alignBottom) + y = exposeRect.maxY() - visibleRect.height(); + else if (scrollY == alignCenter) + y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2; + else + y = exposeRect.y(); + + return LayoutRect(LayoutPoint(x, y), visibleRect.size()); +} + }; // namespace WebCore |