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/layout/LayoutBox.h" | 9 #include "core/layout/LayoutBox.h" |
| 10 #include "core/layout/api/LayoutViewItem.h" |
| 11 #include "core/layout/compositing/PaintLayerCompositor.h" |
10 #include "core/page/Page.h" | 12 #include "core/page/Page.h" |
11 #include "core/page/scrolling/RootScrollerController.h" | 13 #include "core/page/scrolling/RootScrollerController.h" |
| 14 #include "core/page/scrolling/TopDocumentRootScrollerController.h" |
12 #include "core/paint/PaintLayerScrollableArea.h" | 15 #include "core/paint/PaintLayerScrollableArea.h" |
13 #include "platform/testing/URLTestHelpers.h" | 16 #include "platform/testing/URLTestHelpers.h" |
14 #include "platform/testing/UnitTestHelpers.h" | 17 #include "platform/testing/UnitTestHelpers.h" |
15 #include "public/platform/Platform.h" | 18 #include "public/platform/Platform.h" |
16 #include "public/platform/WebURLLoaderMockFactory.h" | 19 #include "public/platform/WebURLLoaderMockFactory.h" |
17 #include "public/web/WebCache.h" | 20 #include "public/web/WebCache.h" |
18 #include "public/web/WebConsoleMessage.h" | 21 #include "public/web/WebConsoleMessage.h" |
19 #include "public/web/WebRemoteFrame.h" | 22 #include "public/web/WebRemoteFrame.h" |
20 #include "public/web/WebScriptSource.h" | 23 #include "public/web/WebScriptSource.h" |
21 #include "public/web/WebSettings.h" | 24 #include "public/web/WebSettings.h" |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 mainFrameView()->layerForScrolling()); | 549 mainFrameView()->layerForScrolling()); |
547 EXPECT_TRUE(mainController->isViewportScrollCallback( | 550 EXPECT_TRUE(mainController->isViewportScrollCallback( |
548 mainFrame()->document()->documentElement()->getApplyScroll())); | 551 mainFrame()->document()->documentElement()->getApplyScroll())); |
549 } | 552 } |
550 | 553 |
551 // Set a root scroller in the iframe. Since the main document didn't set a | 554 // Set a root scroller in the iframe. Since the main document didn't set a |
552 // root scroller, the global root scroller shouldn't change. | 555 // root scroller, the global root scroller shouldn't change. |
553 { | 556 { |
554 | 557 |
555 iframe->contentDocument()->setRootScroller(container, nonThrow); | 558 iframe->contentDocument()->setRootScroller(container, nonThrow); |
| 559 mainFrameView()->updateAllLifecyclePhases(); |
556 | 560 |
557 EXPECT_EQ( | 561 EXPECT_EQ( |
558 mainController->rootScrollerLayer(), | 562 mainController->rootScrollerLayer(), |
559 mainFrameView()->layerForScrolling()); | 563 mainFrameView()->layerForScrolling()); |
560 EXPECT_TRUE(mainController->isViewportScrollCallback( | 564 EXPECT_TRUE(mainController->isViewportScrollCallback( |
561 mainFrame()->document()->documentElement()->getApplyScroll())); | 565 mainFrame()->document()->documentElement()->getApplyScroll())); |
562 } | 566 } |
563 | 567 |
564 // Setting the iframe as the root scroller in the main frame should now | 568 // Setting the iframe as the root scroller in the main frame should now |
565 // link the root scrollers so the container should now be the global root | 569 // link the root scrollers so the container should now be the global root |
566 // scroller. | 570 // scroller. |
567 { | 571 { |
568 mainFrame()->document()->setRootScroller(iframe, nonThrow); | 572 mainFrame()->document()->setRootScroller(iframe, nonThrow); |
| 573 mainFrameView()->updateAllLifecyclePhases(); |
569 | 574 |
570 ScrollableArea* containerScroller = | 575 ScrollableArea* containerScroller = |
571 static_cast<PaintInvalidationCapableScrollableArea*>( | 576 static_cast<PaintInvalidationCapableScrollableArea*>( |
572 toLayoutBox(container->layoutObject())->getScrollableArea()); | 577 toLayoutBox(container->layoutObject())->getScrollableArea()); |
573 | 578 |
574 EXPECT_EQ( | 579 EXPECT_EQ( |
575 mainController->rootScrollerLayer(), | 580 mainController->rootScrollerLayer(), |
576 containerScroller->layerForScrolling()); | 581 containerScroller->layerForScrolling()); |
577 EXPECT_FALSE(mainController->isViewportScrollCallback( | 582 EXPECT_FALSE(mainController->isViewportScrollCallback( |
578 mainFrame()->document()->documentElement()->getApplyScroll())); | 583 mainFrame()->document()->documentElement()->getApplyScroll())); |
579 EXPECT_TRUE(mainController->isViewportScrollCallback( | 584 EXPECT_TRUE(mainController->isViewportScrollCallback( |
580 container->getApplyScroll())); | 585 container->getApplyScroll())); |
581 } | 586 } |
582 | 587 |
583 // Unsetting the root scroller in the iframe should reset its effective | 588 // Unsetting the root scroller in the iframe should reset its effective |
584 // root scroller to the iframe's documentElement and thus the iframe's | 589 // root scroller to the iframe's documentElement and thus the iframe's |
585 // documentElement becomes the global root scroller. | 590 // documentElement becomes the global root scroller. |
586 { | 591 { |
587 iframe->contentDocument()->setRootScroller(nullptr, nonThrow); | 592 iframe->contentDocument()->setRootScroller(nullptr, nonThrow); |
| 593 mainFrameView()->updateAllLifecyclePhases(); |
588 EXPECT_EQ( | 594 EXPECT_EQ( |
589 mainController->rootScrollerLayer(), | 595 mainController->rootScrollerLayer(), |
590 iframe->contentDocument()->view()->layerForScrolling()); | 596 iframe->contentDocument()->view()->layerForScrolling()); |
591 EXPECT_FALSE(mainController->isViewportScrollCallback( | 597 EXPECT_FALSE(mainController->isViewportScrollCallback( |
592 container->getApplyScroll())); | 598 container->getApplyScroll())); |
593 EXPECT_FALSE(mainController->isViewportScrollCallback( | 599 EXPECT_FALSE(mainController->isViewportScrollCallback( |
594 mainFrame()->document()->documentElement()->getApplyScroll())); | 600 mainFrame()->document()->documentElement()->getApplyScroll())); |
595 EXPECT_TRUE(mainController->isViewportScrollCallback( | 601 EXPECT_TRUE(mainController->isViewportScrollCallback( |
596 iframe->contentDocument()->documentElement()->getApplyScroll())); | 602 iframe->contentDocument()->documentElement()->getApplyScroll())); |
597 } | 603 } |
598 | 604 |
599 // Finally, unsetting the main frame's root scroller should reset it to the | 605 // Finally, unsetting the main frame's root scroller should reset it to the |
600 // documentElement and corresponding layer. | 606 // documentElement and corresponding layer. |
601 { | 607 { |
602 mainFrame()->document()->setRootScroller(nullptr, nonThrow); | 608 mainFrame()->document()->setRootScroller(nullptr, nonThrow); |
| 609 mainFrameView()->updateAllLifecyclePhases(); |
603 EXPECT_EQ( | 610 EXPECT_EQ( |
604 mainController->rootScrollerLayer(), | 611 mainController->rootScrollerLayer(), |
605 mainFrameView()->layerForScrolling()); | 612 mainFrameView()->layerForScrolling()); |
606 EXPECT_TRUE(mainController->isViewportScrollCallback( | 613 EXPECT_TRUE(mainController->isViewportScrollCallback( |
607 mainFrame()->document()->documentElement()->getApplyScroll())); | 614 mainFrame()->document()->documentElement()->getApplyScroll())); |
608 EXPECT_FALSE(mainController->isViewportScrollCallback( | 615 EXPECT_FALSE(mainController->isViewportScrollCallback( |
609 container->getApplyScroll())); | 616 container->getApplyScroll())); |
610 EXPECT_FALSE(mainController->isViewportScrollCallback( | 617 EXPECT_FALSE(mainController->isViewportScrollCallback( |
611 iframe->contentDocument()->documentElement()->getApplyScroll())); | 618 iframe->contentDocument()->documentElement()->getApplyScroll())); |
612 } | 619 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 // ViewportScrollCallback removed. Keep the scrolls to guard crashes | 757 // ViewportScrollCallback removed. Keep the scrolls to guard crashes |
751 // but the expectations on when a ViewportScrollCallback have changed | 758 // but the expectations on when a ViewportScrollCallback have changed |
752 // and should be updated. | 759 // and should be updated. |
753 // EXPECT_EQ(200, container->scrollTop()); | 760 // EXPECT_EQ(200, container->scrollTop()); |
754 } | 761 } |
755 | 762 |
756 // Reset explicitly to prevent lifetime issues with the RemoteFrameClient. | 763 // Reset explicitly to prevent lifetime issues with the RemoteFrameClient. |
757 m_helper.reset(); | 764 m_helper.reset(); |
758 } | 765 } |
759 | 766 |
| 767 // Tests that clipping layers belonging to any compositors in the ancestor chain |
| 768 // of the global root scroller have their masking bit removed. |
| 769 TEST_F(RootScrollerTest, RemoveClippingOnCompositorLayers) |
| 770 { |
| 771 // TODO(bokan): Remove casts to TDRSC once follow-up patch lands separating
TDRSC |
| 772 // from RootScrollerController. |
| 773 |
| 774 initialize("root-scroller-iframe.html"); |
| 775 |
| 776 HTMLFrameOwnerElement* iframe = toHTMLFrameOwnerElement( |
| 777 mainFrame()->document()->getElementById("iframe")); |
| 778 Element* container = |
| 779 iframe->contentDocument()->getElementById("container"); |
| 780 |
| 781 RootScrollerController* mainController = |
| 782 mainFrame()->document()->rootScrollerController(); |
| 783 RootScrollerController* childController = |
| 784 iframe->contentDocument()->rootScrollerController(); |
| 785 |
| 786 PaintLayerCompositor* mainCompositor = |
| 787 mainFrameView()->layoutViewItem().compositor(); |
| 788 PaintLayerCompositor* childCompositor = |
| 789 iframe->contentDocument()->view()->layoutViewItem().compositor(); |
| 790 |
| 791 NonThrowableExceptionState nonThrow; |
| 792 |
| 793 // No root scroller set, on the main frame the root content layer should |
| 794 // clip. Additionally, on the child frame, the overflow controls host and |
| 795 // container layers should also clip. |
| 796 { |
| 797 EXPECT_TRUE(mainCompositor->rootContentLayer()->platformLayer() |
| 798 ->masksToBounds()); |
| 799 EXPECT_FALSE(mainCompositor->rootGraphicsLayer()->platformLayer() |
| 800 ->masksToBounds()); |
| 801 EXPECT_FALSE(mainCompositor->containerLayer()->platformLayer() |
| 802 ->masksToBounds()); |
| 803 |
| 804 EXPECT_TRUE(childCompositor->rootContentLayer()->platformLayer() |
| 805 ->masksToBounds()); |
| 806 EXPECT_TRUE(childCompositor->rootGraphicsLayer()->platformLayer() |
| 807 ->masksToBounds()); |
| 808 EXPECT_TRUE(childCompositor->containerLayer()->platformLayer() |
| 809 ->masksToBounds()); |
| 810 } |
| 811 |
| 812 // Now set the root scrollers such that the container in the iframe is the |
| 813 // global root scroller. All the previously clipping layers in both paint |
| 814 // layer compositors should no longer clip. |
| 815 { |
| 816 iframe->contentDocument()->setRootScroller(container, nonThrow); |
| 817 mainFrame()->document()->setRootScroller(iframe, nonThrow); |
| 818 mainFrameView()->updateAllLifecyclePhases(); |
| 819 |
| 820 ASSERT_EQ(iframe, mainController->effectiveRootScroller()); |
| 821 ASSERT_EQ(container, childController->effectiveRootScroller()); |
| 822 |
| 823 EXPECT_FALSE(mainCompositor->rootContentLayer()->platformLayer() |
| 824 ->masksToBounds()); |
| 825 EXPECT_FALSE(mainCompositor->rootGraphicsLayer()->platformLayer() |
| 826 ->masksToBounds()); |
| 827 EXPECT_FALSE(mainCompositor->containerLayer()->platformLayer() |
| 828 ->masksToBounds()); |
| 829 |
| 830 EXPECT_FALSE(childCompositor->rootContentLayer()->platformLayer() |
| 831 ->masksToBounds()); |
| 832 EXPECT_FALSE(childCompositor->rootGraphicsLayer()->platformLayer() |
| 833 ->masksToBounds()); |
| 834 EXPECT_FALSE(childCompositor->containerLayer()->platformLayer() |
| 835 ->masksToBounds()); |
| 836 } |
| 837 |
| 838 // Now reset the iframe's root scroller. Since the iframe itself is now the |
| 839 // global root scroller we want it to behave as if it were the main frame, w
hich |
| 840 // means it should clip only on its root content layer. |
| 841 { |
| 842 iframe->contentDocument()->setRootScroller(nullptr, nonThrow); |
| 843 mainFrameView()->updateAllLifecyclePhases(); |
| 844 |
| 845 ASSERT_EQ(iframe, mainController->effectiveRootScroller()); |
| 846 ASSERT_EQ(iframe->contentDocument()->documentElement(), |
| 847 childController->effectiveRootScroller()); |
| 848 ASSERT_EQ(iframe->contentDocument()->documentElement(), |
| 849 ((TopDocumentRootScrollerController*)mainController) |
| 850 ->globalRootScroller()); |
| 851 |
| 852 EXPECT_FALSE(mainCompositor->rootContentLayer()->platformLayer() |
| 853 ->masksToBounds()); |
| 854 EXPECT_FALSE(mainCompositor->rootGraphicsLayer()->platformLayer() |
| 855 ->masksToBounds()); |
| 856 EXPECT_FALSE(mainCompositor->containerLayer()->platformLayer() |
| 857 ->masksToBounds()); |
| 858 |
| 859 EXPECT_TRUE(childCompositor->rootContentLayer()->platformLayer() |
| 860 ->masksToBounds()); |
| 861 EXPECT_FALSE(childCompositor->rootGraphicsLayer()->platformLayer() |
| 862 ->masksToBounds()); |
| 863 EXPECT_FALSE(childCompositor->containerLayer()->platformLayer() |
| 864 ->masksToBounds()); |
| 865 } |
| 866 |
| 867 // Now reset the main frame's root scroller. Its compositor should go back |
| 868 // to clipping as well. Because the iframe is now no longer the global root |
| 869 // scroller, it should go back to clipping its overflow host and container |
| 870 // layers. This checks that we invalidate the compositing state even though |
| 871 // the iframe's effective root scroller hasn't changed. |
| 872 |
| 873 { |
| 874 mainFrame()->document()->setRootScroller(nullptr, nonThrow); |
| 875 mainFrameView()->updateAllLifecyclePhases(); |
| 876 |
| 877 ASSERT_EQ(mainFrame()->document()->documentElement(), |
| 878 mainController->effectiveRootScroller()); |
| 879 ASSERT_EQ(iframe->contentDocument()->documentElement(), |
| 880 childController->effectiveRootScroller()); |
| 881 ASSERT_EQ(mainFrame()->document()->documentElement(), |
| 882 ((TopDocumentRootScrollerController*)mainController) |
| 883 ->globalRootScroller()); |
| 884 |
| 885 EXPECT_TRUE(mainCompositor->rootContentLayer()->platformLayer() |
| 886 ->masksToBounds()); |
| 887 EXPECT_FALSE(mainCompositor->rootGraphicsLayer()->platformLayer() |
| 888 ->masksToBounds()); |
| 889 EXPECT_FALSE(mainCompositor->containerLayer()->platformLayer() |
| 890 ->masksToBounds()); |
| 891 |
| 892 EXPECT_TRUE(childCompositor->rootContentLayer()->platformLayer() |
| 893 ->masksToBounds()); |
| 894 EXPECT_TRUE(childCompositor->rootGraphicsLayer()->platformLayer() |
| 895 ->masksToBounds()); |
| 896 EXPECT_TRUE(childCompositor->containerLayer()->platformLayer() |
| 897 ->masksToBounds()); |
| 898 } |
| 899 |
| 900 // Set the iframe back as the main frame's root scroller. Since its the |
| 901 // global root scroller again, it should clip like the root frame. This |
| 902 // checks that we invalidate the compositing state even though the iframe's |
| 903 // effective root scroller hasn't changed. |
| 904 { |
| 905 mainFrame()->document()->setRootScroller(iframe, nonThrow); |
| 906 mainFrameView()->updateAllLifecyclePhases(); |
| 907 |
| 908 ASSERT_EQ(iframe, mainController->effectiveRootScroller()); |
| 909 ASSERT_EQ(iframe->contentDocument()->documentElement(), |
| 910 childController->effectiveRootScroller()); |
| 911 ASSERT_EQ(iframe->contentDocument()->documentElement(), |
| 912 ((TopDocumentRootScrollerController*)mainController) |
| 913 ->globalRootScroller()); |
| 914 |
| 915 EXPECT_FALSE(mainCompositor->rootContentLayer()->platformLayer() |
| 916 ->masksToBounds()); |
| 917 EXPECT_FALSE(mainCompositor->rootGraphicsLayer()->platformLayer() |
| 918 ->masksToBounds()); |
| 919 EXPECT_FALSE(mainCompositor->containerLayer()->platformLayer() |
| 920 ->masksToBounds()); |
| 921 |
| 922 EXPECT_TRUE(childCompositor->rootContentLayer()->platformLayer() |
| 923 ->masksToBounds()); |
| 924 EXPECT_FALSE(childCompositor->rootGraphicsLayer()->platformLayer() |
| 925 ->masksToBounds()); |
| 926 EXPECT_FALSE(childCompositor->containerLayer()->platformLayer() |
| 927 ->masksToBounds()); |
| 928 } |
| 929 |
| 930 // Set just the iframe's root scroller. We should stop clipping the |
| 931 // iframe's compositor's layers but not the main frame's. |
| 932 { |
| 933 mainFrame()->document()->setRootScroller(nullptr, nonThrow); |
| 934 iframe->contentDocument()->setRootScroller(container, nonThrow); |
| 935 mainFrameView()->updateAllLifecyclePhases(); |
| 936 |
| 937 ASSERT_EQ(mainFrame()->document()->documentElement(), |
| 938 mainController->effectiveRootScroller()); |
| 939 ASSERT_EQ(container, childController->effectiveRootScroller()); |
| 940 |
| 941 EXPECT_TRUE(mainCompositor->rootContentLayer()->platformLayer() |
| 942 ->masksToBounds()); |
| 943 EXPECT_FALSE(mainCompositor->rootGraphicsLayer()->platformLayer() |
| 944 ->masksToBounds()); |
| 945 EXPECT_FALSE(mainCompositor->containerLayer()->platformLayer() |
| 946 ->masksToBounds()); |
| 947 |
| 948 EXPECT_FALSE(childCompositor->rootContentLayer()->platformLayer() |
| 949 ->masksToBounds()); |
| 950 EXPECT_FALSE(childCompositor->rootGraphicsLayer()->platformLayer() |
| 951 ->masksToBounds()); |
| 952 EXPECT_FALSE(childCompositor->containerLayer()->platformLayer() |
| 953 ->masksToBounds()); |
| 954 } |
| 955 } |
| 956 |
760 } // namespace | 957 } // namespace |
761 | 958 |
762 } // namespace blink | 959 } // namespace blink |
OLD | NEW |