OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "SnapCoordinator.h" | 5 #include "SnapCoordinator.h" |
6 | 6 |
7 #include <gtest/gtest.h> | 7 #include <gtest/gtest.h> |
8 #include <memory> | 8 #include <memory> |
9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
10 #include "core/dom/Element.h" | 10 #include "core/dom/Element.h" |
11 #include "core/frame/LocalFrameView.h" | 11 #include "core/frame/LocalFrameView.h" |
12 #include "core/html/HTMLElement.h" | 12 #include "core/html/HTMLElement.h" |
| 13 #include "core/layout/LayoutBox.h" |
13 #include "core/style/ComputedStyle.h" | 14 #include "core/style/ComputedStyle.h" |
14 #include "core/testing/DummyPageHolder.h" | 15 #include "core/testing/DummyPageHolder.h" |
15 #include "platform/scroll/ScrollTypes.h" | 16 #include "platform/scroll/ScrollTypes.h" |
16 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" | 17 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" |
17 | 18 |
18 namespace blink { | 19 namespace blink { |
19 | 20 |
20 using HTMLNames::styleAttr; | 21 using HTMLNames::styleAttr; |
21 | 22 |
22 typedef bool TestParamRootLayerScrolling; | 23 typedef bool TestParamRootLayerScrolling; |
23 class SnapCoordinatorTest | 24 class SnapCoordinatorTest |
24 : public testing::TestWithParam<TestParamRootLayerScrolling>, | 25 : public testing::TestWithParam<TestParamRootLayerScrolling>, |
25 private ScopedRootLayerScrollingForTest { | 26 private ScopedRootLayerScrollingForTest { |
26 protected: | 27 protected: |
27 SnapCoordinatorTest() : ScopedRootLayerScrollingForTest(GetParam()) {} | 28 SnapCoordinatorTest() : ScopedRootLayerScrollingForTest(GetParam()) {} |
28 | 29 |
29 void SetUp() override { | 30 void SetUp() override { |
30 page_holder_ = DummyPageHolder::Create(); | 31 page_holder_ = DummyPageHolder::Create(); |
31 | 32 |
32 SetHTML( | 33 SetHTML( |
33 "<style>" | 34 "<style>" |
34 " #snap-container {" | 35 " #snap-container {" |
35 " height: 1000px;" | 36 " height: 1000px;" |
36 " width: 1000px;" | 37 " width: 1000px;" |
37 " overflow: scroll;" | 38 " overflow: scroll;" |
38 " scroll-snap-type: mandatory;" | 39 " scroll-snap-type: both mandatory;" |
39 " }" | 40 " }" |
40 " #snap-element-fixed-position {" | 41 " #snap-element-fixed-position {" |
41 " position: fixed;" | 42 " position: fixed;" |
42 " }" | 43 " }" |
43 "</style>" | 44 "</style>" |
44 "<body>" | 45 "<body>" |
45 " <div id='snap-container'>" | 46 " <div id='snap-container'>" |
46 " <div id='snap-element'></div>" | 47 " <div id='snap-element'></div>" |
47 " <div id='intermediate'>" | 48 " <div id='intermediate'>" |
48 " <div id='nested-snap-element'></div>" | 49 " <div id='nested-snap-element'></div>" |
(...skipping 10 matching lines...) Expand all Loading... |
59 Document& GetDocument() { return page_holder_->GetDocument(); } | 60 Document& GetDocument() { return page_holder_->GetDocument(); } |
60 | 61 |
61 void SetHTML(const char* html_content) { | 62 void SetHTML(const char* html_content) { |
62 GetDocument().documentElement()->setInnerHTML(html_content); | 63 GetDocument().documentElement()->setInnerHTML(html_content); |
63 } | 64 } |
64 | 65 |
65 Element& SnapContainer() { | 66 Element& SnapContainer() { |
66 return *GetDocument().getElementById("snap-container"); | 67 return *GetDocument().getElementById("snap-container"); |
67 } | 68 } |
68 | 69 |
69 SnapCoordinator& Coordinator() { return *GetDocument().GetSnapCoordinator(); } | 70 unsigned SizeOfSnapAreas(const ContainerNode& node) { |
70 | 71 if (node.GetLayoutBox()->SnapAreas()) |
71 Vector<double> SnapOffsets(const ContainerNode& node, | 72 return node.GetLayoutBox()->SnapAreas()->size(); |
72 ScrollbarOrientation orientation) { | 73 return 0U; |
73 return Coordinator().SnapOffsets(node, orientation); | |
74 } | 74 } |
75 | 75 |
76 std::unique_ptr<DummyPageHolder> page_holder_; | 76 std::unique_ptr<DummyPageHolder> page_holder_; |
77 }; | 77 }; |
78 | 78 |
79 INSTANTIATE_TEST_CASE_P(All, SnapCoordinatorTest, ::testing::Bool()); | 79 INSTANTIATE_TEST_CASE_P(All, SnapCoordinatorTest, ::testing::Bool()); |
80 | 80 |
81 TEST_P(SnapCoordinatorTest, ValidRepeat) { | 81 TEST_P(SnapCoordinatorTest, SimpleSnapElement) { |
82 SnapContainer().setAttribute(styleAttr, | 82 Element& snap_element = *GetDocument().getElementById("snap-element"); |
83 "scroll-snap-points-x: repeat(20%); " | 83 snap_element.setAttribute(styleAttr, "scroll-snap-align: start;"); |
84 "scroll-snap-points-y: repeat(400px);"); | |
85 GetDocument().UpdateStyleAndLayout(); | |
86 { | |
87 const int expected_step_size = SnapContainer().clientWidth() * 0.2; | |
88 Vector<double> actual = SnapOffsets(SnapContainer(), kHorizontalScrollbar); | |
89 EXPECT_EQ(5U, actual.size()); | |
90 for (size_t i = 0; i < actual.size(); ++i) | |
91 EXPECT_EQ((i + 1) * expected_step_size, actual[i]); | |
92 } | |
93 { | |
94 Vector<double> actual = SnapOffsets(SnapContainer(), kVerticalScrollbar); | |
95 EXPECT_EQ(2U, actual.size()); | |
96 EXPECT_EQ(400, actual[0]); | |
97 EXPECT_EQ(800, actual[1]); | |
98 } | |
99 } | |
100 | |
101 TEST_P(SnapCoordinatorTest, EmptyRepeat) { | |
102 SnapContainer().setAttribute( | |
103 styleAttr, "scroll-snap-points-x: none; scroll-snap-points-y: none;"); | |
104 GetDocument().UpdateStyleAndLayout(); | 84 GetDocument().UpdateStyleAndLayout(); |
105 | 85 |
106 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kHorizontalScrollbar).size()); | 86 EXPECT_EQ(1U, SizeOfSnapAreas(SnapContainer())); |
107 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kVerticalScrollbar).size()); | |
108 } | |
109 | |
110 TEST_P(SnapCoordinatorTest, ZeroAndNegativeRepeat) { | |
111 // These be rejected as an invalid repeat values thus no snap offset is | |
112 // created. | |
113 SnapContainer().setAttribute( | |
114 styleAttr, | |
115 "scroll-snap-points-x: repeat(-1px); scroll-snap-points-y: repeat(0px);"); | |
116 GetDocument().UpdateStyleAndLayout(); | |
117 | |
118 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kHorizontalScrollbar).size()); | |
119 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kVerticalScrollbar).size()); | |
120 | |
121 // Calc values are not be rejected outright but instead clamped to 1px min | |
122 // repeat value. | |
123 SnapContainer().setAttribute(styleAttr, | |
124 "scroll-snap-points-x: repeat(calc(10px - " | |
125 "100%)); scroll-snap-points-y: " | |
126 "repeat(calc(0px));"); | |
127 GetDocument().UpdateStyleAndLayout(); | |
128 | |
129 // A repeat value of 1px should give us |(scroll size - client size) / 1| snap | |
130 // offsets. | |
131 unsigned expected_horizontal_snap_offsets = | |
132 SnapContainer().scrollWidth() - SnapContainer().clientWidth(); | |
133 EXPECT_EQ(expected_horizontal_snap_offsets, | |
134 SnapOffsets(SnapContainer(), kHorizontalScrollbar).size()); | |
135 unsigned expected_vertical_snap_offsets = | |
136 SnapContainer().scrollHeight() - SnapContainer().clientHeight(); | |
137 EXPECT_EQ(expected_vertical_snap_offsets, | |
138 SnapOffsets(SnapContainer(), kVerticalScrollbar).size()); | |
139 } | |
140 | |
141 TEST_P(SnapCoordinatorTest, SimpleSnapElement) { | |
142 Element& snap_element = *GetDocument().getElementById("snap-element"); | |
143 snap_element.setAttribute(styleAttr, "scroll-snap-coordinate: 10px 11px;"); | |
144 GetDocument().UpdateStyleAndLayout(); | |
145 | |
146 EXPECT_EQ(10, SnapOffsets(SnapContainer(), kHorizontalScrollbar)[0]); | |
147 EXPECT_EQ(11, SnapOffsets(SnapContainer(), kVerticalScrollbar)[0]); | |
148 | |
149 // Multiple coordinate and translates | |
150 snap_element.setAttribute(styleAttr, | |
151 "scroll-snap-coordinate: 20px 21px, 40px 41px; " | |
152 "transform: translate(10px, 10px);"); | |
153 GetDocument().UpdateStyleAndLayout(); | |
154 | |
155 Vector<double> result = SnapOffsets(SnapContainer(), kHorizontalScrollbar); | |
156 EXPECT_EQ(30, result[0]); | |
157 EXPECT_EQ(50, result[1]); | |
158 result = SnapOffsets(SnapContainer(), kVerticalScrollbar); | |
159 EXPECT_EQ(31, result[0]); | |
160 EXPECT_EQ(51, result[1]); | |
161 } | 87 } |
162 | 88 |
163 TEST_P(SnapCoordinatorTest, NestedSnapElement) { | 89 TEST_P(SnapCoordinatorTest, NestedSnapElement) { |
164 Element& snap_element = *GetDocument().getElementById("nested-snap-element"); | 90 Element& snap_element = *GetDocument().getElementById("nested-snap-element"); |
165 snap_element.setAttribute(styleAttr, "scroll-snap-coordinate: 20px 25px;"); | 91 snap_element.setAttribute(styleAttr, "scroll-snap-align: start;"); |
166 GetDocument().UpdateStyleAndLayout(); | 92 GetDocument().UpdateStyleAndLayout(); |
167 | 93 |
168 EXPECT_EQ(20, SnapOffsets(SnapContainer(), kHorizontalScrollbar)[0]); | 94 EXPECT_EQ(1U, SizeOfSnapAreas(SnapContainer())); |
169 EXPECT_EQ(25, SnapOffsets(SnapContainer(), kVerticalScrollbar)[0]); | |
170 } | 95 } |
171 | 96 |
172 TEST_P(SnapCoordinatorTest, NestedSnapElementCaptured) { | 97 TEST_P(SnapCoordinatorTest, NestedSnapElementCaptured) { |
173 Element& snap_element = *GetDocument().getElementById("nested-snap-element"); | 98 Element& snap_element = *GetDocument().getElementById("nested-snap-element"); |
174 snap_element.setAttribute(styleAttr, "scroll-snap-coordinate: 20px 25px;"); | 99 snap_element.setAttribute(styleAttr, "scroll-snap-align: start;"); |
175 | 100 |
176 Element* intermediate = GetDocument().getElementById("intermediate"); | 101 Element* intermediate = GetDocument().getElementById("intermediate"); |
177 intermediate->setAttribute(styleAttr, "overflow: scroll;"); | 102 intermediate->setAttribute(styleAttr, "overflow: scroll;"); |
178 | 103 |
179 GetDocument().UpdateStyleAndLayout(); | 104 GetDocument().UpdateStyleAndLayout(); |
180 | 105 |
181 // Intermediate scroller captures nested snap elements first so ancestor | 106 // Intermediate scroller captures nested snap elements first so ancestor |
182 // does not get them. | 107 // does not get them. |
183 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kHorizontalScrollbar).size()); | 108 EXPECT_EQ(0U, SizeOfSnapAreas(SnapContainer())); |
184 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kVerticalScrollbar).size()); | 109 EXPECT_EQ(1U, SizeOfSnapAreas(*intermediate)); |
185 } | 110 } |
186 | 111 |
187 TEST_P(SnapCoordinatorTest, PositionFixedSnapElement) { | 112 TEST_P(SnapCoordinatorTest, PositionFixedSnapElement) { |
188 Element& snap_element = | 113 Element& snap_element = |
189 *GetDocument().getElementById("snap-element-fixed-position"); | 114 *GetDocument().getElementById("snap-element-fixed-position"); |
190 snap_element.setAttribute(styleAttr, "scroll-snap-coordinate: 1px 1px;"); | 115 snap_element.setAttribute(styleAttr, "scroll-snap-align: start;"); |
191 GetDocument().UpdateStyleAndLayout(); | 116 GetDocument().UpdateStyleAndLayout(); |
192 | 117 |
193 // Position fixed elements are contained in document and not its immediate | 118 // Position fixed elements are contained in document and not its immediate |
194 // ancestor scroller. They cannot be a valid snap destination so they should | 119 // ancestor scroller. They cannot be a valid snap destination so they should |
195 // not contribute snap points to their immediate snap container or document | 120 // not contribute snap points to their immediate snap container or document |
196 // See: https://lists.w3.org/Archives/Public/www-style/2015Jun/0376.html | 121 // See: https://lists.w3.org/Archives/Public/www-style/2015Jun/0376.html |
197 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kHorizontalScrollbar).size()); | 122 EXPECT_EQ(0U, SizeOfSnapAreas(SnapContainer())); |
198 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kVerticalScrollbar).size()); | |
199 | 123 |
200 Element* body = GetDocument().ViewportDefiningElement(); | 124 Element* body = GetDocument().ViewportDefiningElement(); |
201 EXPECT_EQ(0U, SnapOffsets(*body, kHorizontalScrollbar).size()); | 125 EXPECT_EQ(0U, SizeOfSnapAreas(*body)); |
202 EXPECT_EQ(0U, SnapOffsets(*body, kVerticalScrollbar).size()); | |
203 } | |
204 | |
205 TEST_P(SnapCoordinatorTest, RepeatAndSnapElementTogether) { | |
206 GetDocument() | |
207 .getElementById("snap-element") | |
208 ->setAttribute(styleAttr, "scroll-snap-coordinate: 5px 10px;"); | |
209 GetDocument() | |
210 .getElementById("nested-snap-element") | |
211 ->setAttribute(styleAttr, "scroll-snap-coordinate: 250px 450px;"); | |
212 | |
213 SnapContainer().setAttribute(styleAttr, | |
214 "scroll-snap-points-x: repeat(200px); " | |
215 "scroll-snap-points-y: repeat(400px);"); | |
216 GetDocument().UpdateStyleAndLayout(); | |
217 | |
218 { | |
219 Vector<double> result = SnapOffsets(SnapContainer(), kHorizontalScrollbar); | |
220 EXPECT_EQ(7U, result.size()); | |
221 EXPECT_EQ(5, result[0]); | |
222 EXPECT_EQ(200, result[1]); | |
223 EXPECT_EQ(250, result[2]); | |
224 } | |
225 { | |
226 Vector<double> result = SnapOffsets(SnapContainer(), kVerticalScrollbar); | |
227 EXPECT_EQ(4U, result.size()); | |
228 EXPECT_EQ(10, result[0]); | |
229 EXPECT_EQ(400, result[1]); | |
230 EXPECT_EQ(450, result[2]); | |
231 } | |
232 } | |
233 | |
234 TEST_P(SnapCoordinatorTest, SnapPointsAreScrollOffsetIndependent) { | |
235 Element& snap_element = *GetDocument().getElementById("snap-element"); | |
236 snap_element.setAttribute(styleAttr, "scroll-snap-coordinate: 10px 11px;"); | |
237 SnapContainer().scrollBy(100, 100); | |
238 GetDocument().UpdateStyleAndLayout(); | |
239 | |
240 EXPECT_EQ(SnapContainer().scrollLeft(), 100); | |
241 EXPECT_EQ(SnapContainer().scrollTop(), 100); | |
242 EXPECT_EQ(10, SnapOffsets(SnapContainer(), kHorizontalScrollbar)[0]); | |
243 EXPECT_EQ(11, SnapOffsets(SnapContainer(), kVerticalScrollbar)[0]); | |
244 } | 126 } |
245 | 127 |
246 TEST_P(SnapCoordinatorTest, UpdateStyleForSnapElement) { | 128 TEST_P(SnapCoordinatorTest, UpdateStyleForSnapElement) { |
247 Element& snap_element = *GetDocument().getElementById("snap-element"); | 129 Element& snap_element = *GetDocument().getElementById("snap-element"); |
248 snap_element.setAttribute(styleAttr, "scroll-snap-coordinate: 10px 11px;"); | 130 snap_element.setAttribute(styleAttr, "scroll-snap-align: start;"); |
249 GetDocument().UpdateStyleAndLayout(); | 131 GetDocument().UpdateStyleAndLayout(); |
250 | 132 |
251 EXPECT_EQ(10, SnapOffsets(SnapContainer(), kHorizontalScrollbar)[0]); | 133 EXPECT_EQ(1U, SizeOfSnapAreas(SnapContainer())); |
252 EXPECT_EQ(11, SnapOffsets(SnapContainer(), kVerticalScrollbar)[0]); | |
253 | 134 |
254 snap_element.remove(); | 135 snap_element.remove(); |
255 GetDocument().UpdateStyleAndLayout(); | 136 GetDocument().UpdateStyleAndLayout(); |
256 | 137 |
257 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kHorizontalScrollbar).size()); | 138 EXPECT_EQ(0U, SizeOfSnapAreas(SnapContainer())); |
258 EXPECT_EQ(0U, SnapOffsets(SnapContainer(), kVerticalScrollbar).size()); | |
259 | 139 |
260 // Add a new snap element | 140 // Add a new snap element |
261 Element& container = *GetDocument().getElementById("snap-container"); | 141 Element& container = *GetDocument().getElementById("snap-container"); |
262 container.setInnerHTML( | 142 container.setInnerHTML( |
263 "<div style='scroll-snap-coordinate: 20px 22px;'><div " | 143 "<div style='scroll-snap-align: start;'>" |
264 "style='width:2000px; height:2000px;'></div></div>"); | 144 " <div style='width:2000px; height:2000px;'></div>" |
| 145 "</div>"); |
265 GetDocument().UpdateStyleAndLayout(); | 146 GetDocument().UpdateStyleAndLayout(); |
266 | 147 |
267 EXPECT_EQ(20, SnapOffsets(SnapContainer(), kHorizontalScrollbar)[0]); | 148 EXPECT_EQ(1U, SizeOfSnapAreas(SnapContainer())); |
268 EXPECT_EQ(22, SnapOffsets(SnapContainer(), kVerticalScrollbar)[0]); | |
269 } | 149 } |
270 | 150 |
271 TEST_P(SnapCoordinatorTest, LayoutViewCapturesWhenBodyElementViewportDefining) { | 151 TEST_P(SnapCoordinatorTest, LayoutViewCapturesWhenBodyElementViewportDefining) { |
272 SetHTML( | 152 SetHTML( |
273 "<style>" | 153 "<style>" |
274 "body {" | 154 "body {" |
275 " overflow: scroll;" | 155 " overflow: scroll;" |
276 " scroll-snap-type: mandatory;" | 156 " scroll-snap-type: both mandatory;" |
277 " height: 1000px;" | 157 " height: 1000px;" |
278 " width: 1000px;" | 158 " width: 1000px;" |
279 " margin: 5px;" | 159 " margin: 5px;" |
280 "}" | 160 "}" |
281 "</style>" | 161 "</style>" |
282 "<body>" | 162 "<body>" |
283 " <div id='snap-element' style='scroll-snap-coordinate: 5px " | 163 " <div id='snap-element' style='scroll-snap-align: start;></div>" |
284 "6px;'></div>" | 164 " <div id='intermediate'>" |
285 " <div>" | 165 " <div id='nested-snap-element'" |
286 " <div id='nested-snap-element' style='scroll-snap-coordinate: " | 166 " style='scroll-snap-align: start;'></div>" |
287 "10px 11px;'></div>" | |
288 " </div>" | 167 " </div>" |
289 " <div style='width:2000px; height:2000px;'></div>" | 168 " <div style='width:2000px; height:2000px;'></div>" |
290 "</body>"); | 169 "</body>"); |
291 | 170 |
292 GetDocument().UpdateStyleAndLayout(); | 171 GetDocument().UpdateStyleAndLayout(); |
293 | 172 |
294 // Sanity check that body is the viewport defining element | 173 // Sanity check that body is the viewport defining element |
295 EXPECT_EQ(GetDocument().body(), GetDocument().ViewportDefiningElement()); | 174 EXPECT_EQ(GetDocument().body(), GetDocument().ViewportDefiningElement()); |
296 | 175 |
297 // When body is viewport defining and overflows then any snap points on the | 176 // When body is viewport defining and overflows then any snap points on the |
298 // body element will be captured by layout view as the snap container. | 177 // body element will be captured by layout view as the snap container. |
299 Vector<double> result = SnapOffsets(GetDocument(), kHorizontalScrollbar); | 178 EXPECT_EQ(2U, SizeOfSnapAreas(GetDocument())); |
300 EXPECT_EQ(10, result[0]); | 179 EXPECT_EQ(0U, SizeOfSnapAreas(*(GetDocument().body()))); |
301 EXPECT_EQ(15, result[1]); | 180 EXPECT_EQ(0U, SizeOfSnapAreas(*(GetDocument().documentElement()))); |
302 result = SnapOffsets(GetDocument(), kVerticalScrollbar); | |
303 EXPECT_EQ(11, result[0]); | |
304 EXPECT_EQ(16, result[1]); | |
305 } | 181 } |
306 | 182 |
307 TEST_P(SnapCoordinatorTest, | 183 TEST_P(SnapCoordinatorTest, |
308 LayoutViewCapturesWhenDocumentElementViewportDefining) { | 184 LayoutViewCapturesWhenDocumentElementViewportDefining) { |
309 SetHTML( | 185 SetHTML( |
310 "<style>" | 186 "<style>" |
311 ":root {" | 187 ":root {" |
312 " overflow: scroll;" | 188 " overflow: scroll;" |
313 " scroll-snap-type: mandatory;" | 189 " scroll-snap-type: both mandatory;" |
314 " height: 500px;" | 190 " height: 500px;" |
315 " width: 500px;" | 191 " width: 500px;" |
316 "}" | 192 "}" |
317 "body {" | 193 "body {" |
318 " margin: 5px;" | 194 " margin: 5px;" |
319 "}" | 195 "}" |
320 "</style>" | 196 "</style>" |
321 "<html>" | 197 "<html>" |
322 " <body>" | 198 " <body>" |
323 " <div id='snap-element' style='scroll-snap-coordinate: 5px " | 199 " <div id='snap-element' style='scroll-snap-align: start;></div>" |
324 "6px;'></div>" | 200 " <div id='intermediate'>" |
325 " <div>" | 201 " <div id='nested-snap-element'" |
326 " <div id='nested-snap-element' style='scroll-snap-coordinate: " | 202 " style='scroll-snap-align: start;'></div>" |
327 "10px 11px;'></div>" | |
328 " </div>" | 203 " </div>" |
329 " <div style='width:2000px; height:2000px;'></div>" | 204 " <div style='width:2000px; height:2000px;'></div>" |
330 " </body>" | 205 " </body>" |
331 "</html>"); | 206 "</html>"); |
332 | 207 |
333 GetDocument().UpdateStyleAndLayout(); | 208 GetDocument().UpdateStyleAndLayout(); |
334 | 209 |
335 // Sanity check that document element is the viewport defining element | 210 // Sanity check that document element is the viewport defining element |
336 EXPECT_EQ(GetDocument().documentElement(), | 211 EXPECT_EQ(GetDocument().documentElement(), |
337 GetDocument().ViewportDefiningElement()); | 212 GetDocument().ViewportDefiningElement()); |
338 | 213 |
339 // When body is viewport defining and overflows then any snap points on the | 214 // When body is viewport defining and overflows then any snap points on the |
340 // the document element will be captured by layout view as the snap | 215 // the document element will be captured by layout view as the snap |
341 // container. | 216 // container. |
342 Vector<double> result = SnapOffsets(GetDocument(), kHorizontalScrollbar); | 217 EXPECT_EQ(2U, SizeOfSnapAreas(GetDocument())); |
343 EXPECT_EQ(10, result[0]); | 218 EXPECT_EQ(0U, SizeOfSnapAreas(*(GetDocument().body()))); |
344 EXPECT_EQ(15, result[1]); | 219 EXPECT_EQ(0U, SizeOfSnapAreas(*(GetDocument().documentElement()))); |
345 result = SnapOffsets(GetDocument(), kVerticalScrollbar); | |
346 EXPECT_EQ(11, result[0]); | |
347 EXPECT_EQ(16, result[1]); | |
348 } | 220 } |
349 | 221 |
350 TEST_P(SnapCoordinatorTest, | 222 TEST_P(SnapCoordinatorTest, |
351 BodyCapturesWhenBodyOverflowAndDocumentElementViewportDefining) { | 223 BodyCapturesWhenBodyOverflowAndDocumentElementViewportDefining) { |
352 SetHTML( | 224 SetHTML( |
353 "<style>" | 225 "<style>" |
354 ":root {" | 226 ":root {" |
355 " overflow: scroll;" | 227 " overflow: scroll;" |
356 " scroll-snap-type: mandatory;" | 228 " scroll-snap-type: both mandatory;" |
357 " height: 500px;" | 229 " height: 500px;" |
358 " width: 500px;" | 230 " width: 500px;" |
359 "}" | 231 "}" |
360 "body {" | 232 "body {" |
361 " overflow: scroll;" | 233 " overflow: scroll;" |
362 " scroll-snap-type: mandatory;" | 234 " scroll-snap-type: both mandatory;" |
363 " height: 1000px;" | 235 " height: 1000px;" |
364 " width: 1000px;" | 236 " width: 1000px;" |
365 " margin: 5px;" | 237 " margin: 5px;" |
366 "}" | 238 "}" |
367 "</style>" | 239 "</style>" |
368 "<html>" | 240 "<html>" |
369 " <body style='overflow: scroll; scroll-snap-type: mandatory; " | 241 " <body style='overflow: scroll; scroll-snap-type: both mandatory; " |
370 "height:1000px; width:1000px;'>" | 242 "height:1000px; width:1000px;'>" |
371 " <div id='snap-element' style='scroll-snap-coordinate: 5px " | 243 " <div id='snap-element' style='scroll-snap-align: start;></div>" |
372 "6px;'></div>" | 244 " <div id='intermediate'>" |
373 " <div>" | 245 " <div id='nested-snap-element'" |
374 " <div id='nested-snap-element' style='scroll-snap-coordinate: " | 246 " style='scroll-snap-align: start;'></div>" |
375 "10px 11px;'></div>" | |
376 " </div>" | 247 " </div>" |
377 " <div style='width:2000px; height:2000px;'></div>" | 248 " <div style='width:2000px; height:2000px;'></div>" |
378 " </body>" | 249 " </body>" |
379 "</html>"); | 250 "</html>"); |
380 | 251 |
381 GetDocument().UpdateStyleAndLayout(); | 252 GetDocument().UpdateStyleAndLayout(); |
382 | 253 |
383 // Sanity check that document element is the viewport defining element | 254 // Sanity check that document element is the viewport defining element |
384 EXPECT_EQ(GetDocument().documentElement(), | 255 EXPECT_EQ(GetDocument().documentElement(), |
385 GetDocument().ViewportDefiningElement()); | 256 GetDocument().ViewportDefiningElement()); |
386 | 257 |
387 // When body and document elements are both scrollable then body element | 258 // When body and document elements are both scrollable then body element |
388 // should capture snap points defined on it as opposed to layout view. | 259 // should capture snap points defined on it as opposed to layout view. |
389 Element& body = *GetDocument().body(); | 260 Element& body = *GetDocument().body(); |
390 Vector<double> result = SnapOffsets(body, kHorizontalScrollbar); | 261 EXPECT_EQ(2U, SizeOfSnapAreas(body)); |
391 EXPECT_EQ(5, result[0]); | |
392 EXPECT_EQ(10, result[1]); | |
393 result = SnapOffsets(body, kVerticalScrollbar); | |
394 EXPECT_EQ(6, result[0]); | |
395 EXPECT_EQ(11, result[1]); | |
396 } | 262 } |
397 | 263 |
398 } // namespace | 264 } // namespace |
OLD | NEW |