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" | |
33 #include "core/frame/FrameHost.h" | 32 #include "core/frame/FrameHost.h" |
34 #include "core/frame/FrameView.h" | 33 #include "core/frame/FrameView.h" |
35 #include "core/frame/LocalFrame.h" | 34 #include "core/frame/LocalFrame.h" |
36 #include "core/layout/LayoutView.h" | 35 #include "core/layout/LayoutView.h" |
37 #include "core/page/Page.h" | 36 #include "core/page/Page.h" |
38 #include "platform/testing/URLTestHelpers.h" | 37 #include "platform/testing/URLTestHelpers.h" |
39 #include "public/platform/Platform.h" | 38 #include "public/platform/Platform.h" |
40 #include "public/platform/WebUnitTestSupport.h" | 39 #include "public/platform/WebUnitTestSupport.h" |
41 #include "public/web/WebElement.h" | |
42 #include "public/web/WebSettings.h" | 40 #include "public/web/WebSettings.h" |
43 #include "testing/gmock/include/gmock/gmock.h" | 41 #include "testing/gmock/include/gmock/gmock.h" |
44 #include "testing/gtest/include/gtest/gtest.h" | 42 #include "testing/gtest/include/gtest/gtest.h" |
45 #include "web/WebLocalFrameImpl.h" | 43 #include "web/WebLocalFrameImpl.h" |
46 #include "web/tests/FrameTestHelpers.h" | 44 #include "web/tests/FrameTestHelpers.h" |
47 | 45 |
48 namespace blink { | 46 namespace blink { |
49 | 47 |
50 // These tests cover top controls scrolling on main-thread. | 48 // These tests cover top controls scrolling on main-thread. |
51 // The animation for completing a partial show/hide is done in compositor so | 49 // The animation for completing a partial show/hide is done in compositor so |
52 // it is not covered here. | 50 // it is not covered here. |
53 class TopControlsTest : public testing::Test { | 51 class TopControlsTest : public testing::Test { |
54 public: | 52 public: |
55 TopControlsTest() | 53 TopControlsTest() |
56 : m_baseURL("http://www.test.com/") | 54 : m_baseURL("http://www.test.com/") |
57 { | 55 { |
58 registerMockedHttpURLLoad("large-div.html"); | 56 registerMockedHttpURLLoad("large-div.html"); |
59 registerMockedHttpURLLoad("overflow-scrolling.html"); | 57 registerMockedHttpURLLoad("overflow-scrolling.html"); |
60 registerMockedHttpURLLoad("iframe-scrolling.html"); | 58 registerMockedHttpURLLoad("iframe-scrolling.html"); |
61 registerMockedHttpURLLoad("iframe-scrolling-inner.html"); | 59 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"); | |
66 } | 60 } |
67 | 61 |
68 ~TopControlsTest() override | 62 ~TopControlsTest() override |
69 { | 63 { |
70 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); | 64 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); |
71 } | 65 } |
72 | 66 |
73 WebViewImpl* initialize(const std::string& pageName = "large-div.html") | 67 WebViewImpl* initialize(const std::string& pageName = "large-div.html") |
74 { | 68 { |
75 // Load a page with large body and set viewport size to 400x400 to ensur
e | 69 // 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... |
111 return event; | 105 return event; |
112 } | 106 } |
113 | 107 |
114 void verticalScroll(float deltaY) | 108 void verticalScroll(float deltaY) |
115 { | 109 { |
116 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llBegin)); | 110 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llBegin)); |
117 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llUpdate, 0, deltaY)); | 111 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llUpdate, 0, deltaY)); |
118 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llEnd)); | 112 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScro
llEnd)); |
119 } | 113 } |
120 | 114 |
121 PassRefPtrWillBeRawPtr<Element> getElementById(const WebString& id) | |
122 { | |
123 return static_cast<PassRefPtrWillBeRawPtr<Element>>( | |
124 webViewImpl()->mainFrame()->document().getElementById(id)); | |
125 } | |
126 | |
127 | |
128 WebViewImpl* webViewImpl() const { return m_helper.webViewImpl(); } | 115 WebViewImpl* webViewImpl() const { return m_helper.webViewImpl(); } |
129 LocalFrame* frame() const { return m_helper.webViewImpl()->mainFrameImpl()->
frame(); } | 116 LocalFrame* frame() const { return m_helper.webViewImpl()->mainFrameImpl()->
frame(); } |
130 VisualViewport& visualViewport() const { return m_helper.webViewImpl()->page
()->frameHost().visualViewport(); } | 117 VisualViewport& visualViewport() const { return m_helper.webViewImpl()->page
()->frameHost().visualViewport(); } |
131 | 118 |
132 private: | 119 private: |
133 std::string m_baseURL; | 120 std::string m_baseURL; |
134 FrameTestHelpers::WebViewHelper m_helper; | 121 FrameTestHelpers::WebViewHelper m_helper; |
135 }; | 122 }; |
136 | 123 |
137 #define EXPECT_POINT_EQ(expected, actual) \ | 124 #define EXPECT_POINT_EQ(expected, actual) \ |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 // Both states are permitted so controls can either show or hide | 537 // Both states are permitted so controls can either show or hide |
551 verticalScroll(50.f); | 538 verticalScroll(50.f); |
552 EXPECT_FLOAT_EQ(50, webView->topControls().contentOffset()); | 539 EXPECT_FLOAT_EQ(50, webView->topControls().contentOffset()); |
553 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition()); | 540 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition()); |
554 | 541 |
555 verticalScroll(-50.f); | 542 verticalScroll(-50.f); |
556 EXPECT_FLOAT_EQ(0, webView->topControls().contentOffset()); | 543 EXPECT_FLOAT_EQ(0, webView->topControls().contentOffset()); |
557 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition()); | 544 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition()); |
558 } | 545 } |
559 | 546 |
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 | |
732 } // namespace blink | 547 } // namespace blink |
OLD | NEW |