OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2015 Google Inc. All rights reserved. | 2 * Copyright (C) 2015 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 11 matching lines...) Expand all Loading... |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 #include "core/frame/TopControls.h" | 30 #include "core/frame/TopControls.h" |
31 | 31 |
| 32 #include "core/dom/ClientRect.h" |
32 #include "core/frame/FrameHost.h" | 33 #include "core/frame/FrameHost.h" |
33 #include "core/frame/FrameView.h" | 34 #include "core/frame/FrameView.h" |
34 #include "core/frame/LocalFrame.h" | 35 #include "core/frame/LocalFrame.h" |
35 #include "core/layout/LayoutView.h" | 36 #include "core/layout/LayoutView.h" |
36 #include "core/page/Page.h" | 37 #include "core/page/Page.h" |
37 #include "platform/testing/URLTestHelpers.h" | 38 #include "platform/testing/URLTestHelpers.h" |
38 #include "public/platform/Platform.h" | 39 #include "public/platform/Platform.h" |
39 #include "public/platform/WebUnitTestSupport.h" | 40 #include "public/platform/WebUnitTestSupport.h" |
| 41 #include "public/web/WebElement.h" |
40 #include "public/web/WebSettings.h" | 42 #include "public/web/WebSettings.h" |
41 #include "testing/gmock/include/gmock/gmock.h" | 43 #include "testing/gmock/include/gmock/gmock.h" |
42 #include "testing/gtest/include/gtest/gtest.h" | 44 #include "testing/gtest/include/gtest/gtest.h" |
43 #include "web/WebLocalFrameImpl.h" | 45 #include "web/WebLocalFrameImpl.h" |
44 #include "web/tests/FrameTestHelpers.h" | 46 #include "web/tests/FrameTestHelpers.h" |
45 | 47 |
46 namespace blink { | 48 namespace blink { |
47 | 49 |
48 // These tests cover top controls scrolling on main-thread. | 50 // These tests cover top controls scrolling on main-thread. |
49 // The animation for completing a partial show/hide is done in compositor so | 51 // The animation for completing a partial show/hide is done in compositor so |
50 // it is not covered here. | 52 // it is not covered here. |
51 class TopControlsTest : public testing::Test { | 53 class TopControlsTest : public testing::Test { |
52 public: | 54 public: |
53 TopControlsTest() | 55 TopControlsTest() |
54 : m_baseURL("http://www.test.com/") | 56 : m_baseURL("http://www.test.com/") |
55 { | 57 { |
56 registerMockedHttpURLLoad("large-div.html"); | 58 registerMockedHttpURLLoad("large-div.html"); |
57 registerMockedHttpURLLoad("overflow-scrolling.html"); | 59 registerMockedHttpURLLoad("overflow-scrolling.html"); |
58 registerMockedHttpURLLoad("iframe-scrolling.html"); | 60 registerMockedHttpURLLoad("iframe-scrolling.html"); |
59 registerMockedHttpURLLoad("iframe-scrolling-inner.html"); | 61 registerMockedHttpURLLoad("iframe-scrolling-inner.html"); |
| 62 registerMockedHttpURLLoad("percent-height.html"); |
| 63 registerMockedHttpURLLoad("vh-height.html"); |
| 64 registerMockedHttpURLLoad("vh-height-width-800.html"); |
| 65 registerMockedHttpURLLoad("vh-height-width-800-extra-wide.html"); |
60 } | 66 } |
61 | 67 |
62 ~TopControlsTest() override | 68 ~TopControlsTest() override |
63 { | 69 { |
64 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); | 70 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); |
65 } | 71 } |
66 | 72 |
67 WebViewImpl* initialize(const std::string& pageName = "large-div.html") | 73 WebViewImpl* initialize(const std::string& pageName = "large-div.html") |
68 { | 74 { |
69 // Load a page with large body and set viewport size to 400x400 to ensur
e | 75 // Load a page with large body and set viewport size to 400x400 to ensur
e |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 return event; | 111 return event; |
106 } | 112 } |
107 | 113 |
108 void verticalScroll(float deltaY) | 114 void verticalScroll(float deltaY) |
109 { | 115 { |
110 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llBegin)); | 116 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llBegin)); |
111 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llUpdate, 0, deltaY)); | 117 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llUpdate, 0, deltaY)); |
112 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llEnd)); | 118 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llEnd)); |
113 } | 119 } |
114 | 120 |
| 121 PassRefPtrWillBeRawPtr<Element> getElementById(const WebString& id) |
| 122 { |
| 123 return static_cast<PassRefPtrWillBeRawPtr<Element>>( |
| 124 webViewImpl()->mainFrame()->document().getElementById(id)); |
| 125 } |
| 126 |
| 127 |
115 WebViewImpl* webViewImpl() const { return m_helper.webViewImpl(); } | 128 WebViewImpl* webViewImpl() const { return m_helper.webViewImpl(); } |
116 LocalFrame* frame() const { return m_helper.webViewImpl()->mainFrameImpl()->
frame(); } | 129 LocalFrame* frame() const { return m_helper.webViewImpl()->mainFrameImpl()->
frame(); } |
117 VisualViewport& visualViewport() const { return m_helper.webViewImpl()->page
()->frameHost().visualViewport(); } | 130 VisualViewport& visualViewport() const { return m_helper.webViewImpl()->page
()->frameHost().visualViewport(); } |
118 | 131 |
119 private: | 132 private: |
120 std::string m_baseURL; | 133 std::string m_baseURL; |
121 FrameTestHelpers::WebViewHelper m_helper; | 134 FrameTestHelpers::WebViewHelper m_helper; |
122 }; | 135 }; |
123 | 136 |
124 #define EXPECT_POINT_EQ(expected, actual) \ | 137 #define EXPECT_POINT_EQ(expected, actual) \ |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 // Both states are permitted so controls can either show or hide | 550 // Both states are permitted so controls can either show or hide |
538 verticalScroll(50.f); | 551 verticalScroll(50.f); |
539 EXPECT_FLOAT_EQ(50, webView->topControls().contentOffset()); | 552 EXPECT_FLOAT_EQ(50, webView->topControls().contentOffset()); |
540 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition()); | 553 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition()); |
541 | 554 |
542 verticalScroll(-50.f); | 555 verticalScroll(-50.f); |
543 EXPECT_FLOAT_EQ(0, webView->topControls().contentOffset()); | 556 EXPECT_FLOAT_EQ(0, webView->topControls().contentOffset()); |
544 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition()); | 557 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition()); |
545 } | 558 } |
546 | 559 |
| 560 // Ensure that top controls do not affect the layout by showing and hiding |
| 561 // except for position: fixed elements. |
| 562 TEST_F(TopControlsTest, MAYBE(DontAffectLayoutHeight)) |
| 563 { |
| 564 // Initialize with the top controls showing. |
| 565 WebViewImpl* webView = initialize("percent-height.html"); |
| 566 webView->setTopControlsHeight(100.f, true); |
| 567 webView->updateTopControlsState( |
| 568 WebTopControlsBoth, WebTopControlsShown, false); |
| 569 webView->topControls().setShownRatio(1); |
| 570 webView->resize(WebSize(400, 300)); |
| 571 webView->updateAllLifecyclePhases(); |
| 572 |
| 573 ASSERT_EQ(100.f, webView->topControls().contentOffset()); |
| 574 |
| 575 // When the top controls are showing, there's 300px for the layout height so |
| 576 // 50% should result in both the position:fixed and position: absolute divs |
| 577 // having 150px of height. |
| 578 RefPtrWillBeRawPtr<Element> absPos = |
| 579 getElementById(WebString::fromUTF8("abs")); |
| 580 RefPtrWillBeRawPtr<Element> fixedPos = |
| 581 getElementById(WebString::fromUTF8("fixed")); |
| 582 EXPECT_FLOAT_EQ(150.f, absPos->getBoundingClientRect()->height()); |
| 583 EXPECT_FLOAT_EQ(150.f, fixedPos->getBoundingClientRect()->height()); |
| 584 |
| 585 // The layout size on the FrameView should not include the top controls. |
| 586 EXPECT_EQ(300, frame()->view()->layoutSize(IncludeScrollbars).height()); |
| 587 |
| 588 // Hide the top controls. |
| 589 verticalScroll(-100.f); |
| 590 webView->setTopControlsHeight(100.f, false); |
| 591 webView->resize(WebSize(400, 400)); |
| 592 webView->updateAllLifecyclePhases(); |
| 593 |
| 594 ASSERT_EQ(0.f, webView->topControls().contentOffset()); |
| 595 |
| 596 // Hiding the top controls shouldn't change the height of the initial |
| 597 // containing block for non-position: fixed. Position: fixed however should |
| 598 // use the entire height of the viewport however. |
| 599 EXPECT_FLOAT_EQ(150.f, absPos->getBoundingClientRect()->height()); |
| 600 EXPECT_FLOAT_EQ(200.f, fixedPos->getBoundingClientRect()->height()); |
| 601 |
| 602 // The layout size should not change as a result of top controls hiding. |
| 603 EXPECT_EQ(300, frame()->view()->layoutSize(IncludeScrollbars).height()); |
| 604 } |
| 605 |
| 606 // Ensure that top controls do not affect vh units. |
| 607 TEST_F(TopControlsTest, MAYBE(DontAffectVHUnits)) |
| 608 { |
| 609 // Initialize with the top controls showing. |
| 610 WebViewImpl* webView = initialize("vh-height.html"); |
| 611 webView->setTopControlsHeight(100.f, true); |
| 612 webView->updateTopControlsState( |
| 613 WebTopControlsBoth, WebTopControlsShown, false); |
| 614 webView->topControls().setShownRatio(1); |
| 615 webView->resize(WebSize(400, 300)); |
| 616 webView->updateAllLifecyclePhases(); |
| 617 |
| 618 ASSERT_EQ(100.f, webView->topControls().contentOffset()); |
| 619 |
| 620 // 'vh' units should be based on the viewport when the top controls are |
| 621 // hidden. |
| 622 RefPtrWillBeRawPtr<Element> absPos = |
| 623 getElementById(WebString::fromUTF8("abs")); |
| 624 RefPtrWillBeRawPtr<Element> fixedPos = |
| 625 getElementById(WebString::fromUTF8("fixed")); |
| 626 EXPECT_FLOAT_EQ(200.f, absPos->getBoundingClientRect()->height()); |
| 627 EXPECT_FLOAT_EQ(200.f, fixedPos->getBoundingClientRect()->height()); |
| 628 |
| 629 // The size used for viewport units should not be reduced by the top |
| 630 // controls. |
| 631 EXPECT_EQ(400, frame()->view()->viewportSizeForViewportUnits().height()); |
| 632 |
| 633 // Hide the top controls. |
| 634 verticalScroll(-100.f); |
| 635 webView->setTopControlsHeight(100.f, false); |
| 636 webView->resize(WebSize(400, 400)); |
| 637 webView->updateAllLifecyclePhases(); |
| 638 |
| 639 ASSERT_EQ(0.f, webView->topControls().contentOffset()); |
| 640 |
| 641 // vh units should be static with respect to the top controls so neighter |
| 642 // <div> should change size are a result of the top controls hiding. |
| 643 EXPECT_FLOAT_EQ(200.f, absPos->getBoundingClientRect()->height()); |
| 644 EXPECT_FLOAT_EQ(200.f, fixedPos->getBoundingClientRect()->height()); |
| 645 |
| 646 // The viewport size used for vh units should not change as a result of top |
| 647 // controls hiding. |
| 648 EXPECT_EQ(400, frame()->view()->viewportSizeForViewportUnits().height()); |
| 649 } |
| 650 |
| 651 // Ensure that on a legacy page (there's a non-1 minimum scale) 100vh units fill |
| 652 // the viewport, with top controls hidden, when the viewport encompasses the |
| 653 // layout width. |
| 654 TEST_F(TopControlsTest, MAYBE(DontAffectVHUnitsWithScale)) |
| 655 { |
| 656 // Initialize with the top controls showing. |
| 657 WebViewImpl* webView = initialize("vh-height-width-800.html"); |
| 658 webView->setTopControlsHeight(100.f, true); |
| 659 webView->updateTopControlsState( |
| 660 WebTopControlsBoth, WebTopControlsShown, false); |
| 661 webView->topControls().setShownRatio(1); |
| 662 webView->resize(WebSize(400, 300)); |
| 663 webView->updateAllLifecyclePhases(); |
| 664 |
| 665 ASSERT_EQ(100.f, webView->topControls().contentOffset()); |
| 666 |
| 667 // Device viewport is 400px but the page is width=800 so minimum-scale |
| 668 // should be 0.5. This is also the scale at which the viewport fills the |
| 669 // layout width. |
| 670 ASSERT_EQ(0.5f, webView->minimumPageScaleFactor()); |
| 671 |
| 672 // We should size vh units so that 100vh fills the viewport at min-scale so |
| 673 // we have to account for the minimum page scale factor. Since both boxes |
| 674 // are 50vh, and layout scale = 0.5, we have a vh viewport of 400 / 0.5 = 80
0 |
| 675 // so we expect 50vh to be 400px. |
| 676 RefPtrWillBeRawPtr<Element> absPos = |
| 677 getElementById(WebString::fromUTF8("abs")); |
| 678 RefPtrWillBeRawPtr<Element> fixedPos = |
| 679 getElementById(WebString::fromUTF8("fixed")); |
| 680 EXPECT_FLOAT_EQ(400.f, absPos->getBoundingClientRect()->height()); |
| 681 EXPECT_FLOAT_EQ(400.f, fixedPos->getBoundingClientRect()->height()); |
| 682 |
| 683 // The size used for viewport units should not be reduced by the top |
| 684 // controls. |
| 685 EXPECT_EQ(800, frame()->view()->viewportSizeForViewportUnits().height()); |
| 686 |
| 687 // Hide the top controls. |
| 688 verticalScroll(-100.f); |
| 689 webView->setTopControlsHeight(100.f, false); |
| 690 webView->resize(WebSize(400, 400)); |
| 691 webView->updateAllLifecyclePhases(); |
| 692 |
| 693 ASSERT_EQ(0.f, webView->topControls().contentOffset()); |
| 694 |
| 695 // vh units should be static with respect to the top controls so neighter |
| 696 // <div> should change size are a result of the top controls hiding. |
| 697 EXPECT_FLOAT_EQ(400.f, absPos->getBoundingClientRect()->height()); |
| 698 EXPECT_FLOAT_EQ(400.f, fixedPos->getBoundingClientRect()->height()); |
| 699 |
| 700 // The viewport size used for vh units should not change as a result of top |
| 701 // controls hiding. |
| 702 EXPECT_EQ(800, frame()->view()->viewportSizeForViewportUnits().height()); |
| 703 } |
| 704 |
| 705 // Ensure that on a legacy page (there's a non-1 minimum scale) whose viewport |
| 706 // at minimum-scale is larger than the layout size, 100vh units fill the |
| 707 // viewport, with top controls hidden, when the viewport is scaled such that |
| 708 // its width equals the layout width. |
| 709 TEST_F(TopControlsTest, MAYBE(DontAffectVHUnitsUseLayoutSize)) |
| 710 { |
| 711 // Initialize with the top controls showing. |
| 712 WebViewImpl* webView = initialize("vh-height-width-800-extra-wide.html"); |
| 713 webView->setTopControlsHeight(100.f, true); |
| 714 webView->updateTopControlsState( |
| 715 WebTopControlsBoth, WebTopControlsShown, false); |
| 716 webView->topControls().setShownRatio(1); |
| 717 webView->resize(WebSize(400, 300)); |
| 718 webView->updateAllLifecyclePhases(); |
| 719 |
| 720 ASSERT_EQ(100.f, webView->topControls().contentOffset()); |
| 721 |
| 722 // Device viewport is 400px and page is width=800 but there's an element |
| 723 // that's 1600px wide so the minimum scale is 0.25 to encompass that. |
| 724 ASSERT_EQ(0.25f, webView->minimumPageScaleFactor()); |
| 725 |
| 726 // The viewport will match the layout width at scale=0.5 so the height used |
| 727 // for vh should be (300 / 0.5) for the layout height + (100 / 0.5) for top |
| 728 // controls = 800. |
| 729 EXPECT_EQ(800, frame()->view()->viewportSizeForViewportUnits().height()); |
| 730 } |
| 731 |
547 } // namespace blink | 732 } // namespace blink |
OLD | NEW |