Chromium Code Reviews| 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 "core/frame/FrameHost.h" | 5 #include "core/frame/FrameHost.h" |
| 6 #include "core/frame/FrameView.h" | 6 #include "core/frame/FrameView.h" |
| 7 #include "core/frame/TopControls.h" | 7 #include "core/frame/TopControls.h" |
| 8 #include "core/html/HTMLFrameOwnerElement.h" | 8 #include "core/html/HTMLFrameOwnerElement.h" |
| 9 #include "core/page/Page.h" | 9 #include "core/page/Page.h" |
| 10 #include "core/page/scrolling/RootScrollerController.h" | 10 #include "core/page/scrolling/RootScrollerController.h" |
| 11 #include "core/paint/PaintLayerScrollableArea.h" | 11 #include "core/paint/PaintLayerScrollableArea.h" |
| 12 #include "platform/testing/URLTestHelpers.h" | 12 #include "platform/testing/URLTestHelpers.h" |
| 13 #include "platform/testing/UnitTestHelpers.h" | 13 #include "platform/testing/UnitTestHelpers.h" |
| 14 #include "public/platform/Platform.h" | 14 #include "public/platform/Platform.h" |
| 15 #include "public/platform/WebURLLoaderMockFactory.h" | 15 #include "public/platform/WebURLLoaderMockFactory.h" |
| 16 #include "public/web/WebCache.h" | 16 #include "public/web/WebCache.h" |
| 17 #include "public/web/WebConsoleMessage.h" | 17 #include "public/web/WebConsoleMessage.h" |
| 18 #include "public/web/WebRemoteFrame.h" | |
| 18 #include "public/web/WebScriptSource.h" | 19 #include "public/web/WebScriptSource.h" |
| 19 #include "public/web/WebSettings.h" | 20 #include "public/web/WebSettings.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 #include "web/WebLocalFrameImpl.h" | 22 #include "web/WebLocalFrameImpl.h" |
| 23 #include "web/WebRemoteFrameImpl.h" | |
| 22 #include "web/tests/FrameTestHelpers.h" | 24 #include "web/tests/FrameTestHelpers.h" |
| 23 #include "wtf/Vector.h" | 25 #include "wtf/Vector.h" |
| 24 | 26 |
| 25 using blink::testing::runPendingTasks; | 27 using blink::testing::runPendingTasks; |
| 26 using testing::Mock; | 28 using testing::Mock; |
| 27 | 29 |
| 28 namespace blink { | 30 namespace blink { |
| 29 | 31 |
| 30 namespace { | 32 namespace { |
| 31 | 33 |
| 32 class RootScrollerTestWebViewClient : public FrameTestHelpers::TestWebViewClient { | |
| 33 public: | |
| 34 MOCK_METHOD4(didOverscroll, void(const WebFloatSize&, const WebFloatSize&, c onst WebFloatPoint&, const WebFloatSize&)); | |
| 35 }; | |
| 36 | |
| 37 class RootScrollerTest : public ::testing::Test { | 34 class RootScrollerTest : public ::testing::Test { |
| 38 public: | 35 public: |
| 39 RootScrollerTest() | 36 RootScrollerTest() |
| 40 : m_baseURL("http://www.test.com/") | 37 : m_baseURL("http://www.test.com/") |
| 41 { | 38 { |
| 42 registerMockedHttpURLLoad("overflow-scrolling.html"); | 39 registerMockedHttpURLLoad("overflow-scrolling.html"); |
| 43 registerMockedHttpURLLoad("root-scroller.html"); | 40 registerMockedHttpURLLoad("root-scroller.html"); |
| 44 registerMockedHttpURLLoad("root-scroller-iframe.html"); | 41 registerMockedHttpURLLoad("root-scroller-iframe.html"); |
| 45 registerMockedHttpURLLoad("root-scroller-child.html"); | 42 registerMockedHttpURLLoad("root-scroller-child.html"); |
| 46 } | 43 } |
| 47 | 44 |
| 48 ~RootScrollerTest() override | 45 ~RootScrollerTest() override |
| 49 { | 46 { |
| 50 m_featuresBackup.restore(); | 47 m_featuresBackup.restore(); |
| 51 Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs(); | 48 Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs(); |
| 52 WebCache::clear(); | 49 WebCache::clear(); |
| 53 } | 50 } |
| 54 | 51 |
| 55 WebViewImpl* initialize(const std::string& pageName) | 52 WebViewImpl* initialize(const std::string& pageName, |
| 53 FrameTestHelpers::TestWebViewClient* client) | |
| 56 { | 54 { |
| 57 RuntimeEnabledFeatures::setSetRootScrollerEnabled(true); | 55 RuntimeEnabledFeatures::setSetRootScrollerEnabled(true); |
| 58 | 56 |
| 59 // Load a page with large body and set viewport size to 400x400 to | |
| 60 // ensure main frame is scrollable. | |
| 61 m_helper.initializeAndLoad( | 57 m_helper.initializeAndLoad( |
| 62 m_baseURL + pageName, true, nullptr, &m_client, nullptr, | 58 m_baseURL + pageName, true, nullptr, client, nullptr, |
| 63 &configureSettings); | 59 &configureSettings); |
| 64 | 60 |
| 65 // Initialize top controls to be shown. | 61 // Initialize top controls to be shown. |
| 66 webViewImpl()->resizeWithTopControls(IntSize(400, 400), 50, true); | 62 webViewImpl()->resizeWithTopControls(IntSize(400, 400), 50, true); |
| 67 webViewImpl()->topControls().setShownRatio(1); | 63 webViewImpl()->topControls().setShownRatio(1); |
| 68 | 64 |
| 69 mainFrameView()->updateAllLifecyclePhases(); | 65 mainFrameView()->updateAllLifecyclePhases(); |
| 70 | 66 |
| 71 return webViewImpl(); | 67 return webViewImpl(); |
| 72 } | 68 } |
| 73 | 69 |
| 70 WebViewImpl* initialize(const std::string& pageName) | |
| 71 { | |
| 72 return initialize(pageName, &m_client); | |
| 73 } | |
| 74 | |
| 74 static void configureSettings(WebSettings* settings) | 75 static void configureSettings(WebSettings* settings) |
| 75 { | 76 { |
| 76 settings->setJavaScriptEnabled(true); | 77 settings->setJavaScriptEnabled(true); |
| 77 settings->setAcceleratedCompositingEnabled(true); | 78 settings->setAcceleratedCompositingEnabled(true); |
| 78 settings->setPreferCompositingToLCDTextEnabled(true); | 79 settings->setPreferCompositingToLCDTextEnabled(true); |
| 79 // Android settings. | 80 // Android settings. |
| 80 settings->setViewportEnabled(true); | 81 settings->setViewportEnabled(true); |
| 81 settings->setViewportMetaEnabled(true); | 82 settings->setViewportMetaEnabled(true); |
| 82 settings->setShrinksViewportContentToFit(true); | 83 settings->setShrinksViewportContentToFit(true); |
| 83 settings->setMainFrameResizesAreOrientationChanges(true); | 84 settings->setMainFrameResizesAreOrientationChanges(true); |
| 84 } | 85 } |
| 85 | 86 |
| 86 void registerMockedHttpURLLoad(const std::string& fileName) | 87 void registerMockedHttpURLLoad(const std::string& fileName) |
| 87 { | 88 { |
| 88 URLTestHelpers::registerMockedURLFromBaseURL( | 89 URLTestHelpers::registerMockedURLFromBaseURL( |
| 89 WebString::fromUTF8(m_baseURL.c_str()), | 90 WebString::fromUTF8(m_baseURL.c_str()), |
| 90 WebString::fromUTF8(fileName.c_str())); | 91 WebString::fromUTF8(fileName.c_str())); |
| 91 } | 92 } |
| 92 | 93 |
| 93 void executeScript(const WebString& code) | 94 void executeScript(const WebString& code) |
| 94 { | 95 { |
| 95 mainWebFrame()->executeScript(WebScriptSource(code)); | 96 mainWebFrame()->executeScript(WebScriptSource(code)); |
| 96 mainWebFrame()->view()->updateAllLifecyclePhases(); | 97 mainWebFrame()->view()->updateAllLifecyclePhases(); |
| 97 runPendingTasks(); | 98 runPendingTasks(); |
| 98 } | 99 } |
| 99 | 100 |
| 100 WebGestureEvent generateEvent( | |
| 101 WebInputEvent::Type type, int deltaX = 0, int deltaY = 0) | |
| 102 { | |
| 103 WebGestureEvent event; | |
| 104 event.type = type; | |
| 105 event.sourceDevice = WebGestureDeviceTouchscreen; | |
| 106 event.x = 100; | |
| 107 event.y = 100; | |
| 108 if (type == WebInputEvent::GestureScrollUpdate) { | |
| 109 event.data.scrollUpdate.deltaX = deltaX; | |
| 110 event.data.scrollUpdate.deltaY = deltaY; | |
| 111 } | |
| 112 return event; | |
| 113 } | |
| 114 | |
| 115 void verticalScroll(float deltaY) | |
|
bokan
2016/08/30 20:37:19
This was unused
| |
| 116 { | |
| 117 webViewImpl()->handleInputEvent( | |
| 118 generateEvent(WebInputEvent::GestureScrollBegin)); | |
| 119 webViewImpl()->handleInputEvent( | |
| 120 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -deltaY)); | |
| 121 webViewImpl()->handleInputEvent( | |
| 122 generateEvent(WebInputEvent::GestureScrollEnd)); | |
| 123 } | |
| 124 | |
| 125 WebViewImpl* webViewImpl() const | 101 WebViewImpl* webViewImpl() const |
| 126 { | 102 { |
| 127 return m_helper.webView(); | 103 return m_helper.webView(); |
| 128 } | 104 } |
| 129 | 105 |
| 130 FrameHost& frameHost() const | 106 FrameHost& frameHost() const |
| 131 { | 107 { |
| 132 return m_helper.webView()->page()->frameHost(); | 108 return m_helper.webView()->page()->frameHost(); |
| 133 } | 109 } |
| 134 | 110 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 155 TopControls& topControls() const | 131 TopControls& topControls() const |
| 156 { | 132 { |
| 157 return frameHost().topControls(); | 133 return frameHost().topControls(); |
| 158 } | 134 } |
| 159 | 135 |
| 160 Element* effectiveRootScroller(Document* doc) const | 136 Element* effectiveRootScroller(Document* doc) const |
| 161 { | 137 { |
| 162 return doc->rootScrollerController()->effectiveRootScroller(); | 138 return doc->rootScrollerController()->effectiveRootScroller(); |
| 163 } | 139 } |
| 164 | 140 |
| 141 WebGestureEvent generateTouchGestureEvent( | |
| 142 WebInputEvent::Type type, | |
| 143 int deltaX = 0, | |
| 144 int deltaY = 0) | |
| 145 { | |
| 146 return generateGestureEvent( | |
| 147 type, WebGestureDeviceTouchscreen, deltaX, deltaY); | |
| 148 } | |
| 149 | |
| 150 WebGestureEvent generateWheelGestureEvent( | |
| 151 WebInputEvent::Type type, | |
| 152 int deltaX = 0, | |
| 153 int deltaY = 0) | |
| 154 { | |
| 155 return generateGestureEvent( | |
| 156 type, WebGestureDeviceTouchpad, deltaX, deltaY); | |
| 157 } | |
| 158 | |
| 165 protected: | 159 protected: |
| 160 WebGestureEvent generateGestureEvent( | |
| 161 WebInputEvent::Type type, | |
| 162 WebGestureDevice device, | |
| 163 int deltaX, | |
| 164 int deltaY) | |
| 165 { | |
| 166 WebGestureEvent event; | |
| 167 event.type = type; | |
| 168 event.sourceDevice = device; | |
| 169 event.x = 100; | |
| 170 event.y = 100; | |
| 171 if (type == WebInputEvent::GestureScrollUpdate) { | |
| 172 event.data.scrollUpdate.deltaX = deltaX; | |
| 173 event.data.scrollUpdate.deltaY = deltaY; | |
| 174 } | |
| 175 return event; | |
| 176 } | |
| 177 | |
| 166 std::string m_baseURL; | 178 std::string m_baseURL; |
| 167 RootScrollerTestWebViewClient m_client; | 179 FrameTestHelpers::TestWebViewClient m_client; |
| 168 FrameTestHelpers::WebViewHelper m_helper; | 180 FrameTestHelpers::WebViewHelper m_helper; |
| 169 RuntimeEnabledFeatures::Backup m_featuresBackup; | 181 RuntimeEnabledFeatures::Backup m_featuresBackup; |
| 170 }; | 182 }; |
| 171 | 183 |
| 172 // Test that no root scroller element is set if setRootScroller isn't called on | 184 // Test that no root scroller element is set if setRootScroller isn't called on |
| 173 // any elements. The document element should be the default effective root | 185 // any elements. The document element should be the default effective root |
| 174 // scroller. | 186 // scroller. |
| 175 TEST_F(RootScrollerTest, TestDefaultRootScroller) | 187 TEST_F(RootScrollerTest, TestDefaultRootScroller) |
| 176 { | 188 { |
| 177 initialize("overflow-scrolling.html"); | 189 initialize("overflow-scrolling.html"); |
| 178 | 190 |
| 179 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 191 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
| 180 | 192 |
| 181 Element* htmlElement = mainFrame()->document()->documentElement(); | 193 Element* htmlElement = mainFrame()->document()->documentElement(); |
| 182 EXPECT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document())); | 194 EXPECT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document())); |
| 183 } | 195 } |
| 184 | 196 |
| 197 class OverscrollTestWebViewClient : public FrameTestHelpers::TestWebViewClient { | |
| 198 public: | |
| 199 MOCK_METHOD4(didOverscroll, void(const WebFloatSize&, const WebFloatSize&, c onst WebFloatPoint&, const WebFloatSize&)); | |
| 200 }; | |
| 201 | |
| 185 // Tests that setting an element as the root scroller causes it to control url | 202 // Tests that setting an element as the root scroller causes it to control url |
| 186 // bar hiding and overscroll. | 203 // bar hiding and overscroll. |
| 187 TEST_F(RootScrollerTest, TestSetRootScroller) | 204 TEST_F(RootScrollerTest, TestSetRootScroller) |
| 188 { | 205 { |
| 189 initialize("root-scroller.html"); | 206 OverscrollTestWebViewClient client; |
| 207 initialize("root-scroller.html", &client); | |
| 190 | 208 |
| 191 Element* container = mainFrame()->document()->getElementById("container"); | 209 Element* container = mainFrame()->document()->getElementById("container"); |
| 192 TrackExceptionState exceptionState; | 210 TrackExceptionState exceptionState; |
| 193 mainFrame()->document()->setRootScroller(container, exceptionState); | 211 mainFrame()->document()->setRootScroller(container, exceptionState); |
| 194 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 212 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); |
| 195 | 213 |
| 196 // Content is 1000x1000, WebView size is 400x400 so max scroll is 600px. | 214 // Content is 1000x1000, WebView size is 400x400 so max scroll is 600px. |
| 197 double maximumScroll = 600; | 215 double maximumScroll = 600; |
| 198 | 216 |
| 199 webViewImpl()->handleInputEvent( | 217 webViewImpl()->handleInputEvent( |
| 200 generateEvent(WebInputEvent::GestureScrollBegin)); | 218 generateTouchGestureEvent(WebInputEvent::GestureScrollBegin)); |
| 201 | 219 |
| 202 { | 220 { |
| 203 // Scrolling over the #container DIV should cause the top controls to | 221 // Scrolling over the #container DIV should cause the top controls to |
| 204 // hide. | 222 // hide. |
| 205 EXPECT_FLOAT_EQ(1, topControls().shownRatio()); | 223 EXPECT_FLOAT_EQ(1, topControls().shownRatio()); |
| 206 webViewImpl()->handleInputEvent(generateEvent( | 224 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 207 WebInputEvent::GestureScrollUpdate, 0, -topControls().height())); | 225 WebInputEvent::GestureScrollUpdate, 0, -topControls().height())); |
| 208 EXPECT_FLOAT_EQ(0, topControls().shownRatio()); | 226 EXPECT_FLOAT_EQ(0, topControls().shownRatio()); |
| 209 } | 227 } |
| 210 | 228 |
| 211 { | 229 { |
| 212 // Make sure we're actually scrolling the DIV and not the FrameView. | 230 // Make sure we're actually scrolling the DIV and not the FrameView. |
| 213 webViewImpl()->handleInputEvent( | 231 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 214 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -100)); | 232 WebInputEvent::GestureScrollUpdate, 0, -100)); |
| 215 EXPECT_FLOAT_EQ(100, container->scrollTop()); | 233 EXPECT_FLOAT_EQ(100, container->scrollTop()); |
| 216 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); | 234 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); |
| 217 } | 235 } |
| 218 | 236 |
| 219 { | 237 { |
| 220 // Scroll 50 pixels past the end. Ensure we report the 50 pixels as | 238 // Scroll 50 pixels past the end. Ensure we report the 50 pixels as |
| 221 // overscroll. | 239 // overscroll. |
| 222 EXPECT_CALL(m_client, | 240 EXPECT_CALL(client, |
| 223 didOverscroll( | 241 didOverscroll( |
| 224 WebFloatSize(0, 50), | 242 WebFloatSize(0, 50), |
| 225 WebFloatSize(0, 50), | 243 WebFloatSize(0, 50), |
| 226 WebFloatPoint(100, 100), | 244 WebFloatPoint(100, 100), |
| 227 WebFloatSize())); | 245 WebFloatSize())); |
| 228 webViewImpl()->handleInputEvent( | 246 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 229 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -550)); | 247 WebInputEvent::GestureScrollUpdate, 0, -550)); |
| 230 EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop()); | 248 EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop()); |
| 231 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); | 249 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); |
| 232 Mock::VerifyAndClearExpectations(&m_client); | 250 Mock::VerifyAndClearExpectations(&client); |
| 233 } | 251 } |
| 234 | 252 |
| 235 { | 253 { |
| 236 // Continue the gesture overscroll. | 254 // Continue the gesture overscroll. |
| 237 EXPECT_CALL(m_client, | 255 EXPECT_CALL(client, |
| 238 didOverscroll( | 256 didOverscroll( |
| 239 WebFloatSize(0, 20), | 257 WebFloatSize(0, 20), |
| 240 WebFloatSize(0, 70), | 258 WebFloatSize(0, 70), |
| 241 WebFloatPoint(100, 100), | 259 WebFloatPoint(100, 100), |
| 242 WebFloatSize())); | 260 WebFloatSize())); |
| 243 webViewImpl()->handleInputEvent( | 261 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 244 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -20)); | 262 WebInputEvent::GestureScrollUpdate, 0, -20)); |
| 245 EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop()); | 263 EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop()); |
| 246 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); | 264 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); |
| 247 Mock::VerifyAndClearExpectations(&m_client); | 265 Mock::VerifyAndClearExpectations(&client); |
| 248 } | 266 } |
| 249 | 267 |
| 250 webViewImpl()->handleInputEvent( | 268 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 251 generateEvent(WebInputEvent::GestureScrollEnd)); | 269 WebInputEvent::GestureScrollEnd)); |
| 252 | 270 |
| 253 { | 271 { |
| 254 // Make sure a new gesture scroll still won't scroll the frameview and | 272 // Make sure a new gesture scroll still won't scroll the frameview and |
| 255 // overscrolls. | 273 // overscrolls. |
| 256 webViewImpl()->handleInputEvent( | 274 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 257 generateEvent(WebInputEvent::GestureScrollBegin)); | 275 WebInputEvent::GestureScrollBegin)); |
| 258 | 276 |
| 259 EXPECT_CALL(m_client, | 277 EXPECT_CALL(client, |
| 260 didOverscroll( | 278 didOverscroll( |
| 261 WebFloatSize(0, 30), | 279 WebFloatSize(0, 30), |
| 262 WebFloatSize(0, 30), | 280 WebFloatSize(0, 30), |
| 263 WebFloatPoint(100, 100), | 281 WebFloatPoint(100, 100), |
| 264 WebFloatSize())); | 282 WebFloatSize())); |
| 265 webViewImpl()->handleInputEvent( | 283 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 266 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -30)); | 284 WebInputEvent::GestureScrollUpdate, 0, -30)); |
| 267 EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop()); | 285 EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop()); |
| 268 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); | 286 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); |
| 269 Mock::VerifyAndClearExpectations(&m_client); | 287 Mock::VerifyAndClearExpectations(&client); |
| 270 | 288 |
| 271 webViewImpl()->handleInputEvent( | 289 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 272 generateEvent(WebInputEvent::GestureScrollEnd)); | 290 WebInputEvent::GestureScrollEnd)); |
| 273 } | 291 } |
| 274 | 292 |
| 275 { | 293 { |
| 276 // Scrolling up should show the top controls. | 294 // Scrolling up should show the top controls. |
| 277 webViewImpl()->handleInputEvent( | 295 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 278 generateEvent(WebInputEvent::GestureScrollBegin)); | 296 WebInputEvent::GestureScrollBegin)); |
| 279 | 297 |
| 280 EXPECT_FLOAT_EQ(0, topControls().shownRatio()); | 298 EXPECT_FLOAT_EQ(0, topControls().shownRatio()); |
| 281 webViewImpl()->handleInputEvent( | 299 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 282 generateEvent(WebInputEvent::GestureScrollUpdate, 0, 30)); | 300 WebInputEvent::GestureScrollUpdate, 0, 30)); |
| 283 EXPECT_FLOAT_EQ(0.6, topControls().shownRatio()); | 301 EXPECT_FLOAT_EQ(0.6, topControls().shownRatio()); |
| 284 | 302 |
| 285 webViewImpl()->handleInputEvent( | 303 webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
| 286 generateEvent(WebInputEvent::GestureScrollEnd)); | 304 WebInputEvent::GestureScrollEnd)); |
| 287 } | 305 } |
| 306 | |
| 307 // Reset manually to avoid lifetime issues with custom WebViewClient. | |
| 308 m_helper.reset(); | |
| 288 } | 309 } |
| 289 | 310 |
| 290 // Tests that removing the element that is the root scroller from the DOM tree | 311 // Tests that removing the element that is the root scroller from the DOM tree |
| 291 // doesn't remove it as the root scroller but it does change the effective root | 312 // doesn't remove it as the root scroller but it does change the effective root |
| 292 // scroller. | 313 // scroller. |
| 293 TEST_F(RootScrollerTest, TestRemoveRootScrollerFromDom) | 314 TEST_F(RootScrollerTest, TestRemoveRootScrollerFromDom) |
| 294 { | 315 { |
| 295 initialize("root-scroller.html"); | 316 initialize("root-scroller.html"); |
| 296 | 317 |
| 297 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 318 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 EXPECT_EQ(iframe, | 516 EXPECT_EQ(iframe, |
| 496 mainFrame()->document()->rootScrollerController() | 517 mainFrame()->document()->rootScrollerController() |
| 497 ->effectiveRootScroller()); | 518 ->effectiveRootScroller()); |
| 498 } | 519 } |
| 499 } | 520 } |
| 500 | 521 |
| 501 // Tests that the global root scroller is correctly calculated when getting the | 522 // Tests that the global root scroller is correctly calculated when getting the |
| 502 // root scroller layer and that the viewport apply scroll is set on it. | 523 // root scroller layer and that the viewport apply scroll is set on it. |
| 503 TEST_F(RootScrollerTest, SetRootScrollerIframeUsesCorrectLayerAndCallback) | 524 TEST_F(RootScrollerTest, SetRootScrollerIframeUsesCorrectLayerAndCallback) |
| 504 { | 525 { |
| 526 // TODO(bokan): The expectation and actual in the checks here are backwards. | |
| 505 initialize("root-scroller-iframe.html"); | 527 initialize("root-scroller-iframe.html"); |
| 506 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 528 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
| 507 | 529 |
| 508 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( | 530 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
| 509 mainFrame()->document()->getElementById("iframe")); | 531 mainFrame()->document()->getElementById("iframe")); |
| 510 Element* container = | 532 Element* container = |
| 511 iframe->contentDocument()->getElementById("container"); | 533 iframe->contentDocument()->getElementById("container"); |
| 512 | 534 |
| 513 RootScrollerController* mainController = | 535 RootScrollerController* mainController = |
| 514 mainFrame()->document()->rootScrollerController(); | 536 mainFrame()->document()->rootScrollerController(); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 626 // Try to set the root scroller of the child document to be the | 648 // Try to set the root scroller of the child document to be the |
| 627 // <body> element of the parent document. | 649 // <body> element of the parent document. |
| 628 iframe->contentDocument()->setRootScroller( | 650 iframe->contentDocument()->setRootScroller( |
| 629 body, | 651 body, |
| 630 exceptionState); | 652 exceptionState); |
| 631 | 653 |
| 632 EXPECT_EQ(body, iframe->contentDocument()->rootScroller()); | 654 EXPECT_EQ(body, iframe->contentDocument()->rootScroller()); |
| 633 } | 655 } |
| 634 } | 656 } |
| 635 | 657 |
| 658 // Do a basic sanity check that setting as root scroller an iframe that's remote | |
| 659 // doesn't crash or otherwise fail catastrophically. | |
| 660 TEST_F(RootScrollerTest, RemoteIFrame) | |
| 661 { | |
| 662 FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient; | |
| 663 initialize("root-scroller-iframe.html"); | |
| 664 | |
| 665 // Initialization: Replace the iframe with a remote frame. | |
| 666 { | |
| 667 WebRemoteFrame* remoteFrame = WebRemoteFrame::create( | |
| 668 WebTreeScopeType::Document, &remoteFrameClient); | |
| 669 WebFrame* childFrame = mainWebFrame()->firstChild(); | |
| 670 childFrame->swap(remoteFrame); | |
| 671 } | |
| 672 | |
| 673 // Set the root scroller in the local main frame to the iframe (which is | |
| 674 // remote). | |
| 675 { | |
| 676 Element* iframe = mainFrame()->document()->getElementById("iframe"); | |
| 677 NonThrowableExceptionState nonThrow; | |
| 678 mainFrame()->document()->setRootScroller(iframe, nonThrow); | |
| 679 EXPECT_EQ(iframe, mainFrame()->document()->rootScroller()); | |
| 680 } | |
| 681 | |
| 682 // Reset explicitly to prevent lifetime issues with the RemoteFrameClient. | |
| 683 m_helper.reset(); | |
| 684 } | |
| 685 | |
| 686 // Do a basic sanity check that the scrolling and root scroller machinery | |
| 687 // doesn't fail catastrophically in site isolation when the main frame is | |
| 688 // remote. Setting a root scroller in OOPIF isn't implemented yet but we should | |
| 689 // still scroll as before and not crash. | |
| 690 TEST_F(RootScrollerTest, RemoteMainFrame) | |
| 691 { | |
| 692 FrameTestHelpers::TestWebRemoteFrameClient remoteClient; | |
| 693 FrameTestHelpers::TestWebWidgetClient webWidgetClient; | |
| 694 WebFrameWidget* widget; | |
| 695 WebLocalFrameImpl* localFrame; | |
| 696 | |
| 697 initialize("root-scroller-iframe.html"); | |
| 698 | |
| 699 // Initialization: Set the main frame to be a RemoteFrame and add a local | |
| 700 // child. | |
| 701 { | |
| 702 webViewImpl()->setMainFrame(remoteClient.frame()); | |
| 703 WebRemoteFrame* root = webViewImpl()->mainFrame()->toWebRemoteFrame(); | |
| 704 root->setReplicatedOrigin(SecurityOrigin::createUnique()); | |
| 705 WebFrameOwnerProperties properties; | |
| 706 localFrame = FrameTestHelpers::createLocalChild( | |
| 707 root, "frameName", nullptr, nullptr, nullptr, properties); | |
| 708 | |
| 709 widget = WebFrameWidget::create(&webWidgetClient, localFrame); | |
|
lfg
2016/08/31 15:51:19
FrameTestHelpers::createLocalChild() already creat
bokan
2016/09/02 20:40:22
Done.
| |
| 710 FrameTestHelpers::loadFrame( | |
| 711 localFrame, m_baseURL + "root-scroller-child.html"); | |
| 712 widget->resize(WebSize(400, 400)); | |
| 713 } | |
| 714 | |
| 715 Document* document = localFrame->frameView()->frame().document(); | |
| 716 Element* container = document->getElementById("container"); | |
| 717 | |
| 718 // Try scrolling in the iframe. | |
| 719 { | |
| 720 widget->handleInputEvent(generateWheelGestureEvent( | |
| 721 WebInputEvent::GestureScrollBegin)); | |
| 722 widget->handleInputEvent(generateWheelGestureEvent( | |
| 723 WebInputEvent::GestureScrollUpdate, 0, -100)); | |
| 724 widget->handleInputEvent(generateWheelGestureEvent( | |
| 725 WebInputEvent::GestureScrollEnd)); | |
| 726 EXPECT_EQ(100, container->scrollTop()); | |
| 727 } | |
| 728 | |
| 729 // Set the container Element as the root scroller. | |
| 730 { | |
| 731 NonThrowableExceptionState nonThrow; | |
| 732 document->setRootScroller(container, nonThrow); | |
| 733 EXPECT_EQ(container, document->rootScroller()); | |
| 734 } | |
| 735 | |
| 736 // Try scrolling in the iframe now that it has a root scroller set. | |
| 737 { | |
| 738 widget->handleInputEvent(generateWheelGestureEvent( | |
| 739 WebInputEvent::GestureScrollBegin)); | |
| 740 widget->handleInputEvent(generateWheelGestureEvent( | |
| 741 WebInputEvent::GestureScrollUpdate, 0, -100)); | |
| 742 widget->handleInputEvent(generateWheelGestureEvent( | |
| 743 WebInputEvent::GestureScrollEnd)); | |
| 744 | |
| 745 // TODO(bokan): This doesn't work right now because we notice in | |
| 746 // Element::nativeApplyScroll that the container is the | |
| 747 // effectiveRootScroller but the only way we expect to get to | |
| 748 // nativeApplyScroll is if the effective scroller had its applyScroll | |
| 749 // ViewportScrollCallback removed. Keep the scrolls to guard crashes | |
| 750 // but the expectations on when a ViewportScrollCallback have changed | |
| 751 // and should be updated. | |
| 752 // EXPECT_EQ(200, container->scrollTop()); | |
| 753 } | |
| 754 | |
| 755 // Reset explicitly to prevent lifetime issues with the RemoteFrameClient. | |
| 756 m_helper.reset(); | |
| 757 } | |
| 758 | |
| 636 } // namespace | 759 } // namespace |
| 637 | 760 |
| 638 } // namespace blink | 761 } // namespace blink |
| OLD | NEW |