diff options
-rw-r--r-- | third_party/WebKit/Source/core/layout/ScrollAnchor.cpp | 12 | ||||
-rw-r--r-- | third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp | 40 |
2 files changed, 51 insertions, 1 deletions
diff --git a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp index ba2558b..7959b41 100644 --- a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp +++ b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp @@ -86,6 +86,16 @@ static LayoutPoint computeRelativeOffset(const LayoutObject* layoutObject, const return cornerPointOfRect(relativeBounds(layoutObject, scroller), corner); } +static bool candidateMovesWithScroller(const LayoutObject* candidate, const ScrollableArea* scroller) +{ + if (candidate->style() && candidate->style()->hasViewportConstrainedPosition()) + return false; + + bool skippedByContainerLookup = false; + candidate->container(scrollerLayoutBox(scroller), &skippedByContainerLookup); + return !skippedByContainerLookup; +} + ScrollAnchor::ExamineResult ScrollAnchor::examine(const LayoutObject* candidate) const { if (candidate->isLayoutInline()) @@ -94,7 +104,7 @@ ScrollAnchor::ExamineResult ScrollAnchor::examine(const LayoutObject* candidate) if (!candidate->isText() && !candidate->isBox()) return ExamineResult(Skip); - if (candidate->style() && candidate->style()->hasViewportConstrainedPosition()) + if (!candidateMovesWithScroller(candidate, m_scroller)) return ExamineResult(Skip); LayoutRect candidateRect = relativeBounds(candidate, m_scroller); diff --git a/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp b/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp index 0f7a5e0..f52e831 100644 --- a/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp +++ b/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp @@ -180,6 +180,46 @@ TEST_F(ScrollAnchorTest, ExcludeFixedPosition) scrollAnchor(layoutViewport()).anchorObject()); } +TEST_F(ScrollAnchorTest, ExcludeAbsolutePosition) +{ + setBodyInnerHTML( + "<style>" + " body { margin: 0; }" + " #scroller { overflow: scroll; width: 500px; height: 400px; }" + " #space { height: 1000px; }" + " #abs {" + " position: absolute; background-color: red;" + " left: 200px; top: 100px; width: 100px; height: 100px;" + " }" + " #rel {" + " position: relative; background-color: green;" + " left: 50px; top: 100px; width: 100px; height: 75px;" + " }" + "</style>" + "<div id='scroller'><div id='space'>" + " <div id='abs'></div>" + " <div id='rel'></div>" + "</div></div>"); + + Element* scrollerElement = document().getElementById("scroller"); + ScrollableArea* scroller = scrollerForElement(scrollerElement); + Element* absPos = document().getElementById("abs"); + Element* relPos = document().getElementById("rel"); + + scroller->scrollBy(DoubleSize(0, 25), UserScroll); + setHeight(relPos, 100); + + // When the scroller is position:static, the anchor cannot be position:absolute. + EXPECT_EQ(relPos->layoutObject(), scrollAnchor(scroller).anchorObject()); + + scrollerElement->setAttribute(HTMLNames::styleAttr, "position: relative"); + scroller->scrollBy(DoubleSize(0, 25), UserScroll); + setHeight(relPos, 125); + + // When the scroller is position:relative, the anchor may be position:absolute. + EXPECT_EQ(absPos->layoutObject(), scrollAnchor(scroller).anchorObject()); +} + class ScrollAnchorCornerTest : public ScrollAnchorTest { protected: void checkCorner(const AtomicString& id, Corner corner, DoublePoint startPos, DoubleSize expectedAdjustment) |