2 * Copyright (C) 2015 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "core/frame/TopControls.h"
33 #include "core/frame/FrameHost.h"
34 #include "core/frame/LocalFrame.h"
35 #include "core/layout/LayoutView.h"
36 #include "core/page/Page.h"
37 #include "platform/testing/URLTestHelpers.h"
38 #include "public/platform/Platform.h"
39 #include "public/platform/WebUnitTestSupport.h"
40 #include "public/web/WebSettings.h"
41 #include "web/WebLocalFrameImpl.h"
42 #include "web/tests/FrameTestHelpers.h"
43 #include <gmock/gmock.h>
44 #include <gtest/gtest.h>
48 // These tests cover top controls scrolling on main-thread.
49 // The animation for completing a partial show/hide is done in compositor so
50 // it is not covered here.
51 class TopControlsTest
: public testing::Test
{
54 : m_baseURL("http://www.test.com/")
56 registerMockedHttpURLLoad("large-div.html");
57 registerMockedHttpURLLoad("overflow-scrolling.html");
58 registerMockedHttpURLLoad("iframe-scrolling.html");
59 registerMockedHttpURLLoad("iframe-scrolling-inner.html");
62 ~TopControlsTest() override
64 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
67 WebViewImpl
* initialize(const std::string
& pageName
= "large-div.html")
69 // Load a page with large body and set viewport size to 400x400 to ensure
70 // main frame is scrollable.
71 m_helper
.initializeAndLoad(m_baseURL
+ pageName
, true, 0, 0, &configureSettings
);
73 webViewImpl()->resize(IntSize(400, 400));
77 static void configureSettings(WebSettings
* settings
)
79 settings
->setJavaScriptEnabled(true);
80 settings
->setAcceleratedCompositingEnabled(true);
81 settings
->setPreferCompositingToLCDTextEnabled(true);
83 settings
->setViewportEnabled(true);
84 settings
->setViewportMetaEnabled(true);
85 settings
->setShrinksViewportContentToFit(true);
86 settings
->setMainFrameResizesAreOrientationChanges(true);
89 void registerMockedHttpURLLoad(const std::string
& fileName
)
91 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8(fileName
.c_str()));
94 WebGestureEvent
generateEvent(WebInputEvent::Type type
, int deltaX
= 0, int deltaY
= 0)
96 WebGestureEvent event
;
100 if (type
== WebInputEvent::GestureScrollUpdate
) {
101 event
.data
.scrollUpdate
.deltaX
= deltaX
;
102 event
.data
.scrollUpdate
.deltaY
= deltaY
;
107 void verticalScroll(float deltaY
)
109 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin
));
110 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, deltaY
));
111 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollEnd
));
114 WebViewImpl
* webViewImpl() const { return m_helper
.webViewImpl(); }
115 LocalFrame
* frame() const { return m_helper
.webViewImpl()->mainFrameImpl()->frame(); }
116 VisualViewport
& visualViewport() const { return m_helper
.webViewImpl()->page()->frameHost().visualViewport(); }
119 std::string m_baseURL
;
120 FrameTestHelpers::WebViewHelper m_helper
;
122 // To prevent platform differences in content layout, use mock
123 // scrollbars. This is especially needed for Mac, where the presence
124 // or absence of a mouse will change frame sizes because of different
126 FrameTestHelpers::UseMockScrollbarSettings m_useMockScrollbars
;
129 #define EXPECT_POINT_EQ(expected, actual) \
131 EXPECT_DOUBLE_EQ((expected).x(), (actual).x()); \
132 EXPECT_DOUBLE_EQ((expected).y(), (actual).y()); \
135 // Disable these tests on Mac OSX until further investigation.
136 // Local build on Mac is OK but the bot fails. This is not an issue as
137 // Top Controls are currently only used on Android.
139 #define MAYBE(test) DISABLED_##test
141 #define MAYBE(test) test
144 // Scrolling down should hide top controls.
145 TEST_F(TopControlsTest
, MAYBE(HideOnScrollDown
))
147 WebViewImpl
* webView
= initialize();
148 // initialize top controls to be shown.
149 webView
->setTopControlsHeight(50.f
, true);
150 webView
->topControls().setShownRatio(1);
152 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin
));
153 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
155 // Top controls should be scrolled partially and page should not scroll.
156 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, -25.f
));
157 EXPECT_FLOAT_EQ(25.f
, webView
->topControls().contentOffset());
158 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollPosition());
160 // Top controls should consume 30px and become hidden. Excess scroll should be consumed by the page.
161 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, -40.f
));
162 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
163 EXPECT_POINT_EQ(IntPoint(0, 15), frame()->view()->scrollPosition());
165 // Only page should consume scroll
166 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, -20.f
));
167 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
168 EXPECT_POINT_EQ(IntPoint(0, 35), frame()->view()->scrollPosition());
171 // Scrolling up should show top controls.
172 TEST_F(TopControlsTest
, MAYBE(ShowOnScrollUp
))
174 WebViewImpl
* webView
= initialize();
175 // initialize top controls to be hidden.
176 webView
->setTopControlsHeight(50.f
, false);
177 webView
->topControls().setShownRatio(0);
179 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin
));
180 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
182 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, 10.f
));
183 EXPECT_FLOAT_EQ(10.f
, webView
->topControls().contentOffset());
184 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollPosition());
186 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, 50.f
));
187 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
188 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollPosition());
191 // Scrolling up after previous scroll downs should cause top controls to be
192 // shown only after all previously scrolled down amount is compensated.
193 TEST_F(TopControlsTest
, MAYBE(ScrollDownThenUp
))
195 WebViewImpl
* webView
= initialize();
196 // initialize top controls to be shown and position page at 100px.
197 webView
->setTopControlsHeight(50.f
, true);
198 webView
->topControls().setShownRatio(1);
199 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll
);
201 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin
));
202 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
204 // Scroll down to completely hide top controls. Excess deltaY (100px) should be consumed by the page.
205 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, -150.f
));
206 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
207 EXPECT_POINT_EQ(IntPoint(0, 200), frame()->view()->scrollPosition());
209 // Scroll up and ensure the top controls does not move until we recover 100px previously scrolled.
210 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, 40.f
));
211 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
212 EXPECT_POINT_EQ(IntPoint(0, 160), frame()->view()->scrollPosition());
214 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, 60.f
));
215 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
216 EXPECT_POINT_EQ(IntPoint(0, 100), frame()->view()->scrollPosition());
218 // Now we have hit the threshold so further scroll up should be consumed by top controls.
219 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, 30.f
));
220 EXPECT_FLOAT_EQ(30.f
, webView
->topControls().contentOffset());
221 EXPECT_POINT_EQ(IntPoint(0, 100), frame()->view()->scrollPosition());
223 // Once top control is fully shown then page should consume any excess scroll.
224 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, 70.f
));
225 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
226 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
229 // Scrolling down should always cause visible top controls to start hiding even
230 // if we have been scrolling up previously.
231 TEST_F(TopControlsTest
, MAYBE(ScrollUpThenDown
))
233 WebViewImpl
* webView
= initialize();
234 // initialize top controls to be hidden and position page at 100px.
235 webView
->setTopControlsHeight(50.f
, false);
236 webView
->topControls().setShownRatio(0);
237 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll
);
239 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin
));
240 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
242 // Scroll up to completely show top controls. Excess deltaY (50px) should be consumed by the page.
243 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, 100.f
));
244 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
245 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
247 // Scroll down and ensure only top controls is scrolled
248 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, -40.f
));
249 EXPECT_FLOAT_EQ(10.f
, webView
->topControls().contentOffset());
250 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
252 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, -60.f
));
253 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
254 EXPECT_POINT_EQ(IntPoint(0, 100), frame()->view()->scrollPosition());
257 // Top controls should not consume horizontal scroll.
258 TEST_F(TopControlsTest
, MAYBE(HorizontalScroll
))
260 WebViewImpl
* webView
= initialize();
261 // initialize top controls to be shown.
262 webView
->setTopControlsHeight(50.f
, true);
263 webView
->topControls().setShownRatio(1);
265 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin
));
266 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
268 // Top controls should not consume horizontal scroll.
269 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, -110.f
, -100.f
));
270 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
271 EXPECT_POINT_EQ(IntPoint(110, 50), frame()->view()->scrollPosition());
273 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, -40.f
, 0));
274 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
275 EXPECT_POINT_EQ(IntPoint(150, 50), frame()->view()->scrollPosition());
278 // Page scale should not impact top controls scrolling
279 TEST_F(TopControlsTest
, MAYBE(PageScaleHasNoImpact
))
281 WebViewImpl
* webView
= initialize();
282 webViewImpl()->setDefaultPageScaleLimits(0.25f
, 5);
283 webView
->setPageScaleFactor(2.0);
285 // Initialize top controls to be shown.
286 webView
->setTopControlsHeight(50.f
, true);
287 webView
->topControls().setShownRatio(1);
289 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin
));
290 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
292 // Top controls should be scrolled partially and page should not scroll.
293 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, -20.f
));
294 EXPECT_FLOAT_EQ(30.f
, webView
->topControls().contentOffset());
295 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollableArea()->scrollPositionDouble());
297 // Top controls should consume 30px and become hidden. Excess scroll should be consumed by the page at 2x scale.
298 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, -70.f
));
299 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
300 EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->scrollableArea()->scrollPositionDouble());
302 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollEnd
));
304 // Change page scale and test.
305 webView
->setPageScaleFactor(0.5);
307 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin
));
308 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
309 EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->scrollableArea()->scrollPositionDouble());
311 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, 50.f
));
312 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
313 EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->scrollableArea()->scrollPositionDouble());
315 // At 0.5x scale scrolling 10px should take us to the top of the page.
316 webView
->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, 0, 10.f
));
317 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
318 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollableArea()->scrollPositionDouble());
321 // Some scroll deltas result in a shownRatio that can't be realized in a
322 // floating-point number. Make sure that if the top controls aren't fully
323 // scrolled, scrollBy doesn't return any excess delta. i.e. There should be no
324 // slippage between the content and top controls.
325 TEST_F(TopControlsTest
, MAYBE(FloatingPointSlippage
))
327 WebViewImpl
* webView
= initialize();
328 webViewImpl()->setDefaultPageScaleLimits(0.25f
, 5);
329 webView
->setPageScaleFactor(2.0);
331 // Initialize top controls to be shown.
332 webView
->setTopControlsHeight(50.f
, true);
333 webView
->topControls().setShownRatio(1);
335 webView
->topControls().scrollBegin();
336 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
338 // This will result in a 20px scroll to the top controls so the show ratio
339 // will be 30/50 == 0.6 which is not representible in a float. Make sure
340 // that scroll still consumes the whole delta.
341 FloatSize remainingDelta
= webView
->topControls().scrollBy(FloatSize(0, -10));
342 EXPECT_EQ(0, remainingDelta
.height());
345 // Scrollable subregions should scroll before top controls
346 TEST_F(TopControlsTest
, MAYBE(ScrollableSubregionScrollFirst
))
348 WebViewImpl
* webView
= initialize("overflow-scrolling.html");
349 webView
->setTopControlsHeight(50.f
, true);
350 webView
->topControls().setShownRatio(1);
351 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 50), ProgrammaticScroll
);
354 // Scroll down should scroll the overflow div first but top controls and main frame should not scroll.
355 verticalScroll(-800.f
);
356 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
357 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
359 // Continued scroll down should start hiding top controls but main frame should not scroll.
360 verticalScroll(-40.f
);
361 EXPECT_FLOAT_EQ(10.f
, webView
->topControls().contentOffset());
362 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
364 // Continued scroll down should scroll down the main frame
365 verticalScroll(-40.f
);
366 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
367 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
370 // scroll up should scroll overflow div first
371 verticalScroll(800.f
);
372 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
373 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
375 // Continued scroll up should start showing top controls but main frame should not scroll.
376 verticalScroll(40.f
);
377 EXPECT_FLOAT_EQ(40.f
, webView
->topControls().contentOffset());
378 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
380 // Continued scroll down up scroll up the main frame
381 verticalScroll(40.f
);
382 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
383 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
387 // Scrollable iframes should scroll before top controls
388 TEST_F(TopControlsTest
, MAYBE(ScrollableIframeScrollFirst
))
390 WebViewImpl
* webView
= initialize("iframe-scrolling.html");
391 webView
->setTopControlsHeight(50.f
, true);
392 webView
->topControls().setShownRatio(1);
393 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 50), ProgrammaticScroll
);
396 // Scroll down should scroll the iframe first but top controls and main frame should not scroll.
397 verticalScroll(-800.f
);
398 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
399 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
401 // Continued scroll down should start hiding top controls but main frame should not scroll.
402 verticalScroll(-40.f
);
403 EXPECT_FLOAT_EQ(10.f
, webView
->topControls().contentOffset());
404 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
406 // Continued scroll down should scroll down the main frame
407 verticalScroll(-40.f
);
408 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
409 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
412 // scroll up should scroll iframe first
413 verticalScroll(800.f
);
414 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
415 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
417 // Continued scroll up should start showing top controls but main frame should not scroll.
418 verticalScroll(40.f
);
419 EXPECT_FLOAT_EQ(40.f
, webView
->topControls().contentOffset());
420 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
422 // Continued scroll down up scroll up the main frame
423 verticalScroll(40.f
);
424 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
425 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
428 // Top controls visibility should remain consistent when height is changed.
429 TEST_F(TopControlsTest
, MAYBE(HeightChangeMaintainsVisibility
))
431 WebViewImpl
* webView
= initialize();
432 webView
->setTopControlsHeight(20.f
, false);
433 webView
->topControls().setShownRatio(0);
435 webView
->setTopControlsHeight(20.f
, false);
436 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
438 webView
->setTopControlsHeight(40.f
, false);
439 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
441 // Scroll up to show top controls.
442 verticalScroll(40.f
);
443 EXPECT_FLOAT_EQ(40.f
, webView
->topControls().contentOffset());
445 // Changing height of a fully shown top controls should correctly adjust content offset
446 webView
->setTopControlsHeight(30.f
, false);
447 EXPECT_FLOAT_EQ(30.f
, webView
->topControls().contentOffset());
450 // Zero delta should not have any effect on top controls.
451 TEST_F(TopControlsTest
, MAYBE(ZeroHeightMeansNoEffect
))
453 WebViewImpl
* webView
= initialize();
454 webView
->setTopControlsHeight(0, false);
455 webView
->topControls().setShownRatio(0);
456 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll
);
458 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
460 verticalScroll(20.f
);
461 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
462 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
464 verticalScroll(-30.f
);
465 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
466 EXPECT_POINT_EQ(IntPoint(0, 110), frame()->view()->scrollPosition());
468 webView
->topControls().setShownRatio(1);
469 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
472 // Top controls should not hide when scrolling up past limit
473 TEST_F(TopControlsTest
, MAYBE(ScrollUpPastLimitDoesNotHide
))
475 WebViewImpl
* webView
= initialize();
476 // Initialize top controls to be shown
477 webView
->setTopControlsHeight(50.f
, true);
478 webView
->topControls().setShownRatio(1);
479 // Use 2x scale so that both visual viewport and frameview are scrollable
480 webView
->setPageScaleFactor(2.0);
482 // Fully scroll frameview but visualviewport remains scrollable
483 webView
->mainFrame()->setScrollOffset(WebSize(0, 10000));
484 visualViewport().setLocation(FloatPoint(0, 0));
485 verticalScroll(-10.f
);
486 EXPECT_FLOAT_EQ(40, webView
->topControls().contentOffset());
488 webView
->topControls().setShownRatio(1);
489 // Fully scroll visual veiwport but frameview remains scrollable
490 webView
->mainFrame()->setScrollOffset(WebSize(0, 0));
491 visualViewport().setLocation(FloatPoint(0, 10000));
492 verticalScroll(-20.f
);
493 EXPECT_FLOAT_EQ(30, webView
->topControls().contentOffset());
495 webView
->topControls().setShownRatio(1);
496 // Fully scroll both frameview and visual viewport
497 webView
->mainFrame()->setScrollOffset(WebSize(0, 10000));
498 visualViewport().setLocation(FloatPoint(0, 10000));
499 verticalScroll(-30.f
);
500 // Top controls should not move because neither frameview nor visual viewport
502 EXPECT_FLOAT_EQ(50.f
, webView
->topControls().contentOffset());
505 // Top controls should honor its constraints
506 TEST_F(TopControlsTest
, MAYBE(StateConstraints
))
508 WebViewImpl
* webView
= initialize();
509 webView
->setTopControlsHeight(50.f
, false);
510 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll
);
512 // Setting permitted state should not change content offset
513 webView
->updateTopControlsState(WebTopControlsShown
, WebTopControlsShown
, false);
514 EXPECT_FLOAT_EQ(0.f
, webView
->topControls().contentOffset());
516 // Showing is permitted
517 webView
->topControls().setShownRatio(1);
518 EXPECT_FLOAT_EQ(50, webView
->topControls().contentOffset());
520 // Only shown state is permitted so controls cannot hide
521 verticalScroll(-20.f
);
522 EXPECT_FLOAT_EQ(50, webView
->topControls().contentOffset());
523 EXPECT_POINT_EQ(IntPoint(0, 120), frame()->view()->scrollPosition());
525 // Setting permitted state should not change content offset
526 webView
->updateTopControlsState(WebTopControlsHidden
, WebTopControlsHidden
, false);
527 EXPECT_FLOAT_EQ(50, webView
->topControls().contentOffset());
529 // Hiding is permitted
530 webView
->topControls().setShownRatio(0);
531 EXPECT_FLOAT_EQ(0, webView
->topControls().contentOffset());
533 // Only hidden state is permitted so controls cannot show
534 verticalScroll(30.f
);
535 EXPECT_FLOAT_EQ(0, webView
->topControls().contentOffset());
536 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition());
538 // Setting permitted state should not change content offset
539 webView
->updateTopControlsState(WebTopControlsBoth
, WebTopControlsBoth
, false);
540 EXPECT_FLOAT_EQ(0, webView
->topControls().contentOffset());
542 // Both states are permitted so controls can either show or hide
543 verticalScroll(50.f
);
544 EXPECT_FLOAT_EQ(50, webView
->topControls().contentOffset());
545 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition());
547 verticalScroll(-50.f
);
548 EXPECT_FLOAT_EQ(0, webView
->topControls().contentOffset());
549 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition());