// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/web/web_console_message.h"
#include "third_party/blink/public/web/web_hit_test_result.h"
#include "third_party/blink/public/web/web_remote_frame.h"
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/renderer/bindings/core/v8/node_or_string.h"
#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
#include "third_party/blink/renderer/core/frame/browser_controls.h"
#include "third_party/blink/renderer/core/frame/dom_visual_viewport.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

using blink::test::RunPendingTasks;
using testing::Mock;

namespace blink {

namespace {

class RootScrollerTest : public testing::Test,
                         private ScopedImplicitRootScrollerForTest,
                         private ScopedSetRootScrollerForTest {
 public:
  RootScrollerTest()
      : ScopedImplicitRootScrollerForTest(false),
        ScopedSetRootScrollerForTest(true),
        base_url_("http://www.test.com/") {
    RegisterMockedHttpURLLoad("overflow-scrolling.html");
    RegisterMockedHttpURLLoad("root-scroller.html");
    RegisterMockedHttpURLLoad("root-scroller-rotation.html");
    RegisterMockedHttpURLLoad("root-scroller-iframe.html");
    RegisterMockedHttpURLLoad("root-scroller-child.html");
  }

  ~RootScrollerTest() override {
    features_backup_.Restore();
    Platform::Current()
        ->GetURLLoaderMockFactory()
        ->UnregisterAllURLsAndClearMemoryCache();
  }

  void SetAndSelectRootScroller(Document& document, Element* element) {
    document.setRootScroller(element, ASSERT_NO_EXCEPTION);
    if (document.GetFrame()) {
      LocalFrameView* root_view = document.GetFrame()->LocalFrameRoot().View();
      if (root_view)
        UpdateAllLifecyclePhases(root_view);
    }
  }

  WebViewImpl* Initialize(const std::string& page_name,
                          frame_test_helpers::TestWebWidgetClient* client) {
    return InitializeInternal(base_url_ + page_name, client);
  }

  WebViewImpl* Initialize(const std::string& page_name) {
    return InitializeInternal(base_url_ + page_name, nullptr);
  }

  WebViewImpl* Initialize() {
    return InitializeInternal("about:blank", nullptr);
  }

  static void ConfigureSettings(WebSettings* settings) {
    settings->SetJavaScriptEnabled(true);
    settings->SetPreferCompositingToLCDTextEnabled(true);
    // Android settings.
    settings->SetViewportEnabled(true);
    settings->SetViewportMetaEnabled(true);
    settings->SetShrinksViewportContentToFit(true);
    settings->SetMainFrameResizesAreOrientationChanges(true);
  }

  void RegisterMockedHttpURLLoad(const std::string& file_name) {
    url_test_helpers::RegisterMockedURLLoadFromBase(
        WebString::FromUTF8(base_url_), test::CoreTestDataPath(),
        WebString::FromUTF8(file_name));
  }

  void ExecuteScript(const WebString& code) {
    ExecuteScript(code, *MainWebFrame());
  }

  void ExecuteScript(const WebString& code, WebLocalFrame& frame) {
    frame.ExecuteScript(WebScriptSource(code));
    frame.View()->MainFrameWidget()->UpdateAllLifecyclePhases(
        WebWidget::LifecycleUpdateReason::kTest);
    RunPendingTasks();
  }

  WebViewImpl* GetWebView() const { return helper_.GetWebView(); }

  Page& GetPage() const { return *GetWebView()->GetPage(); }

  LocalFrame* MainFrame() const {
    return GetWebView()->MainFrameImpl()->GetFrame();
  }

  WebLocalFrame* MainWebFrame() const { return GetWebView()->MainFrameImpl(); }

  LocalFrameView* MainFrameView() const {
    return GetWebView()->MainFrameImpl()->GetFrame()->View();
  }

  VisualViewport& GetVisualViewport() const {
    return GetPage().GetVisualViewport();
  }

  BrowserControls& GetBrowserControls() const {
    return GetPage().GetBrowserControls();
  }

  Node* EffectiveRootScroller(Document* doc) const {
    return &doc->GetRootScrollerController().EffectiveRootScroller();
  }

  WebCoalescedInputEvent GenerateTouchGestureEvent(WebInputEvent::Type type,
                                                   int delta_x = 0,
                                                   int delta_y = 0) {
    return GenerateGestureEvent(type, kWebGestureDeviceTouchscreen, delta_x,
                                delta_y);
  }

  WebCoalescedInputEvent GenerateWheelGestureEvent(WebInputEvent::Type type,
                                                   int delta_x = 0,
                                                   int delta_y = 0) {
    return GenerateGestureEvent(type, kWebGestureDeviceTouchpad, delta_x,
                                delta_y);
  }

 protected:
  WebCoalescedInputEvent GenerateGestureEvent(WebInputEvent::Type type,
                                              WebGestureDevice device,
                                              int delta_x,
                                              int delta_y) {
    WebGestureEvent event(type, WebInputEvent::kNoModifiers,
                          WebInputEvent::GetStaticTimeStampForTests(), device);
    event.SetPositionInWidget(WebFloatPoint(100, 100));
    if (type == WebInputEvent::kGestureScrollUpdate) {
      event.data.scroll_update.delta_x = delta_x;
      event.data.scroll_update.delta_y = delta_y;
    } else if (type == WebInputEvent::kGestureScrollBegin) {
      event.data.scroll_begin.delta_x_hint = delta_x;
      event.data.scroll_begin.delta_y_hint = delta_y;
    }
    return WebCoalescedInputEvent(event);
  }

  WebViewImpl* InitializeInternal(
      const std::string& url,
      frame_test_helpers::TestWebWidgetClient* client) {
    helper_.InitializeAndLoad(url, nullptr, nullptr, client,
                              &ConfigureSettings);

    // Initialize browser controls to be shown.
    GetWebView()->ResizeWithBrowserControls(IntSize(400, 400), 50, 0, true);
    GetWebView()->GetBrowserControls().SetShownRatio(1);

    UpdateAllLifecyclePhases(MainFrameView());

    return GetWebView();
  }

  void UpdateAllLifecyclePhases(LocalFrameView* view) {
    view->UpdateAllLifecyclePhases(
        DocumentLifecycle::LifecycleUpdateReason::kTest);
  }

  std::string base_url_;
  std::unique_ptr<frame_test_helpers::TestWebViewClient> view_client_;
  frame_test_helpers::WebViewHelper helper_;
  RuntimeEnabledFeatures::Backup features_backup_;
};

// Test that no root scroller element is set if setRootScroller isn't called on
// any elements. The document Node should be the default effective root
// scroller.
TEST_F(RootScrollerTest, TestDefaultRootScroller) {
  Initialize("overflow-scrolling.html");

  ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
  EXPECT_EQ(MainFrame()->GetDocument(),
            EffectiveRootScroller(MainFrame()->GetDocument()));
}

// Make sure that replacing the documentElement doesn't change the effective
// root scroller when no root scroller is set.
TEST_F(RootScrollerTest, defaultEffectiveRootScrollerIsDocumentNode) {
  Initialize("root-scroller.html");

  Document* document = MainFrame()->GetDocument();
  Element* iframe = document->CreateRawElement(html_names::kIFrameTag);

  EXPECT_EQ(MainFrame()->GetDocument(),
            EffectiveRootScroller(MainFrame()->GetDocument()));

  // Replace the documentElement with the iframe. The effectiveRootScroller
  // should remain the same.
  HeapVector<NodeOrString> nodes;
  nodes.push_back(NodeOrString::FromNode(iframe));
  document->documentElement()->ReplaceWith(nodes, ASSERT_NO_EXCEPTION);

  UpdateAllLifecyclePhases(MainFrameView());

  EXPECT_EQ(MainFrame()->GetDocument(),
            EffectiveRootScroller(MainFrame()->GetDocument()));
}

class OverscrollTestWebWidgetClient
    : public frame_test_helpers::TestWebWidgetClient {
 public:
  MOCK_METHOD5(DidOverscroll,
               void(const WebFloatSize&,
                    const WebFloatSize&,
                    const WebFloatPoint&,
                    const WebFloatSize&,
                    const cc::OverscrollBehavior&));
};

// Tests that setting an element as the root scroller causes it to control url
// bar hiding and overscroll.
TEST_F(RootScrollerTest, TestSetRootScroller) {
  OverscrollTestWebWidgetClient client;
  Initialize("root-scroller.html", &client);

  Element* container = MainFrame()->GetDocument()->getElementById("container");
  SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
  ASSERT_EQ(container, MainFrame()->GetDocument()->rootScroller());

  // Content is 1000x1000, WebView size is 400x400 but hiding the top controls
  // makes it 400x450 so max scroll is 550px.
  double maximum_scroll = 550;

  GetWebView()->MainFrameWidget()->HandleInputEvent(
      GenerateTouchGestureEvent(WebInputEvent::kGestureScrollBegin));

  {
    // Scrolling over the #container DIV should cause the browser controls to
    // hide.
    EXPECT_FLOAT_EQ(1, GetBrowserControls().ShownRatio());
    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollUpdate, 0,
                                  -GetBrowserControls().TopHeight()));
    EXPECT_FLOAT_EQ(0, GetBrowserControls().ShownRatio());
  }

  {
    // Make sure we're actually scrolling the DIV and not the LocalFrameView.
    GetWebView()->MainFrameWidget()->HandleInputEvent(GenerateTouchGestureEvent(
        WebInputEvent::kGestureScrollUpdate, 0, -100));
    EXPECT_FLOAT_EQ(100, container->scrollTop());
    EXPECT_FLOAT_EQ(
        0, MainFrameView()->LayoutViewport()->GetScrollOffset().Height());
  }

  {
    // Scroll 50 pixels past the end. Ensure we report the 50 pixels as
    // overscroll.
    EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 50), WebFloatSize(0, 50),
                                      WebFloatPoint(100, 100), WebFloatSize(),
                                      cc::OverscrollBehavior()));
    GetWebView()->MainFrameWidget()->HandleInputEvent(GenerateTouchGestureEvent(
        WebInputEvent::kGestureScrollUpdate, 0, -500));
    EXPECT_FLOAT_EQ(maximum_scroll, container->scrollTop());
    EXPECT_FLOAT_EQ(
        0, MainFrameView()->LayoutViewport()->GetScrollOffset().Height());
    Mock::VerifyAndClearExpectations(&client);
  }

  {
    // Continue the gesture overscroll.
    EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 20), WebFloatSize(0, 70),
                                      WebFloatPoint(100, 100), WebFloatSize(),
                                      cc::OverscrollBehavior()));
    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollUpdate, 0, -20));
    EXPECT_FLOAT_EQ(maximum_scroll, container->scrollTop());
    EXPECT_FLOAT_EQ(
        0, MainFrameView()->LayoutViewport()->GetScrollOffset().Height());
    Mock::VerifyAndClearExpectations(&client);
  }

  GetWebView()->MainFrameWidget()->HandleInputEvent(
      GenerateTouchGestureEvent(WebInputEvent::kGestureScrollEnd));

  {
    // Make sure a new gesture scroll still won't scroll the frameview and
    // overscrolls.
    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollBegin));

    EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 30), WebFloatSize(0, 30),
                                      WebFloatPoint(100, 100), WebFloatSize(),
                                      cc::OverscrollBehavior()));
    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollUpdate, 0, -30));
    EXPECT_FLOAT_EQ(maximum_scroll, container->scrollTop());
    EXPECT_FLOAT_EQ(
        0, MainFrameView()->LayoutViewport()->GetScrollOffset().Height());
    Mock::VerifyAndClearExpectations(&client);

    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollEnd));
  }

  {
    // Scrolling up should show the browser controls.
    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollBegin));

    EXPECT_FLOAT_EQ(0, GetBrowserControls().ShownRatio());
    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollUpdate, 0, 30));
    EXPECT_FLOAT_EQ(0.6, GetBrowserControls().ShownRatio());

    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollEnd));
  }

  // Reset manually to avoid lifetime issues with custom WebViewClient.
  helper_.Reset();
}

// Tests that removing the element that is the root scroller from the DOM tree
// doesn't remove it as the root scroller but it does change the effective root
// scroller.
TEST_F(RootScrollerTest, TestRemoveRootScrollerFromDom) {
  Initialize("root-scroller.html");

  ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());

  Element* container = MainFrame()->GetDocument()->getElementById("container");
  SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);
  UpdateAllLifecyclePhases(MainFrameView());

  EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
  EXPECT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));

  MainFrame()->GetDocument()->body()->RemoveChild(container);
  UpdateAllLifecyclePhases(MainFrameView());

  EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
  EXPECT_NE(container, EffectiveRootScroller(MainFrame()->GetDocument()));
}

// Tests that setting an element that isn't a valid scroller as the root
// scroller doesn't change the effective root scroller.
TEST_F(RootScrollerTest, TestSetRootScrollerOnInvalidElement) {
  Initialize("root-scroller.html");

  {
    // Set to a non-block element. Should be rejected and a console message
    // logged.
    Element* element = MainFrame()->GetDocument()->getElementById("nonBlock");
    SetAndSelectRootScroller(*MainFrame()->GetDocument(), element);
    EXPECT_EQ(element, MainFrame()->GetDocument()->rootScroller());
    EXPECT_NE(element, EffectiveRootScroller(MainFrame()->GetDocument()));
  }

  {
    // Set to an element with no size.
    Element* element = MainFrame()->GetDocument()->getElementById("empty");
    SetAndSelectRootScroller(*MainFrame()->GetDocument(), element);
    EXPECT_EQ(element, MainFrame()->GetDocument()->rootScroller());
    EXPECT_NE(element, EffectiveRootScroller(MainFrame()->GetDocument()));
  }
}

// Test that the effective root scroller resets to the document Node when the
// current root scroller element becomes invalid as a scroller.
TEST_F(RootScrollerTest, TestRootScrollerBecomesInvalid) {
  Initialize("root-scroller.html");

  Element* container = MainFrame()->GetDocument()->getElementById("container");

  ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
  ASSERT_EQ(MainFrame()->GetDocument(),
            EffectiveRootScroller(MainFrame()->GetDocument()));

  {
    SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);

    EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
    EXPECT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));

    ExecuteScript(
        "document.querySelector('#container').style.display = 'inline'");
    UpdateAllLifecyclePhases(MainFrameView());

    EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
    EXPECT_EQ(MainFrame()->GetDocument(),
              EffectiveRootScroller(MainFrame()->GetDocument()));
  }

  ExecuteScript("document.querySelector('#container').style.display = 'block'");
  SetAndSelectRootScroller(*MainFrame()->GetDocument(), nullptr);
  EXPECT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
  EXPECT_EQ(MainFrame()->GetDocument(),
            EffectiveRootScroller(MainFrame()->GetDocument()));

  {
    SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);

    EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
    EXPECT_EQ(container, EffectiveRootScroller(MainFrame()->GetDocument()));

    ExecuteScript("document.querySelector('#container').style.width = '98%'");
    UpdateAllLifecyclePhases(MainFrameView());

    EXPECT_EQ(container, MainFrame()->GetDocument()->rootScroller());
    EXPECT_EQ(MainFrame()->GetDocument(),
              EffectiveRootScroller(MainFrame()->GetDocument()));
  }
}

// Tests that setting the root scroller of the top document to an element that
// belongs to a nested document works.
TEST_F(RootScrollerTest, TestSetRootScrollerOnElementInIframe) {
  Initialize("root-scroller-iframe.html");

  ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());

  {
    // Trying to set an element from a nested document should fail.
    HTMLFrameOwnerElement* iframe = ToHTMLFrameOwnerElement(
        MainFrame()->GetDocument()->getElementById("iframe"));
    Element* inner_container =
        iframe->contentDocument()->getElementById("container");

    SetAndSelectRootScroller(*MainFrame()->GetDocument(), inner_container);

    EXPECT_EQ(inner_container, MainFrame()->GetDocument()->rootScroller());
    EXPECT_EQ(inner_container,
              EffectiveRootScroller(MainFrame()->GetDocument()));
  }

  {
    // Setting the iframe itself should also work.
    HTMLFrameOwnerElement* iframe = ToHTMLFrameOwnerElement(
        MainFrame()->GetDocument()->getElementById("iframe"));

    SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);

    EXPECT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
    EXPECT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
  }
}

// Tests that setting a valid element as the root scroller on a document within
// an iframe works as expected.
TEST_F(RootScrollerTest, TestRootScrollerWithinIframe) {
  Initialize("root-scroller-iframe.html");

  ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());

  {
    HTMLFrameOwnerElement* iframe = ToHTMLFrameOwnerElement(
        MainFrame()->GetDocument()->getElementById("iframe"));

    EXPECT_EQ(iframe->contentDocument(),
              EffectiveRootScroller(iframe->contentDocument()));

    Element* inner_container =
        iframe->contentDocument()->getElementById("container");
    SetAndSelectRootScroller(*iframe->contentDocument(), inner_container);

    EXPECT_EQ(inner_container, iframe->contentDocument()->rootScroller());
    EXPECT_EQ(inner_container,
              EffectiveRootScroller(iframe->contentDocument()));
  }
}

// Tests that setting an iframe as the root scroller makes the iframe the
// effective root scroller in the parent frame.
TEST_F(RootScrollerTest, SetRootScrollerIframeBecomesEffective) {
  Initialize("root-scroller-iframe.html");
  ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());

  {
    // Try to set the root scroller in the main frame to be the iframe
    // element.
    HTMLFrameOwnerElement* iframe = ToHTMLFrameOwnerElement(
        MainFrame()->GetDocument()->getElementById("iframe"));

    SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);

    EXPECT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
    EXPECT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));

    Element* container = iframe->contentDocument()->getElementById("container");

    SetAndSelectRootScroller(*iframe->contentDocument(), container);

    EXPECT_EQ(container, iframe->contentDocument()->rootScroller());
    EXPECT_EQ(container, EffectiveRootScroller(iframe->contentDocument()));
    EXPECT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
    EXPECT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
  }
}

// Tests that the global root scroller is correctly calculated when getting the
// root scroller layer and that the viewport apply scroll is set on it.
TEST_F(RootScrollerTest, SetRootScrollerIframeUsesCorrectLayerAndCallback) {
  // TODO(bokan): The expectation and actual in the checks here are backwards.
  Initialize("root-scroller-iframe.html");
  ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());

  HTMLFrameOwnerElement* iframe = ToHTMLFrameOwnerElement(
      MainFrame()->GetDocument()->getElementById("iframe"));
  Element* container = iframe->contentDocument()->getElementById("container");

  const TopDocumentRootScrollerController& main_controller =
      MainFrame()->GetDocument()->GetPage()->GlobalRootScrollerController();

  // No root scroller set, the document node should be the global root and the
  // main LocalFrameView's scroll layer should be the layer to use.
  {
    EXPECT_EQ(main_controller.RootScrollerLayer(),
              MainFrameView()->LayoutViewport()->LayerForScrolling());
    EXPECT_TRUE(main_controller.IsViewportScrollCallback(
        MainFrame()->GetDocument()->GetApplyScroll()));
  }

  // Set a root scroller in the iframe. Since the main document didn't set a
  // root scroller, the global root scroller shouldn't change.
  {
    SetAndSelectRootScroller(*iframe->contentDocument(), container);

    EXPECT_EQ(main_controller.RootScrollerLayer(),
              MainFrameView()->LayoutViewport()->LayerForScrolling());
    EXPECT_TRUE(main_controller.IsViewportScrollCallback(
        MainFrame()->GetDocument()->GetApplyScroll()));
  }

  // Setting the iframe as the root scroller in the main frame should now
  // link the root scrollers so the container should now be the global root
  // scroller.
  {
    SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);

    ScrollableArea* container_scroller =
        ToLayoutBox(container->GetLayoutObject())->GetScrollableArea();
    EXPECT_EQ(main_controller.RootScrollerLayer(),
              container_scroller->LayerForScrolling());
    EXPECT_FALSE(main_controller.IsViewportScrollCallback(
        MainFrame()->GetDocument()->GetApplyScroll()));
    EXPECT_TRUE(
        main_controller.IsViewportScrollCallback(container->GetApplyScroll()));
  }

  // Unsetting the root scroller in the iframe should reset its effective root
  // scroller to the iframe's document node and thus it becomes the global root
  // scroller.
  {
    SetAndSelectRootScroller(*iframe->contentDocument(), nullptr);
    EXPECT_EQ(main_controller.RootScrollerLayer(), iframe->contentDocument()
                                                       ->View()
                                                       ->LayoutViewport()
                                                       ->LayerForScrolling());
    EXPECT_FALSE(
        main_controller.IsViewportScrollCallback(container->GetApplyScroll()));
    EXPECT_FALSE(main_controller.IsViewportScrollCallback(
        MainFrame()->GetDocument()->GetApplyScroll()));
    EXPECT_TRUE(main_controller.IsViewportScrollCallback(
        iframe->contentDocument()->GetApplyScroll()));
  }

  // Finally, unsetting the main frame's root scroller should reset it to the
  // document node and corresponding layer.
  {
    SetAndSelectRootScroller(*MainFrame()->GetDocument(), nullptr);
    EXPECT_EQ(main_controller.RootScrollerLayer(),
              MainFrameView()->LayoutViewport()->LayerForScrolling());
    EXPECT_TRUE(main_controller.IsViewportScrollCallback(
        MainFrame()->GetDocument()->GetApplyScroll()));
    EXPECT_FALSE(
        main_controller.IsViewportScrollCallback(container->GetApplyScroll()));
    EXPECT_FALSE(main_controller.IsViewportScrollCallback(
        iframe->contentDocument()->GetApplyScroll()));
  }
}

// Ensures that disconnecting the element currently set as the root scroller
// recomputes the effective root scroller, before a lifecycle update.
TEST_F(RootScrollerTest, RemoveCurrentRootScroller) {
  Initialize();

  WebURL base_url = url_test_helpers::ToKURL("http://www.test.com/");
  frame_test_helpers::LoadHTMLString(GetWebView()->MainFrameImpl(),
                                     "<!DOCTYPE html>"
                                     "<style>"
                                     "  body {"
                                     "    margin: 0px;"
                                     "  }"
                                     "  #container {"
                                     "    width: 100%;"
                                     "    height: 100%;"
                                     "    position: absolute;"
                                     "    overflow: auto;"
                                     "  }"
                                     "</style>"
                                     "<div id='container'></div>",
                                     base_url);

  RootScrollerController& controller =
      MainFrame()->GetDocument()->GetRootScrollerController();
  Element* container = MainFrame()->GetDocument()->getElementById("container");

  // Set the div as the rootScroller. After a lifecycle update it will be the
  // effective root scroller.
  {
    MainFrame()->GetDocument()->setRootScroller(container, ASSERT_NO_EXCEPTION);
    ASSERT_EQ(container, controller.Get());
    UpdateAllLifecyclePhases(MainFrameView());
    ASSERT_EQ(container, controller.EffectiveRootScroller());
  }

  // Remove the div from the document. It should remain the
  // document.rootScroller, however, it should be demoted from the effective
  // root scroller. The effective will fallback to the document Node.
  {
    MainFrame()->GetDocument()->body()->setTextContent("");
    EXPECT_EQ(container, controller.Get());
    EXPECT_EQ(MainFrame()->GetDocument(), controller.EffectiveRootScroller());
  }
}

// Ensures that the root scroller always gets composited with scrolling layers.
// This is necessary since we replace the Frame scrolling layers in CC as the
// OuterViewport, we need something to replace them with.
TEST_F(RootScrollerTest, AlwaysCreateCompositedScrollingLayers) {
  Initialize();

  WebURL base_url = url_test_helpers::ToKURL("http://www.test.com/");
  frame_test_helpers::LoadHTMLString(GetWebView()->MainFrameImpl(),
                                     "<!DOCTYPE html>"
                                     "<style>"
                                     "  body {"
                                     "    margin: 0px;"
                                     "  }"
                                     "  #container {"
                                     "    width: 100%;"
                                     "    height: 100%;"
                                     "    position: absolute;"
                                     "    overflow: auto;"
                                     "  }"
                                     "</style>"
                                     "<div id='container'></div>",
                                     base_url);

  GetWebView()->ResizeWithBrowserControls(IntSize(400, 400), 50, 0, true);
  UpdateAllLifecyclePhases(MainFrameView());

  Element* container = MainFrame()->GetDocument()->getElementById("container");

  PaintLayerScrollableArea* container_scroller =
      ToLayoutBox(container->GetLayoutObject())->GetScrollableArea();
  PaintLayer* layer = container_scroller->Layer();

  ASSERT_FALSE(layer->HasCompositedLayerMapping());

  SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);

  ASSERT_TRUE(layer->HasCompositedLayerMapping());
  EXPECT_TRUE(layer->GetCompositedLayerMapping()->ScrollingContentsLayer());
  EXPECT_TRUE(layer->GetCompositedLayerMapping()->ScrollingLayer());

  SetAndSelectRootScroller(*MainFrame()->GetDocument(), nullptr);

  EXPECT_FALSE(layer->HasCompositedLayerMapping());
}

TEST_F(RootScrollerTest, TestSetRootScrollerCausesViewportLayerChange) {
  // TODO(bokan): Need a test that changing root scrollers actually sets the
  // outer viewport layer on the compositor, even in the absence of other
  // compositing changes. crbug.com/505516
}

// Tests that trying to set an element as the root scroller of a document inside
// an iframe fails when that element belongs to the parent document.
// TODO(bokan): Recent changes mean this is now possible but should be fixed.
TEST_F(RootScrollerTest,
       DISABLED_TestSetRootScrollerOnElementFromOutsideIframe) {
  Initialize("root-scroller-iframe.html");

  ASSERT_EQ(nullptr, MainFrame()->GetDocument()->rootScroller());
  {
    // Try to set the the root scroller of the child document to be the
    // <iframe> element in the parent document.
    HTMLFrameOwnerElement* iframe = ToHTMLFrameOwnerElement(
        MainFrame()->GetDocument()->getElementById("iframe"));
    Element* body =
        MainFrame()->GetDocument()->QuerySelector("body", ASSERT_NO_EXCEPTION);

    EXPECT_EQ(nullptr, iframe->contentDocument()->rootScroller());

    iframe->contentDocument()->setRootScroller(iframe);

    EXPECT_EQ(iframe, iframe->contentDocument()->rootScroller());

    // Try to set the root scroller of the child document to be the
    // <body> element of the parent document.
    iframe->contentDocument()->setRootScroller(body);

    EXPECT_EQ(body, iframe->contentDocument()->rootScroller());
  }
}

// Do a basic sanity check that setting as root scroller an iframe that's remote
// doesn't crash or otherwise fail catastrophically.
TEST_F(RootScrollerTest, RemoteIFrame) {
  Initialize("root-scroller-iframe.html");

  // Initialization: Replace the iframe with a remote frame.
  MainWebFrame()->FirstChild()->Swap(frame_test_helpers::CreateRemote());

  // Set the root scroller in the local main frame to the iframe (which is
  // remote). Make sure we don't promote a remote frame to the root scroller.
  {
    Element* iframe = MainFrame()->GetDocument()->getElementById("iframe");
    SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
    EXPECT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
    EXPECT_EQ(MainFrame()->GetDocument(),
              EffectiveRootScroller(MainFrame()->GetDocument()));
    UpdateAllLifecyclePhases(MainFrameView());
  }
}

// Make sure that if an effective root scroller becomes a remote frame, it's
// immediately demoted.
TEST_F(RootScrollerTest, IFrameSwapToRemote) {
  Initialize("root-scroller-iframe.html");
  Element* iframe = MainFrame()->GetDocument()->getElementById("iframe");

  {
    SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
    ASSERT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
  }

  // Swap in a remote frame. Make sure we revert back to the document.
  {
    MainWebFrame()->FirstChild()->Swap(frame_test_helpers::CreateRemote());
    UpdateAllLifecyclePhases(MainFrameView());
    EXPECT_EQ(MainFrame()->GetDocument(),
              EffectiveRootScroller(MainFrame()->GetDocument()));
    GetWebView()->ResizeWithBrowserControls(IntSize(400, 450), 50, 0, false);
    UpdateAllLifecyclePhases(MainFrameView());
    EXPECT_EQ(MainFrame()->GetDocument(),
              EffectiveRootScroller(MainFrame()->GetDocument()));
  }
}

// Do a basic sanity check that the scrolling and root scroller machinery
// doesn't fail catastrophically in site isolation when the main frame is
// remote. Setting a root scroller in OOPIF isn't implemented yet but we should
// still scroll as before and not crash. TODO(crbug.com/730269): appears to
// segfault during teardown on TSAN.
#if defined(THREAD_SANITIZER)
TEST_F(RootScrollerTest, DISABLED_RemoteMainFrame) {
#else
TEST_F(RootScrollerTest, RemoteMainFrame) {
#endif
  WebLocalFrameImpl* local_frame;
  WebFrameWidget* widget;

  Initialize("root-scroller-iframe.html");

  // Initialization: Set the main frame to be a RemoteFrame and add a local
  // child.
  {
    WebRemoteFrameImpl* remote_main_frame = frame_test_helpers::CreateRemote();
    helper_.LocalMainFrame()->Swap(remote_main_frame);
    remote_main_frame->SetReplicatedOrigin(
        WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
    local_frame = frame_test_helpers::CreateLocalChild(*remote_main_frame);

    frame_test_helpers::LoadFrame(local_frame,
                                  base_url_ + "root-scroller-child.html");
    widget = local_frame->FrameWidget();
    widget->Resize(WebSize(400, 400));
  }

  Document* document = local_frame->GetFrameView()->GetFrame().GetDocument();
  Element* container = document->getElementById("container");

  // Try scrolling in the iframe.
  {
    widget->HandleInputEvent(
        GenerateWheelGestureEvent(WebInputEvent::kGestureScrollBegin, 0, -100));
    widget->HandleInputEvent(GenerateWheelGestureEvent(
        WebInputEvent::kGestureScrollUpdate, 0, -100));
    widget->HandleInputEvent(
        GenerateWheelGestureEvent(WebInputEvent::kGestureScrollEnd));
    EXPECT_EQ(100, container->scrollTop());
  }

  // Set the container Element as the root scroller.
  {
    SetAndSelectRootScroller(*document, container);
    EXPECT_EQ(container, document->rootScroller());
  }

  // Try scrolling in the iframe now that it has a root scroller set.
  {
    widget->HandleInputEvent(
        GenerateWheelGestureEvent(WebInputEvent::kGestureScrollBegin, 0, -100));
    widget->HandleInputEvent(GenerateWheelGestureEvent(
        WebInputEvent::kGestureScrollUpdate, 0, -100));
    widget->HandleInputEvent(
        GenerateWheelGestureEvent(WebInputEvent::kGestureScrollEnd));

    // TODO(bokan): This doesn't work right now because we notice in
    // Element::nativeApplyScroll that the container is the
    // effectiveRootScroller but the only way we expect to get to
    // nativeApplyScroll is if the effective scroller had its applyScroll
    // ViewportScrollCallback removed.  Keep the scrolls to guard crashes
    // but the expectations on when a ViewportScrollCallback have changed
    // and should be updated.
    // EXPECT_EQ(200, container->scrollTop());
  }
}

// Ensure a non-main local root doesn't interfere with the global root
// scroller. This happens in this situation: Local <- Remote <- Local. This
// tests the crash in https://crbug.com/800566.
TEST_F(RootScrollerTest, NonMainLocalRootLifecycle) {
  WebLocalFrameImpl* non_main_local_root = nullptr;

  // Setup a Local <- Remote <- Local frame hierarchy.
  {
    Initialize();
    WebURL base_url = url_test_helpers::ToKURL("http://www.test.com/");
    frame_test_helpers::LoadHTMLString(GetWebView()->MainFrameImpl(),
                                       R"HTML(
                                              <!DOCTYPE html>
                                              <iframe></iframe>
                                          )HTML",
                                       base_url);
    UpdateAllLifecyclePhases(MainFrameView());

    WebRemoteFrameImpl* remote_frame = frame_test_helpers::CreateRemote();
    WebLocalFrameImpl* child =
        ToWebLocalFrameImpl(helper_.LocalMainFrame()->FirstChild());
    child->Swap(remote_frame);
    remote_frame->SetReplicatedOrigin(
        WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);

    non_main_local_root = frame_test_helpers::CreateLocalChild(*remote_frame);
    ASSERT_EQ(non_main_local_root->LocalRoot(), non_main_local_root);
    ASSERT_TRUE(non_main_local_root->Parent());
  }

  const TopDocumentRootScrollerController& global_controller =
      MainFrame()->GetDocument()->GetPage()->GlobalRootScrollerController();

  ASSERT_EQ(MainFrame()->GetDocument(), global_controller.GlobalRootScroller());

  UpdateAllLifecyclePhases(MainFrameView());
  GraphicsLayer* scroll_layer = global_controller.RootScrollerLayer();
  GraphicsLayer* container_layer = global_controller.RootContainerLayer();

  ASSERT_TRUE(scroll_layer);
  ASSERT_TRUE(container_layer);

  // Put the local main frame into Layout clean and have the non-main local
  // root do a complete lifecycle update.
  helper_.LocalMainFrame()->GetFrameView()->SetNeedsLayout();
  helper_.LocalMainFrame()->GetFrameView()->UpdateLifecycleToLayoutClean();
  UpdateAllLifecyclePhases(non_main_local_root->GetFrameView());
  UpdateAllLifecyclePhases(helper_.LocalMainFrame()->GetFrameView());

  EXPECT_EQ(MainFrame()->GetDocument(), global_controller.GlobalRootScroller());
  EXPECT_EQ(global_controller.RootScrollerLayer(), scroll_layer);
  EXPECT_EQ(global_controller.RootContainerLayer(), container_layer);
}

// Tests that removing the root scroller element from the DOM resets the
// effective root scroller without waiting for any lifecycle events.
TEST_F(RootScrollerTest, RemoveRootScrollerFromDom) {
  Initialize("root-scroller-iframe.html");

  {
    HTMLFrameOwnerElement* iframe = ToHTMLFrameOwnerElement(
        MainFrame()->GetDocument()->getElementById("iframe"));
    Element* inner_container =
        iframe->contentDocument()->getElementById("container");

    SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);
    SetAndSelectRootScroller(*iframe->contentDocument(), inner_container);

    ASSERT_EQ(iframe, MainFrame()->GetDocument()->rootScroller());
    ASSERT_EQ(iframe, EffectiveRootScroller(MainFrame()->GetDocument()));
    ASSERT_EQ(inner_container, iframe->contentDocument()->rootScroller());
    ASSERT_EQ(inner_container,
              EffectiveRootScroller(iframe->contentDocument()));

    iframe->contentDocument()->body()->SetInnerHTMLFromString("");

    // If the root scroller wasn't updated by the DOM removal above, this
    // will touch the disposed root scroller's ScrollableArea.
    MainFrameView()->GetRootFrameViewport()->ServiceScrollAnimations(0);
  }
}

// Tests that we still have a global root scroller layer when the HTML element
// has no layout object. crbug.com/637036.
TEST_F(RootScrollerTest, DocumentElementHasNoLayoutObject) {
  Initialize("overflow-scrolling.html");

  // There's no rootScroller set on this page so we should default to the
  // document Node, which means we should use the layout viewport. Ensure this
  // happens even if the <html> element has no LayoutObject.
  ExecuteScript("document.documentElement.style.display = 'none';");

  const TopDocumentRootScrollerController& global_controller =
      MainFrame()->GetDocument()->GetPage()->GlobalRootScrollerController();

  EXPECT_EQ(MainFrame()->GetDocument(), global_controller.GlobalRootScroller());
  EXPECT_EQ(MainFrameView()->LayoutViewport()->LayerForScrolling(),
            global_controller.RootScrollerLayer());
}

// On Android, the main scrollbars are owned by the visual viewport and the
// LocalFrameView's disabled. This functionality should extend to a rootScroller
// that isn't the main LocalFrameView.
TEST_F(RootScrollerTest, UseVisualViewportScrollbars) {
  Initialize("root-scroller.html");

  Element* container = MainFrame()->GetDocument()->getElementById("container");
  SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);

  ScrollableArea* container_scroller =
      ToLayoutBox(container->GetLayoutObject())->GetScrollableArea();
  EXPECT_FALSE(container_scroller->HorizontalScrollbar());
  EXPECT_FALSE(container_scroller->VerticalScrollbar());
  EXPECT_GT(container_scroller->MaximumScrollOffset().Width(), 0);
  EXPECT_GT(container_scroller->MaximumScrollOffset().Height(), 0);
}

// On Android, the main scrollbars are owned by the visual viewport and the
// LocalFrameView's disabled. This functionality should extend to a rootScroller
// that's a nested iframe.
TEST_F(RootScrollerTest, UseVisualViewportScrollbarsIframe) {
  Initialize("root-scroller-iframe.html");

  Element* iframe = MainFrame()->GetDocument()->getElementById("iframe");
  LocalFrame* child_frame =
      ToLocalFrame(ToHTMLFrameOwnerElement(iframe)->ContentFrame());

  SetAndSelectRootScroller(*MainFrame()->GetDocument(), iframe);

  WebLocalFrame* child_web_frame =
      MainWebFrame()->FirstChild()->ToWebLocalFrame();
  ExecuteScript(
      "document.getElementById('container').style.width = '200%';"
      "document.getElementById('container').style.height = '200%';",
      *child_web_frame);

  UpdateAllLifecyclePhases(MainFrameView());

  ScrollableArea* container_scroller = child_frame->View()->LayoutViewport();

  EXPECT_FALSE(container_scroller->HorizontalScrollbar());
  EXPECT_FALSE(container_scroller->VerticalScrollbar());
  EXPECT_GT(container_scroller->MaximumScrollOffset().Width(), 0);
  EXPECT_GT(container_scroller->MaximumScrollOffset().Height(), 0);
}

TEST_F(RootScrollerTest, TopControlsAdjustmentAppliedToRootScroller) {
  Initialize();

  WebURL base_url = url_test_helpers::ToKURL("http://www.test.com/");
  frame_test_helpers::LoadHTMLString(GetWebView()->MainFrameImpl(),
                                     "<!DOCTYPE html>"
                                     "<style>"
                                     "  body, html {"
                                     "    width: 100%;"
                                     "    height: 100%;"
                                     "    margin: 0px;"
                                     "  }"
                                     "  #container {"
                                     "    width: 100%;"
                                     "    height: 100%;"
                                     "    overflow: auto;"
                                     "  }"
                                     "</style>"
                                     "<div id='container'>"
                                     "  <div style='height:1000px'>test</div>"
                                     "</div>",
                                     base_url);

  GetWebView()->ResizeWithBrowserControls(IntSize(400, 400), 50, 0, true);
  UpdateAllLifecyclePhases(MainFrameView());

  Element* container = MainFrame()->GetDocument()->getElementById("container");
  SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);

  ScrollableArea* container_scroller =
      ToLayoutBox(container->GetLayoutObject())->GetScrollableArea();

  // Hide the top controls and scroll down maximally. We should account for the
  // change in maximum scroll offset due to the top controls hiding. That is,
  // since the controls are hidden, the "content area" is taller so the maximum
  // scroll offset should shrink.
  ASSERT_EQ(1000 - 400, container_scroller->MaximumScrollOffset().Height());

  GetWebView()->MainFrameWidget()->HandleInputEvent(
      GenerateTouchGestureEvent(WebInputEvent::kGestureScrollBegin));
  ASSERT_EQ(1, GetBrowserControls().ShownRatio());
  GetWebView()->MainFrameWidget()->HandleInputEvent(
      GenerateTouchGestureEvent(WebInputEvent::kGestureScrollUpdate, 0,
                                -GetBrowserControls().TopHeight()));
  ASSERT_EQ(0, GetBrowserControls().ShownRatio());
  EXPECT_EQ(1000 - 450, container_scroller->MaximumScrollOffset().Height());

  GetWebView()->MainFrameWidget()->HandleInputEvent(
      GenerateTouchGestureEvent(WebInputEvent::kGestureScrollUpdate, 0, -3000));
  EXPECT_EQ(1000 - 450, container_scroller->GetScrollOffset().Height());

  GetWebView()->MainFrameWidget()->HandleInputEvent(
      GenerateTouchGestureEvent(WebInputEvent::kGestureScrollEnd));
  GetWebView()->ResizeWithBrowserControls(IntSize(400, 450), 50, 0, false);
  EXPECT_EQ(1000 - 450, container_scroller->MaximumScrollOffset().Height());
}

TEST_F(RootScrollerTest, RotationAnchoring) {
  Initialize("root-scroller-rotation.html");

  ScrollableArea* container_scroller;

  {
    GetWebView()->ResizeWithBrowserControls(IntSize(250, 1000), 0, 0, true);
    UpdateAllLifecyclePhases(MainFrameView());

    Element* container =
        MainFrame()->GetDocument()->getElementById("container");
    SetAndSelectRootScroller(*MainFrame()->GetDocument(), container);

    container_scroller =
        ToLayoutBox(container->GetLayoutObject())->GetScrollableArea();
  }

  Element* target = MainFrame()->GetDocument()->getElementById("target");

  // Zoom in and scroll the viewport so that the target is fully in the
  // viewport and the visual viewport is fully scrolled within the layout
  // viepwort.
  {
    int scroll_x = 250 * 4;
    int scroll_y = 1000 * 4;

    GetWebView()->SetPageScaleFactor(2);
    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollBegin));
    GetWebView()->MainFrameWidget()->HandleInputEvent(GenerateTouchGestureEvent(
        WebInputEvent::kGestureScrollUpdate, -scroll_x, -scroll_y));
    GetWebView()->MainFrameWidget()->HandleInputEvent(
        GenerateTouchGestureEvent(WebInputEvent::kGestureScrollEnd));

    // The visual viewport should be 1.5 screens scrolled so that the target
    // occupies the bottom quadrant of the layout viewport.
    ASSERT_EQ((250 * 3) / 2, container_scroller->GetScrollOffset().Width());
    ASSERT_EQ((1000 * 3) / 2, container_scroller->GetScrollOffset().Height());

    // The visual viewport should have scrolled the last half layout viewport.
    ASSERT_EQ((250) / 2, GetVisualViewport().GetScrollOffset().Width());
    ASSERT_EQ((1000) / 2, GetVisualViewport().GetScrollOffset().Height());
  }

  // Now do a rotation resize.
  GetWebView()->ResizeWithBrowserControls(IntSize(1000, 250), 50, 0, false);
  UpdateAllLifecyclePhases(MainFrameView());

  // The visual viewport should remain fully filled by the target.
  DOMRect* rect = target->getBoundingClientRect();
  EXPECT_EQ(rect->left(), GetVisualViewport().GetScrollOffset().Width());
  EXPECT_EQ(rect->top(), GetVisualViewport().GetScrollOffset().Height());
}

// Tests that we don't crash if the default documentElement isn't a valid root
// scroller. This can happen in some edge cases where documentElement isn't
// <html>. crbug.com/668553.
TEST_F(RootScrollerTest, InvalidDefaultRootScroller) {
  Initialize("overflow-scrolling.html");

  Document* document = MainFrame()->GetDocument();

  Element* br = document->CreateRawElement(html_names::kBrTag);
  document->ReplaceChild(br, document->documentElement());
  UpdateAllLifecyclePhases(MainFrameView());
  Element* html = document->CreateRawElement(html_names::kHTMLTag);
  Element* body = document->CreateRawElement(html_names::kBodyTag);
  html->AppendChild(body);
  body->AppendChild(br);
  document->AppendChild(html);
  UpdateAllLifecyclePhases(MainFrameView());
}

// Makes sure that when an iframe becomes the effective root scroller, its
// FrameView stops sizing layout to the frame rect and uses its parent's layout
// size instead. This allows matching the layout size semantics of the root
// FrameView since its layout size can differ from the frame rect due to
// resizes by the URL bar.
TEST_F(RootScrollerTest, IFrameRootScrollerGetsNonFixedLayoutSize) {
  Initialize("root-scroller-iframe.html");
  UpdateAllLifecyclePhases(MainFrameView());

  Document* document = MainFrame()->GetDocument();
  HTMLFrameOwnerElement* iframe = ToHTMLFrameOwnerElement(
      MainFrame()->GetDocument()->getElementById("iframe"));
  LocalFrameView* iframe_view = ToLocalFrame(iframe->ContentFrame())->View();

  ASSERT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
  ASSERT_EQ(IntSize(400, 400), iframe_view->Size());
  ASSERT_TRUE(iframe_view->LayoutSizeFixedToFrameSize());

  // Make the iframe the rootscroller. This should cause the iframe's layout
  // size to be manually controlled.
  {
    SetAndSelectRootScroller(*document, iframe);
    EXPECT_FALSE(iframe_view->LayoutSizeFixedToFrameSize());
    EXPECT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
    EXPECT_EQ(IntSize(400, 400), iframe_view->Size());
  }

  // Hide the URL bar, the iframe's frame rect should expand but the layout
  // size should remain the same.
  {
    GetWebView()->ResizeWithBrowserControls(IntSize(400, 450), 50, 0, false);
    UpdateAllLifecyclePhases(MainFrameView());
    EXPECT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
    EXPECT_EQ(IntSize(400, 450), iframe_view->Size());
  }

  // Simulate a rotation. This time the layout size should reflect the resize.
  {
    GetWebView()->ResizeWithBrowserControls(IntSize(450, 400), 50, 0, false);
    UpdateAllLifecyclePhases(MainFrameView());
    EXPECT_EQ(IntSize(450, 350), iframe_view->GetLayoutSize());
    EXPECT_EQ(IntSize(450, 400), iframe_view->Size());

    // "Un-rotate" for following tests.
    GetWebView()->ResizeWithBrowserControls(IntSize(400, 450), 50, 0, false);
    UpdateAllLifecyclePhases(MainFrameView());
  }

  // Show the URL bar again. The frame rect should match the viewport.
  {
    GetWebView()->ResizeWithBrowserControls(IntSize(400, 400), 50, 0, true);
    UpdateAllLifecyclePhases(MainFrameView());
    EXPECT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
    EXPECT_EQ(IntSize(400, 400), iframe_view->Size());
  }

  // Hide the URL bar and reset the rootScroller. The iframe should go back to
  // tracking layout size by frame rect.
  {
    GetWebView()->ResizeWithBrowserControls(IntSize(400, 450), 50, 0, false);
    UpdateAllLifecyclePhases(MainFrameView());
    EXPECT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
    EXPECT_EQ(IntSize(400, 450), iframe_view->Size());
    SetAndSelectRootScroller(*document, nullptr);
    EXPECT_TRUE(iframe_view->LayoutSizeFixedToFrameSize());
    EXPECT_EQ(IntSize(400, 400), iframe_view->GetLayoutSize());
    EXPECT_EQ(IntSize(400, 400), iframe_view->Size());
  }
}

// Ensure that removing the root scroller element causes an update to the RFV's
// layout viewport immediately since old layout viewport is now part of a
// detached layout hierarchy.
TEST_F(RootScrollerTest, ImmediateUpdateOfLayoutViewport) {
  Initialize("root-scroller-iframe.html");

  Document* document = MainFrame()->GetDocument();
  HTMLFrameOwnerElement* iframe = ToHTMLFrameOwnerElement(
      MainFrame()->GetDocument()->getElementById("iframe"));

  SetAndSelectRootScroller(*document, iframe);

  RootScrollerController& main_controller =
      MainFrame()->GetDocument()->GetRootScrollerController();

  LocalFrame* iframe_local_frame = ToLocalFrame(iframe->ContentFrame());
  EXPECT_EQ(iframe, &main_controller.EffectiveRootScroller());
  EXPECT_EQ(iframe_local_frame->View()->LayoutViewport(),
            &MainFrameView()->GetRootFrameViewport()->LayoutViewport());

  // Remove the <iframe> and make sure the layout viewport reverts to the
  // LocalFrameView without a layout.
  iframe->remove();

  EXPECT_EQ(MainFrameView()->LayoutViewport(),
            &MainFrameView()->GetRootFrameViewport()->LayoutViewport());
}

class RootScrollerSimTest : public SimTest {
 public:
  RootScrollerSimTest() : implicit_root_scroller_for_test_(false) {}

  void SetUp() override {
    SimTest::SetUp();
    WebView().GetPage()->GetSettings().SetViewportEnabled(true);
  }

 private:
  ScopedImplicitRootScrollerForTest implicit_root_scroller_for_test_;
};

// Test that setting a root scroller causes us to request a begin frame.
// However, until a frame is produced, the effective root scroller should
// not change.
TEST_F(RootScrollerSimTest, SetCausesNeedsBeginFrame) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            body, html {
              margin: 0;
              width: 100%;
              height: 100%;
            }
            #container {
              width: 100%;
              height: 100%;
              overflow: scroll;
            }
          </style>
          <div id="container"></div>
      )HTML");
  Compositor().BeginFrame();
  ASSERT_FALSE(Compositor().NeedsBeginFrame());

  Element* container = GetDocument().getElementById("container");
  GetDocument().setRootScroller(container);

  // Setting the root scroller should cause us to need a new frame but we
  // shouldn't have set the effective yet.
  EXPECT_TRUE(Compositor().NeedsBeginFrame());
  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  Compositor().BeginFrame();

  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
}

// Test that the cached IsEffectiveRootScroller bit on LayoutObject is set
// correctly when the Document is the effective root scroller. It becomes the
// root scroller before Document has a LayoutView.
TEST_F(RootScrollerSimTest, DocumentEffectiveSetsCachedBit) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
      )HTML");
  Compositor().BeginFrame();

  EXPECT_TRUE(GetDocument().GetLayoutView()->IsEffectiveRootScroller());
}

// Test that layout from outside a lifecycle wont select a new effective root
// scroller.
TEST_F(RootScrollerSimTest, NonLifecycleLayoutDoesntCauseReselection) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            body, html {
              margin: 0;
              width: 100%;
              height: 100%;
            }
            #container {
              width: 100%;
              height: 100%;
              overflow: scroll;
            }
          </style>
          <div id="container"></div>
      )HTML");
  Element* container = GetDocument().getElementById("container");
  GetDocument().setRootScroller(container);
  Compositor().BeginFrame();
  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  container->style()->setProperty(&GetDocument(), "width", "95%", String(),
                                  ASSERT_NO_EXCEPTION);

  ASSERT_TRUE(Compositor().NeedsBeginFrame());

  // Cause a layout.
  container->scrollTop();
  ASSERT_TRUE(Compositor().NeedsBeginFrame());

  // Shouldn't yet cause a change since we haven't done a full lifecycle update.
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  Compositor().BeginFrame();

  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
}

// Tests that we don't explode when a layout occurs and the effective
// rootScroller no longer has a ContentFrame(). We setup the frame tree such
// that the first iframe is the effective root scroller. The second iframe has
// an unload handler that reaches back to the common parent and causes a
// layout. This will cause us to recalculate the effective root scroller while
// the current one is valid in all ways except that it no longer has a content
// frame. This test passes if it doesn't crash. https://crbug.com/805317.
TEST_F(RootScrollerSimTest, RecomputeEffectiveWithNoContentFrame) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  SimRequest first_request("https://example.com/first.html", "text/html");
  SimRequest second_request("https://example.com/second.html", "text/html");
  SimRequest final_request("https://newdomain.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
          </style>
          <iframe id="first" src="https://example.com/first.html">
          </iframe>
          <iframe id="second" src="https://example.com/second.html">
          </iframe>
          <script>
            // Dirty layout on unload
            window.addEventListener('unload', function() {
                document.getElementById("first").style.width="0";
            });
          </script>
      )HTML");

  first_request.Complete(R"HTML(
          <!DOCTYPE html>
      )HTML");

  second_request.Complete(R"HTML(
          <!DOCTYPE html>
          <body></body>
          <script>
            window.addEventListener('unload', function() {
                // This will do a layout.
                window.top.document.getElementById("first").clientWidth;
            });
          </script>
      )HTML");

  Element* container = GetDocument().getElementById("first");
  GetDocument().GetRootScrollerController().Set(container);
  Compositor().BeginFrame();

  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // This will unload first the root, then the first frame, then the second.
  LoadURL("https://newdomain.com/test.html");
  final_request.Complete(R"HTML(
          <!DOCTYPE html>
      )HTML");
}

// Test that the element is considered to be viewport filling only if its
// padding box fills the viewport. That means it must have no border.
TEST_F(RootScrollerSimTest, UsePaddingBoxForViewportFillingCondition) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            body {
              margin: 0;
            }
            #container {
              position: absolute;
              width: 100%;
              height: 100%;
              box-sizing: border-box;
              overflow: scroll;
            }
          </style>
          <div id="container"></div>
      )HTML");

  Element* container = GetDocument().getElementById("container");
  GetDocument().setRootScroller(container);
  Compositor().BeginFrame();

  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // Setting a border should cause the element to no longer be valid as its
  // padding box doesn't fill the viewport exactly.
  container->setAttribute(html_names::kStyleAttr, "border: 1px solid black");
  Compositor().BeginFrame();
  EXPECT_EQ(&GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
}

// Tests that the root scroller doesn't affect visualViewport pageLeft and
// pageTop.
TEST_F(RootScrollerSimTest, RootScrollerDoesntAffectVisualViewport) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Write(R"HTML(
          <!DOCTYPE html>
          <style>
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }

            #spacer {
              width: 1000px;
              height: 1000px;
            }

            #container {
              width: 100%;
              height: 100%;
              overflow: auto;
            }
          </style>
          <div id="container">
            <div id="spacer"></div>
          </div>
      )HTML");

  GetDocument().GetPage()->GetVisualViewport().SetScale(2);
  GetDocument().GetPage()->GetVisualViewport().SetLocation(
      FloatPoint(100, 120));

  LocalFrame* frame = ToLocalFrame(GetDocument().GetPage()->MainFrame());
  EXPECT_EQ(100, frame->DomWindow()->visualViewport()->pageLeft());
  EXPECT_EQ(120, frame->DomWindow()->visualViewport()->pageTop());

  request.Finish();
  Compositor().BeginFrame();

  Element* container = GetDocument().getElementById("container");
  GetDocument().setRootScroller(container);

  Compositor().BeginFrame();

  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
  container->setScrollTop(50);
  container->setScrollLeft(60);

  ASSERT_EQ(50, container->scrollTop());
  ASSERT_EQ(60, container->scrollLeft());
  ASSERT_EQ(100, frame->DomWindow()->visualViewport()->pageLeft());
  EXPECT_EQ(120, frame->DomWindow()->visualViewport()->pageTop());
}

// Tests that we don't crash or violate lifecycle assumptions when we resize
// from within layout.
TEST_F(RootScrollerSimTest, ResizeFromResizeAfterLayout) {
  WebView().GetSettings()->SetShrinksViewportContentToFit(true);
  WebView().SetDefaultPageScaleLimits(0.25f, 5);

  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Write(R"HTML(
          <!DOCTYPE html>
          <style>
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }

            #spacer {
              width: 1000px;
              height: 1000px;
            }

            #container {
              width: 100%;
              height: 100%;
              border: 0;
            }
          </style>
          <iframe id="container"
                  srcdoc="<!DOCTYPE html>
                          <style>html {height: 300%;}</style>">
          </iframe>
      )HTML");
  Element* container = GetDocument().getElementById("container");
  GetDocument().setRootScroller(container);
  Compositor().BeginFrame();
  RunPendingTasks();
  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
  ASSERT_EQ(IntSize(800, 600), GetDocument().View()->Size());

  request.Write(R"HTML(
          <div style="width:2000px;height:1000px"></div>
      )HTML");
  request.Finish();
  Compositor().BeginFrame();

  ASSERT_EQ(IntSize(2000, 1500), GetDocument().View()->Size());
}

class ImplicitRootScrollerSimTest : public SimTest {
 public:
  ImplicitRootScrollerSimTest()
      : root_scroller_for_test_(false),
        implicit_root_scroller_for_test_(true) {}

  void SetUp() override {
    SimTest::SetUp();
    WebView().GetPage()->GetSettings().SetViewportEnabled(true);
  }

 private:
  ScopedSetRootScrollerForTest root_scroller_for_test_;
  ScopedImplicitRootScrollerForTest implicit_root_scroller_for_test_;
};

// Tests basic implicit root scroller mode with a <div>.
TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScroller) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            html {
              overflow: hidden;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            #spacer {
              width: 1000px;
              height: 1000px;
            }
            #container {
              width: 100%;
              height: 100%;
            }
          </style>
          <div id="container">
            <div id="spacer"></div>
          </div>
      )HTML");
  Compositor().BeginFrame();

  ASSERT_EQ(&GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
  Element* container = GetDocument().getElementById("container");

  // overflow: auto and overflow: scroll should cause a valid element to be
  // promoted to root scroller. Otherwise, they shouldn't, even if they're
  // otherwise a valid root scroller element.
  std::vector<std::tuple<String, String, Node*>> test_cases = {
      {"overflow", "hidden", &GetDocument()},
      {"overflow", "auto", container},
      {"overflow", "scroll", container},
      {"overflow", "visible", &GetDocument()},
      // Overflow: hidden in one axis forces the other axis to auto so it should
      // be promoted.
      {"overflow-x", "hidden", container},
      {"overflow-x", "auto", container},
      {"overflow-x", "scroll", container},
      {"overflow-x", "visible", &GetDocument()},
      {"overflow-y", "hidden", container},
      {"overflow-y", "auto", container},
      {"overflow-y", "scroll", container},
      {"overflow-y", "visible", &GetDocument()}};

  for (auto test_case : test_cases) {
    String& style = std::get<0>(test_case);
    String& style_val = std::get<1>(test_case);
    Node* expected_root_scroller = std::get<2>(test_case);

    container->style()->setProperty(&GetDocument(), style, style_val, String(),
                                    ASSERT_NO_EXCEPTION);
    Compositor().BeginFrame();
    ASSERT_EQ(expected_root_scroller,
              GetDocument().GetRootScrollerController().EffectiveRootScroller())
        << "Failed to set rootScroller after setting " << std::get<0>(test_case)
        << ": " << std::get<1>(test_case);
    container->style()->setProperty(&GetDocument(), std::get<0>(test_case),
                                    String(), String(), ASSERT_NO_EXCEPTION);
    Compositor().BeginFrame();
    ASSERT_EQ(&GetDocument(),
              GetDocument().GetRootScrollerController().EffectiveRootScroller())
        << "Failed to reset rootScroller after setting "
        << std::get<0>(test_case) << ": " << std::get<1>(test_case);
  }

  // Now remove the overflowing element and rerun the tests. The container
  // element should no longer be implicitly promoted as it doesn't have any
  // overflow.
  Element* spacer = GetDocument().getElementById("spacer");
  spacer->remove();

  for (auto test_case : test_cases) {
    String& style = std::get<0>(test_case);
    String& style_val = std::get<1>(test_case);
    Node* expected_root_scroller = &GetDocument();

    container->style()->setProperty(&GetDocument(), style, style_val, String(),
                                    ASSERT_NO_EXCEPTION);
    Compositor().BeginFrame();
    ASSERT_EQ(expected_root_scroller,
              GetDocument().GetRootScrollerController().EffectiveRootScroller())
        << "Failed to set rootScroller after setting " << std::get<0>(test_case)
        << ": " << std::get<1>(test_case);

    container->style()->setProperty(&GetDocument(), std::get<0>(test_case),
                                    String(), String(), ASSERT_NO_EXCEPTION);
    Compositor().BeginFrame();
    ASSERT_EQ(&GetDocument(),
              GetDocument().GetRootScrollerController().EffectiveRootScroller())
        << "Failed to reset rootScroller after setting "
        << std::get<0>(test_case) << ": " << std::get<1>(test_case);
  }
}

// Test that adding overflow to an element that would otherwise be eligable to
// be implicitly pomoted causes promotion.
TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScrollerAddOverflow) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            #container {
              width: 100%;
              height: 100%;
              overflow: auto;
            }
          </style>
          <div id="container">
            <div id="spacer"></div>
          </div>
      )HTML");
  Compositor().BeginFrame();

  ASSERT_EQ(&GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Shouldn't promote 'container' since it has no overflow.";

  Element* spacer = GetDocument().getElementById("spacer");
  spacer->style()->setProperty(&GetDocument(), "height", "2000px", String(),
                               ASSERT_NO_EXCEPTION);
  spacer->style()->setProperty(&GetDocument(), "width", "2000px", String(),
                               ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  Element* container = GetDocument().getElementById("container");
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Adding overflow should cause 'container' to be promoted.";
}

// Tests that we don't crash if an implicit candidate is no longer a box. This
// test passes if it doesn't crash.
TEST_F(ImplicitRootScrollerSimTest, CandidateLosesLayoutBoxDontCrash) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            #spacer {
              width: 300px;
              height: 300px;
            }

            .box {
              width: 200px;
              height: 200px;
              overflow: scroll;
              display: block;
            }

            .nonbox {
              display: inline;
            }
          </style>
          <b id="container">
            <div id="spacer"></div>
          </b>
      )HTML");
  Element* container = GetDocument().getElementById("container");

  // An overflowing box will be added to the implicit candidates list.
  container->setAttribute(html_names::kClassAttr, "box");
  Compositor().BeginFrame();

  // This will make change from a box to an inline. Ensure we don't crash when
  // we reevaluate the candidates list.
  container->setAttribute(html_names::kClassAttr, "nonbox");
  Compositor().BeginFrame();
}

// Ensure that a plugin view being considered for implicit promotion doesn't
// cause a crash. https://crbug.com/903440.
TEST_F(ImplicitRootScrollerSimTest, ConsiderEmbedCrash) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <embed id="embed" height="1" src="data:video/mp4,">
          <script>
           embed.type = "JavaScript 1.5";
           embed.src = "x";
          </script>
      )HTML");
  Compositor().BeginFrame();
  Element* embed = GetDocument().getElementById("embed");
  GetDocument().GetRootScrollerController().ConsiderForImplicit(*embed);
}

// Test that a valid implicit root scroller wont be promoted/will be demoted if
// the main document has overflow.
TEST_F(ImplicitRootScrollerSimTest,
       ImplicitRootScrollerDocumentScrollsOverflow) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            #container {
              width: 100%;
              height: 100%;
              overflow: auto;
            }
            #spacer {
              width: 2000px;
              height: 2000px;
            }
          </style>
          <div id="container">
            <div id="spacer"></div>
          </div>
          <div id="overflow"></div>
      )HTML");
  Compositor().BeginFrame();

  Element* container = GetDocument().getElementById("container");
  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  Element* overflow = GetDocument().getElementById("overflow");
  overflow->style()->setProperty(&GetDocument(), "height", "10px", String(),
                                 ASSERT_NO_EXCEPTION);
  overflow->style()->setProperty(&GetDocument(), "width", "10px", String(),
                                 ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(&GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Adding overflow to document should cause 'container' to be demoted.";

  overflow->remove();
  Compositor().BeginFrame();
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Removing document overflow should cause 'container' to be promoted.";
}

// Test that we'll only implicitly promote an element if its visible.
TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScrollerVisibilityCondition) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            #container {
              width: 100%;
              height: 100%;
              overflow: auto;
            }
            #spacer {
              width: 2000px;
              height: 2000px;
            }
          </style>
          <div id="container">
            <div id="spacer"></div>
          </div>
      )HTML");
  Compositor().BeginFrame();

  Element* container = GetDocument().getElementById("container");
  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  container->style()->setProperty(&GetDocument(), "opacity", "0.5", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(&GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Adding opacity to 'container' causes it to be demoted.";

  container->style()->setProperty(&GetDocument(), "opacity", "", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Removing opacity from 'container' causes it to be promoted.";

  container->style()->setProperty(&GetDocument(), "visibility", "hidden",
                                  String(), ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(&GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "visibility:hidden causes 'container' to be demoted.";

  container->style()->setProperty(&GetDocument(), "visibility", "collapse",
                                  String(), ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(&GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "visibility:collapse doesn't cause 'container' to be promoted.";

  container->style()->setProperty(&GetDocument(), "visibility", "visible",
                                  String(), ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "visibility:visible causes promotion";
}

// Tests implicit root scroller mode for iframes.
TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScrollerIframe) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
          </style>
          <iframe id="container"
                  srcdoc="<!DOCTYPE html><style>html {height: 300%;}</style>">
          </iframe>
      )HTML");
  // srcdoc iframe loads via posted tasks.
  RunPendingTasks();
  Compositor().BeginFrame();

  Element* container = GetDocument().getElementById("container");
  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  container->style()->setProperty(&GetDocument(), "height", "95%", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();

  ASSERT_EQ(&GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
}

// Tests use counter for implicit root scroller. Ensure it's not counted on a
// page without an implicit root scroller.
TEST_F(ImplicitRootScrollerSimTest, UseCounterNegative) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            div {
              width: 100%;
              height: 100%;
            }
          </style>
          <div id="container"></div>
      )HTML");
  Compositor().BeginFrame();

  Element* container = GetDocument().getElementById("container");
  ASSERT_NE(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  EXPECT_FALSE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kActivatedImplicitRootScroller));

  container->style()->setProperty(&GetDocument(), "height", "150%", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();

  EXPECT_FALSE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kActivatedImplicitRootScroller));
}

// Tests use counter for implicit root scroller. Ensure it's counted on a
// page that loads with an implicit root scroller.
TEST_F(ImplicitRootScrollerSimTest, UseCounterPositive) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            #container {
              width: 100%;
              height: 100%;
              overflow: auto;
            }
            #spacer {
              height: 2000px;
            }
          </style>
          <div id="container">
            <div id="spacer"></div>
          </div>
      )HTML");
  Compositor().BeginFrame();

  Element* container = GetDocument().getElementById("container");
  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  EXPECT_TRUE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kActivatedImplicitRootScroller));

  container->style()->setProperty(&GetDocument(), "height", "150%", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();

  ASSERT_NE(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  EXPECT_TRUE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kActivatedImplicitRootScroller));
}

// Tests use counter for implicit root scroller. Ensure it's counted on a
// page that loads without an implicit root scroller but later gets one.
TEST_F(ImplicitRootScrollerSimTest, UseCounterPositiveAfterLoad) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            #container {
              width: 100%;
              height: 40%;
              overflow: auto;
            }
            #spacer {
              height: 2000px;
            }
          </style>
          <div id="container">
            <div id="spacer"></div>
          </div>
      )HTML");
  Compositor().BeginFrame();

  Element* container = GetDocument().getElementById("container");
  ASSERT_NE(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  EXPECT_FALSE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kActivatedImplicitRootScroller));

  container->style()->setProperty(&GetDocument(), "height", "100%", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();

  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  EXPECT_TRUE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kActivatedImplicitRootScroller));
}

// Tests that if we have multiple valid candidates for implicit promotion, we
// don't promote either.
TEST_F(ImplicitRootScrollerSimTest, DontPromoteWhenMultipleAreValid) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              position: absolute;
              left: 0;
              top: 0;
              width: 100%;
              height: 100%;
              border: 0;
            }
          </style>
          <iframe id="container"
                  srcdoc="<!DOCTYPE html><style>html {height: 300%;}</style>">
          </iframe>
          <iframe id="container2"
                  srcdoc="<!DOCTYPE html><style>html {height: 300%;}</style>">
          </iframe>
      )HTML");
  // srcdoc iframe loads via posted tasks.
  RunPendingTasks();
  Compositor().BeginFrame();

  // Since both iframes are valid candidates, neither should be promoted.
  ASSERT_EQ(&GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // Now make the second one invalid, that should cause the first to be
  // promoted.
  Element* container2 = GetDocument().getElementById("container2");
  container2->style()->setProperty(&GetDocument(), "height", "95%", String(),
                                   ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();

  Element* container = GetDocument().getElementById("container");
  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
}

// Test that when a valid iframe becomes loaded and thus should be promoted, it
// becomes the root scroller, without needing an intervening layout.
TEST_F(ImplicitRootScrollerSimTest, IframeLoadedWithoutLayout) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest main_request("https://example.com/test.html", "text/html");
  SimRequest child_request("https://example.com/child.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
          </style>
          <iframe id="container" src="child.html">
          </iframe>
      )HTML");
  Compositor().BeginFrame();
  ASSERT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "The iframe isn't yet scrollable.";

  // Ensure that it gets promoted when the new FrameView is connected even
  // though there's no layout in the parent to trigger it.
  child_request.Complete(R"HTML(
        <!DOCTYPE html>
        <style>
          body {
            height: 1000px;
          }
        </style>
  )HTML");

  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument().getElementById("container"),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Once loaded, the iframe should be promoted.";
}

// Ensure that navigating an iframe while it is the effective root scroller,
// causes it to remain the effective root scroller after the navigation (to a
// page where it remains valid) is finished.
TEST_F(ImplicitRootScrollerSimTest, NavigateToValidRemainsRootScroller) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest main_request("https://example.com/test.html", "text/html");
  SimRequest child_request("https://example.com/child.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
          </style>
          <iframe id="container" src="child.html">
          </iframe>
      )HTML");
  child_request.Complete(R"HTML(
        <!DOCTYPE html>
        <style>
          body {
            height: 1000px;
          }
        </style>
  )HTML");
  Compositor().BeginFrame();
  ASSERT_EQ(GetDocument().getElementById("container"),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // Navigate the child frame. When it's loaded, the FrameView should swap.
  // Ensure that we remain the root scroller even though there's no layout in
  // the parent.
  SimRequest child_request2("https://example.com/child-next.html", "text/html");
  frame_test_helpers::LoadFrameDontWait(
      WebView().MainFrameImpl()->FirstChild()->ToWebLocalFrame(),
      KURL("https://example.com/child-next.html"));

  child_request2.Write(R"HTML(
        <!DOCTYPE html>
  )HTML");
  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "The iframe should be demoted once a navigation is committed";

  // Ensure that it gets promoted when the new FrameView is connected even
  // though there's no layout in the parent to trigger it.
  child_request2.Write(R"HTML(
        <style>
          body {
            height: 2000px;
          }
        </style>
  )HTML");
  child_request2.Finish();
  Compositor().BeginFrame();

  EXPECT_EQ(GetDocument().getElementById("container"),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Once loaded, the iframe should be promoted again.";
}

// Test that a root scroller is considered to fill the viewport at both the URL
// bar shown and URL bar hidden height.
TEST_F(ImplicitRootScrollerSimTest,
       RootScrollerFillsViewportAtBothURLBarStates) {
  WebView().ResizeWithBrowserControls(IntSize(800, 600), 50, 0, true);
  SimRequest main_request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            #container {
              width: 100%;
              height: 100%;
              overflow: auto;
              border: 0;
            }
          </style>
          <div id="container">
            <div style="height: 2000px;"></div>
          </div>
          <script>
            onresize = () => {
              document.getElementById("container").style.height =
                  window.innerHeight + "px";
            };
          </script>
      )HTML");
  Element* container = GetDocument().getElementById("container");
  GetDocument().setRootScroller(container);

  Compositor().BeginFrame();

  ASSERT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // Simulate hiding the top controls. The root scroller should remain valid at
  // the new height.
  WebView().GetPage()->GetBrowserControls().SetShownRatio(0);
  WebView().ResizeWithBrowserControls(IntSize(800, 650), 50, 0, false);
  Compositor().BeginFrame();
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // Simulate showing the top controls. The root scroller should remain valid.
  WebView().GetPage()->GetBrowserControls().SetShownRatio(1);
  WebView().ResizeWithBrowserControls(IntSize(800, 600), 50, 0, true);
  Compositor().BeginFrame();
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // Set the height explicitly to a new value in-between. The root scroller
  // should be demoted.
  container->style()->setProperty(&GetDocument(), "height", "601px", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // Reset back to valid and hide the top controls. Zoom to 2x. Ensure we're
  // still considered valid.
  container->style()->setProperty(&GetDocument(), "height", "", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
  EXPECT_EQ(ToLayoutBox(container->GetLayoutObject())->Size().Height(), 600);
  WebView().SetZoomLevel(WebView::ZoomFactorToZoomLevel(2.0));
  WebView().GetPage()->GetBrowserControls().SetShownRatio(0);
  WebView().ResizeWithBrowserControls(IntSize(800, 650), 50, 0, false);
  Compositor().BeginFrame();
  EXPECT_EQ(container->clientHeight(), 325);
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
}

// Tests that implicit is continually reevaluating whether to promote or demote
// a scroller.
TEST_F(ImplicitRootScrollerSimTest, ContinuallyReevaluateImplicitPromotion) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            html {
              overflow: hidden;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            #container {
              width: 100%;
              height: 100%;
            }
            #parent {
              width: 100%;
              height: 100%;
            }
          </style>
          <div id="parent">
            <div id="container">
              <div id="spacer"></div>
            </div>
          </div>
      )HTML");
  Compositor().BeginFrame();

  Element* parent = GetDocument().getElementById("parent");
  Element* container = GetDocument().getElementById("container");
  Element* spacer = GetDocument().getElementById("spacer");

  // The container isn't yet scrollable.
  ASSERT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // The container now has overflow but still doesn't scroll.
  spacer->style()->setProperty(&GetDocument(), "height", "2000px", String(),
                               ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // The container is now scrollable and should be promoted.
  container->style()->setProperty(&GetDocument(), "overflow", "auto", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // The container is now not viewport-filling so it should be demoted.
  container->style()->setProperty(&GetDocument(), "transform",
                                  "translateX(-50px)", String(),
                                  ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // The container is viewport-filling again so it should be promoted.
  parent->style()->setProperty(&GetDocument(), "transform", "translateX(50px)",
                               String(), ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // No longer scrollable so demote.
  container->style()->setProperty(&GetDocument(), "overflow", "hidden",
                                  String(), ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
}

// Tests that implicit mode correctly recognizes when an iframe becomes
// scrollable.
TEST_F(ImplicitRootScrollerSimTest, IframeScrollingAffectsPromotion) {
  WebView().MainFrameWidget()->Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
          </style>
          <iframe id="container"
                  srcdoc="<!DOCTYPE html><style>html {overflow: hidden; height: 300%;}</style>">
          </iframe>
      )HTML");

  // srcdoc iframe loads via posted tasks.
  RunPendingTasks();
  Compositor().BeginFrame();

  HTMLFrameOwnerElement* container =
      ToHTMLFrameOwnerElement(GetDocument().getElementById("container"));
  Element* inner_html_element = container->contentDocument()->documentElement();

  // Shouldn't be promoted since it's not scrollable.
  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // Allows scrolling now so promote.
  inner_html_element->style()->setProperty(container->contentDocument(),
                                           "overflow", "auto", String(),
                                           ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(container,
            GetDocument().GetRootScrollerController().EffectiveRootScroller());

  // Demote again.
  inner_html_element->style()->setProperty(container->contentDocument(),
                                           "overflow", "hidden", String(),
                                           ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller());
}

// Loads with a larger than the ICB (but otherwise valid) implicit root
// scrolling iframe. When the iframe is promoted (which happens at the end of
// layout) its layout size is changed which makes it easy to violate lifecycle
// assumptions.  (e.g. NeedsLayout at the end of layout)
TEST_F(ImplicitRootScrollerSimTest, PromotionChangesLayoutSize) {
  WebView().ResizeWithBrowserControls(IntSize(800, 650), 50, 0, false);
  SimRequest main_request("https://example.com/test.html", "text/html");
  SimRequest child_request("https://example.com/child.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 650px;
              border: 0;
            }
          </style>
          <iframe id="container" src="child.html">
          </iframe>
      )HTML");
  child_request.Complete(R"HTML(
        <!DOCTYPE html>
        <style>
          body {
            height: 1000px;
          }
        </style>
  )HTML");

  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument().getElementById("container"),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Once loaded, the iframe should be promoted.";
}

// Test that we don't promote any elements implicitly if the main document has
// vertical scrolling.
TEST_F(ImplicitRootScrollerSimTest, OverflowInMainDocumentRestrictsImplicit) {
  WebView().ResizeWithBrowserControls(IntSize(800, 600), 50, 0, true);
  SimRequest main_request("https://example.com/test.html", "text/html");
  SimRequest child_request("https://example.com/child.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
            div {
              position: absolute;
              left: 0;
              top: 0;
              height: 150%;
              width: 150%;
            }
          </style>
          <iframe id="container" src="child.html">
          </iframe>
          <div id="spacer"></div>
      )HTML");
  child_request.Complete(R"HTML(
        <!DOCTYPE html>
        <style>
          body {
            height: 1000px;
          }
        </style>
  )HTML");

  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "iframe shouldn't be promoted due to overflow in the main document.";

  Element* spacer = GetDocument().getElementById("spacer");
  spacer->style()->setProperty(&GetDocument(), "height", "100%", String(),
                               ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();

  EXPECT_EQ(GetDocument().getElementById("container"),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "Once vertical overflow is removed, the iframe should be promoted.";
}

// Test that we overflow in the document allows promotion only so long as the
// document isn't scrollable.
TEST_F(ImplicitRootScrollerSimTest, OverflowHiddenDoesntRestrictImplicit) {
  WebView().ResizeWithBrowserControls(IntSize(800, 600), 50, 0, true);
  SimRequest main_request("https://example.com/test.html", "text/html");
  SimRequest child_request("https://example.com/child.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            html {
              overflow: hidden;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
            #spacer {
              position: absolute;
              left: 0;
              top: 0;
              height: 150%;
              width: 150%;
            }
          </style>
          <iframe id="container" src="child.html">
          </iframe>
          <div id="spacer"></div>
      )HTML");
  child_request.Complete(R"HTML(
        <!DOCTYPE html>
        <style>
          body {
            height: 1000px;
          }
        </style>
  )HTML");

  Compositor().BeginFrame();
  EXPECT_EQ(GetDocument().getElementById("container"),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "iframe should be promoted since document's overflow is hidden.";

  Element* html = GetDocument().documentElement();
  html->style()->setProperty(&GetDocument(), "overflow", "auto", String(),
                             ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();

  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "iframe should now be demoted since main document scrolls overflow.";

  html->style()->setProperty(&GetDocument(), "overflow", "visible", String(),
                             ASSERT_NO_EXCEPTION);
  Compositor().BeginFrame();

  EXPECT_EQ(GetDocument(),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "iframe should remain demoted since overflow:visible on document "
      << "allows scrolling.";
}

// Test that any non-document, clipping ancestor prevents implicit promotion.
TEST_F(ImplicitRootScrollerSimTest, ClippingAncestorPreventsPromotion) {
  WebView().ResizeWithBrowserControls(IntSize(800, 600), 50, 0, true);
  SimRequest main_request("https://example.com/test.html", "text/html");
  SimRequest child_request("https://example.com/child.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            html {
              overflow: hidden;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
            #ancestor {
              position: absolute;
              width: 100%;
              height: 100%;
              overflow: visible;
              /* opacity ensures #ancestor doesn't get considered for root
               * scroller promotion. */
              opacity: 0.5;
            }
            #spacer {
              height: 150%;
              width: 150%;
            }
          </style>
          <div id="ancestor">
            <iframe id="container" src="child.html"></iframe>
            <div id="spacer"></div>
          </div>
      )HTML");
  child_request.Complete(R"HTML(
        <!DOCTYPE html>
        <style>
          body {
            height: 1000px;
          }
        </style>
  )HTML");
  Compositor().BeginFrame();

  // Each of these style-value pairs should prevent promotion of the iframe.
  std::vector<std::tuple<String, String>> test_cases = {
      {"overflow", "scroll"},
      {"overflow", "hidden"},
      {"overflow", "auto"},
      {"contain", "paint"},
      {"-webkit-mask-image", "linear-gradient(black 25%, transparent 50%)"},
      {"clip", "rect(10px, 290px, 190px, 10px"},
      {"clip-path", "circle(40%)"}};

  for (auto test_case : test_cases) {
    String& style = std::get<0>(test_case);
    String& style_val = std::get<1>(test_case);
    Element* ancestor = GetDocument().getElementById("ancestor");
    Element* iframe = GetDocument().getElementById("container");

    ASSERT_EQ(iframe,
              GetDocument().GetRootScrollerController().EffectiveRootScroller())
        << "iframe should start off promoted.";

    ancestor->style()->setProperty(&GetDocument(), style, style_val, String(),
                                   ASSERT_NO_EXCEPTION);
    Compositor().BeginFrame();

    EXPECT_EQ(GetDocument(),
              GetDocument().GetRootScrollerController().EffectiveRootScroller())
        << "iframe should be demoted since ancestor has " << style << ": "
        << style_val;

    ancestor->style()->setProperty(&GetDocument(), style, String(), String(),
                                   ASSERT_NO_EXCEPTION);
    Compositor().BeginFrame();
    ASSERT_EQ(iframe,
              GetDocument().GetRootScrollerController().EffectiveRootScroller())
        << "iframe should be promoted since ancestor removed " << style << ": "
        << style_val;
  }
}

TEST_F(ImplicitRootScrollerSimTest, AppliedAtFractionalZoom) {
  // Matches Pixel 2XL screen size of 412x671 at 3.5 DevicePixelRatio.
  WebView().SetZoomFactorForDeviceScaleFactor(3.5f);
  WebView().ResizeWithBrowserControls(IntSize(1442, 2349), 196, 0, true);

  SimRequest main_request("https://example.com/test.html", "text/html");
  SimRequest child_request("https://example.com/child.html", "text/html");
  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              border: 0;
              display: block;
            }
          </style>
          <iframe id="container" src="child.html">
          </iframe>
          <script>
            // innerHeight is non-fractional so pages don't have a great way to
            // set the size to "exctly" 100%. Ensure we still promote in this
            // common pattern.
            function resize_handler() {
              document.getElementById("container").style.height =
                  window.innerHeight + "px";
              document.getElementById("container").style.width =
                  window.innerWidth + "px";
            }

            resize_handler();
            window.addEventHandler('resize', resize_handler);
          </script>
      )HTML");

  child_request.Complete(R"HTML(
        <!DOCTYPE html>
        <style>
          body {
            height: 1000px;
          }
        </style>
  )HTML");

  Compositor().BeginFrame();
  PaintLayerScrollableArea* area = GetDocument().View()->LayoutViewport();
  ASSERT_FALSE(area->HasVerticalOverflow());

  EXPECT_EQ(GetDocument().getElementById("container"),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "<iframe> should be promoted when URL bar is hidden";

  WebView().ResizeWithBrowserControls(IntSize(1442, 2545), 196, 0, false);
  Compositor().BeginFrame();

  EXPECT_EQ(GetDocument().getElementById("container"),
            GetDocument().GetRootScrollerController().EffectiveRootScroller())
      << "<iframe> should remain promoted when URL bar is hidden";
}

class RootScrollerHitTest : public RootScrollerSimTest {
 public:
  void CheckHitTestAtBottomOfScreen(Element* target) {
    HideTopControlsWithMaximalScroll();

    // Do a hit test at the very bottom of the screen. This should be outside
    // the root scroller's LayoutBox since inert top controls won't resize the
    // ICB but, since we expaned the clip, we should still be able to hit the
    // target.
    gfx::Point point(200, 445);
    WebSize tap_area(20, 20);
    WebHitTestResult result = WebView().HitTestResultForTap(point, tap_area);

    Node* hit_node = result.GetNode().Unwrap<Node>();
    EXPECT_EQ(target, hit_node);
  }

  BrowserControls& GetBrowserControls() {
    return GetDocument().GetPage()->GetBrowserControls();
  }

 private:
  void HideTopControlsWithMaximalScroll() {
    // Do a scroll gesture that hides the top controls and scrolls all the way
    // to the bottom.
    ASSERT_EQ(1, GetBrowserControls().ShownRatio());
    WebView().MainFrameWidget()->ApplyViewportChanges(
        {gfx::ScrollOffset(), gfx::Vector2dF(), 1, -1,
         cc::BrowserControlsState::kBoth});
    ASSERT_EQ(0, GetBrowserControls().ShownRatio());

    Node* scroller = GetDocument()
                         .GetPage()
                         ->GlobalRootScrollerController()
                         .GlobalRootScroller();
    ScrollableArea* scrollable_area =
        ToLayoutBox(scroller->GetLayoutObject())->GetScrollableArea();
    scrollable_area->DidScroll(FloatPoint(0, 100000));

    WebView().ResizeWithBrowserControls(IntSize(400, 450), 50, 0, false);

    Compositor().BeginFrame();
  }
};

// Test that hit testing in the area revealed at the bottom of the screen
// revealed by hiding the URL bar works properly when using a root scroller
// when the target and scroller are in the same PaintLayer.
TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarSameLayer) {
  WebView().ResizeWithBrowserControls(IntSize(400, 400), 50, 0, true);
  GetBrowserControls().SetShownRatio(1);
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");

  // Add a target at the bottom of the root scroller that's the size of the url
  // bar. We'll test that hiding the URL bar appropriately adjusts clipping so
  // that we can hit this target.
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            body, html {
              height: 100%;
              margin: 0px;
            }
            #spacer {
              height: 1000px;
            }
            #container {
              position: absolute;
              width: 100%;
              height: 100%;
              overflow: auto;
            }
            #target {
              width: 100%;
              height: 50px;
            }
          </style>
          <div id='container'>
            <div id='spacer'></div>
            <div id='target'></div>
          </div>
      )HTML");

  Element* container = GetDocument().getElementById("container");
  Element* target = GetDocument().getElementById("target");
  GetDocument().setRootScroller(container, ASSERT_NO_EXCEPTION);

  Compositor().BeginFrame();

  // This test checks hit testing while the target is in the same PaintLayer as
  // the root scroller.
  ASSERT_EQ(ToLayoutBox(target->GetLayoutObject())->EnclosingLayer(),
            ToLayoutBox(container->GetLayoutObject())->Layer());

  CheckHitTestAtBottomOfScreen(target);
}

// Test that hit testing in the area revealed at the bottom of the screen
// revealed by hiding the URL bar works properly when using a root scroller
// when the target and scroller are in different PaintLayers.
TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarDifferentLayer) {
  WebView().ResizeWithBrowserControls(IntSize(400, 400), 50, 0, true);
  GetBrowserControls().SetShownRatio(1);
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");

  // Add a target at the bottom of the root scroller that's the size of the url
  // bar. We'll test that hiding the URL bar appropriately adjusts clipping so
  // that we can hit this target.
  request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            body, html {
              height: 100%;
              margin: 0px;
            }
            #spacer {
              height: 1000px;
            }
            #container {
              position: absolute;
              width: 100%;
              height: 100%;
              overflow: auto;
            }
            #target {
              width: 100%;
              height: 50px;
              will-change: transform;
            }
          </style>
          <div id='container'>
            <div id='spacer'></div>
            <div id='target'></div>
          </div>
      )HTML");

  Element* container = GetDocument().getElementById("container");
  Element* target = GetDocument().getElementById("target");
  GetDocument().setRootScroller(container, ASSERT_NO_EXCEPTION);

  Compositor().BeginFrame();

  // Ensure the target and container weren't put into the same layer.
  ASSERT_NE(ToLayoutBox(target->GetLayoutObject())->EnclosingLayer(),
            ToLayoutBox(container->GetLayoutObject())->Layer());

  CheckHitTestAtBottomOfScreen(target);
}

// Test that hit testing in the area revealed at the bottom of the screen
// revealed by hiding the URL bar works properly when using a root scroller
// inside an iframe, when the target and scroller are in different PaintLayers.
TEST_F(RootScrollerHitTest, HitTestHideURLBarDifferentLayerIframe) {
  WebView().ResizeWithBrowserControls(IntSize(400, 400), 50, 0, true);
  GetBrowserControls().SetShownRatio(1);
  SimRequest main_request("https://example.com/test.html", "text/html");
  SimRequest child_request("https://example.com/child.html", "text/html");

  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
          </style>
          <iframe id="container" src="child.html">
          </iframe>
      )HTML");

  // Add a target at the bottom of the root scroller that's the size of the url
  // bar. We'll test that hiding the URL bar appropriately adjusts clipping so
  // that we can hit this target.
  child_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            body, html {
              height: 100%;
              margin: 0px;
            }
            #spacer {
              height: 1000px;
            }
            #container {
              position: absolute;
              width: 100%;
              height: 100%;
              overflow: auto;
            }
            #target {
              width: 100%;
              height: 50px;
              will-change: transform;
            }
          </style>
          <div id='container'>
            <div id='spacer'></div>
            <div id='target'></div>
          </div>
      )HTML");

  Element* container = GetDocument().getElementById("container");
  GetDocument().setRootScroller(container, ASSERT_NO_EXCEPTION);

  Document* child_document =
      ToHTMLFrameOwnerElement(container)->contentDocument();
  Element* child_container = child_document->getElementById("container");
  child_document->setRootScroller(child_container, ASSERT_NO_EXCEPTION);

  Compositor().BeginFrame();

  // Ensure the target and container weren't put into the same layer.
  Element* target = child_document->getElementById("target");
  ASSERT_NE(ToLayoutBox(target->GetLayoutObject())->EnclosingLayer(),
            ToLayoutBox(child_container->GetLayoutObject())->Layer());

  CheckHitTestAtBottomOfScreen(target);
}

// Test that hit testing in the area revealed at the bottom of the screen
// revealed by hiding the URL bar works properly when using a root scroller
// inside an iframe, when the target and scroller are in the same PaintLayer.
TEST_F(RootScrollerHitTest, HitTestHideURLBarSameLayerIframe) {
  WebView().ResizeWithBrowserControls(IntSize(400, 400), 50, 0, true);
  GetBrowserControls().SetShownRatio(1);
  SimRequest main_request("https://example.com/test.html", "text/html");
  SimRequest child_request("https://example.com/child.html", "text/html");

  LoadURL("https://example.com/test.html");
  main_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            ::-webkit-scrollbar {
              width: 0px;
              height: 0px;
            }
            body, html {
              width: 100%;
              height: 100%;
              margin: 0px;
            }
            iframe {
              width: 100%;
              height: 100%;
              border: 0;
            }
          </style>
          <iframe id="container" src="child.html">
          </iframe>
      )HTML");

  // Add a target at the bottom of the root scroller that's the size of the url
  // bar. We'll test that hiding the URL bar appropriately adjusts clipping so
  // that we can hit this target.
  child_request.Complete(R"HTML(
          <!DOCTYPE html>
          <style>
            body, html {
              height: 100%;
              margin: 0px;
            }
            #spacer {
              height: 1000px;
            }
            #container {
              position: absolute;
              width: 100%;
              height: 100%;
              overflow: auto;
            }
            #target {
              width: 100%;
              height: 50px;
            }
          </style>
          <div id='container'>
            <div id='spacer'></div>
            <div id='target'></div>
          </div>
      )HTML");

  Element* container = GetDocument().getElementById("container");
  GetDocument().setRootScroller(container, ASSERT_NO_EXCEPTION);

  Document* child_document =
      ToHTMLFrameOwnerElement(container)->contentDocument();
  Element* child_container = child_document->getElementById("container");
  child_document->setRootScroller(child_container, ASSERT_NO_EXCEPTION);

  Compositor().BeginFrame();

  // Ensure the target and container weren't put into the same layer.
  Element* target = child_document->getElementById("target");
  ASSERT_EQ(ToLayoutBox(target->GetLayoutObject())->EnclosingLayer(),
            ToLayoutBox(child_container->GetLayoutObject())->Layer());

  CheckHitTestAtBottomOfScreen(target);
}

}  // namespace

}  // namespace blink
