/*
 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
 *                     1999 Lars Knoll <knoll@kde.org>
 *                     1999 Antti Koivisto <koivisto@kde.org>
 *                     2000 Dirk Mueller <mueller@kde.org>
 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
 *           (C) 2006 Graham Dennis (graham.dennis@gmail.com)
 *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
 * Copyright (C) 2009 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "core/frame/FrameView.h"

#include "core/HTMLNames.h"
#include "core/MediaTypeNames.h"
#include "core/animation/DocumentAnimations.h"
#include "core/css/FontFaceSet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/AXObjectCache.h"
#include "core/dom/DOMNodeIds.h"
#include "core/dom/ElementVisibilityObserver.h"
#include "core/dom/Fullscreen.h"
#include "core/dom/IntersectionObserverCallback.h"
#include "core/dom/IntersectionObserverController.h"
#include "core/dom/IntersectionObserverInit.h"
#include "core/dom/TaskRunnerHelper.h"
#include "core/editing/EditingUtilities.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/RenderedPosition.h"
#include "core/editing/markers/DocumentMarkerController.h"
#include "core/events/ErrorEvent.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/frame/BrowserControls.h"
#include "core/frame/EventHandlerRegistry.h"
#include "core/frame/FrameHost.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Location.h"
#include "core/frame/PageScaleConstraintsSet.h"
#include "core/frame/PerformanceMonitor.h"
#include "core/frame/Settings.h"
#include "core/frame/VisualViewport.h"
#include "core/html/HTMLFrameElement.h"
#include "core/html/HTMLPlugInElement.h"
#include "core/html/TextControlElement.h"
#include "core/html/parser/TextResourceDecoder.h"
#include "core/input/EventHandler.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/InspectorTraceEvents.h"
#include "core/layout/LayoutAnalyzer.h"
#include "core/layout/LayoutCounter.h"
#include "core/layout/LayoutEmbeddedObject.h"
#include "core/layout/LayoutPart.h"
#include "core/layout/LayoutScrollbar.h"
#include "core/layout/LayoutScrollbarPart.h"
#include "core/layout/LayoutView.h"
#include "core/layout/ScrollAlignment.h"
#include "core/layout/TextAutosizer.h"
#include "core/layout/TracedLayoutObject.h"
#include "core/layout/api/LayoutBoxModel.h"
#include "core/layout/api/LayoutItem.h"
#include "core/layout/api/LayoutPartItem.h"
#include "core/layout/api/LayoutViewItem.h"
#include "core/layout/compositing/CompositedLayerMapping.h"
#include "core/layout/compositing/CompositedSelection.h"
#include "core/layout/compositing/CompositingInputsUpdater.h"
#include "core/layout/compositing/PaintLayerCompositor.h"
#include "core/layout/svg/LayoutSVGRoot.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/observer/ResizeObserverController.h"
#include "core/page/AutoscrollController.h"
#include "core/page/ChromeClient.h"
#include "core/page/FocusController.h"
#include "core/page/FrameTree.h"
#include "core/page/Page.h"
#include "core/page/scrolling/RootScrollerUtil.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
#include "core/page/scrolling/TopDocumentRootScrollerController.h"
#include "core/paint/FramePainter.h"
#include "core/paint/PaintLayer.h"
#include "core/paint/PrePaintTreeWalk.h"
#include "core/plugins/PluginView.h"
#include "core/style/ComputedStyle.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGSVGElement.h"
#include "platform/Histogram.h"
#include "platform/HostWindow.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/ScriptForbiddenScope.h"
#include "platform/WebFrameScheduler.h"
#include "platform/fonts/FontCache.h"
#include "platform/geometry/DoubleRect.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/LayoutRect.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/GraphicsLayerDebugInfo.h"
#include "platform/graphics/compositing/PaintArtifactCompositor.h"
#include "platform/graphics/paint/CullRect.h"
#include "platform/graphics/paint/PaintController.h"
#include "platform/graphics/paint/ScopedPaintChunkProperties.h"
#include "platform/json/JSONValues.h"
#include "platform/scroll/ScrollAnimatorBase.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "platform/text/TextStream.h"
#include "platform/tracing/TraceEvent.h"
#include "platform/tracing/TracedValue.h"
#include "public/platform/WebDisplayItemList.h"
#include "wtf/CurrentTime.h"
#include "wtf/PtrUtil.h"
#include "wtf/StdLibExtras.h"
#include <memory>

// Used to check for dirty layouts violating document lifecycle rules.
// If arg evaluates to true, the program will continue. If arg evaluates to
// false, program will crash if DCHECK_IS_ON() or return false from the current
// function.
#define CHECK_FOR_DIRTY_LAYOUT(arg) \
  do {                              \
    if (!(arg)) {                   \
      NOTREACHED();                 \
      return false;                 \
    }                               \
  } while (false)

namespace blink {

using namespace HTMLNames;

// The maximum number of updateWidgets iterations that should be done before
// returning.
static const unsigned maxUpdateWidgetsIterations = 2;
static const double resourcePriorityUpdateDelayAfterScroll = 0.250;

static bool s_initialTrackAllPaintInvalidations = false;

FrameView::FrameView(LocalFrame& frame)
    : m_frame(frame),
      m_displayMode(WebDisplayModeBrowser),
      m_canHaveScrollbars(true),
      m_hasPendingLayout(false),
      m_inSynchronousPostLayout(false),
      m_postLayoutTasksTimer(TaskRunnerHelper::get(TaskType::Internal, &frame),
                             this,
                             &FrameView::postLayoutTimerFired),
      m_updateWidgetsTimer(TaskRunnerHelper::get(TaskType::Internal, &frame),
                           this,
                           &FrameView::updateWidgetsTimerFired),
      m_isTransparent(false),
      m_baseBackgroundColor(Color::white),
      m_mediaType(MediaTypeNames::screen),
      m_safeToPropagateScrollToParent(true),
      m_scrollCorner(nullptr),
      m_stickyPositionObjectCount(0),
      m_inputEventsScaleFactorForEmulation(1),
      m_layoutSizeFixedToFrameSize(true),
      m_didScrollTimer(this, &FrameView::didScrollTimerFired),
      m_browserControlsViewportAdjustment(0),
      m_needsUpdateWidgetGeometries(false),
      m_needsUpdateViewportIntersection(true),
#if ENABLE(ASSERT)
      m_hasBeenDisposed(false),
#endif
      m_horizontalScrollbarMode(ScrollbarAuto),
      m_verticalScrollbarMode(ScrollbarAuto),
      m_horizontalScrollbarLock(false),
      m_verticalScrollbarLock(false),
      m_scrollbarsSuppressed(false),
      m_inUpdateScrollbars(false),
      m_frameTimingRequestsDirty(true),
      m_hiddenForThrottling(false),
      m_subtreeThrottled(false),
      m_lifecycleUpdatesThrottled(false),
      m_needsPaintPropertyUpdate(true),
      m_currentUpdateLifecyclePhasesTargetState(
          DocumentLifecycle::Uninitialized),
      m_scrollAnchor(this),
      m_scrollbarManager(*this),
      m_needsScrollbarsUpdate(false),
      m_suppressAdjustViewSize(false),
      m_allowsLayoutInvalidationAfterLayoutClean(true) {
  init();
}

FrameView* FrameView::create(LocalFrame& frame) {
  FrameView* view = new FrameView(frame);
  view->show();
  return view;
}

FrameView* FrameView::create(LocalFrame& frame, const IntSize& initialSize) {
  FrameView* view = new FrameView(frame);
  view->Widget::setFrameRect(IntRect(view->location(), initialSize));
  view->setLayoutSizeInternal(initialSize);

  view->show();
  return view;
}

FrameView::~FrameView() {
  ASSERT(m_hasBeenDisposed);
}

DEFINE_TRACE(FrameView) {
  visitor->trace(m_frame);
  visitor->trace(m_fragmentAnchor);
  visitor->trace(m_scrollableAreas);
  visitor->trace(m_animatingScrollableAreas);
  visitor->trace(m_autoSizeInfo);
  visitor->trace(m_children);
  visitor->trace(m_viewportScrollableArea);
  visitor->trace(m_visibilityObserver);
  visitor->trace(m_scrollAnchor);
  visitor->trace(m_anchoringAdjustmentQueue);
  visitor->trace(m_scrollbarManager);
  Widget::trace(visitor);
  ScrollableArea::trace(visitor);
}

void FrameView::reset() {
  // The compositor throttles the main frame using deferred commits, we can't
  // throttle it here or it seems the root compositor doesn't get setup
  // properly.
  if (RuntimeEnabledFeatures::
          renderingPipelineThrottlingLoadingIframesEnabled())
    m_lifecycleUpdatesThrottled = !frame().isMainFrame();
  m_hasPendingLayout = false;
  m_layoutSchedulingEnabled = true;
  m_inSynchronousPostLayout = false;
  m_layoutCount = 0;
  m_nestedLayoutCount = 0;
  m_postLayoutTasksTimer.stop();
  m_updateWidgetsTimer.stop();
  m_firstLayout = true;
  m_safeToPropagateScrollToParent = true;
  m_lastViewportSize = IntSize();
  m_lastZoomFactor = 1.0f;
  m_trackedObjectPaintInvalidations = WTF::wrapUnique(
      s_initialTrackAllPaintInvalidations ? new Vector<ObjectPaintInvalidation>
                                          : nullptr);
  m_visuallyNonEmptyCharacterCount = 0;
  m_visuallyNonEmptyPixelCount = 0;
  m_isVisuallyNonEmpty = false;
  m_layoutObjectCounter.reset();
  clearFragmentAnchor();
  m_viewportConstrainedObjects.reset();
  m_layoutSubtreeRootList.clear();
  m_orthogonalWritingModeRootList.clear();
}

// Call function for each non-throttled frame view in pre tree order.
// Note it needs a null check of the frame's layoutView to access it in case of
// detached frames.
template <typename Function>
void FrameView::forAllNonThrottledFrameViews(const Function& function) {
  if (shouldThrottleRendering())
    return;

  function(*this);

  for (Frame* child = m_frame->tree().firstChild(); child;
       child = child->tree().nextSibling()) {
    if (!child->isLocalFrame())
      continue;
    if (FrameView* childView = toLocalFrame(child)->view())
      childView->forAllNonThrottledFrameViews(function);
  }
}

void FrameView::init() {
  reset();

  m_size = LayoutSize();

  // Propagate the marginwidth/height and scrolling modes to the view.
  if (m_frame->owner() &&
      m_frame->owner()->scrollingMode() == ScrollbarAlwaysOff)
    setCanHaveScrollbars(false);
}

void FrameView::setupRenderThrottling() {
  if (m_visibilityObserver)
    return;

  // We observe the frame owner element instead of the document element, because
  // if the document has no content we can falsely think the frame is invisible.
  // Note that this means we cannot throttle top-level frames or (currently)
  // frames whose owner element is remote.
  Element* targetElement = frame().deprecatedLocalOwner();
  if (!targetElement)
    return;

  m_visibilityObserver = new ElementVisibilityObserver(
      targetElement, WTF::bind(
                         [](FrameView* frameView, bool isVisible) {
                           frameView->updateRenderThrottlingStatus(
                               !isVisible, frameView->m_subtreeThrottled);
                           frameView->maybeRecordLoadReason();
                         },
                         wrapWeakPersistent(this)));
  m_visibilityObserver->start();
}

void FrameView::dispose() {
  RELEASE_ASSERT(!isInPerformLayout());

  if (ScrollAnimatorBase* scrollAnimator = existingScrollAnimator())
    scrollAnimator->cancelAnimation();
  cancelProgrammaticScrollAnimation();

  detachScrollbars();

  if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    scrollingCoordinator->willDestroyScrollableArea(this);

  FrameHost* frameHost = m_frame->host();
  DCHECK(frameHost);
  frameHost->globalRootScrollerController().didDisposeScrollableArea(*this);

  // We need to clear the RootFrameViewport's animator since it gets called
  // from non-GC'd objects and RootFrameViewport will still have a pointer to
  // this class.
  if (m_viewportScrollableArea)
    m_viewportScrollableArea->clearScrollableArea();

  clearScrollableArea();

  // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing
  // partially destroyed |this| via |m_autoSizeInfo->m_frameView|.
  m_autoSizeInfo.clear();

  m_postLayoutTasksTimer.stop();
  m_didScrollTimer.stop();

  // FIXME: Do we need to do something here for OOPI?
  HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
  // TODO(dcheng): It seems buggy that we can have an owner element that
  // points to another Widget.
  if (ownerElement && ownerElement->ownedWidget() == this)
    ownerElement->setWidget(nullptr);

#if ENABLE(ASSERT)
  m_hasBeenDisposed = true;
#endif
}

void FrameView::detachScrollbars() {
  // Previously, we detached custom scrollbars as early as possible to prevent
  // Document::detachLayoutTree() from messing with the view such that its
  // scroll bars won't be torn down. However, scripting in
  // Document::detachLayoutTree() is forbidden
  // now, so it's not clear if these edge cases can still happen.
  // However, for Oilpan, we still need to remove the native scrollbars before
  // we lose the connection to the HostWindow, so we just unconditionally
  // detach any scrollbars now.
  m_scrollbarManager.dispose();

  if (m_scrollCorner) {
    m_scrollCorner->destroy();
    m_scrollCorner = nullptr;
  }
}

void FrameView::ScrollbarManager::setHasHorizontalScrollbar(bool hasScrollbar) {
  if (hasScrollbar == hasHorizontalScrollbar())
    return;

  if (hasScrollbar) {
    m_hBar = createScrollbar(HorizontalScrollbar);
    m_scrollableArea->layoutBox()->document().view()->addChild(m_hBar.get());
    m_scrollableArea->didAddScrollbar(*m_hBar, HorizontalScrollbar);
    m_hBar->styleChanged();
    m_hBarIsAttached = 1;
  } else {
    m_hBarIsAttached = 0;
    destroyScrollbar(HorizontalScrollbar);
  }

  m_scrollableArea->setScrollCornerNeedsPaintInvalidation();
}

void FrameView::ScrollbarManager::setHasVerticalScrollbar(bool hasScrollbar) {
  if (hasScrollbar == hasVerticalScrollbar())
    return;

  if (hasScrollbar) {
    m_vBar = createScrollbar(VerticalScrollbar);
    m_scrollableArea->layoutBox()->document().view()->addChild(m_vBar.get());
    m_scrollableArea->didAddScrollbar(*m_vBar, VerticalScrollbar);
    m_vBar->styleChanged();
    m_vBarIsAttached = 1;
  } else {
    m_vBarIsAttached = 0;
    destroyScrollbar(VerticalScrollbar);
  }

  m_scrollableArea->setScrollCornerNeedsPaintInvalidation();
}

Scrollbar* FrameView::ScrollbarManager::createScrollbar(
    ScrollbarOrientation orientation) {
  Element* customScrollbarElement = nullptr;
  LocalFrame* customScrollbarFrame = nullptr;

  LayoutBox* box = m_scrollableArea->layoutBox();
  if (box->document().view()->shouldUseCustomScrollbars(customScrollbarElement,
                                                        customScrollbarFrame)) {
    return LayoutScrollbar::createCustomScrollbar(
        m_scrollableArea.get(), orientation, customScrollbarElement,
        customScrollbarFrame);
  }

  // Nobody set a custom style, so we just use a native scrollbar.
  return Scrollbar::create(m_scrollableArea.get(), orientation,
                           RegularScrollbar,
                           &box->frame()->page()->chromeClient());
}

void FrameView::ScrollbarManager::destroyScrollbar(
    ScrollbarOrientation orientation) {
  Member<Scrollbar>& scrollbar =
      orientation == HorizontalScrollbar ? m_hBar : m_vBar;
  DCHECK(orientation == HorizontalScrollbar ? !m_hBarIsAttached
                                            : !m_vBarIsAttached);
  if (!scrollbar)
    return;

  m_scrollableArea->willRemoveScrollbar(*scrollbar, orientation);
  m_scrollableArea->layoutBox()->document().view()->removeChild(
      scrollbar.get());
  scrollbar->disconnectFromScrollableArea();
  scrollbar = nullptr;
}

void FrameView::recalculateCustomScrollbarStyle() {
  bool didStyleChange = false;
  if (horizontalScrollbar() && horizontalScrollbar()->isCustomScrollbar()) {
    horizontalScrollbar()->styleChanged();
    didStyleChange = true;
  }
  if (verticalScrollbar() && verticalScrollbar()->isCustomScrollbar()) {
    verticalScrollbar()->styleChanged();
    didStyleChange = true;
  }
  if (didStyleChange) {
    updateScrollbarGeometry();
    updateScrollCorner();
    positionScrollbarLayers();
  }
}

void FrameView::invalidateAllCustomScrollbarsOnActiveChanged() {
  bool usesWindowInactiveSelector =
      m_frame->document()->styleEngine().usesWindowInactiveSelector();

  const ChildrenWidgetSet* viewChildren = children();
  for (const Member<Widget>& child : *viewChildren) {
    Widget* widget = child.get();
    if (widget->isFrameView())
      toFrameView(widget)->invalidateAllCustomScrollbarsOnActiveChanged();
    else if (usesWindowInactiveSelector && widget->isScrollbar() &&
             toScrollbar(widget)->isCustomScrollbar())
      toScrollbar(widget)->styleChanged();
  }
  if (usesWindowInactiveSelector)
    recalculateCustomScrollbarStyle();
}

void FrameView::clear() {
  reset();
  setScrollbarsSuppressed(true);
}

bool FrameView::didFirstLayout() const {
  return !m_firstLayout;
}

void FrameView::invalidateRect(const IntRect& rect) {
  LayoutPartItem layoutItem = m_frame->ownerLayoutItem();
  if (layoutItem.isNull())
    return;

  IntRect paintInvalidationRect = rect;
  paintInvalidationRect.move(
      (layoutItem.borderLeft() + layoutItem.paddingLeft()).toInt(),
      (layoutItem.borderTop() + layoutItem.paddingTop()).toInt());
  // FIXME: We should not allow paint invalidation out of paint invalidation
  // state. crbug.com/457415
  DisablePaintInvalidationStateAsserts paintInvalidationAssertDisabler;
  layoutItem.invalidatePaintRectangle(LayoutRect(paintInvalidationRect));
}

void FrameView::setFrameRect(const IntRect& newRect) {
  IntRect oldRect = frameRect();
  if (newRect == oldRect)
    return;

  Widget::setFrameRect(newRect);

  const bool frameSizeChanged = oldRect.size() != newRect.size();

  m_needsScrollbarsUpdate = frameSizeChanged;
  // TODO(wjmaclean): find out why scrollbars fail to resize for complex
  // subframes after changing the zoom level. For now always calling
  // updateScrollbarsIfNeeded() here fixes the issue, but it would be good to
  // discover the deeper cause of this. http://crbug.com/607987.
  updateScrollbarsIfNeeded();

  frameRectsChanged();

  updateParentScrollableAreaSet();

  if (frameSizeChanged) {
    viewportSizeChanged(newRect.width() != oldRect.width(),
                        newRect.height() != oldRect.height());

    if (m_frame->isMainFrame())
      m_frame->host()->visualViewport().mainFrameDidChangeSize();

    frame().loader().restoreScrollPositionAndViewState();
  }
}

Page* FrameView::page() const {
  return frame().page();
}

LayoutView* FrameView::layoutView() const {
  return frame().contentLayoutObject();
}

LayoutViewItem FrameView::layoutViewItem() const {
  return LayoutViewItem(frame().contentLayoutObject());
}

ScrollingCoordinator* FrameView::scrollingCoordinator() const {
  Page* p = page();
  return p ? p->scrollingCoordinator() : 0;
}

CompositorAnimationTimeline* FrameView::compositorAnimationTimeline() const {
  ScrollingCoordinator* c = scrollingCoordinator();
  return c ? c->compositorAnimationTimeline() : nullptr;
}

LayoutBox* FrameView::layoutBox() const {
  return layoutView();
}

FloatQuad FrameView::localToVisibleContentQuad(
    const FloatQuad& quad,
    const LayoutObject* localObject,
    MapCoordinatesFlags flags) const {
  LayoutBox* box = layoutBox();
  if (!box)
    return quad;
  DCHECK(localObject);
  FloatQuad result = localObject->localToAncestorQuad(quad, box, flags);
  result.move(-getScrollOffset());
  return result;
}

void FrameView::setCanHaveScrollbars(bool canHaveScrollbars) {
  m_canHaveScrollbars = canHaveScrollbars;

  ScrollbarMode newVerticalMode = m_verticalScrollbarMode;
  if (canHaveScrollbars && m_verticalScrollbarMode == ScrollbarAlwaysOff)
    newVerticalMode = ScrollbarAuto;
  else if (!canHaveScrollbars)
    newVerticalMode = ScrollbarAlwaysOff;

  ScrollbarMode newHorizontalMode = m_horizontalScrollbarMode;
  if (canHaveScrollbars && m_horizontalScrollbarMode == ScrollbarAlwaysOff)
    newHorizontalMode = ScrollbarAuto;
  else if (!canHaveScrollbars)
    newHorizontalMode = ScrollbarAlwaysOff;

  setScrollbarModes(newHorizontalMode, newVerticalMode);
}

bool FrameView::shouldUseCustomScrollbars(
    Element*& customScrollbarElement,
    LocalFrame*& customScrollbarFrame) const {
  customScrollbarElement = nullptr;
  customScrollbarFrame = nullptr;

  if (Settings* settings = m_frame->settings()) {
    if (!settings->allowCustomScrollbarInMainFrame() && m_frame->isMainFrame())
      return false;
  }

  // FIXME: We need to update the scrollbar dynamically as documents change (or
  // as doc elements and bodies get discovered that have custom styles).
  Document* doc = m_frame->document();

  // Try the <body> element first as a scrollbar source.
  Element* body = doc ? doc->body() : 0;
  if (body && body->layoutObject() &&
      body->layoutObject()->style()->hasPseudoStyle(PseudoIdScrollbar)) {
    customScrollbarElement = body;
    return true;
  }

  // If the <body> didn't have a custom style, then the root element might.
  Element* docElement = doc ? doc->documentElement() : 0;
  if (docElement && docElement->layoutObject() &&
      docElement->layoutObject()->style()->hasPseudoStyle(PseudoIdScrollbar)) {
    customScrollbarElement = docElement;
    return true;
  }

  return false;
}

Scrollbar* FrameView::createScrollbar(ScrollbarOrientation orientation) {
  return m_scrollbarManager.createScrollbar(orientation);
}

void FrameView::setContentsSize(const IntSize& size) {
  if (size == contentsSize())
    return;

  m_contentsSize = size;
  updateScrollbars();
  ScrollableArea::contentsResized();

  if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() &&
      !RuntimeEnabledFeatures::rootLayerScrollingEnabled())
    setNeedsPaintPropertyUpdate();

  Page* page = frame().page();
  if (!page)
    return;

  updateParentScrollableAreaSet();

  page->chromeClient().contentsSizeChanged(m_frame.get(), size);

  // Ensure the scrollToFragmentAnchor is called before
  // restoreScrollPositionAndViewState when reload
  scrollToFragmentAnchor();
  frame().loader().restoreScrollPositionAndViewState();
}

void FrameView::adjustViewSize() {
  if (m_suppressAdjustViewSize)
    return;

  LayoutViewItem layoutViewItem = this->layoutViewItem();
  if (layoutViewItem.isNull())
    return;

  ASSERT(m_frame->view() == this);

  const IntRect rect = layoutViewItem.documentRect();
  const IntSize& size = rect.size();

  const IntPoint origin(-rect.x(), -rect.y());
  if (scrollOrigin() != origin) {
    ScrollableArea::setScrollOrigin(origin);
    // setContentSize (below) also calls updateScrollbars so we can avoid
    // updating scrollbars twice by skipping the call here when the content
    // size does not change.
    if (!m_frame->document()->printing() && size == contentsSize())
      updateScrollbars();
  }

  setContentsSize(size);
}

void FrameView::adjustViewSizeAndLayout() {
  adjustViewSize();
  if (needsLayout()) {
    AutoReset<bool> suppressAdjustViewSize(&m_suppressAdjustViewSize, true);
    layout();
  }
}

void FrameView::calculateScrollbarModesFromOverflowStyle(
    const ComputedStyle* style,
    ScrollbarMode& hMode,
    ScrollbarMode& vMode) {
  hMode = vMode = ScrollbarAuto;

  EOverflow overflowX = style->overflowX();
  EOverflow overflowY = style->overflowY();

  if (!shouldIgnoreOverflowHidden()) {
    if (overflowX == OverflowHidden)
      hMode = ScrollbarAlwaysOff;
    if (overflowY == OverflowHidden)
      vMode = ScrollbarAlwaysOff;
  }

  if (overflowX == OverflowScroll)
    hMode = ScrollbarAlwaysOn;
  if (overflowY == OverflowScroll)
    vMode = ScrollbarAlwaysOn;
}

void FrameView::calculateScrollbarModes(
    ScrollbarMode& hMode,
    ScrollbarMode& vMode,
    ScrollbarModesCalculationStrategy strategy) {
#define RETURN_SCROLLBAR_MODE(mode) \
  {                                 \
    hMode = vMode = mode;           \
    return;                         \
  }

  // Setting scrolling="no" on an iframe element disables scrolling.
  if (m_frame->owner() &&
      m_frame->owner()->scrollingMode() == ScrollbarAlwaysOff)
    RETURN_SCROLLBAR_MODE(ScrollbarAlwaysOff);

  // Framesets can't scroll.
  Node* body = m_frame->document()->body();
  if (isHTMLFrameSetElement(body) && body->layoutObject())
    RETURN_SCROLLBAR_MODE(ScrollbarAlwaysOff);

  // Scrollbars can be disabled by FrameView::setCanHaveScrollbars.
  if (!m_canHaveScrollbars && strategy != RulesFromWebContentOnly)
    RETURN_SCROLLBAR_MODE(ScrollbarAlwaysOff);

  // This will be the LayoutObject for either the body element or the html
  // element (see Document::viewportDefiningElement).
  LayoutObject* viewport = viewportLayoutObject();
  if (!viewport || !viewport->style())
    RETURN_SCROLLBAR_MODE(ScrollbarAuto);

  if (viewport->isSVGRoot()) {
    // Don't allow overflow to affect <img> and css backgrounds
    if (toLayoutSVGRoot(viewport)->isEmbeddedThroughSVGImage())
      RETURN_SCROLLBAR_MODE(ScrollbarAuto);

    // FIXME: evaluate if we can allow overflow for these cases too.
    // Overflow is always hidden when stand-alone SVG documents are embedded.
    if (toLayoutSVGRoot(viewport)
            ->isEmbeddedThroughFrameContainingSVGDocument())
      RETURN_SCROLLBAR_MODE(ScrollbarAlwaysOff);
  }

  calculateScrollbarModesFromOverflowStyle(viewport->style(), hMode, vMode);

#undef RETURN_SCROLLBAR_MODE
}

void FrameView::updateAcceleratedCompositingSettings() {
  if (LayoutViewItem layoutViewItem = this->layoutViewItem())
    layoutViewItem.compositor()->updateAcceleratedCompositingSettings();
}

void FrameView::recalcOverflowAfterStyleChange() {
  LayoutViewItem layoutViewItem = this->layoutViewItem();
  RELEASE_ASSERT(!layoutViewItem.isNull());
  if (!layoutViewItem.needsOverflowRecalcAfterStyleChange())
    return;

  layoutViewItem.recalcOverflowAfterStyleChange();

  // Changing overflow should notify scrolling coordinator to ensures that it
  // updates non-fast scroll rects even if there is no layout.
  if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    scrollingCoordinator->notifyOverflowUpdated();

  IntRect documentRect = layoutViewItem.documentRect();
  if (scrollOrigin() == -documentRect.location() &&
      contentsSize() == documentRect.size())
    return;

  if (needsLayout())
    return;

  // TODO(pdr): This should be refactored to just block scrollbar updates as
  // we are not in a scrollbar update here and m_inUpdateScrollbars has other
  // side effects. This scope is only for preventing a synchronous layout from
  // scroll origin changes which would not be allowed during style recalc.
  InUpdateScrollbarsScope inUpdateScrollbarsScope(this);

  bool shouldHaveHorizontalScrollbar = false;
  bool shouldHaveVerticalScrollbar = false;
  computeScrollbarExistence(shouldHaveHorizontalScrollbar,
                            shouldHaveVerticalScrollbar, documentRect.size());

  bool hasHorizontalScrollbar = horizontalScrollbar();
  bool hasVerticalScrollbar = verticalScrollbar();
  if (hasHorizontalScrollbar != shouldHaveHorizontalScrollbar ||
      hasVerticalScrollbar != shouldHaveVerticalScrollbar) {
    setNeedsLayout();
    return;
  }

  adjustViewSize();
  updateScrollbarGeometry();

  if (scrollOriginChanged())
    setNeedsLayout();
}

bool FrameView::usesCompositedScrolling() const {
  LayoutViewItem layoutView = this->layoutViewItem();
  if (layoutView.isNull())
    return false;
  if (m_frame->settings() &&
      m_frame->settings()->preferCompositingToLCDTextEnabled())
    return layoutView.compositor()->inCompositingMode();
  return false;
}

bool FrameView::shouldScrollOnMainThread() const {
  if (ScrollingCoordinator* sc = scrollingCoordinator()) {
    if (sc->shouldUpdateScrollLayerPositionOnMainThread())
      return true;
  }
  return ScrollableArea::shouldScrollOnMainThread();
}

GraphicsLayer* FrameView::layerForScrolling() const {
  LayoutViewItem layoutView = this->layoutViewItem();
  if (layoutView.isNull())
    return nullptr;
  return layoutView.compositor()->frameScrollLayer();
}

GraphicsLayer* FrameView::layerForHorizontalScrollbar() const {
  LayoutViewItem layoutView = this->layoutViewItem();
  if (layoutView.isNull())
    return nullptr;
  return layoutView.compositor()->layerForHorizontalScrollbar();
}

GraphicsLayer* FrameView::layerForVerticalScrollbar() const {
  LayoutViewItem layoutView = this->layoutViewItem();
  if (layoutView.isNull())
    return nullptr;
  return layoutView.compositor()->layerForVerticalScrollbar();
}

GraphicsLayer* FrameView::layerForScrollCorner() const {
  LayoutViewItem layoutView = this->layoutViewItem();
  if (layoutView.isNull())
    return nullptr;
  return layoutView.compositor()->layerForScrollCorner();
}

bool FrameView::isEnclosedInCompositingLayer() const {
  // FIXME: It's a bug that compositing state isn't always up to date when this
  // is called. crbug.com/366314
  DisableCompositingQueryAsserts disabler;

  LayoutItem frameOwnerLayoutItem = m_frame->ownerLayoutItem();
  return !frameOwnerLayoutItem.isNull() &&
         frameOwnerLayoutItem.enclosingLayer()
             ->enclosingLayerForPaintInvalidationCrossingFrameBoundaries();
}

void FrameView::countObjectsNeedingLayout(unsigned& needsLayoutObjects,
                                          unsigned& totalObjects,
                                          bool& isSubtree) {
  needsLayoutObjects = 0;
  totalObjects = 0;
  isSubtree = isSubtreeLayout();
  if (isSubtree)
    m_layoutSubtreeRootList.countObjectsNeedingLayout(needsLayoutObjects,
                                                      totalObjects);
  else
    LayoutSubtreeRootList::countObjectsNeedingLayoutInRoot(
        layoutView(), needsLayoutObjects, totalObjects);
}

inline void FrameView::forceLayoutParentViewIfNeeded() {
  LayoutPartItem ownerLayoutItem = m_frame->ownerLayoutItem();
  if (ownerLayoutItem.isNull() || !ownerLayoutItem.frame())
    return;

  LayoutReplaced* contentBox = embeddedReplacedContent();
  if (!contentBox)
    return;

  LayoutSVGRoot* svgRoot = toLayoutSVGRoot(contentBox);
  if (svgRoot->everHadLayout() && !svgRoot->needsLayout())
    return;

  // If the embedded SVG document appears the first time, the ownerLayoutObject
  // has already finished layout without knowing about the existence of the
  // embedded SVG document, because LayoutReplaced embeddedReplacedContent()
  // returns 0, as long as the embedded document isn't loaded yet. Before
  // bothering to lay out the SVG document, mark the ownerLayoutObject needing
  // layout and ask its FrameView for a layout. After that the
  // LayoutEmbeddedObject (ownerLayoutObject) carries the correct size, which
  // LayoutSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying out
  // for the first time, or when the LayoutSVGRoot size has changed dynamically
  // (eg. via <script>).
  FrameView* frameView = ownerLayoutItem.frame()->view();

  // Mark the owner layoutObject as needing layout.
  ownerLayoutItem.setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
      LayoutInvalidationReason::Unknown);

  // Synchronously enter layout, to layout the view containing the host
  // object/embed/iframe.
  ASSERT(frameView);
  frameView->layout();
}

void FrameView::performPreLayoutTasks() {
  TRACE_EVENT0("blink,benchmark", "FrameView::performPreLayoutTasks");
  lifecycle().advanceTo(DocumentLifecycle::InPreLayout);

  // Don't schedule more layouts, we're in one.
  AutoReset<bool> changeSchedulingEnabled(&m_layoutSchedulingEnabled, false);

  if (!m_nestedLayoutCount && !m_inSynchronousPostLayout &&
      m_postLayoutTasksTimer.isActive()) {
    // This is a new top-level layout. If there are any remaining tasks from the
    // previous layout, finish them now.
    m_inSynchronousPostLayout = true;
    performPostLayoutTasks();
    m_inSynchronousPostLayout = false;
  }

  bool wasResized = wasViewportResized();
  Document* document = m_frame->document();
  if (wasResized)
    document->notifyResizeForViewportUnits();

  // Viewport-dependent or device-dependent media queries may cause us to need
  // completely different style information.
  bool mainFrameRotation =
      m_frame->isMainFrame() && m_frame->settings() &&
      m_frame->settings()->mainFrameResizesAreOrientationChanges();
  if ((wasResized &&
       document->styleEngine().mediaQueryAffectedByViewportChange()) ||
      (wasResized && mainFrameRotation &&
       document->styleEngine().mediaQueryAffectedByDeviceChange())) {
    document->mediaQueryAffectingValueChanged();
  } else if (wasResized) {
    document->evaluateMediaQueryList();
  }

  document->updateStyleAndLayoutTree();
  lifecycle().advanceTo(DocumentLifecycle::StyleClean);

  if (shouldPerformScrollAnchoring())
    m_scrollAnchor.notifyBeforeLayout();
}

bool FrameView::shouldPerformScrollAnchoring() const {
  return RuntimeEnabledFeatures::scrollAnchoringEnabled() &&
         !RuntimeEnabledFeatures::rootLayerScrollingEnabled() &&
         m_scrollAnchor.hasScroller() &&
         layoutBox()->style()->overflowAnchor() != EOverflowAnchor::None &&
         !m_frame->document()->finishingOrIsPrinting();
}

static inline void layoutFromRootObject(LayoutObject& root) {
  LayoutState layoutState(root);
  root.layout();
}

void FrameView::prepareLayoutAnalyzer() {
  bool isTracing = false;
  TRACE_EVENT_CATEGORY_GROUP_ENABLED(
      TRACE_DISABLED_BY_DEFAULT("blink.debug.layout"), &isTracing);
  if (!isTracing) {
    m_analyzer.reset();
    return;
  }
  if (!m_analyzer)
    m_analyzer = WTF::makeUnique<LayoutAnalyzer>();
  m_analyzer->reset();
}

std::unique_ptr<TracedValue> FrameView::analyzerCounters() {
  if (!m_analyzer)
    return TracedValue::create();
  std::unique_ptr<TracedValue> value = m_analyzer->toTracedValue();
  value->setString("host", layoutViewItem().document().location()->host());
  value->setString("frame",
                   String::format("0x%" PRIxPTR,
                                  reinterpret_cast<uintptr_t>(m_frame.get())));
  value->setInteger("contentsHeightAfterLayout",
                    layoutViewItem().documentRect().height());
  value->setInteger("visibleHeight", visibleHeight());
  value->setInteger(
      "approximateBlankCharacterCount",
      FontFaceSet::approximateBlankCharacterCount(*m_frame->document()));
  return value;
}

#define PERFORM_LAYOUT_TRACE_CATEGORIES \
  "blink,benchmark,rail," TRACE_DISABLED_BY_DEFAULT("blink.debug.layout")

void FrameView::performLayout(bool inSubtreeLayout) {
  ASSERT(inSubtreeLayout || m_layoutSubtreeRootList.isEmpty());

  int contentsHeightBeforeLayout = layoutViewItem().documentRect().height();
  TRACE_EVENT_BEGIN1(PERFORM_LAYOUT_TRACE_CATEGORIES,
                     "FrameView::performLayout", "contentsHeightBeforeLayout",
                     contentsHeightBeforeLayout);
  prepareLayoutAnalyzer();

  ScriptForbiddenScope forbidScript;

  ASSERT(!isInPerformLayout());
  lifecycle().advanceTo(DocumentLifecycle::InPerformLayout);

  // performLayout is the actual guts of layout().
  // FIXME: The 300 other lines in layout() probably belong in other helper
  // functions so that a single human could understand what layout() is actually
  // doing.

  forceLayoutParentViewIfNeeded();

  if (hasOrthogonalWritingModeRoots())
    layoutOrthogonalWritingModeRoots();

  if (inSubtreeLayout) {
    if (m_analyzer)
      m_analyzer->increment(LayoutAnalyzer::PerformLayoutRootLayoutObjects,
                            m_layoutSubtreeRootList.size());
    for (auto& root : m_layoutSubtreeRootList.ordered()) {
      if (!root->needsLayout())
        continue;
      layoutFromRootObject(*root);

      // We need to ensure that we mark up all layoutObjects up to the
      // LayoutView for paint invalidation. This simplifies our code as we just
      // always do a full tree walk.
      if (LayoutItem container = LayoutItem(root->container()))
        container.setMayNeedPaintInvalidation();
    }
    m_layoutSubtreeRootList.clear();
  } else {
    layoutFromRootObject(*layoutView());
  }

  m_frame->document()->fetcher()->updateAllImageResourcePriorities();

  lifecycle().advanceTo(DocumentLifecycle::AfterPerformLayout);

  TRACE_EVENT_END1(PERFORM_LAYOUT_TRACE_CATEGORIES, "FrameView::performLayout",
                   "counters", analyzerCounters());
  FirstMeaningfulPaintDetector::from(*m_frame->document())
      .markNextPaintAsMeaningfulIfNeeded(
          m_layoutObjectCounter, contentsHeightBeforeLayout,
          layoutViewItem().documentRect().height(), visibleHeight());
}

void FrameView::scheduleOrPerformPostLayoutTasks() {
  if (m_postLayoutTasksTimer.isActive())
    return;

  if (!m_inSynchronousPostLayout) {
    m_inSynchronousPostLayout = true;
    // Calls resumeScheduledEvents()
    performPostLayoutTasks();
    m_inSynchronousPostLayout = false;
  }

  if (!m_postLayoutTasksTimer.isActive() &&
      (needsLayout() || m_inSynchronousPostLayout)) {
    // If we need layout or are already in a synchronous call to
    // postLayoutTasks(), defer widget updates and event dispatch until after we
    // return.  postLayoutTasks() can make us need to update again, and we can
    // get stuck in a nasty cycle unless we call it through the timer here.
    m_postLayoutTasksTimer.startOneShot(0, BLINK_FROM_HERE);
    if (needsLayout())
      layout();
  }
}

void FrameView::layout() {
  // We should never layout a Document which is not in a LocalFrame.
  ASSERT(m_frame);
  ASSERT(m_frame->view() == this);
  ASSERT(m_frame->page());

  ScriptForbiddenScope forbidScript;

  if (isInPerformLayout() || shouldThrottleRendering() ||
      !m_frame->document()->isActive())
    return;

  TRACE_EVENT0("blink,benchmark", "FrameView::layout");

  if (m_autoSizeInfo)
    m_autoSizeInfo->autoSizeIfNeeded();

  m_hasPendingLayout = false;
  DocumentLifecycle::Scope lifecycleScope(lifecycle(),
                                          DocumentLifecycle::LayoutClean);

  Document* document = m_frame->document();
  TRACE_EVENT_BEGIN1("devtools.timeline", "Layout", "beginData",
                     InspectorLayoutEvent::beginData(this));
  PerformanceMonitor::willUpdateLayout(document);

  performPreLayoutTasks();

  // TODO(crbug.com/460956): The notion of a single root for layout is no longer
  // applicable. Remove or update this code.
  LayoutObject* rootForThisLayout = layoutView();

  FontCachePurgePreventer fontCachePurgePreventer;
  {
    AutoReset<bool> changeSchedulingEnabled(&m_layoutSchedulingEnabled, false);
    m_nestedLayoutCount++;

    updateCounters();

    // If the layout view was marked as needing layout after we added items in
    // the subtree roots we need to clear the roots and do the layout from the
    // layoutView.
    if (layoutViewItem().needsLayout())
      clearLayoutSubtreeRootsAndMarkContainingBlocks();
    layoutViewItem().clearHitTestCache();

    bool inSubtreeLayout = isSubtreeLayout();

    // TODO(crbug.com/460956): The notion of a single root for layout is no
    // longer applicable. Remove or update this code.
    if (inSubtreeLayout)
      rootForThisLayout = m_layoutSubtreeRootList.randomRoot();

    if (!rootForThisLayout) {
      // FIXME: Do we need to set m_size here?
      NOTREACHED();
      return;
    }

    if (!inSubtreeLayout) {
      clearLayoutSubtreeRootsAndMarkContainingBlocks();
      Node* body = document->body();
      if (body && body->layoutObject()) {
        if (isHTMLFrameSetElement(*body)) {
          body->layoutObject()->setChildNeedsLayout();
        } else if (isHTMLBodyElement(*body)) {
          if (!m_firstLayout && m_size.height() != layoutSize().height() &&
              body->layoutObject()->enclosingBox()->stretchesToViewport())
            body->layoutObject()->setChildNeedsLayout();
        }
      }

      ScrollbarMode hMode;
      ScrollbarMode vMode;
      calculateScrollbarModes(hMode, vMode);

      // Now set our scrollbar state for the layout.
      ScrollbarMode currentHMode = horizontalScrollbarMode();
      ScrollbarMode currentVMode = verticalScrollbarMode();

      if (m_firstLayout) {
        setScrollbarsSuppressed(true);

        m_firstLayout = false;
        m_lastViewportSize = layoutSize(IncludeScrollbars);
        m_lastZoomFactor = layoutViewItem().style()->zoom();

        // Set the initial vMode to AlwaysOn if we're auto.
        if (vMode == ScrollbarAuto) {
          // This causes a vertical scrollbar to appear.
          setVerticalScrollbarMode(ScrollbarAlwaysOn);
        }
        // Set the initial hMode to AlwaysOff if we're auto.
        if (hMode == ScrollbarAuto) {
          // This causes a horizontal scrollbar to disappear.
          setHorizontalScrollbarMode(ScrollbarAlwaysOff);
        }

        setScrollbarModes(hMode, vMode);
        setScrollbarsSuppressed(false);
      } else if (hMode != currentHMode || vMode != currentVMode) {
        setScrollbarModes(hMode, vMode);
      }

      updateScrollbarsIfNeeded();

      LayoutSize oldSize = m_size;

      m_size = LayoutSize(layoutSize());

      if (oldSize != m_size && !m_firstLayout) {
        LayoutBox* rootLayoutObject =
            document->documentElement()
                ? document->documentElement()->layoutBox()
                : 0;
        LayoutBox* bodyLayoutObject = rootLayoutObject && document->body()
                                          ? document->body()->layoutBox()
                                          : 0;
        if (bodyLayoutObject && bodyLayoutObject->stretchesToViewport())
          bodyLayoutObject->setChildNeedsLayout();
        else if (rootLayoutObject && rootLayoutObject->stretchesToViewport())
          rootLayoutObject->setChildNeedsLayout();
      }
    }

    TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
        TRACE_DISABLED_BY_DEFAULT("blink.debug.layout.trees"), "LayoutTree",
        this, TracedLayoutObject::create(*layoutView(), false));

    performLayout(inSubtreeLayout);

    if (!inSubtreeLayout && !document->printing())
      adjustViewSizeAndLayout();

    ASSERT(m_layoutSubtreeRootList.isEmpty());
  }  // Reset m_layoutSchedulingEnabled to its previous value.
  checkDoesNotNeedLayout();

  m_frameTimingRequestsDirty = true;

  // FIXME: Could find the common ancestor layer of all dirty subtrees and mark
  // from there. crbug.com/462719
  layoutViewItem().enclosingLayer()->updateLayerPositionsAfterLayout();

  TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
      TRACE_DISABLED_BY_DEFAULT("blink.debug.layout.trees"), "LayoutTree", this,
      TracedLayoutObject::create(*layoutView(), true));

  layoutViewItem().compositor()->didLayout();

  m_layoutCount++;

  if (AXObjectCache* cache = document->axObjectCache()) {
    const KURL& url = document->url();
    if (url.isValid() && !url.isAboutBlankURL())
      cache->handleLayoutComplete(document);
  }
  updateDocumentAnnotatedRegions();
  checkDoesNotNeedLayout();

  scheduleOrPerformPostLayoutTasks();
  checkDoesNotNeedLayout();

  // FIXME: The notion of a single root for layout is no longer applicable.
  // Remove or update this code. crbug.com/460596
  TRACE_EVENT_END1("devtools.timeline", "Layout", "endData",
                   InspectorLayoutEvent::endData(rootForThisLayout));
  InspectorInstrumentation::didUpdateLayout(m_frame.get());
  PerformanceMonitor::didUpdateLayout(document);

  m_nestedLayoutCount--;
  if (m_nestedLayoutCount)
    return;

#if DCHECK_IS_ON()
  // Post-layout assert that nobody was re-marked as needing layout during
  // layout.
  layoutView()->assertSubtreeIsLaidOut();
#endif

  frame().document()->layoutUpdated();
  checkDoesNotNeedLayout();
}

void FrameView::invalidateTreeIfNeeded(
    const PaintInvalidationState& paintInvalidationState) {
  DCHECK(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled());

  if (shouldThrottleRendering())
    return;

  lifecycle().advanceTo(DocumentLifecycle::InPaintInvalidation);

  RELEASE_ASSERT(!layoutViewItem().isNull());
  LayoutViewItem rootForPaintInvalidation = layoutViewItem();
  ASSERT(!rootForPaintInvalidation.needsLayout());

  TRACE_EVENT1("blink", "FrameView::invalidateTree", "root",
               rootForPaintInvalidation.debugName().ascii());

  invalidatePaintIfNeeded(paintInvalidationState);
  rootForPaintInvalidation.invalidateTreeIfNeeded(paintInvalidationState);

#if DCHECK_IS_ON()
  layoutView()->assertSubtreeClearedPaintInvalidationFlags();
#endif

  lifecycle().advanceTo(DocumentLifecycle::PaintInvalidationClean);
}

void FrameView::invalidatePaintIfNeeded(
    const PaintInvalidationState& paintInvalidationState) {
  RELEASE_ASSERT(!layoutViewItem().isNull());
  if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled())
    invalidatePaintOfScrollControlsIfNeeded(paintInvalidationState);

  if (m_frame->selection().isCaretBoundsDirty())
    m_frame->selection().invalidateCaretRect();
}

void FrameView::setNeedsPaintPropertyUpdate() {
  m_needsPaintPropertyUpdate = true;
  if (LayoutObject* owner = frame().ownerLayoutObject())
    owner->setNeedsPaintPropertyUpdate();
}

IntRect FrameView::computeVisibleArea() {
  // Return our clipping bounds in the root frame.
  IntRect us(frameRect());
  if (FrameView* parent = parentFrameView()) {
    us = parent->contentsToRootFrame(us);
    IntRect parentRect = parent->computeVisibleArea();
    if (parentRect.isEmpty())
      return IntRect();

    us.intersect(parentRect);
  }

  return us;
}

FloatSize FrameView::viewportSizeForViewportUnits() const {
  float zoom = frame().pageZoomFactor();

  if (m_frame->settings() &&
      !RuntimeEnabledFeatures::inertTopControlsEnabled()) {
    FloatSize viewportSize;

    LayoutViewItem layoutViewItem = this->layoutViewItem();
    if (layoutViewItem.isNull())
      return viewportSize;

    viewportSize.setWidth(layoutViewItem.viewWidth(IncludeScrollbars) / zoom);
    viewportSize.setHeight(layoutViewItem.viewHeight(IncludeScrollbars) / zoom);
    return viewportSize;
  }

  FloatSize size(layoutSize(IncludeScrollbars));

  // We use the layoutSize rather than frameRect to calculate viewport units
  // so that we get correct results on mobile where the page is laid out into
  // a rect that may be larger than the viewport (e.g. the 980px fallback
  // width for desktop pages). Since the layout height is statically set to
  // be the viewport with browser controls showing, we add the browser controls
  // height, compensating for page scale as well, since we want to use the
  // viewport with browser controls hidden for vh (to match Safari).
  BrowserControls& browserControls = m_frame->host()->browserControls();
  if (m_frame->isMainFrame() && size.width()) {
    float pageScaleAtLayoutWidth =
        m_frame->host()->visualViewport().size().width() / size.width();
    size.expand(0, browserControls.height() / pageScaleAtLayoutWidth);
  }

  size.scale(1 / zoom);
  return size;
}

DocumentLifecycle& FrameView::lifecycle() const {
  DCHECK(m_frame);
  DCHECK(m_frame->document());
  return m_frame->document()->lifecycle();
}

LayoutReplaced* FrameView::embeddedReplacedContent() const {
  LayoutViewItem layoutViewItem = this->layoutViewItem();
  if (layoutViewItem.isNull())
    return nullptr;

  LayoutObject* firstChild = layoutView()->firstChild();
  if (!firstChild || !firstChild->isBox())
    return nullptr;

  // Currently only embedded SVG documents participate in the size-negotiation
  // logic.
  if (firstChild->isSVGRoot())
    return toLayoutSVGRoot(firstChild);

  return nullptr;
}

void FrameView::addPart(LayoutPart* object) {
  m_parts.add(object);
}

void FrameView::removePart(LayoutPart* object) {
  m_parts.remove(object);
}

void FrameView::updateWidgetGeometries() {
  Vector<RefPtr<LayoutPart>> parts;
  copyToVector(m_parts, parts);

  for (auto part : parts) {
    // Script or plugins could detach the frame so abort processing if that
    // happens.
    if (layoutViewItem().isNull())
      break;

    if (Widget* widget = part->widget()) {
      if (widget->isFrameView()) {
        FrameView* frameView = toFrameView(widget);
        bool didNeedLayout = frameView->needsLayout();
        part->updateWidgetGeometry();
        if (!didNeedLayout && !frameView->shouldThrottleRendering())
          frameView->checkDoesNotNeedLayout();
      } else {
        part->updateWidgetGeometry();
      }
    }
  }
}

void FrameView::addPartToUpdate(LayoutEmbeddedObject& object) {
  ASSERT(isInPerformLayout());
  // Tell the DOM element that it needs a widget update.
  Node* node = object.node();
  ASSERT(node);
  if (isHTMLObjectElement(*node) || isHTMLEmbedElement(*node))
    toHTMLPlugInElement(node)->setNeedsWidgetUpdate(true);

  m_partUpdateSet.add(&object);
}

void FrameView::setDisplayMode(WebDisplayMode mode) {
  if (mode == m_displayMode)
    return;

  m_displayMode = mode;

  if (m_frame->document())
    m_frame->document()->mediaQueryAffectingValueChanged();
}

void FrameView::setDisplayShape(DisplayShape displayShape) {
  if (displayShape == m_displayShape)
    return;

  m_displayShape = displayShape;

  if (m_frame->document())
    m_frame->document()->mediaQueryAffectingValueChanged();
}

void FrameView::setMediaType(const AtomicString& mediaType) {
  DCHECK(m_frame->document());
  m_mediaType = mediaType;
  m_frame->document()->mediaQueryAffectingValueChanged();
}

AtomicString FrameView::mediaType() const {
  // See if we have an override type.
  if (m_frame->settings() &&
      !m_frame->settings()->mediaTypeOverride().isEmpty())
    return AtomicString(m_frame->settings()->mediaTypeOverride());
  return m_mediaType;
}

void FrameView::adjustMediaTypeForPrinting(bool printing) {
  if (printing) {
    if (m_mediaTypeWhenNotPrinting.isNull())
      m_mediaTypeWhenNotPrinting = mediaType();
    setMediaType(MediaTypeNames::print);
  } else {
    if (!m_mediaTypeWhenNotPrinting.isNull())
      setMediaType(m_mediaTypeWhenNotPrinting);
    m_mediaTypeWhenNotPrinting = nullAtom;
  }
}

bool FrameView::contentsInCompositedLayer() const {
  LayoutViewItem layoutViewItem = this->layoutViewItem();
  return !layoutViewItem.isNull() &&
         layoutViewItem.compositingState() == PaintsIntoOwnBacking;
}

void FrameView::addBackgroundAttachmentFixedObject(LayoutObject* object) {
  ASSERT(!m_backgroundAttachmentFixedObjects.contains(object));

  m_backgroundAttachmentFixedObjects.add(object);
  if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    scrollingCoordinator->frameViewHasBackgroundAttachmentFixedObjectsDidChange(
        this);

  // Ensure main thread scrolling reasons are recomputed.
  if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) {
    setNeedsPaintPropertyUpdate();
    // The object's scroll properties are not affected by its own background.
    object->setAncestorsNeedPaintPropertyUpdateForMainThreadScrolling();
  }
}

void FrameView::removeBackgroundAttachmentFixedObject(LayoutObject* object) {
  ASSERT(m_backgroundAttachmentFixedObjects.contains(object));

  m_backgroundAttachmentFixedObjects.remove(object);
  if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    scrollingCoordinator->frameViewHasBackgroundAttachmentFixedObjectsDidChange(
        this);

  // Ensure main thread scrolling reasons are recomputed.
  if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) {
    setNeedsPaintPropertyUpdate();
    // The object's scroll properties are not affected by its own background.
    object->setAncestorsNeedPaintPropertyUpdateForMainThreadScrolling();
  }
}

void FrameView::addViewportConstrainedObject(LayoutObject* object) {
  if (!m_viewportConstrainedObjects) {
    m_viewportConstrainedObjects =
        WTF::wrapUnique(new ViewportConstrainedObjectSet);
  }

  if (!m_viewportConstrainedObjects->contains(object)) {
    m_viewportConstrainedObjects->add(object);

    if (ScrollingCoordinator* scrollingCoordinator =
            this->scrollingCoordinator())
      scrollingCoordinator->frameViewFixedObjectsDidChange(this);
  }
}

void FrameView::removeViewportConstrainedObject(LayoutObject* object) {
  if (m_viewportConstrainedObjects &&
      m_viewportConstrainedObjects->contains(object)) {
    m_viewportConstrainedObjects->remove(object);

    if (ScrollingCoordinator* scrollingCoordinator =
            this->scrollingCoordinator())
      scrollingCoordinator->frameViewFixedObjectsDidChange(this);
  }
}

void FrameView::viewportSizeChanged(bool widthChanged, bool heightChanged) {
  DCHECK(widthChanged || heightChanged);

  if (LayoutViewItem layoutView = this->layoutViewItem()) {
    if (layoutView.usesCompositing())
      layoutView.compositor()->frameViewDidChangeSize();
  }

  // Ensure the root scroller compositing layers update geometry in response to
  // the URL bar resizing.
  if (m_frame->isMainFrame()) {
    m_frame->document()
        ->frameHost()
        ->globalRootScrollerController()
        .mainFrameViewResized();
  }

  showOverlayScrollbars();
  if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
    // The background must be repainted when the FrameView is resized, even if
    // the initial containing block does not change (so we can't rely on layout
    // to issue the invalidation).  This is because the background fills the
    // main GraphicsLayer, which takes the size of the layout viewport.
    // TODO(skobes): Paint non-fixed backgrounds into the scrolling contents
    // layer and avoid this invalidation (http://crbug.com/568847).
    LayoutViewItem lvi = layoutViewItem();
    if (!lvi.isNull())
      lvi.setShouldDoFullPaintInvalidation();
  }

  if (RuntimeEnabledFeatures::inertTopControlsEnabled() && layoutView() &&
      layoutView()->style()->hasFixedBackgroundImage()) {
    // In the case where we don't change layout size from top control resizes,
    // we wont perform a layout. If we have a fixed background image however,
    // the background layer needs to get resized so we should request a layout
    // explicitly.
    PaintLayer* layer = layoutView()->layer();
    if (layoutView()->compositor()->needsFixedRootBackgroundLayer(layer)) {
      setNeedsLayout();
    } else if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
      // If root layer scrolls is on, we've already issued a full invalidation
      // above.
      layoutView()->setShouldDoFullPaintInvalidationOnResizeIfNeeded(
          widthChanged, heightChanged);
    }
  }

  if (!hasViewportConstrainedObjects())
    return;

  for (const auto& viewportConstrainedObject : *m_viewportConstrainedObjects) {
    LayoutObject* layoutObject = viewportConstrainedObject;
    const ComputedStyle& style = layoutObject->styleRef();
    if (widthChanged) {
      if (style.width().isFixed() &&
          (style.left().isAuto() || style.right().isAuto()))
        layoutObject->setNeedsPositionedMovementLayout();
      else
        layoutObject->setNeedsLayoutAndFullPaintInvalidation(
            LayoutInvalidationReason::SizeChanged);
    }
    if (heightChanged) {
      if (style.height().isFixed() &&
          (style.top().isAuto() || style.bottom().isAuto()))
        layoutObject->setNeedsPositionedMovementLayout();
      else
        layoutObject->setNeedsLayoutAndFullPaintInvalidation(
            LayoutInvalidationReason::SizeChanged);
    }
  }
}

IntPoint FrameView::lastKnownMousePosition() const {
  return m_frame->eventHandler().lastKnownMousePosition();
}

bool FrameView::shouldSetCursor() const {
  Page* page = frame().page();
  return page && page->visibilityState() != PageVisibilityStateHidden &&
         page->focusController().isActive() &&
         page->settings().deviceSupportsMouse();
}

void FrameView::scrollContentsIfNeededRecursive() {
  forAllNonThrottledFrameViews(
      [](FrameView& frameView) { frameView.scrollContentsIfNeeded(); });
}

void FrameView::invalidateBackgroundAttachmentFixedObjects() {
  for (const auto& layoutObject : m_backgroundAttachmentFixedObjects)
    layoutObject->setShouldDoFullPaintInvalidation();
}

bool FrameView::hasBackgroundAttachmentFixedDescendants(
    const LayoutObject& object) const {
  for (const auto* potentialDescendant : m_backgroundAttachmentFixedObjects) {
    if (potentialDescendant == &object)
      continue;
    if (potentialDescendant->isDescendantOf(&object))
      return true;
  }
  return false;
}

bool FrameView::invalidateViewportConstrainedObjects() {
  bool fastPathAllowed = true;
  for (const auto& viewportConstrainedObject : *m_viewportConstrainedObjects) {
    LayoutObject* layoutObject = viewportConstrainedObject;
    LayoutItem layoutItem = LayoutItem(layoutObject);
    ASSERT(layoutItem.style()->hasViewportConstrainedPosition());
    ASSERT(layoutItem.hasLayer());
    PaintLayer* layer = LayoutBoxModel(layoutItem).layer();

    if (layer->isPaintInvalidationContainer())
      continue;

    if (layer->subtreeIsInvisible())
      continue;

    // invalidate even if there is an ancestor with a filter that moves pixels.
    layoutItem
        .setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();

    TRACE_EVENT_INSTANT1(
        TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
        "ScrollInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data",
        InspectorScrollInvalidationTrackingEvent::data(*layoutObject));

    // If the fixed layer has a blur/drop-shadow filter applied on at least one
    // of its parents, we cannot scroll using the fast path, otherwise the
    // outsets of the filter will be moved around the page.
    if (layer->hasAncestorWithFilterThatMovesPixels())
      fastPathAllowed = false;
  }
  return fastPathAllowed;
}

bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta) {
  if (!contentsInCompositedLayer())
    return false;

  invalidateBackgroundAttachmentFixedObjects();

  if (!m_viewportConstrainedObjects ||
      m_viewportConstrainedObjects->isEmpty()) {
    InspectorInstrumentation::didUpdateLayout(m_frame.get());
    return true;
  }

  if (!invalidateViewportConstrainedObjects())
    return false;

  InspectorInstrumentation::didUpdateLayout(m_frame.get());
  return true;
}

void FrameView::scrollContentsSlowPath() {
  TRACE_EVENT0("blink", "FrameView::scrollContentsSlowPath");
  // We need full invalidation during slow scrolling. For slimming paint, full
  // invalidation of the LayoutView is not enough. We also need to invalidate
  // all of the objects.
  // FIXME: Find out what are enough to invalidate in slow path scrolling.
  // crbug.com/451090#9.
  ASSERT(!layoutViewItem().isNull());
  if (contentsInCompositedLayer())
    layoutViewItem()
        .layer()
        ->compositedLayerMapping()
        ->setContentsNeedDisplay();
  else
    layoutViewItem()
        .setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();

  if (contentsInCompositedLayer()) {
    IntRect updateRect = visibleContentRect();
    ASSERT(!layoutViewItem().isNull());
    // FIXME: We should not allow paint invalidation out of paint invalidation
    // state. crbug.com/457415
    DisablePaintInvalidationStateAsserts disabler;
    layoutViewItem().invalidatePaintRectangle(LayoutRect(updateRect));
  }
  LayoutPartItem frameLayoutItem = m_frame->ownerLayoutItem();
  if (!frameLayoutItem.isNull()) {
    if (isEnclosedInCompositingLayer()) {
      LayoutRect rect(
          frameLayoutItem.borderLeft() + frameLayoutItem.paddingLeft(),
          frameLayoutItem.borderTop() + frameLayoutItem.paddingTop(),
          LayoutUnit(visibleWidth()), LayoutUnit(visibleHeight()));
      // FIXME: We should not allow paint invalidation out of paint invalidation
      // state. crbug.com/457415
      DisablePaintInvalidationStateAsserts disabler;
      frameLayoutItem.invalidatePaintRectangle(rect);
      return;
    }
  }
}

void FrameView::restoreScrollbar() {
  setScrollbarsSuppressed(false);
}

void FrameView::processUrlFragment(const KURL& url,
                                   UrlFragmentBehavior behavior) {
  // If our URL has no ref, then we have no place we need to jump to.
  // OTOH If CSS target was set previously, we want to set it to 0, recalc
  // and possibly paint invalidation because :target pseudo class may have been
  // set (see bug 11321).
  // Similarly for svg, if we had a previous svgView() then we need to reset
  // the initial view if we don't have a fragment.
  if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget() &&
      !m_frame->document()->isSVGDocument())
    return;

  String fragmentIdentifier = url.fragmentIdentifier();
  if (processUrlFragmentHelper(fragmentIdentifier, behavior))
    return;

  // Try again after decoding the ref, based on the document's encoding.
  if (m_frame->document()->encoding().isValid())
    processUrlFragmentHelper(
        decodeURLEscapeSequences(fragmentIdentifier,
                                 m_frame->document()->encoding()),
        behavior);
}

bool FrameView::processUrlFragmentHelper(const String& name,
                                         UrlFragmentBehavior behavior) {
  ASSERT(m_frame->document());

  if (behavior == UrlFragmentScroll &&
      !m_frame->document()->isRenderingReady()) {
    m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
    return false;
  }

  m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false);

  Element* anchorNode = m_frame->document()->findAnchor(name);

  // Setting to null will clear the current target.
  m_frame->document()->setCSSTarget(anchorNode);

  if (m_frame->document()->isSVGDocument()) {
    if (SVGSVGElement* svg =
            SVGDocumentExtensions::rootElement(*m_frame->document())) {
      svg->setupInitialView(name, anchorNode);
      if (!anchorNode)
        return true;
    }
  }

  // Implement the rule that "" and "top" both mean top of page as in other
  // browsers.
  if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top")))
    return false;

  if (behavior == UrlFragmentScroll)
    setFragmentAnchor(anchorNode ? static_cast<Node*>(anchorNode)
                                 : m_frame->document());

  // If the anchor accepts keyboard focus and fragment scrolling is allowed,
  // move focus there to aid users relying on keyboard navigation.
  // If anchorNode is not focusable or fragment scrolling is not allowed,
  // clear focus, which matches the behavior of other browsers.
  if (anchorNode) {
    m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
    if (behavior == UrlFragmentScroll && anchorNode->isFocusable()) {
      anchorNode->focus();
    } else {
      if (behavior == UrlFragmentScroll)
        m_frame->document()->setSequentialFocusNavigationStartingPoint(
            anchorNode);
      m_frame->document()->clearFocusedElement();
    }
  }
  return true;
}

void FrameView::setFragmentAnchor(Node* anchorNode) {
  ASSERT(anchorNode);
  m_fragmentAnchor = anchorNode;

  // We need to update the layout tree before scrolling.
  m_frame->document()->updateStyleAndLayoutTree();

  // If layout is needed, we will scroll in performPostLayoutTasks. Otherwise,
  // scroll immediately.
  LayoutViewItem layoutViewItem = this->layoutViewItem();
  if (!layoutViewItem.isNull() && layoutViewItem.needsLayout())
    layout();
  else
    scrollToFragmentAnchor();
}

void FrameView::clearFragmentAnchor() {
  m_fragmentAnchor = nullptr;
}

void FrameView::didUpdateElasticOverscroll() {
  Page* page = frame().page();
  if (!page)
    return;
  FloatSize elasticOverscroll = page->chromeClient().elasticOverscroll();
  if (horizontalScrollbar()) {
    float delta =
        elasticOverscroll.width() - horizontalScrollbar()->elasticOverscroll();
    if (delta != 0) {
      horizontalScrollbar()->setElasticOverscroll(elasticOverscroll.width());
      scrollAnimator().notifyContentAreaScrolled(FloatSize(delta, 0));
      setScrollbarNeedsPaintInvalidation(HorizontalScrollbar);
    }
  }
  if (verticalScrollbar()) {
    float delta =
        elasticOverscroll.height() - verticalScrollbar()->elasticOverscroll();
    if (delta != 0) {
      verticalScrollbar()->setElasticOverscroll(elasticOverscroll.height());
      scrollAnimator().notifyContentAreaScrolled(FloatSize(0, delta));
      setScrollbarNeedsPaintInvalidation(VerticalScrollbar);
    }
  }
}

IntSize FrameView::layoutSize(
    IncludeScrollbarsInRect scrollbarInclusion) const {
  return scrollbarInclusion == ExcludeScrollbars
             ? excludeScrollbars(m_layoutSize)
             : m_layoutSize;
}

void FrameView::setLayoutSize(const IntSize& size) {
  ASSERT(!layoutSizeFixedToFrameSize());

  setLayoutSizeInternal(size);
}

void FrameView::didScrollTimerFired(TimerBase*) {
  if (m_frame->document() && !m_frame->document()->layoutViewItem().isNull())
    m_frame->document()->fetcher()->updateAllImageResourcePriorities();
}

void FrameView::updateLayersAndCompositingAfterScrollIfNeeded(
    const ScrollOffset& scrollDelta) {
  // Nothing to do after scrolling if there are no fixed position elements.
  if (!hasViewportConstrainedObjects())
    return;

  // Update sticky position objects which are stuck to the viewport.
  for (const auto& viewportConstrainedObject : *m_viewportConstrainedObjects) {
    LayoutObject* layoutObject = viewportConstrainedObject;
    PaintLayer* layer = toLayoutBoxModelObject(layoutObject)->layer();
    if (layoutObject->style()->position() == StickyPosition) {
      // TODO(skobes): Resolve circular dependency between scroll offset and
      // compositing state, and remove this disabler. https://crbug.com/420741
      DisableCompositingQueryAsserts disabler;
      layer->updateLayerPositionsAfterOverflowScroll(scrollDelta);
    }
  }

  // If there fixed position elements, scrolling may cause compositing layers to
  // change.  Update widget and layer positions after scrolling, but only if
  // we're not inside of layout.
  if (!m_nestedLayoutCount) {
    updateWidgetGeometries();
    LayoutViewItem layoutViewItem = this->layoutViewItem();
    if (!layoutViewItem.isNull())
      layoutViewItem.layer()->setNeedsCompositingInputsUpdate();
  }
}

bool FrameView::computeCompositedSelection(LocalFrame& frame,
                                           CompositedSelection& selection) {
  if (!frame.view() || frame.view()->shouldThrottleRendering())
    return false;

  const VisibleSelection& visibleSelection = frame.selection().selection();
  if (visibleSelection.isNone())
    return false;

  // Non-editable caret selections lack any kind of UI affordance, and
  // needn't be tracked by the client.
  if (visibleSelection.isCaret() && !visibleSelection.isContentEditable())
    return false;

  VisiblePosition visibleStart(visibleSelection.visibleStart());
  RenderedPosition renderedStart(visibleStart);
  renderedStart.positionInGraphicsLayerBacking(selection.start, true);
  if (!selection.start.layer)
    return false;

  VisiblePosition visibleEnd(visibleSelection.visibleEnd());
  RenderedPosition renderedEnd(visibleEnd);
  renderedEnd.positionInGraphicsLayerBacking(selection.end, false);
  if (!selection.end.layer)
    return false;

  selection.type = visibleSelection.getSelectionType();
  selection.isEditable = visibleSelection.isContentEditable();
  if (selection.isEditable) {
    if (TextControlElement* enclosingTextControlElement =
            enclosingTextControl(visibleSelection.rootEditableElement())) {
      selection.isEmptyTextControl =
          enclosingTextControlElement->value().isEmpty();
    }
  }
  selection.start.isTextDirectionRTL |=
      primaryDirectionOf(*visibleSelection.start().anchorNode()) == RTL;
  selection.end.isTextDirectionRTL |=
      primaryDirectionOf(*visibleSelection.end().anchorNode()) == RTL;

  return true;
}

void FrameView::updateCompositedSelectionIfNeeded() {
  if (!RuntimeEnabledFeatures::compositedSelectionUpdateEnabled())
    return;

  TRACE_EVENT0("blink", "FrameView::updateCompositedSelectionIfNeeded");

  Page* page = frame().page();
  ASSERT(page);

  CompositedSelection selection;
  LocalFrame* focusedFrame = page->focusController().focusedFrame();
  LocalFrame* localFrame = (focusedFrame && (focusedFrame->localFrameRoot() ==
                                             m_frame->localFrameRoot()))
                               ? focusedFrame
                               : nullptr;

  if (localFrame && computeCompositedSelection(*localFrame, selection)) {
    page->chromeClient().updateCompositedSelection(localFrame, selection);
  } else {
    if (!localFrame) {
      // Clearing the mainframe when there is no focused frame (and hence
      // no localFrame) is legacy behaviour, and implemented here to
      // satisfy ParameterizedWebFrameTest.CompositedSelectionBoundsCleared's
      // first check that the composited selection has been cleared even
      // though no frame has focus yet. If this is not desired, then the
      // expectation needs to be removed from the test.
      localFrame = m_frame->localFrameRoot();
    }

    if (localFrame)
      page->chromeClient().clearCompositedSelection(localFrame);
  }
}

HostWindow* FrameView::getHostWindow() const {
  Page* page = frame().page();
  if (!page)
    return nullptr;
  return &page->chromeClient();
}

void FrameView::contentsResized() {
  if (m_frame->isMainFrame() && m_frame->document()) {
    if (TextAutosizer* textAutosizer = m_frame->document()->textAutosizer())
      textAutosizer->updatePageInfoInAllFrames();
  }

  ScrollableArea::contentsResized();
  setNeedsLayout();
}

void FrameView::scrollbarExistenceDidChange() {
  // We check to make sure the view is attached to a frame() as this method can
  // be triggered before the view is attached by LocalFrame::createView(...)
  // setting various values such as setScrollBarModes(...) for example.  An
  // ASSERT is triggered when a view is layout before being attached to a
  // frame().
  if (!frame().view())
    return;

  bool usesOverlayScrollbars = ScrollbarTheme::theme().usesOverlayScrollbars();

  // FIXME: this call to layout() could be called within FrameView::layout(),
  // but before performLayout(), causing double-layout. See also
  // crbug.com/429242.
  if (!usesOverlayScrollbars && needsLayout())
    layout();

  if (!layoutViewItem().isNull() && layoutViewItem().usesCompositing()) {
    layoutViewItem().compositor()->frameViewScrollbarsExistenceDidChange();

    if (!usesOverlayScrollbars)
      layoutViewItem().compositor()->frameViewDidChangeSize();
  }
}

void FrameView::handleLoadCompleted() {
  // Once loading has completed, allow autoSize one last opportunity to
  // reduce the size of the frame.
  if (m_autoSizeInfo)
    m_autoSizeInfo->autoSizeIfNeeded();

  // If there is a pending layout, the fragment anchor will be cleared when it
  // finishes.
  if (!needsLayout())
    clearFragmentAnchor();
}

void FrameView::clearLayoutSubtreeRoot(const LayoutObject& root) {
  m_layoutSubtreeRootList.remove(const_cast<LayoutObject&>(root));
}

void FrameView::clearLayoutSubtreeRootsAndMarkContainingBlocks() {
  m_layoutSubtreeRootList.clearAndMarkContainingBlocksForLayout();
}

void FrameView::addOrthogonalWritingModeRoot(LayoutBox& root) {
  DCHECK(!root.isLayoutScrollbarPart());
  m_orthogonalWritingModeRootList.add(root);
}

void FrameView::removeOrthogonalWritingModeRoot(LayoutBox& root) {
  m_orthogonalWritingModeRootList.remove(root);
}

bool FrameView::hasOrthogonalWritingModeRoots() const {
  return !m_orthogonalWritingModeRootList.isEmpty();
}

static inline void removeFloatingObjectsForSubtreeRoot(LayoutObject& root) {
  // TODO(kojii): Under certain conditions, moveChildTo() defers
  // removeFloatingObjects() until the containing block layouts. For
  // instance, when descendants of the moving child is floating,
  // removeChildNode() does not clear them. In such cases, at this
  // point, FloatingObjects may contain old or even deleted objects.
  // Dealing this in markAllDescendantsWithFloatsForLayout() could
  // solve, but since that is likely to suffer the performance and
  // since the containing block of orthogonal writing mode roots
  // having floats is very rare, prefer to re-create
  // FloatingObjects.
  if (LayoutBlock* cb = root.containingBlock()) {
    if ((cb->normalChildNeedsLayout() || cb->selfNeedsLayout()) &&
        cb->isLayoutBlockFlow())
      toLayoutBlockFlow(cb)->removeFloatingObjects();
  }
}

void FrameView::layoutOrthogonalWritingModeRoots() {
  for (auto& root : m_orthogonalWritingModeRootList.ordered()) {
    ASSERT(root->isBox() && toLayoutBox(*root).isOrthogonalWritingModeRoot());
    if (!root->needsLayout() || root->isOutOfFlowPositioned() ||
        root->isColumnSpanAll() ||
        !root->styleRef().logicalHeight().isIntrinsicOrAuto()) {
      continue;
    }

    removeFloatingObjectsForSubtreeRoot(*root);
    layoutFromRootObject(*root);
  }
}

bool FrameView::checkLayoutInvalidationIsAllowed() const {
  if (m_allowsLayoutInvalidationAfterLayoutClean)
    return true;

  // If we are updating all lifecycle phases beyond LayoutClean, we don't expect
  // dirty layout after LayoutClean.
  CHECK_FOR_DIRTY_LAYOUT(lifecycle().state() < DocumentLifecycle::LayoutClean);

  return true;
}

void FrameView::scheduleRelayout() {
  DCHECK(m_frame->view() == this);

  if (!m_layoutSchedulingEnabled)
    return;
  // TODO(crbug.com/590856): It's still broken when we choose not to crash when
  // the check fails.
  if (!checkLayoutInvalidationIsAllowed())
    return;
  if (!needsLayout())
    return;
  if (!m_frame->document()->shouldScheduleLayout())
    return;
  TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
                       "InvalidateLayout", TRACE_EVENT_SCOPE_THREAD, "data",
                       InspectorInvalidateLayoutEvent::data(m_frame.get()));

  clearLayoutSubtreeRootsAndMarkContainingBlocks();

  if (m_hasPendingLayout)
    return;
  m_hasPendingLayout = true;

  if (!shouldThrottleRendering())
    page()->animator().scheduleVisualUpdate(m_frame.get());
}

void FrameView::scheduleRelayoutOfSubtree(LayoutObject* relayoutRoot) {
  DCHECK(m_frame->view() == this);

  // TODO(crbug.com/590856): It's still broken when we choose not to crash when
  // the check fails.
  if (!checkLayoutInvalidationIsAllowed())
    return;

  // FIXME: Should this call shouldScheduleLayout instead?
  if (!m_frame->document()->isActive())
    return;

  LayoutView* layoutView = this->layoutView();
  if (layoutView && layoutView->needsLayout()) {
    if (relayoutRoot)
      relayoutRoot->markContainerChainForLayout(false);
    return;
  }

  if (relayoutRoot == layoutView)
    m_layoutSubtreeRootList.clearAndMarkContainingBlocksForLayout();
  else
    m_layoutSubtreeRootList.add(*relayoutRoot);

  if (m_layoutSchedulingEnabled) {
    m_hasPendingLayout = true;

    if (!shouldThrottleRendering())
      page()->animator().scheduleVisualUpdate(m_frame.get());

    lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean);
  }
  TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
                       "InvalidateLayout", TRACE_EVENT_SCOPE_THREAD, "data",
                       InspectorInvalidateLayoutEvent::data(m_frame.get()));
}

bool FrameView::layoutPending() const {
  // FIXME: This should check Document::lifecycle instead.
  return m_hasPendingLayout;
}

bool FrameView::isInPerformLayout() const {
  return lifecycle().state() == DocumentLifecycle::InPerformLayout;
}

bool FrameView::needsLayout() const {
  // This can return true in cases where the document does not have a body yet.
  // Document::shouldScheduleLayout takes care of preventing us from scheduling
  // layout in that case.

  LayoutViewItem layoutViewItem = this->layoutViewItem();
  return layoutPending() ||
         (!layoutViewItem.isNull() && layoutViewItem.needsLayout()) ||
         isSubtreeLayout();
}

NOINLINE bool FrameView::checkDoesNotNeedLayout() const {
  CHECK_FOR_DIRTY_LAYOUT(!layoutPending());
  CHECK_FOR_DIRTY_LAYOUT(layoutViewItem().isNull() ||
                         !layoutViewItem().needsLayout());
  CHECK_FOR_DIRTY_LAYOUT(!isSubtreeLayout());
  return true;
}

void FrameView::setNeedsLayout() {
  LayoutViewItem layoutViewItem = this->layoutViewItem();
  if (layoutViewItem.isNull())
    return;
  // TODO(crbug.com/590856): It's still broken if we choose not to crash when
  // the check fails.
  if (!checkLayoutInvalidationIsAllowed())
    return;
  layoutViewItem.setNeedsLayout(LayoutInvalidationReason::Unknown);
}

bool FrameView::isTransparent() const {
  return m_isTransparent;
}

void FrameView::setTransparent(bool isTransparent) {
  m_isTransparent = isTransparent;
  DisableCompositingQueryAsserts disabler;
  if (!layoutViewItem().isNull() &&
      layoutViewItem().layer()->hasCompositedLayerMapping())
    layoutViewItem().layer()->compositedLayerMapping()->updateContentsOpaque();
}

bool FrameView::hasOpaqueBackground() const {
  return !m_isTransparent && !m_baseBackgroundColor.hasAlpha();
}

Color FrameView::baseBackgroundColor() const {
  return m_baseBackgroundColor;
}

void FrameView::setBaseBackgroundColor(const Color& backgroundColor) {
  m_baseBackgroundColor = backgroundColor;

  if (!layoutViewItem().isNull() &&
      layoutViewItem().layer()->hasCompositedLayerMapping()) {
    CompositedLayerMapping* compositedLayerMapping =
        layoutViewItem().layer()->compositedLayerMapping();
    compositedLayerMapping->updateContentsOpaque();
    if (compositedLayerMapping->mainGraphicsLayer())
      compositedLayerMapping->mainGraphicsLayer()->setNeedsDisplay();
  }
  recalculateScrollbarOverlayColorTheme(documentBackgroundColor());

  if (!shouldThrottleRendering())
    page()->animator().scheduleVisualUpdate(m_frame.get());
}

void FrameView::updateBackgroundRecursively(const Color& backgroundColor,
                                            bool transparent) {
  forAllNonThrottledFrameViews(
      [backgroundColor, transparent](FrameView& frameView) {
        frameView.setTransparent(transparent);
        frameView.setBaseBackgroundColor(backgroundColor);
      });
}

void FrameView::scrollToFragmentAnchor() {
  Node* anchorNode = m_fragmentAnchor;
  if (!anchorNode)
    return;

  // Scrolling is disabled during updateScrollbars (see
  // isProgrammaticallyScrollable).  Bail now to avoid clearing m_fragmentAnchor
  // before we actually have a chance to scroll.
  if (m_inUpdateScrollbars)
    return;

  if (anchorNode->layoutObject()) {
    LayoutRect rect;
    if (anchorNode != m_frame->document()) {
      rect = anchorNode->boundingBox();
    } else if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
      if (Element* documentElement = m_frame->document()->documentElement())
        rect = documentElement->boundingBox();
    }

    Frame* boundaryFrame = m_frame->findUnsafeParentScrollPropagationBoundary();

    // FIXME: Handle RemoteFrames
    if (boundaryFrame && boundaryFrame->isLocalFrame())
      toLocalFrame(boundaryFrame)
          ->view()
          ->setSafeToPropagateScrollToParent(false);

    // Scroll nested layers and frames to reveal the anchor.
    // Align to the top and to the closest side (this matches other browsers).
    anchorNode->layoutObject()->scrollRectToVisible(
        rect, ScrollAlignment::alignToEdgeIfNeeded,
        ScrollAlignment::alignTopAlways);

    if (boundaryFrame && boundaryFrame->isLocalFrame())
      toLocalFrame(boundaryFrame)
          ->view()
          ->setSafeToPropagateScrollToParent(true);

    if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
      cache->handleScrolledToAnchor(anchorNode);
  }

  // The fragment anchor should only be maintained while the frame is still
  // loading.  If the frame is done loading, clear the anchor now. Otherwise,
  // restore it since it may have been cleared during scrollRectToVisible.
  m_fragmentAnchor =
      m_frame->document()->isLoadCompleted() ? nullptr : anchorNode;
}

bool FrameView::updateWidgets() {
  // This is always called from updateWidgetsTimerFired.
  // m_updateWidgetsTimer should only be scheduled if we have widgets to update.
  // Thus I believe we can stop checking isEmpty here, and just ASSERT isEmpty:
  // FIXME: This assert has been temporarily removed due to
  // https://crbug.com/430344
  if (m_nestedLayoutCount > 1 || m_partUpdateSet.isEmpty())
    return true;

  // Need to swap because script will run inside the below loop and invalidate
  // the iterator.
  EmbeddedObjectSet objects;
  objects.swap(m_partUpdateSet);

  for (const auto& embeddedObject : objects) {
    LayoutEmbeddedObject& object = *embeddedObject;
    HTMLPlugInElement* element = toHTMLPlugInElement(object.node());

    // The object may have already been destroyed (thus node cleared),
    // but FrameView holds a manual ref, so it won't have been deleted.
    if (!element)
      continue;

    // No need to update if it's already crashed or known to be missing.
    if (object.showsUnavailablePluginIndicator())
      continue;

    if (element->needsWidgetUpdate())
      element->updateWidget();
    object.updateWidgetGeometry();

    // Prevent plugins from causing infinite updates of themselves.
    // FIXME: Do we really need to prevent this?
    m_partUpdateSet.remove(&object);
  }

  return m_partUpdateSet.isEmpty();
}

void FrameView::updateWidgetsTimerFired(TimerBase*) {
  ASSERT(!isInPerformLayout());
  for (unsigned i = 0; i < maxUpdateWidgetsIterations; ++i) {
    if (updateWidgets())
      return;
  }
}

void FrameView::flushAnyPendingPostLayoutTasks() {
  ASSERT(!isInPerformLayout());
  if (m_postLayoutTasksTimer.isActive())
    performPostLayoutTasks();
  if (m_updateWidgetsTimer.isActive()) {
    m_updateWidgetsTimer.stop();
    updateWidgetsTimerFired(nullptr);
  }
}

void FrameView::scheduleUpdateWidgetsIfNecessary() {
  ASSERT(!isInPerformLayout());
  if (m_updateWidgetsTimer.isActive() || m_partUpdateSet.isEmpty())
    return;
  m_updateWidgetsTimer.startOneShot(0, BLINK_FROM_HERE);
}

void FrameView::performPostLayoutTasks() {
  // FIXME: We can reach here, even when the page is not active!
  // http/tests/inspector/elements/html-link-import.html and many other
  // tests hit that case.
  // We should ASSERT(isActive()); or at least return early if we can!

  // Always called before or after performLayout(), part of the highest-level
  // layout() call.
  ASSERT(!isInPerformLayout());
  TRACE_EVENT0("blink,benchmark", "FrameView::performPostLayoutTasks");

  m_postLayoutTasksTimer.stop();

  m_frame->selection().setCaretRectNeedsUpdate();
  m_frame->selection().updateAppearance();

  ASSERT(m_frame->document());

  FontFaceSet::didLayout(*m_frame->document());
  // Cursor update scheduling is done by the local root, which is the main frame
  // if there are no RemoteFrame ancestors in the frame tree. Use of
  // localFrameRoot() is discouraged but will change when cursor update
  // scheduling is moved from EventHandler to PageEventHandler.
  frame().localFrameRoot()->eventHandler().scheduleCursorUpdate();

  updateWidgetGeometries();

  // Plugins could have torn down the page inside updateWidgetGeometries().
  if (layoutViewItem().isNull())
    return;

  scheduleUpdateWidgetsIfNecessary();

  if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    scrollingCoordinator->notifyGeometryChanged();

  scrollToFragmentAnchor();
  sendResizeEventIfNeeded();
}

bool FrameView::wasViewportResized() {
  ASSERT(m_frame);
  LayoutViewItem layoutViewItem = this->layoutViewItem();
  if (layoutViewItem.isNull())
    return false;
  ASSERT(layoutViewItem.style());
  return (layoutSize(IncludeScrollbars) != m_lastViewportSize ||
          layoutViewItem.style()->zoom() != m_lastZoomFactor);
}

void FrameView::sendResizeEventIfNeeded() {
  ASSERT(m_frame);

  LayoutViewItem layoutViewItem = this->layoutViewItem();
  if (layoutViewItem.isNull() || layoutViewItem.document().printing())
    return;

  if (!wasViewportResized())
    return;

  m_lastViewportSize = layoutSize(IncludeScrollbars);
  m_lastZoomFactor = layoutViewItem.style()->zoom();

  if (RuntimeEnabledFeatures::visualViewportAPIEnabled())
    m_frame->document()->enqueueVisualViewportResizeEvent();

  m_frame->document()->enqueueResizeEvent();

  if (m_frame->isMainFrame())
    InspectorInstrumentation::didResizeMainFrame(m_frame.get());
}

void FrameView::postLayoutTimerFired(TimerBase*) {
  performPostLayoutTasks();
}

void FrameView::updateCounters() {
  LayoutView* view = layoutView();
  if (!view->hasLayoutCounters())
    return;

  for (LayoutObject* layoutObject = view; layoutObject;
       layoutObject = layoutObject->nextInPreOrder()) {
    if (!layoutObject->isCounter())
      continue;

    toLayoutCounter(layoutObject)->updateCounter();
  }
}

bool FrameView::shouldUseIntegerScrollOffset() const {
  if (m_frame->settings() &&
      !m_frame->settings()->preferCompositingToLCDTextEnabled())
    return true;

  return ScrollableArea::shouldUseIntegerScrollOffset();
}

bool FrameView::isActive() const {
  Page* page = frame().page();
  return page && page->focusController().isActive();
}

void FrameView::invalidatePaintForTickmarks() {
  if (Scrollbar* scrollbar = verticalScrollbar())
    scrollbar->setNeedsPaintInvalidation(
        static_cast<ScrollbarPart>(~ThumbPart));
}

void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const {
  if (!m_tickmarks.isEmpty())
    tickmarks = m_tickmarks;
  else
    tickmarks = frame().document()->markers().renderedRectsForMarkers(
        DocumentMarker::TextMatch);
}

void FrameView::setInputEventsTransformForEmulation(const IntSize& offset,
                                                    float contentScaleFactor) {
  m_inputEventsOffsetForEmulation = offset;
  m_inputEventsScaleFactorForEmulation = contentScaleFactor;
}

IntSize FrameView::inputEventsOffsetForEmulation() const {
  return m_inputEventsOffsetForEmulation;
}

float FrameView::inputEventsScaleFactor() const {
  float pageScale = m_frame->host()->visualViewport().scale();
  return pageScale * m_inputEventsScaleFactorForEmulation;
}

bool FrameView::scrollbarsCanBeActive() const {
  if (m_frame->view() != this)
    return false;

  return !!m_frame->document();
}

void FrameView::scrollbarVisibilityChanged() {
  updateScrollbarEnabledState();
  LayoutViewItem viewItem = layoutViewItem();
  if (!viewItem.isNull())
    viewItem.clearHitTestCache();
}

IntRect FrameView::scrollableAreaBoundingBox() const {
  LayoutPartItem ownerLayoutItem = frame().ownerLayoutItem();
  if (ownerLayoutItem.isNull())
    return frameRect();

  return ownerLayoutItem.absoluteContentQuad().enclosingBoundingBox();
}

bool FrameView::isScrollable() {
  return getScrollingReasons() == Scrollable;
}

bool FrameView::isProgrammaticallyScrollable() {
  return !m_inUpdateScrollbars;
}

FrameView::ScrollingReasons FrameView::getScrollingReasons() {
  // Check for:
  // 1) If there an actual overflow.
  // 2) display:none or visibility:hidden set to self or inherited.
  // 3) overflow{-x,-y}: hidden;
  // 4) scrolling: no;

  // Covers #1
  IntSize contentsSize = this->contentsSize();
  IntSize visibleContentSize = visibleContentRect().size();
  if ((contentsSize.height() <= visibleContentSize.height() &&
       contentsSize.width() <= visibleContentSize.width()))
    return NotScrollableNoOverflow;

  // Covers #2.
  // FIXME: Do we need to fix this for OOPI?
  HTMLFrameOwnerElement* owner = m_frame->deprecatedLocalOwner();
  if (owner &&
      (!owner->layoutObject() || !owner->layoutObject()->visibleToHitTesting()))
    return NotScrollableNotVisible;

  // Cover #3 and #4.
  ScrollbarMode horizontalMode;
  ScrollbarMode verticalMode;
  calculateScrollbarModes(horizontalMode, verticalMode,
                          RulesFromWebContentOnly);
  if (horizontalMode == ScrollbarAlwaysOff &&
      verticalMode == ScrollbarAlwaysOff)
    return NotScrollableExplicitlyDisabled;

  return Scrollable;
}

void FrameView::updateParentScrollableAreaSet() {
  // That ensures that only inner frames are cached.
  FrameView* parentFrameView = this->parentFrameView();
  if (!parentFrameView)
    return;

  if (!isScrollable()) {
    parentFrameView->removeScrollableArea(this);
    return;
  }

  parentFrameView->addScrollableArea(this);
}

bool FrameView::shouldSuspendScrollAnimations() const {
  return !m_frame->document()->loadEventFinished();
}

void FrameView::scrollbarStyleChanged() {
  // FIXME: Why does this only apply to the main frame?
  if (!m_frame->isMainFrame())
    return;
  adjustScrollbarOpacity();
  contentsResized();
  updateScrollbars();
  positionScrollbarLayers();
}

void FrameView::notifyPageThatContentAreaWillPaint() const {
  Page* page = m_frame->page();
  if (!page)
    return;

  contentAreaWillPaint();

  if (!m_scrollableAreas)
    return;

  for (const auto& scrollableArea : *m_scrollableAreas) {
    if (!scrollableArea->scrollbarsCanBeActive())
      continue;

    scrollableArea->contentAreaWillPaint();
  }
}

bool FrameView::scrollAnimatorEnabled() const {
  return m_frame->settings() && m_frame->settings()->scrollAnimatorEnabled();
}

void FrameView::updateDocumentAnnotatedRegions() const {
  Document* document = m_frame->document();
  if (!document->hasAnnotatedRegions())
    return;
  Vector<AnnotatedRegionValue> newRegions;
  collectAnnotatedRegions(*(document->layoutBox()), newRegions);
  if (newRegions == document->annotatedRegions())
    return;
  document->setAnnotatedRegions(newRegions);
  if (Page* page = m_frame->page())
    page->chromeClient().annotatedRegionsChanged();
}

void FrameView::didAttachDocument() {
  FrameHost* frameHost = m_frame->host();
  DCHECK(frameHost);

  DCHECK(m_frame->document());

  if (m_frame->isMainFrame()) {
    ScrollableArea& visualViewport = frameHost->visualViewport();
    ScrollableArea* layoutViewport = layoutViewportScrollableArea();
    DCHECK(layoutViewport);

    RootFrameViewport* rootFrameViewport =
        RootFrameViewport::create(visualViewport, *layoutViewport);
    m_viewportScrollableArea = rootFrameViewport;

    frameHost->globalRootScrollerController().initializeViewportScrollCallback(
        *rootFrameViewport);
  }
}

void FrameView::updateScrollCorner() {
  RefPtr<ComputedStyle> cornerStyle;
  IntRect cornerRect = scrollCornerRect();
  Document* doc = m_frame->document();

  if (doc && !cornerRect.isEmpty()) {
    // Try the <body> element first as a scroll corner source.
    if (Element* body = doc->body()) {
      if (LayoutObject* layoutObject = body->layoutObject())
        cornerStyle = layoutObject->getUncachedPseudoStyle(
            PseudoStyleRequest(PseudoIdScrollbarCorner), layoutObject->style());
    }

    if (!cornerStyle) {
      // If the <body> didn't have a custom style, then the root element might.
      if (Element* docElement = doc->documentElement()) {
        if (LayoutObject* layoutObject = docElement->layoutObject())
          cornerStyle = layoutObject->getUncachedPseudoStyle(
              PseudoStyleRequest(PseudoIdScrollbarCorner),
              layoutObject->style());
      }
    }

    if (!cornerStyle) {
      // If we have an owning ipage/LocalFrame element, then it can set the
      // custom scrollbar also.
      LayoutPartItem layoutItem = m_frame->ownerLayoutItem();
      if (!layoutItem.isNull())
        cornerStyle = layoutItem.getUncachedPseudoStyle(
            PseudoStyleRequest(PseudoIdScrollbarCorner), layoutItem.style());
    }
  }

  if (cornerStyle) {
    if (!m_scrollCorner)
      m_scrollCorner = LayoutScrollbarPart::createAnonymous(doc, this);
    m_scrollCorner->setStyleWithWritingModeOfParent(cornerStyle.release());
    setScrollCornerNeedsPaintInvalidation();
  } else if (m_scrollCorner) {
    m_scrollCorner->destroy();
    m_scrollCorner = nullptr;
  }
}

Color FrameView::documentBackgroundColor() const {
  // The LayoutView's background color is set in
  // Document::inheritHtmlAndBodyElementStyles.  Blend this with the base
  // background color of the FrameView. This should match the color drawn by
  // ViewPainter::paintBoxDecorationBackground.
  Color result = baseBackgroundColor();
  LayoutItem documentLayoutObject = layoutViewItem();
  if (!documentLayoutObject.isNull())
    result = result.blend(
        documentLayoutObject.resolveColor(CSSPropertyBackgroundColor));
  return result;
}

FrameView* FrameView::parentFrameView() const {
  if (!parent())
    return nullptr;

  Frame* parentFrame = m_frame->tree().parent();
  if (parentFrame && parentFrame->isLocalFrame())
    return toLocalFrame(parentFrame)->view();

  return nullptr;
}

void FrameView::didChangeGlobalRootScroller() {
  if (!m_frame->settings() || !m_frame->settings()->viewportEnabled())
    return;

  // Avoid drawing two sets of scrollbars when visual viewport is enabled.
  bool hasHorizontalScrollbar = horizontalScrollbar();
  bool hasVerticalScrollbar = verticalScrollbar();
  bool shouldHaveHorizontalScrollbar = false;
  bool shouldHaveVerticalScrollbar = false;
  computeScrollbarExistence(shouldHaveHorizontalScrollbar,
                            shouldHaveVerticalScrollbar, contentsSize());
  m_scrollbarManager.setHasHorizontalScrollbar(shouldHaveHorizontalScrollbar);
  m_scrollbarManager.setHasVerticalScrollbar(shouldHaveVerticalScrollbar);

  if (hasHorizontalScrollbar != shouldHaveHorizontalScrollbar ||
      hasVerticalScrollbar != shouldHaveVerticalScrollbar)
    scrollbarExistenceDidChange();
}

void FrameView::updateWidgetGeometriesIfNeeded() {
  if (!m_needsUpdateWidgetGeometries)
    return;

  m_needsUpdateWidgetGeometries = false;

  updateWidgetGeometries();
}

void FrameView::updateAllLifecyclePhases() {
  frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(
      DocumentLifecycle::PaintClean);
}

// TODO(chrishtr): add a scrolling update lifecycle phase.
void FrameView::updateLifecycleToCompositingCleanPlusScrolling() {
  if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
    updateAllLifecyclePhasesExceptPaint();
  } else {
    frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(
        DocumentLifecycle::CompositingClean);
  }
}

void FrameView::updateAllLifecyclePhasesExceptPaint() {
  frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(
      DocumentLifecycle::PrePaintClean);
}

void FrameView::updateLifecycleToLayoutClean() {
  frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(
      DocumentLifecycle::LayoutClean);
}

void FrameView::scheduleVisualUpdateForPaintInvalidationIfNeeded() {
  LocalFrame* localFrameRoot = frame().localFrameRoot();
  if (localFrameRoot->view()->m_currentUpdateLifecyclePhasesTargetState <
          DocumentLifecycle::PaintInvalidationClean ||
      lifecycle().state() >= DocumentLifecycle::PrePaintClean) {
    // Schedule visual update to process the paint invalidation in the next
    // cycle.
    localFrameRoot->scheduleVisualUpdateUnlessThrottled();
  }
  // Otherwise the paint invalidation will be handled in paint invalidation
  // phase of this cycle.
}

void FrameView::notifyResizeObservers() {
  // Controller exists only if ResizeObserver was created.
  if (!frame().document()->resizeObserverController())
    return;

  ResizeObserverController& resizeController =
      m_frame->document()->ensureResizeObserverController();

  DCHECK(lifecycle().state() >= DocumentLifecycle::LayoutClean);

  size_t minDepth = 0;
  for (minDepth = resizeController.gatherObservations(0);
       minDepth != ResizeObserverController::kDepthBottom;
       minDepth = resizeController.gatherObservations(minDepth)) {
    resizeController.deliverObservations();
    frame().document()->updateStyleAndLayout();
  }

  if (resizeController.skippedObservations()) {
    resizeController.clearObservations();
    ErrorEvent* error = ErrorEvent::create(
        "ResizeObserver loop limit exceeded",
        SourceLocation::capture(m_frame->document()), nullptr);
    m_frame->document()->dispatchErrorEvent(error, NotSharableCrossOrigin);
    // Ensure notifications will get delivered in next cycle.
    if (FrameView* frameView = m_frame->view())
      frameView->scheduleAnimation();
  }

  DCHECK(!layoutView()->needsLayout());
}

// TODO(leviw): We don't assert lifecycle information from documents in child
// PluginViews.
void FrameView::updateLifecyclePhasesInternal(
    DocumentLifecycle::LifecycleState targetState) {
  if (m_currentUpdateLifecyclePhasesTargetState !=
      DocumentLifecycle::Uninitialized) {
    NOTREACHED() << "FrameView::updateLifecyclePhasesInternal() reentrance";
    return;
  }

  // This must be called from the root frame, since it recurses down, not up.
  // Otherwise the lifecycles of the frames might be out of sync.
  DCHECK(m_frame->isLocalRoot());

  // Only the following target states are supported.
  DCHECK(targetState == DocumentLifecycle::LayoutClean ||
         targetState == DocumentLifecycle::CompositingClean ||
         targetState == DocumentLifecycle::PrePaintClean ||
         targetState == DocumentLifecycle::PaintClean);

  if (!m_frame->document()->isActive())
    return;

  AutoReset<DocumentLifecycle::LifecycleState> targetStateScope(
      &m_currentUpdateLifecyclePhasesTargetState, targetState);

  if (shouldThrottleRendering()) {
    updateViewportIntersectionsForSubtree(
        std::min(targetState, DocumentLifecycle::CompositingClean));
    return;
  }

  updateStyleAndLayoutIfNeededRecursive();
  DCHECK(lifecycle().state() >= DocumentLifecycle::LayoutClean);

  if (targetState == DocumentLifecycle::LayoutClean) {
    updateViewportIntersectionsForSubtree(targetState);
    return;
  }

  forAllNonThrottledFrameViews([](FrameView& frameView) {
    frameView.performScrollAnchoringAdjustments();
  });

  if (targetState == DocumentLifecycle::PaintClean) {
    forAllNonThrottledFrameViews(
        [](FrameView& frameView) { frameView.notifyResizeObservers(); });
  }

  if (LayoutViewItem view = layoutViewItem()) {
    forAllNonThrottledFrameViews([](FrameView& frameView) {
      frameView.checkDoesNotNeedLayout();
      frameView.m_allowsLayoutInvalidationAfterLayoutClean = false;
    });

    {
      TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data",
                   InspectorUpdateLayerTreeEvent::data(m_frame.get()));

      if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
        view.compositor()->updateIfNeededRecursive();
      } else {
        DocumentAnimations::updateAnimations(layoutView()->document());

        forAllNonThrottledFrameViews([](FrameView& frameView) {
          frameView.layoutView()->layer()->updateDescendantDependentFlags();
          frameView.layoutView()->commitPendingSelection();
        });
      }

      scrollContentsIfNeededRecursive();
      DCHECK(RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() ||
             lifecycle().state() >= DocumentLifecycle::CompositingClean);

      m_frame->host()->globalRootScrollerController().didUpdateCompositing();

      if (targetState >= DocumentLifecycle::PrePaintClean) {
        if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled())
          invalidateTreeIfNeededRecursive();

        if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
          if (view.compositor()->inCompositingMode())
            scrollingCoordinator()->updateAfterCompositingChangeIfNeeded();
        }

        updateCompositedSelectionIfNeeded();
      }
    }

    if (targetState >= DocumentLifecycle::PrePaintClean) {
      updatePaintProperties();
    }

    if (targetState == DocumentLifecycle::PaintClean) {
      if (!m_frame->document()->printing())
        synchronizedPaint();

      if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
        pushPaintArtifactToCompositor();

      DCHECK(!view.hasPendingSelection());
      DCHECK((m_frame->document()->printing() &&
              lifecycle().state() == DocumentLifecycle::PrePaintClean) ||
             lifecycle().state() == DocumentLifecycle::PaintClean);
    }

    forAllNonThrottledFrameViews([](FrameView& frameView) {
      frameView.checkDoesNotNeedLayout();
      frameView.m_allowsLayoutInvalidationAfterLayoutClean = true;
    });
  }

  updateViewportIntersectionsForSubtree(targetState);
}

void FrameView::enqueueScrollAnchoringAdjustment(
    ScrollableArea* scrollableArea) {
  m_anchoringAdjustmentQueue.add(scrollableArea);
}

void FrameView::performScrollAnchoringAdjustments() {
  for (WeakMember<ScrollableArea>& scroller : m_anchoringAdjustmentQueue) {
    if (scroller) {
      DCHECK(scroller->scrollAnchor());
      scroller->scrollAnchor()->adjust();
    }
  }
  m_anchoringAdjustmentQueue.clear();
}

void FrameView::updatePaintProperties() {
  TRACE_EVENT0("blink", "FrameView::updatePaintProperties");

  if (!m_paintController)
    m_paintController = PaintController::create();

  forAllNonThrottledFrameViews([](FrameView& frameView) {
    frameView.lifecycle().advanceTo(DocumentLifecycle::InPrePaint);
  });

  if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled())
    PrePaintTreeWalk().walk(*this);

  forAllNonThrottledFrameViews([](FrameView& frameView) {
    frameView.lifecycle().advanceTo(DocumentLifecycle::PrePaintClean);
  });
}

void FrameView::synchronizedPaint() {
  TRACE_EVENT0("blink", "FrameView::synchronizedPaint");
  SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.Paint.UpdateTime");

  ASSERT(frame() == page()->mainFrame() ||
         (!frame().tree().parent()->isLocalFrame()));

  LayoutViewItem view = layoutViewItem();
  ASSERT(!view.isNull());
  forAllNonThrottledFrameViews([](FrameView& frameView) {
    frameView.lifecycle().advanceTo(DocumentLifecycle::InPaint);
  });

  if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
    if (layoutView()->layer()->needsRepaint()) {
      GraphicsContext graphicsContext(*m_paintController);
      paint(graphicsContext, CullRect(LayoutRect::infiniteIntRect()));
      m_paintController->commitNewDisplayItems(LayoutSize());
    }
  } else {
    // A null graphics layer can occur for painting of SVG images that are not
    // parented into the main frame tree, or when the FrameView is the main
    // frame view of a page overlay. The page overlay is in the layer tree of
    // the host page and will be painted during synchronized painting of the
    // host page.
    if (GraphicsLayer* rootGraphicsLayer =
            view.compositor()->rootGraphicsLayer()) {
      synchronizedPaintRecursively(rootGraphicsLayer);
    }

    // TODO(sataya.m):Main frame doesn't create RootFrameViewport in some
    // webkit_unit_tests (http://crbug.com/644788).
    if (m_viewportScrollableArea) {
      if (GraphicsLayer* layerForHorizontalScrollbar =
              m_viewportScrollableArea->layerForHorizontalScrollbar()) {
        synchronizedPaintRecursively(layerForHorizontalScrollbar);
      }
      if (GraphicsLayer* layerForVerticalScrollbar =
              m_viewportScrollableArea->layerForVerticalScrollbar()) {
        synchronizedPaintRecursively(layerForVerticalScrollbar);
      }
      if (GraphicsLayer* layerForScrollCorner =
              m_viewportScrollableArea->layerForScrollCorner()) {
        synchronizedPaintRecursively(layerForScrollCorner);
      }
    }
  }

  forAllNonThrottledFrameViews([](FrameView& frameView) {
    frameView.lifecycle().advanceTo(DocumentLifecycle::PaintClean);
    LayoutViewItem layoutViewItem = frameView.layoutViewItem();
    if (!layoutViewItem.isNull())
      layoutViewItem.layer()->clearNeedsRepaintRecursively();
  });
}

void FrameView::synchronizedPaintRecursively(GraphicsLayer* graphicsLayer) {
  if (graphicsLayer->drawsContent())
    graphicsLayer->paint(nullptr);

  if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
    if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
      synchronizedPaintRecursively(maskLayer);
    if (GraphicsLayer* contentsClippingMaskLayer =
            graphicsLayer->contentsClippingMaskLayer())
      synchronizedPaintRecursively(contentsClippingMaskLayer);
  }

  for (auto& child : graphicsLayer->children())
    synchronizedPaintRecursively(child);
}

void FrameView::pushPaintArtifactToCompositor() {
  TRACE_EVENT0("blink", "FrameView::pushPaintArtifactToCompositor");

  DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled());

  Page* page = frame().page();
  if (!page)
    return;

  if (!m_paintArtifactCompositor) {
    m_paintArtifactCompositor = PaintArtifactCompositor::create();
    page->chromeClient().attachRootLayer(
        m_paintArtifactCompositor->getWebLayer(), &frame());
  }

  SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.Compositing.UpdateTime");

  m_paintArtifactCompositor->update(
      m_paintController->paintArtifact(),
      m_paintController->paintChunksRasterInvalidationTrackingMap());
}

std::unique_ptr<JSONObject> FrameView::compositedLayersAsJSON(
    LayerTreeFlags flags) {
  return frame()
      .localFrameRoot()
      ->view()
      ->m_paintArtifactCompositor->layersAsJSON(flags);
}

void FrameView::updateStyleAndLayoutIfNeededRecursive() {
  SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.StyleAndLayout.UpdateTime");
  updateStyleAndLayoutIfNeededRecursiveInternal();
}

void FrameView::updateStyleAndLayoutIfNeededRecursiveInternal() {
  if (shouldThrottleRendering() || !m_frame->document()->isActive())
    return;

  ScopedFrameBlamer frameBlamer(m_frame);
  TRACE_EVENT0("blink", "FrameView::updateStyleAndLayoutIfNeededRecursive");

  // We have to crawl our entire subtree looking for any FrameViews that need
  // layout and make sure they are up to date.
  // Mac actually tests for intersection with the dirty region and tries not to
  // update layout for frames that are outside the dirty region.  Not only does
  // this seem pointless (since those frames will have set a zero timer to
  // layout anyway), but it is also incorrect, since if two frames overlap, the
  // first could be excluded from the dirty region but then become included
  // later by the second frame adding rects to the dirty region when it lays
  // out.

  m_frame->document()->updateStyleAndLayoutTree();

  CHECK(!shouldThrottleRendering());
  CHECK(m_frame->document()->isActive());
  CHECK(!m_nestedLayoutCount);

  if (needsLayout())
    layout();

  checkDoesNotNeedLayout();

  // WebView plugins need to update regardless of whether the
  // LayoutEmbeddedObject that owns them needed layout.
  // TODO(leviw): This currently runs the entire lifecycle on plugin WebViews.
  // We should have a way to only run these other Documents to the same
  // lifecycle stage as this frame.
  const ChildrenWidgetSet* viewChildren = children();
  for (const Member<Widget>& child : *viewChildren) {
    if ((*child).isPluginContainer())
      toPluginView(child.get())->updateAllLifecyclePhases();
  }
  checkDoesNotNeedLayout();

  // FIXME: Calling layout() shouldn't trigger script execution or have any
  // observable effects on the frame tree but we're not quite there yet.
  HeapVector<Member<FrameView>> frameViews;
  for (Frame* child = m_frame->tree().firstChild(); child;
       child = child->tree().nextSibling()) {
    if (!child->isLocalFrame())
      continue;
    if (FrameView* view = toLocalFrame(child)->view())
      frameViews.append(view);
  }

  for (const auto& frameView : frameViews)
    frameView->updateStyleAndLayoutIfNeededRecursiveInternal();

  // These asserts ensure that parent frames are clean, when child frames
  // finished updating layout and style.
  checkDoesNotNeedLayout();
#if DCHECK_IS_ON()
  m_frame->document()->layoutView()->assertLaidOut();
#endif

  updateWidgetGeometriesIfNeeded();

  if (lifecycle().state() < DocumentLifecycle::LayoutClean)
    lifecycle().advanceTo(DocumentLifecycle::LayoutClean);

  // Ensure that we become visually non-empty eventually.
  // TODO(esprehn): This should check isRenderingReady() instead.
  if (frame().document()->hasFinishedParsing() &&
      frame().loader().stateMachine()->committedFirstRealDocumentLoad())
    m_isVisuallyNonEmpty = true;
}

void FrameView::invalidateTreeIfNeededRecursive() {
  SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.PaintInvalidation.UpdateTime");
  invalidateTreeIfNeededRecursiveInternal();
}

void FrameView::invalidateTreeIfNeededRecursiveInternal() {
  DCHECK(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled());
  CHECK(layoutView());

  // We need to stop recursing here since a child frame view might not be
  // throttled even though we are (e.g., it didn't compute its visibility yet).
  if (shouldThrottleRendering())
    return;
  TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root",
               layoutView()->debugName().ascii());

  Vector<const LayoutObject*> pendingDelayedPaintInvalidations;
  PaintInvalidationState rootPaintInvalidationState(
      *layoutView(), pendingDelayedPaintInvalidations);

  if (lifecycle().state() < DocumentLifecycle::PaintInvalidationClean)
    invalidateTreeIfNeeded(rootPaintInvalidationState);

  // Some frames may be not reached during the above invalidateTreeIfNeeded
  // because
  // - the frame is a detached frame; or
  // - it didn't need paint invalidation.
  // We need to call invalidateTreeIfNeededRecursive() for such frames to finish
  // required paint invalidation and advance their life cycle state.
  for (Frame* child = m_frame->tree().firstChild(); child;
       child = child->tree().nextSibling()) {
    if (child->isLocalFrame()) {
      FrameView& childFrameView = *toLocalFrame(child)->view();
      // The children frames can be in any state, including stopping.
      // Thus we have to check that it makes sense to do paint
      // invalidation onto them here.
      if (!childFrameView.layoutView())
        continue;
      childFrameView.invalidateTreeIfNeededRecursiveInternal();
    }
  }

  // Process objects needing paint invalidation on the next frame. See the
  // definition of PaintInvalidationDelayedFull for more details.
  for (auto& target : pendingDelayedPaintInvalidations)
    target->getMutableForPainting().setShouldDoFullPaintInvalidation(
        PaintInvalidationDelayedFull);
}

void FrameView::enableAutoSizeMode(const IntSize& minSize,
                                   const IntSize& maxSize) {
  if (!m_autoSizeInfo)
    m_autoSizeInfo = FrameViewAutoSizeInfo::create(this);

  m_autoSizeInfo->configureAutoSizeMode(minSize, maxSize);
  setLayoutSizeFixedToFrameSize(true);
  setNeedsLayout();
  scheduleRelayout();
}

void FrameView::disableAutoSizeMode() {
  if (!m_autoSizeInfo)
    return;

  setLayoutSizeFixedToFrameSize(false);
  setNeedsLayout();
  scheduleRelayout();

  // Since autosize mode forces the scrollbar mode, change them to being auto.
  setVerticalScrollbarLock(false);
  setHorizontalScrollbarLock(false);
  setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
  m_autoSizeInfo.clear();
}

void FrameView::forceLayoutForPagination(const FloatSize& pageSize,
                                         const FloatSize& originalPageSize,
                                         float maximumShrinkFactor) {
  // Dumping externalRepresentation(m_frame->layoutObject()).ascii() is a good
  // trick to see the state of things before and after the layout
  if (LayoutView* layoutView = this->layoutView()) {
    float pageLogicalWidth = layoutView->style()->isHorizontalWritingMode()
                                 ? pageSize.width()
                                 : pageSize.height();
    float pageLogicalHeight = layoutView->style()->isHorizontalWritingMode()
                                  ? pageSize.height()
                                  : pageSize.width();

    LayoutUnit flooredPageLogicalWidth =
        static_cast<LayoutUnit>(pageLogicalWidth);
    LayoutUnit flooredPageLogicalHeight =
        static_cast<LayoutUnit>(pageLogicalHeight);
    layoutView->setLogicalWidth(flooredPageLogicalWidth);
    layoutView->setPageLogicalHeight(flooredPageLogicalHeight);
    layoutView->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
        LayoutInvalidationReason::PrintingChanged);
    layout();

    // If we don't fit in the given page width, we'll lay out again. If we don't
    // fit in the page width when shrunk, we will lay out at maximum shrink and
    // clip extra content.
    // FIXME: We are assuming a shrink-to-fit printing implementation.  A
    // cropping implementation should not do this!
    bool horizontalWritingMode = layoutView->style()->isHorizontalWritingMode();
    const LayoutRect& documentRect = LayoutRect(layoutView->documentRect());
    LayoutUnit docLogicalWidth =
        horizontalWritingMode ? documentRect.width() : documentRect.height();
    if (docLogicalWidth > pageLogicalWidth) {
      FloatSize expectedPageSize(
          std::min<float>(documentRect.width().toFloat(),
                          pageSize.width() * maximumShrinkFactor),
          std::min<float>(documentRect.height().toFloat(),
                          pageSize.height() * maximumShrinkFactor));
      FloatSize maxPageSize = m_frame->resizePageRectsKeepingRatio(
          FloatSize(originalPageSize.width(), originalPageSize.height()),
          expectedPageSize);
      pageLogicalWidth =
          horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
      pageLogicalHeight =
          horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();

      flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
      flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
      layoutView->setLogicalWidth(flooredPageLogicalWidth);
      layoutView->setPageLogicalHeight(flooredPageLogicalHeight);
      layoutView->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
          LayoutInvalidationReason::PrintingChanged);
      layout();

      const LayoutRect& updatedDocumentRect =
          LayoutRect(layoutView->documentRect());
      LayoutUnit docLogicalHeight = horizontalWritingMode
                                        ? updatedDocumentRect.height()
                                        : updatedDocumentRect.width();
      LayoutUnit docLogicalTop = horizontalWritingMode
                                     ? updatedDocumentRect.y()
                                     : updatedDocumentRect.x();
      LayoutUnit docLogicalRight = horizontalWritingMode
                                       ? updatedDocumentRect.maxX()
                                       : updatedDocumentRect.maxY();
      LayoutUnit clippedLogicalLeft;
      if (!layoutView->style()->isLeftToRightDirection())
        clippedLogicalLeft = LayoutUnit(docLogicalRight - pageLogicalWidth);
      LayoutRect overflow(clippedLogicalLeft, docLogicalTop,
                          LayoutUnit(pageLogicalWidth), docLogicalHeight);

      if (!horizontalWritingMode)
        overflow = overflow.transposedRect();
      layoutView->clearLayoutOverflow();
      layoutView->addLayoutOverflow(
          overflow);  // This is how we clip in case we overflow again.
    }
  }

  adjustViewSizeAndLayout();
}

IntRect FrameView::convertFromLayoutItem(
    const LayoutItem& layoutItem,
    const IntRect& layoutObjectRect) const {
  // Convert from page ("absolute") to FrameView coordinates.
  LayoutRect rect = enclosingLayoutRect(
      layoutItem.localToAbsoluteQuad(FloatRect(layoutObjectRect))
          .boundingBox());
  rect.move(LayoutSize(-getScrollOffset()));
  return pixelSnappedIntRect(rect);
}

IntRect FrameView::convertToLayoutItem(const LayoutItem& layoutItem,
                                       const IntRect& frameRect) const {
  IntRect rectInContent = frameToContents(frameRect);

  // Convert from FrameView coords into page ("absolute") coordinates.
  rectInContent.move(scrollOffsetInt());

  // FIXME: we don't have a way to map an absolute rect down to a local quad, so
  // just move the rect for now.
  rectInContent.setLocation(roundedIntPoint(
      layoutItem.absoluteToLocal(rectInContent.location(), UseTransforms)));
  return rectInContent;
}

IntPoint FrameView::convertFromLayoutItem(
    const LayoutItem& layoutItem,
    const IntPoint& layoutObjectPoint) const {
  IntPoint point = roundedIntPoint(
      layoutItem.localToAbsolute(layoutObjectPoint, UseTransforms));

  // Convert from page ("absolute") to FrameView coordinates.
  point.move(-scrollOffsetInt());
  return point;
}

IntPoint FrameView::convertToLayoutItem(const LayoutItem& layoutItem,
                                        const IntPoint& framePoint) const {
  IntPoint point = framePoint;

  // Convert from FrameView coords into page ("absolute") coordinates.
  point += IntSize(scrollX(), scrollY());

  return roundedIntPoint(layoutItem.absoluteToLocal(point, UseTransforms));
}

IntRect FrameView::convertToContainingWidget(const IntRect& localRect) const {
  if (const FrameView* parentView = toFrameView(parent())) {
    // Get our layoutObject in the parent view
    LayoutPartItem layoutItem = m_frame->ownerLayoutItem();
    if (layoutItem.isNull())
      return localRect;

    IntRect rect(localRect);
    // Add borders and padding??
    rect.move((layoutItem.borderLeft() + layoutItem.paddingLeft()).toInt(),
              (layoutItem.borderTop() + layoutItem.paddingTop()).toInt());
    return parentView->convertFromLayoutItem(layoutItem, rect);
  }

  return localRect;
}

IntRect FrameView::convertFromContainingWidget(
    const IntRect& parentRect) const {
  if (const FrameView* parentView = toFrameView(parent())) {
    // Get our layoutObject in the parent view
    LayoutPartItem layoutItem = m_frame->ownerLayoutItem();
    if (layoutItem.isNull())
      return parentRect;

    IntRect rect = parentView->convertToLayoutItem(layoutItem, parentRect);
    // Subtract borders and padding
    rect.move((-layoutItem.borderLeft() - layoutItem.paddingLeft()).toInt(),
              (-layoutItem.borderTop() - layoutItem.paddingTop().toInt()));
    return rect;
  }

  return parentRect;
}

IntPoint FrameView::convertToContainingWidget(
    const IntPoint& localPoint) const {
  if (const FrameView* parentView = toFrameView(parent())) {
    // Get our layoutObject in the parent view
    LayoutPartItem layoutItem = m_frame->ownerLayoutItem();
    if (layoutItem.isNull())
      return localPoint;

    IntPoint point(localPoint);

    // Add borders and padding
    point.move((layoutItem.borderLeft() + layoutItem.paddingLeft()).toInt(),
               (layoutItem.borderTop() + layoutItem.paddingTop()).toInt());
    return parentView->convertFromLayoutItem(layoutItem, point);
  }

  return localPoint;
}

IntPoint FrameView::convertFromContainingWidget(
    const IntPoint& parentPoint) const {
  if (const FrameView* parentView = toFrameView(parent())) {
    // Get our layoutObject in the parent view
    LayoutPartItem layoutItem = m_frame->ownerLayoutItem();
    if (layoutItem.isNull())
      return parentPoint;

    IntPoint point = parentView->convertToLayoutItem(layoutItem, parentPoint);
    // Subtract borders and padding
    point.move((-layoutItem.borderLeft() - layoutItem.paddingLeft()).toInt(),
               (-layoutItem.borderTop() - layoutItem.paddingTop()).toInt());
    return point;
  }

  return parentPoint;
}

void FrameView::setInitialTracksPaintInvalidationsForTesting(
    bool trackPaintInvalidations) {
  s_initialTrackAllPaintInvalidations = trackPaintInvalidations;
}

void FrameView::setTracksPaintInvalidations(bool trackPaintInvalidations) {
  if (trackPaintInvalidations == isTrackingPaintInvalidations())
    return;

  for (Frame* frame = m_frame->tree().top(); frame;
       frame = frame->tree().traverseNext()) {
    if (!frame->isLocalFrame())
      continue;
    if (LayoutViewItem layoutView = toLocalFrame(frame)->contentLayoutItem()) {
      layoutView.frameView()->m_trackedObjectPaintInvalidations =
          WTF::wrapUnique(trackPaintInvalidations
                              ? new Vector<ObjectPaintInvalidation>
                              : nullptr);
      if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
        m_paintController->setTracksRasterInvalidations(
            trackPaintInvalidations);
        m_paintArtifactCompositor->setTracksRasterInvalidations(
            trackPaintInvalidations);
      } else {
        layoutView.compositor()->setTracksRasterInvalidations(
            trackPaintInvalidations);
      }
    }
  }

  TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"),
                       "FrameView::setTracksPaintInvalidations",
                       TRACE_EVENT_SCOPE_GLOBAL, "enabled",
                       trackPaintInvalidations);
}

void FrameView::trackObjectPaintInvalidation(const DisplayItemClient& client,
                                             PaintInvalidationReason reason) {
  if (!m_trackedObjectPaintInvalidations)
    return;

  ObjectPaintInvalidation invalidation = {client.debugName(), reason};
  m_trackedObjectPaintInvalidations->append(invalidation);
}

std::unique_ptr<JSONArray> FrameView::trackedObjectPaintInvalidationsAsJSON()
    const {
  if (!m_trackedObjectPaintInvalidations)
    return nullptr;

  std::unique_ptr<JSONArray> result = JSONArray::create();
  for (Frame* frame = m_frame->tree().top(); frame;
       frame = frame->tree().traverseNext()) {
    if (!frame->isLocalFrame())
      continue;
    if (LayoutViewItem layoutView = toLocalFrame(frame)->contentLayoutItem()) {
      if (!layoutView.frameView()->m_trackedObjectPaintInvalidations)
        continue;
      for (const auto& item :
           *layoutView.frameView()->m_trackedObjectPaintInvalidations) {
        std::unique_ptr<JSONObject> itemJSON = JSONObject::create();
        itemJSON->setString("object", item.name);
        itemJSON->setString("reason",
                            paintInvalidationReasonToString(item.reason));
        result->pushObject(std::move(itemJSON));
      }
    }
  }
  return result;
}

void FrameView::addResizerArea(LayoutBox& resizerBox) {
  if (!m_resizerAreas)
    m_resizerAreas = WTF::wrapUnique(new ResizerAreaSet);
  m_resizerAreas->add(&resizerBox);
}

void FrameView::removeResizerArea(LayoutBox& resizerBox) {
  if (!m_resizerAreas)
    return;

  ResizerAreaSet::iterator it = m_resizerAreas->find(&resizerBox);
  if (it != m_resizerAreas->end())
    m_resizerAreas->remove(it);
}

void FrameView::addScrollableArea(ScrollableArea* scrollableArea) {
  ASSERT(scrollableArea);
  if (!m_scrollableAreas)
    m_scrollableAreas = new ScrollableAreaSet;
  m_scrollableAreas->add(scrollableArea);

  if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    scrollingCoordinator->scrollableAreasDidChange();
}

void FrameView::removeScrollableArea(ScrollableArea* scrollableArea) {
  if (!m_scrollableAreas)
    return;
  m_scrollableAreas->remove(scrollableArea);

  if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
    scrollingCoordinator->scrollableAreasDidChange();
}

void FrameView::addAnimatingScrollableArea(ScrollableArea* scrollableArea) {
  ASSERT(scrollableArea);
  if (!m_animatingScrollableAreas)
    m_animatingScrollableAreas = new ScrollableAreaSet;
  m_animatingScrollableAreas->add(scrollableArea);
}

void FrameView::removeAnimatingScrollableArea(ScrollableArea* scrollableArea) {
  if (!m_animatingScrollableAreas)
    return;
  m_animatingScrollableAreas->remove(scrollableArea);
}

void FrameView::setParent(Widget* parentView) {
  if (parentView == parent())
    return;

  Widget::setParent(parentView);

  updateParentScrollableAreaSet();
  setNeedsUpdateViewportIntersection();
  setupRenderThrottling();

  if (parentFrameView())
    m_subtreeThrottled = parentFrameView()->canThrottleRendering();
}

void FrameView::removeChild(Widget* child) {
  ASSERT(child->parent() == this);

  if (child->isFrameView())
    removeScrollableArea(toFrameView(child));

  child->setParent(0);
  m_children.remove(child);
}

bool FrameView::visualViewportSuppliesScrollbars() {
  // On desktop, we always use the layout viewport's scrollbars.
  if (!m_frame->settings() || !m_frame->settings()->viewportEnabled() ||
      !m_frame->document() || !m_frame->host())
    return false;

  const TopDocumentRootScrollerController& controller =
      m_frame->host()->globalRootScrollerController();

  if (!layoutViewportScrollableArea())
    return false;

  return RootScrollerUtil::scrollableAreaForRootScroller(
             controller.globalRootScroller()) == layoutViewportScrollableArea();
}

AXObjectCache* FrameView::axObjectCache() const {
  if (frame().document())
    return frame().document()->existingAXObjectCache();
  return nullptr;
}

void FrameView::setCursor(const Cursor& cursor) {
  Page* page = frame().page();
  if (!page || !page->settings().deviceSupportsMouse())
    return;
  page->chromeClient().setCursor(cursor, m_frame);
}

void FrameView::frameRectsChanged() {
  TRACE_EVENT0("blink", "FrameView::frameRectsChanged");
  if (layoutSizeFixedToFrameSize())
    setLayoutSizeInternal(frameRect().size());

  setNeedsUpdateViewportIntersection();
  if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) {
    // The overflow clip property depends on the frame rect.
    setNeedsPaintPropertyUpdate();
  }

  for (const auto& child : m_children)
    child->frameRectsChanged();
}

void FrameView::setLayoutSizeInternal(const IntSize& size) {
  if (m_layoutSize == size)
    return;

  m_layoutSize = size;
  contentsResized();
}

void FrameView::didAddScrollbar(Scrollbar& scrollbar,
                                ScrollbarOrientation orientation) {
  ScrollableArea::didAddScrollbar(scrollbar, orientation);
}

void FrameView::setBrowserControlsViewportAdjustment(float adjustment) {
  m_browserControlsViewportAdjustment = adjustment;
}

PaintLayer* FrameView::layer() const {
  LayoutViewItem layoutView = layoutViewItem();
  if (layoutView.isNull() || !layoutView.compositor())
    return nullptr;

  return layoutView.compositor()->rootLayer();
}

IntSize FrameView::maximumScrollOffsetInt() const {
  // Make the same calculation as in CC's LayerImpl::MaxScrollOffset()
  // FIXME: We probably shouldn't be storing the bounds in a float.
  // crbug.com/422331.
  IntSize visibleSize =
      visibleContentSize(ExcludeScrollbars) + browserControlsSize();
  IntSize contentBounds = contentsSize();
  IntSize maximumOffset =
      toIntSize(-scrollOrigin() + (contentBounds - visibleSize));
  return maximumOffset.expandedTo(minimumScrollOffsetInt());
}

void FrameView::addChild(Widget* child) {
  ASSERT(child != this && !child->parent());
  child->setParent(this);
  m_children.add(child);
}

void FrameView::setScrollbarModes(ScrollbarMode horizontalMode,
                                  ScrollbarMode verticalMode,
                                  bool horizontalLock,
                                  bool verticalLock) {
  bool needsUpdate = false;

  // If the page's overflow setting has disabled scrolling, do not allow
  // anything to override that setting, http://crbug.com/426447
  LayoutObject* viewport = viewportLayoutObject();
  if (viewport && !shouldIgnoreOverflowHidden()) {
    if (viewport->style()->overflowX() == OverflowHidden)
      horizontalMode = ScrollbarAlwaysOff;
    if (viewport->style()->overflowY() == OverflowHidden)
      verticalMode = ScrollbarAlwaysOff;
  }

  if (horizontalMode != horizontalScrollbarMode() &&
      !m_horizontalScrollbarLock) {
    m_horizontalScrollbarMode = horizontalMode;
    needsUpdate = true;
  }

  if (verticalMode != verticalScrollbarMode() && !m_verticalScrollbarLock) {
    m_verticalScrollbarMode = verticalMode;
    needsUpdate = true;
  }

  if (horizontalLock)
    setHorizontalScrollbarLock();

  if (verticalLock)
    setVerticalScrollbarLock();

  if (!needsUpdate)
    return;

  updateScrollbars();

  if (!layerForScrolling())
    return;
  WebLayer* layer = layerForScrolling()->platformLayer();
  if (!layer)
    return;
  layer->setUserScrollable(userInputScrollable(HorizontalScrollbar),
                           userInputScrollable(VerticalScrollbar));
}

IntSize FrameView::visibleContentSize(
    IncludeScrollbarsInRect scrollbarInclusion) const {
  return scrollbarInclusion == ExcludeScrollbars
             ? excludeScrollbars(frameRect().size())
             : frameRect().size();
}

IntRect FrameView::visibleContentRect(
    IncludeScrollbarsInRect scrollbarInclusion) const {
  return IntRect(IntPoint(flooredIntSize(m_scrollOffset)),
                 visibleContentSize(scrollbarInclusion));
}

IntSize FrameView::contentsSize() const {
  return m_contentsSize;
}

void FrameView::clipPaintRect(FloatRect* paintRect) const {
  // Paint the whole rect if "mainFrameClipsContent" is false, meaning that
  // WebPreferences::record_whole_document is true.
  if (!m_frame->settings()->mainFrameClipsContent())
    return;

  paintRect->intersect(
      page()->chromeClient().visibleContentRectForPainting().value_or(
          visibleContentRect()));
}

IntSize FrameView::minimumScrollOffsetInt() const {
  return IntSize(-scrollOrigin().x(), -scrollOrigin().y());
}

void FrameView::adjustScrollbarOpacity() {
  if (horizontalScrollbar() && layerForHorizontalScrollbar()) {
    bool isOpaqueScrollbar = !horizontalScrollbar()->isOverlayScrollbar();
    layerForHorizontalScrollbar()->setContentsOpaque(isOpaqueScrollbar);
  }
  if (verticalScrollbar() && layerForVerticalScrollbar()) {
    bool isOpaqueScrollbar = !verticalScrollbar()->isOverlayScrollbar();
    layerForVerticalScrollbar()->setContentsOpaque(isOpaqueScrollbar);
  }
}

int FrameView::scrollSize(ScrollbarOrientation orientation) const {
  Scrollbar* scrollbar =
      ((orientation == HorizontalScrollbar) ? horizontalScrollbar()
                                            : verticalScrollbar());

  // If no scrollbars are present, the content may still be scrollable.
  if (!scrollbar) {
    IntSize scrollSize = m_contentsSize - visibleContentRect().size();
    scrollSize.clampNegativeToZero();
    return orientation == HorizontalScrollbar ? scrollSize.width()
                                              : scrollSize.height();
  }

  return scrollbar->totalSize() - scrollbar->visibleSize();
}

void FrameView::updateScrollOffset(const ScrollOffset& offset,
                                   ScrollType scrollType) {
  ScrollOffset scrollDelta = offset - m_scrollOffset;
  if (scrollDelta.isZero())
    return;

  showOverlayScrollbars();

  if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
    // Don't scroll the FrameView!
    ASSERT_NOT_REACHED();
  }

  m_scrollOffset = offset;

  if (!scrollbarsSuppressed())
    m_pendingScrollDelta += scrollDelta;

  if (scrollTypeClearsFragmentAnchor(scrollType))
    clearFragmentAnchor();
  updateLayersAndCompositingAfterScrollIfNeeded(scrollDelta);

  Document* document = m_frame->document();
  document->enqueueScrollEventForNode(document);

  m_frame->eventHandler().dispatchFakeMouseMoveEventSoon();
  Page* page = frame().page();
  if (page)
    page->chromeClient().clearToolTip(*m_frame);

  LayoutViewItem layoutViewItem = document->layoutViewItem();
  if (!layoutViewItem.isNull()) {
    if (layoutViewItem.usesCompositing())
      layoutViewItem.compositor()->frameViewDidScroll();
    layoutViewItem.clearHitTestCache();
  }

  m_didScrollTimer.startOneShot(resourcePriorityUpdateDelayAfterScroll,
                                BLINK_FROM_HERE);

  if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
    cache->handleScrollPositionChanged(this);

  frame().loader().saveScrollState();
  didChangeScrollOffset();

  if (scrollType == CompositorScroll && m_frame->isMainFrame()) {
    if (DocumentLoader* documentLoader = m_frame->loader().documentLoader())
      documentLoader->initialScrollState().wasScrolledByUser = true;
  }

  if (scrollType != AnchoringScroll && scrollType != ClampingScroll)
    clearScrollAnchor();
}

void FrameView::didChangeScrollOffset() {
  frame().loader().client()->didChangeScrollOffset();
  if (frame().isMainFrame())
    frame().host()->chromeClient().mainFrameScrollOffsetChanged();
}

void FrameView::clearScrollAnchor() {
  if (!RuntimeEnabledFeatures::scrollAnchoringEnabled())
    return;
  m_scrollAnchor.clear();
}

bool FrameView::hasOverlayScrollbars() const {
  return (horizontalScrollbar() &&
          horizontalScrollbar()->isOverlayScrollbar()) ||
         (verticalScrollbar() && verticalScrollbar()->isOverlayScrollbar());
}

void FrameView::computeScrollbarExistence(
    bool& newHasHorizontalScrollbar,
    bool& newHasVerticalScrollbar,
    const IntSize& docSize,
    ComputeScrollbarExistenceOption option) {
  if ((m_frame->settings() && m_frame->settings()->hideScrollbars()) ||
      visualViewportSuppliesScrollbars()) {
    newHasHorizontalScrollbar = false;
    newHasVerticalScrollbar = false;
    return;
  }

  bool hasHorizontalScrollbar = horizontalScrollbar();
  bool hasVerticalScrollbar = verticalScrollbar();

  newHasHorizontalScrollbar = hasHorizontalScrollbar;
  newHasVerticalScrollbar = hasVerticalScrollbar;

  if (RuntimeEnabledFeatures::rootLayerScrollingEnabled())
    return;

  ScrollbarMode hScroll = m_horizontalScrollbarMode;
  ScrollbarMode vScroll = m_verticalScrollbarMode;

  if (hScroll != ScrollbarAuto)
    newHasHorizontalScrollbar = (hScroll == ScrollbarAlwaysOn);
  if (vScroll != ScrollbarAuto)
    newHasVerticalScrollbar = (vScroll == ScrollbarAlwaysOn);

  if (m_scrollbarsSuppressed ||
      (hScroll != ScrollbarAuto && vScroll != ScrollbarAuto))
    return;

  if (hScroll == ScrollbarAuto)
    newHasHorizontalScrollbar = docSize.width() > visibleWidth();
  if (vScroll == ScrollbarAuto)
    newHasVerticalScrollbar = docSize.height() > visibleHeight();

  if (hasOverlayScrollbars())
    return;

  IntSize fullVisibleSize = visibleContentRect(IncludeScrollbars).size();

  bool attemptToRemoveScrollbars =
      (option == FirstPass && docSize.width() <= fullVisibleSize.width() &&
       docSize.height() <= fullVisibleSize.height());
  if (attemptToRemoveScrollbars) {
    if (hScroll == ScrollbarAuto)
      newHasHorizontalScrollbar = false;
    if (vScroll == ScrollbarAuto)
      newHasVerticalScrollbar = false;
  }
}

void FrameView::updateScrollbarEnabledState() {
  bool forceDisabled =
      ScrollbarTheme::theme().shouldDisableInvisibleScrollbars() &&
      scrollbarsHidden();

  if (horizontalScrollbar()) {
    horizontalScrollbar()->setEnabled(contentsWidth() > visibleWidth() &&
                                      !forceDisabled);
  }
  if (verticalScrollbar()) {
    verticalScrollbar()->setEnabled(contentsHeight() > visibleHeight() &&
                                    !forceDisabled);
  }
}

void FrameView::updateScrollbarGeometry() {
  updateScrollbarEnabledState();
  if (horizontalScrollbar()) {
    int thickness = horizontalScrollbar()->scrollbarThickness();
    IntRect oldRect(horizontalScrollbar()->frameRect());
    IntRect hBarRect(
        (shouldPlaceVerticalScrollbarOnLeft() && verticalScrollbar())
            ? verticalScrollbar()->width()
            : 0,
        height() - thickness,
        width() - (verticalScrollbar() ? verticalScrollbar()->width() : 0),
        thickness);
    horizontalScrollbar()->setFrameRect(hBarRect);
    if (oldRect != horizontalScrollbar()->frameRect())
      setScrollbarNeedsPaintInvalidation(HorizontalScrollbar);

    horizontalScrollbar()->setProportion(visibleWidth(), contentsWidth());
    horizontalScrollbar()->offsetDidChange();
  }

  if (verticalScrollbar()) {
    int thickness = verticalScrollbar()->scrollbarThickness();
    IntRect oldRect(verticalScrollbar()->frameRect());
    IntRect vBarRect(
        shouldPlaceVerticalScrollbarOnLeft() ? 0 : (width() - thickness), 0,
        thickness,
        height() -
            (horizontalScrollbar() ? horizontalScrollbar()->height() : 0));
    verticalScrollbar()->setFrameRect(vBarRect);
    if (oldRect != verticalScrollbar()->frameRect())
      setScrollbarNeedsPaintInvalidation(VerticalScrollbar);

    verticalScrollbar()->setProportion(visibleHeight(), contentsHeight());
    verticalScrollbar()->offsetDidChange();
  }
}

bool FrameView::adjustScrollbarExistence(
    ComputeScrollbarExistenceOption option) {
  ASSERT(m_inUpdateScrollbars);

  // If we came in here with the view already needing a layout, then go ahead
  // and do that first.  (This will be the common case, e.g., when the page
  // changes due to window resizing for example).  This layout will not re-enter
  // updateScrollbars and does not count towards our max layout pass total.
  if (!m_scrollbarsSuppressed)
    scrollbarExistenceDidChange();

  bool hasHorizontalScrollbar = horizontalScrollbar();
  bool hasVerticalScrollbar = verticalScrollbar();

  bool newHasHorizontalScrollbar = false;
  bool newHasVerticalScrollbar = false;
  computeScrollbarExistence(newHasHorizontalScrollbar, newHasVerticalScrollbar,
                            contentsSize(), option);

  bool scrollbarExistenceChanged =
      hasHorizontalScrollbar != newHasHorizontalScrollbar ||
      hasVerticalScrollbar != newHasVerticalScrollbar;
  if (!scrollbarExistenceChanged)
    return false;

  m_scrollbarManager.setHasHorizontalScrollbar(newHasHorizontalScrollbar);
  m_scrollbarManager.setHasVerticalScrollbar(newHasVerticalScrollbar);

  if (m_scrollbarsSuppressed)
    return true;

  if (!hasOverlayScrollbars())
    contentsResized();
  scrollbarExistenceDidChange();
  return true;
}

bool FrameView::needsScrollbarReconstruction() const {
  Element* customScrollbarElement = nullptr;
  LocalFrame* customScrollbarFrame = nullptr;
  bool shouldUseCustom =
      shouldUseCustomScrollbars(customScrollbarElement, customScrollbarFrame);

  bool hasAnyScrollbar = horizontalScrollbar() || verticalScrollbar();
  bool hasCustom =
      (horizontalScrollbar() && horizontalScrollbar()->isCustomScrollbar()) ||
      (verticalScrollbar() && verticalScrollbar()->isCustomScrollbar());

  return hasAnyScrollbar && (shouldUseCustom != hasCustom);
}

bool FrameView::shouldIgnoreOverflowHidden() const {
  return m_frame->settings()->ignoreMainFrameOverflowHiddenQuirk() &&
         m_frame->isMainFrame();
}

void FrameView::updateScrollbarsIfNeeded() {
  if (m_needsScrollbarsUpdate || needsScrollbarReconstruction() ||
      scrollOriginChanged())
    updateScrollbars();
}

void FrameView::updateScrollbars() {
  m_needsScrollbarsUpdate = false;

  if (RuntimeEnabledFeatures::rootLayerScrollingEnabled())
    return;

  // Avoid drawing two sets of scrollbars when visual viewport is enabled.
  if (visualViewportSuppliesScrollbars()) {
    m_scrollbarManager.setHasHorizontalScrollbar(false);
    m_scrollbarManager.setHasVerticalScrollbar(false);
    adjustScrollOffsetFromUpdateScrollbars();
    return;
  }

  if (m_inUpdateScrollbars)
    return;
  InUpdateScrollbarsScope inUpdateScrollbarsScope(this);

  bool scrollbarExistenceChanged = false;

  if (needsScrollbarReconstruction()) {
    m_scrollbarManager.setHasHorizontalScrollbar(false);
    m_scrollbarManager.setHasVerticalScrollbar(false);
    scrollbarExistenceChanged = true;
  }

  int maxUpdateScrollbarsPass =
      hasOverlayScrollbars() || m_scrollbarsSuppressed ? 1 : 3;
  for (int updateScrollbarsPass = 0;
       updateScrollbarsPass < maxUpdateScrollbarsPass; updateScrollbarsPass++) {
    if (!adjustScrollbarExistence(updateScrollbarsPass ? Incremental
                                                       : FirstPass))
      break;
    scrollbarExistenceChanged = true;
  }

  updateScrollbarGeometry();

  if (scrollbarExistenceChanged) {
    // FIXME: Is frameRectsChanged really necessary here? Have any frame rects
    // changed?
    frameRectsChanged();
    positionScrollbarLayers();
    updateScrollCorner();
  }

  adjustScrollOffsetFromUpdateScrollbars();
}

void FrameView::adjustScrollOffsetFromUpdateScrollbars() {
  ScrollOffset clamped = clampScrollOffset(getScrollOffset());
  if (clamped != getScrollOffset() || scrollOriginChanged()) {
    ScrollableArea::setScrollOffset(clamped, ClampingScroll);
    resetScrollOriginChanged();
  }
}

void FrameView::scrollContentsIfNeeded() {
  if (m_pendingScrollDelta.isZero())
    return;
  ScrollOffset scrollDelta = m_pendingScrollDelta;
  m_pendingScrollDelta = ScrollOffset();
  // FIXME: Change scrollContents() to take DoubleSize. crbug.com/414283.
  scrollContents(flooredIntSize(scrollDelta));
}

void FrameView::scrollContents(const IntSize& scrollDelta) {
  HostWindow* window = getHostWindow();
  if (!window)
    return;

  TRACE_EVENT0("blink", "FrameView::scrollContents");

  if (!scrollContentsFastPath(-scrollDelta))
    scrollContentsSlowPath();

  // This call will move children with native widgets (plugins) and invalidate
  // them as well.
  frameRectsChanged();
}

IntPoint FrameView::contentsToFrame(const IntPoint& pointInContentSpace) const {
  return pointInContentSpace - scrollOffsetInt();
}

IntRect FrameView::contentsToFrame(const IntRect& rectInContentSpace) const {
  return IntRect(contentsToFrame(rectInContentSpace.location()),
                 rectInContentSpace.size());
}

FloatPoint FrameView::frameToContents(const FloatPoint& pointInFrame) const {
  return pointInFrame + getScrollOffset();
}

IntPoint FrameView::frameToContents(const IntPoint& pointInFrame) const {
  return pointInFrame + scrollOffsetInt();
}

IntRect FrameView::frameToContents(const IntRect& rectInFrame) const {
  return IntRect(frameToContents(rectInFrame.location()), rectInFrame.size());
}

IntPoint FrameView::rootFrameToContents(const IntPoint& rootFramePoint) const {
  IntPoint framePoint = convertFromRootFrame(rootFramePoint);
  return frameToContents(framePoint);
}

IntRect FrameView::rootFrameToContents(const IntRect& rootFrameRect) const {
  return IntRect(rootFrameToContents(rootFrameRect.location()),
                 rootFrameRect.size());
}

IntPoint FrameView::contentsToRootFrame(const IntPoint& contentsPoint) const {
  IntPoint framePoint = contentsToFrame(contentsPoint);
  return convertToRootFrame(framePoint);
}

IntRect FrameView::contentsToRootFrame(const IntRect& contentsRect) const {
  IntRect rectInFrame = contentsToFrame(contentsRect);
  return convertToRootFrame(rectInFrame);
}

FloatPoint FrameView::rootFrameToContents(
    const FloatPoint& pointInRootFrame) const {
  FloatPoint framePoint = convertFromRootFrame(pointInRootFrame);
  return frameToContents(framePoint);
}

IntRect FrameView::viewportToContents(const IntRect& rectInViewport) const {
  IntRect rectInRootFrame =
      m_frame->host()->visualViewport().viewportToRootFrame(rectInViewport);
  IntRect frameRect = convertFromRootFrame(rectInRootFrame);
  return frameToContents(frameRect);
}

IntPoint FrameView::viewportToContents(const IntPoint& pointInViewport) const {
  IntPoint pointInRootFrame =
      m_frame->host()->visualViewport().viewportToRootFrame(pointInViewport);
  IntPoint pointInFrame = convertFromRootFrame(pointInRootFrame);
  return frameToContents(pointInFrame);
}

IntRect FrameView::contentsToViewport(const IntRect& rectInContents) const {
  IntRect rectInFrame = contentsToFrame(rectInContents);
  IntRect rectInRootFrame = convertToRootFrame(rectInFrame);
  return m_frame->host()->visualViewport().rootFrameToViewport(rectInRootFrame);
}

IntPoint FrameView::contentsToViewport(const IntPoint& pointInContents) const {
  IntPoint pointInFrame = contentsToFrame(pointInContents);
  IntPoint pointInRootFrame = convertToRootFrame(pointInFrame);
  return m_frame->host()->visualViewport().rootFrameToViewport(
      pointInRootFrame);
}

IntRect FrameView::contentsToScreen(const IntRect& rect) const {
  HostWindow* window = getHostWindow();
  if (!window)
    return IntRect();
  return window->viewportToScreen(contentsToViewport(rect), this);
}

IntPoint FrameView::soonToBeRemovedUnscaledViewportToContents(
    const IntPoint& pointInViewport) const {
  IntPoint pointInRootFrame = flooredIntPoint(
      m_frame->host()->visualViewport().viewportCSSPixelsToRootFrame(
          pointInViewport));
  IntPoint pointInThisFrame = convertFromRootFrame(pointInRootFrame);
  return frameToContents(pointInThisFrame);
}

Scrollbar* FrameView::scrollbarAtFramePoint(const IntPoint& pointInFrame) {
  if (horizontalScrollbar() &&
      horizontalScrollbar()->shouldParticipateInHitTesting() &&
      horizontalScrollbar()->frameRect().contains(pointInFrame))
    return horizontalScrollbar();
  if (verticalScrollbar() &&
      verticalScrollbar()->shouldParticipateInHitTesting() &&
      verticalScrollbar()->frameRect().contains(pointInFrame))
    return verticalScrollbar();
  return nullptr;
}

static void positionScrollbarLayer(GraphicsLayer* graphicsLayer,
                                   Scrollbar* scrollbar) {
  if (!graphicsLayer || !scrollbar)
    return;

  IntRect scrollbarRect = scrollbar->frameRect();
  graphicsLayer->setPosition(scrollbarRect.location());

  if (scrollbarRect.size() == graphicsLayer->size())
    return;

  graphicsLayer->setSize(FloatSize(scrollbarRect.size()));

  if (graphicsLayer->hasContentsLayer()) {
    graphicsLayer->setContentsRect(
        IntRect(0, 0, scrollbarRect.width(), scrollbarRect.height()));
    return;
  }

  graphicsLayer->setDrawsContent(true);
  graphicsLayer->setNeedsDisplay();
}

static void positionScrollCornerLayer(GraphicsLayer* graphicsLayer,
                                      const IntRect& cornerRect) {
  if (!graphicsLayer)
    return;
  graphicsLayer->setDrawsContent(!cornerRect.isEmpty());
  graphicsLayer->setPosition(cornerRect.location());
  if (cornerRect.size() != graphicsLayer->size())
    graphicsLayer->setNeedsDisplay();
  graphicsLayer->setSize(FloatSize(cornerRect.size()));
}

void FrameView::positionScrollbarLayers() {
  positionScrollbarLayer(layerForHorizontalScrollbar(), horizontalScrollbar());
  positionScrollbarLayer(layerForVerticalScrollbar(), verticalScrollbar());
  positionScrollCornerLayer(layerForScrollCorner(), scrollCornerRect());
}

bool FrameView::userInputScrollable(ScrollbarOrientation orientation) const {
  Document* document = frame().document();
  Element* fullscreenElement = Fullscreen::fullscreenElementFrom(*document);
  if (fullscreenElement && fullscreenElement != document->documentElement())
    return false;

  if (RuntimeEnabledFeatures::rootLayerScrollingEnabled())
    return false;

  ScrollbarMode mode = (orientation == HorizontalScrollbar)
                           ? m_horizontalScrollbarMode
                           : m_verticalScrollbarMode;

  return mode == ScrollbarAuto || mode == ScrollbarAlwaysOn;
}

bool FrameView::shouldPlaceVerticalScrollbarOnLeft() const {
  return false;
}

Widget* FrameView::getWidget() {
  return this;
}

LayoutRect FrameView::scrollIntoView(const LayoutRect& rectInContent,
                                     const ScrollAlignment& alignX,
                                     const ScrollAlignment& alignY,
                                     ScrollType scrollType) {
  LayoutRect viewRect(visibleContentRect());
  LayoutRect exposeRect =
      ScrollAlignment::getRectToExpose(viewRect, rectInContent, alignX, alignY);
  if (exposeRect != viewRect) {
    setScrollOffset(
        ScrollOffset(exposeRect.x().toFloat(), exposeRect.y().toFloat()),
        scrollType);
  }

  // Scrolling the FrameView cannot change the input rect's location relative to
  // the document.
  return rectInContent;
}

IntRect FrameView::scrollCornerRect() const {
  IntRect cornerRect;

  if (hasOverlayScrollbars())
    return cornerRect;

  if (horizontalScrollbar() && width() - horizontalScrollbar()->width() > 0) {
    cornerRect.unite(IntRect(shouldPlaceVerticalScrollbarOnLeft()
                                 ? 0
                                 : horizontalScrollbar()->width(),
                             height() - horizontalScrollbar()->height(),
                             width() - horizontalScrollbar()->width(),
                             horizontalScrollbar()->height()));
  }

  if (verticalScrollbar() && height() - verticalScrollbar()->height() > 0) {
    cornerRect.unite(IntRect(shouldPlaceVerticalScrollbarOnLeft()
                                 ? 0
                                 : (width() - verticalScrollbar()->width()),
                             verticalScrollbar()->height(),
                             verticalScrollbar()->width(),
                             height() - verticalScrollbar()->height()));
  }

  return cornerRect;
}

bool FrameView::isScrollCornerVisible() const {
  return !scrollCornerRect().isEmpty();
}

ScrollBehavior FrameView::scrollBehaviorStyle() const {
  Element* scrollElement = m_frame->document()->scrollingElement();
  LayoutObject* layoutObject =
      scrollElement ? scrollElement->layoutObject() : nullptr;
  if (layoutObject &&
      layoutObject->style()->getScrollBehavior() == ScrollBehaviorSmooth)
    return ScrollBehaviorSmooth;

  return ScrollBehaviorInstant;
}

void FrameView::paint(GraphicsContext& context,
                      const CullRect& cullRect) const {
  paint(context, GlobalPaintNormalPhase, cullRect);
}

void FrameView::paint(GraphicsContext& context,
                      const GlobalPaintFlags globalPaintFlags,
                      const CullRect& cullRect) const {
  FramePainter(*this).paint(context, globalPaintFlags, cullRect);
}

void FrameView::paintContents(GraphicsContext& context,
                              const GlobalPaintFlags globalPaintFlags,
                              const IntRect& damageRect) const {
  FramePainter(*this).paintContents(context, globalPaintFlags, damageRect);
}

bool FrameView::isPointInScrollbarCorner(const IntPoint& pointInRootFrame) {
  if (!scrollbarCornerPresent())
    return false;

  IntPoint framePoint = convertFromRootFrame(pointInRootFrame);

  if (horizontalScrollbar()) {
    int horizontalScrollbarYMin = horizontalScrollbar()->frameRect().y();
    int horizontalScrollbarYMax = horizontalScrollbar()->frameRect().y() +
                                  horizontalScrollbar()->frameRect().height();
    int horizontalScrollbarXMin = horizontalScrollbar()->frameRect().x() +
                                  horizontalScrollbar()->frameRect().width();

    return framePoint.y() > horizontalScrollbarYMin &&
           framePoint.y() < horizontalScrollbarYMax &&
           framePoint.x() > horizontalScrollbarXMin;
  }

  int verticalScrollbarXMin = verticalScrollbar()->frameRect().x();
  int verticalScrollbarXMax = verticalScrollbar()->frameRect().x() +
                              verticalScrollbar()->frameRect().width();
  int verticalScrollbarYMin = verticalScrollbar()->frameRect().y() +
                              verticalScrollbar()->frameRect().height();

  return framePoint.x() > verticalScrollbarXMin &&
         framePoint.x() < verticalScrollbarXMax &&
         framePoint.y() > verticalScrollbarYMin;
}

bool FrameView::scrollbarCornerPresent() const {
  return (horizontalScrollbar() &&
          width() - horizontalScrollbar()->width() > 0) ||
         (verticalScrollbar() && height() - verticalScrollbar()->height() > 0);
}

IntRect FrameView::convertFromScrollbarToContainingWidget(
    const Scrollbar& scrollbar,
    const IntRect& localRect) const {
  // Scrollbars won't be transformed within us
  IntRect newRect = localRect;
  newRect.moveBy(scrollbar.location());
  return newRect;
}

IntRect FrameView::convertFromContainingWidgetToScrollbar(
    const Scrollbar& scrollbar,
    const IntRect& parentRect) const {
  IntRect newRect = parentRect;
  // Scrollbars won't be transformed within us
  newRect.moveBy(-scrollbar.location());
  return newRect;
}

// FIXME: test these on windows
IntPoint FrameView::convertFromScrollbarToContainingWidget(
    const Scrollbar& scrollbar,
    const IntPoint& localPoint) const {
  // Scrollbars won't be transformed within us
  IntPoint newPoint = localPoint;
  newPoint.moveBy(scrollbar.location());
  return newPoint;
}

IntPoint FrameView::convertFromContainingWidgetToScrollbar(
    const Scrollbar& scrollbar,
    const IntPoint& parentPoint) const {
  IntPoint newPoint = parentPoint;
  // Scrollbars won't be transformed within us
  newPoint.moveBy(-scrollbar.location());
  return newPoint;
}

static void setNeedsCompositingUpdate(LayoutViewItem layoutViewItem,
                                      CompositingUpdateType updateType) {
  if (PaintLayerCompositor* compositor =
          !layoutViewItem.isNull() ? layoutViewItem.compositor() : nullptr)
    compositor->setNeedsCompositingUpdate(updateType);
}

void FrameView::setParentVisible(bool visible) {
  if (isParentVisible() == visible)
    return;

  // As parent visibility changes, we may need to recomposite this frame view
  // and potentially child frame views.
  setNeedsCompositingUpdate(layoutViewItem(), CompositingUpdateRebuildTree);

  Widget::setParentVisible(visible);

  if (!isSelfVisible())
    return;

  for (const auto& child : m_children)
    child->setParentVisible(visible);
}

void FrameView::show() {
  if (!isSelfVisible()) {
    setSelfVisible(true);
    if (ScrollingCoordinator* scrollingCoordinator =
            this->scrollingCoordinator())
      scrollingCoordinator->frameViewVisibilityDidChange();
    setNeedsCompositingUpdate(layoutViewItem(), CompositingUpdateRebuildTree);
    updateParentScrollableAreaSet();
    if (isParentVisible()) {
      for (const auto& child : m_children)
        child->setParentVisible(true);
    }
  }

  Widget::show();
}

void FrameView::hide() {
  if (isSelfVisible()) {
    if (isParentVisible()) {
      for (const auto& child : m_children)
        child->setParentVisible(false);
    }
    setSelfVisible(false);
    if (ScrollingCoordinator* scrollingCoordinator =
            this->scrollingCoordinator())
      scrollingCoordinator->frameViewVisibilityDidChange();
    setNeedsCompositingUpdate(layoutViewItem(), CompositingUpdateRebuildTree);
    updateParentScrollableAreaSet();
  }

  Widget::hide();
}

int FrameView::viewportWidth() const {
  int viewportWidth = layoutSize(IncludeScrollbars).width();
  return adjustForAbsoluteZoom(viewportWidth, layoutView());
}

ScrollableArea* FrameView::getScrollableArea() {
  if (m_viewportScrollableArea)
    return m_viewportScrollableArea.get();

  return layoutViewportScrollableArea();
}

ScrollableArea* FrameView::layoutViewportScrollableArea() {
  if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled())
    return this;

  LayoutViewItem layoutViewItem = this->layoutViewItem();
  return layoutViewItem.isNull() ? nullptr : layoutViewItem.getScrollableArea();
}

RootFrameViewport* FrameView::getRootFrameViewport() {
  return m_viewportScrollableArea.get();
}

LayoutObject* FrameView::viewportLayoutObject() const {
  if (Document* document = frame().document()) {
    if (Element* element = document->viewportDefiningElement())
      return element->layoutObject();
  }
  return nullptr;
}

void FrameView::collectAnnotatedRegions(
    LayoutObject& layoutObject,
    Vector<AnnotatedRegionValue>& regions) const {
  // LayoutTexts don't have their own style, they just use their parent's style,
  // so we don't want to include them.
  if (layoutObject.isText())
    return;

  layoutObject.addAnnotatedRegions(regions);
  for (LayoutObject* curr = layoutObject.slowFirstChild(); curr;
       curr = curr->nextSibling())
    collectAnnotatedRegions(*curr, regions);
}

void FrameView::setNeedsUpdateViewportIntersection() {
  for (FrameView* parent = parentFrameView(); parent;
       parent = parent->parentFrameView())
    parent->m_needsUpdateViewportIntersectionInSubtree = true;
}

void FrameView::updateViewportIntersectionsForSubtree(
    DocumentLifecycle::LifecycleState targetState) {
  // Notify javascript IntersectionObservers
  if (targetState == DocumentLifecycle::PaintClean &&
      frame().document()->intersectionObserverController())
    frame()
        .document()
        ->intersectionObserverController()
        ->computeTrackedIntersectionObservations();

  if (!m_needsUpdateViewportIntersectionInSubtree)
    return;
  m_needsUpdateViewportIntersectionInSubtree = false;

  for (Frame* child = m_frame->tree().firstChild(); child;
       child = child->tree().nextSibling()) {
    if (!child->isLocalFrame())
      continue;
    if (FrameView* view = toLocalFrame(child)->view())
      view->updateViewportIntersectionsForSubtree(targetState);
  }
}

void FrameView::updateRenderThrottlingStatusForTesting() {
  m_visibilityObserver->deliverObservationsForTesting();
}

void FrameView::updateRenderThrottlingStatus(bool hidden,
                                             bool subtreeThrottled) {
  TRACE_EVENT0("blink", "FrameView::updateRenderThrottlingStatus");
  DCHECK(!isInPerformLayout());
  DCHECK(!m_frame->document() || !m_frame->document()->inStyleRecalc());
  bool wasThrottled = canThrottleRendering();

  // Note that we disallow throttling of 0x0 frames because some sites use
  // them to drive UI logic.
  m_hiddenForThrottling = hidden && !frameRect().isEmpty();
  m_subtreeThrottled = subtreeThrottled;

  bool isThrottled = canThrottleRendering();
  bool becameUnthrottled = wasThrottled && !isThrottled;

  // If this FrameView became unthrottled or throttled, we must make sure all
  // its children are notified synchronously. Otherwise we 1) might attempt to
  // paint one of the children with an out-of-date layout before
  // |updateRenderThrottlingStatus| has made it throttled or 2) fail to
  // unthrottle a child whose parent is unthrottled by a later notification.
  if (wasThrottled != isThrottled) {
    for (const Member<Widget>& child : *children()) {
      if (child->isFrameView()) {
        FrameView* childView = toFrameView(child);
        childView->updateRenderThrottlingStatus(
            childView->m_hiddenForThrottling, isThrottled);
      }
    }
  }

  ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator();
  if (becameUnthrottled) {
    // ScrollingCoordinator needs to update according to the new throttling
    // status.
    if (scrollingCoordinator)
      scrollingCoordinator->notifyGeometryChanged();
    // Start ticking animation frames again if necessary.
    if (page())
      page()->animator().scheduleVisualUpdate(m_frame.get());
    // Force a full repaint of this frame to ensure we are not left with a
    // partially painted version of this frame's contents if we skipped
    // painting them while the frame was throttled.
    LayoutViewItem layoutViewItem = this->layoutViewItem();
    if (!layoutViewItem.isNull())
      layoutViewItem.invalidatePaintForViewAndCompositedLayers();
  }

  bool hasHandlers = m_frame->host() &&
                     m_frame->host()->eventHandlerRegistry().hasEventHandlers(
                         EventHandlerRegistry::TouchStartOrMoveEventBlocking);
  if (wasThrottled != canThrottleRendering() && scrollingCoordinator &&
      hasHandlers)
    scrollingCoordinator->touchEventTargetRectsDidChange();

#if DCHECK_IS_ON()
  // Make sure we never have an unthrottled frame inside a throttled one.
  FrameView* parent = parentFrameView();
  while (parent) {
    DCHECK(canThrottleRendering() || !parent->canThrottleRendering());
    parent = parent->parentFrameView();
  }
#endif
}

// TODO(esprehn): Rename this and the method on Document to
// recordDeferredLoadReason().
void FrameView::maybeRecordLoadReason() {
  FrameView* parent = parentFrameView();
  if (frame().document()->frame()) {
    if (!parent) {
      HTMLFrameOwnerElement* element = frame().deprecatedLocalOwner();
      if (!element)
        frame().document()->maybeRecordLoadReason(WouldLoadOutOfProcess);
      // Having no layout object means the frame is not drawn.
      else if (!element->layoutObject())
        frame().document()->maybeRecordLoadReason(WouldLoadDisplayNone);
    } else {
      // Assume the main frame has always loaded since we don't track its
      // visibility.
      bool parentLoaded =
          !parent->parentFrameView() ||
          parent->frame().document()->wouldLoadReason() > Created;
      // If the parent wasn't loaded, the children won't be either.
      if (parentLoaded) {
        if (frameRect().isEmpty())
          frame().document()->maybeRecordLoadReason(WouldLoadZeroByZero);
        else if (frameRect().maxY() < 0 && frameRect().maxX() < 0)
          frame().document()->maybeRecordLoadReason(WouldLoadAboveAndLeft);
        else if (frameRect().maxY() < 0)
          frame().document()->maybeRecordLoadReason(WouldLoadAbove);
        else if (frameRect().maxX() < 0)
          frame().document()->maybeRecordLoadReason(WouldLoadLeft);
        else if (!m_hiddenForThrottling)
          frame().document()->maybeRecordLoadReason(WouldLoadVisible);
      }
    }
  }
}

bool FrameView::shouldThrottleRendering() const {
  return canThrottleRendering() && m_frame->document() &&
         lifecycle().throttlingAllowed();
}

bool FrameView::canThrottleRendering() const {
  if (m_lifecycleUpdatesThrottled)
    return true;
  if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled())
    return false;
  if (m_subtreeThrottled)
    return true;
  // We only throttle hidden cross-origin frames. This is to avoid a situation
  // where an ancestor frame directly depends on the pipeline timing of a
  // descendant and breaks as a result of throttling. The rationale is that
  // cross-origin frames must already communicate with asynchronous messages,
  // so they should be able to tolerate some delay in receiving replies from a
  // throttled peer.
  return m_hiddenForThrottling && m_frame->isCrossOriginSubframe();
}

void FrameView::beginLifecycleUpdates() {
  // Avoid pumping frames for the initially empty document.
  if (!frame().loader().stateMachine()->committedFirstRealDocumentLoad())
    return;
  m_lifecycleUpdatesThrottled = false;
  setupRenderThrottling();
  updateRenderThrottlingStatus(m_hiddenForThrottling, m_subtreeThrottled);
  // The compositor will "defer commits" for the main frame until we
  // explicitly request them.
  if (frame().isMainFrame())
    frame().host()->chromeClient().beginLifecycleUpdates();
}

void FrameView::setInitialViewportSize(const IntSize& viewportSize) {
  if (viewportSize == m_initialViewportSize)
    return;

  m_initialViewportSize = viewportSize;
  if (Document* document = m_frame->document())
    document->styleEngine().initialViewportChanged();
}

int FrameView::initialViewportWidth() const {
  DCHECK(m_frame->isMainFrame());
  return m_initialViewportSize.width();
}

int FrameView::initialViewportHeight() const {
  DCHECK(m_frame->isMainFrame());
  return m_initialViewportSize.height();
}

}  // namespace blink
