OLD | NEW |
| (Empty) |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "bindings/core/v8/ScrollIntoViewOptionsOrBoolean.h" | |
6 #include "core/frame/ScrollIntoViewOptions.h" | |
7 #include "core/frame/ScrollToOptions.h" | |
8 #include "public/web/WebScriptSource.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 #include "web/WebLocalFrameImpl.h" | |
11 #include "web/tests/sim/SimCompositor.h" | |
12 #include "web/tests/sim/SimDisplayItemList.h" | |
13 #include "web/tests/sim/SimRequest.h" | |
14 #include "web/tests/sim/SimTest.h" | |
15 | |
16 namespace blink { | |
17 | |
18 namespace { | |
19 | |
20 class SmoothScrollTest : public SimTest {}; | |
21 | |
22 TEST_F(SmoothScrollTest, InstantScroll) { | |
23 v8::HandleScope HandleScope(v8::Isolate::GetCurrent()); | |
24 WebView().Resize(WebSize(800, 600)); | |
25 SimRequest request("https://example.com/test.html", "text/html"); | |
26 LoadURL("https://example.com/test.html"); | |
27 request.Complete( | |
28 "<div id='space' style='height: 1000px'></div>" | |
29 "<div id='content' style='height: 1000px'></div>"); | |
30 | |
31 Compositor().BeginFrame(); | |
32 ASSERT_EQ(Window().scrollY(), 0); | |
33 Element* content = GetDocument().getElementById("content"); | |
34 ScrollIntoViewOptionsOrBoolean arg; | |
35 ScrollIntoViewOptions options; | |
36 options.setBlock("start"); | |
37 arg.setScrollIntoViewOptions(options); | |
38 content->scrollIntoView(arg); | |
39 | |
40 ASSERT_EQ(Window().scrollY(), content->OffsetTop()); | |
41 } | |
42 | |
43 TEST_F(SmoothScrollTest, SmoothScroll) { | |
44 v8::HandleScope HandleScope(v8::Isolate::GetCurrent()); | |
45 WebView().Resize(WebSize(800, 600)); | |
46 SimRequest request("https://example.com/test.html", "text/html"); | |
47 LoadURL("https://example.com/test.html"); | |
48 request.Complete( | |
49 "<div id='space' style='height: 1000px'></div>" | |
50 "<div id='content' style='height: 1000px'></div>"); | |
51 | |
52 Element* content = GetDocument().getElementById("content"); | |
53 ScrollIntoViewOptionsOrBoolean arg; | |
54 ScrollIntoViewOptions options; | |
55 options.setBlock("start"); | |
56 options.setBehavior("smooth"); | |
57 arg.setScrollIntoViewOptions(options); | |
58 Compositor().BeginFrame(); | |
59 ASSERT_EQ(Window().scrollY(), 0); | |
60 | |
61 content->scrollIntoView(arg); | |
62 // Scrolling the container | |
63 Compositor().BeginFrame(); // update run_state_. | |
64 Compositor().BeginFrame(); // Set start_time = now. | |
65 Compositor().BeginFrame(0.2); | |
66 ASSERT_EQ(Window().scrollY(), 299); | |
67 | |
68 // Finish scrolling the container | |
69 Compositor().BeginFrame(1); | |
70 ASSERT_EQ(Window().scrollY(), content->OffsetTop()); | |
71 } | |
72 | |
73 TEST_F(SmoothScrollTest, NestedContainer) { | |
74 v8::HandleScope HandleScope(v8::Isolate::GetCurrent()); | |
75 WebView().Resize(WebSize(800, 600)); | |
76 SimRequest request("https://example.com/test.html", "text/html"); | |
77 LoadURL("https://example.com/test.html"); | |
78 request.Complete( | |
79 "<div id='space' style='height: 1000px'></div>" | |
80 "<div id='container' style='height: 600px; overflow: scroll'>" | |
81 " <div id='space1' style='height: 1000px'></div>" | |
82 " <div id='content' style='height: 1000px'></div>" | |
83 "</div>"); | |
84 | |
85 Element* container = GetDocument().getElementById("container"); | |
86 Element* content = GetDocument().getElementById("content"); | |
87 ScrollIntoViewOptionsOrBoolean arg; | |
88 ScrollIntoViewOptions options; | |
89 options.setBlock("start"); | |
90 options.setBehavior("smooth"); | |
91 arg.setScrollIntoViewOptions(options); | |
92 Compositor().BeginFrame(); | |
93 ASSERT_EQ(Window().scrollY(), 0); | |
94 ASSERT_EQ(container->scrollTop(), 0); | |
95 | |
96 content->scrollIntoView(arg); | |
97 // Scrolling the outer container | |
98 Compositor().BeginFrame(); // update run_state_. | |
99 Compositor().BeginFrame(); // Set start_time = now. | |
100 Compositor().BeginFrame(0.2); | |
101 ASSERT_EQ(Window().scrollY(), 299); | |
102 ASSERT_EQ(container->scrollTop(), 0); | |
103 | |
104 // Finish scrolling the outer container | |
105 Compositor().BeginFrame(1); | |
106 ASSERT_EQ(Window().scrollY(), container->OffsetTop()); | |
107 ASSERT_EQ(container->scrollTop(), 0); | |
108 | |
109 // Scrolling the inner container | |
110 Compositor().BeginFrame(); // Set start_time = now. | |
111 Compositor().BeginFrame(0.2); | |
112 ASSERT_EQ(container->scrollTop(), 299); | |
113 | |
114 // Finish scrolling the inner container | |
115 Compositor().BeginFrame(1); | |
116 ASSERT_EQ(container->scrollTop(), | |
117 content->OffsetTop() - container->OffsetTop()); | |
118 } | |
119 | |
120 TEST_F(SmoothScrollTest, NewScrollIntoViewAbortsCurrentAnimation) { | |
121 v8::HandleScope HandleScope(v8::Isolate::GetCurrent()); | |
122 WebView().Resize(WebSize(800, 600)); | |
123 SimRequest request("https://example.com/test.html", "text/html"); | |
124 LoadURL("https://example.com/test.html"); | |
125 request.Complete( | |
126 "<div id='container2' style='height: 1000px; overflow: scroll'>" | |
127 " <div id='space2' style='height: 1200px'></div>" | |
128 " <div id='content2' style='height: 1000px'></div>" | |
129 "</div>" | |
130 "<div id='container1' style='height: 600px; overflow: scroll'>" | |
131 " <div id='space1' style='height: 1000px'></div>" | |
132 " <div id='content1' style='height: 1000px'></div>" | |
133 "</div>"); | |
134 | |
135 Element* container1 = GetDocument().getElementById("container1"); | |
136 Element* container2 = GetDocument().getElementById("container2"); | |
137 Element* content1 = GetDocument().getElementById("content1"); | |
138 Element* content2 = GetDocument().getElementById("content2"); | |
139 ScrollIntoViewOptionsOrBoolean arg; | |
140 ScrollIntoViewOptions options; | |
141 options.setBlock("start"); | |
142 options.setBehavior("smooth"); | |
143 arg.setScrollIntoViewOptions(options); | |
144 | |
145 Compositor().BeginFrame(); | |
146 ASSERT_EQ(Window().scrollY(), 0); | |
147 ASSERT_EQ(container1->scrollTop(), 0); | |
148 ASSERT_EQ(container2->scrollTop(), 0); | |
149 | |
150 content1->scrollIntoView(arg); | |
151 Compositor().BeginFrame(); // update run_state_. | |
152 Compositor().BeginFrame(); // Set start_time = now. | |
153 Compositor().BeginFrame(0.2); | |
154 ASSERT_EQ(Window().scrollY(), 299); | |
155 ASSERT_EQ(container1->scrollTop(), 0); | |
156 | |
157 content2->scrollIntoView(arg); | |
158 Compositor().BeginFrame(); // update run_state_. | |
159 Compositor().BeginFrame(); // Set start_time = now. | |
160 Compositor().BeginFrame(0.2); | |
161 ASSERT_EQ(Window().scrollY(), 61); | |
162 ASSERT_EQ(container1->scrollTop(), 0); // container1 should not scroll. | |
163 | |
164 Compositor().BeginFrame(1); | |
165 ASSERT_EQ(Window().scrollY(), container2->OffsetTop()); | |
166 ASSERT_EQ(container2->scrollTop(), 0); | |
167 | |
168 // Scrolling content2 in container2 | |
169 Compositor().BeginFrame(); // Set start_time = now. | |
170 Compositor().BeginFrame(0.2); | |
171 ASSERT_EQ(container2->scrollTop(), 300); | |
172 | |
173 // Finish all the animation to make sure there is no another animation queued | |
174 // on container1. | |
175 while (Compositor().NeedsBeginFrame()) { | |
176 Compositor().BeginFrame(); | |
177 } | |
178 ASSERT_EQ(Window().scrollY(), container2->OffsetTop()); | |
179 ASSERT_EQ(container2->scrollTop(), | |
180 content2->OffsetTop() - container2->OffsetTop()); | |
181 ASSERT_EQ(container1->scrollTop(), 0); | |
182 } | |
183 | |
184 TEST_F(SmoothScrollTest, ScrollWindowAbortsCurrentAnimation) { | |
185 v8::HandleScope HandleScope(v8::Isolate::GetCurrent()); | |
186 WebView().Resize(WebSize(800, 600)); | |
187 SimRequest request("https://example.com/test.html", "text/html"); | |
188 LoadURL("https://example.com/test.html"); | |
189 request.Complete( | |
190 "<div id='space' style='height: 1000px'></div>" | |
191 "<div id='container' style='height: 600px; overflow: scroll'>" | |
192 " <div id='space1' style='height: 1000px'></div>" | |
193 " <div id='content' style='height: 1000px'></div>" | |
194 "</div>"); | |
195 | |
196 Element* container = GetDocument().getElementById("container"); | |
197 Element* content = GetDocument().getElementById("content"); | |
198 ScrollIntoViewOptionsOrBoolean arg; | |
199 ScrollIntoViewOptions options; | |
200 options.setBlock("start"); | |
201 options.setBehavior("smooth"); | |
202 arg.setScrollIntoViewOptions(options); | |
203 Compositor().BeginFrame(); | |
204 ASSERT_EQ(Window().scrollY(), 0); | |
205 ASSERT_EQ(container->scrollTop(), 0); | |
206 | |
207 content->scrollIntoView(arg); | |
208 // Scrolling the outer container | |
209 Compositor().BeginFrame(); // update run_state_. | |
210 Compositor().BeginFrame(); // Set start_time = now. | |
211 Compositor().BeginFrame(0.2); | |
212 ASSERT_EQ(Window().scrollY(), 299); | |
213 ASSERT_EQ(container->scrollTop(), 0); | |
214 | |
215 ScrollToOptions window_option; | |
216 window_option.setLeft(0); | |
217 window_option.setTop(0); | |
218 window_option.setBehavior("smooth"); | |
219 Window().scrollTo(window_option); | |
220 Compositor().BeginFrame(); // update run_state_. | |
221 Compositor().BeginFrame(); // Set start_time = now. | |
222 Compositor().BeginFrame(0.2); | |
223 ASSERT_EQ(Window().scrollY(), 58); | |
224 | |
225 Compositor().BeginFrame(1); | |
226 ASSERT_EQ(Window().scrollY(), 0); | |
227 ASSERT_EQ(container->scrollTop(), 0); | |
228 } | |
229 | |
230 TEST_F(SmoothScrollTest, BlockAndInlineSettings) { | |
231 v8::HandleScope HandleScope(v8::Isolate::GetCurrent()); | |
232 WebView().Resize(WebSize(800, 600)); | |
233 SimRequest request("https://example.com/test.html", "text/html"); | |
234 LoadURL("https://example.com/test.html"); | |
235 request.Complete( | |
236 "<div id='container' style='height: 2500px; width: 2500px;'>" | |
237 "<div id='content' style='height: 500px; width: 500px;" | |
238 "margin-left: 1000px; margin-right: 1000px; margin-top: 1000px;" | |
239 "margin-bottom: 1000px'></div></div>"); | |
240 | |
241 int content_height = 500; | |
242 int content_width = 500; | |
243 int window_height = 600; | |
244 int window_width = 800; | |
245 | |
246 Element* content = GetDocument().getElementById("content"); | |
247 ScrollIntoViewOptionsOrBoolean arg1, arg2, arg3, arg4; | |
248 ScrollIntoViewOptions options; | |
249 ASSERT_EQ(Window().scrollY(), 0); | |
250 | |
251 options.setBlock("nearest"); | |
252 options.setInlinePosition("nearest"); | |
253 arg1.setScrollIntoViewOptions(options); | |
254 content->scrollIntoView(arg1); | |
255 ASSERT_EQ(Window().scrollX(), | |
256 content->OffsetLeft() + content_width - window_width); | |
257 ASSERT_EQ(Window().scrollY(), | |
258 content->OffsetTop() + content_height - window_height); | |
259 | |
260 options.setBlock("start"); | |
261 options.setInlinePosition("start"); | |
262 arg2.setScrollIntoViewOptions(options); | |
263 content->scrollIntoView(arg2); | |
264 ASSERT_EQ(Window().scrollX(), content->OffsetLeft()); | |
265 ASSERT_EQ(Window().scrollY(), content->OffsetTop()); | |
266 | |
267 options.setBlock("center"); | |
268 options.setInlinePosition("center"); | |
269 arg3.setScrollIntoViewOptions(options); | |
270 content->scrollIntoView(arg3); | |
271 ASSERT_EQ(Window().scrollX(), | |
272 content->OffsetLeft() + (content_width - window_width) / 2); | |
273 ASSERT_EQ(Window().scrollY(), | |
274 content->OffsetTop() + (content_height - window_height) / 2); | |
275 | |
276 options.setBlock("end"); | |
277 options.setInlinePosition("end"); | |
278 arg4.setScrollIntoViewOptions(options); | |
279 content->scrollIntoView(arg4); | |
280 ASSERT_EQ(Window().scrollX(), | |
281 content->OffsetLeft() + content_width - window_width); | |
282 ASSERT_EQ(Window().scrollY(), | |
283 content->OffsetTop() + content_height - window_height); | |
284 } | |
285 | |
286 } // namespace | |
287 | |
288 } // namespace blink | |
OLD | NEW |