Home | History | Annotate | Download | only in frame
      1 /*
      2  * Copyright (C) 1998, 1999 Torben Weis <weis (at) kde.org>
      3  *                     1999 Lars Knoll <knoll (at) kde.org>
      4  *                     1999 Antti Koivisto <koivisto (at) kde.org>
      5  *                     2000 Dirk Mueller <mueller (at) kde.org>
      6  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
      7  *           (C) 2006 Graham Dennis (graham.dennis (at) gmail.com)
      8  *           (C) 2006 Alexey Proskuryakov (ap (at) nypop.com)
      9  * Copyright (C) 2009 Google Inc. All rights reserved.
     10  *
     11  * This library is free software; you can redistribute it and/or
     12  * modify it under the terms of the GNU Library General Public
     13  * License as published by the Free Software Foundation; either
     14  * version 2 of the License, or (at your option) any later version.
     15  *
     16  * This library is distributed in the hope that it will be useful,
     17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19  * Library General Public License for more details.
     20  *
     21  * You should have received a copy of the GNU Library General Public License
     22  * along with this library; see the file COPYING.LIB.  If not, write to
     23  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     24  * Boston, MA 02110-1301, USA.
     25  */
     26 
     27 #include "config.h"
     28 #include "core/frame/FrameView.h"
     29 
     30 #include "core/HTMLNames.h"
     31 #include "core/MediaTypeNames.h"
     32 #include "core/accessibility/AXObjectCache.h"
     33 #include "core/css/FontFaceSet.h"
     34 #include "core/css/resolver/StyleResolver.h"
     35 #include "core/dom/DocumentMarkerController.h"
     36 #include "core/editing/FrameSelection.h"
     37 #include "core/editing/RenderedPosition.h"
     38 #include "core/events/OverflowEvent.h"
     39 #include "core/fetch/ResourceFetcher.h"
     40 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
     41 #include "core/frame/FrameHost.h"
     42 #include "core/frame/LocalFrame.h"
     43 #include "core/frame/Settings.h"
     44 #include "core/html/HTMLFrameElement.h"
     45 #include "core/html/HTMLPlugInElement.h"
     46 #include "core/html/parser/TextResourceDecoder.h"
     47 #include "core/inspector/InspectorInstrumentation.h"
     48 #include "core/inspector/InspectorTraceEvents.h"
     49 #include "core/loader/FrameLoader.h"
     50 #include "core/loader/FrameLoaderClient.h"
     51 #include "core/page/Chrome.h"
     52 #include "core/page/ChromeClient.h"
     53 #include "core/page/EventHandler.h"
     54 #include "core/page/FocusController.h"
     55 #include "core/page/FrameTree.h"
     56 #include "core/page/Page.h"
     57 #include "core/page/scrolling/ScrollingCoordinator.h"
     58 #include "core/rendering/RenderCounter.h"
     59 #include "core/rendering/RenderEmbeddedObject.h"
     60 #include "core/rendering/RenderLayer.h"
     61 #include "core/rendering/RenderListBox.h"
     62 #include "core/rendering/RenderPart.h"
     63 #include "core/rendering/RenderScrollbar.h"
     64 #include "core/rendering/RenderScrollbarPart.h"
     65 #include "core/rendering/RenderTheme.h"
     66 #include "core/rendering/RenderView.h"
     67 #include "core/rendering/RenderWidget.h"
     68 #include "core/rendering/TextAutosizer.h"
     69 #include "core/rendering/compositing/CompositedLayerMapping.h"
     70 #include "core/rendering/compositing/CompositedSelectionBound.h"
     71 #include "core/rendering/compositing/RenderLayerCompositor.h"
     72 #include "core/rendering/style/RenderStyle.h"
     73 #include "core/rendering/svg/RenderSVGRoot.h"
     74 #include "core/svg/SVGDocumentExtensions.h"
     75 #include "core/svg/SVGSVGElement.h"
     76 #include "platform/RuntimeEnabledFeatures.h"
     77 #include "platform/ScriptForbiddenScope.h"
     78 #include "platform/TraceEvent.h"
     79 #include "platform/fonts/FontCache.h"
     80 #include "platform/geometry/FloatRect.h"
     81 #include "platform/graphics/GraphicsContext.h"
     82 #include "platform/graphics/GraphicsLayerDebugInfo.h"
     83 #include "platform/scroll/ScrollAnimator.h"
     84 #include "platform/scroll/ScrollbarTheme.h"
     85 #include "platform/text/TextStream.h"
     86 #include "wtf/CurrentTime.h"
     87 #include "wtf/TemporaryChange.h"
     88 
     89 namespace blink {
     90 
     91 using namespace HTMLNames;
     92 
     93 double FrameView::s_currentFrameTimeStamp = 0.0;
     94 bool FrameView::s_inPaintContents = false;
     95 
     96 // The maximum number of updateWidgets iterations that should be done before returning.
     97 static const unsigned maxUpdateWidgetsIterations = 2;
     98 static const double resourcePriorityUpdateDelayAfterScroll = 0.250;
     99 
    100 FrameView::FrameView(LocalFrame* frame)
    101     : m_frame(frame)
    102     , m_canHaveScrollbars(true)
    103     , m_slowRepaintObjectCount(0)
    104     , m_hasPendingLayout(false)
    105     , m_layoutSubtreeRoot(0)
    106     , m_inSynchronousPostLayout(false)
    107     , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
    108     , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired)
    109     , m_isTransparent(false)
    110     , m_baseBackgroundColor(Color::white)
    111     , m_mediaType(MediaTypeNames::screen)
    112     , m_overflowStatusDirty(true)
    113     , m_viewportRenderer(0)
    114     , m_wasScrolledByUser(false)
    115     , m_inProgrammaticScroll(false)
    116     , m_safeToPropagateScrollToParent(true)
    117     , m_isTrackingPaintInvalidations(false)
    118     , m_scrollCorner(nullptr)
    119     , m_visibleContentScaleFactor(1)
    120     , m_inputEventsScaleFactorForEmulation(1)
    121     , m_layoutSizeFixedToFrameSize(true)
    122     , m_didScrollTimer(this, &FrameView::didScrollTimerFired)
    123     , m_needsUpdateWidgetPositions(false)
    124     , m_topControlsViewportAdjustment(0)
    125 {
    126     ASSERT(m_frame);
    127     init();
    128 
    129     if (!m_frame->isMainFrame())
    130         return;
    131 
    132     ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
    133     ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
    134 }
    135 
    136 PassRefPtr<FrameView> FrameView::create(LocalFrame* frame)
    137 {
    138     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
    139     view->show();
    140     return view.release();
    141 }
    142 
    143 PassRefPtr<FrameView> FrameView::create(LocalFrame* frame, const IntSize& initialSize)
    144 {
    145     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
    146     view->Widget::setFrameRect(IntRect(view->location(), initialSize));
    147     view->setLayoutSizeInternal(initialSize);
    148 
    149     view->show();
    150     return view.release();
    151 }
    152 
    153 FrameView::~FrameView()
    154 {
    155     if (m_postLayoutTasksTimer.isActive())
    156         m_postLayoutTasksTimer.stop();
    157 
    158     if (m_didScrollTimer.isActive())
    159         m_didScrollTimer.stop();
    160 
    161     removeFromAXObjectCache();
    162 
    163     // Custom scrollbars should already be destroyed at this point
    164     ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
    165     ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
    166 
    167     setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
    168     setHasVerticalScrollbar(false);
    169 
    170     ASSERT(!m_scrollCorner);
    171 
    172     ASSERT(m_frame);
    173     ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
    174     // FIXME: Do we need to do something here for OOPI?
    175     HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
    176     if (ownerElement && ownerElement->ownedWidget() == this)
    177         ownerElement->setWidget(nullptr);
    178 }
    179 
    180 void FrameView::reset()
    181 {
    182     m_hasPendingLayout = false;
    183     m_layoutSubtreeRoot = 0;
    184     m_doFullPaintInvalidation = false;
    185     m_layoutSchedulingEnabled = true;
    186     m_inPerformLayout = false;
    187     m_canInvalidatePaintDuringPerformLayout = false;
    188     m_inSynchronousPostLayout = false;
    189     m_layoutCount = 0;
    190     m_nestedLayoutCount = 0;
    191     m_postLayoutTasksTimer.stop();
    192     m_updateWidgetsTimer.stop();
    193     m_firstLayout = true;
    194     m_firstLayoutCallbackPending = false;
    195     m_wasScrolledByUser = false;
    196     m_safeToPropagateScrollToParent = true;
    197     m_lastViewportSize = IntSize();
    198     m_lastZoomFactor = 1.0f;
    199     m_isTrackingPaintInvalidations = false;
    200     m_trackedPaintInvalidationRects.clear();
    201     m_lastPaintTime = 0;
    202     m_paintBehavior = PaintBehaviorNormal;
    203     m_isPainting = false;
    204     m_visuallyNonEmptyCharacterCount = 0;
    205     m_visuallyNonEmptyPixelCount = 0;
    206     m_isVisuallyNonEmpty = false;
    207     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
    208     m_maintainScrollPositionAnchor = nullptr;
    209     m_viewportConstrainedObjects.clear();
    210 }
    211 
    212 void FrameView::removeFromAXObjectCache()
    213 {
    214     if (AXObjectCache* cache = axObjectCache()) {
    215         cache->remove(this);
    216         cache->childrenChanged(m_frame->pagePopupOwner());
    217     }
    218 }
    219 
    220 void FrameView::init()
    221 {
    222     reset();
    223 
    224     m_size = LayoutSize();
    225 
    226     // Propagate the marginwidth/height and scrolling modes to the view.
    227     // FIXME: Do we need to do this for OOPI?
    228     Element* ownerElement = m_frame->deprecatedLocalOwner();
    229     if (ownerElement && (isHTMLFrameElement(*ownerElement) || isHTMLIFrameElement(*ownerElement))) {
    230         HTMLFrameElementBase* frameElt = toHTMLFrameElementBase(ownerElement);
    231         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
    232             setCanHaveScrollbars(false);
    233     }
    234 }
    235 
    236 void FrameView::prepareForDetach()
    237 {
    238     RELEASE_ASSERT(!isInPerformLayout());
    239 
    240     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
    241         scrollAnimator->cancelAnimations();
    242     cancelProgrammaticScrollAnimation();
    243 
    244     detachCustomScrollbars();
    245     // When the view is no longer associated with a frame, it needs to be removed from the ax object cache
    246     // right now, otherwise it won't be able to reach the topDocument()'s axObject cache later.
    247     removeFromAXObjectCache();
    248 
    249     if (m_frame->page()) {
    250         if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator())
    251             scrollingCoordinator->willDestroyScrollableArea(this);
    252     }
    253 }
    254 
    255 void FrameView::detachCustomScrollbars()
    256 {
    257     Scrollbar* horizontalBar = horizontalScrollbar();
    258     if (horizontalBar && horizontalBar->isCustomScrollbar())
    259         setHasHorizontalScrollbar(false);
    260 
    261     Scrollbar* verticalBar = verticalScrollbar();
    262     if (verticalBar && verticalBar->isCustomScrollbar())
    263         setHasVerticalScrollbar(false);
    264 
    265     if (m_scrollCorner) {
    266         m_scrollCorner->destroy();
    267         m_scrollCorner = nullptr;
    268     }
    269 }
    270 
    271 void FrameView::recalculateScrollbarOverlayStyle()
    272 {
    273     ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
    274     ScrollbarOverlayStyle overlayStyle = ScrollbarOverlayStyleDefault;
    275 
    276     Color backgroundColor = documentBackgroundColor();
    277     // Reduce the background color from RGB to a lightness value
    278     // and determine which scrollbar style to use based on a lightness
    279     // heuristic.
    280     double hue, saturation, lightness;
    281     backgroundColor.getHSL(hue, saturation, lightness);
    282     if (lightness <= .5)
    283         overlayStyle = ScrollbarOverlayStyleLight;
    284 
    285     if (oldOverlayStyle != overlayStyle)
    286         setScrollbarOverlayStyle(overlayStyle);
    287 }
    288 
    289 void FrameView::clear()
    290 {
    291     reset();
    292     setScrollbarsSuppressed(true);
    293 }
    294 
    295 bool FrameView::didFirstLayout() const
    296 {
    297     return !m_firstLayout;
    298 }
    299 
    300 void FrameView::invalidateRect(const IntRect& rect)
    301 {
    302     // For querying RenderLayer::compositingState() when invalidating scrollbars.
    303     // FIXME: do all scrollbar invalidations after layout of all frames is complete. It's currently not recursively true.
    304     DisableCompositingQueryAsserts disabler;
    305     if (!parent()) {
    306         if (HostWindow* window = hostWindow())
    307             window->invalidateContentsAndRootView(rect);
    308         return;
    309     }
    310 
    311     RenderPart* renderer = m_frame->ownerRenderer();
    312     if (!renderer)
    313         return;
    314 
    315     IntRect paintInvalidationRect = rect;
    316     paintInvalidationRect.move(renderer->borderLeft() + renderer->paddingLeft(),
    317                      renderer->borderTop() + renderer->paddingTop());
    318     renderer->invalidatePaintRectangle(paintInvalidationRect);
    319 }
    320 
    321 void FrameView::setFrameRect(const IntRect& newRect)
    322 {
    323     IntRect oldRect = frameRect();
    324     if (newRect == oldRect)
    325         return;
    326 
    327     // Autosized font sizes depend on the width of the viewing area.
    328     bool autosizerNeedsUpdating = false;
    329     if (newRect.width() != oldRect.width() && m_frame->isMainFrame() && m_frame->settings()->textAutosizingEnabled())
    330         autosizerNeedsUpdating = true;
    331 
    332     ScrollView::setFrameRect(newRect);
    333 
    334     updateScrollableAreaSet();
    335 
    336     if (autosizerNeedsUpdating) {
    337         // This needs to be after the call to ScrollView::setFrameRect, because it reads the new width.
    338         if (TextAutosizer* textAutosizer = m_frame->document()->textAutosizer())
    339             textAutosizer->updatePageInfoInAllFrames();
    340     }
    341 
    342     if (RenderView* renderView = this->renderView()) {
    343         if (renderView->usesCompositing())
    344             renderView->compositor()->frameViewDidChangeSize();
    345     }
    346 
    347     viewportConstrainedVisibleContentSizeChanged(newRect.width() != oldRect.width(), newRect.height() != oldRect.height());
    348 
    349     if (oldRect.size() != newRect.size()
    350         && m_frame->isMainFrame()
    351         && m_frame->settings()->pinchVirtualViewportEnabled())
    352         page()->frameHost().pinchViewport().mainFrameDidChangeSize();
    353 }
    354 
    355 Page* FrameView::page() const
    356 {
    357     return frame().page();
    358 }
    359 
    360 RenderView* FrameView::renderView() const
    361 {
    362     return frame().contentRenderer();
    363 }
    364 
    365 void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
    366 {
    367     m_canHaveScrollbars = canHaveScrollbars;
    368     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
    369 }
    370 
    371 bool FrameView::shouldUseCustomScrollbars(Element*& customScrollbarElement, LocalFrame*& customScrollbarFrame)
    372 {
    373     customScrollbarElement = 0;
    374     customScrollbarFrame = 0;
    375 
    376     if (Settings* settings = m_frame->settings()) {
    377         if (!settings->allowCustomScrollbarInMainFrame() && m_frame->isMainFrame())
    378             return false;
    379     }
    380 
    381     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
    382     Document* doc = m_frame->document();
    383 
    384     // Try the <body> element first as a scrollbar source.
    385     Element* body = doc ? doc->body() : 0;
    386     if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR)) {
    387         customScrollbarElement = body;
    388         return true;
    389     }
    390 
    391     // If the <body> didn't have a custom style, then the root element might.
    392     Element* docElement = doc ? doc->documentElement() : 0;
    393     if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(SCROLLBAR)) {
    394         customScrollbarElement = docElement;
    395         return true;
    396     }
    397 
    398     // If we have an owning ipage/LocalFrame element, then it can set the custom scrollbar also.
    399     RenderPart* frameRenderer = m_frame->ownerRenderer();
    400     if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR)) {
    401         customScrollbarFrame = m_frame.get();
    402         return true;
    403     }
    404 
    405     return false;
    406 }
    407 
    408 PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
    409 {
    410     Element* customScrollbarElement = 0;
    411     LocalFrame* customScrollbarFrame = 0;
    412     if (shouldUseCustomScrollbars(customScrollbarElement, customScrollbarFrame))
    413         return RenderScrollbar::createCustomScrollbar(this, orientation, customScrollbarElement, customScrollbarFrame);
    414 
    415     // Nobody set a custom style, so we just use a native scrollbar.
    416     return ScrollView::createScrollbar(orientation);
    417 }
    418 
    419 void FrameView::setContentsSize(const IntSize& size)
    420 {
    421     if (size == contentsSize())
    422         return;
    423 
    424     ScrollView::setContentsSize(size);
    425     ScrollView::contentsResized();
    426 
    427     Page* page = frame().page();
    428     if (!page)
    429         return;
    430 
    431     updateScrollableAreaSet();
    432 
    433     page->chrome().contentsSizeChanged(m_frame.get(), size);
    434 }
    435 
    436 IntPoint FrameView::clampOffsetAtScale(const IntPoint& offset, float scale) const
    437 {
    438     IntPoint maxScrollExtent(contentsSize().width() - scrollOrigin().x(), contentsSize().height() - scrollOrigin().y());
    439     FloatSize scaledSize = unscaledVisibleContentSize();
    440     if (scale)
    441         scaledSize.scale(1 / scale);
    442 
    443     IntPoint clampedOffset = offset;
    444     clampedOffset = clampedOffset.shrunkTo(maxScrollExtent - expandedIntSize(scaledSize));
    445     clampedOffset = clampedOffset.expandedTo(-scrollOrigin());
    446 
    447     return clampedOffset;
    448 }
    449 
    450 void FrameView::adjustViewSize()
    451 {
    452     RenderView* renderView = this->renderView();
    453     if (!renderView)
    454         return;
    455 
    456     ASSERT(m_frame->view() == this);
    457 
    458     const IntRect rect = renderView->documentRect();
    459     const IntSize& size = rect.size();
    460     ScrollView::setScrollOrigin(IntPoint(-rect.x(), -rect.y()), !m_frame->document()->printing(), size == contentsSize());
    461 
    462     setContentsSize(size);
    463 }
    464 
    465 void FrameView::applyOverflowToViewportAndSetRenderer(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
    466 {
    467     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
    468     // overflow:hidden and overflow:scroll on <body> as applying to the document's
    469     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
    470     // use the root element.
    471 
    472     EOverflow overflowX = o->style()->overflowX();
    473     EOverflow overflowY = o->style()->overflowY();
    474 
    475     if (o->isSVGRoot()) {
    476         // Don't allow overflow to affect <img> and css backgrounds
    477         if (toRenderSVGRoot(o)->isEmbeddedThroughSVGImage())
    478             return;
    479 
    480         // FIXME: evaluate if we can allow overflow for these cases too.
    481         // Overflow is always hidden when stand-alone SVG documents are embedded.
    482         if (toRenderSVGRoot(o)->isEmbeddedThroughFrameContainingSVGDocument()) {
    483             overflowX = OHIDDEN;
    484             overflowY = OHIDDEN;
    485         }
    486     }
    487 
    488     bool ignoreOverflowHidden = false;
    489     if (m_frame->settings()->ignoreMainFrameOverflowHiddenQuirk() && m_frame->isMainFrame())
    490         ignoreOverflowHidden = true;
    491 
    492     switch (overflowX) {
    493         case OHIDDEN:
    494             if (!ignoreOverflowHidden)
    495                 hMode = ScrollbarAlwaysOff;
    496             break;
    497         case OSCROLL:
    498             hMode = ScrollbarAlwaysOn;
    499             break;
    500         case OAUTO:
    501             hMode = ScrollbarAuto;
    502             break;
    503         default:
    504             // Don't set it at all.
    505             ;
    506     }
    507 
    508      switch (overflowY) {
    509         case OHIDDEN:
    510             if (!ignoreOverflowHidden)
    511                 vMode = ScrollbarAlwaysOff;
    512             break;
    513         case OSCROLL:
    514             vMode = ScrollbarAlwaysOn;
    515             break;
    516         case OAUTO:
    517             vMode = ScrollbarAuto;
    518             break;
    519         default:
    520             // Don't set it at all.
    521             ;
    522     }
    523 
    524     m_viewportRenderer = o;
    525 }
    526 
    527 void FrameView::calculateScrollbarModesForLayoutAndSetViewportRenderer(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
    528 {
    529     m_viewportRenderer = 0;
    530 
    531     // FIXME: How do we handle this for OOPI?
    532     const HTMLFrameOwnerElement* owner = m_frame->deprecatedLocalOwner();
    533     if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
    534         hMode = ScrollbarAlwaysOff;
    535         vMode = ScrollbarAlwaysOff;
    536         return;
    537     }
    538 
    539     if (m_canHaveScrollbars || strategy == RulesFromWebContentOnly) {
    540         hMode = ScrollbarAuto;
    541         vMode = ScrollbarAuto;
    542     } else {
    543         hMode = ScrollbarAlwaysOff;
    544         vMode = ScrollbarAlwaysOff;
    545     }
    546 
    547     if (!isSubtreeLayout()) {
    548         Document* document = m_frame->document();
    549         Node* body = document->body();
    550         if (isHTMLFrameSetElement(body) && body->renderer()) {
    551             vMode = ScrollbarAlwaysOff;
    552             hMode = ScrollbarAlwaysOff;
    553         } else if (Element* viewportElement = document->viewportDefiningElement()) {
    554             if (RenderObject* viewportRenderer = viewportElement->renderer()) {
    555                 if (viewportRenderer->style())
    556                     applyOverflowToViewportAndSetRenderer(viewportRenderer, hMode, vMode);
    557             }
    558         }
    559     }
    560 }
    561 
    562 void FrameView::updateAcceleratedCompositingSettings()
    563 {
    564     if (RenderView* renderView = this->renderView())
    565         renderView->compositor()->updateAcceleratedCompositingSettings();
    566 }
    567 
    568 void FrameView::recalcOverflowAfterStyleChange()
    569 {
    570     RenderView* renderView = this->renderView();
    571     RELEASE_ASSERT(renderView);
    572     if (!renderView->needsOverflowRecalcAfterStyleChange())
    573         return;
    574 
    575     renderView->recalcOverflowAfterStyleChange();
    576 
    577     IntRect documentRect = renderView->documentRect();
    578     if (scrollOrigin() == -documentRect.location() && contentsSize() == documentRect.size())
    579         return;
    580 
    581     if (needsLayout())
    582         return;
    583 
    584     InUpdateScrollbarsScope inUpdateScrollbarsScope(this);
    585 
    586     bool shouldHaveHorizontalScrollbar = false;
    587     bool shouldHaveVerticalScrollbar = false;
    588     computeScrollbarExistence(shouldHaveHorizontalScrollbar, shouldHaveVerticalScrollbar, documentRect.size());
    589 
    590     bool hasHorizontalScrollbar = horizontalScrollbar();
    591     bool hasVerticalScrollbar = verticalScrollbar();
    592     if (hasHorizontalScrollbar != shouldHaveHorizontalScrollbar
    593         || hasVerticalScrollbar != shouldHaveVerticalScrollbar) {
    594         setNeedsLayout();
    595         return;
    596     }
    597 
    598     adjustViewSize();
    599     updateScrollbarGeometry();
    600 }
    601 
    602 bool FrameView::usesCompositedScrolling() const
    603 {
    604     RenderView* renderView = this->renderView();
    605     if (!renderView)
    606         return false;
    607     if (m_frame->settings() && m_frame->settings()->preferCompositingToLCDTextEnabled())
    608         return renderView->compositor()->inCompositingMode();
    609     return false;
    610 }
    611 
    612 GraphicsLayer* FrameView::layerForScrolling() const
    613 {
    614     RenderView* renderView = this->renderView();
    615     if (!renderView)
    616         return 0;
    617     return renderView->compositor()->scrollLayer();
    618 }
    619 
    620 GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
    621 {
    622     RenderView* renderView = this->renderView();
    623     if (!renderView)
    624         return 0;
    625     return renderView->compositor()->layerForHorizontalScrollbar();
    626 }
    627 
    628 GraphicsLayer* FrameView::layerForVerticalScrollbar() const
    629 {
    630     RenderView* renderView = this->renderView();
    631     if (!renderView)
    632         return 0;
    633     return renderView->compositor()->layerForVerticalScrollbar();
    634 }
    635 
    636 GraphicsLayer* FrameView::layerForScrollCorner() const
    637 {
    638     RenderView* renderView = this->renderView();
    639     if (!renderView)
    640         return 0;
    641     return renderView->compositor()->layerForScrollCorner();
    642 }
    643 
    644 bool FrameView::isEnclosedInCompositingLayer() const
    645 {
    646     // FIXME: It's a bug that compositing state isn't always up to date when this is called. crbug.com/366314
    647     DisableCompositingQueryAsserts disabler;
    648 
    649     RenderObject* frameOwnerRenderer = m_frame->ownerRenderer();
    650     return frameOwnerRenderer && frameOwnerRenderer->enclosingLayer()->enclosingLayerForPaintInvalidationCrossingFrameBoundaries();
    651 }
    652 
    653 RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
    654 {
    655     return onlyDuringLayout && layoutPending() ? 0 : m_layoutSubtreeRoot;
    656 }
    657 
    658 inline void FrameView::forceLayoutParentViewIfNeeded()
    659 {
    660     RenderPart* ownerRenderer = m_frame->ownerRenderer();
    661     if (!ownerRenderer || !ownerRenderer->frame())
    662         return;
    663 
    664     RenderBox* contentBox = embeddedContentBox();
    665     if (!contentBox)
    666         return;
    667 
    668     RenderSVGRoot* svgRoot = toRenderSVGRoot(contentBox);
    669     if (svgRoot->everHadLayout() && !svgRoot->needsLayout())
    670         return;
    671 
    672     // If the embedded SVG document appears the first time, the ownerRenderer has already finished
    673     // layout without knowing about the existence of the embedded SVG document, because RenderReplaced
    674     // embeddedContentBox() returns 0, as long as the embedded document isn't loaded yet. Before
    675     // bothering to lay out the SVG document, mark the ownerRenderer needing layout and ask its
    676     // FrameView for a layout. After that the RenderEmbeddedObject (ownerRenderer) carries the
    677     // correct size, which RenderSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying
    678     // out for the first time, or when the RenderSVGRoot size has changed dynamically (eg. via <script>).
    679     RefPtr<FrameView> frameView = ownerRenderer->frame()->view();
    680 
    681     // Mark the owner renderer as needing layout.
    682     ownerRenderer->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
    683 
    684     // Synchronously enter layout, to layout the view containing the host object/embed/iframe.
    685     ASSERT(frameView);
    686     frameView->layout();
    687 }
    688 
    689 void FrameView::performPreLayoutTasks()
    690 {
    691     TRACE_EVENT0("blink", "FrameView::performPreLayoutTasks");
    692     lifecycle().advanceTo(DocumentLifecycle::InPreLayout);
    693 
    694     // Don't schedule more layouts, we're in one.
    695     TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
    696 
    697     if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive()) {
    698         // This is a new top-level layout. If there are any remaining tasks from the previous layout, finish them now.
    699         m_inSynchronousPostLayout = true;
    700         performPostLayoutTasks();
    701         m_inSynchronousPostLayout = false;
    702     }
    703 
    704     Document* document = m_frame->document();
    705     if (wasViewportResized())
    706         document->notifyResizeForViewportUnits();
    707 
    708     // Viewport-dependent media queries may cause us to need completely different style information.
    709     if (!document->styleResolver() || document->styleResolver()->mediaQueryAffectedByViewportChange()) {
    710         document->styleResolverChanged();
    711         document->mediaQueryAffectingValueChanged();
    712 
    713         // FIXME: This instrumentation event is not strictly accurate since cached media query results
    714         //        do not persist across StyleResolver rebuilds.
    715         InspectorInstrumentation::mediaQueryResultChanged(document);
    716     } else {
    717         document->evaluateMediaQueryList();
    718     }
    719 
    720     document->updateRenderTreeIfNeeded();
    721     lifecycle().advanceTo(DocumentLifecycle::StyleClean);
    722 }
    723 
    724 void FrameView::performLayout(RenderObject* rootForThisLayout, bool inSubtreeLayout)
    725 {
    726     TRACE_EVENT0("blink", "FrameView::performLayout");
    727 
    728     ScriptForbiddenScope forbidScript;
    729 
    730     ASSERT(!isInPerformLayout());
    731     lifecycle().advanceTo(DocumentLifecycle::InPerformLayout);
    732 
    733     TemporaryChange<bool> changeInPerformLayout(m_inPerformLayout, true);
    734 
    735     // performLayout is the actual guts of layout().
    736     // FIXME: The 300 other lines in layout() probably belong in other helper functions
    737     // so that a single human could understand what layout() is actually doing.
    738 
    739     LayoutState layoutState(*rootForThisLayout);
    740 
    741     forceLayoutParentViewIfNeeded();
    742 
    743     // FIXME (crbug.com/256657): Do not do two layouts for text autosizing.
    744     rootForThisLayout->layout();
    745     gatherDebugLayoutRects(rootForThisLayout);
    746 
    747     ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllImageResourcePriorities();
    748 
    749     lifecycle().advanceTo(DocumentLifecycle::AfterPerformLayout);
    750 }
    751 
    752 void FrameView::scheduleOrPerformPostLayoutTasks()
    753 {
    754     if (m_postLayoutTasksTimer.isActive())
    755         return;
    756 
    757     if (!m_inSynchronousPostLayout) {
    758         m_inSynchronousPostLayout = true;
    759         // Calls resumeScheduledEvents()
    760         performPostLayoutTasks();
    761         m_inSynchronousPostLayout = false;
    762     }
    763 
    764     if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout)) {
    765         // If we need layout or are already in a synchronous call to postLayoutTasks(),
    766         // defer widget updates and event dispatch until after we return. postLayoutTasks()
    767         // can make us need to update again, and we can get stuck in a nasty cycle unless
    768         // we call it through the timer here.
    769         m_postLayoutTasksTimer.startOneShot(0, FROM_HERE);
    770         if (needsLayout())
    771             layout();
    772     }
    773 }
    774 
    775 void FrameView::layout(bool allowSubtree)
    776 {
    777     // We should never layout a Document which is not in a LocalFrame.
    778     ASSERT(m_frame);
    779     ASSERT(m_frame->view() == this);
    780     ASSERT(m_frame->page());
    781 
    782     ScriptForbiddenScope forbidScript;
    783 
    784     if (isInPerformLayout() || !m_frame->document()->isActive())
    785         return;
    786 
    787     TRACE_EVENT0("blink", "FrameView::layout");
    788     TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "Layout");
    789 
    790     // Protect the view from being deleted during layout (in recalcStyle)
    791     RefPtr<FrameView> protector(this);
    792 
    793     // Every scroll that happens during layout is programmatic.
    794     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
    795 
    796     if (m_autoSizeInfo)
    797         m_autoSizeInfo->autoSizeIfNeeded();
    798 
    799     m_hasPendingLayout = false;
    800     DocumentLifecycle::Scope lifecycleScope(lifecycle(), DocumentLifecycle::LayoutClean);
    801 
    802     RELEASE_ASSERT(!isPainting());
    803 
    804     TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Layout", "beginData", InspectorLayoutEvent::beginData(this));
    805     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
    806     // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
    807     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(m_frame.get());
    808 
    809     if (!allowSubtree && isSubtreeLayout()) {
    810         m_layoutSubtreeRoot->markContainingBlocksForLayout(false);
    811         m_layoutSubtreeRoot = 0;
    812     }
    813 
    814     performPreLayoutTasks();
    815 
    816     // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
    817     // so there's no point to continuing to layout
    818     if (protector->hasOneRef())
    819         return;
    820 
    821     Document* document = m_frame->document();
    822     bool inSubtreeLayout = isSubtreeLayout();
    823     RenderObject* rootForThisLayout = inSubtreeLayout ? m_layoutSubtreeRoot : document->renderView();
    824     if (!rootForThisLayout) {
    825         // FIXME: Do we need to set m_size here?
    826         ASSERT_NOT_REACHED();
    827         return;
    828     }
    829 
    830     FontCachePurgePreventer fontCachePurgePreventer;
    831     RenderLayer* layer;
    832     {
    833         TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
    834 
    835         m_nestedLayoutCount++;
    836         if (!inSubtreeLayout) {
    837             Document* document = m_frame->document();
    838             Node* body = document->body();
    839             if (body && body->renderer()) {
    840                 if (isHTMLFrameSetElement(*body)) {
    841                     body->renderer()->setChildNeedsLayout();
    842                 } else if (isHTMLBodyElement(*body)) {
    843                     if (!m_firstLayout && m_size.height() != layoutSize().height() && body->renderer()->enclosingBox()->stretchesToViewport())
    844                         body->renderer()->setChildNeedsLayout();
    845                 }
    846             }
    847         }
    848         updateCounters();
    849 
    850         ScrollbarMode hMode;
    851         ScrollbarMode vMode;
    852         calculateScrollbarModesForLayoutAndSetViewportRenderer(hMode, vMode);
    853 
    854         if (!inSubtreeLayout) {
    855             // Now set our scrollbar state for the layout.
    856             ScrollbarMode currentHMode = horizontalScrollbarMode();
    857             ScrollbarMode currentVMode = verticalScrollbarMode();
    858 
    859             if (m_firstLayout) {
    860                 setScrollbarsSuppressed(true);
    861 
    862                 m_doFullPaintInvalidation = true;
    863                 m_firstLayout = false;
    864                 m_firstLayoutCallbackPending = true;
    865                 m_lastViewportSize = layoutSize(IncludeScrollbars);
    866                 m_lastZoomFactor = rootForThisLayout->style()->zoom();
    867 
    868                 // Set the initial vMode to AlwaysOn if we're auto.
    869                 if (vMode == ScrollbarAuto)
    870                     setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
    871                 // Set the initial hMode to AlwaysOff if we're auto.
    872                 if (hMode == ScrollbarAuto)
    873                     setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
    874 
    875                 setScrollbarModes(hMode, vMode);
    876                 setScrollbarsSuppressed(false, true);
    877             } else if (hMode != currentHMode || vMode != currentVMode) {
    878                 setScrollbarModes(hMode, vMode);
    879             }
    880 
    881             LayoutSize oldSize = m_size;
    882 
    883             m_size = LayoutSize(layoutSize().width(), layoutSize().height());
    884 
    885             if (oldSize != m_size && !m_firstLayout) {
    886                 RenderBox* rootRenderer = document->documentElement() ? document->documentElement()->renderBox() : 0;
    887                 RenderBox* bodyRenderer = rootRenderer && document->body() ? document->body()->renderBox() : 0;
    888                 if (bodyRenderer && bodyRenderer->stretchesToViewport())
    889                     bodyRenderer->setChildNeedsLayout();
    890                 else if (rootRenderer && rootRenderer->stretchesToViewport())
    891                     rootRenderer->setChildNeedsLayout();
    892             }
    893 
    894             // We need to set m_doFullPaintInvalidation before triggering layout as RenderObject::checkForPaintInvalidation
    895             // checks the boolean to disable local paint invalidations.
    896             m_doFullPaintInvalidation |= renderView()->shouldDoFullPaintInvalidationForNextLayout();
    897         }
    898 
    899         layer = rootForThisLayout->enclosingLayer();
    900 
    901         performLayout(rootForThisLayout, inSubtreeLayout);
    902 
    903         m_layoutSubtreeRoot = 0;
    904         // We need to ensure that we mark up all renderers up to the RenderView
    905         // for paint invalidation. This simplifies our code as we just always
    906         // do a full tree walk.
    907         if (RenderObject* container = rootForThisLayout->container())
    908             container->setMayNeedPaintInvalidation(true);
    909     } // Reset m_layoutSchedulingEnabled to its previous value.
    910 
    911     if (!inSubtreeLayout && !toRenderView(rootForThisLayout)->document().printing())
    912         adjustViewSize();
    913 
    914     layer->updateLayerPositionsAfterLayout();
    915 
    916     renderView()->compositor()->didLayout();
    917 
    918     m_layoutCount++;
    919 
    920     if (AXObjectCache* cache = rootForThisLayout->document().axObjectCache()) {
    921         const KURL& url = rootForThisLayout->document().url();
    922         if (url.isValid() && !url.isAboutBlankURL())
    923             cache->handleLayoutComplete(rootForThisLayout);
    924     }
    925     updateAnnotatedRegions();
    926 
    927     ASSERT(!rootForThisLayout->needsLayout());
    928 
    929     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
    930         updateOverflowStatus(layoutSize().width() < contentsWidth(), layoutSize().height() < contentsHeight());
    931 
    932     scheduleOrPerformPostLayoutTasks();
    933 
    934     TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Layout", "endData", InspectorLayoutEvent::endData(rootForThisLayout));
    935     // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
    936     InspectorInstrumentation::didLayout(cookie, rootForThisLayout);
    937 
    938     m_nestedLayoutCount--;
    939     if (m_nestedLayoutCount)
    940         return;
    941 
    942 #if ENABLE(ASSERT)
    943     // Post-layout assert that nobody was re-marked as needing layout during layout.
    944     document->renderView()->assertSubtreeIsLaidOut();
    945 #endif
    946 
    947     // FIXME: It should be not possible to remove the FrameView from the frame/page during layout
    948     // however m_inPerformLayout is not set for most of this function, so none of our RELEASE_ASSERTS
    949     // in LocalFrame/Page will fire. One of the post-layout tasks is disconnecting the LocalFrame from
    950     // the page in fast/frames/crash-remove-iframe-during-object-beforeload-2.html
    951     // necessitating this check here.
    952     // ASSERT(frame()->page());
    953     if (frame().page())
    954         frame().page()->chrome().client().layoutUpdated(m_frame.get());
    955 }
    956 
    957 // The plan is to move to compositor-queried paint invalidation, in which case this
    958 // method would setNeedsRedraw on the GraphicsLayers with invalidations and
    959 // let the compositor pick which to actually draw.
    960 // See http://crbug.com/306706
    961 void FrameView::invalidateTreeIfNeeded()
    962 {
    963     ASSERT(renderView());
    964     RenderView& rootForPaintInvalidation = *renderView();
    965     ASSERT(!rootForPaintInvalidation.needsLayout());
    966 
    967     TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", rootForPaintInvalidation.debugName().ascii());
    968 
    969     PaintInvalidationState rootPaintInvalidationState(rootForPaintInvalidation);
    970 
    971     if (m_doFullPaintInvalidation)
    972         renderView()->compositor()->fullyInvalidatePaint();
    973 
    974     rootForPaintInvalidation.invalidateTreeIfNeeded(rootPaintInvalidationState);
    975 
    976     // Invalidate the paint of the frameviews scrollbars if needed
    977     if (hasVerticalBarDamage())
    978         invalidateRect(verticalBarDamage());
    979     if (hasHorizontalBarDamage())
    980         invalidateRect(horizontalBarDamage());
    981     resetScrollbarDamage();
    982 
    983 
    984 #ifndef NDEBUG
    985     renderView()->assertSubtreeClearedPaintInvalidationState();
    986 #endif
    987 
    988     if (m_frame->selection().isCaretBoundsDirty())
    989         m_frame->selection().invalidateCaretRect();
    990 }
    991 
    992 DocumentLifecycle& FrameView::lifecycle() const
    993 {
    994     return m_frame->document()->lifecycle();
    995 }
    996 
    997 void FrameView::gatherDebugLayoutRects(RenderObject* layoutRoot)
    998 {
    999     bool isTracing;
   1000     TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("blink.debug.layout"), &isTracing);
   1001     if (!isTracing)
   1002         return;
   1003     if (!layoutRoot->enclosingLayer()->hasCompositedLayerMapping())
   1004         return;
   1005     // For access to compositedLayerMapping().
   1006     DisableCompositingQueryAsserts disabler;
   1007     GraphicsLayer* graphicsLayer = layoutRoot->enclosingLayer()->compositedLayerMapping()->mainGraphicsLayer();
   1008     if (!graphicsLayer)
   1009         return;
   1010 
   1011     GraphicsLayerDebugInfo& debugInfo = graphicsLayer->debugInfo();
   1012 
   1013     debugInfo.currentLayoutRects().clear();
   1014     for (RenderObject* renderer = layoutRoot; renderer; renderer = renderer->nextInPreOrder()) {
   1015         if (renderer->layoutDidGetCalled()) {
   1016             FloatQuad quad = renderer->localToAbsoluteQuad(FloatQuad(renderer->previousPaintInvalidationRect()));
   1017             LayoutRect rect = quad.enclosingBoundingBox();
   1018             debugInfo.currentLayoutRects().append(rect);
   1019             renderer->setLayoutDidGetCalled(false);
   1020         }
   1021     }
   1022 }
   1023 
   1024 RenderBox* FrameView::embeddedContentBox() const
   1025 {
   1026     RenderView* renderView = this->renderView();
   1027     if (!renderView)
   1028         return 0;
   1029 
   1030     RenderObject* firstChild = renderView->firstChild();
   1031     if (!firstChild || !firstChild->isBox())
   1032         return 0;
   1033 
   1034     // Curently only embedded SVG documents participate in the size-negotiation logic.
   1035     if (firstChild->isSVGRoot())
   1036         return toRenderBox(firstChild);
   1037 
   1038     return 0;
   1039 }
   1040 
   1041 
   1042 void FrameView::addWidget(RenderWidget* object)
   1043 {
   1044     m_widgets.add(object);
   1045 }
   1046 
   1047 void FrameView::removeWidget(RenderWidget* object)
   1048 {
   1049     m_widgets.remove(object);
   1050 }
   1051 
   1052 void FrameView::updateWidgetPositions()
   1053 {
   1054     WillBeHeapVector<RefPtrWillBeMember<RenderWidget> > widgets;
   1055     copyToVector(m_widgets, widgets);
   1056 
   1057     // Script or plugins could detach the frame so abort processing if that happens.
   1058 
   1059     for (size_t i = 0; i < widgets.size() && renderView(); ++i)
   1060         widgets[i]->updateWidgetPosition();
   1061 
   1062     for (size_t i = 0; i < widgets.size() && renderView(); ++i)
   1063         widgets[i]->widgetPositionsUpdated();
   1064 }
   1065 
   1066 void FrameView::addWidgetToUpdate(RenderEmbeddedObject& object)
   1067 {
   1068     ASSERT(isInPerformLayout());
   1069     // Tell the DOM element that it needs a widget update.
   1070     Node* node = object.node();
   1071     ASSERT(node);
   1072     if (isHTMLObjectElement(*node) || isHTMLEmbedElement(*node))
   1073         toHTMLPlugInElement(node)->setNeedsWidgetUpdate(true);
   1074 
   1075     m_widgetUpdateSet.add(&object);
   1076 }
   1077 
   1078 void FrameView::setMediaType(const AtomicString& mediaType)
   1079 {
   1080     ASSERT(m_frame->document());
   1081     m_frame->document()->mediaQueryAffectingValueChanged();
   1082     m_mediaType = mediaType;
   1083 }
   1084 
   1085 AtomicString FrameView::mediaType() const
   1086 {
   1087     // See if we have an override type.
   1088     String overrideType;
   1089     InspectorInstrumentation::applyEmulatedMedia(m_frame.get(), &overrideType);
   1090     if (!overrideType.isNull())
   1091         return AtomicString(overrideType);
   1092     return m_mediaType;
   1093 }
   1094 
   1095 void FrameView::adjustMediaTypeForPrinting(bool printing)
   1096 {
   1097     if (printing) {
   1098         if (m_mediaTypeWhenNotPrinting.isNull())
   1099             m_mediaTypeWhenNotPrinting = mediaType();
   1100             setMediaType(MediaTypeNames::print);
   1101     } else {
   1102         if (!m_mediaTypeWhenNotPrinting.isNull())
   1103             setMediaType(m_mediaTypeWhenNotPrinting);
   1104         m_mediaTypeWhenNotPrinting = nullAtom;
   1105     }
   1106 }
   1107 
   1108 bool FrameView::contentsInCompositedLayer() const
   1109 {
   1110     RenderView* renderView = this->renderView();
   1111     if (renderView && renderView->compositingState() == PaintsIntoOwnBacking) {
   1112         GraphicsLayer* layer = renderView->layer()->compositedLayerMapping()->mainGraphicsLayer();
   1113         if (layer && layer->drawsContent())
   1114             return true;
   1115     }
   1116 
   1117     return false;
   1118 }
   1119 
   1120 void FrameView::addSlowRepaintObject()
   1121 {
   1122     if (!m_slowRepaintObjectCount++) {
   1123         if (Page* page = m_frame->page()) {
   1124             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   1125                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
   1126         }
   1127     }
   1128 }
   1129 
   1130 void FrameView::removeSlowRepaintObject()
   1131 {
   1132     ASSERT(m_slowRepaintObjectCount > 0);
   1133     m_slowRepaintObjectCount--;
   1134     if (!m_slowRepaintObjectCount) {
   1135         if (Page* page = m_frame->page()) {
   1136             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   1137                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
   1138         }
   1139     }
   1140 }
   1141 
   1142 void FrameView::addViewportConstrainedObject(RenderObject* object)
   1143 {
   1144     if (!m_viewportConstrainedObjects)
   1145         m_viewportConstrainedObjects = adoptPtr(new ViewportConstrainedObjectSet);
   1146 
   1147     if (!m_viewportConstrainedObjects->contains(object)) {
   1148         m_viewportConstrainedObjects->add(object);
   1149 
   1150         if (Page* page = m_frame->page()) {
   1151             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   1152                 scrollingCoordinator->frameViewFixedObjectsDidChange(this);
   1153         }
   1154     }
   1155 }
   1156 
   1157 void FrameView::removeViewportConstrainedObject(RenderObject* object)
   1158 {
   1159     if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->contains(object)) {
   1160         m_viewportConstrainedObjects->remove(object);
   1161 
   1162         if (Page* page = m_frame->page()) {
   1163             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   1164                 scrollingCoordinator->frameViewFixedObjectsDidChange(this);
   1165         }
   1166     }
   1167 }
   1168 
   1169 LayoutRect FrameView::viewportConstrainedVisibleContentRect() const
   1170 {
   1171     LayoutRect viewportRect = visibleContentRect();
   1172     // Ignore overhang. No-op when not using rubber banding.
   1173     viewportRect.setLocation(clampScrollPosition(scrollPosition()));
   1174     return viewportRect;
   1175 }
   1176 
   1177 void FrameView::viewportConstrainedVisibleContentSizeChanged(bool widthChanged, bool heightChanged)
   1178 {
   1179     if (!hasViewportConstrainedObjects())
   1180         return;
   1181 
   1182     // If viewport is not enabled, frameRect change will cause layout size change and then layout.
   1183     // Otherwise, viewport constrained objects need their layout flags set separately to ensure
   1184     // they are positioned correctly. In the virtual-viewport pinch mode frame rect changes wont
   1185     // necessarily cause a layout size change so only take this early-out if we're in old-style
   1186     // pinch.
   1187     if (m_frame->settings()
   1188         && !m_frame->settings()->viewportEnabled()
   1189         && !m_frame->settings()->pinchVirtualViewportEnabled())
   1190         return;
   1191 
   1192     ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
   1193     for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
   1194         RenderObject* renderer = *it;
   1195         RenderStyle* style = renderer->style();
   1196         if (widthChanged) {
   1197             if (style->width().isFixed() && (style->left().isAuto() || style->right().isAuto()))
   1198                 renderer->setNeedsPositionedMovementLayout();
   1199             else
   1200                 renderer->setNeedsLayoutAndFullPaintInvalidation();
   1201         }
   1202         if (heightChanged) {
   1203             if (style->height().isFixed() && (style->top().isAuto() || style->bottom().isAuto()))
   1204                 renderer->setNeedsPositionedMovementLayout();
   1205             else
   1206                 renderer->setNeedsLayoutAndFullPaintInvalidation();
   1207         }
   1208     }
   1209 }
   1210 
   1211 IntSize FrameView::scrollOffsetForFixedPosition() const
   1212 {
   1213     return toIntSize(clampScrollPosition(scrollPosition()));
   1214 }
   1215 
   1216 IntPoint FrameView::lastKnownMousePosition() const
   1217 {
   1218     return m_frame->eventHandler().lastKnownMousePosition();
   1219 }
   1220 
   1221 bool FrameView::shouldSetCursor() const
   1222 {
   1223     Page* page = frame().page();
   1224     return page && page->visibilityState() != PageVisibilityStateHidden && page->focusController().isActive() && page->settings().deviceSupportsMouse();
   1225 }
   1226 
   1227 void FrameView::scrollContentsIfNeededRecursive()
   1228 {
   1229     scrollContentsIfNeeded();
   1230 
   1231     for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
   1232         if (!child->isLocalFrame())
   1233             continue;
   1234         if (FrameView* view = toLocalFrame(child)->view())
   1235             view->scrollContentsIfNeededRecursive();
   1236     }
   1237 }
   1238 
   1239 void FrameView::scrollContentsIfNeeded()
   1240 {
   1241     bool didScroll = !pendingScrollDelta().isZero();
   1242     ScrollView::scrollContentsIfNeeded();
   1243     if (didScroll)
   1244         updateFixedElementPaintInvalidationRectsAfterScroll();
   1245 }
   1246 
   1247 static LayoutRect paintInvalidationRectIncludingNonCompositingDescendants(const RenderLayer* layer)
   1248 {
   1249     LayoutRect paintInvalidationRect = layer->renderer()->previousPaintInvalidationRect();
   1250 
   1251     for (const RenderLayer* child = layer->firstChild(); child; child = child->nextSibling()) {
   1252         // Don't include paint invalidation rects for composited child layers; they will paint themselves and have a different origin.
   1253         if (child->compositingState() == PaintsIntoOwnBacking || child->compositingState() == PaintsIntoGroupedBacking)
   1254             continue;
   1255 
   1256         paintInvalidationRect.unite(paintInvalidationRectIncludingNonCompositingDescendants(child));
   1257     }
   1258     return paintInvalidationRect;
   1259 }
   1260 
   1261 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta)
   1262 {
   1263     if (!contentsInCompositedLayer() || hasSlowRepaintObjects())
   1264         return false;
   1265 
   1266     if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty()) {
   1267         InspectorInstrumentation::didScroll(page());
   1268         return true;
   1269     }
   1270 
   1271     Region regionToUpdate;
   1272     ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
   1273     for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
   1274         RenderObject* renderer = *it;
   1275         ASSERT(renderer->style()->hasViewportConstrainedPosition());
   1276         ASSERT(renderer->hasLayer());
   1277         RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
   1278 
   1279         CompositingState state = layer->compositingState();
   1280         if (state == PaintsIntoOwnBacking || state == PaintsIntoGroupedBacking)
   1281             continue;
   1282 
   1283         if (layer->subtreeIsInvisible())
   1284             continue;
   1285 
   1286         // If the fixed layer has a blur/drop-shadow filter applied on at least one of its parents, we cannot
   1287         // scroll using the fast path, otherwise the outsets of the filter will be moved around the page.
   1288         if (layer->hasAncestorWithFilterOutsets())
   1289             return false;
   1290 
   1291         IntRect updateRect = pixelSnappedIntRect(paintInvalidationRectIncludingNonCompositingDescendants(layer));
   1292 
   1293         const RenderLayerModelObject* repaintContainer = layer->renderer()->containerForPaintInvalidation();
   1294         if (repaintContainer && !repaintContainer->isRenderView()) {
   1295             // Invalidate the old and new locations of fixed position elements that are not drawn into the RenderView.
   1296             updateRect.moveBy(scrollPosition());
   1297             IntRect previousRect = updateRect;
   1298             previousRect.move(scrollDelta);
   1299             // FIXME: Rather than uniting the rects, we should just issue both invalidations.
   1300             updateRect.unite(previousRect);
   1301             layer->renderer()->invalidatePaintUsingContainer(repaintContainer, updateRect, InvalidationScroll);
   1302         } else {
   1303             // Coalesce the paint invalidations that will be issued to the renderView.
   1304             updateRect = contentsToRootView(updateRect);
   1305             if (!updateRect.isEmpty())
   1306                 regionToUpdate.unite(updateRect);
   1307         }
   1308     }
   1309 
   1310     InspectorInstrumentation::didScroll(page());
   1311 
   1312     // Invalidate the old and new locations of fixed position elements that are drawn into the RenderView.
   1313     Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
   1314     size_t viewportConstrainedObjectsCount = subRectsToUpdate.size();
   1315     for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) {
   1316         IntRect updateRect = subRectsToUpdate[i];
   1317         IntRect scrolledRect = updateRect;
   1318         scrolledRect.move(-scrollDelta);
   1319         updateRect.unite(scrolledRect);
   1320         // FIXME: We should be able to issue these invalidations separately and before we actually scroll.
   1321         renderView()->setBackingNeedsPaintInvalidationInRect(rootViewToContents(updateRect));
   1322     }
   1323 
   1324     return true;
   1325 }
   1326 
   1327 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
   1328 {
   1329     if (contentsInCompositedLayer()) {
   1330         IntRect updateRect = visibleContentRect();
   1331         ASSERT(renderView());
   1332         renderView()->invalidatePaintRectangle(updateRect);
   1333     }
   1334     if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
   1335         if (isEnclosedInCompositingLayer()) {
   1336             LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
   1337                             frameRenderer->borderTop() + frameRenderer->paddingTop(),
   1338                             visibleWidth(), visibleHeight());
   1339             frameRenderer->invalidatePaintRectangle(rect);
   1340             return;
   1341         }
   1342     }
   1343 
   1344     ScrollView::scrollContentsSlowPath(updateRect);
   1345 }
   1346 
   1347 void FrameView::restoreScrollbar()
   1348 {
   1349     setScrollbarsSuppressed(false);
   1350 }
   1351 
   1352 bool FrameView::scrollToFragment(const KURL& url)
   1353 {
   1354     // If our URL has no ref, then we have no place we need to jump to.
   1355     // OTOH If CSS target was set previously, we want to set it to 0, recalc
   1356     // and possibly paint invalidation because :target pseudo class may have been
   1357     // set (see bug 11321).
   1358     if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget())
   1359         return false;
   1360 
   1361     String fragmentIdentifier = url.fragmentIdentifier();
   1362     if (scrollToAnchor(fragmentIdentifier))
   1363         return true;
   1364 
   1365     // Try again after decoding the ref, based on the document's encoding.
   1366     if (m_frame->document()->encoding().isValid())
   1367         return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, m_frame->document()->encoding()));
   1368 
   1369     return false;
   1370 }
   1371 
   1372 bool FrameView::scrollToAnchor(const String& name)
   1373 {
   1374     ASSERT(m_frame->document());
   1375 
   1376     if (!m_frame->document()->isRenderingReady()) {
   1377         m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
   1378         return false;
   1379     }
   1380 
   1381     m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false);
   1382 
   1383     Element* anchorNode = m_frame->document()->findAnchor(name);
   1384 
   1385     // Setting to null will clear the current target.
   1386     m_frame->document()->setCSSTarget(anchorNode);
   1387 
   1388     if (m_frame->document()->isSVGDocument()) {
   1389         if (SVGSVGElement* svg = SVGDocumentExtensions::rootElement(*m_frame->document())) {
   1390             svg->setupInitialView(name, anchorNode);
   1391             if (!anchorNode)
   1392                 return true;
   1393         }
   1394     }
   1395 
   1396     // Implement the rule that "" and "top" both mean top of page as in other browsers.
   1397     if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top")))
   1398         return false;
   1399 
   1400     maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document());
   1401 
   1402     // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
   1403     // If anchorNode is not focusable, setFocusedElement() will still clear focus, which matches the behavior of other browsers.
   1404     if (anchorNode)
   1405         m_frame->document()->setFocusedElement(anchorNode);
   1406 
   1407     return true;
   1408 }
   1409 
   1410 void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
   1411 {
   1412     m_maintainScrollPositionAnchor = anchorNode;
   1413     if (!m_maintainScrollPositionAnchor)
   1414         return;
   1415 
   1416     // We need to update the layout before scrolling, otherwise we could
   1417     // really mess things up if an anchor scroll comes at a bad moment.
   1418     m_frame->document()->updateRenderTreeIfNeeded();
   1419     // Only do a layout if changes have occurred that make it necessary.
   1420     RenderView* renderView = this->renderView();
   1421     if (renderView && renderView->needsLayout())
   1422         layout();
   1423     else
   1424         scrollToAnchor();
   1425 }
   1426 
   1427 void FrameView::scrollElementToRect(Element* element, const IntRect& rect)
   1428 {
   1429     // FIXME(http://crbug.com/371896) - This method shouldn't be manually doing
   1430     // coordinate transformations to the PinchViewport.
   1431     IntRect targetRect(rect);
   1432 
   1433     m_frame->document()->updateLayoutIgnorePendingStylesheets();
   1434 
   1435     bool pinchVirtualViewportEnabled = m_frame->settings()->pinchVirtualViewportEnabled();
   1436 
   1437     if (pinchVirtualViewportEnabled) {
   1438         PinchViewport& pinchViewport = m_frame->page()->frameHost().pinchViewport();
   1439 
   1440         IntSize pinchViewportSize = expandedIntSize(pinchViewport.visibleRect().size());
   1441         targetRect.moveBy(ceiledIntPoint(pinchViewport.visibleRect().location()));
   1442         targetRect.setSize(pinchViewportSize.shrunkTo(targetRect.size()));
   1443     }
   1444 
   1445     LayoutRect bounds = element->boundingBox();
   1446     int centeringOffsetX = (targetRect.width() - bounds.width()) / 2;
   1447     int centeringOffsetY = (targetRect.height() - bounds.height()) / 2;
   1448 
   1449     IntPoint targetOffset(
   1450         bounds.x() - centeringOffsetX - targetRect.x(),
   1451         bounds.y() - centeringOffsetY - targetRect.y());
   1452 
   1453     setScrollPosition(targetOffset);
   1454 
   1455     if (pinchVirtualViewportEnabled) {
   1456         IntPoint remainder = IntPoint(targetOffset - scrollPosition());
   1457         m_frame->page()->frameHost().pinchViewport().move(remainder);
   1458     }
   1459 }
   1460 
   1461 void FrameView::setScrollPosition(const IntPoint& scrollPoint, ScrollBehavior scrollBehavior)
   1462 {
   1463     cancelProgrammaticScrollAnimation();
   1464     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
   1465     m_maintainScrollPositionAnchor = nullptr;
   1466 
   1467     IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
   1468 
   1469     if (newScrollPosition == scrollPosition())
   1470         return;
   1471 
   1472     if (scrollBehavior == ScrollBehaviorAuto) {
   1473         RenderObject* renderer = m_frame->document()->documentElement() ? m_frame->document()->documentElement()->renderer() : 0;
   1474         if (renderer)
   1475             scrollBehavior = renderer->style()->scrollBehavior();
   1476         else
   1477             scrollBehavior = ScrollBehaviorInstant;
   1478     }
   1479     ScrollView::setScrollPosition(newScrollPosition, scrollBehavior);
   1480 }
   1481 
   1482 void FrameView::setScrollPositionNonProgrammatically(const IntPoint& scrollPoint)
   1483 {
   1484     IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
   1485 
   1486     if (newScrollPosition == scrollPosition())
   1487         return;
   1488 
   1489     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, false);
   1490     notifyScrollPositionChanged(newScrollPosition);
   1491 }
   1492 
   1493 IntSize FrameView::layoutSize(IncludeScrollbarsInRect scrollbarInclusion) const
   1494 {
   1495     return scrollbarInclusion == ExcludeScrollbars ? excludeScrollbars(m_layoutSize) : m_layoutSize;
   1496 }
   1497 
   1498 void FrameView::setLayoutSize(const IntSize& size)
   1499 {
   1500     ASSERT(!layoutSizeFixedToFrameSize());
   1501 
   1502     setLayoutSizeInternal(size);
   1503 }
   1504 
   1505 void FrameView::scrollPositionChanged()
   1506 {
   1507     setWasScrolledByUser(true);
   1508 
   1509     Document* document = m_frame->document();
   1510     document->enqueueScrollEventForNode(document);
   1511 
   1512     m_frame->eventHandler().dispatchFakeMouseMoveEventSoon();
   1513 
   1514     if (RenderView* renderView = document->renderView()) {
   1515         if (renderView->usesCompositing())
   1516             renderView->compositor()->frameViewDidScroll();
   1517     }
   1518 
   1519     if (m_didScrollTimer.isActive())
   1520         m_didScrollTimer.stop();
   1521     m_didScrollTimer.startOneShot(resourcePriorityUpdateDelayAfterScroll, FROM_HERE);
   1522 
   1523     if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
   1524         cache->handleScrollPositionChanged(this);
   1525 
   1526     frame().loader().saveScrollState();
   1527 }
   1528 
   1529 void FrameView::didScrollTimerFired(Timer<FrameView>*)
   1530 {
   1531     if (m_frame->document() && m_frame->document()->renderView()) {
   1532         ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllImageResourcePriorities();
   1533     }
   1534 }
   1535 
   1536 void FrameView::updateLayersAndCompositingAfterScrollIfNeeded()
   1537 {
   1538     // Nothing to do after scrolling if there are no fixed position elements.
   1539     if (!hasViewportConstrainedObjects())
   1540         return;
   1541 
   1542     RefPtr<FrameView> protect(this);
   1543 
   1544     // If there fixed position elements, scrolling may cause compositing layers to change.
   1545     // Update widget and layer positions after scrolling, but only if we're not inside of
   1546     // layout.
   1547     if (!m_nestedLayoutCount) {
   1548         updateWidgetPositions();
   1549         if (RenderView* renderView = this->renderView())
   1550             renderView->layer()->setNeedsCompositingInputsUpdate();
   1551     }
   1552 }
   1553 
   1554 bool FrameView::computeCompositedSelectionBounds(LocalFrame& frame, CompositedSelectionBound& start, CompositedSelectionBound& end)
   1555 {
   1556     const VisibleSelection &selection = frame.selection().selection();
   1557     if (!selection.isCaretOrRange())
   1558         return false;
   1559 
   1560     VisiblePosition visibleStart(selection.visibleStart());
   1561     VisiblePosition visibleEnd(selection.visibleEnd());
   1562 
   1563     RenderedPosition renderedStart(visibleStart);
   1564     RenderedPosition renderedEnd(visibleEnd);
   1565 
   1566     renderedStart.positionInGraphicsLayerBacking(start);
   1567     if (!start.layer)
   1568         return false;
   1569 
   1570     renderedEnd.positionInGraphicsLayerBacking(end);
   1571     if (!end.layer)
   1572         return false;
   1573 
   1574     if (selection.isCaret()) {
   1575         start.type = end.type = CompositedSelectionBound::Caret;
   1576         return true;
   1577     }
   1578 
   1579     TextDirection startDir = visibleStart.deepEquivalent().primaryDirection();
   1580     TextDirection endDir = visibleEnd.deepEquivalent().primaryDirection();
   1581     start.type = startDir == RTL ? CompositedSelectionBound::SelectionRight : CompositedSelectionBound::SelectionLeft;
   1582     end.type = endDir == RTL ? CompositedSelectionBound::SelectionLeft : CompositedSelectionBound::SelectionRight;
   1583     return true;
   1584 }
   1585 
   1586 static void computePaintInvalidationRectsIncludingNonCompositingDescendants(RenderLayer* layer)
   1587 {
   1588     // FIXME: boundsRectForPaintInvalidation() has to walk up the parent chain
   1589     // for every layer to compute the rects. We should make this more efficient.
   1590     // FIXME: it's wrong to call this when layout is not up-to-date, which we do.
   1591     layer->renderer()->setPreviousPaintInvalidationRect(layer->renderer()->boundsRectForPaintInvalidation(layer->renderer()->containerForPaintInvalidation()));
   1592     // FIXME: We are only updating the paint invalidation bounds but not
   1593     // the positionFromPaintInvalidationContainer. This means that we may
   1594     // forcing a full invaliation of the new position. Is this really correct?
   1595 
   1596     for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling()) {
   1597         if (child->compositingState() != PaintsIntoOwnBacking && child->compositingState() != PaintsIntoGroupedBacking)
   1598             computePaintInvalidationRectsIncludingNonCompositingDescendants(child);
   1599     }
   1600 }
   1601 
   1602 void FrameView::updateFixedElementPaintInvalidationRectsAfterScroll()
   1603 {
   1604     if (!hasViewportConstrainedObjects())
   1605         return;
   1606 
   1607     // Update the paint invalidation rects for fixed elements after scrolling and invalidation to reflect
   1608     // the new scroll position.
   1609     ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
   1610     for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
   1611         RenderObject* renderer = *it;
   1612         // m_viewportConstrainedObjects should not contain non-viewport constrained objects.
   1613         ASSERT(renderer->style()->hasViewportConstrainedPosition());
   1614 
   1615         // Fixed items should always have layers.
   1616         ASSERT(renderer->hasLayer());
   1617 
   1618         RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
   1619 
   1620         // Don't need to do this for composited fixed items.
   1621         if (layer->compositingState() == PaintsIntoOwnBacking)
   1622             continue;
   1623 
   1624         computePaintInvalidationRectsIncludingNonCompositingDescendants(layer);
   1625     }
   1626 }
   1627 
   1628 void FrameView::updateCompositedSelectionBoundsIfNeeded()
   1629 {
   1630     if (!RuntimeEnabledFeatures::compositedSelectionUpdateEnabled())
   1631         return;
   1632 
   1633     Page* page = frame().page();
   1634     ASSERT(page);
   1635 
   1636     CompositedSelectionBound start, end;
   1637     LocalFrame* frame = toLocalFrame(page->focusController().focusedOrMainFrame());
   1638     if (!frame || !computeCompositedSelectionBounds(*frame, start, end)) {
   1639         page->chrome().client().clearCompositedSelectionBounds();
   1640         return;
   1641     }
   1642 
   1643     page->chrome().client().updateCompositedSelectionBounds(start, end);
   1644 }
   1645 
   1646 bool FrameView::isRubberBandInProgress() const
   1647 {
   1648     if (scrollbarsSuppressed())
   1649         return false;
   1650 
   1651     // If the main thread updates the scroll position for this FrameView, we should return
   1652     // ScrollAnimator::isRubberBandInProgress().
   1653     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
   1654         return scrollAnimator->isRubberBandInProgress();
   1655 
   1656     return false;
   1657 }
   1658 
   1659 HostWindow* FrameView::hostWindow() const
   1660 {
   1661     Page* page = frame().page();
   1662     if (!page)
   1663         return 0;
   1664     return &page->chrome();
   1665 }
   1666 
   1667 void FrameView::contentRectangleForPaintInvalidation(const IntRect& r)
   1668 {
   1669     ASSERT(paintInvalidationIsAllowed());
   1670     ASSERT(!m_frame->ownerRenderer());
   1671 
   1672     if (m_isTrackingPaintInvalidations) {
   1673         IntRect paintInvalidationRect = r;
   1674         paintInvalidationRect.move(-scrollOffset());
   1675         m_trackedPaintInvalidationRects.append(paintInvalidationRect);
   1676         // FIXME: http://crbug.com/368518. Eventually, invalidateContentRectangleForPaint
   1677         // is going away entirely once all layout tests are FCM. In the short
   1678         // term, no code should be tracking non-composited FrameView paint invalidations.
   1679         RELEASE_ASSERT_NOT_REACHED();
   1680     }
   1681 
   1682     ScrollView::contentRectangleForPaintInvalidation(r);
   1683 }
   1684 
   1685 void FrameView::contentsResized()
   1686 {
   1687     if (m_frame->isMainFrame() && m_frame->document()) {
   1688         if (TextAutosizer* textAutosizer = m_frame->document()->textAutosizer())
   1689             textAutosizer->updatePageInfoInAllFrames();
   1690     }
   1691 
   1692     ScrollView::contentsResized();
   1693     setNeedsLayout();
   1694 }
   1695 
   1696 void FrameView::scrollbarExistenceDidChange()
   1697 {
   1698     // We check to make sure the view is attached to a frame() as this method can
   1699     // be triggered before the view is attached by LocalFrame::createView(...) setting
   1700     // various values such as setScrollBarModes(...) for example.  An ASSERT is
   1701     // triggered when a view is layout before being attached to a frame().
   1702     if (!frame().view())
   1703         return;
   1704 
   1705     // Note that simply having overlay scrollbars is not sufficient to be
   1706     // certain that scrollbars' presence does not impact layout. This should
   1707     // also check if custom scrollbars (as reported by shouldUseCustomScrollbars)
   1708     // are in use as well.
   1709     // http://crbug.com/269692
   1710     bool useOverlayScrollbars = ScrollbarTheme::theme()->usesOverlayScrollbars();
   1711 
   1712     // FIXME: this call to layout() could be called within FrameView::layout(), but before performLayout(),
   1713     // causing double-layout. See also crbug.com/429242.
   1714     if (!useOverlayScrollbars && needsLayout())
   1715         layout();
   1716 
   1717     if (renderView() && renderView()->usesCompositing()) {
   1718         renderView()->compositor()->frameViewScrollbarsExistenceDidChange();
   1719 
   1720         if (!useOverlayScrollbars)
   1721             renderView()->compositor()->frameViewDidChangeSize();
   1722     }
   1723 }
   1724 
   1725 void FrameView::handleLoadCompleted()
   1726 {
   1727     // Once loading has completed, allow autoSize one last opportunity to
   1728     // reduce the size of the frame.
   1729     if (m_autoSizeInfo)
   1730         m_autoSizeInfo->autoSizeIfNeeded();
   1731 }
   1732 
   1733 void FrameView::scheduleRelayout()
   1734 {
   1735     ASSERT(m_frame->view() == this);
   1736 
   1737     if (isSubtreeLayout()) {
   1738         m_layoutSubtreeRoot->markContainingBlocksForLayout(false);
   1739         m_layoutSubtreeRoot = 0;
   1740     }
   1741     if (!m_layoutSchedulingEnabled)
   1742         return;
   1743     if (!needsLayout())
   1744         return;
   1745     if (!m_frame->document()->shouldScheduleLayout())
   1746         return;
   1747     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "InvalidateLayout", "frame", m_frame.get());
   1748     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
   1749     // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
   1750     InspectorInstrumentation::didInvalidateLayout(m_frame.get());
   1751 
   1752     if (m_hasPendingLayout)
   1753         return;
   1754     m_hasPendingLayout = true;
   1755 
   1756     page()->animator().scheduleVisualUpdate();
   1757     lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean);
   1758 }
   1759 
   1760 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
   1761 {
   1762     for (RenderObject* r = descendant; r; r = r->container()) {
   1763         if (r == ancestor)
   1764             return true;
   1765     }
   1766     return false;
   1767 }
   1768 
   1769 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
   1770 {
   1771     ASSERT(m_frame->view() == this);
   1772 
   1773     // FIXME: Should this call shouldScheduleLayout instead?
   1774     if (!m_frame->document()->isActive())
   1775         return;
   1776 
   1777     RenderView* renderView = this->renderView();
   1778     if (renderView && renderView->needsLayout()) {
   1779         if (relayoutRoot)
   1780             relayoutRoot->markContainingBlocksForLayout(false);
   1781         return;
   1782     }
   1783 
   1784     if (layoutPending() || !m_layoutSchedulingEnabled) {
   1785         if (m_layoutSubtreeRoot != relayoutRoot) {
   1786             if (isObjectAncestorContainerOf(m_layoutSubtreeRoot, relayoutRoot)) {
   1787                 // Keep the current root
   1788                 relayoutRoot->markContainingBlocksForLayout(false, m_layoutSubtreeRoot);
   1789                 ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
   1790             } else if (isSubtreeLayout() && isObjectAncestorContainerOf(relayoutRoot, m_layoutSubtreeRoot)) {
   1791                 // Re-root at relayoutRoot
   1792                 m_layoutSubtreeRoot->markContainingBlocksForLayout(false, relayoutRoot);
   1793                 m_layoutSubtreeRoot = relayoutRoot;
   1794                 ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
   1795             } else {
   1796                 // Just do a full relayout
   1797                 if (isSubtreeLayout())
   1798                     m_layoutSubtreeRoot->markContainingBlocksForLayout(false);
   1799                 m_layoutSubtreeRoot = 0;
   1800                 relayoutRoot->markContainingBlocksForLayout(false);
   1801             }
   1802         }
   1803     } else if (m_layoutSchedulingEnabled) {
   1804         m_layoutSubtreeRoot = relayoutRoot;
   1805         ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
   1806         m_hasPendingLayout = true;
   1807 
   1808         page()->animator().scheduleVisualUpdate();
   1809         lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean);
   1810     }
   1811     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "InvalidateLayout", "frame", m_frame.get());
   1812     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
   1813     // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
   1814     InspectorInstrumentation::didInvalidateLayout(m_frame.get());
   1815 }
   1816 
   1817 bool FrameView::layoutPending() const
   1818 {
   1819     // FIXME: This should check Document::lifecycle instead.
   1820     return m_hasPendingLayout;
   1821 }
   1822 
   1823 bool FrameView::isInPerformLayout() const
   1824 {
   1825     ASSERT(m_inPerformLayout == (lifecycle().state() == DocumentLifecycle::InPerformLayout));
   1826     return m_inPerformLayout;
   1827 }
   1828 
   1829 bool FrameView::needsLayout() const
   1830 {
   1831     // This can return true in cases where the document does not have a body yet.
   1832     // Document::shouldScheduleLayout takes care of preventing us from scheduling
   1833     // layout in that case.
   1834 
   1835     RenderView* renderView = this->renderView();
   1836     return layoutPending()
   1837         || (renderView && renderView->needsLayout())
   1838         || isSubtreeLayout();
   1839 }
   1840 
   1841 void FrameView::setNeedsLayout()
   1842 {
   1843     if (RenderView* renderView = this->renderView())
   1844         renderView->setNeedsLayout();
   1845 }
   1846 
   1847 bool FrameView::isTransparent() const
   1848 {
   1849     return m_isTransparent;
   1850 }
   1851 
   1852 void FrameView::setTransparent(bool isTransparent)
   1853 {
   1854     m_isTransparent = isTransparent;
   1855     DisableCompositingQueryAsserts disabler;
   1856     if (renderView() && renderView()->layer()->hasCompositedLayerMapping())
   1857         renderView()->layer()->compositedLayerMapping()->updateContentsOpaque();
   1858 }
   1859 
   1860 bool FrameView::hasOpaqueBackground() const
   1861 {
   1862     return !m_isTransparent && !m_baseBackgroundColor.hasAlpha();
   1863 }
   1864 
   1865 Color FrameView::baseBackgroundColor() const
   1866 {
   1867     return m_baseBackgroundColor;
   1868 }
   1869 
   1870 void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
   1871 {
   1872     m_baseBackgroundColor = backgroundColor;
   1873 
   1874     if (renderView() && renderView()->layer()->hasCompositedLayerMapping()) {
   1875         CompositedLayerMapping* compositedLayerMapping = renderView()->layer()->compositedLayerMapping();
   1876         compositedLayerMapping->updateContentsOpaque();
   1877         if (compositedLayerMapping->mainGraphicsLayer())
   1878             compositedLayerMapping->mainGraphicsLayer()->setNeedsDisplay();
   1879     }
   1880     recalculateScrollbarOverlayStyle();
   1881 }
   1882 
   1883 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
   1884 {
   1885     for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
   1886         if (!frame->isLocalFrame())
   1887             continue;
   1888         if (FrameView* view = toLocalFrame(frame)->view()) {
   1889             view->setTransparent(transparent);
   1890             view->setBaseBackgroundColor(backgroundColor);
   1891         }
   1892     }
   1893 }
   1894 
   1895 void FrameView::scrollToAnchor()
   1896 {
   1897     RefPtrWillBeRawPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
   1898     if (!anchorNode)
   1899         return;
   1900 
   1901     if (!anchorNode->renderer())
   1902         return;
   1903 
   1904     LayoutRect rect;
   1905     if (anchorNode != m_frame->document())
   1906         rect = anchorNode->boundingBox();
   1907 
   1908     RefPtrWillBeRawPtr<LocalFrame> boundaryFrame = m_frame->document()->findUnsafeParentScrollPropagationBoundary();
   1909 
   1910     if (boundaryFrame)
   1911         boundaryFrame->view()->setSafeToPropagateScrollToParent(false);
   1912 
   1913     // Scroll nested layers and frames to reveal the anchor.
   1914     // Align to the top and to the closest side (this matches other browsers).
   1915     anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
   1916 
   1917     if (boundaryFrame)
   1918         boundaryFrame->view()->setSafeToPropagateScrollToParent(true);
   1919 
   1920     if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
   1921         cache->handleScrolledToAnchor(anchorNode.get());
   1922 
   1923     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
   1924     m_maintainScrollPositionAnchor = anchorNode;
   1925 }
   1926 
   1927 bool FrameView::updateWidgets()
   1928 {
   1929     // This is always called from updateWidgetsTimerFired.
   1930     // m_updateWidgetsTimer should only be scheduled if we have widgets to update.
   1931     // Thus I believe we can stop checking isEmpty here, and just ASSERT isEmpty:
   1932     ASSERT(!m_widgetUpdateSet.isEmpty());
   1933     if (m_nestedLayoutCount > 1 || m_widgetUpdateSet.isEmpty())
   1934         return true;
   1935 
   1936     // Need to swap because script will run inside the below loop and invalidate the iterator.
   1937     EmbeddedObjectSet objects;
   1938     objects.swap(m_widgetUpdateSet);
   1939 
   1940     for (EmbeddedObjectSet::iterator it = objects.begin(); it != objects.end(); ++it) {
   1941         RenderEmbeddedObject& object = **it;
   1942         HTMLPlugInElement* element = toHTMLPlugInElement(object.node());
   1943 
   1944         // The object may have already been destroyed (thus node cleared),
   1945         // but FrameView holds a manual ref, so it won't have been deleted.
   1946         if (!element)
   1947             continue;
   1948 
   1949         // No need to update if it's already crashed or known to be missing.
   1950         if (object.showsUnavailablePluginIndicator())
   1951             continue;
   1952 
   1953         if (element->needsWidgetUpdate())
   1954             element->updateWidget();
   1955         object.updateWidgetPosition();
   1956 
   1957         // Prevent plugins from causing infinite updates of themselves.
   1958         // FIXME: Do we really need to prevent this?
   1959         m_widgetUpdateSet.remove(&object);
   1960     }
   1961 
   1962     return m_widgetUpdateSet.isEmpty();
   1963 }
   1964 
   1965 void FrameView::updateWidgetsTimerFired(Timer<FrameView>*)
   1966 {
   1967     ASSERT(!isInPerformLayout());
   1968     RefPtr<FrameView> protect(this);
   1969     m_updateWidgetsTimer.stop();
   1970     for (unsigned i = 0; i < maxUpdateWidgetsIterations; ++i) {
   1971         if (updateWidgets())
   1972             return;
   1973     }
   1974 }
   1975 
   1976 void FrameView::flushAnyPendingPostLayoutTasks()
   1977 {
   1978     ASSERT(!isInPerformLayout());
   1979     if (m_postLayoutTasksTimer.isActive())
   1980         performPostLayoutTasks();
   1981     if (m_updateWidgetsTimer.isActive())
   1982         updateWidgetsTimerFired(0);
   1983 }
   1984 
   1985 void FrameView::scheduleUpdateWidgetsIfNecessary()
   1986 {
   1987     ASSERT(!isInPerformLayout());
   1988     if (m_updateWidgetsTimer.isActive() || m_widgetUpdateSet.isEmpty())
   1989         return;
   1990     m_updateWidgetsTimer.startOneShot(0, FROM_HERE);
   1991 }
   1992 
   1993 void FrameView::performPostLayoutTasks()
   1994 {
   1995     // FIXME: We can reach here, even when the page is not active!
   1996     // http/tests/inspector/elements/html-link-import.html and many other
   1997     // tests hit that case.
   1998     // We should ASSERT(isActive()); or at least return early if we can!
   1999     ASSERT(!isInPerformLayout()); // Always before or after performLayout(), part of the highest-level layout() call.
   2000     TRACE_EVENT0("blink", "FrameView::performPostLayoutTasks");
   2001     RefPtr<FrameView> protect(this);
   2002 
   2003     m_postLayoutTasksTimer.stop();
   2004 
   2005     m_frame->selection().setCaretRectNeedsUpdate();
   2006 
   2007     {
   2008         // Hits in compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html
   2009         DisableCompositingQueryAsserts disabler;
   2010         m_frame->selection().updateAppearance();
   2011     }
   2012 
   2013     ASSERT(m_frame->document());
   2014     if (m_nestedLayoutCount <= 1) {
   2015         if (m_firstLayoutCallbackPending)
   2016             m_firstLayoutCallbackPending = false;
   2017 
   2018         // Ensure that we always send this eventually.
   2019         if (!m_frame->document()->parsing() && m_frame->loader().stateMachine()->committedFirstRealDocumentLoad())
   2020             m_isVisuallyNonEmpty = true;
   2021 
   2022         // If the layout was done with pending sheets, we are not in fact visually non-empty yet.
   2023         if (m_isVisuallyNonEmpty && !m_frame->document()->didLayoutWithPendingStylesheets() && m_firstVisuallyNonEmptyLayoutCallbackPending) {
   2024             m_firstVisuallyNonEmptyLayoutCallbackPending = false;
   2025             // FIXME: This callback is probably not needed, but is currently used
   2026             // by android for setting the background color.
   2027             m_frame->loader().client()->dispatchDidFirstVisuallyNonEmptyLayout();
   2028         }
   2029     }
   2030 
   2031     FontFaceSet::didLayout(*m_frame->document());
   2032 
   2033     updateWidgetPositions();
   2034 
   2035     // Plugins could have torn down the page inside updateWidgetPositions().
   2036     if (!renderView())
   2037         return;
   2038 
   2039     scheduleUpdateWidgetsIfNecessary();
   2040 
   2041     if (Page* page = m_frame->page()) {
   2042         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   2043             scrollingCoordinator->notifyLayoutUpdated();
   2044     }
   2045 
   2046     scrollToAnchor();
   2047 
   2048     sendResizeEventIfNeeded();
   2049 }
   2050 
   2051 bool FrameView::wasViewportResized()
   2052 {
   2053     ASSERT(m_frame);
   2054     RenderView* renderView = this->renderView();
   2055     if (!renderView)
   2056         return false;
   2057     return (layoutSize(IncludeScrollbars) != m_lastViewportSize || renderView->style()->zoom() != m_lastZoomFactor);
   2058 }
   2059 
   2060 void FrameView::sendResizeEventIfNeeded()
   2061 {
   2062     ASSERT(m_frame);
   2063 
   2064     RenderView* renderView = this->renderView();
   2065     if (!renderView || renderView->document().printing())
   2066         return;
   2067 
   2068     if (!wasViewportResized())
   2069         return;
   2070 
   2071     m_lastViewportSize = layoutSize(IncludeScrollbars);
   2072     m_lastZoomFactor = renderView->style()->zoom();
   2073 
   2074     m_frame->document()->enqueueResizeEvent();
   2075 
   2076     if (m_frame->isMainFrame())
   2077         InspectorInstrumentation::didResizeMainFrame(m_frame->page());
   2078 }
   2079 
   2080 void FrameView::postLayoutTimerFired(Timer<FrameView>*)
   2081 {
   2082     performPostLayoutTasks();
   2083 }
   2084 
   2085 void FrameView::updateCounters()
   2086 {
   2087     RenderView* view = renderView();
   2088     if (!view->hasRenderCounters())
   2089         return;
   2090 
   2091     for (RenderObject* renderer = view; renderer; renderer = renderer->nextInPreOrder()) {
   2092         if (!renderer->isCounter())
   2093             continue;
   2094 
   2095         toRenderCounter(renderer)->updateCounter();
   2096     }
   2097 }
   2098 
   2099 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
   2100 {
   2101     if (!m_viewportRenderer)
   2102         return;
   2103 
   2104     if (m_overflowStatusDirty) {
   2105         m_horizontalOverflow = horizontalOverflow;
   2106         m_verticalOverflow = verticalOverflow;
   2107         m_overflowStatusDirty = false;
   2108         return;
   2109     }
   2110 
   2111     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
   2112     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
   2113 
   2114     if (horizontalOverflowChanged || verticalOverflowChanged) {
   2115         m_horizontalOverflow = horizontalOverflow;
   2116         m_verticalOverflow = verticalOverflow;
   2117 
   2118         RefPtrWillBeRawPtr<OverflowEvent> event = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow);
   2119         event->setTarget(m_viewportRenderer->node());
   2120         m_frame->document()->enqueueAnimationFrameEvent(event.release());
   2121     }
   2122 
   2123 }
   2124 
   2125 IntRect FrameView::windowClipRect(IncludeScrollbarsInRect scrollbarInclusion) const
   2126 {
   2127     ASSERT(m_frame->view() == this);
   2128 
   2129     // Set our clip rect to be our contents.
   2130     IntRect clipRect = contentsToWindow(visibleContentRect(scrollbarInclusion));
   2131     if (!m_frame->deprecatedLocalOwner())
   2132         return clipRect;
   2133 
   2134     // Take our owner element and get its clip rect.
   2135     // FIXME: Do we need to do this for remote frames?
   2136     HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
   2137     FrameView* parentView = ownerElement->document().view();
   2138     if (parentView)
   2139         clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement));
   2140     return clipRect;
   2141 }
   2142 
   2143 IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement) const
   2144 {
   2145     // The renderer can sometimes be null when style="display:none" interacts
   2146     // with external content and plugins.
   2147     if (!ownerElement->renderer())
   2148         return windowClipRect();
   2149 
   2150     // If we have no layer, just return our window clip rect.
   2151     const RenderLayer* enclosingLayer = ownerElement->renderer()->enclosingLayer();
   2152     if (!enclosingLayer)
   2153         return windowClipRect();
   2154 
   2155     // FIXME: childrenClipRect relies on compositingState, which is not necessarily up to date.
   2156     // https://code.google.com/p/chromium/issues/detail?id=343769
   2157     DisableCompositingQueryAsserts disabler;
   2158 
   2159     // Apply the clip from the layer.
   2160     IntRect clipRect = contentsToWindow(pixelSnappedIntRect(enclosingLayer->clipper().childrenClipRect()));
   2161     return intersection(clipRect, windowClipRect());
   2162 }
   2163 
   2164 bool FrameView::isActive() const
   2165 {
   2166     Page* page = frame().page();
   2167     return page && page->focusController().isActive();
   2168 }
   2169 
   2170 void FrameView::scrollTo(const IntSize& newOffset)
   2171 {
   2172     LayoutSize offset = scrollOffset();
   2173     ScrollView::scrollTo(newOffset);
   2174     if (offset != scrollOffset()) {
   2175         updateLayersAndCompositingAfterScrollIfNeeded();
   2176         scrollPositionChanged();
   2177     }
   2178     frame().loader().client()->didChangeScrollOffset();
   2179 }
   2180 
   2181 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
   2182 {
   2183     // Add in our offset within the FrameView.
   2184     IntRect dirtyRect = rect;
   2185     dirtyRect.moveBy(scrollbar->location());
   2186 
   2187     if (isInPerformLayout())
   2188         addScrollbarDamage(scrollbar, rect);
   2189     else
   2190         invalidateRect(dirtyRect);
   2191 }
   2192 
   2193 void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
   2194 {
   2195     if (!m_tickmarks.isEmpty())
   2196         tickmarks = m_tickmarks;
   2197     else
   2198         tickmarks = frame().document()->markers().renderedRectsForMarkers(DocumentMarker::TextMatch);
   2199 }
   2200 
   2201 IntRect FrameView::windowResizerRect() const
   2202 {
   2203     Page* page = frame().page();
   2204     if (!page)
   2205         return IntRect();
   2206     return page->chrome().windowResizerRect();
   2207 }
   2208 
   2209 void FrameView::setVisibleContentScaleFactor(float visibleContentScaleFactor)
   2210 {
   2211     if (m_visibleContentScaleFactor == visibleContentScaleFactor)
   2212         return;
   2213 
   2214     m_visibleContentScaleFactor = visibleContentScaleFactor;
   2215     updateScrollbars(scrollOffset());
   2216 }
   2217 
   2218 void FrameView::setInputEventsTransformForEmulation(const IntSize& offset, float contentScaleFactor)
   2219 {
   2220     m_inputEventsOffsetForEmulation = offset;
   2221     m_inputEventsScaleFactorForEmulation = contentScaleFactor;
   2222 }
   2223 
   2224 IntSize FrameView::inputEventsOffsetForEmulation() const
   2225 {
   2226     return m_inputEventsOffsetForEmulation;
   2227 }
   2228 
   2229 float FrameView::inputEventsScaleFactor() const
   2230 {
   2231     float pageScale = m_frame->settings()->pinchVirtualViewportEnabled()
   2232         ? m_frame->page()->frameHost().pinchViewport().scale()
   2233         : visibleContentScaleFactor();
   2234     return pageScale * m_inputEventsScaleFactorForEmulation;
   2235 }
   2236 
   2237 bool FrameView::scrollbarsCanBeActive() const
   2238 {
   2239     if (m_frame->view() != this)
   2240         return false;
   2241 
   2242     return !!m_frame->document();
   2243 }
   2244 
   2245 IntRect FrameView::scrollableAreaBoundingBox() const
   2246 {
   2247     RenderPart* ownerRenderer = frame().ownerRenderer();
   2248     if (!ownerRenderer)
   2249         return frameRect();
   2250 
   2251     return ownerRenderer->absoluteContentQuad().enclosingBoundingBox();
   2252 }
   2253 
   2254 
   2255 bool FrameView::isScrollable()
   2256 {
   2257     return scrollingReasons() == Scrollable;
   2258 }
   2259 
   2260 FrameView::ScrollingReasons FrameView::scrollingReasons()
   2261 {
   2262     // Check for:
   2263     // 1) If there an actual overflow.
   2264     // 2) display:none or visibility:hidden set to self or inherited.
   2265     // 3) overflow{-x,-y}: hidden;
   2266     // 4) scrolling: no;
   2267 
   2268     // Covers #1
   2269     IntSize contentsSize = this->contentsSize();
   2270     IntSize visibleContentSize = visibleContentRect().size();
   2271     if ((contentsSize.height() <= visibleContentSize.height() && contentsSize.width() <= visibleContentSize.width()))
   2272         return NotScrollableNoOverflow;
   2273 
   2274     // Covers #2.
   2275     // FIXME: Do we need to fix this for OOPI?
   2276     HTMLFrameOwnerElement* owner = m_frame->deprecatedLocalOwner();
   2277     if (owner && (!owner->renderer() || !owner->renderer()->visibleToHitTesting()))
   2278         return NotScrollableNotVisible;
   2279 
   2280     // Cover #3 and #4.
   2281     ScrollbarMode horizontalMode;
   2282     ScrollbarMode verticalMode;
   2283     calculateScrollbarModesForLayoutAndSetViewportRenderer(horizontalMode, verticalMode, RulesFromWebContentOnly);
   2284     if (horizontalMode == ScrollbarAlwaysOff && verticalMode == ScrollbarAlwaysOff)
   2285         return NotScrollableExplicitlyDisabled;
   2286 
   2287     return Scrollable;
   2288 }
   2289 
   2290 void FrameView::updateScrollableAreaSet()
   2291 {
   2292     // That ensures that only inner frames are cached.
   2293     FrameView* parentFrameView = this->parentFrameView();
   2294     if (!parentFrameView)
   2295         return;
   2296 
   2297     if (!isScrollable()) {
   2298         parentFrameView->removeScrollableArea(this);
   2299         return;
   2300     }
   2301 
   2302     parentFrameView->addScrollableArea(this);
   2303 }
   2304 
   2305 bool FrameView::shouldSuspendScrollAnimations() const
   2306 {
   2307     return m_frame->loader().state() != FrameStateComplete;
   2308 }
   2309 
   2310 void FrameView::scrollbarStyleChanged()
   2311 {
   2312     // FIXME: Why does this only apply to the main frame?
   2313     if (!m_frame->isMainFrame())
   2314         return;
   2315     ScrollView::scrollbarStyleChanged();
   2316 }
   2317 
   2318 void FrameView::notifyPageThatContentAreaWillPaint() const
   2319 {
   2320     Page* page = m_frame->page();
   2321     if (!page)
   2322         return;
   2323 
   2324     contentAreaWillPaint();
   2325 
   2326     if (!m_scrollableAreas)
   2327         return;
   2328 
   2329     for (HashSet<ScrollableArea*>::const_iterator it = m_scrollableAreas->begin(), end = m_scrollableAreas->end(); it != end; ++it) {
   2330         ScrollableArea* scrollableArea = *it;
   2331 
   2332         if (!scrollableArea->scrollbarsCanBeActive())
   2333             continue;
   2334 
   2335         scrollableArea->contentAreaWillPaint();
   2336     }
   2337 }
   2338 
   2339 bool FrameView::scrollAnimatorEnabled() const
   2340 {
   2341     return m_frame->settings() && m_frame->settings()->scrollAnimatorEnabled();
   2342 }
   2343 
   2344 void FrameView::updateAnnotatedRegions()
   2345 {
   2346     Document* document = m_frame->document();
   2347     if (!document->hasAnnotatedRegions())
   2348         return;
   2349     Vector<AnnotatedRegionValue> newRegions;
   2350     document->renderBox()->collectAnnotatedRegions(newRegions);
   2351     if (newRegions == document->annotatedRegions())
   2352         return;
   2353     document->setAnnotatedRegions(newRegions);
   2354     if (Page* page = m_frame->page())
   2355         page->chrome().client().annotatedRegionsChanged();
   2356 }
   2357 
   2358 void FrameView::updateScrollCorner()
   2359 {
   2360     RefPtr<RenderStyle> cornerStyle;
   2361     IntRect cornerRect = scrollCornerRect();
   2362     Document* doc = m_frame->document();
   2363 
   2364     if (doc && !cornerRect.isEmpty()) {
   2365         // Try the <body> element first as a scroll corner source.
   2366         if (Element* body = doc->body()) {
   2367             if (RenderObject* renderer = body->renderer())
   2368                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
   2369         }
   2370 
   2371         if (!cornerStyle) {
   2372             // If the <body> didn't have a custom style, then the root element might.
   2373             if (Element* docElement = doc->documentElement()) {
   2374                 if (RenderObject* renderer = docElement->renderer())
   2375                     cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
   2376             }
   2377         }
   2378 
   2379         if (!cornerStyle) {
   2380             // If we have an owning ipage/LocalFrame element, then it can set the custom scrollbar also.
   2381             if (RenderPart* renderer = m_frame->ownerRenderer())
   2382                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
   2383         }
   2384     }
   2385 
   2386     if (cornerStyle) {
   2387         if (!m_scrollCorner)
   2388             m_scrollCorner = RenderScrollbarPart::createAnonymous(doc);
   2389         m_scrollCorner->setStyle(cornerStyle.release());
   2390         invalidateScrollCorner(cornerRect);
   2391     } else if (m_scrollCorner) {
   2392         m_scrollCorner->destroy();
   2393         m_scrollCorner = nullptr;
   2394     }
   2395 
   2396     ScrollView::updateScrollCorner();
   2397 }
   2398 
   2399 void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
   2400 {
   2401     if (m_scrollCorner) {
   2402         bool needsBackgorund = m_frame->isMainFrame();
   2403         if (needsBackgorund)
   2404             context->fillRect(cornerRect, baseBackgroundColor());
   2405         m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect);
   2406         return;
   2407     }
   2408 
   2409     ScrollView::paintScrollCorner(context, cornerRect);
   2410 }
   2411 
   2412 void FrameView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
   2413 {
   2414     bool needsBackgorund = bar->isCustomScrollbar() && m_frame->isMainFrame();
   2415     if (needsBackgorund) {
   2416         IntRect toFill = bar->frameRect();
   2417         toFill.intersect(rect);
   2418         context->fillRect(toFill, baseBackgroundColor());
   2419     }
   2420 
   2421     ScrollView::paintScrollbar(context, bar, rect);
   2422 }
   2423 
   2424 Color FrameView::documentBackgroundColor() const
   2425 {
   2426     // <https://bugs.webkit.org/show_bug.cgi?id=59540> We blend the background color of
   2427     // the document and the body against the base background color of the frame view.
   2428     // Background images are unfortunately impractical to include.
   2429 
   2430     Color result = baseBackgroundColor();
   2431     if (!frame().document())
   2432         return result;
   2433 
   2434     Element* htmlElement = frame().document()->documentElement();
   2435     Element* bodyElement = frame().document()->body();
   2436 
   2437     // We take the aggregate of the base background color
   2438     // the <html> background color, and the <body>
   2439     // background color to find the document color. The
   2440     // addition of the base background color is not
   2441     // technically part of the document background, but it
   2442     // otherwise poses problems when the aggregate is not
   2443     // fully opaque.
   2444     if (htmlElement && htmlElement->renderer())
   2445         result = result.blend(htmlElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor));
   2446     if (bodyElement && bodyElement->renderer())
   2447         result = result.blend(bodyElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor));
   2448 
   2449     return result;
   2450 }
   2451 
   2452 bool FrameView::hasCustomScrollbars() const
   2453 {
   2454     const HashSet<RefPtr<Widget> >* viewChildren = children();
   2455     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
   2456     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
   2457         Widget* widget = current->get();
   2458         if (widget->isFrameView()) {
   2459             if (toFrameView(widget)->hasCustomScrollbars())
   2460                 return true;
   2461         } else if (widget->isScrollbar()) {
   2462             Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
   2463             if (scrollbar->isCustomScrollbar())
   2464                 return true;
   2465         }
   2466     }
   2467 
   2468     return false;
   2469 }
   2470 
   2471 FrameView* FrameView::parentFrameView() const
   2472 {
   2473     if (!parent())
   2474         return 0;
   2475 
   2476     Frame* parentFrame = m_frame->tree().parent();
   2477     if (parentFrame && parentFrame->isLocalFrame())
   2478         return toLocalFrame(parentFrame)->view();
   2479 
   2480     return 0;
   2481 }
   2482 
   2483 bool FrameView::wasScrolledByUser() const
   2484 {
   2485     return m_wasScrolledByUser;
   2486 }
   2487 
   2488 void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
   2489 {
   2490     if (m_inProgrammaticScroll)
   2491         return;
   2492     m_maintainScrollPositionAnchor = nullptr;
   2493     m_wasScrolledByUser = wasScrolledByUser;
   2494 }
   2495 
   2496 void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
   2497 {
   2498     Document* document = m_frame->document();
   2499 
   2500 #ifndef NDEBUG
   2501     bool fillWithRed;
   2502     if (document->printing())
   2503         fillWithRed = false; // Printing, don't fill with red (can't remember why).
   2504     else if (m_frame->owner())
   2505         fillWithRed = false; // Subframe, don't fill with red.
   2506     else if (isTransparent())
   2507         fillWithRed = false; // Transparent, don't fill with red.
   2508     else if (m_paintBehavior & PaintBehaviorSelectionOnly)
   2509         fillWithRed = false; // Selections are transparent, don't fill with red.
   2510     else if (m_nodeToDraw)
   2511         fillWithRed = false; // Element images are transparent, don't fill with red.
   2512     else
   2513         fillWithRed = true;
   2514 
   2515     if (fillWithRed)
   2516         p->fillRect(rect, Color(0xFF, 0, 0));
   2517 #endif
   2518 
   2519     RenderView* renderView = this->renderView();
   2520     if (!renderView) {
   2521         WTF_LOG_ERROR("called FrameView::paint with nil renderer");
   2522         return;
   2523     }
   2524 
   2525     RELEASE_ASSERT(!needsLayout());
   2526     ASSERT(document->lifecycle().state() >= DocumentLifecycle::CompositingClean);
   2527 
   2528     TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Paint", "data", InspectorPaintEvent::data(renderView, rect, 0));
   2529     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
   2530     // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
   2531     InspectorInstrumentation::willPaint(renderView, 0);
   2532 
   2533     bool isTopLevelPainter = !s_inPaintContents;
   2534     s_inPaintContents = true;
   2535 
   2536     FontCachePurgePreventer fontCachePurgePreventer;
   2537 
   2538     PaintBehavior oldPaintBehavior = m_paintBehavior;
   2539 
   2540     if (FrameView* parentView = parentFrameView()) {
   2541         if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers)
   2542             m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
   2543     }
   2544 
   2545     if (m_paintBehavior == PaintBehaviorNormal)
   2546         document->markers().invalidateRenderedRectsForMarkersInRect(rect);
   2547 
   2548     if (document->printing())
   2549         m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
   2550 
   2551     ASSERT(!m_isPainting);
   2552     m_isPainting = true;
   2553 
   2554     // m_nodeToDraw is used to draw only one element (and its descendants)
   2555     RenderObject* renderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
   2556     RenderLayer* rootLayer = renderView->layer();
   2557 
   2558 #if ENABLE(ASSERT)
   2559     renderView->assertSubtreeIsLaidOut();
   2560     RenderObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(*rootLayer->renderer());
   2561 #endif
   2562 
   2563     rootLayer->paint(p, rect, m_paintBehavior, renderer);
   2564 
   2565     if (rootLayer->containsDirtyOverlayScrollbars())
   2566         rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, renderer);
   2567 
   2568     m_isPainting = false;
   2569 
   2570     m_paintBehavior = oldPaintBehavior;
   2571     m_lastPaintTime = currentTime();
   2572 
   2573     // Regions may have changed as a result of the visibility/z-index of element changing.
   2574     if (document->annotatedRegionsDirty())
   2575         updateAnnotatedRegions();
   2576 
   2577     if (isTopLevelPainter) {
   2578         // Everything that happens after paintContents completions is considered
   2579         // to be part of the next frame.
   2580         s_currentFrameTimeStamp = currentTime();
   2581         s_inPaintContents = false;
   2582     }
   2583 
   2584     InspectorInstrumentation::didPaint(renderView, 0, p, rect);
   2585 }
   2586 
   2587 void FrameView::setPaintBehavior(PaintBehavior behavior)
   2588 {
   2589     m_paintBehavior = behavior;
   2590 }
   2591 
   2592 PaintBehavior FrameView::paintBehavior() const
   2593 {
   2594     return m_paintBehavior;
   2595 }
   2596 
   2597 bool FrameView::isPainting() const
   2598 {
   2599     return m_isPainting;
   2600 }
   2601 
   2602 void FrameView::setNodeToDraw(Node* node)
   2603 {
   2604     m_nodeToDraw = node;
   2605 }
   2606 
   2607 void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
   2608 {
   2609     if (m_frame->document()->printing())
   2610         return;
   2611 
   2612     if (m_frame->isMainFrame()) {
   2613         if (m_frame->page()->chrome().client().paintCustomOverhangArea(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect))
   2614             return;
   2615     }
   2616 
   2617     ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
   2618 }
   2619 
   2620 void FrameView::updateWidgetPositionsIfNeeded()
   2621 {
   2622     if (!m_needsUpdateWidgetPositions)
   2623         return;
   2624 
   2625     m_needsUpdateWidgetPositions = false;
   2626 
   2627     updateWidgetPositions();
   2628 }
   2629 
   2630 void FrameView::updateLayoutAndStyleForPainting()
   2631 {
   2632     // Updating layout can run script, which can tear down the FrameView.
   2633     RefPtr<FrameView> protector(this);
   2634 
   2635     updateLayoutAndStyleIfNeededRecursive();
   2636 
   2637     updateWidgetPositionsIfNeeded();
   2638 
   2639     if (RenderView* view = renderView()) {
   2640         TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateLayerTree", "frame", m_frame.get());
   2641         // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
   2642         InspectorInstrumentation::willUpdateLayerTree(m_frame.get());
   2643 
   2644         view->compositor()->updateIfNeededRecursive();
   2645 
   2646         if (view->compositor()->inCompositingMode() && m_frame->isLocalRoot())
   2647             m_frame->page()->scrollingCoordinator()->updateAfterCompositingChangeIfNeeded();
   2648 
   2649         updateCompositedSelectionBoundsIfNeeded();
   2650 
   2651         InspectorInstrumentation::didUpdateLayerTree(m_frame.get());
   2652 
   2653         invalidateTreeIfNeededRecursive();
   2654     }
   2655 
   2656     scrollContentsIfNeededRecursive();
   2657     ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationClean);
   2658 }
   2659 
   2660 void FrameView::updateLayoutAndStyleIfNeededRecursive()
   2661 {
   2662     // We have to crawl our entire tree looking for any FrameViews that need
   2663     // layout and make sure they are up to date.
   2664     // Mac actually tests for intersection with the dirty region and tries not to
   2665     // update layout for frames that are outside the dirty region.  Not only does this seem
   2666     // pointless (since those frames will have set a zero timer to layout anyway), but
   2667     // it is also incorrect, since if two frames overlap, the first could be excluded from the dirty
   2668     // region but then become included later by the second frame adding rects to the dirty region
   2669     // when it lays out.
   2670 
   2671     m_frame->document()->updateRenderTreeIfNeeded();
   2672 
   2673     if (needsLayout())
   2674         layout();
   2675 
   2676     // FIXME: Calling layout() shouldn't trigger scripe execution or have any
   2677     // observable effects on the frame tree but we're not quite there yet.
   2678     Vector<RefPtr<FrameView> > frameViews;
   2679     for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
   2680         if (!child->isLocalFrame())
   2681             continue;
   2682         if (FrameView* view = toLocalFrame(child)->view())
   2683             frameViews.append(view);
   2684     }
   2685 
   2686     const Vector<RefPtr<FrameView> >::iterator end = frameViews.end();
   2687     for (Vector<RefPtr<FrameView> >::iterator it = frameViews.begin(); it != end; ++it)
   2688         (*it)->updateLayoutAndStyleIfNeededRecursive();
   2689 
   2690     // When an <iframe> gets composited, it triggers an extra style recalc in its containing FrameView.
   2691     // To avoid pushing an invalid tree for display, we have to check for this case and do another
   2692     // style recalc. The extra style recalc needs to happen after our child <iframes> were updated.
   2693     // FIXME: We shouldn't be triggering an extra style recalc in the first place.
   2694     if (m_frame->document()->hasSVGFilterElementsRequiringLayerUpdate()) {
   2695         m_frame->document()->updateRenderTreeIfNeeded();
   2696 
   2697         if (needsLayout())
   2698             layout();
   2699     }
   2700 
   2701     // These asserts ensure that parent frames are clean, when child frames finished updating layout and style.
   2702     ASSERT(!needsLayout());
   2703     ASSERT(!m_frame->document()->hasSVGFilterElementsRequiringLayerUpdate());
   2704 #if ENABLE(ASSERT)
   2705     m_frame->document()->renderView()->assertRendererLaidOut();
   2706 #endif
   2707 
   2708 }
   2709 
   2710 void FrameView::invalidateTreeIfNeededRecursive()
   2711 {
   2712     // FIXME: We should be more aggressive at cutting tree traversals.
   2713     lifecycle().advanceTo(DocumentLifecycle::InPaintInvalidation);
   2714     invalidateTreeIfNeeded();
   2715     lifecycle().advanceTo(DocumentLifecycle::PaintInvalidationClean);
   2716 
   2717     for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
   2718         if (!child->isLocalFrame())
   2719             continue;
   2720 
   2721         toLocalFrame(child)->view()->invalidateTreeIfNeededRecursive();
   2722     }
   2723 
   2724     m_doFullPaintInvalidation = false;
   2725 }
   2726 
   2727 void FrameView::enableAutoSizeMode(const IntSize& minSize, const IntSize& maxSize)
   2728 {
   2729     if (!m_autoSizeInfo)
   2730         m_autoSizeInfo = adoptPtr(new FrameViewAutoSizeInfo(this));
   2731 
   2732     m_autoSizeInfo->configureAutoSizeMode(minSize, maxSize);
   2733 }
   2734 
   2735 void FrameView::forceLayout(bool allowSubtree)
   2736 {
   2737     layout(allowSubtree);
   2738 }
   2739 
   2740 void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor)
   2741 {
   2742     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
   2743     // the state of things before and after the layout
   2744     if (RenderView* renderView = this->renderView()) {
   2745         float pageLogicalWidth = renderView->style()->isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
   2746         float pageLogicalHeight = renderView->style()->isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
   2747 
   2748         LayoutUnit flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
   2749         LayoutUnit flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
   2750         renderView->setLogicalWidth(flooredPageLogicalWidth);
   2751         renderView->setPageLogicalHeight(flooredPageLogicalHeight);
   2752         renderView->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
   2753         forceLayout();
   2754 
   2755         // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
   2756         // page width when shrunk, we will lay out at maximum shrink and clip extra content.
   2757         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
   2758         // implementation should not do this!
   2759         bool horizontalWritingMode = renderView->style()->isHorizontalWritingMode();
   2760         const LayoutRect& documentRect = renderView->documentRect();
   2761         LayoutUnit docLogicalWidth = horizontalWritingMode ? documentRect.width() : documentRect.height();
   2762         if (docLogicalWidth > pageLogicalWidth) {
   2763             FloatSize expectedPageSize(std::min<float>(documentRect.width().toFloat(), pageSize.width() * maximumShrinkFactor), std::min<float>(documentRect.height().toFloat(), pageSize.height() * maximumShrinkFactor));
   2764             FloatSize maxPageSize = m_frame->resizePageRectsKeepingRatio(FloatSize(originalPageSize.width(), originalPageSize.height()), expectedPageSize);
   2765             pageLogicalWidth = horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
   2766             pageLogicalHeight = horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();
   2767 
   2768             flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
   2769             flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
   2770             renderView->setLogicalWidth(flooredPageLogicalWidth);
   2771             renderView->setPageLogicalHeight(flooredPageLogicalHeight);
   2772             renderView->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
   2773             forceLayout();
   2774 
   2775             const LayoutRect& updatedDocumentRect = renderView->documentRect();
   2776             LayoutUnit docLogicalHeight = horizontalWritingMode ? updatedDocumentRect.height() : updatedDocumentRect.width();
   2777             LayoutUnit docLogicalTop = horizontalWritingMode ? updatedDocumentRect.y() : updatedDocumentRect.x();
   2778             LayoutUnit docLogicalRight = horizontalWritingMode ? updatedDocumentRect.maxX() : updatedDocumentRect.maxY();
   2779             LayoutUnit clippedLogicalLeft = 0;
   2780             if (!renderView->style()->isLeftToRightDirection())
   2781                 clippedLogicalLeft = docLogicalRight - pageLogicalWidth;
   2782             LayoutRect overflow(clippedLogicalLeft, docLogicalTop, pageLogicalWidth, docLogicalHeight);
   2783 
   2784             if (!horizontalWritingMode)
   2785                 overflow = overflow.transposedRect();
   2786             renderView->clearLayoutOverflow();
   2787             renderView->addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
   2788         }
   2789     }
   2790 
   2791     adjustViewSize();
   2792 }
   2793 
   2794 IntRect FrameView::convertFromRenderer(const RenderObject& renderer, const IntRect& rendererRect) const
   2795 {
   2796     IntRect rect = pixelSnappedIntRect(enclosingLayoutRect(renderer.localToAbsoluteQuad(FloatRect(rendererRect)).boundingBox()));
   2797 
   2798     // Convert from page ("absolute") to FrameView coordinates.
   2799     rect.moveBy(-scrollPosition());
   2800 
   2801     return rect;
   2802 }
   2803 
   2804 IntRect FrameView::convertToRenderer(const RenderObject& renderer, const IntRect& viewRect) const
   2805 {
   2806     IntRect rect = viewRect;
   2807 
   2808     // Convert from FrameView coords into page ("absolute") coordinates.
   2809     rect.moveBy(scrollPosition());
   2810 
   2811     // FIXME: we don't have a way to map an absolute rect down to a local quad, so just
   2812     // move the rect for now.
   2813     rect.setLocation(roundedIntPoint(renderer.absoluteToLocal(rect.location(), UseTransforms)));
   2814     return rect;
   2815 }
   2816 
   2817 IntPoint FrameView::convertFromRenderer(const RenderObject& renderer, const IntPoint& rendererPoint) const
   2818 {
   2819     IntPoint point = roundedIntPoint(renderer.localToAbsolute(rendererPoint, UseTransforms));
   2820 
   2821     // Convert from page ("absolute") to FrameView coordinates.
   2822     point.moveBy(-scrollPosition());
   2823     return point;
   2824 }
   2825 
   2826 IntPoint FrameView::convertToRenderer(const RenderObject& renderer, const IntPoint& viewPoint) const
   2827 {
   2828     IntPoint point = viewPoint;
   2829 
   2830     // Convert from FrameView coords into page ("absolute") coordinates.
   2831     point += IntSize(scrollX(), scrollY());
   2832 
   2833     return roundedIntPoint(renderer.absoluteToLocal(point, UseTransforms));
   2834 }
   2835 
   2836 IntRect FrameView::convertToContainingView(const IntRect& localRect) const
   2837 {
   2838     if (const ScrollView* parentScrollView = toScrollView(parent())) {
   2839         if (parentScrollView->isFrameView()) {
   2840             const FrameView* parentView = toFrameView(parentScrollView);
   2841             // Get our renderer in the parent view
   2842             RenderPart* renderer = m_frame->ownerRenderer();
   2843             if (!renderer)
   2844                 return localRect;
   2845 
   2846             IntRect rect(localRect);
   2847             // Add borders and padding??
   2848             rect.move(renderer->borderLeft() + renderer->paddingLeft(),
   2849                 renderer->borderTop() + renderer->paddingTop());
   2850             return parentView->convertFromRenderer(*renderer, rect);
   2851         }
   2852 
   2853         return Widget::convertToContainingView(localRect);
   2854     }
   2855 
   2856     return localRect;
   2857 }
   2858 
   2859 IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
   2860 {
   2861     if (const ScrollView* parentScrollView = toScrollView(parent())) {
   2862         if (parentScrollView->isFrameView()) {
   2863             const FrameView* parentView = toFrameView(parentScrollView);
   2864 
   2865             // Get our renderer in the parent view
   2866             RenderPart* renderer = m_frame->ownerRenderer();
   2867             if (!renderer)
   2868                 return parentRect;
   2869 
   2870             IntRect rect = parentView->convertToRenderer(*renderer, parentRect);
   2871             // Subtract borders and padding
   2872             rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
   2873                       -renderer->borderTop() - renderer->paddingTop());
   2874             return rect;
   2875         }
   2876 
   2877         return Widget::convertFromContainingView(parentRect);
   2878     }
   2879 
   2880     return parentRect;
   2881 }
   2882 
   2883 IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
   2884 {
   2885     if (const ScrollView* parentScrollView = toScrollView(parent())) {
   2886         if (parentScrollView->isFrameView()) {
   2887             const FrameView* parentView = toFrameView(parentScrollView);
   2888 
   2889             // Get our renderer in the parent view
   2890             RenderPart* renderer = m_frame->ownerRenderer();
   2891             if (!renderer)
   2892                 return localPoint;
   2893 
   2894             IntPoint point(localPoint);
   2895 
   2896             // Add borders and padding
   2897             point.move(renderer->borderLeft() + renderer->paddingLeft(),
   2898                        renderer->borderTop() + renderer->paddingTop());
   2899             return parentView->convertFromRenderer(*renderer, point);
   2900         }
   2901 
   2902         return Widget::convertToContainingView(localPoint);
   2903     }
   2904 
   2905     return localPoint;
   2906 }
   2907 
   2908 IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
   2909 {
   2910     if (const ScrollView* parentScrollView = toScrollView(parent())) {
   2911         if (parentScrollView->isFrameView()) {
   2912             const FrameView* parentView = toFrameView(parentScrollView);
   2913 
   2914             // Get our renderer in the parent view
   2915             RenderPart* renderer = m_frame->ownerRenderer();
   2916             if (!renderer)
   2917                 return parentPoint;
   2918 
   2919             IntPoint point = parentView->convertToRenderer(*renderer, parentPoint);
   2920             // Subtract borders and padding
   2921             point.move(-renderer->borderLeft() - renderer->paddingLeft(),
   2922                        -renderer->borderTop() - renderer->paddingTop());
   2923             return point;
   2924         }
   2925 
   2926         return Widget::convertFromContainingView(parentPoint);
   2927     }
   2928 
   2929     return parentPoint;
   2930 }
   2931 
   2932 void FrameView::setTracksPaintInvalidations(bool trackPaintInvalidations)
   2933 {
   2934     if (trackPaintInvalidations == m_isTrackingPaintInvalidations)
   2935         return;
   2936 
   2937     for (Frame* frame = m_frame->tree().top(); frame; frame = frame->tree().traverseNext()) {
   2938         if (!frame->isLocalFrame())
   2939             continue;
   2940         if (RenderView* renderView = toLocalFrame(frame)->contentRenderer())
   2941             renderView->compositor()->setTracksPaintInvalidations(trackPaintInvalidations);
   2942     }
   2943 
   2944     TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"),
   2945         "FrameView::setTracksPaintInvalidations", "enabled", trackPaintInvalidations);
   2946 
   2947     resetTrackedPaintInvalidations();
   2948     m_isTrackingPaintInvalidations = trackPaintInvalidations;
   2949 }
   2950 
   2951 void FrameView::resetTrackedPaintInvalidations()
   2952 {
   2953     m_trackedPaintInvalidationRects.clear();
   2954     if (RenderView* renderView = this->renderView())
   2955         renderView->compositor()->resetTrackedPaintInvalidationRects();
   2956 }
   2957 
   2958 String FrameView::trackedPaintInvalidationRectsAsText() const
   2959 {
   2960     TextStream ts;
   2961     if (!m_trackedPaintInvalidationRects.isEmpty()) {
   2962         ts << "(repaint rects\n";
   2963         for (size_t i = 0; i < m_trackedPaintInvalidationRects.size(); ++i)
   2964             ts << "  (rect " << m_trackedPaintInvalidationRects[i].x() << " " << m_trackedPaintInvalidationRects[i].y() << " " << m_trackedPaintInvalidationRects[i].width() << " " << m_trackedPaintInvalidationRects[i].height() << ")\n";
   2965         ts << ")\n";
   2966     }
   2967     return ts.release();
   2968 }
   2969 
   2970 void FrameView::addResizerArea(RenderBox& resizerBox)
   2971 {
   2972     if (!m_resizerAreas)
   2973         m_resizerAreas = adoptPtr(new ResizerAreaSet);
   2974     m_resizerAreas->add(&resizerBox);
   2975 }
   2976 
   2977 void FrameView::removeResizerArea(RenderBox& resizerBox)
   2978 {
   2979     if (!m_resizerAreas)
   2980         return;
   2981 
   2982     ResizerAreaSet::iterator it = m_resizerAreas->find(&resizerBox);
   2983     if (it != m_resizerAreas->end())
   2984         m_resizerAreas->remove(it);
   2985 }
   2986 
   2987 void FrameView::addScrollableArea(ScrollableArea* scrollableArea)
   2988 {
   2989     ASSERT(scrollableArea);
   2990     if (!m_scrollableAreas)
   2991         m_scrollableAreas = adoptPtr(new ScrollableAreaSet);
   2992     m_scrollableAreas->add(scrollableArea);
   2993 }
   2994 
   2995 void FrameView::removeScrollableArea(ScrollableArea* scrollableArea)
   2996 {
   2997     if (!m_scrollableAreas)
   2998         return;
   2999     m_scrollableAreas->remove(scrollableArea);
   3000 }
   3001 
   3002 void FrameView::setParent(Widget* widget)
   3003 {
   3004     ScrollView::setParent(widget);
   3005     updateScrollableAreaSet();
   3006 }
   3007 
   3008 void FrameView::removeChild(Widget* widget)
   3009 {
   3010     if (widget->isFrameView())
   3011         removeScrollableArea(toFrameView(widget));
   3012 
   3013     ScrollView::removeChild(widget);
   3014 }
   3015 
   3016 bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent)
   3017 {
   3018     bool allowScrolling = userInputScrollable(HorizontalScrollbar) || userInputScrollable(VerticalScrollbar);
   3019 
   3020     // Note that to allow for rubber-band over-scroll behavior, even non-scrollable views
   3021     // should handle wheel events.
   3022 #if !USE(RUBBER_BANDING)
   3023     if (!isScrollable())
   3024         allowScrolling = false;
   3025 #endif
   3026 
   3027     if (allowScrolling && ScrollableArea::handleWheelEvent(wheelEvent))
   3028         return true;
   3029 
   3030     // If the frame didn't handle the event, give the pinch-zoom viewport a chance to
   3031     // process the scroll event.
   3032     if (m_frame->settings()->pinchVirtualViewportEnabled() && m_frame->isMainFrame())
   3033         return page()->frameHost().pinchViewport().handleWheelEvent(wheelEvent);
   3034 
   3035     return false;
   3036 }
   3037 
   3038 bool FrameView::isVerticalDocument() const
   3039 {
   3040     RenderView* renderView = this->renderView();
   3041     if (!renderView)
   3042         return true;
   3043 
   3044     return renderView->style()->isHorizontalWritingMode();
   3045 }
   3046 
   3047 bool FrameView::isFlippedDocument() const
   3048 {
   3049     RenderView* renderView = this->renderView();
   3050     if (!renderView)
   3051         return false;
   3052 
   3053     return renderView->style()->isFlippedBlocksWritingMode();
   3054 }
   3055 
   3056 bool FrameView::scrollbarsDisabled() const
   3057 {
   3058     if (!m_frame->settings() || !m_frame->settings()->pinchVirtualViewportEnabled())
   3059         return false;
   3060 
   3061     return m_frame->isMainFrame() && ScrollbarTheme::theme()->usesOverlayScrollbars();
   3062 }
   3063 
   3064 AXObjectCache* FrameView::axObjectCache() const
   3065 {
   3066     if (frame().document())
   3067         return frame().document()->existingAXObjectCache();
   3068     return 0;
   3069 }
   3070 
   3071 void FrameView::setCursor(const Cursor& cursor)
   3072 {
   3073     Page* page = frame().page();
   3074     if (!page || !page->settings().deviceSupportsMouse())
   3075         return;
   3076     page->chrome().setCursor(cursor);
   3077 }
   3078 
   3079 void FrameView::frameRectsChanged()
   3080 {
   3081     if (layoutSizeFixedToFrameSize())
   3082         setLayoutSizeInternal(frameRect().size());
   3083 
   3084     ScrollView::frameRectsChanged();
   3085 }
   3086 
   3087 void FrameView::setLayoutSizeInternal(const IntSize& size)
   3088 {
   3089     if (m_layoutSize == size)
   3090         return;
   3091 
   3092     m_layoutSize = size;
   3093     contentsResized();
   3094 }
   3095 
   3096 void FrameView::didAddScrollbar(Scrollbar* scrollbar, ScrollbarOrientation orientation)
   3097 {
   3098     ScrollableArea::didAddScrollbar(scrollbar, orientation);
   3099     if (AXObjectCache* cache = axObjectCache())
   3100         cache->handleScrollbarUpdate(this);
   3101 }
   3102 
   3103 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation orientation)
   3104 {
   3105     ScrollableArea::willRemoveScrollbar(scrollbar, orientation);
   3106     if (AXObjectCache* cache = axObjectCache()) {
   3107         cache->remove(scrollbar);
   3108         cache->handleScrollbarUpdate(this);
   3109     }
   3110 }
   3111 
   3112 void FrameView::setTopControlsViewportAdjustment(float adjustment)
   3113 {
   3114     m_topControlsViewportAdjustment = adjustment;
   3115 }
   3116 
   3117 IntPoint FrameView::maximumScrollPosition() const
   3118 {
   3119     FloatSize visibleContentSizeF = unscaledVisibleContentSize(ExcludeScrollbars);
   3120     visibleContentSizeF.expand(0, -m_topControlsViewportAdjustment);
   3121     visibleContentSizeF.scale(1 / visibleContentScaleFactor());
   3122     IntSize visibleSize = expandedIntSize(visibleContentSizeF);
   3123 
   3124     IntPoint maximumOffset(
   3125         contentsWidth() - visibleSize.width() - scrollOrigin().x(),
   3126         contentsHeight() - visibleSize.height() - scrollOrigin().y());
   3127     maximumOffset.clampNegativeToZero();
   3128     return maximumOffset;
   3129 }
   3130 
   3131 } // namespace blink
   3132