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 "platform/testing/URLTestHelpers.h" | 12 #include "platform/testing/URLTestHelpers.h" |
12 #include "platform/testing/UnitTestHelpers.h" | 13 #include "platform/testing/UnitTestHelpers.h" |
13 #include "public/platform/Platform.h" | 14 #include "public/platform/Platform.h" |
14 #include "public/platform/WebURLLoaderMockFactory.h" | 15 #include "public/platform/WebURLLoaderMockFactory.h" |
15 #include "public/web/WebCache.h" | 16 #include "public/web/WebCache.h" |
16 #include "public/web/WebConsoleMessage.h" | 17 #include "public/web/WebConsoleMessage.h" |
17 #include "public/web/WebScriptSource.h" | 18 #include "public/web/WebScriptSource.h" |
18 #include "public/web/WebSettings.h" | 19 #include "public/web/WebSettings.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
20 #include "web/WebLocalFrameImpl.h" | 21 #include "web/WebLocalFrameImpl.h" |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 195 |
195 // Content is 1000x1000, WebView size is 400x400 so max scroll is 600px. | 196 // Content is 1000x1000, WebView size is 400x400 so max scroll is 600px. |
196 double maximumScroll = 600; | 197 double maximumScroll = 600; |
197 | 198 |
198 webViewImpl()->handleInputEvent( | 199 webViewImpl()->handleInputEvent( |
199 generateEvent(WebInputEvent::GestureScrollBegin)); | 200 generateEvent(WebInputEvent::GestureScrollBegin)); |
200 | 201 |
201 { | 202 { |
202 // Scrolling over the #container DIV should cause the top controls to | 203 // Scrolling over the #container DIV should cause the top controls to |
203 // hide. | 204 // hide. |
204 ASSERT_FLOAT_EQ(1, topControls().shownRatio()); | 205 EXPECT_FLOAT_EQ(1, topControls().shownRatio()); |
205 webViewImpl()->handleInputEvent(generateEvent( | 206 webViewImpl()->handleInputEvent(generateEvent( |
206 WebInputEvent::GestureScrollUpdate, 0, -topControls().height())); | 207 WebInputEvent::GestureScrollUpdate, 0, -topControls().height())); |
207 ASSERT_FLOAT_EQ(0, topControls().shownRatio()); | 208 EXPECT_FLOAT_EQ(0, topControls().shownRatio()); |
208 } | 209 } |
209 | 210 |
210 { | 211 { |
211 // Make sure we're actually scrolling the DIV and not the FrameView. | 212 // Make sure we're actually scrolling the DIV and not the FrameView. |
212 webViewImpl()->handleInputEvent( | 213 webViewImpl()->handleInputEvent( |
213 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -100)); | 214 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -100)); |
214 ASSERT_FLOAT_EQ(100, container->scrollTop()); | 215 EXPECT_FLOAT_EQ(100, container->scrollTop()); |
215 ASSERT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); | 216 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); |
216 } | 217 } |
217 | 218 |
218 { | 219 { |
219 // Scroll 50 pixels past the end. Ensure we report the 50 pixels as | 220 // Scroll 50 pixels past the end. Ensure we report the 50 pixels as |
220 // overscroll. | 221 // overscroll. |
221 EXPECT_CALL(m_client, | 222 EXPECT_CALL(m_client, |
222 didOverscroll( | 223 didOverscroll( |
223 WebFloatSize(0, 50), | 224 WebFloatSize(0, 50), |
224 WebFloatSize(0, 50), | 225 WebFloatSize(0, 50), |
225 WebFloatPoint(100, 100), | 226 WebFloatPoint(100, 100), |
226 WebFloatSize())); | 227 WebFloatSize())); |
227 webViewImpl()->handleInputEvent( | 228 webViewImpl()->handleInputEvent( |
228 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -550)); | 229 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -550)); |
229 ASSERT_FLOAT_EQ(maximumScroll, container->scrollTop()); | 230 EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop()); |
230 ASSERT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); | 231 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); |
231 Mock::VerifyAndClearExpectations(&m_client); | 232 Mock::VerifyAndClearExpectations(&m_client); |
232 } | 233 } |
233 | 234 |
234 { | 235 { |
235 // Continue the gesture overscroll. | 236 // Continue the gesture overscroll. |
236 EXPECT_CALL(m_client, | 237 EXPECT_CALL(m_client, |
237 didOverscroll( | 238 didOverscroll( |
238 WebFloatSize(0, 20), | 239 WebFloatSize(0, 20), |
239 WebFloatSize(0, 70), | 240 WebFloatSize(0, 70), |
240 WebFloatPoint(100, 100), | 241 WebFloatPoint(100, 100), |
241 WebFloatSize())); | 242 WebFloatSize())); |
242 webViewImpl()->handleInputEvent( | 243 webViewImpl()->handleInputEvent( |
243 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -20)); | 244 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -20)); |
244 ASSERT_FLOAT_EQ(maximumScroll, container->scrollTop()); | 245 EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop()); |
245 ASSERT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); | 246 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); |
246 Mock::VerifyAndClearExpectations(&m_client); | 247 Mock::VerifyAndClearExpectations(&m_client); |
247 } | 248 } |
248 | 249 |
249 webViewImpl()->handleInputEvent( | 250 webViewImpl()->handleInputEvent( |
250 generateEvent(WebInputEvent::GestureScrollEnd)); | 251 generateEvent(WebInputEvent::GestureScrollEnd)); |
251 | 252 |
252 { | 253 { |
253 // Make sure a new gesture scroll still won't scroll the frameview and | 254 // Make sure a new gesture scroll still won't scroll the frameview and |
254 // overscrolls. | 255 // overscrolls. |
255 webViewImpl()->handleInputEvent( | 256 webViewImpl()->handleInputEvent( |
256 generateEvent(WebInputEvent::GestureScrollBegin)); | 257 generateEvent(WebInputEvent::GestureScrollBegin)); |
257 | 258 |
258 EXPECT_CALL(m_client, | 259 EXPECT_CALL(m_client, |
259 didOverscroll( | 260 didOverscroll( |
260 WebFloatSize(0, 30), | 261 WebFloatSize(0, 30), |
261 WebFloatSize(0, 30), | 262 WebFloatSize(0, 30), |
262 WebFloatPoint(100, 100), | 263 WebFloatPoint(100, 100), |
263 WebFloatSize())); | 264 WebFloatSize())); |
264 webViewImpl()->handleInputEvent( | 265 webViewImpl()->handleInputEvent( |
265 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -30)); | 266 generateEvent(WebInputEvent::GestureScrollUpdate, 0, -30)); |
266 ASSERT_FLOAT_EQ(maximumScroll, container->scrollTop()); | 267 EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop()); |
267 ASSERT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); | 268 EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y()); |
268 Mock::VerifyAndClearExpectations(&m_client); | 269 Mock::VerifyAndClearExpectations(&m_client); |
269 | 270 |
270 webViewImpl()->handleInputEvent( | 271 webViewImpl()->handleInputEvent( |
271 generateEvent(WebInputEvent::GestureScrollEnd)); | 272 generateEvent(WebInputEvent::GestureScrollEnd)); |
272 } | 273 } |
273 | 274 |
274 { | 275 { |
275 // Scrolling up should show the top controls. | 276 // Scrolling up should show the top controls. |
276 webViewImpl()->handleInputEvent( | 277 webViewImpl()->handleInputEvent( |
277 generateEvent(WebInputEvent::GestureScrollBegin)); | 278 generateEvent(WebInputEvent::GestureScrollBegin)); |
278 | 279 |
279 ASSERT_FLOAT_EQ(0, topControls().shownRatio()); | 280 EXPECT_FLOAT_EQ(0, topControls().shownRatio()); |
280 webViewImpl()->handleInputEvent( | 281 webViewImpl()->handleInputEvent( |
281 generateEvent(WebInputEvent::GestureScrollUpdate, 0, 30)); | 282 generateEvent(WebInputEvent::GestureScrollUpdate, 0, 30)); |
282 ASSERT_FLOAT_EQ(0.6, topControls().shownRatio()); | 283 EXPECT_FLOAT_EQ(0.6, topControls().shownRatio()); |
283 | 284 |
284 webViewImpl()->handleInputEvent( | 285 webViewImpl()->handleInputEvent( |
285 generateEvent(WebInputEvent::GestureScrollEnd)); | 286 generateEvent(WebInputEvent::GestureScrollEnd)); |
286 } | 287 } |
287 } | 288 } |
288 | 289 |
289 // Tests that removing the element that is the root scroller from the DOM tree | 290 // Tests that removing the element that is the root scroller from the DOM tree |
290 // doesn't remove it as the root scroller but it does change the effective root | 291 // doesn't remove it as the root scroller but it does change the effective root |
291 // scroller. | 292 // scroller. |
292 TEST_F(RootScrollerTest, TestRemoveRootScrollerFromDom) | 293 TEST_F(RootScrollerTest, TestRemoveRootScrollerFromDom) |
293 { | 294 { |
294 initialize("root-scroller.html"); | 295 initialize("root-scroller.html"); |
295 | 296 |
296 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 297 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
297 | 298 |
298 Element* container = mainFrame()->document()->getElementById("container"); | 299 Element* container = mainFrame()->document()->getElementById("container"); |
299 TrackExceptionState exceptionState; | 300 TrackExceptionState exceptionState; |
300 mainFrame()->document()->setRootScroller(container, exceptionState); | 301 mainFrame()->document()->setRootScroller(container, exceptionState); |
301 | 302 |
302 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 303 EXPECT_EQ(container, mainFrame()->document()->rootScroller()); |
303 ASSERT_EQ(container, effectiveRootScroller(mainFrame()->document())); | 304 EXPECT_EQ(container, effectiveRootScroller(mainFrame()->document())); |
304 | 305 |
305 mainFrame()->document()->body()->removeChild(container); | 306 mainFrame()->document()->body()->removeChild(container); |
306 mainFrameView()->updateAllLifecyclePhases(); | 307 mainFrameView()->updateAllLifecyclePhases(); |
307 | 308 |
308 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 309 EXPECT_EQ(container, mainFrame()->document()->rootScroller()); |
309 ASSERT_NE(container, effectiveRootScroller(mainFrame()->document())); | 310 EXPECT_NE(container, effectiveRootScroller(mainFrame()->document())); |
310 } | 311 } |
311 | 312 |
312 // Tests that setting an element that isn't a valid scroller as the root | 313 // Tests that setting an element that isn't a valid scroller as the root |
313 // scroller doesn't change the effective root scroller. | 314 // scroller doesn't change the effective root scroller. |
314 TEST_F(RootScrollerTest, TestSetRootScrollerOnInvalidElement) | 315 TEST_F(RootScrollerTest, TestSetRootScrollerOnInvalidElement) |
315 { | 316 { |
316 initialize("root-scroller.html"); | 317 initialize("root-scroller.html"); |
317 | 318 |
318 { | 319 { |
319 // Set to a non-block element. Should be rejected and a console message | 320 // Set to a non-block element. Should be rejected and a console message |
320 // logged. | 321 // logged. |
321 Element* element = mainFrame()->document()->getElementById("nonBlock"); | 322 Element* element = mainFrame()->document()->getElementById("nonBlock"); |
322 TrackExceptionState exceptionState; | 323 TrackExceptionState exceptionState; |
323 mainFrame()->document()->setRootScroller(element, exceptionState); | 324 mainFrame()->document()->setRootScroller(element, exceptionState); |
324 mainFrameView()->updateAllLifecyclePhases(); | 325 mainFrameView()->updateAllLifecyclePhases(); |
325 ASSERT_EQ(element, mainFrame()->document()->rootScroller()); | 326 EXPECT_EQ(element, mainFrame()->document()->rootScroller()); |
326 ASSERT_NE(element, effectiveRootScroller(mainFrame()->document())); | 327 EXPECT_NE(element, effectiveRootScroller(mainFrame()->document())); |
327 } | 328 } |
328 | 329 |
329 { | 330 { |
330 // Set to an element with no size. | 331 // Set to an element with no size. |
331 Element* element = mainFrame()->document()->getElementById("empty"); | 332 Element* element = mainFrame()->document()->getElementById("empty"); |
332 TrackExceptionState exceptionState; | 333 TrackExceptionState exceptionState; |
333 mainFrame()->document()->setRootScroller(element, exceptionState); | 334 mainFrame()->document()->setRootScroller(element, exceptionState); |
334 mainFrameView()->updateAllLifecyclePhases(); | 335 mainFrameView()->updateAllLifecyclePhases(); |
335 ASSERT_EQ(element, mainFrame()->document()->rootScroller()); | 336 EXPECT_EQ(element, mainFrame()->document()->rootScroller()); |
336 ASSERT_NE(element, effectiveRootScroller(mainFrame()->document())); | 337 EXPECT_NE(element, effectiveRootScroller(mainFrame()->document())); |
337 } | 338 } |
338 } | 339 } |
339 | 340 |
340 // Test that the effective root scroller resets to the default element when the | 341 // Test that the effective root scroller resets to the default element when the |
341 // current root scroller element becomes invalid as a scroller. | 342 // current root scroller element becomes invalid as a scroller. |
342 TEST_F(RootScrollerTest, TestRootScrollerBecomesInvalid) | 343 TEST_F(RootScrollerTest, TestRootScrollerBecomesInvalid) |
343 { | 344 { |
344 initialize("root-scroller.html"); | 345 initialize("root-scroller.html"); |
345 | 346 |
346 Element* htmlElement = mainFrame()->document()->documentElement(); | 347 Element* htmlElement = mainFrame()->document()->documentElement(); |
347 Element* container = mainFrame()->document()->getElementById("container"); | 348 Element* container = mainFrame()->document()->getElementById("container"); |
348 TrackExceptionState exceptionState; | 349 TrackExceptionState exceptionState; |
349 | 350 |
350 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 351 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
351 ASSERT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document())); | 352 ASSERT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document())); |
352 | 353 |
353 { | 354 { |
354 mainFrame()->document()->setRootScroller(container, exceptionState); | 355 mainFrame()->document()->setRootScroller(container, exceptionState); |
355 mainFrameView()->updateAllLifecyclePhases(); | 356 mainFrameView()->updateAllLifecyclePhases(); |
356 | 357 |
357 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 358 EXPECT_EQ(container, mainFrame()->document()->rootScroller()); |
358 ASSERT_EQ(container, effectiveRootScroller(mainFrame()->document())); | 359 EXPECT_EQ(container, effectiveRootScroller(mainFrame()->document())); |
359 | 360 |
360 executeScript( | 361 executeScript( |
361 "document.querySelector('#container').style.display = 'inline'"); | 362 "document.querySelector('#container').style.display = 'inline'"); |
362 mainFrameView()->updateAllLifecyclePhases(); | 363 mainFrameView()->updateAllLifecyclePhases(); |
363 | 364 |
364 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 365 EXPECT_EQ(container, mainFrame()->document()->rootScroller()); |
365 ASSERT_EQ(htmlElement, | 366 EXPECT_EQ(htmlElement, |
366 effectiveRootScroller(mainFrame()->document())); | 367 effectiveRootScroller(mainFrame()->document())); |
367 } | 368 } |
368 | 369 |
369 executeScript( | 370 executeScript( |
370 "document.querySelector('#container').style.display = 'block'"); | 371 "document.querySelector('#container').style.display = 'block'"); |
371 mainFrame()->document()->setRootScroller(nullptr, exceptionState); | 372 mainFrame()->document()->setRootScroller(nullptr, exceptionState); |
372 mainFrameView()->updateAllLifecyclePhases(); | 373 mainFrameView()->updateAllLifecyclePhases(); |
373 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 374 EXPECT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
374 ASSERT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document())); | 375 EXPECT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document())); |
375 | 376 |
376 { | 377 { |
377 mainFrame()->document()->setRootScroller(container, exceptionState); | 378 mainFrame()->document()->setRootScroller(container, exceptionState); |
378 mainFrameView()->updateAllLifecyclePhases(); | 379 mainFrameView()->updateAllLifecyclePhases(); |
379 | 380 |
380 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 381 EXPECT_EQ(container, mainFrame()->document()->rootScroller()); |
381 ASSERT_EQ(container, effectiveRootScroller(mainFrame()->document())); | 382 EXPECT_EQ(container, effectiveRootScroller(mainFrame()->document())); |
382 | 383 |
383 executeScript( | 384 executeScript( |
384 "document.querySelector('#container').style.width = '98%'"); | 385 "document.querySelector('#container').style.width = '98%'"); |
385 mainFrameView()->updateAllLifecyclePhases(); | 386 mainFrameView()->updateAllLifecyclePhases(); |
386 | 387 |
387 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 388 EXPECT_EQ(container, mainFrame()->document()->rootScroller()); |
388 ASSERT_EQ(htmlElement, | 389 EXPECT_EQ(htmlElement, |
389 effectiveRootScroller(mainFrame()->document())); | 390 effectiveRootScroller(mainFrame()->document())); |
390 } | 391 } |
391 } | 392 } |
392 | 393 |
393 // Tests that setting the root scroller of the top document to an element that | 394 // Tests that setting the root scroller of the top document to an element that |
394 // belongs to a nested document works. | 395 // belongs to a nested document works. |
395 TEST_F(RootScrollerTest, TestSetRootScrollerOnElementInIframe) | 396 TEST_F(RootScrollerTest, TestSetRootScrollerOnElementInIframe) |
396 { | 397 { |
397 initialize("root-scroller-iframe.html"); | 398 initialize("root-scroller-iframe.html"); |
398 | 399 |
399 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 400 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
400 | 401 |
401 { | 402 { |
402 // Trying to set an element from a nested document should fail. | 403 // Trying to set an element from a nested document should fail. |
403 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( | 404 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
404 mainFrame()->document()->getElementById("iframe")); | 405 mainFrame()->document()->getElementById("iframe")); |
405 Element* innerContainer = | 406 Element* innerContainer = |
406 iframe->contentDocument()->getElementById("container"); | 407 iframe->contentDocument()->getElementById("container"); |
407 | 408 |
408 TrackExceptionState exceptionState; | 409 TrackExceptionState exceptionState; |
409 mainFrame()->document()->setRootScroller( | 410 mainFrame()->document()->setRootScroller( |
410 innerContainer, | 411 innerContainer, |
411 exceptionState); | 412 exceptionState); |
412 mainFrameView()->updateAllLifecyclePhases(); | 413 mainFrameView()->updateAllLifecyclePhases(); |
413 | 414 |
414 ASSERT_EQ(innerContainer, mainFrame()->document()->rootScroller()); | 415 EXPECT_EQ(innerContainer, mainFrame()->document()->rootScroller()); |
415 ASSERT_EQ(innerContainer, | 416 EXPECT_EQ(innerContainer, |
416 effectiveRootScroller(mainFrame()->document())); | 417 effectiveRootScroller(mainFrame()->document())); |
417 } | 418 } |
418 | 419 |
419 { | 420 { |
420 // Setting the iframe itself should also work. | 421 // Setting the iframe itself should also work. |
421 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( | 422 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
422 mainFrame()->document()->getElementById("iframe")); | 423 mainFrame()->document()->getElementById("iframe")); |
423 | 424 |
424 TrackExceptionState exceptionState; | 425 TrackExceptionState exceptionState; |
425 mainFrame()->document()->setRootScroller(iframe, exceptionState); | 426 mainFrame()->document()->setRootScroller(iframe, exceptionState); |
426 mainFrameView()->updateAllLifecyclePhases(); | 427 mainFrameView()->updateAllLifecyclePhases(); |
427 | 428 |
428 ASSERT_EQ(iframe, mainFrame()->document()->rootScroller()); | 429 EXPECT_EQ(iframe, mainFrame()->document()->rootScroller()); |
429 ASSERT_EQ(iframe, effectiveRootScroller(mainFrame()->document())); | 430 EXPECT_EQ(iframe, effectiveRootScroller(mainFrame()->document())); |
430 } | 431 } |
431 } | 432 } |
432 | 433 |
433 // Tests that setting a valid element as the root scroller on a document within | 434 // Tests that setting a valid element as the root scroller on a document within |
434 // an iframe works as expected. | 435 // an iframe works as expected. |
435 TEST_F(RootScrollerTest, TestRootScrollerWithinIframe) | 436 TEST_F(RootScrollerTest, TestRootScrollerWithinIframe) |
436 { | 437 { |
437 initialize("root-scroller-iframe.html"); | 438 initialize("root-scroller-iframe.html"); |
438 | 439 |
439 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 440 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
440 | 441 |
441 { | 442 { |
442 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( | 443 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
443 mainFrame()->document()->getElementById("iframe")); | 444 mainFrame()->document()->getElementById("iframe")); |
444 | 445 |
445 ASSERT_EQ(iframe->contentDocument()->documentElement(), | 446 EXPECT_EQ(iframe->contentDocument()->documentElement(), |
446 effectiveRootScroller(iframe->contentDocument())); | 447 effectiveRootScroller(iframe->contentDocument())); |
447 | 448 |
448 Element* innerContainer = | 449 Element* innerContainer = |
449 iframe->contentDocument()->getElementById("container"); | 450 iframe->contentDocument()->getElementById("container"); |
450 TrackExceptionState exceptionState; | 451 TrackExceptionState exceptionState; |
451 iframe->contentDocument()->setRootScroller( | 452 iframe->contentDocument()->setRootScroller( |
452 innerContainer, | 453 innerContainer, |
453 exceptionState); | 454 exceptionState); |
454 mainFrameView()->updateAllLifecyclePhases(); | 455 mainFrameView()->updateAllLifecyclePhases(); |
455 | 456 |
456 ASSERT_EQ(innerContainer, iframe->contentDocument()->rootScroller()); | 457 EXPECT_EQ(innerContainer, iframe->contentDocument()->rootScroller()); |
457 ASSERT_EQ(innerContainer, | 458 EXPECT_EQ(innerContainer, |
458 effectiveRootScroller(iframe->contentDocument())); | 459 effectiveRootScroller(iframe->contentDocument())); |
459 } | 460 } |
460 } | 461 } |
461 | 462 |
| 463 // Tests that setting an iframe as the root scroller makes the iframe the |
| 464 // effective root scroller in the parent frame. |
| 465 TEST_F(RootScrollerTest, SetRootScrollerIframeBecomesEffective) |
| 466 { |
| 467 initialize("root-scroller-iframe.html"); |
| 468 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
| 469 |
| 470 { |
| 471 NonThrowableExceptionState nonThrow; |
| 472 |
| 473 // Try to set the root scroller in the main frame to be the iframe |
| 474 // element. |
| 475 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
| 476 mainFrame()->document()->getElementById("iframe")); |
| 477 |
| 478 mainFrame()->document()->setRootScroller(iframe, nonThrow); |
| 479 |
| 480 EXPECT_EQ(iframe, mainFrame()->document()->rootScroller()); |
| 481 EXPECT_EQ(iframe, |
| 482 mainFrame()->document()->rootScrollerController() |
| 483 ->effectiveRootScroller()); |
| 484 |
| 485 Element* container = |
| 486 iframe->contentDocument()->getElementById("container"); |
| 487 |
| 488 iframe->contentDocument()->setRootScroller(container, nonThrow); |
| 489 |
| 490 EXPECT_EQ(container, iframe->contentDocument()->rootScroller()); |
| 491 EXPECT_EQ(container, |
| 492 iframe->contentDocument()->rootScrollerController() |
| 493 ->effectiveRootScroller()); |
| 494 EXPECT_EQ(iframe, mainFrame()->document()->rootScroller()); |
| 495 EXPECT_EQ(iframe, |
| 496 mainFrame()->document()->rootScrollerController() |
| 497 ->effectiveRootScroller()); |
| 498 } |
| 499 } |
| 500 |
| 501 // 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. |
| 503 TEST_F(RootScrollerTest, SetRootScrollerIframeUsesCorrectLayerAndCallback) |
| 504 { |
| 505 initialize("root-scroller-iframe.html"); |
| 506 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
| 507 |
| 508 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
| 509 mainFrame()->document()->getElementById("iframe")); |
| 510 Element* container = |
| 511 iframe->contentDocument()->getElementById("container"); |
| 512 |
| 513 RootScrollerController* mainController = |
| 514 mainFrame()->document()->rootScrollerController(); |
| 515 |
| 516 NonThrowableExceptionState nonThrow; |
| 517 |
| 518 // No root scroller set, the documentElement should be the effective root |
| 519 // and the main FrameView's scroll layer should be the layer to use. |
| 520 { |
| 521 EXPECT_EQ( |
| 522 mainController->rootScrollerLayer(), |
| 523 mainFrameView()->layerForScrolling()); |
| 524 EXPECT_TRUE(mainController->isViewportScrollCallback( |
| 525 mainFrame()->document()->documentElement()->getApplyScroll())); |
| 526 } |
| 527 |
| 528 // Set a root scroller in the iframe. Since the main document didn't set a |
| 529 // root scroller, the global root scroller shouldn't change. |
| 530 { |
| 531 |
| 532 iframe->contentDocument()->setRootScroller(container, nonThrow); |
| 533 |
| 534 EXPECT_EQ( |
| 535 mainController->rootScrollerLayer(), |
| 536 mainFrameView()->layerForScrolling()); |
| 537 EXPECT_TRUE(mainController->isViewportScrollCallback( |
| 538 mainFrame()->document()->documentElement()->getApplyScroll())); |
| 539 } |
| 540 |
| 541 // Setting the iframe as the root scroller in the main frame should now |
| 542 // link the root scrollers so the container should now be the global root |
| 543 // scroller. |
| 544 { |
| 545 mainFrame()->document()->setRootScroller(iframe, nonThrow); |
| 546 |
| 547 ScrollableArea* containerScroller = |
| 548 static_cast<PaintInvalidationCapableScrollableArea*>( |
| 549 toLayoutBox(container->layoutObject())->getScrollableArea()); |
| 550 |
| 551 EXPECT_EQ( |
| 552 mainController->rootScrollerLayer(), |
| 553 containerScroller->layerForScrolling()); |
| 554 EXPECT_FALSE(mainController->isViewportScrollCallback( |
| 555 mainFrame()->document()->documentElement()->getApplyScroll())); |
| 556 EXPECT_TRUE(mainController->isViewportScrollCallback( |
| 557 container->getApplyScroll())); |
| 558 } |
| 559 |
| 560 // Unsetting the root scroller in the iframe should reset its effective |
| 561 // root scroller to the iframe's documentElement and thus the iframe's |
| 562 // documentElement becomes the global root scroller. |
| 563 { |
| 564 iframe->contentDocument()->setRootScroller(nullptr, nonThrow); |
| 565 EXPECT_EQ( |
| 566 mainController->rootScrollerLayer(), |
| 567 iframe->contentDocument()->view()->layerForScrolling()); |
| 568 EXPECT_FALSE(mainController->isViewportScrollCallback( |
| 569 container->getApplyScroll())); |
| 570 EXPECT_FALSE(mainController->isViewportScrollCallback( |
| 571 mainFrame()->document()->documentElement()->getApplyScroll())); |
| 572 EXPECT_TRUE(mainController->isViewportScrollCallback( |
| 573 iframe->contentDocument()->documentElement()->getApplyScroll())); |
| 574 } |
| 575 |
| 576 // Finally, unsetting the main frame's root scroller should reset it to the |
| 577 // documentElement and corresponding layer. |
| 578 { |
| 579 mainFrame()->document()->setRootScroller(nullptr, nonThrow); |
| 580 EXPECT_EQ( |
| 581 mainController->rootScrollerLayer(), |
| 582 mainFrameView()->layerForScrolling()); |
| 583 EXPECT_TRUE(mainController->isViewportScrollCallback( |
| 584 mainFrame()->document()->documentElement()->getApplyScroll())); |
| 585 EXPECT_FALSE(mainController->isViewportScrollCallback( |
| 586 container->getApplyScroll())); |
| 587 EXPECT_FALSE(mainController->isViewportScrollCallback( |
| 588 iframe->contentDocument()->documentElement()->getApplyScroll())); |
| 589 } |
| 590 } |
| 591 |
| 592 TEST_F(RootScrollerTest, TestSetRootScrollerCausesViewportLayerChange) |
| 593 { |
| 594 // TODO(bokan): Need a test that changing root scrollers actually sets the |
| 595 // outer viewport layer on the compositor, even in the absence of other |
| 596 // compositing changes. crbug.com/505516 |
| 597 } |
| 598 |
| 599 |
462 // Tests that trying to set an element as the root scroller of a document inside | 600 // Tests that trying to set an element as the root scroller of a document inside |
463 // an iframe fails when that element belongs to the parent document. | 601 // an iframe fails when that element belongs to the parent document. |
464 // TODO(bokan): Recent changes mean this is now possible but should be fixed. | 602 // TODO(bokan): Recent changes mean this is now possible but should be fixed. |
465 TEST_F(RootScrollerTest, DISABLED_TestSetRootScrollerOnElementFromOutsideIframe) | 603 TEST_F(RootScrollerTest, DISABLED_TestSetRootScrollerOnElementFromOutsideIframe) |
466 { | 604 { |
467 initialize("root-scroller-iframe.html"); | 605 initialize("root-scroller-iframe.html"); |
468 | 606 |
469 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 607 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
470 { | 608 { |
471 // Try to set the the root scroller of the child document to be the | 609 // Try to set the the root scroller of the child document to be the |
472 // <iframe> element in the parent document. | 610 // <iframe> element in the parent document. |
473 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( | 611 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
474 mainFrame()->document()->getElementById("iframe")); | 612 mainFrame()->document()->getElementById("iframe")); |
475 NonThrowableExceptionState nonThrow; | 613 NonThrowableExceptionState nonThrow; |
476 Element* body = | 614 Element* body = |
477 mainFrame()->document()->querySelector("body", nonThrow); | 615 mainFrame()->document()->querySelector("body", nonThrow); |
478 | 616 |
479 ASSERT_EQ(nullptr, iframe->contentDocument()->rootScroller()); | 617 EXPECT_EQ(nullptr, iframe->contentDocument()->rootScroller()); |
480 | 618 |
481 TrackExceptionState exceptionState; | 619 TrackExceptionState exceptionState; |
482 iframe->contentDocument()->setRootScroller( | 620 iframe->contentDocument()->setRootScroller( |
483 iframe, | 621 iframe, |
484 exceptionState); | 622 exceptionState); |
485 | 623 |
486 ASSERT_EQ(iframe, iframe->contentDocument()->rootScroller()); | 624 EXPECT_EQ(iframe, iframe->contentDocument()->rootScroller()); |
487 | 625 |
488 // Try to set the root scroller of the child document to be the | 626 // Try to set the root scroller of the child document to be the |
489 // <body> element of the parent document. | 627 // <body> element of the parent document. |
490 iframe->contentDocument()->setRootScroller( | 628 iframe->contentDocument()->setRootScroller( |
491 body, | 629 body, |
492 exceptionState); | 630 exceptionState); |
493 | 631 |
494 ASSERT_EQ(body, iframe->contentDocument()->rootScroller()); | 632 EXPECT_EQ(body, iframe->contentDocument()->rootScroller()); |
495 } | 633 } |
496 } | 634 } |
497 | 635 |
498 } // namespace | 636 } // namespace |
499 | 637 |
500 } // namespace blink | 638 } // namespace blink |
OLD | NEW |