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); |
} |