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) | |
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 FrameTestHelpers::loadFrame( |
| 710 localFrame, m_baseURL + "root-scroller-child.html"); |
| 711 widget = localFrame->frameWidget(); |
| 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 |