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 "platform/testing/URLTestHelpers.h" | 11 #include "platform/testing/URLTestHelpers.h" |
11 #include "platform/testing/UnitTestHelpers.h" | 12 #include "platform/testing/UnitTestHelpers.h" |
12 #include "public/platform/Platform.h" | 13 #include "public/platform/Platform.h" |
13 #include "public/platform/WebURLLoaderMockFactory.h" | 14 #include "public/platform/WebURLLoaderMockFactory.h" |
14 #include "public/web/WebCache.h" | 15 #include "public/web/WebCache.h" |
15 #include "public/web/WebConsoleMessage.h" | 16 #include "public/web/WebConsoleMessage.h" |
16 #include "public/web/WebScriptSource.h" | 17 #include "public/web/WebScriptSource.h" |
17 #include "public/web/WebSettings.h" | 18 #include "public/web/WebSettings.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
19 #include "web/WebLocalFrameImpl.h" | 20 #include "web/WebLocalFrameImpl.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 VisualViewport& visualViewport() const | 149 VisualViewport& visualViewport() const |
149 { | 150 { |
150 return frameHost().visualViewport(); | 151 return frameHost().visualViewport(); |
151 } | 152 } |
152 | 153 |
153 TopControls& topControls() const | 154 TopControls& topControls() const |
154 { | 155 { |
155 return frameHost().topControls(); | 156 return frameHost().topControls(); |
156 } | 157 } |
157 | 158 |
| 159 Element* effectiveRootScroller(Document* doc) const |
| 160 { |
| 161 return doc->rootScrollerController()->effectiveRootScroller(); |
| 162 } |
| 163 |
158 protected: | 164 protected: |
159 std::string m_baseURL; | 165 std::string m_baseURL; |
160 RootScrollerTestWebViewClient m_client; | 166 RootScrollerTestWebViewClient m_client; |
161 FrameTestHelpers::WebViewHelper m_helper; | 167 FrameTestHelpers::WebViewHelper m_helper; |
162 RuntimeEnabledFeatures::Backup m_featuresBackup; | 168 RuntimeEnabledFeatures::Backup m_featuresBackup; |
163 }; | 169 }; |
164 | 170 |
165 // Test that no root scroller element is set if setRootScroller isn't called on | 171 // Test that no root scroller element is set if setRootScroller isn't called on |
166 // any elements. The document element should be the default effective root | 172 // any elements. The document element should be the default effective root |
167 // scroller. | 173 // scroller. |
168 TEST_F(RootScrollerTest, TestDefaultRootScroller) | 174 TEST_F(RootScrollerTest, TestDefaultRootScroller) |
169 { | 175 { |
170 initialize("overflow-scrolling.html"); | 176 initialize("overflow-scrolling.html"); |
171 | 177 |
172 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 178 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
173 | 179 |
174 Element* htmlElement = mainFrame()->document()->documentElement(); | 180 Element* htmlElement = mainFrame()->document()->documentElement(); |
175 EXPECT_EQ(htmlElement, mainFrame()->document()->effectiveRootScroller()); | 181 EXPECT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document())); |
176 } | 182 } |
177 | 183 |
178 // Tests that setting an element as the root scroller causes it to control url | 184 // Tests that setting an element as the root scroller causes it to control url |
179 // bar hiding and overscroll. | 185 // bar hiding and overscroll. |
180 TEST_F(RootScrollerTest, TestSetRootScroller) | 186 TEST_F(RootScrollerTest, TestSetRootScroller) |
181 { | 187 { |
182 initialize("root-scroller.html"); | 188 initialize("root-scroller.html"); |
183 | 189 |
184 Element* container = mainFrame()->document()->getElementById("container"); | 190 Element* container = mainFrame()->document()->getElementById("container"); |
185 TrackExceptionState exceptionState; | 191 TrackExceptionState exceptionState; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 { | 293 { |
288 initialize("root-scroller.html"); | 294 initialize("root-scroller.html"); |
289 | 295 |
290 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 296 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
291 | 297 |
292 Element* container = mainFrame()->document()->getElementById("container"); | 298 Element* container = mainFrame()->document()->getElementById("container"); |
293 TrackExceptionState exceptionState; | 299 TrackExceptionState exceptionState; |
294 mainFrame()->document()->setRootScroller(container, exceptionState); | 300 mainFrame()->document()->setRootScroller(container, exceptionState); |
295 | 301 |
296 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 302 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); |
297 ASSERT_EQ(container, mainFrame()->document()->effectiveRootScroller()); | 303 ASSERT_EQ(container, effectiveRootScroller(mainFrame()->document())); |
298 | 304 |
299 mainFrame()->document()->body()->removeChild(container); | 305 mainFrame()->document()->body()->removeChild(container); |
300 mainFrameView()->updateAllLifecyclePhases(); | 306 mainFrameView()->updateAllLifecyclePhases(); |
301 | 307 |
302 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 308 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); |
303 ASSERT_NE(container, mainFrame()->document()->effectiveRootScroller()); | 309 ASSERT_NE(container, effectiveRootScroller(mainFrame()->document())); |
304 } | 310 } |
305 | 311 |
306 // Tests that setting an element that isn't a valid scroller as the root | 312 // Tests that setting an element that isn't a valid scroller as the root |
307 // scroller doesn't change the effective root scroller. | 313 // scroller doesn't change the effective root scroller. |
308 TEST_F(RootScrollerTest, TestSetRootScrollerOnInvalidElement) | 314 TEST_F(RootScrollerTest, TestSetRootScrollerOnInvalidElement) |
309 { | 315 { |
310 initialize("root-scroller.html"); | 316 initialize("root-scroller.html"); |
311 | 317 |
312 { | 318 { |
313 // Set to a non-block element. Should be rejected and a console message | 319 // Set to a non-block element. Should be rejected and a console message |
314 // logged. | 320 // logged. |
315 Element* element = mainFrame()->document()->getElementById("nonBlock"); | 321 Element* element = mainFrame()->document()->getElementById("nonBlock"); |
316 TrackExceptionState exceptionState; | 322 TrackExceptionState exceptionState; |
317 mainFrame()->document()->setRootScroller(element, exceptionState); | 323 mainFrame()->document()->setRootScroller(element, exceptionState); |
318 mainFrameView()->updateAllLifecyclePhases(); | 324 mainFrameView()->updateAllLifecyclePhases(); |
319 ASSERT_EQ(element, mainFrame()->document()->rootScroller()); | 325 ASSERT_EQ(element, mainFrame()->document()->rootScroller()); |
320 ASSERT_NE(element, mainFrame()->document()->effectiveRootScroller()); | 326 ASSERT_NE(element, effectiveRootScroller(mainFrame()->document())); |
321 } | 327 } |
322 | 328 |
323 { | 329 { |
324 // Set to an element with no size. | 330 // Set to an element with no size. |
325 Element* element = mainFrame()->document()->getElementById("empty"); | 331 Element* element = mainFrame()->document()->getElementById("empty"); |
326 TrackExceptionState exceptionState; | 332 TrackExceptionState exceptionState; |
327 mainFrame()->document()->setRootScroller(element, exceptionState); | 333 mainFrame()->document()->setRootScroller(element, exceptionState); |
328 mainFrameView()->updateAllLifecyclePhases(); | 334 mainFrameView()->updateAllLifecyclePhases(); |
329 ASSERT_EQ(element, mainFrame()->document()->rootScroller()); | 335 ASSERT_EQ(element, mainFrame()->document()->rootScroller()); |
330 ASSERT_NE(element, mainFrame()->document()->effectiveRootScroller()); | 336 ASSERT_NE(element, effectiveRootScroller(mainFrame()->document())); |
331 } | 337 } |
332 } | 338 } |
333 | 339 |
334 // Test that the effective root scroller resets to the default element when the | 340 // Test that the effective root scroller resets to the default element when the |
335 // current root scroller element becomes invalid as a scroller. | 341 // current root scroller element becomes invalid as a scroller. |
336 TEST_F(RootScrollerTest, TestRootScrollerBecomesInvalid) | 342 TEST_F(RootScrollerTest, TestRootScrollerBecomesInvalid) |
337 { | 343 { |
338 initialize("root-scroller.html"); | 344 initialize("root-scroller.html"); |
339 | 345 |
340 Element* htmlElement = mainFrame()->document()->documentElement(); | 346 Element* htmlElement = mainFrame()->document()->documentElement(); |
341 Element* container = mainFrame()->document()->getElementById("container"); | 347 Element* container = mainFrame()->document()->getElementById("container"); |
342 TrackExceptionState exceptionState; | 348 TrackExceptionState exceptionState; |
343 | 349 |
344 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 350 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
345 ASSERT_EQ(htmlElement, mainFrame()->document()->effectiveRootScroller()); | 351 ASSERT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document())); |
346 | 352 |
347 { | 353 { |
348 mainFrame()->document()->setRootScroller(container, exceptionState); | 354 mainFrame()->document()->setRootScroller(container, exceptionState); |
349 mainFrameView()->updateAllLifecyclePhases(); | 355 mainFrameView()->updateAllLifecyclePhases(); |
350 | 356 |
351 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 357 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); |
352 ASSERT_EQ(container, mainFrame()->document()->effectiveRootScroller()); | 358 ASSERT_EQ(container, effectiveRootScroller(mainFrame()->document())); |
353 | 359 |
354 executeScript( | 360 executeScript( |
355 "document.querySelector('#container').style.display = 'inline'"); | 361 "document.querySelector('#container').style.display = 'inline'"); |
356 mainFrameView()->updateAllLifecyclePhases(); | 362 mainFrameView()->updateAllLifecyclePhases(); |
357 | 363 |
358 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 364 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); |
359 ASSERT_EQ(htmlElement, | 365 ASSERT_EQ(htmlElement, |
360 mainFrame()->document()->effectiveRootScroller()); | 366 effectiveRootScroller(mainFrame()->document())); |
361 } | 367 } |
362 | 368 |
363 executeScript( | 369 executeScript( |
364 "document.querySelector('#container').style.display = 'block'"); | 370 "document.querySelector('#container').style.display = 'block'"); |
365 mainFrame()->document()->setRootScroller(nullptr, exceptionState); | 371 mainFrame()->document()->setRootScroller(nullptr, exceptionState); |
366 mainFrameView()->updateAllLifecyclePhases(); | 372 mainFrameView()->updateAllLifecyclePhases(); |
367 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 373 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
368 ASSERT_EQ(htmlElement, mainFrame()->document()->effectiveRootScroller()); | 374 ASSERT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document())); |
369 | 375 |
370 { | 376 { |
371 mainFrame()->document()->setRootScroller(container, exceptionState); | 377 mainFrame()->document()->setRootScroller(container, exceptionState); |
372 mainFrameView()->updateAllLifecyclePhases(); | 378 mainFrameView()->updateAllLifecyclePhases(); |
373 | 379 |
374 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 380 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); |
375 ASSERT_EQ(container, mainFrame()->document()->effectiveRootScroller()); | 381 ASSERT_EQ(container, effectiveRootScroller(mainFrame()->document())); |
376 | 382 |
377 executeScript( | 383 executeScript( |
378 "document.querySelector('#container').style.width = '98%'"); | 384 "document.querySelector('#container').style.width = '98%'"); |
379 mainFrameView()->updateAllLifecyclePhases(); | 385 mainFrameView()->updateAllLifecyclePhases(); |
380 | 386 |
381 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); | 387 ASSERT_EQ(container, mainFrame()->document()->rootScroller()); |
382 ASSERT_EQ(htmlElement, | 388 ASSERT_EQ(htmlElement, |
383 mainFrame()->document()->effectiveRootScroller()); | 389 effectiveRootScroller(mainFrame()->document())); |
384 } | 390 } |
385 } | 391 } |
386 | 392 |
387 // Tests that setting the root scroller of the top document to an element that | 393 // Tests that setting the root scroller of the top document to an element that |
388 // belongs to a nested document works. | 394 // belongs to a nested document works. |
389 TEST_F(RootScrollerTest, TestSetRootScrollerOnElementInIframe) | 395 TEST_F(RootScrollerTest, TestSetRootScrollerOnElementInIframe) |
390 { | 396 { |
391 initialize("root-scroller-iframe.html"); | 397 initialize("root-scroller-iframe.html"); |
392 | 398 |
393 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 399 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
394 | 400 |
395 { | 401 { |
396 // Trying to set an element from a nested document should fail. | 402 // Trying to set an element from a nested document should fail. |
397 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( | 403 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
398 mainFrame()->document()->getElementById("iframe")); | 404 mainFrame()->document()->getElementById("iframe")); |
399 Element* innerContainer = | 405 Element* innerContainer = |
400 iframe->contentDocument()->getElementById("container"); | 406 iframe->contentDocument()->getElementById("container"); |
401 | 407 |
402 TrackExceptionState exceptionState; | 408 TrackExceptionState exceptionState; |
403 mainFrame()->document()->setRootScroller( | 409 mainFrame()->document()->setRootScroller( |
404 innerContainer, | 410 innerContainer, |
405 exceptionState); | 411 exceptionState); |
406 mainFrameView()->updateAllLifecyclePhases(); | 412 mainFrameView()->updateAllLifecyclePhases(); |
407 | 413 |
408 ASSERT_EQ(innerContainer, mainFrame()->document()->rootScroller()); | 414 ASSERT_EQ(innerContainer, mainFrame()->document()->rootScroller()); |
409 ASSERT_EQ(innerContainer, | 415 ASSERT_EQ(innerContainer, |
410 mainFrame()->document()->effectiveRootScroller()); | 416 effectiveRootScroller(mainFrame()->document())); |
411 } | 417 } |
412 | 418 |
413 { | 419 { |
414 // Setting the iframe itself should also work. | 420 // Setting the iframe itself should also work. |
415 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( | 421 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
416 mainFrame()->document()->getElementById("iframe")); | 422 mainFrame()->document()->getElementById("iframe")); |
417 | 423 |
418 TrackExceptionState exceptionState; | 424 TrackExceptionState exceptionState; |
419 mainFrame()->document()->setRootScroller(iframe, exceptionState); | 425 mainFrame()->document()->setRootScroller(iframe, exceptionState); |
420 mainFrameView()->updateAllLifecyclePhases(); | 426 mainFrameView()->updateAllLifecyclePhases(); |
421 | 427 |
422 ASSERT_EQ(iframe, mainFrame()->document()->rootScroller()); | 428 ASSERT_EQ(iframe, mainFrame()->document()->rootScroller()); |
423 ASSERT_EQ(iframe, mainFrame()->document()->effectiveRootScroller()); | 429 ASSERT_EQ(iframe, effectiveRootScroller(mainFrame()->document())); |
424 } | 430 } |
425 } | 431 } |
426 | 432 |
427 // Tests that setting a valid element as the root scroller on a document within | 433 // Tests that setting a valid element as the root scroller on a document within |
428 // an iframe works as expected. | 434 // an iframe works as expected. |
429 TEST_F(RootScrollerTest, TestRootScrollerWithinIframe) | 435 TEST_F(RootScrollerTest, TestRootScrollerWithinIframe) |
430 { | 436 { |
431 initialize("root-scroller-iframe.html"); | 437 initialize("root-scroller-iframe.html"); |
432 | 438 |
433 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); | 439 ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller()); |
434 | 440 |
435 { | 441 { |
436 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( | 442 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
437 mainFrame()->document()->getElementById("iframe")); | 443 mainFrame()->document()->getElementById("iframe")); |
438 | 444 |
439 ASSERT_EQ(iframe->contentDocument()->documentElement(), | 445 ASSERT_EQ(iframe->contentDocument()->documentElement(), |
440 iframe->contentDocument()->effectiveRootScroller()); | 446 effectiveRootScroller(iframe->contentDocument())); |
441 | 447 |
442 Element* innerContainer = | 448 Element* innerContainer = |
443 iframe->contentDocument()->getElementById("container"); | 449 iframe->contentDocument()->getElementById("container"); |
444 TrackExceptionState exceptionState; | 450 TrackExceptionState exceptionState; |
445 iframe->contentDocument()->setRootScroller( | 451 iframe->contentDocument()->setRootScroller( |
446 innerContainer, | 452 innerContainer, |
447 exceptionState); | 453 exceptionState); |
448 mainFrameView()->updateAllLifecyclePhases(); | 454 mainFrameView()->updateAllLifecyclePhases(); |
449 | 455 |
450 ASSERT_EQ(innerContainer, iframe->contentDocument()->rootScroller()); | 456 ASSERT_EQ(innerContainer, iframe->contentDocument()->rootScroller()); |
451 ASSERT_EQ(innerContainer, | 457 ASSERT_EQ(innerContainer, |
452 iframe->contentDocument()->effectiveRootScroller()); | 458 effectiveRootScroller(iframe->contentDocument())); |
453 } | 459 } |
454 } | 460 } |
455 | 461 |
456 // Tests that trying to set an element as the root scroller of a document inside | 462 // Tests that trying to set an element as the root scroller of a document inside |
457 // an iframe fails when that element belongs to the parent document. | 463 // an iframe fails when that element belongs to the parent document. |
458 // TODO(bokan): Recent changes mean this is now possible but should be fixed. | 464 // TODO(bokan): Recent changes mean this is now possible but should be fixed. |
459 TEST_F(RootScrollerTest, DISABLED_TestSetRootScrollerOnElementFromOutsideIframe) | 465 TEST_F(RootScrollerTest, DISABLED_TestSetRootScrollerOnElementFromOutsideIframe) |
460 { | 466 { |
461 initialize("root-scroller-iframe.html"); | 467 initialize("root-scroller-iframe.html"); |
462 | 468 |
(...skipping 22 matching lines...) Expand all Loading... |
485 body, | 491 body, |
486 exceptionState); | 492 exceptionState); |
487 | 493 |
488 ASSERT_EQ(body, iframe->contentDocument()->rootScroller()); | 494 ASSERT_EQ(body, iframe->contentDocument()->rootScroller()); |
489 } | 495 } |
490 } | 496 } |
491 | 497 |
492 } // namespace | 498 } // namespace |
493 | 499 |
494 } // namespace blink | 500 } // namespace blink |
OLD | NEW |