| 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" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 ASSERT(scroller->isFrameView() || scroller->isPaintLayerScrollableArea()); | 46 ASSERT(scroller->isFrameView() || scroller->isPaintLayerScrollableArea()); |
| 47 return *(scroller->scrollAnchor()); | 47 return *(scroller->scrollAnchor()); |
| 48 } | 48 } |
| 49 | 49 |
| 50 void setHeight(Element* element, int height) { | 50 void setHeight(Element* element, int height) { |
| 51 element->setAttribute(HTMLNames::styleAttr, | 51 element->setAttribute(HTMLNames::styleAttr, |
| 52 AtomicString(String::format("height: %dpx", height))); | 52 AtomicString(String::format("height: %dpx", height))); |
| 53 update(); | 53 update(); |
| 54 } | 54 } |
| 55 | 55 |
| 56 void scrollLayoutViewport(DoubleSize delta) { | 56 void scrollLayoutViewport(ScrollOffset delta) { |
| 57 Element* scrollingElement = document().scrollingElement(); | 57 Element* scrollingElement = document().scrollingElement(); |
| 58 if (delta.width()) | 58 if (delta.width()) |
| 59 scrollingElement->setScrollLeft(scrollingElement->scrollLeft() + | 59 scrollingElement->setScrollLeft(scrollingElement->scrollLeft() + |
| 60 delta.width()); | 60 delta.width()); |
| 61 if (delta.height()) | 61 if (delta.height()) |
| 62 scrollingElement->setScrollTop(scrollingElement->scrollTop() + | 62 scrollingElement->setScrollTop(scrollingElement->scrollTop() + |
| 63 delta.height()); | 63 delta.height()); |
| 64 } | 64 } |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 // TODO(ymalik): Currently, this should be the first test in the file to avoid | 67 // 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. | 68 // failure when running with other tests. Dig into this more and fix. |
| 69 TEST_F(ScrollAnchorTest, UMAMetricUpdated) { | 69 TEST_F(ScrollAnchorTest, UMAMetricUpdated) { |
| 70 HistogramTester histogramTester; | 70 HistogramTester histogramTester; |
| 71 setBodyInnerHTML( | 71 setBodyInnerHTML( |
| 72 "<style> body { height: 1000px } div { height: 100px } </style>" | 72 "<style> body { height: 1000px } div { height: 100px } </style>" |
| 73 "<div id='block1'>abc</div>" | 73 "<div id='block1'>abc</div>" |
| 74 "<div id='block2'>def</div>"); | 74 "<div id='block2'>def</div>"); |
| 75 | 75 |
| 76 ScrollableArea* viewport = layoutViewport(); | 76 ScrollableArea* viewport = layoutViewport(); |
| 77 | 77 |
| 78 // Scroll position not adjusted, metric not updated. | 78 // Scroll position not adjusted, metric not updated. |
| 79 scrollLayoutViewport(DoubleSize(0, 150)); | 79 scrollLayoutViewport(ScrollOffset(0, 150)); |
| 80 histogramTester.expectTotalCount("Layout.ScrollAnchor.AdjustedScrollOffset", | 80 histogramTester.expectTotalCount("Layout.ScrollAnchor.AdjustedScrollOffset", |
| 81 0); | 81 0); |
| 82 | 82 |
| 83 // Height changed, verify metric updated once. | 83 // Height changed, verify metric updated once. |
| 84 setHeight(document().getElementById("block1"), 200); | 84 setHeight(document().getElementById("block1"), 200); |
| 85 histogramTester.expectUniqueSample("Layout.ScrollAnchor.AdjustedScrollOffset", | 85 histogramTester.expectUniqueSample("Layout.ScrollAnchor.AdjustedScrollOffset", |
| 86 1, 1); | 86 1, 1); |
| 87 | 87 |
| 88 EXPECT_EQ(250, viewport->scrollPosition().y()); | 88 EXPECT_EQ(250, viewport->scrollOffsetInt().height()); |
| 89 EXPECT_EQ(document().getElementById("block2")->layoutObject(), | 89 EXPECT_EQ(document().getElementById("block2")->layoutObject(), |
| 90 scrollAnchor(viewport).anchorObject()); | 90 scrollAnchor(viewport).anchorObject()); |
| 91 } | 91 } |
| 92 | 92 |
| 93 TEST_F(ScrollAnchorTest, Basic) { | 93 TEST_F(ScrollAnchorTest, Basic) { |
| 94 setBodyInnerHTML( | 94 setBodyInnerHTML( |
| 95 "<style> body { height: 1000px } div { height: 100px } </style>" | 95 "<style> body { height: 1000px } div { height: 100px } </style>" |
| 96 "<div id='block1'>abc</div>" | 96 "<div id='block1'>abc</div>" |
| 97 "<div id='block2'>def</div>"); | 97 "<div id='block2'>def</div>"); |
| 98 | 98 |
| 99 ScrollableArea* viewport = layoutViewport(); | 99 ScrollableArea* viewport = layoutViewport(); |
| 100 | 100 |
| 101 // No anchor at origin (0,0). | 101 // No anchor at origin (0,0). |
| 102 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); | 102 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); |
| 103 | 103 |
| 104 scrollLayoutViewport(DoubleSize(0, 150)); | 104 scrollLayoutViewport(ScrollOffset(0, 150)); |
| 105 setHeight(document().getElementById("block1"), 200); | 105 setHeight(document().getElementById("block1"), 200); |
| 106 | 106 |
| 107 EXPECT_EQ(250, viewport->scrollPosition().y()); | 107 EXPECT_EQ(250, viewport->scrollOffsetInt().height()); |
| 108 EXPECT_EQ(document().getElementById("block2")->layoutObject(), | 108 EXPECT_EQ(document().getElementById("block2")->layoutObject(), |
| 109 scrollAnchor(viewport).anchorObject()); | 109 scrollAnchor(viewport).anchorObject()); |
| 110 | 110 |
| 111 // ScrollableArea::userScroll should clear the anchor. | 111 // ScrollableArea::userScroll should clear the anchor. |
| 112 viewport->userScroll(ScrollByPrecisePixel, FloatSize(0, 100)); | 112 viewport->userScroll(ScrollByPrecisePixel, FloatSize(0, 100)); |
| 113 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); | 113 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); |
| 114 } | 114 } |
| 115 | 115 |
| 116 TEST_F(ScrollAnchorTest, VisualViewportAnchors) { | 116 TEST_F(ScrollAnchorTest, VisualViewportAnchors) { |
| 117 setBodyInnerHTML( | 117 setBodyInnerHTML( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 130 // No anchor at origin (0,0). | 130 // No anchor at origin (0,0). |
| 131 EXPECT_EQ(nullptr, scrollAnchor(lViewport).anchorObject()); | 131 EXPECT_EQ(nullptr, scrollAnchor(lViewport).anchorObject()); |
| 132 | 132 |
| 133 // Scroll the visual viewport to bring #text to the top. | 133 // Scroll the visual viewport to bring #text to the top. |
| 134 int top = document().getElementById("text")->getBoundingClientRect()->top(); | 134 int top = document().getElementById("text")->getBoundingClientRect()->top(); |
| 135 vViewport.setLocation(FloatPoint(0, top)); | 135 vViewport.setLocation(FloatPoint(0, top)); |
| 136 | 136 |
| 137 setHeight(document().getElementById("div"), 10); | 137 setHeight(document().getElementById("div"), 10); |
| 138 EXPECT_EQ(document().getElementById("text")->layoutObject(), | 138 EXPECT_EQ(document().getElementById("text")->layoutObject(), |
| 139 scrollAnchor(lViewport).anchorObject()); | 139 scrollAnchor(lViewport).anchorObject()); |
| 140 EXPECT_EQ(top - 90, vViewport.scrollPosition().y()); | 140 EXPECT_EQ(top - 90, vViewport.scrollOffsetInt().height()); |
| 141 | 141 |
| 142 setHeight(document().getElementById("div"), 100); | 142 setHeight(document().getElementById("div"), 100); |
| 143 EXPECT_EQ(document().getElementById("text")->layoutObject(), | 143 EXPECT_EQ(document().getElementById("text")->layoutObject(), |
| 144 scrollAnchor(lViewport).anchorObject()); | 144 scrollAnchor(lViewport).anchorObject()); |
| 145 EXPECT_EQ(top, vViewport.scrollPosition().y()); | 145 EXPECT_EQ(top, vViewport.scrollOffsetInt().height()); |
| 146 | 146 |
| 147 // Scrolling the visual viewport should clear the anchor. | 147 // Scrolling the visual viewport should clear the anchor. |
| 148 vViewport.setLocation(FloatPoint(0, 0)); | 148 vViewport.setLocation(FloatPoint(0, 0)); |
| 149 EXPECT_EQ(nullptr, scrollAnchor(lViewport).anchorObject()); | 149 EXPECT_EQ(nullptr, scrollAnchor(lViewport).anchorObject()); |
| 150 } | 150 } |
| 151 | 151 |
| 152 // Test that we ignore the clipped content when computing visibility otherwise | 152 // Test that we ignore the clipped content when computing visibility otherwise |
| 153 // we may end up with an anchor that we think is in the viewport but is not. | 153 // we may end up with an anchor that we think is in the viewport but is not. |
| 154 TEST_F(ScrollAnchorTest, ClippedScrollersSkipped) { | 154 TEST_F(ScrollAnchorTest, ClippedScrollersSkipped) { |
| 155 setBodyInnerHTML( | 155 setBodyInnerHTML( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 168 " <div id='forceScrolling'></div>" | 168 " <div id='forceScrolling'></div>" |
| 169 "</div>" | 169 "</div>" |
| 170 "<div id='outerChanger'></div>" | 170 "<div id='outerChanger'></div>" |
| 171 "<div id='outerAnchor' class='anchor'></div>"); | 171 "<div id='outerAnchor' class='anchor'></div>"); |
| 172 | 172 |
| 173 ScrollableArea* scroller = | 173 ScrollableArea* scroller = |
| 174 scrollerForElement(document().getElementById("scroller")); | 174 scrollerForElement(document().getElementById("scroller")); |
| 175 ScrollableArea* viewport = layoutViewport(); | 175 ScrollableArea* viewport = layoutViewport(); |
| 176 | 176 |
| 177 document().getElementById("scroller")->setScrollTop(100); | 177 document().getElementById("scroller")->setScrollTop(100); |
| 178 scrollLayoutViewport(DoubleSize(0, 350)); | 178 scrollLayoutViewport(ScrollOffset(0, 350)); |
| 179 | 179 |
| 180 setHeight(document().getElementById("innerChanger"), 200); | 180 setHeight(document().getElementById("innerChanger"), 200); |
| 181 setHeight(document().getElementById("outerChanger"), 150); | 181 setHeight(document().getElementById("outerChanger"), 150); |
| 182 | 182 |
| 183 EXPECT_EQ(300, scroller->scrollPosition().y()); | 183 EXPECT_EQ(300, scroller->scrollOffsetInt().height()); |
| 184 EXPECT_EQ(document().getElementById("innerAnchor")->layoutObject(), | 184 EXPECT_EQ(document().getElementById("innerAnchor")->layoutObject(), |
| 185 scrollAnchor(scroller).anchorObject()); | 185 scrollAnchor(scroller).anchorObject()); |
| 186 EXPECT_EQ(500, viewport->scrollPosition().y()); | 186 EXPECT_EQ(500, viewport->scrollOffsetInt().height()); |
| 187 EXPECT_EQ(document().getElementById("outerAnchor")->layoutObject(), | 187 EXPECT_EQ(document().getElementById("outerAnchor")->layoutObject(), |
| 188 scrollAnchor(viewport).anchorObject()); | 188 scrollAnchor(viewport).anchorObject()); |
| 189 } | 189 } |
| 190 | 190 |
| 191 // Test that scroll anchoring causes no visible jump when a layout change | 191 // Test that scroll anchoring causes no visible jump when a layout change |
| 192 // (such as removal of a DOM element) changes the scroll bounds. | 192 // (such as removal of a DOM element) changes the scroll bounds. |
| 193 TEST_F(ScrollAnchorTest, AnchoringWhenContentRemoved) { | 193 TEST_F(ScrollAnchorTest, AnchoringWhenContentRemoved) { |
| 194 setBodyInnerHTML( | 194 setBodyInnerHTML( |
| 195 "<style>" | 195 "<style>" |
| 196 " #changer { height: 1500px; }" | 196 " #changer { height: 1500px; }" |
| 197 " #anchor {" | 197 " #anchor {" |
| 198 " width: 150px; height: 1000px; background-color: pink;" | 198 " width: 150px; height: 1000px; background-color: pink;" |
| 199 " }" | 199 " }" |
| 200 "</style>" | 200 "</style>" |
| 201 "<div id='changer'></div>" | 201 "<div id='changer'></div>" |
| 202 "<div id='anchor'></div>"); | 202 "<div id='anchor'></div>"); |
| 203 | 203 |
| 204 ScrollableArea* viewport = layoutViewport(); | 204 ScrollableArea* viewport = layoutViewport(); |
| 205 scrollLayoutViewport(DoubleSize(0, 1600)); | 205 scrollLayoutViewport(ScrollOffset(0, 1600)); |
| 206 | 206 |
| 207 setHeight(document().getElementById("changer"), 0); | 207 setHeight(document().getElementById("changer"), 0); |
| 208 | 208 |
| 209 EXPECT_EQ(100, viewport->scrollPosition().y()); | 209 EXPECT_EQ(100, viewport->scrollOffsetInt().height()); |
| 210 EXPECT_EQ(document().getElementById("anchor")->layoutObject(), | 210 EXPECT_EQ(document().getElementById("anchor")->layoutObject(), |
| 211 scrollAnchor(viewport).anchorObject()); | 211 scrollAnchor(viewport).anchorObject()); |
| 212 } | 212 } |
| 213 | 213 |
| 214 // Test that scroll anchoring causes no visible jump when a layout change | 214 // Test that scroll anchoring causes no visible jump when a layout change |
| 215 // (such as removal of a DOM element) changes the scroll bounds of a scrolling | 215 // (such as removal of a DOM element) changes the scroll bounds of a scrolling |
| 216 // div. | 216 // div. |
| 217 TEST_F(ScrollAnchorTest, AnchoringWhenContentRemovedFromScrollingDiv) { | 217 TEST_F(ScrollAnchorTest, AnchoringWhenContentRemovedFromScrollingDiv) { |
| 218 setBodyInnerHTML( | 218 setBodyInnerHTML( |
| 219 "<style>" | 219 "<style>" |
| 220 " #scroller { height: 500px; width: 200px; overflow: scroll; }" | 220 " #scroller { height: 500px; width: 200px; overflow: scroll; }" |
| 221 " #changer { height: 1500px; }" | 221 " #changer { height: 1500px; }" |
| 222 " #anchor {" | 222 " #anchor {" |
| 223 " width: 150px; height: 1000px; overflow: scroll;" | 223 " width: 150px; height: 1000px; overflow: scroll;" |
| 224 " }" | 224 " }" |
| 225 "</style>" | 225 "</style>" |
| 226 "<div id='scroller'>" | 226 "<div id='scroller'>" |
| 227 " <div id='changer'></div>" | 227 " <div id='changer'></div>" |
| 228 " <div id='anchor'></div>" | 228 " <div id='anchor'></div>" |
| 229 "</div>"); | 229 "</div>"); |
| 230 | 230 |
| 231 ScrollableArea* scroller = | 231 ScrollableArea* scroller = |
| 232 scrollerForElement(document().getElementById("scroller")); | 232 scrollerForElement(document().getElementById("scroller")); |
| 233 | 233 |
| 234 document().getElementById("scroller")->setScrollTop(1600); | 234 document().getElementById("scroller")->setScrollTop(1600); |
| 235 | 235 |
| 236 setHeight(document().getElementById("changer"), 0); | 236 setHeight(document().getElementById("changer"), 0); |
| 237 | 237 |
| 238 EXPECT_EQ(100, scroller->scrollPosition().y()); | 238 EXPECT_EQ(100, scroller->scrollOffsetInt().height()); |
| 239 EXPECT_EQ(document().getElementById("anchor")->layoutObject(), | 239 EXPECT_EQ(document().getElementById("anchor")->layoutObject(), |
| 240 scrollAnchor(scroller).anchorObject()); | 240 scrollAnchor(scroller).anchorObject()); |
| 241 } | 241 } |
| 242 | 242 |
| 243 TEST_F(ScrollAnchorTest, FractionalOffsetsAreRoundedBeforeComparing) { | 243 TEST_F(ScrollAnchorTest, FractionalOffsetsAreRoundedBeforeComparing) { |
| 244 setBodyInnerHTML( | 244 setBodyInnerHTML( |
| 245 "<style> body { height: 1000px } </style>" | 245 "<style> body { height: 1000px } </style>" |
| 246 "<div id='block1' style='height: 50.4px'>abc</div>" | 246 "<div id='block1' style='height: 50.4px'>abc</div>" |
| 247 "<div id='block2' style='height: 100px'>def</div>"); | 247 "<div id='block2' style='height: 100px'>def</div>"); |
| 248 | 248 |
| 249 ScrollableArea* viewport = layoutViewport(); | 249 ScrollableArea* viewport = layoutViewport(); |
| 250 scrollLayoutViewport(DoubleSize(0, 100)); | 250 scrollLayoutViewport(ScrollOffset(0, 100)); |
| 251 | 251 |
| 252 document().getElementById("block1")->setAttribute(HTMLNames::styleAttr, | 252 document().getElementById("block1")->setAttribute(HTMLNames::styleAttr, |
| 253 "height: 50.6px"); | 253 "height: 50.6px"); |
| 254 update(); | 254 update(); |
| 255 | 255 |
| 256 EXPECT_EQ(101, viewport->scrollPosition().y()); | 256 EXPECT_EQ(101, viewport->scrollOffsetInt().height()); |
| 257 } | 257 } |
| 258 | 258 |
| 259 TEST_F(ScrollAnchorTest, AnchorWithLayerInScrollingDiv) { | 259 TEST_F(ScrollAnchorTest, AnchorWithLayerInScrollingDiv) { |
| 260 setBodyInnerHTML( | 260 setBodyInnerHTML( |
| 261 "<style>" | 261 "<style>" |
| 262 " #scroller { overflow: scroll; width: 500px; height: 400px; }" | 262 " #scroller { overflow: scroll; width: 500px; height: 400px; }" |
| 263 " div { height: 100px }" | 263 " div { height: 100px }" |
| 264 " #block2 { overflow: hidden }" | 264 " #block2 { overflow: hidden }" |
| 265 " #space { height: 1000px; }" | 265 " #space { height: 1000px; }" |
| 266 "</style>" | 266 "</style>" |
| 267 "<div id='scroller'><div id='space'>" | 267 "<div id='scroller'><div id='space'>" |
| 268 "<div id='block1'>abc</div>" | 268 "<div id='block1'>abc</div>" |
| 269 "<div id='block2'>def</div>" | 269 "<div id='block2'>def</div>" |
| 270 "</div></div>"); | 270 "</div></div>"); |
| 271 | 271 |
| 272 ScrollableArea* scroller = | 272 ScrollableArea* scroller = |
| 273 scrollerForElement(document().getElementById("scroller")); | 273 scrollerForElement(document().getElementById("scroller")); |
| 274 Element* block1 = document().getElementById("block1"); | 274 Element* block1 = document().getElementById("block1"); |
| 275 Element* block2 = document().getElementById("block2"); | 275 Element* block2 = document().getElementById("block2"); |
| 276 | 276 |
| 277 scroller->scrollBy(DoubleSize(0, 150), UserScroll); | 277 scroller->scrollBy(ScrollOffset(0, 150), UserScroll); |
| 278 | 278 |
| 279 // In this layout pass we will anchor to #block2 which has its own PaintLayer. | 279 // In this layout pass we will anchor to #block2 which has its own PaintLayer. |
| 280 setHeight(block1, 200); | 280 setHeight(block1, 200); |
| 281 EXPECT_EQ(250, scroller->scrollPosition().y()); | 281 EXPECT_EQ(250, scroller->scrollOffsetInt().height()); |
| 282 EXPECT_EQ(block2->layoutObject(), scrollAnchor(scroller).anchorObject()); | 282 EXPECT_EQ(block2->layoutObject(), scrollAnchor(scroller).anchorObject()); |
| 283 | 283 |
| 284 // Test that the anchor object can be destroyed without affecting the scroll p
osition. | 284 // Test that the anchor object can be destroyed without affecting the scroll p
osition. |
| 285 block2->remove(); | 285 block2->remove(); |
| 286 update(); | 286 update(); |
| 287 EXPECT_EQ(250, scroller->scrollPosition().y()); | 287 EXPECT_EQ(250, scroller->scrollOffsetInt().height()); |
| 288 } | 288 } |
| 289 | 289 |
| 290 TEST_F(ScrollAnchorTest, ExcludeAnonymousCandidates) { | 290 TEST_F(ScrollAnchorTest, ExcludeAnonymousCandidates) { |
| 291 setBodyInnerHTML( | 291 setBodyInnerHTML( |
| 292 "<style>" | 292 "<style>" |
| 293 " body { height: 3500px }" | 293 " body { height: 3500px }" |
| 294 " #div {" | 294 " #div {" |
| 295 " position: relative; background-color: pink;" | 295 " position: relative; background-color: pink;" |
| 296 " top: 5px; left: 5px; width: 100px; height: 3500px;" | 296 " top: 5px; left: 5px; width: 100px; height: 3500px;" |
| 297 " }" | 297 " }" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 328 " body { height: 1000px }" | 328 " body { height: 1000px }" |
| 329 " #outer { line-height: 100px }" | 329 " #outer { line-height: 100px }" |
| 330 " #ib1, #ib2 { display: inline-block }" | 330 " #ib1, #ib2 { display: inline-block }" |
| 331 "</style>" | 331 "</style>" |
| 332 "<span id=outer>" | 332 "<span id=outer>" |
| 333 " <span id=ib1>abc</span>" | 333 " <span id=ib1>abc</span>" |
| 334 " <br><br>" | 334 " <br><br>" |
| 335 " <span id=ib2>def</span>" | 335 " <span id=ib2>def</span>" |
| 336 "</span>"); | 336 "</span>"); |
| 337 | 337 |
| 338 scrollLayoutViewport(DoubleSize(0, 150)); | 338 scrollLayoutViewport(ScrollOffset(0, 150)); |
| 339 | 339 |
| 340 Element* ib1 = document().getElementById("ib1"); | 340 Element* ib1 = document().getElementById("ib1"); |
| 341 ib1->setAttribute(HTMLNames::styleAttr, "line-height: 150px"); | 341 ib1->setAttribute(HTMLNames::styleAttr, "line-height: 150px"); |
| 342 update(); | 342 update(); |
| 343 EXPECT_EQ(document().getElementById("ib2")->layoutObject(), | 343 EXPECT_EQ(document().getElementById("ib2")->layoutObject(), |
| 344 scrollAnchor(layoutViewport()).anchorObject()); | 344 scrollAnchor(layoutViewport()).anchorObject()); |
| 345 } | 345 } |
| 346 | 346 |
| 347 TEST_F(ScrollAnchorTest, TextBounds) { | 347 TEST_F(ScrollAnchorTest, TextBounds) { |
| 348 setBodyInnerHTML( | 348 setBodyInnerHTML( |
| 349 "<style>" | 349 "<style>" |
| 350 " body {" | 350 " body {" |
| 351 " position: absolute;" | 351 " position: absolute;" |
| 352 " font-size: 100px;" | 352 " font-size: 100px;" |
| 353 " width: 200px;" | 353 " width: 200px;" |
| 354 " height: 1000px;" | 354 " height: 1000px;" |
| 355 " line-height: 100px;" | 355 " line-height: 100px;" |
| 356 " }" | 356 " }" |
| 357 "</style>" | 357 "</style>" |
| 358 "abc <b id=b>def</b> ghi" | 358 "abc <b id=b>def</b> ghi" |
| 359 "<div id=a>after</div>"); | 359 "<div id=a>after</div>"); |
| 360 | 360 |
| 361 scrollLayoutViewport(DoubleSize(0, 150)); | 361 scrollLayoutViewport(ScrollOffset(0, 150)); |
| 362 | 362 |
| 363 setHeight(document().getElementById("a"), 100); | 363 setHeight(document().getElementById("a"), 100); |
| 364 EXPECT_EQ(document().getElementById("b")->layoutObject()->slowFirstChild(), | 364 EXPECT_EQ(document().getElementById("b")->layoutObject()->slowFirstChild(), |
| 365 scrollAnchor(layoutViewport()).anchorObject()); | 365 scrollAnchor(layoutViewport()).anchorObject()); |
| 366 } | 366 } |
| 367 | 367 |
| 368 TEST_F(ScrollAnchorTest, ExcludeFixedPosition) { | 368 TEST_F(ScrollAnchorTest, ExcludeFixedPosition) { |
| 369 setBodyInnerHTML( | 369 setBodyInnerHTML( |
| 370 "<style>" | 370 "<style>" |
| 371 " body { height: 1000px; padding: 20px; }" | 371 " body { height: 1000px; padding: 20px; }" |
| 372 " div { position: relative; top: 100px; }" | 372 " div { position: relative; top: 100px; }" |
| 373 " #f { position: fixed }" | 373 " #f { position: fixed }" |
| 374 "</style>" | 374 "</style>" |
| 375 "<div id=f>fixed</div>" | 375 "<div id=f>fixed</div>" |
| 376 "<div id=c>content</div>" | 376 "<div id=c>content</div>" |
| 377 "<div id=a>after</div>"); | 377 "<div id=a>after</div>"); |
| 378 | 378 |
| 379 scrollLayoutViewport(DoubleSize(0, 50)); | 379 scrollLayoutViewport(ScrollOffset(0, 50)); |
| 380 | 380 |
| 381 setHeight(document().getElementById("a"), 100); | 381 setHeight(document().getElementById("a"), 100); |
| 382 EXPECT_EQ(document().getElementById("c")->layoutObject(), | 382 EXPECT_EQ(document().getElementById("c")->layoutObject(), |
| 383 scrollAnchor(layoutViewport()).anchorObject()); | 383 scrollAnchor(layoutViewport()).anchorObject()); |
| 384 } | 384 } |
| 385 | 385 |
| 386 // This test verifies that position:absolute elements that stick to the viewport | 386 // This test verifies that position:absolute elements that stick to the viewport |
| 387 // are not selected as anchors. | 387 // are not selected as anchors. |
| 388 TEST_F(ScrollAnchorTest, ExcludeAbsolutePositionThatSticksToViewport) { | 388 TEST_F(ScrollAnchorTest, ExcludeAbsolutePositionThatSticksToViewport) { |
| 389 setBodyInnerHTML( | 389 setBodyInnerHTML( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 404 " <div id='abs'></div>" | 404 " <div id='abs'></div>" |
| 405 " <div id='rel'></div>" | 405 " <div id='rel'></div>" |
| 406 " <div id=a>after</div>" | 406 " <div id=a>after</div>" |
| 407 "</div></div>"); | 407 "</div></div>"); |
| 408 | 408 |
| 409 Element* scrollerElement = document().getElementById("scroller"); | 409 Element* scrollerElement = document().getElementById("scroller"); |
| 410 ScrollableArea* scroller = scrollerForElement(scrollerElement); | 410 ScrollableArea* scroller = scrollerForElement(scrollerElement); |
| 411 Element* absPos = document().getElementById("abs"); | 411 Element* absPos = document().getElementById("abs"); |
| 412 Element* relPos = document().getElementById("rel"); | 412 Element* relPos = document().getElementById("rel"); |
| 413 | 413 |
| 414 scroller->scrollBy(DoubleSize(0, 25), UserScroll); | 414 scroller->scrollBy(ScrollOffset(0, 25), UserScroll); |
| 415 setHeight(document().getElementById("a"), 100); | 415 setHeight(document().getElementById("a"), 100); |
| 416 | 416 |
| 417 // When the scroller is position:static, the anchor cannot be position:absolut
e. | 417 // When the scroller is position:static, the anchor cannot be position:absolut
e. |
| 418 EXPECT_EQ(relPos->layoutObject(), scrollAnchor(scroller).anchorObject()); | 418 EXPECT_EQ(relPos->layoutObject(), scrollAnchor(scroller).anchorObject()); |
| 419 | 419 |
| 420 scrollerElement->setAttribute(HTMLNames::styleAttr, "position: relative"); | 420 scrollerElement->setAttribute(HTMLNames::styleAttr, "position: relative"); |
| 421 update(); | 421 update(); |
| 422 scroller->scrollBy(DoubleSize(0, 25), UserScroll); | 422 scroller->scrollBy(ScrollOffset(0, 25), UserScroll); |
| 423 setHeight(document().getElementById("a"), 125); | 423 setHeight(document().getElementById("a"), 125); |
| 424 | 424 |
| 425 // When the scroller is position:relative, the anchor may be position:absolute
. | 425 // When the scroller is position:relative, the anchor may be position:absolute
. |
| 426 EXPECT_EQ(absPos->layoutObject(), scrollAnchor(scroller).anchorObject()); | 426 EXPECT_EQ(absPos->layoutObject(), scrollAnchor(scroller).anchorObject()); |
| 427 } | 427 } |
| 428 | 428 |
| 429 // Test that we descend into zero-height containers that have overflowing conten
t. | 429 // Test that we descend into zero-height containers that have overflowing conten
t. |
| 430 TEST_F(ScrollAnchorTest, DescendsIntoContainerWithOverflow) { | 430 TEST_F(ScrollAnchorTest, DescendsIntoContainerWithOverflow) { |
| 431 setBodyInnerHTML( | 431 setBodyInnerHTML( |
| 432 "<style>" | 432 "<style>" |
| 433 " body { height: 1000; }" | 433 " body { height: 1000; }" |
| 434 " #outer { width: 300px; }" | 434 " #outer { width: 300px; }" |
| 435 " #zeroheight { height: 0px; }" | 435 " #zeroheight { height: 0px; }" |
| 436 " #changer { height: 100px; background-color: red; }" | 436 " #changer { height: 100px; background-color: red; }" |
| 437 " #bottom { margin-top: 600px; }" | 437 " #bottom { margin-top: 600px; }" |
| 438 "</style>" | 438 "</style>" |
| 439 "<div id='outer'>" | 439 "<div id='outer'>" |
| 440 " <div id='zeroheight'>" | 440 " <div id='zeroheight'>" |
| 441 " <div id='changer'></div>" | 441 " <div id='changer'></div>" |
| 442 " <div id='bottom'>bottom</div>" | 442 " <div id='bottom'>bottom</div>" |
| 443 " </div>" | 443 " </div>" |
| 444 "</div>"); | 444 "</div>"); |
| 445 | 445 |
| 446 ScrollableArea* viewport = layoutViewport(); | 446 ScrollableArea* viewport = layoutViewport(); |
| 447 | 447 |
| 448 scrollLayoutViewport(DoubleSize(0, 200)); | 448 scrollLayoutViewport(ScrollOffset(0, 200)); |
| 449 setHeight(document().getElementById("changer"), 200); | 449 setHeight(document().getElementById("changer"), 200); |
| 450 | 450 |
| 451 EXPECT_EQ(300, viewport->scrollPosition().y()); | 451 EXPECT_EQ(300, viewport->scrollOffsetInt().height()); |
| 452 EXPECT_EQ(document().getElementById("bottom")->layoutObject(), | 452 EXPECT_EQ(document().getElementById("bottom")->layoutObject(), |
| 453 scrollAnchor(viewport).anchorObject()); | 453 scrollAnchor(viewport).anchorObject()); |
| 454 } | 454 } |
| 455 | 455 |
| 456 // Test that we descend into zero-height containers that have floating content. | 456 // Test that we descend into zero-height containers that have floating content. |
| 457 TEST_F(ScrollAnchorTest, DescendsIntoContainerWithFloat) { | 457 TEST_F(ScrollAnchorTest, DescendsIntoContainerWithFloat) { |
| 458 setBodyInnerHTML( | 458 setBodyInnerHTML( |
| 459 "<style>" | 459 "<style>" |
| 460 " body { height: 1000; }" | 460 " body { height: 1000; }" |
| 461 " #outer { width: 300px; }" | 461 " #outer { width: 300px; }" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 475 "</div>" | 475 "</div>" |
| 476 "<div id=a>after</div>"); | 476 "<div id=a>after</div>"); |
| 477 | 477 |
| 478 EXPECT_EQ(0, | 478 EXPECT_EQ(0, |
| 479 toLayoutBox(document().getElementById("zeroheight")->layoutObject()) | 479 toLayoutBox(document().getElementById("zeroheight")->layoutObject()) |
| 480 ->size() | 480 ->size() |
| 481 .height()); | 481 .height()); |
| 482 | 482 |
| 483 ScrollableArea* viewport = layoutViewport(); | 483 ScrollableArea* viewport = layoutViewport(); |
| 484 | 484 |
| 485 scrollLayoutViewport(DoubleSize(0, 200)); | 485 scrollLayoutViewport(ScrollOffset(0, 200)); |
| 486 setHeight(document().getElementById("a"), 100); | 486 setHeight(document().getElementById("a"), 100); |
| 487 | 487 |
| 488 EXPECT_EQ(200, viewport->scrollPosition().y()); | 488 EXPECT_EQ(200, viewport->scrollOffsetInt().height()); |
| 489 EXPECT_EQ(document().getElementById("float")->layoutObject(), | 489 EXPECT_EQ(document().getElementById("float")->layoutObject(), |
| 490 scrollAnchor(viewport).anchorObject()); | 490 scrollAnchor(viewport).anchorObject()); |
| 491 } | 491 } |
| 492 | 492 |
| 493 // This test verifies that scroll anchoring is disabled when any element within | 493 // This test verifies that scroll anchoring is disabled when any element within |
| 494 // the main scroller changes its in-flow state. | 494 // the main scroller changes its in-flow state. |
| 495 TEST_F(ScrollAnchorTest, ChangeInFlowStateDisablesAnchoringForMainScroller) { | 495 TEST_F(ScrollAnchorTest, ChangeInFlowStateDisablesAnchoringForMainScroller) { |
| 496 setBodyInnerHTML( | 496 setBodyInnerHTML( |
| 497 "<style>" | 497 "<style>" |
| 498 " body { height: 1000px; }" | 498 " body { height: 1000px; }" |
| 499 " #header { background-color: #F5B335; height: 50px; width: 100%; }" | 499 " #header { background-color: #F5B335; height: 50px; width: 100%; }" |
| 500 " #content { background-color: #D3D3D3; height: 200px; }" | 500 " #content { background-color: #D3D3D3; height: 200px; }" |
| 501 "</style>" | 501 "</style>" |
| 502 "<div id='header'></div>" | 502 "<div id='header'></div>" |
| 503 "<div id='content'></div>"); | 503 "<div id='content'></div>"); |
| 504 | 504 |
| 505 ScrollableArea* viewport = layoutViewport(); | 505 ScrollableArea* viewport = layoutViewport(); |
| 506 scrollLayoutViewport(DoubleSize(0, 200)); | 506 scrollLayoutViewport(ScrollOffset(0, 200)); |
| 507 | 507 |
| 508 document().getElementById("header")->setAttribute(HTMLNames::styleAttr, | 508 document().getElementById("header")->setAttribute(HTMLNames::styleAttr, |
| 509 "position: fixed;"); | 509 "position: fixed;"); |
| 510 update(); | 510 update(); |
| 511 | 511 |
| 512 EXPECT_EQ(200, viewport->scrollPosition().y()); | 512 EXPECT_EQ(200, viewport->scrollOffsetInt().height()); |
| 513 } | 513 } |
| 514 | 514 |
| 515 // This test verifies that scroll anchoring is disabled when any element within | 515 // This test verifies that scroll anchoring is disabled when any element within |
| 516 // a scrolling div changes its in-flow state. | 516 // a scrolling div changes its in-flow state. |
| 517 TEST_F(ScrollAnchorTest, ChangeInFlowStateDisablesAnchoringForScrollingDiv) { | 517 TEST_F(ScrollAnchorTest, ChangeInFlowStateDisablesAnchoringForScrollingDiv) { |
| 518 setBodyInnerHTML( | 518 setBodyInnerHTML( |
| 519 "<style>" | 519 "<style>" |
| 520 " #container { position: relative; width: 500px; }" | 520 " #container { position: relative; width: 500px; }" |
| 521 " #scroller { height: 200px; overflow: scroll; }" | 521 " #scroller { height: 200px; overflow: scroll; }" |
| 522 " #changer { background-color: #F5B335; height: 50px; width: 100%; }" | 522 " #changer { background-color: #F5B335; height: 50px; width: 100%; }" |
| 523 " #anchor { background-color: #D3D3D3; height: 300px; }" | 523 " #anchor { background-color: #D3D3D3; height: 300px; }" |
| 524 "</style>" | 524 "</style>" |
| 525 "<div id='container'>" | 525 "<div id='container'>" |
| 526 " <div id='scroller'>" | 526 " <div id='scroller'>" |
| 527 " <div id='changer'></div>" | 527 " <div id='changer'></div>" |
| 528 " <div id='anchor'></div>" | 528 " <div id='anchor'></div>" |
| 529 " </div>" | 529 " </div>" |
| 530 "</div>"); | 530 "</div>"); |
| 531 | 531 |
| 532 ScrollableArea* scroller = | 532 ScrollableArea* scroller = |
| 533 scrollerForElement(document().getElementById("scroller")); | 533 scrollerForElement(document().getElementById("scroller")); |
| 534 document().getElementById("scroller")->setScrollTop(100); | 534 document().getElementById("scroller")->setScrollTop(100); |
| 535 | 535 |
| 536 document().getElementById("changer")->setAttribute(HTMLNames::styleAttr, | 536 document().getElementById("changer")->setAttribute(HTMLNames::styleAttr, |
| 537 "position: absolute;"); | 537 "position: absolute;"); |
| 538 update(); | 538 update(); |
| 539 | 539 |
| 540 EXPECT_EQ(100, scroller->scrollPosition().y()); | 540 EXPECT_EQ(100, scroller->scrollOffsetInt().height()); |
| 541 } | 541 } |
| 542 | 542 |
| 543 TEST_F(ScrollAnchorTest, FlexboxDelayedClampingAlsoDelaysAdjustment) { | 543 TEST_F(ScrollAnchorTest, FlexboxDelayedClampingAlsoDelaysAdjustment) { |
| 544 setBodyInnerHTML( | 544 setBodyInnerHTML( |
| 545 "<style>" | 545 "<style>" |
| 546 " html { overflow: hidden; }" | 546 " html { overflow: hidden; }" |
| 547 " body {" | 547 " body {" |
| 548 " position: absolute; display: flex;" | 548 " position: absolute; display: flex;" |
| 549 " top: 0; bottom: 0; margin: 0;" | 549 " top: 0; bottom: 0; margin: 0;" |
| 550 " }" | 550 " }" |
| 551 " #scroller { overflow: auto; }" | 551 " #scroller { overflow: auto; }" |
| 552 " #spacer { width: 600px; height: 1200px; }" | 552 " #spacer { width: 600px; height: 1200px; }" |
| 553 " #before { height: 50px; }" | 553 " #before { height: 50px; }" |
| 554 " #anchor {" | 554 " #anchor {" |
| 555 " width: 100px; height: 100px;" | 555 " width: 100px; height: 100px;" |
| 556 " background-color: #8f8;" | 556 " background-color: #8f8;" |
| 557 " }" | 557 " }" |
| 558 "</style>" | 558 "</style>" |
| 559 "<div id='scroller'>" | 559 "<div id='scroller'>" |
| 560 " <div id='spacer'>" | 560 " <div id='spacer'>" |
| 561 " <div id='before'></div>" | 561 " <div id='before'></div>" |
| 562 " <div id='anchor'></div>" | 562 " <div id='anchor'></div>" |
| 563 " </div>" | 563 " </div>" |
| 564 "</div>"); | 564 "</div>"); |
| 565 | 565 |
| 566 Element* scroller = document().getElementById("scroller"); | 566 Element* scroller = document().getElementById("scroller"); |
| 567 scroller->setScrollTop(100); | 567 scroller->setScrollTop(100); |
| 568 | 568 |
| 569 setHeight(document().getElementById("before"), 100); | 569 setHeight(document().getElementById("before"), 100); |
| 570 EXPECT_EQ(150, scrollerForElement(scroller)->scrollPosition().y()); | 570 EXPECT_EQ(150, scrollerForElement(scroller)->scrollOffsetInt().height()); |
| 571 } | 571 } |
| 572 | 572 |
| 573 TEST_F(ScrollAnchorTest, FlexboxDelayedAdjustmentRespectsSANACLAP) { | 573 TEST_F(ScrollAnchorTest, FlexboxDelayedAdjustmentRespectsSANACLAP) { |
| 574 setBodyInnerHTML( | 574 setBodyInnerHTML( |
| 575 "<style>" | 575 "<style>" |
| 576 " html { overflow: hidden; }" | 576 " html { overflow: hidden; }" |
| 577 " body {" | 577 " body {" |
| 578 " position: absolute; display: flex;" | 578 " position: absolute; display: flex;" |
| 579 " top: 0; bottom: 0; margin: 0;" | 579 " top: 0; bottom: 0; margin: 0;" |
| 580 " }" | 580 " }" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 591 " <div id='anchor'></div>" | 591 " <div id='anchor'></div>" |
| 592 " </div>" | 592 " </div>" |
| 593 "</div>"); | 593 "</div>"); |
| 594 | 594 |
| 595 Element* scroller = document().getElementById("scroller"); | 595 Element* scroller = document().getElementById("scroller"); |
| 596 scroller->setScrollTop(100); | 596 scroller->setScrollTop(100); |
| 597 | 597 |
| 598 document().getElementById("spacer")->setAttribute(HTMLNames::styleAttr, | 598 document().getElementById("spacer")->setAttribute(HTMLNames::styleAttr, |
| 599 "margin-top: 50px"); | 599 "margin-top: 50px"); |
| 600 update(); | 600 update(); |
| 601 EXPECT_EQ(100, scrollerForElement(scroller)->scrollPosition().y()); | 601 EXPECT_EQ(100, scrollerForElement(scroller)->scrollOffsetInt().height()); |
| 602 } | 602 } |
| 603 | 603 |
| 604 // Test then an element and its children are not selected as the anchor when | 604 // Test then an element and its children are not selected as the anchor when |
| 605 // it has the overflow-anchor property set to none. | 605 // it has the overflow-anchor property set to none. |
| 606 TEST_F(ScrollAnchorTest, OptOutElement) { | 606 TEST_F(ScrollAnchorTest, OptOutElement) { |
| 607 setBodyInnerHTML( | 607 setBodyInnerHTML( |
| 608 "<style>" | 608 "<style>" |
| 609 " body { height: 1000px }" | 609 " body { height: 1000px }" |
| 610 " .div {" | 610 " .div {" |
| 611 " height: 100px; width: 100px;" | 611 " height: 100px; width: 100px;" |
| 612 " border: 1px solid gray; background-color: #afa;" | 612 " border: 1px solid gray; background-color: #afa;" |
| 613 " }" | 613 " }" |
| 614 " #innerDiv {" | 614 " #innerDiv {" |
| 615 " height: 50px; width: 50px;" | 615 " height: 50px; width: 50px;" |
| 616 " border: 1px solid gray; background-color: pink;" | 616 " border: 1px solid gray; background-color: pink;" |
| 617 " }" | 617 " }" |
| 618 "</style>" | 618 "</style>" |
| 619 "<div id='changer'></div>" | 619 "<div id='changer'></div>" |
| 620 "<div class='div' id='firstDiv'><div id='innerDiv'></div></div>" | 620 "<div class='div' id='firstDiv'><div id='innerDiv'></div></div>" |
| 621 "<div class='div' id='secondDiv'></div>"); | 621 "<div class='div' id='secondDiv'></div>"); |
| 622 | 622 |
| 623 ScrollableArea* viewport = layoutViewport(); | 623 ScrollableArea* viewport = layoutViewport(); |
| 624 scrollLayoutViewport(DoubleSize(0, 50)); | 624 scrollLayoutViewport(ScrollOffset(0, 50)); |
| 625 | 625 |
| 626 // No opt-out. | 626 // No opt-out. |
| 627 setHeight(document().getElementById("changer"), 100); | 627 setHeight(document().getElementById("changer"), 100); |
| 628 EXPECT_EQ(150, viewport->scrollPosition().y()); | 628 EXPECT_EQ(150, viewport->scrollOffsetInt().height()); |
| 629 EXPECT_EQ(document().getElementById("innerDiv")->layoutObject(), | 629 EXPECT_EQ(document().getElementById("innerDiv")->layoutObject(), |
| 630 scrollAnchor(viewport).anchorObject()); | 630 scrollAnchor(viewport).anchorObject()); |
| 631 | 631 |
| 632 // Clear anchor and opt-out element. | 632 // Clear anchor and opt-out element. |
| 633 scrollLayoutViewport(DoubleSize(0, 10)); | 633 scrollLayoutViewport(ScrollOffset(0, 10)); |
| 634 document() | 634 document() |
| 635 .getElementById("firstDiv") | 635 .getElementById("firstDiv") |
| 636 ->setAttribute(HTMLNames::styleAttr, | 636 ->setAttribute(HTMLNames::styleAttr, |
| 637 AtomicString("overflow-anchor: none")); | 637 AtomicString("overflow-anchor: none")); |
| 638 update(); | 638 update(); |
| 639 | 639 |
| 640 // Opted out element and it's children skipped. | 640 // Opted out element and it's children skipped. |
| 641 setHeight(document().getElementById("changer"), 200); | 641 setHeight(document().getElementById("changer"), 200); |
| 642 EXPECT_EQ(260, viewport->scrollPosition().y()); | 642 EXPECT_EQ(260, viewport->scrollOffsetInt().height()); |
| 643 EXPECT_EQ(document().getElementById("secondDiv")->layoutObject(), | 643 EXPECT_EQ(document().getElementById("secondDiv")->layoutObject(), |
| 644 scrollAnchor(viewport).anchorObject()); | 644 scrollAnchor(viewport).anchorObject()); |
| 645 } | 645 } |
| 646 | 646 |
| 647 TEST_F(ScrollAnchorTest, | 647 TEST_F(ScrollAnchorTest, |
| 648 SuppressAnchorNodeAncestorChangingLayoutAffectingProperty) { | 648 SuppressAnchorNodeAncestorChangingLayoutAffectingProperty) { |
| 649 setBodyInnerHTML( | 649 setBodyInnerHTML( |
| 650 "<style> body { height: 1000px } div { height: 100px } </style>" | 650 "<style> body { height: 1000px } div { height: 100px } </style>" |
| 651 "<div id='block1'>abc</div>"); | 651 "<div id='block1'>abc</div>"); |
| 652 | 652 |
| 653 ScrollableArea* viewport = layoutViewport(); | 653 ScrollableArea* viewport = layoutViewport(); |
| 654 | 654 |
| 655 scrollLayoutViewport(DoubleSize(0, 50)); | 655 scrollLayoutViewport(ScrollOffset(0, 50)); |
| 656 document().body()->setAttribute(HTMLNames::styleAttr, "padding-top: 20px"); | 656 document().body()->setAttribute(HTMLNames::styleAttr, "padding-top: 20px"); |
| 657 update(); | 657 update(); |
| 658 | 658 |
| 659 EXPECT_EQ(50, viewport->scrollPosition().y()); | 659 EXPECT_EQ(50, viewport->scrollOffsetInt().height()); |
| 660 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); | 660 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); |
| 661 } | 661 } |
| 662 | 662 |
| 663 TEST_F(ScrollAnchorTest, AnchorNodeAncestorChangingNonLayoutAffectingProperty) { | 663 TEST_F(ScrollAnchorTest, AnchorNodeAncestorChangingNonLayoutAffectingProperty) { |
| 664 setBodyInnerHTML( | 664 setBodyInnerHTML( |
| 665 "<style> body { height: 1000px } div { height: 100px } </style>" | 665 "<style> body { height: 1000px } div { height: 100px } </style>" |
| 666 "<div id='block1'>abc</div>" | 666 "<div id='block1'>abc</div>" |
| 667 "<div id='block2'>def</div>"); | 667 "<div id='block2'>def</div>"); |
| 668 | 668 |
| 669 ScrollableArea* viewport = layoutViewport(); | 669 ScrollableArea* viewport = layoutViewport(); |
| 670 scrollLayoutViewport(DoubleSize(0, 150)); | 670 scrollLayoutViewport(ScrollOffset(0, 150)); |
| 671 | 671 |
| 672 document().body()->setAttribute(HTMLNames::styleAttr, "color: red"); | 672 document().body()->setAttribute(HTMLNames::styleAttr, "color: red"); |
| 673 setHeight(document().getElementById("block1"), 200); | 673 setHeight(document().getElementById("block1"), 200); |
| 674 | 674 |
| 675 EXPECT_EQ(250, viewport->scrollPosition().y()); | 675 EXPECT_EQ(250, viewport->scrollOffsetInt().height()); |
| 676 EXPECT_EQ(document().getElementById("block2")->layoutObject(), | 676 EXPECT_EQ(document().getElementById("block2")->layoutObject(), |
| 677 scrollAnchor(viewport).anchorObject()); | 677 scrollAnchor(viewport).anchorObject()); |
| 678 } | 678 } |
| 679 | 679 |
| 680 TEST_F(ScrollAnchorTest, TransformIsLayoutAffecting) { | 680 TEST_F(ScrollAnchorTest, TransformIsLayoutAffecting) { |
| 681 setBodyInnerHTML( | 681 setBodyInnerHTML( |
| 682 "<style>" | 682 "<style>" |
| 683 " body { height: 1000px }" | 683 " body { height: 1000px }" |
| 684 " #block1 { height: 100px }" | 684 " #block1 { height: 100px }" |
| 685 "</style>" | 685 "</style>" |
| 686 "<div id='block1'>abc</div>" | 686 "<div id='block1'>abc</div>" |
| 687 "<div id=a>after</div>"); | 687 "<div id=a>after</div>"); |
| 688 | 688 |
| 689 ScrollableArea* viewport = layoutViewport(); | 689 ScrollableArea* viewport = layoutViewport(); |
| 690 | 690 |
| 691 scrollLayoutViewport(DoubleSize(0, 50)); | 691 scrollLayoutViewport(ScrollOffset(0, 50)); |
| 692 document().getElementById("block1")->setAttribute( | 692 document().getElementById("block1")->setAttribute( |
| 693 HTMLNames::styleAttr, "transform: matrix(1, 0, 0, 1, 25, 25);"); | 693 HTMLNames::styleAttr, "transform: matrix(1, 0, 0, 1, 25, 25);"); |
| 694 update(); | 694 update(); |
| 695 | 695 |
| 696 document().getElementById("block1")->setAttribute( | 696 document().getElementById("block1")->setAttribute( |
| 697 HTMLNames::styleAttr, "transform: matrix(1, 0, 0, 1, 50, 50);"); | 697 HTMLNames::styleAttr, "transform: matrix(1, 0, 0, 1, 50, 50);"); |
| 698 setHeight(document().getElementById("a"), 100); | 698 setHeight(document().getElementById("a"), 100); |
| 699 update(); | 699 update(); |
| 700 | 700 |
| 701 EXPECT_EQ(50, viewport->scrollPosition().y()); | 701 EXPECT_EQ(50, viewport->scrollOffsetInt().height()); |
| 702 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); | 702 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); |
| 703 } | 703 } |
| 704 | 704 |
| 705 TEST_F(ScrollAnchorTest, OptOutBody) { | 705 TEST_F(ScrollAnchorTest, OptOutBody) { |
| 706 setBodyInnerHTML( | 706 setBodyInnerHTML( |
| 707 "<style>" | 707 "<style>" |
| 708 " body { height: 2000px; overflow-anchor: none; }" | 708 " body { height: 2000px; overflow-anchor: none; }" |
| 709 " #scroller { overflow: scroll; width: 500px; height: 300px; }" | 709 " #scroller { overflow: scroll; width: 500px; height: 300px; }" |
| 710 " .anchor {" | 710 " .anchor {" |
| 711 " position:relative; height: 100px; width: 150px;" | 711 " position:relative; height: 100px; width: 150px;" |
| 712 " background-color: #afa; border: 1px solid gray;" | 712 " background-color: #afa; border: 1px solid gray;" |
| 713 " }" | 713 " }" |
| 714 " #forceScrolling { height: 500px; background-color: #fcc; }" | 714 " #forceScrolling { height: 500px; background-color: #fcc; }" |
| 715 "</style>" | 715 "</style>" |
| 716 "<div id='outerChanger'></div>" | 716 "<div id='outerChanger'></div>" |
| 717 "<div id='outerAnchor' class='anchor'></div>" | 717 "<div id='outerAnchor' class='anchor'></div>" |
| 718 "<div id='scroller'>" | 718 "<div id='scroller'>" |
| 719 " <div id='innerChanger'></div>" | 719 " <div id='innerChanger'></div>" |
| 720 " <div id='innerAnchor' class='anchor'></div>" | 720 " <div id='innerAnchor' class='anchor'></div>" |
| 721 " <div id='forceScrolling'></div>" | 721 " <div id='forceScrolling'></div>" |
| 722 "</div>"); | 722 "</div>"); |
| 723 | 723 |
| 724 ScrollableArea* scroller = | 724 ScrollableArea* scroller = |
| 725 scrollerForElement(document().getElementById("scroller")); | 725 scrollerForElement(document().getElementById("scroller")); |
| 726 ScrollableArea* viewport = layoutViewport(); | 726 ScrollableArea* viewport = layoutViewport(); |
| 727 | 727 |
| 728 document().getElementById("scroller")->setScrollTop(100); | 728 document().getElementById("scroller")->setScrollTop(100); |
| 729 scrollLayoutViewport(DoubleSize(0, 100)); | 729 scrollLayoutViewport(ScrollOffset(0, 100)); |
| 730 | 730 |
| 731 setHeight(document().getElementById("innerChanger"), 200); | 731 setHeight(document().getElementById("innerChanger"), 200); |
| 732 setHeight(document().getElementById("outerChanger"), 150); | 732 setHeight(document().getElementById("outerChanger"), 150); |
| 733 | 733 |
| 734 // Scroll anchoring should apply within #scroller. | 734 // Scroll anchoring should apply within #scroller. |
| 735 EXPECT_EQ(300, scroller->scrollPosition().y()); | 735 EXPECT_EQ(300, scroller->scrollOffsetInt().height()); |
| 736 EXPECT_EQ(document().getElementById("innerAnchor")->layoutObject(), | 736 EXPECT_EQ(document().getElementById("innerAnchor")->layoutObject(), |
| 737 scrollAnchor(scroller).anchorObject()); | 737 scrollAnchor(scroller).anchorObject()); |
| 738 // Scroll anchoring should not apply within main frame. | 738 // Scroll anchoring should not apply within main frame. |
| 739 EXPECT_EQ(100, viewport->scrollPosition().y()); | 739 EXPECT_EQ(100, viewport->scrollOffsetInt().height()); |
| 740 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); | 740 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); |
| 741 } | 741 } |
| 742 | 742 |
| 743 TEST_F(ScrollAnchorTest, OptOutScrollingDiv) { | 743 TEST_F(ScrollAnchorTest, OptOutScrollingDiv) { |
| 744 setBodyInnerHTML( | 744 setBodyInnerHTML( |
| 745 "<style>" | 745 "<style>" |
| 746 " body { height: 2000px; }" | 746 " body { height: 2000px; }" |
| 747 " #scroller {" | 747 " #scroller {" |
| 748 " overflow: scroll; width: 500px; height: 300px;" | 748 " overflow: scroll; width: 500px; height: 300px;" |
| 749 " overflow-anchor: none;" | 749 " overflow-anchor: none;" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 760 " <div id='innerChanger'></div>" | 760 " <div id='innerChanger'></div>" |
| 761 " <div id='innerAnchor' class='anchor'></div>" | 761 " <div id='innerAnchor' class='anchor'></div>" |
| 762 " <div id='forceScrolling'></div>" | 762 " <div id='forceScrolling'></div>" |
| 763 "</div>"); | 763 "</div>"); |
| 764 | 764 |
| 765 ScrollableArea* scroller = | 765 ScrollableArea* scroller = |
| 766 scrollerForElement(document().getElementById("scroller")); | 766 scrollerForElement(document().getElementById("scroller")); |
| 767 ScrollableArea* viewport = layoutViewport(); | 767 ScrollableArea* viewport = layoutViewport(); |
| 768 | 768 |
| 769 document().getElementById("scroller")->setScrollTop(100); | 769 document().getElementById("scroller")->setScrollTop(100); |
| 770 scrollLayoutViewport(DoubleSize(0, 100)); | 770 scrollLayoutViewport(ScrollOffset(0, 100)); |
| 771 | 771 |
| 772 setHeight(document().getElementById("innerChanger"), 200); | 772 setHeight(document().getElementById("innerChanger"), 200); |
| 773 setHeight(document().getElementById("outerChanger"), 150); | 773 setHeight(document().getElementById("outerChanger"), 150); |
| 774 | 774 |
| 775 // Scroll anchoring should not apply within #scroller. | 775 // Scroll anchoring should not apply within #scroller. |
| 776 EXPECT_EQ(100, scroller->scrollPosition().y()); | 776 EXPECT_EQ(100, scroller->scrollOffsetInt().height()); |
| 777 EXPECT_EQ(nullptr, scrollAnchor(scroller).anchorObject()); | 777 EXPECT_EQ(nullptr, scrollAnchor(scroller).anchorObject()); |
| 778 // Scroll anchoring should apply within main frame. | 778 // Scroll anchoring should apply within main frame. |
| 779 EXPECT_EQ(250, viewport->scrollPosition().y()); | 779 EXPECT_EQ(250, viewport->scrollOffsetInt().height()); |
| 780 EXPECT_EQ(document().getElementById("outerAnchor")->layoutObject(), | 780 EXPECT_EQ(document().getElementById("outerAnchor")->layoutObject(), |
| 781 scrollAnchor(viewport).anchorObject()); | 781 scrollAnchor(viewport).anchorObject()); |
| 782 } | 782 } |
| 783 | 783 |
| 784 TEST_F(ScrollAnchorTest, NonDefaultRootScroller) { | 784 TEST_F(ScrollAnchorTest, NonDefaultRootScroller) { |
| 785 setBodyInnerHTML( | 785 setBodyInnerHTML( |
| 786 "<style>" | 786 "<style>" |
| 787 " ::-webkit-scrollbar {" | 787 " ::-webkit-scrollbar {" |
| 788 " width: 0px; height: 0px;" | 788 " width: 0px; height: 0px;" |
| 789 " }" | 789 " }" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 &document().view()->getRootFrameViewport()->layoutViewport()); | 821 &document().view()->getRootFrameViewport()->layoutViewport()); |
| 822 | 822 |
| 823 // The #rootScroller DIV's anchor should have the RootFrameViewport set as | 823 // The #rootScroller DIV's anchor should have the RootFrameViewport set as |
| 824 // the scroller, rather than the FrameView's anchor. | 824 // the scroller, rather than the FrameView's anchor. |
| 825 | 825 |
| 826 rootScrollerElement->setScrollTop(600); | 826 rootScrollerElement->setScrollTop(600); |
| 827 | 827 |
| 828 setHeight(document().getElementById("firstChild"), 1000); | 828 setHeight(document().getElementById("firstChild"), 1000); |
| 829 | 829 |
| 830 // Scroll anchoring should be applied to #rootScroller. | 830 // Scroll anchoring should be applied to #rootScroller. |
| 831 EXPECT_EQ(1000, scroller->scrollPosition().y()); | 831 EXPECT_EQ(1000, scroller->scrollOffset().height()); |
| 832 EXPECT_EQ(document().getElementById("target")->layoutObject(), | 832 EXPECT_EQ(document().getElementById("target")->layoutObject(), |
| 833 scrollAnchor(scroller).anchorObject()); | 833 scrollAnchor(scroller).anchorObject()); |
| 834 // Scroll anchoring should not apply within main frame. | 834 // Scroll anchoring should not apply within main frame. |
| 835 EXPECT_EQ(0, layoutViewport()->scrollPosition().y()); | 835 EXPECT_EQ(0, layoutViewport()->scrollOffset().height()); |
| 836 EXPECT_EQ(nullptr, scrollAnchor(layoutViewport()).anchorObject()); | 836 EXPECT_EQ(nullptr, scrollAnchor(layoutViewport()).anchorObject()); |
| 837 } | 837 } |
| 838 | 838 |
| 839 class ScrollAnchorCornerTest : public ScrollAnchorTest { | 839 class ScrollAnchorCornerTest : public ScrollAnchorTest { |
| 840 protected: | 840 protected: |
| 841 void checkCorner(Corner corner, | 841 void checkCorner(Corner corner, |
| 842 DoublePoint startPos, | 842 ScrollOffset startOffset, |
| 843 DoubleSize expectedAdjustment) { | 843 ScrollOffset expectedAdjustment) { |
| 844 ScrollableArea* viewport = layoutViewport(); | 844 ScrollableArea* viewport = layoutViewport(); |
| 845 Element* element = document().getElementById("changer"); | 845 Element* element = document().getElementById("changer"); |
| 846 | 846 |
| 847 viewport->setScrollPosition(startPos, UserScroll); | 847 viewport->setScrollOffset(startOffset, UserScroll); |
| 848 element->setAttribute(HTMLNames::classAttr, "change"); | 848 element->setAttribute(HTMLNames::classAttr, "change"); |
| 849 update(); | 849 update(); |
| 850 | 850 |
| 851 DoublePoint endPos = startPos; | 851 ScrollOffset endPos = startOffset; |
| 852 endPos.move(expectedAdjustment); | 852 endPos += expectedAdjustment; |
| 853 | 853 |
| 854 EXPECT_EQ(endPos, viewport->scrollPositionDouble()); | 854 EXPECT_EQ(endPos, viewport->scrollOffset()); |
| 855 EXPECT_EQ(document().getElementById("a")->layoutObject(), | 855 EXPECT_EQ(document().getElementById("a")->layoutObject(), |
| 856 scrollAnchor(viewport).anchorObject()); | 856 scrollAnchor(viewport).anchorObject()); |
| 857 EXPECT_EQ(corner, scrollAnchor(viewport).corner()); | 857 EXPECT_EQ(corner, scrollAnchor(viewport).corner()); |
| 858 | 858 |
| 859 element->removeAttribute(HTMLNames::classAttr); | 859 element->removeAttribute(HTMLNames::classAttr); |
| 860 update(); | 860 update(); |
| 861 } | 861 } |
| 862 }; | 862 }; |
| 863 | 863 |
| 864 // Verify that we anchor to the top left corner of an element for LTR. | 864 // Verify that we anchor to the top left corner of an element for LTR. |
| 865 TEST_F(ScrollAnchorCornerTest, CornersLTR) { | 865 TEST_F(ScrollAnchorCornerTest, CornersLTR) { |
| 866 setBodyInnerHTML( | 866 setBodyInnerHTML( |
| 867 "<style>" | 867 "<style>" |
| 868 " body { position: relative; width: 1220px; height: 920px; }" | 868 " body { position: relative; width: 1220px; height: 920px; }" |
| 869 " #a { width: 400px; height: 300px; }" | 869 " #a { width: 400px; height: 300px; }" |
| 870 " .change { height: 100px; }" | 870 " .change { height: 100px; }" |
| 871 "</style>" | 871 "</style>" |
| 872 "<div id='changer'></div>" | 872 "<div id='changer'></div>" |
| 873 "<div id='a'></div>"); | 873 "<div id='a'></div>"); |
| 874 | 874 |
| 875 checkCorner(Corner::TopLeft, DoublePoint(20, 20), DoubleSize(0, 100)); | 875 checkCorner(Corner::TopLeft, ScrollOffset(20, 20), ScrollOffset(0, 100)); |
| 876 } | 876 } |
| 877 | 877 |
| 878 // Verify that we anchor to the top left corner of an anchor element for | 878 // Verify that we anchor to the top left corner of an anchor element for |
| 879 // vertical-lr writing mode. | 879 // vertical-lr writing mode. |
| 880 TEST_F(ScrollAnchorCornerTest, CornersVerticalLR) { | 880 TEST_F(ScrollAnchorCornerTest, CornersVerticalLR) { |
| 881 setBodyInnerHTML( | 881 setBodyInnerHTML( |
| 882 "<style>" | 882 "<style>" |
| 883 " html { writing-mode: vertical-lr; }" | 883 " html { writing-mode: vertical-lr; }" |
| 884 " body { position: relative; width: 1220px; height: 920px; }" | 884 " body { position: relative; width: 1220px; height: 920px; }" |
| 885 " #a { width: 400px; height: 300px; }" | 885 " #a { width: 400px; height: 300px; }" |
| 886 " .change { width: 100px; }" | 886 " .change { width: 100px; }" |
| 887 "</style>" | 887 "</style>" |
| 888 "<div id='changer'></div>" | 888 "<div id='changer'></div>" |
| 889 "<div id='a'></div>"); | 889 "<div id='a'></div>"); |
| 890 | 890 |
| 891 checkCorner(Corner::TopLeft, DoublePoint(20, 20), DoubleSize(100, 0)); | 891 checkCorner(Corner::TopLeft, ScrollOffset(20, 20), ScrollOffset(100, 0)); |
| 892 } | 892 } |
| 893 | 893 |
| 894 // Verify that we anchor to the top right corner of an anchor element for RTL. | 894 // Verify that we anchor to the top right corner of an anchor element for RTL. |
| 895 TEST_F(ScrollAnchorCornerTest, CornersRTL) { | 895 TEST_F(ScrollAnchorCornerTest, CornersRTL) { |
| 896 setBodyInnerHTML( | 896 setBodyInnerHTML( |
| 897 "<style>" | 897 "<style>" |
| 898 " html { direction: rtl; }" | 898 " html { direction: rtl; }" |
| 899 " body { position: relative; width: 1220px; height: 920px; }" | 899 " body { position: relative; width: 1220px; height: 920px; }" |
| 900 " #a { width: 400px; height: 300px; }" | 900 " #a { width: 400px; height: 300px; }" |
| 901 " .change { height: 100px; }" | 901 " .change { height: 100px; }" |
| 902 "</style>" | 902 "</style>" |
| 903 "<div id='changer'></div>" | 903 "<div id='changer'></div>" |
| 904 "<div id='a'></div>"); | 904 "<div id='a'></div>"); |
| 905 | 905 |
| 906 checkCorner(Corner::TopRight, DoublePoint(-20, 20), DoubleSize(0, 100)); | 906 checkCorner(Corner::TopRight, ScrollOffset(-20, 20), ScrollOffset(0, 100)); |
| 907 } | 907 } |
| 908 | 908 |
| 909 // Verify that we anchor to the top right corner of an anchor element for | 909 // Verify that we anchor to the top right corner of an anchor element for |
| 910 // vertical-lr writing mode. | 910 // vertical-lr writing mode. |
| 911 TEST_F(ScrollAnchorCornerTest, CornersVerticalRL) { | 911 TEST_F(ScrollAnchorCornerTest, CornersVerticalRL) { |
| 912 setBodyInnerHTML( | 912 setBodyInnerHTML( |
| 913 "<style>" | 913 "<style>" |
| 914 " html { writing-mode: vertical-rl; }" | 914 " html { writing-mode: vertical-rl; }" |
| 915 " body { position: relative; width: 1220px; height: 920px; }" | 915 " body { position: relative; width: 1220px; height: 920px; }" |
| 916 " #a { width: 400px; height: 300px; }" | 916 " #a { width: 400px; height: 300px; }" |
| 917 " .change { width: 100px; }" | 917 " .change { width: 100px; }" |
| 918 "</style>" | 918 "</style>" |
| 919 "<div id='changer'></div>" | 919 "<div id='changer'></div>" |
| 920 "<div id='a'></div>"); | 920 "<div id='a'></div>"); |
| 921 | 921 |
| 922 checkCorner(Corner::TopRight, DoublePoint(-20, 20), DoubleSize(-100, 0)); | 922 checkCorner(Corner::TopRight, ScrollOffset(-20, 20), ScrollOffset(-100, 0)); |
| 923 } | 923 } |
| 924 | 924 |
| 925 TEST_F(ScrollAnchorTest, IgnoreNonBlockLayoutAxis) { | 925 TEST_F(ScrollAnchorTest, IgnoreNonBlockLayoutAxis) { |
| 926 setBodyInnerHTML( | 926 setBodyInnerHTML( |
| 927 "<style>" | 927 "<style>" |
| 928 " body {" | 928 " body {" |
| 929 " margin: 0; line-height: 0;" | 929 " margin: 0; line-height: 0;" |
| 930 " width: 1200px; height: 1200px;" | 930 " width: 1200px; height: 1200px;" |
| 931 " }" | 931 " }" |
| 932 " div {" | 932 " div {" |
| 933 " width: 100px; height: 100px;" | 933 " width: 100px; height: 100px;" |
| 934 " border: 5px solid gray;" | 934 " border: 5px solid gray;" |
| 935 " display: inline-block;" | 935 " display: inline-block;" |
| 936 " box-sizing: border-box;" | 936 " box-sizing: border-box;" |
| 937 " }" | 937 " }" |
| 938 "</style>" | 938 "</style>" |
| 939 "<div id='a'></div><br>" | 939 "<div id='a'></div><br>" |
| 940 "<div id='b'></div><div id='c'></div>"); | 940 "<div id='b'></div><div id='c'></div>"); |
| 941 | 941 |
| 942 ScrollableArea* viewport = layoutViewport(); | 942 ScrollableArea* viewport = layoutViewport(); |
| 943 scrollLayoutViewport(DoubleSize(150, 0)); | 943 scrollLayoutViewport(ScrollOffset(150, 0)); |
| 944 | 944 |
| 945 Element* a = document().getElementById("a"); | 945 Element* a = document().getElementById("a"); |
| 946 Element* b = document().getElementById("b"); | 946 Element* b = document().getElementById("b"); |
| 947 Element* c = document().getElementById("c"); | 947 Element* c = document().getElementById("c"); |
| 948 | 948 |
| 949 a->setAttribute(HTMLNames::styleAttr, "height: 150px"); | 949 a->setAttribute(HTMLNames::styleAttr, "height: 150px"); |
| 950 update(); | 950 update(); |
| 951 EXPECT_EQ(DoublePoint(150, 0), viewport->scrollPositionDouble()); | 951 EXPECT_EQ(ScrollOffset(150, 0), viewport->scrollOffset()); |
| 952 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); | 952 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); |
| 953 | 953 |
| 954 scrollLayoutViewport(DoubleSize(0, 50)); | 954 scrollLayoutViewport(ScrollOffset(0, 50)); |
| 955 | 955 |
| 956 a->setAttribute(HTMLNames::styleAttr, "height: 200px"); | 956 a->setAttribute(HTMLNames::styleAttr, "height: 200px"); |
| 957 b->setAttribute(HTMLNames::styleAttr, "width: 150px"); | 957 b->setAttribute(HTMLNames::styleAttr, "width: 150px"); |
| 958 update(); | 958 update(); |
| 959 EXPECT_EQ(DoublePoint(150, 100), viewport->scrollPositionDouble()); | 959 EXPECT_EQ(ScrollOffset(150, 100), viewport->scrollOffset()); |
| 960 EXPECT_EQ(c->layoutObject(), scrollAnchor(viewport).anchorObject()); | 960 EXPECT_EQ(c->layoutObject(), scrollAnchor(viewport).anchorObject()); |
| 961 | 961 |
| 962 a->setAttribute(HTMLNames::styleAttr, "height: 100px"); | 962 a->setAttribute(HTMLNames::styleAttr, "height: 100px"); |
| 963 b->setAttribute(HTMLNames::styleAttr, "width: 100px"); | 963 b->setAttribute(HTMLNames::styleAttr, "width: 100px"); |
| 964 document().documentElement()->setAttribute(HTMLNames::styleAttr, | 964 document().documentElement()->setAttribute(HTMLNames::styleAttr, |
| 965 "writing-mode: vertical-rl"); | 965 "writing-mode: vertical-rl"); |
| 966 document().scrollingElement()->setScrollLeft(0); | 966 document().scrollingElement()->setScrollLeft(0); |
| 967 document().scrollingElement()->setScrollTop(0); | 967 document().scrollingElement()->setScrollTop(0); |
| 968 scrollLayoutViewport(DoubleSize(0, 150)); | 968 scrollLayoutViewport(ScrollOffset(0, 150)); |
| 969 | 969 |
| 970 a->setAttribute(HTMLNames::styleAttr, "width: 150px"); | 970 a->setAttribute(HTMLNames::styleAttr, "width: 150px"); |
| 971 update(); | 971 update(); |
| 972 EXPECT_EQ(DoublePoint(0, 150), viewport->scrollPositionDouble()); | 972 EXPECT_EQ(ScrollOffset(0, 150), viewport->scrollOffset()); |
| 973 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); | 973 EXPECT_EQ(nullptr, scrollAnchor(viewport).anchorObject()); |
| 974 | 974 |
| 975 scrollLayoutViewport(DoubleSize(-50, 0)); | 975 scrollLayoutViewport(ScrollOffset(-50, 0)); |
| 976 | 976 |
| 977 a->setAttribute(HTMLNames::styleAttr, "width: 200px"); | 977 a->setAttribute(HTMLNames::styleAttr, "width: 200px"); |
| 978 b->setAttribute(HTMLNames::styleAttr, "height: 150px"); | 978 b->setAttribute(HTMLNames::styleAttr, "height: 150px"); |
| 979 update(); | 979 update(); |
| 980 EXPECT_EQ(DoublePoint(-100, 150), viewport->scrollPositionDouble()); | 980 EXPECT_EQ(ScrollOffset(-100, 150), viewport->scrollOffset()); |
| 981 EXPECT_EQ(c->layoutObject(), scrollAnchor(viewport).anchorObject()); | 981 EXPECT_EQ(c->layoutObject(), scrollAnchor(viewport).anchorObject()); |
| 982 } | 982 } |
| 983 } | 983 } |
| OLD | NEW |