| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/layout/ScrollAnchor.h" | 5 #include "core/layout/ScrollAnchor.h" |
| 6 | 6 |
| 7 #include "core/dom/ClientRect.h" | 7 #include "core/dom/ClientRect.h" |
| 8 #include "core/frame/VisualViewport.h" | 8 #include "core/frame/VisualViewport.h" |
| 9 #include "core/layout/LayoutBox.h" | 9 #include "core/layout/LayoutBox.h" |
| 10 #include "core/layout/LayoutTestHelper.h" | 10 #include "core/layout/LayoutTestHelper.h" |
| 11 #include "core/paint/PaintLayerScrollableArea.h" | 11 #include "core/paint/PaintLayerScrollableArea.h" |
| 12 #include "platform/testing/HistogramTester.h" | 12 #include "platform/testing/HistogramTester.h" |
| 13 | 13 |
| 14 namespace blink { | 14 namespace blink { |
| 15 | 15 |
| 16 using Corner = ScrollAnchor::Corner; | 16 using Corner = ScrollAnchor::Corner; |
| 17 | 17 |
| 18 class ScrollAnchorTest : public RenderingTest { | 18 class ScrollAnchorTest : public RenderingTest { |
| 19 public: | 19 public: |
| 20 ScrollAnchorTest() { | 20 explicit ScrollAnchorTest(FrameLoaderClient* frameLoaderClient = nullptr) |
| 21 : RenderingTest(frameLoaderClient) { |
| 21 RuntimeEnabledFeatures::setScrollAnchoringEnabled(true); | 22 RuntimeEnabledFeatures::setScrollAnchoringEnabled(true); |
| 22 } | 23 } |
| 23 ~ScrollAnchorTest() { | 24 ~ScrollAnchorTest() { |
| 24 RuntimeEnabledFeatures::setScrollAnchoringEnabled(false); | 25 RuntimeEnabledFeatures::setScrollAnchoringEnabled(false); |
| 25 } | 26 } |
| 26 | 27 |
| 27 protected: | 28 protected: |
| 28 void update() { | 29 void update() { |
| 29 // TODO(skobes): Use SimTest instead of RenderingTest and move into Source/w
eb? | 30 // TODO(skobes): Use SimTest instead of RenderingTest and move into Source/w
eb? |
| 30 document().view()->updateAllLifecyclePhases(); | 31 document().view()->updateAllLifecyclePhases(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 57 Element* scrollingElement = document().scrollingElement(); | 58 Element* scrollingElement = document().scrollingElement(); |
| 58 if (delta.width()) | 59 if (delta.width()) |
| 59 scrollingElement->setScrollLeft(scrollingElement->scrollLeft() + | 60 scrollingElement->setScrollLeft(scrollingElement->scrollLeft() + |
| 60 delta.width()); | 61 delta.width()); |
| 61 if (delta.height()) | 62 if (delta.height()) |
| 62 scrollingElement->setScrollTop(scrollingElement->scrollTop() + | 63 scrollingElement->setScrollTop(scrollingElement->scrollTop() + |
| 63 delta.height()); | 64 delta.height()); |
| 64 } | 65 } |
| 65 }; | 66 }; |
| 66 | 67 |
| 68 class ScrollAnchorFrameTest : public ScrollAnchorTest { |
| 69 public: |
| 70 ScrollAnchorFrameTest() |
| 71 : ScrollAnchorTest(SingleChildFrameLoaderClient::create()) {} |
| 72 }; |
| 73 |
| 67 // TODO(ymalik): Currently, this should be the first test in the file to avoid | 74 // TODO(ymalik): Currently, this should be the first test in the file to avoid |
| 68 // failure when running with other tests. Dig into this more and fix. | 75 // failure when running with other tests. Dig into this more and fix. |
| 69 TEST_F(ScrollAnchorTest, UMAMetricUpdated) { | 76 TEST_F(ScrollAnchorTest, UMAMetricUpdated) { |
| 70 HistogramTester histogramTester; | 77 HistogramTester histogramTester; |
| 71 setBodyInnerHTML( | 78 setBodyInnerHTML( |
| 72 "<style> body { height: 1000px } div { height: 100px } </style>" | 79 "<style> body { height: 1000px } div { height: 100px } </style>" |
| 73 "<div id='block1'>abc</div>" | 80 "<div id='block1'>abc</div>" |
| 74 "<div id='block2'>def</div>"); | 81 "<div id='block2'>def</div>"); |
| 75 | 82 |
| 76 ScrollableArea* viewport = layoutViewport(); | 83 ScrollableArea* viewport = layoutViewport(); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 | 240 |
| 234 document().getElementById("scroller")->setScrollTop(1600); | 241 document().getElementById("scroller")->setScrollTop(1600); |
| 235 | 242 |
| 236 setHeight(document().getElementById("changer"), 0); | 243 setHeight(document().getElementById("changer"), 0); |
| 237 | 244 |
| 238 EXPECT_EQ(100, scroller->scrollPosition().y()); | 245 EXPECT_EQ(100, scroller->scrollPosition().y()); |
| 239 EXPECT_EQ(document().getElementById("anchor")->layoutObject(), | 246 EXPECT_EQ(document().getElementById("anchor")->layoutObject(), |
| 240 scrollAnchor(scroller).anchorObject()); | 247 scrollAnchor(scroller).anchorObject()); |
| 241 } | 248 } |
| 242 | 249 |
| 250 // Test that a non-anchoring scroll on scroller clears scroll anchors for all |
| 251 // parent scrollers. |
| 252 TEST_F(ScrollAnchorTest, ClearScrollAnchorsOnAncestors) { |
| 253 setBodyInnerHTML( |
| 254 "<style>" |
| 255 " body { height: 1000px } div { height: 200px }" |
| 256 " #scroller { height: 100px; width: 200px; overflow: scroll; }" |
| 257 "</style>" |
| 258 "<div id='changer'>abc</div>" |
| 259 "<div id='anchor'>def</div>" |
| 260 "<div id='scroller'><div></div></div>"); |
| 261 |
| 262 ScrollableArea* viewport = layoutViewport(); |
| 263 |
| 264 scrollLayoutViewport(DoubleSize(0, 250)); |
| 265 setHeight(document().getElementById("changer"), 300); |
| 266 |
| 267 EXPECT_EQ(350, viewport->scrollPosition().y()); |
| 268 EXPECT_EQ(document().getElementById("anchor")->layoutObject(), |
| 269 scrollAnchor(viewport).anchorObject()); |
| 270 |
| 271 // Scrolling the nested scroller should clear the anchor on the main frame. |
| 272 ScrollableArea* scroller = |
| 273 scrollerForElement(document().getElementById("scroller")); |
| 274 scroller->scrollBy(DoubleSize(0, 100), UserScroll); |
| 275 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); |
| 276 } |
| 277 |
| 278 TEST_F(ScrollAnchorFrameTest, ClearScrollAnchorsOnAncestorsOfIframe) { |
| 279 document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com")); |
| 280 setBodyInnerHTML( |
| 281 "<style>" |
| 282 " body { height: 1000px } div { height: 200px }" |
| 283 " #scroller { height: 100px; width: 200px; overflow: scroll; }" |
| 284 "</style>" |
| 285 "<div id='changer'>abc</div>" |
| 286 "<div id='anchor'>def</div>" |
| 287 "<iframe id='scroller' src='http://test.com'></iframe>"); |
| 288 |
| 289 Document& frameDocument = |
| 290 setupChildIframe("scroller", "<style> body { height: 1000px } </style>"); |
| 291 |
| 292 ScrollableArea* viewport = layoutViewport(); |
| 293 |
| 294 scrollLayoutViewport(DoubleSize(0, 250)); |
| 295 setHeight(document().getElementById("changer"), 300); |
| 296 |
| 297 EXPECT_EQ(350, viewport->scrollPosition().y()); |
| 298 EXPECT_EQ(document().getElementById("anchor")->layoutObject(), |
| 299 scrollAnchor(viewport).anchorObject()); |
| 300 |
| 301 // Scrolling the iframe should clear the anchor on the main frame. |
| 302 frameDocument.view()->setScrollPosition(DoublePoint(0.0, 1000), |
| 303 ProgrammaticScroll); |
| 304 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); |
| 305 } |
| 306 |
| 243 TEST_F(ScrollAnchorTest, FractionalOffsetsAreRoundedBeforeComparing) { | 307 TEST_F(ScrollAnchorTest, FractionalOffsetsAreRoundedBeforeComparing) { |
| 244 setBodyInnerHTML( | 308 setBodyInnerHTML( |
| 245 "<style> body { height: 1000px } </style>" | 309 "<style> body { height: 1000px } </style>" |
| 246 "<div id='block1' style='height: 50.4px'>abc</div>" | 310 "<div id='block1' style='height: 50.4px'>abc</div>" |
| 247 "<div id='block2' style='height: 100px'>def</div>"); | 311 "<div id='block2' style='height: 100px'>def</div>"); |
| 248 | 312 |
| 249 ScrollableArea* viewport = layoutViewport(); | 313 ScrollableArea* viewport = layoutViewport(); |
| 250 scrollLayoutViewport(DoubleSize(0, 100)); | 314 scrollLayoutViewport(DoubleSize(0, 100)); |
| 251 | 315 |
| 252 document().getElementById("block1")->setAttribute(HTMLNames::styleAttr, | 316 document().getElementById("block1")->setAttribute(HTMLNames::styleAttr, |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 | 1038 |
| 975 scrollLayoutViewport(DoubleSize(-50, 0)); | 1039 scrollLayoutViewport(DoubleSize(-50, 0)); |
| 976 | 1040 |
| 977 a->setAttribute(HTMLNames::styleAttr, "width: 200px"); | 1041 a->setAttribute(HTMLNames::styleAttr, "width: 200px"); |
| 978 b->setAttribute(HTMLNames::styleAttr, "height: 150px"); | 1042 b->setAttribute(HTMLNames::styleAttr, "height: 150px"); |
| 979 update(); | 1043 update(); |
| 980 EXPECT_EQ(DoublePoint(-100, 150), viewport->scrollPositionDouble()); | 1044 EXPECT_EQ(DoublePoint(-100, 150), viewport->scrollPositionDouble()); |
| 981 EXPECT_EQ(c->layoutObject(), scrollAnchor(viewport).anchorObject()); | 1045 EXPECT_EQ(c->layoutObject(), scrollAnchor(viewport).anchorObject()); |
| 982 } | 1046 } |
| 983 } | 1047 } |
| OLD | NEW |