| Index: third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
|
| index 3242c0d94d87e53a6851496dfa2c6488d5e56e30..6f6b4c61103e571e9f092d232d653359e17b91d9 100644
|
| --- a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
|
| @@ -4,8 +4,9 @@
|
|
|
| #include "core/layout/ScrollAnchor.h"
|
|
|
| -#include "core/layout/LayoutObject.h"
|
| -#include "platform/scroll/ScrollableArea.h"
|
| +#include "core/frame/FrameView.h"
|
| +#include "core/layout/LayoutView.h"
|
| +#include "core/paint/PaintLayerScrollableArea.h"
|
| #include "wtf/Assertions.h"
|
|
|
| namespace blink {
|
| @@ -22,26 +23,51 @@ ScrollAnchor::~ScrollAnchor()
|
| {
|
| }
|
|
|
| +static LayoutBox* scrollerLayoutBox(const ScrollableArea* scroller)
|
| +{
|
| + LayoutBox* box = scroller->isFrameView()
|
| + ? toFrameView(scroller)->layoutView()
|
| + : &toPaintLayerScrollableArea(scroller)->box();
|
| + ASSERT(box);
|
| + return box;
|
| +}
|
| +
|
| static LayoutObject* findAnchor(const ScrollableArea* scroller)
|
| {
|
| - // TODO(skobes): implement.
|
| - return nullptr;
|
| + LayoutBox* scrollerBox = scrollerLayoutBox(scroller);
|
| +
|
| + FloatRect absoluteVisibleRect = scroller->isFrameView()
|
| + ? scroller->visibleContentRect()
|
| + : scrollerBox->localToAbsoluteQuad(
|
| + FloatQuad(FloatRect(scrollerBox->overflowClipRect(LayoutPoint())))).boundingBox();
|
| +
|
| + LayoutObject* child = scrollerBox->nextInPreOrder(scrollerBox);
|
| + LayoutObject* candidate = nullptr;
|
| + while (child) {
|
| + // TODO(skobes): Compute scroller-relative bounds instead of absolute bounds.
|
| + FloatRect childRect = child->absoluteBoundingBoxFloatRect();
|
| + if (absoluteVisibleRect.intersects(childRect))
|
| + candidate = child;
|
| + if (absoluteVisibleRect.contains(childRect))
|
| + break;
|
| + child = child->nextInPreOrder(scrollerBox);
|
| + }
|
| + return candidate;
|
| }
|
|
|
| static DoublePoint computeRelativeOffset(const ScrollableArea* scroller, const LayoutObject* layoutObject)
|
| {
|
| - // TODO(skobes): implement.
|
| - return DoublePoint();
|
| + return DoublePoint(layoutObject->localToAbsolute() - scrollerLayoutBox(scroller)->localToAbsolute());
|
| }
|
|
|
| void ScrollAnchor::save()
|
| {
|
| - if (!m_anchorObject) {
|
| - m_anchorObject = findAnchor(m_scroller);
|
| - if (!m_anchorObject)
|
| - return;
|
| - m_anchorObject->setIsScrollAnchorObject();
|
| - }
|
| + if (m_anchorObject)
|
| + return;
|
| + m_anchorObject = findAnchor(m_scroller);
|
| + if (!m_anchorObject)
|
| + return;
|
| + m_anchorObject->setIsScrollAnchorObject();
|
| m_savedRelativeOffset = computeRelativeOffset(m_scroller, m_anchorObject);
|
| }
|
|
|
|
|