Home | History | Annotate | Download | only in page
      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/page/FrameView.h"
     29 
     30 #include "HTMLNames.h"
     31 #include "RuntimeEnabledFeatures.h"
     32 #include "core/accessibility/AXObjectCache.h"
     33 #include "core/animation/DocumentTimeline.h"
     34 #include "core/css/FontLoader.h"
     35 #include "core/css/resolver/StyleResolver.h"
     36 #include "core/dom/DocumentMarkerController.h"
     37 #include "core/dom/OverflowEvent.h"
     38 #include "core/editing/FrameSelection.h"
     39 #include "core/html/HTMLFrameElement.h"
     40 #include "core/html/HTMLHtmlElement.h"
     41 #include "core/html/HTMLPlugInImageElement.h"
     42 #include "core/inspector/InspectorInstrumentation.h"
     43 #include "core/loader/FrameLoader.h"
     44 #include "core/loader/FrameLoaderClient.h"
     45 #include "core/loader/TextResourceDecoder.h"
     46 #include "core/loader/cache/ResourceFetcher.h"
     47 #include "core/page/Chrome.h"
     48 #include "core/page/ChromeClient.h"
     49 #include "core/page/EventHandler.h"
     50 #include "core/page/FocusController.h"
     51 #include "core/page/Frame.h"
     52 #include "core/page/FrameActionScheduler.h"
     53 #include "core/page/FrameTree.h"
     54 #include "core/page/Settings.h"
     55 #include "core/page/animation/AnimationController.h"
     56 #include "core/page/scrolling/ScrollingCoordinator.h"
     57 #include "core/platform/ScrollAnimator.h"
     58 #include "core/platform/graphics/FloatRect.h"
     59 #include "core/platform/graphics/FontCache.h"
     60 #include "core/platform/graphics/GraphicsContext.h"
     61 #include "core/platform/text/TextStream.h"
     62 #include "core/rendering/RenderEmbeddedObject.h"
     63 #include "core/rendering/RenderLayer.h"
     64 #include "core/rendering/RenderLayerBacking.h"
     65 #include "core/rendering/RenderLayerCompositor.h"
     66 #include "core/rendering/RenderLazyBlock.h"
     67 #include "core/rendering/RenderPart.h"
     68 #include "core/rendering/RenderScrollbar.h"
     69 #include "core/rendering/RenderScrollbarPart.h"
     70 #include "core/rendering/RenderTheme.h"
     71 #include "core/rendering/RenderView.h"
     72 #include "core/rendering/TextAutosizer.h"
     73 #include "core/rendering/style/RenderStyle.h"
     74 #include "core/rendering/svg/RenderSVGRoot.h"
     75 #include "core/svg/SVGDocument.h"
     76 #include "core/svg/SVGSVGElement.h"
     77 
     78 #include "wtf/CurrentTime.h"
     79 #include "wtf/TemporaryChange.h"
     80 
     81 #include "core/platform/chromium/TraceEvent.h"
     82 
     83 namespace WebCore {
     84 
     85 using namespace HTMLNames;
     86 
     87 double FrameView::sCurrentPaintTimeStamp = 0.0;
     88 
     89 
     90 // REPAINT_THROTTLING now chooses default values for throttling parameters.
     91 // Should be removed when applications start using runtime configuration.
     92 #if ENABLE(REPAINT_THROTTLING)
     93 // Normal delay
     94 double FrameView::s_normalDeferredRepaintDelay = 0.016;
     95 // Negative value would mean that first few repaints happen without a delay
     96 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
     97 // The delay grows on each repaint to this maximum value
     98 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 2.5;
     99 // On each repaint the delay increses by this amount
    100 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5;
    101 #else
    102 // FIXME: Repaint throttling could be good to have on all platform.
    103 // The balance between CPU use and repaint frequency will need some tuning for desktop.
    104 // More hooks may be needed to reset the delay on things like GIF and CSS animations.
    105 double FrameView::s_normalDeferredRepaintDelay = 0;
    106 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
    107 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0;
    108 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0;
    109 #endif
    110 
    111 // The maximum number of updateWidgets iterations that should be done before returning.
    112 static const unsigned maxUpdateWidgetsIterations = 2;
    113 
    114 static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLayer* layer, bool isRelayoutingSubtree, bool didFullRepaint)
    115 {
    116     RenderLayer::UpdateLayerPositionsFlags flags = RenderLayer::defaultFlags;
    117     if (didFullRepaint) {
    118         flags &= ~RenderLayer::CheckForRepaint;
    119         flags |= RenderLayer::NeedsFullRepaintInBacking;
    120     }
    121     if (isRelayoutingSubtree && layer->isPaginated())
    122         flags |= RenderLayer::UpdatePagination;
    123     return flags;
    124 }
    125 
    126 Pagination::Mode paginationModeForRenderStyle(RenderStyle* style)
    127 {
    128     EOverflow overflow = style->overflowY();
    129     if (overflow != OPAGEDX && overflow != OPAGEDY)
    130         return Pagination::Unpaginated;
    131 
    132     bool isHorizontalWritingMode = style->isHorizontalWritingMode();
    133     TextDirection textDirection = style->direction();
    134     WritingMode writingMode = style->writingMode();
    135 
    136     // paged-x always corresponds to LeftToRightPaginated or RightToLeftPaginated. If the WritingMode
    137     // is horizontal, then we use TextDirection to choose between those options. If the WritingMode
    138     // is vertical, then the direction of the verticality dictates the choice.
    139     if (overflow == OPAGEDX) {
    140         if ((isHorizontalWritingMode && textDirection == LTR) || writingMode == LeftToRightWritingMode)
    141             return Pagination::LeftToRightPaginated;
    142         return Pagination::RightToLeftPaginated;
    143     }
    144 
    145     // paged-y always corresponds to TopToBottomPaginated or BottomToTopPaginated. If the WritingMode
    146     // is horizontal, then the direction of the horizontality dictates the choice. If the WritingMode
    147     // is vertical, then we use TextDirection to choose between those options.
    148     if (writingMode == TopToBottomWritingMode || (!isHorizontalWritingMode && textDirection == RTL))
    149         return Pagination::TopToBottomPaginated;
    150     return Pagination::BottomToTopPaginated;
    151 }
    152 
    153 FrameView::FrameView(Frame* frame)
    154     : m_frame(frame)
    155     , m_canHaveScrollbars(true)
    156     , m_slowRepaintObjectCount(0)
    157     , m_layoutTimer(this, &FrameView::layoutTimerFired)
    158     , m_layoutRoot(0)
    159     , m_inSynchronousPostLayout(false)
    160     , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
    161     , m_isTransparent(false)
    162     , m_baseBackgroundColor(Color::white)
    163     , m_mediaType("screen")
    164     , m_actionScheduler(adoptPtr(new FrameActionScheduler))
    165     , m_overflowStatusDirty(true)
    166     , m_viewportRenderer(0)
    167     , m_wasScrolledByUser(false)
    168     , m_inProgrammaticScroll(false)
    169     , m_safeToPropagateScrollToParent(true)
    170     , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired)
    171     , m_disableRepaints(0)
    172     , m_isTrackingRepaints(false)
    173     , m_shouldUpdateWhileOffscreen(true)
    174     , m_deferSetNeedsLayouts(0)
    175     , m_setNeedsLayoutWasDeferred(false)
    176     , m_scrollCorner(0)
    177     , m_shouldAutoSize(false)
    178     , m_inAutoSize(false)
    179     , m_didRunAutosize(false)
    180     , m_hasSoftwareFilters(false)
    181     , m_visibleContentScaleFactor(1)
    182 {
    183     init();
    184 
    185     // FIXME: Can m_frame ever be null here?
    186     if (!m_frame)
    187         return;
    188 
    189     Page* page = m_frame->page();
    190     if (!page)
    191         return;
    192 
    193     if (m_frame == page->mainFrame()) {
    194         ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
    195         ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
    196     }
    197 }
    198 
    199 PassRefPtr<FrameView> FrameView::create(Frame* frame)
    200 {
    201     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
    202     view->show();
    203     return view.release();
    204 }
    205 
    206 PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize)
    207 {
    208     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
    209     view->Widget::setFrameRect(IntRect(view->location(), initialSize));
    210     view->show();
    211     return view.release();
    212 }
    213 
    214 FrameView::~FrameView()
    215 {
    216     if (m_postLayoutTasksTimer.isActive()) {
    217         m_postLayoutTasksTimer.stop();
    218         m_actionScheduler->clear();
    219     }
    220 
    221     removeFromAXObjectCache();
    222     resetScrollbars();
    223 
    224     // Custom scrollbars should already be destroyed at this point
    225     ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
    226     ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
    227 
    228     setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
    229     setHasVerticalScrollbar(false);
    230 
    231     ASSERT(!m_scrollCorner);
    232     ASSERT(m_actionScheduler->isEmpty());
    233 
    234     if (m_frame) {
    235         ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
    236         RenderPart* renderer = m_frame->ownerRenderer();
    237         if (renderer && renderer->widget() == this)
    238             renderer->setWidget(0);
    239     }
    240 }
    241 
    242 void FrameView::reset()
    243 {
    244     m_cannotBlitToWindow = false;
    245     m_isOverlapped = false;
    246     m_contentIsOpaque = false;
    247     m_borderX = 30;
    248     m_borderY = 30;
    249     m_layoutTimer.stop();
    250     m_layoutRoot = 0;
    251     m_delayedLayout = false;
    252     m_doFullRepaint = true;
    253     m_layoutSchedulingEnabled = true;
    254     m_inLayout = false;
    255     m_doingPreLayoutStyleUpdate = false;
    256     m_inSynchronousPostLayout = false;
    257     m_layoutCount = 0;
    258     m_nestedLayoutCount = 0;
    259     m_postLayoutTasksTimer.stop();
    260     m_firstLayout = true;
    261     m_firstLayoutCallbackPending = false;
    262     m_wasScrolledByUser = false;
    263     m_safeToPropagateScrollToParent = true;
    264     m_lastViewportSize = IntSize();
    265     m_lastZoomFactor = 1.0f;
    266     m_deferringRepaints = 0;
    267     m_repaintCount = 0;
    268     m_repaintRects.clear();
    269     m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading;
    270     m_deferredRepaintTimer.stop();
    271     m_isTrackingRepaints = false;
    272     m_trackedRepaintRects.clear();
    273     m_lastPaintTime = 0;
    274     m_paintBehavior = PaintBehaviorNormal;
    275     m_isPainting = false;
    276     m_visuallyNonEmptyCharacterCount = 0;
    277     m_visuallyNonEmptyPixelCount = 0;
    278     m_isVisuallyNonEmpty = false;
    279     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
    280     m_maintainScrollPositionAnchor = 0;
    281     m_disableRepaints = 0;
    282 }
    283 
    284 void FrameView::removeFromAXObjectCache()
    285 {
    286     if (AXObjectCache* cache = axObjectCache())
    287         cache->remove(this);
    288 }
    289 
    290 void FrameView::clearFrame()
    291 {
    292     RELEASE_ASSERT(!isInLayout());
    293     m_frame = 0;
    294 }
    295 
    296 void FrameView::resetScrollbars()
    297 {
    298     // Reset the document's scrollbars back to our defaults before we yield the floor.
    299     m_firstLayout = true;
    300     setScrollbarsSuppressed(true);
    301     if (m_canHaveScrollbars)
    302         setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
    303     else
    304         setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
    305     setScrollbarsSuppressed(false);
    306 }
    307 
    308 void FrameView::init()
    309 {
    310     reset();
    311 
    312     m_margins = LayoutSize(-1, -1); // undefined
    313     m_size = LayoutSize();
    314 
    315     // Propagate the marginwidth/height and scrolling modes to the view.
    316     Element* ownerElement = m_frame ? m_frame->ownerElement() : 0;
    317     if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
    318         HTMLFrameElementBase* frameElt = static_cast<HTMLFrameElementBase*>(ownerElement);
    319         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
    320             setCanHaveScrollbars(false);
    321         LayoutUnit marginWidth = frameElt->marginWidth();
    322         LayoutUnit marginHeight = frameElt->marginHeight();
    323         if (marginWidth != -1)
    324             setMarginWidth(marginWidth);
    325         if (marginHeight != -1)
    326             setMarginHeight(marginHeight);
    327     }
    328 }
    329 
    330 void FrameView::prepareForDetach()
    331 {
    332     RELEASE_ASSERT(!isInLayout());
    333 
    334     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
    335         scrollAnimator->cancelAnimations();
    336 
    337     detachCustomScrollbars();
    338     // When the view is no longer associated with a frame, it needs to be removed from the ax object cache
    339     // right now, otherwise it won't be able to reach the topDocument()'s axObject cache later.
    340     removeFromAXObjectCache();
    341 
    342     if (m_frame && m_frame->page()) {
    343         if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator())
    344             scrollingCoordinator->willDestroyScrollableArea(this);
    345     }
    346 }
    347 
    348 void FrameView::detachCustomScrollbars()
    349 {
    350     Scrollbar* horizontalBar = horizontalScrollbar();
    351     if (horizontalBar && horizontalBar->isCustomScrollbar())
    352         setHasHorizontalScrollbar(false);
    353 
    354     Scrollbar* verticalBar = verticalScrollbar();
    355     if (verticalBar && verticalBar->isCustomScrollbar())
    356         setHasVerticalScrollbar(false);
    357 
    358     if (m_scrollCorner) {
    359         m_scrollCorner->destroy();
    360         m_scrollCorner = 0;
    361     }
    362 }
    363 
    364 void FrameView::recalculateScrollbarOverlayStyle()
    365 {
    366     ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
    367     ScrollbarOverlayStyle overlayStyle = ScrollbarOverlayStyleDefault;
    368 
    369     StyleColor backgroundColor = documentBackgroundColor();
    370     if (backgroundColor.isValid()) {
    371         // Reduce the background color from RGB to a lightness value
    372         // and determine which scrollbar style to use based on a lightness
    373         // heuristic.
    374         double hue, saturation, lightness;
    375         backgroundColor.color().getHSL(hue, saturation, lightness);
    376         if (lightness <= .5)
    377             overlayStyle = ScrollbarOverlayStyleLight;
    378     }
    379 
    380     if (oldOverlayStyle != overlayStyle)
    381         setScrollbarOverlayStyle(overlayStyle);
    382 }
    383 
    384 void FrameView::clear()
    385 {
    386     setCanBlitOnScroll(true);
    387 
    388     reset();
    389 
    390     if (m_frame) {
    391         if (RenderPart* renderer = m_frame->ownerRenderer())
    392             renderer->viewCleared();
    393     }
    394 
    395     setScrollbarsSuppressed(true);
    396 }
    397 
    398 bool FrameView::didFirstLayout() const
    399 {
    400     return !m_firstLayout;
    401 }
    402 
    403 void FrameView::invalidateRect(const IntRect& rect)
    404 {
    405     if (!parent()) {
    406         if (HostWindow* window = hostWindow())
    407             window->invalidateContentsAndRootView(rect);
    408         return;
    409     }
    410 
    411     if (!m_frame)
    412         return;
    413 
    414     RenderPart* renderer = m_frame->ownerRenderer();
    415     if (!renderer)
    416         return;
    417 
    418     IntRect repaintRect = rect;
    419     repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
    420                      renderer->borderTop() + renderer->paddingTop());
    421     renderer->repaintRectangle(repaintRect);
    422 }
    423 
    424 void FrameView::setFrameRect(const IntRect& newRect)
    425 {
    426     IntRect oldRect = frameRect();
    427     if (newRect == oldRect)
    428         return;
    429 
    430     // Autosized font sizes depend on the width of the viewing area.
    431     if (newRect.width() != oldRect.width()) {
    432         Page* page = m_frame ? m_frame->page() : 0;
    433         if (page && page->mainFrame() == m_frame && page->settings()->textAutosizingEnabled()) {
    434             for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
    435                 m_frame->document()->textAutosizer()->recalculateMultipliers();
    436         }
    437     }
    438 
    439     ScrollView::setFrameRect(newRect);
    440 
    441     updateScrollableAreaSet();
    442 
    443     if (RenderView* renderView = this->renderView()) {
    444         if (renderView->usesCompositing())
    445             renderView->compositor()->frameViewDidChangeSize();
    446     }
    447 }
    448 
    449 bool FrameView::scheduleAnimation()
    450 {
    451     if (HostWindow* window = hostWindow()) {
    452         window->scheduleAnimation();
    453         return true;
    454     }
    455     return false;
    456 }
    457 
    458 void FrameView::setMarginWidth(LayoutUnit w)
    459 {
    460     // make it update the rendering area when set
    461     m_margins.setWidth(w);
    462 }
    463 
    464 void FrameView::setMarginHeight(LayoutUnit h)
    465 {
    466     // make it update the rendering area when set
    467     m_margins.setHeight(h);
    468 }
    469 
    470 void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
    471 {
    472     m_canHaveScrollbars = canHaveScrollbars;
    473     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
    474 }
    475 
    476 void FrameView::updateCanHaveScrollbars()
    477 {
    478     ScrollbarMode hMode;
    479     ScrollbarMode vMode;
    480     scrollbarModes(hMode, vMode);
    481     if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
    482         setCanHaveScrollbars(false);
    483     else
    484         setCanHaveScrollbars(true);
    485 }
    486 
    487 PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
    488 {
    489     if (Settings* settings = m_frame->settings()) {
    490         if (!settings->allowCustomScrollbarInMainFrame() && m_frame->page() && m_frame->page()->mainFrame() == m_frame)
    491             return ScrollView::createScrollbar(orientation);
    492     }
    493 
    494     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
    495     Document* doc = m_frame->document();
    496 
    497     // Try the <body> element first as a scrollbar source.
    498     Element* body = doc ? doc->body() : 0;
    499     if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR))
    500         return RenderScrollbar::createCustomScrollbar(this, orientation, body);
    501 
    502     // If the <body> didn't have a custom style, then the root element might.
    503     Element* docElement = doc ? doc->documentElement() : 0;
    504     if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(SCROLLBAR))
    505         return RenderScrollbar::createCustomScrollbar(this, orientation, docElement);
    506 
    507     // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
    508     RenderPart* frameRenderer = m_frame->ownerRenderer();
    509     if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR))
    510         return RenderScrollbar::createCustomScrollbar(this, orientation, 0, m_frame.get());
    511 
    512     // Nobody set a custom style, so we just use a native scrollbar.
    513     return ScrollView::createScrollbar(orientation);
    514 }
    515 
    516 void FrameView::setContentsSize(const IntSize& size)
    517 {
    518     if (size == contentsSize())
    519         return;
    520 
    521     m_deferSetNeedsLayouts++;
    522 
    523     ScrollView::setContentsSize(size);
    524     ScrollView::contentsResized();
    525 
    526     Page* page = frame() ? frame()->page() : 0;
    527     if (!page)
    528         return;
    529 
    530     updateScrollableAreaSet();
    531 
    532     page->chrome().contentsSizeChanged(frame(), size); // Notify only.
    533 
    534     m_deferSetNeedsLayouts--;
    535 
    536     if (!m_deferSetNeedsLayouts)
    537         m_setNeedsLayoutWasDeferred = false; // FIXME: Find a way to make the deferred layout actually happen.
    538 }
    539 
    540 void FrameView::adjustViewSize()
    541 {
    542     RenderView* renderView = this->renderView();
    543     if (!renderView)
    544         return;
    545 
    546     ASSERT(m_frame->view() == this);
    547 
    548     const IntRect rect = renderView->documentRect();
    549     const IntSize& size = rect.size();
    550     ScrollView::setScrollOrigin(IntPoint(-rect.x(), -rect.y()), !m_frame->document()->printing(), size == contentsSize());
    551 
    552     setContentsSize(size);
    553 }
    554 
    555 void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
    556 {
    557     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
    558     // overflow:hidden and overflow:scroll on <body> as applying to the document's
    559     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
    560     // use the root element.
    561 
    562     EOverflow overflowX = o->style()->overflowX();
    563     EOverflow overflowY = o->style()->overflowY();
    564 
    565     if (o->isSVGRoot()) {
    566         // overflow is ignored in stand-alone SVG documents.
    567         if (!toRenderSVGRoot(o)->isEmbeddedThroughFrameContainingSVGDocument())
    568             return;
    569         overflowX = OHIDDEN;
    570         overflowY = OHIDDEN;
    571     }
    572 
    573     bool ignoreOverflowHidden = false;
    574     if (m_frame->page()->settings()->ignoreMainFrameOverflowHiddenQuirk() && m_frame->page()->mainFrame() == m_frame)
    575         ignoreOverflowHidden = true;
    576 
    577     switch (overflowX) {
    578         case OHIDDEN:
    579             if (!ignoreOverflowHidden)
    580                 hMode = ScrollbarAlwaysOff;
    581             break;
    582         case OSCROLL:
    583             hMode = ScrollbarAlwaysOn;
    584             break;
    585         case OAUTO:
    586             hMode = ScrollbarAuto;
    587             break;
    588         default:
    589             // Don't set it at all.
    590             ;
    591     }
    592 
    593      switch (overflowY) {
    594         case OHIDDEN:
    595             if (!ignoreOverflowHidden)
    596                 vMode = ScrollbarAlwaysOff;
    597             break;
    598         case OSCROLL:
    599             vMode = ScrollbarAlwaysOn;
    600             break;
    601         case OAUTO:
    602             vMode = ScrollbarAuto;
    603             break;
    604         default:
    605             // Don't set it at all. Values of OPAGEDX and OPAGEDY are handled by applyPaginationToViewPort().
    606             ;
    607     }
    608 
    609     m_viewportRenderer = o;
    610 }
    611 
    612 void FrameView::applyPaginationToViewport()
    613 {
    614     Document* document = m_frame->document();
    615     Node* documentElement = document->documentElement();
    616     RenderObject* documentRenderer = documentElement ? documentElement->renderer() : 0;
    617     RenderObject* documentOrBodyRenderer = documentRenderer;
    618     Node* body = document->body();
    619     if (body && body->renderer()) {
    620         if (body->hasTagName(bodyTag))
    621             documentOrBodyRenderer = documentRenderer->style()->overflowX() == OVISIBLE && isHTMLHtmlElement(documentElement) ? body->renderer() : documentRenderer;
    622     }
    623 
    624     Pagination pagination;
    625 
    626     if (!documentOrBodyRenderer) {
    627         setPagination(pagination);
    628         return;
    629     }
    630 
    631     EOverflow overflowY = documentOrBodyRenderer->style()->overflowY();
    632     if (overflowY == OPAGEDX || overflowY == OPAGEDY) {
    633         pagination.mode = WebCore::paginationModeForRenderStyle(documentOrBodyRenderer->style());
    634         pagination.gap = static_cast<unsigned>(documentOrBodyRenderer->style()->columnGap());
    635     }
    636 
    637     setPagination(pagination);
    638 }
    639 
    640 void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
    641 {
    642     m_viewportRenderer = 0;
    643 
    644     const HTMLFrameOwnerElement* owner = m_frame->ownerElement();
    645     if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
    646         hMode = ScrollbarAlwaysOff;
    647         vMode = ScrollbarAlwaysOff;
    648         return;
    649     }
    650 
    651     if (m_canHaveScrollbars || strategy == RulesFromWebContentOnly) {
    652         hMode = ScrollbarAuto;
    653         // Seamless documents begin with heights of 0; we special case that here
    654         // to correctly render documents that don't need scrollbars.
    655         IntSize fullVisibleSize = visibleContentRect(IncludeScrollbars).size();
    656         bool isSeamlessDocument = frame() && frame()->document() && frame()->document()->shouldDisplaySeamlesslyWithParent();
    657         vMode = (isSeamlessDocument && !fullVisibleSize.height()) ? ScrollbarAlwaysOff : ScrollbarAuto;
    658     } else {
    659         hMode = ScrollbarAlwaysOff;
    660         vMode = ScrollbarAlwaysOff;
    661     }
    662 
    663     if (!m_layoutRoot) {
    664         Document* document = m_frame->document();
    665         Node* documentElement = document->documentElement();
    666         RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
    667         Node* body = document->body();
    668         if (body && body->renderer()) {
    669             if (body->hasTagName(framesetTag)) {
    670                 vMode = ScrollbarAlwaysOff;
    671                 hMode = ScrollbarAlwaysOff;
    672             } else if (body->hasTagName(bodyTag)) {
    673                 // It's sufficient to just check the X overflow,
    674                 // since it's illegal to have visible in only one direction.
    675                 RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && isHTMLHtmlElement(document->documentElement()) ? body->renderer() : rootRenderer;
    676                 applyOverflowToViewport(o, hMode, vMode);
    677             }
    678         } else if (rootRenderer)
    679             applyOverflowToViewport(rootRenderer, hMode, vMode);
    680     }
    681 }
    682 
    683 void FrameView::updateCompositingLayersAfterStyleChange()
    684 {
    685     RenderView* renderView = this->renderView();
    686     if (!renderView)
    687         return;
    688 
    689     // If we expect to update compositing after an incipient layout, don't do so here.
    690     if (m_doingPreLayoutStyleUpdate || layoutPending() || renderView->needsLayout())
    691         return;
    692 
    693     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
    694     renderView->compositor()->cacheAcceleratedCompositingFlags();
    695 
    696     // Sometimes we will change a property (for example, z-index) that will not
    697     // cause a layout, but will require us to update compositing state. We only
    698     // need to do this if a layout is not already scheduled.
    699     if (!needsLayout())
    700         renderView->compositor()->updateCompositingRequirementsState();
    701 
    702     renderView->compositor()->updateCompositingLayers(CompositingUpdateAfterStyleChange);
    703 }
    704 
    705 void FrameView::updateCompositingLayersAfterLayout()
    706 {
    707     RenderView* renderView = this->renderView();
    708     if (!renderView)
    709         return;
    710 
    711     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
    712     renderView->compositor()->cacheAcceleratedCompositingFlags();
    713     renderView->compositor()->updateCompositingRequirementsState();
    714     renderView->compositor()->updateCompositingLayers(CompositingUpdateAfterLayout);
    715 }
    716 
    717 bool FrameView::usesCompositedScrolling() const
    718 {
    719     RenderView* renderView = this->renderView();
    720     if (!renderView)
    721         return false;
    722     if (m_frame->settings() && m_frame->settings()->compositedScrollingForFramesEnabled())
    723         return renderView->compositor()->inForcedCompositingMode();
    724     return false;
    725 }
    726 
    727 GraphicsLayer* FrameView::layerForScrolling() const
    728 {
    729     RenderView* renderView = this->renderView();
    730     if (!renderView)
    731         return 0;
    732     return renderView->compositor()->scrollLayer();
    733 }
    734 
    735 GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
    736 {
    737     RenderView* renderView = this->renderView();
    738     if (!renderView)
    739         return 0;
    740     return renderView->compositor()->layerForHorizontalScrollbar();
    741 }
    742 
    743 GraphicsLayer* FrameView::layerForVerticalScrollbar() const
    744 {
    745     RenderView* renderView = this->renderView();
    746     if (!renderView)
    747         return 0;
    748     return renderView->compositor()->layerForVerticalScrollbar();
    749 }
    750 
    751 GraphicsLayer* FrameView::layerForScrollCorner() const
    752 {
    753     RenderView* renderView = this->renderView();
    754     if (!renderView)
    755         return 0;
    756     return renderView->compositor()->layerForScrollCorner();
    757 }
    758 
    759 #if ENABLE(RUBBER_BANDING)
    760 GraphicsLayer* FrameView::layerForOverhangAreas() const
    761 {
    762     RenderView* renderView = this->renderView();
    763     if (!renderView)
    764         return 0;
    765     return renderView->compositor()->layerForOverhangAreas();
    766 }
    767 #endif // ENABLE(RUBBER_BANDING)
    768 
    769 bool FrameView::hasCompositedContent() const
    770 {
    771     if (RenderView* renderView = this->renderView())
    772         return renderView->compositor()->inCompositingMode();
    773     return false;
    774 }
    775 
    776 bool FrameView::isEnclosedInCompositingLayer() const
    777 {
    778     RenderObject* frameOwnerRenderer = m_frame->ownerRenderer();
    779     if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
    780         return true;
    781 
    782     if (FrameView* parentView = parentFrameView())
    783         return parentView->isEnclosedInCompositingLayer();
    784 
    785     return false;
    786 }
    787 
    788 bool FrameView::isSoftwareRenderable() const
    789 {
    790     RenderView* renderView = this->renderView();
    791     return !renderView || !renderView->compositor()->has3DContent();
    792 }
    793 
    794 RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
    795 {
    796     return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
    797 }
    798 
    799 static inline void collectFrameViewChildren(FrameView* frameView, Vector<RefPtr<FrameView> >& frameViews)
    800 {
    801     const HashSet<RefPtr<Widget> >* viewChildren = frameView->children();
    802     ASSERT(viewChildren);
    803 
    804     const HashSet<RefPtr<Widget> >::iterator end = viewChildren->end();
    805     for (HashSet<RefPtr<Widget> >::iterator current = viewChildren->begin(); current != end; ++current) {
    806         Widget* widget = (*current).get();
    807         if (widget->isFrameView())
    808             frameViews.append(toFrameView(widget));
    809     }
    810 }
    811 
    812 inline void FrameView::forceLayoutParentViewIfNeeded()
    813 {
    814     RenderPart* ownerRenderer = m_frame->ownerRenderer();
    815     if (!ownerRenderer || !ownerRenderer->frame())
    816         return;
    817 
    818     RenderBox* contentBox = embeddedContentBox();
    819     if (!contentBox)
    820         return;
    821 
    822     RenderSVGRoot* svgRoot = toRenderSVGRoot(contentBox);
    823     if (svgRoot->everHadLayout() && !svgRoot->needsLayout())
    824         return;
    825 
    826     // If the embedded SVG document appears the first time, the ownerRenderer has already finished
    827     // layout without knowing about the existence of the embedded SVG document, because RenderReplaced
    828     // embeddedContentBox() returns 0, as long as the embedded document isn't loaded yet. Before
    829     // bothering to lay out the SVG document, mark the ownerRenderer needing layout and ask its
    830     // FrameView for a layout. After that the RenderEmbeddedObject (ownerRenderer) carries the
    831     // correct size, which RenderSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying
    832     // out for the first time, or when the RenderSVGRoot size has changed dynamically (eg. via <script>).
    833     RefPtr<FrameView> frameView = ownerRenderer->frame()->view();
    834 
    835     // Mark the owner renderer as needing layout.
    836     ownerRenderer->setNeedsLayoutAndPrefWidthsRecalc();
    837 
    838     // Synchronously enter layout, to layout the view containing the host object/embed/iframe.
    839     ASSERT(frameView);
    840     frameView->layout();
    841 }
    842 
    843 void FrameView::layout(bool allowSubtree)
    844 {
    845     // We should never layout a Document which is not in a Frame.
    846     ASSERT(m_frame);
    847     ASSERT(m_frame->view() == this);
    848     ASSERT(m_frame->page());
    849 
    850     if (m_inLayout)
    851         return;
    852 
    853     TRACE_EVENT0("webkit", "FrameView::layout");
    854     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "Layout");
    855 
    856     // Protect the view from being deleted during layout (in recalcStyle)
    857     RefPtr<FrameView> protector(this);
    858 
    859     // Every scroll that happens during layout is programmatic.
    860     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
    861 
    862     m_layoutTimer.stop();
    863     m_delayedLayout = false;
    864     m_setNeedsLayoutWasDeferred = false;
    865 
    866     // we shouldn't enter layout() while painting
    867     ASSERT(!isPainting());
    868     if (isPainting())
    869         return;
    870 
    871     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(m_frame.get());
    872 
    873     if (!allowSubtree && m_layoutRoot) {
    874         m_layoutRoot->markContainingBlocksForLayout(false);
    875         m_layoutRoot = 0;
    876     }
    877 
    878     Document* document = m_frame->document();
    879     bool inSubtreeLayout = false;
    880     RenderObject* rootForThisLayout = 0;
    881 
    882     {
    883         TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
    884 
    885         if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive() && !frame()->document()->shouldDisplaySeamlesslyWithParent()) {
    886             // This is a new top-level layout. If there are any remaining tasks from the previous layout, finish them now.
    887             m_inSynchronousPostLayout = true;
    888             performPostLayoutTasks();
    889             m_inSynchronousPostLayout = false;
    890         }
    891 
    892         // Viewport-dependent media queries may cause us to need completely different style information.
    893         if (!document->styleResolverIfExists() || document->styleResolverIfExists()->affectedByViewportChange()) {
    894             document->styleResolverChanged(DeferRecalcStyle);
    895             // FIXME: This instrumentation event is not strictly accurate since cached media query results
    896             //        do not persist across StyleResolver rebuilds.
    897             InspectorInstrumentation::mediaQueryResultChanged(document);
    898         } else {
    899             document->evaluateMediaQueryList();
    900         }
    901 
    902         // If there is any pagination to apply, it will affect the RenderView's style, so we should
    903         // take care of that now.
    904         applyPaginationToViewport();
    905 
    906         // Always ensure our style info is up-to-date. This can happen in situations where
    907         // the layout beats any sort of style recalc update that needs to occur.
    908         TemporaryChange<bool> changeDoingPreLayoutStyleUpdate(m_doingPreLayoutStyleUpdate, true);
    909         document->updateStyleIfNeeded();
    910 
    911         inSubtreeLayout = m_layoutRoot;
    912 
    913         // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
    914         // so there's no point to continuing to layout
    915         if (protector->hasOneRef())
    916             return;
    917 
    918         rootForThisLayout = inSubtreeLayout ? m_layoutRoot : document->renderer();
    919         if (!rootForThisLayout) {
    920             // FIXME: Do we need to set m_size here?
    921             return;
    922         }
    923     } // Reset m_layoutSchedulingEnabled to its previous value.
    924     // The only reason the scoping was closed here is allow fontCachePurgePreventer
    925     // to outlive the change and reset of m_layoutSchedulingEnabled.
    926 
    927     FontCachePurgePreventer fontCachePurgePreventer;
    928     RenderLayer* layer;
    929     {
    930         TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
    931 
    932         m_nestedLayoutCount++;
    933 
    934         autoSizeIfEnabled();
    935 
    936         ScrollbarMode hMode;
    937         ScrollbarMode vMode;
    938         calculateScrollbarModesForLayout(hMode, vMode);
    939 
    940         m_doFullRepaint = !inSubtreeLayout && (m_firstLayout || toRenderView(rootForThisLayout)->printing());
    941 
    942         if (!inSubtreeLayout) {
    943             // Now set our scrollbar state for the layout.
    944             ScrollbarMode currentHMode = horizontalScrollbarMode();
    945             ScrollbarMode currentVMode = verticalScrollbarMode();
    946 
    947             if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
    948                 if (m_firstLayout) {
    949                     setScrollbarsSuppressed(true);
    950 
    951                     m_firstLayout = false;
    952                     m_firstLayoutCallbackPending = true;
    953                     m_lastViewportSize = layoutSize(IncludeScrollbars);
    954                     m_lastZoomFactor = rootForThisLayout->style()->zoom();
    955 
    956                     // Set the initial vMode to AlwaysOn if we're auto.
    957                     if (vMode == ScrollbarAuto)
    958                         setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
    959                     // Set the initial hMode to AlwaysOff if we're auto.
    960                     if (hMode == ScrollbarAuto)
    961                         setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
    962 
    963                     setScrollbarModes(hMode, vMode);
    964                     setScrollbarsSuppressed(false, true);
    965                 } else
    966                     setScrollbarModes(hMode, vMode);
    967             }
    968 
    969             LayoutSize oldSize = m_size;
    970 
    971             m_size = LayoutSize(layoutWidth(), layoutHeight());
    972 
    973             if (oldSize != m_size) {
    974                 m_doFullRepaint = true;
    975                 if (!m_firstLayout) {
    976                     RenderBox* rootRenderer = document->documentElement() ? document->documentElement()->renderBox() : 0;
    977                     RenderBox* bodyRenderer = rootRenderer && document->body() ? document->body()->renderBox() : 0;
    978                     if (bodyRenderer && bodyRenderer->stretchesToViewport())
    979                         bodyRenderer->setChildNeedsLayout();
    980                     else if (rootRenderer && rootRenderer->stretchesToViewport())
    981                         rootRenderer->setChildNeedsLayout();
    982                 }
    983             }
    984         }
    985 
    986         layer = rootForThisLayout->enclosingLayer();
    987 
    988         m_actionScheduler->pause();
    989 
    990         {
    991             bool disableLayoutState = false;
    992             if (inSubtreeLayout) {
    993                 RenderView* view = rootForThisLayout->view();
    994                 disableLayoutState = view->shouldDisableLayoutStateForSubtree(rootForThisLayout);
    995                 view->pushLayoutState(rootForThisLayout);
    996             }
    997             LayoutStateDisabler layoutStateDisabler(disableLayoutState ? rootForThisLayout->view() : 0);
    998 
    999             m_inLayout = true;
   1000             beginDeferredRepaints();
   1001             forceLayoutParentViewIfNeeded();
   1002             rootForThisLayout->layout();
   1003 
   1004             bool autosized = document->textAutosizer()->processSubtree(rootForThisLayout);
   1005             if (autosized && rootForThisLayout->needsLayout()) {
   1006                 TRACE_EVENT0("webkit", "2nd layout due to Text Autosizing");
   1007                 rootForThisLayout->layout();
   1008             }
   1009 
   1010             endDeferredRepaints();
   1011             m_inLayout = false;
   1012 
   1013             if (inSubtreeLayout)
   1014                 rootForThisLayout->view()->popLayoutState(rootForThisLayout);
   1015         }
   1016         m_layoutRoot = 0;
   1017     } // Reset m_layoutSchedulingEnabled to its previous value.
   1018 
   1019     bool neededFullRepaint = m_doFullRepaint;
   1020 
   1021     if (!inSubtreeLayout && !toRenderView(rootForThisLayout)->printing())
   1022         adjustViewSize();
   1023 
   1024     m_doFullRepaint = neededFullRepaint;
   1025 
   1026     // Now update the positions of all layers.
   1027     beginDeferredRepaints();
   1028     if (m_doFullRepaint)
   1029         rootForThisLayout->view()->repaint(); // FIXME: This isn't really right, since the RenderView doesn't fully encompass the visibleContentRect(). It just happens
   1030                                  // to work out most of the time, since first layouts and printing don't have you scrolled anywhere.
   1031 
   1032     layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layer, inSubtreeLayout, m_doFullRepaint));
   1033 
   1034     endDeferredRepaints();
   1035 
   1036     updateCompositingLayersAfterLayout();
   1037 
   1038     m_layoutCount++;
   1039 
   1040     if (AXObjectCache* cache = rootForThisLayout->document()->existingAXObjectCache())
   1041         cache->postNotification(rootForThisLayout, AXObjectCache::AXLayoutComplete, true);
   1042     updateAnnotatedRegions();
   1043 
   1044     layoutLazyBlocks();
   1045 
   1046     ASSERT(!rootForThisLayout->needsLayout());
   1047 
   1048     updateCanBlitOnScrollRecursively();
   1049 
   1050     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
   1051         updateOverflowStatus(layoutWidth() < contentsWidth(), layoutHeight() < contentsHeight());
   1052 
   1053     if (!m_postLayoutTasksTimer.isActive()) {
   1054         if (!m_inSynchronousPostLayout) {
   1055             if (frame()->document()->shouldDisplaySeamlesslyWithParent()) {
   1056                 if (RenderView* renderView = this->renderView())
   1057                     renderView->updateWidgetPositions();
   1058             } else {
   1059                 m_inSynchronousPostLayout = true;
   1060                 // Calls resumeScheduledEvents()
   1061                 performPostLayoutTasks();
   1062                 m_inSynchronousPostLayout = false;
   1063             }
   1064         }
   1065 
   1066         if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout || frame()->document()->shouldDisplaySeamlesslyWithParent())) {
   1067             // If we need layout or are already in a synchronous call to postLayoutTasks(),
   1068             // defer widget updates and event dispatch until after we return. postLayoutTasks()
   1069             // can make us need to update again, and we can get stuck in a nasty cycle unless
   1070             // we call it through the timer here.
   1071             m_postLayoutTasksTimer.startOneShot(0);
   1072             if (needsLayout()) {
   1073                 m_actionScheduler->pause();
   1074                 layout();
   1075             }
   1076         }
   1077     } else {
   1078         m_actionScheduler->resume();
   1079     }
   1080 
   1081     InspectorInstrumentation::didLayout(cookie, rootForThisLayout);
   1082 
   1083     m_nestedLayoutCount--;
   1084     if (m_nestedLayoutCount)
   1085         return;
   1086 
   1087 #ifndef NDEBUG
   1088     // Post-layout assert that nobody was re-marked as needing layout during layout.
   1089     for (RenderObject* renderer = document->renderer(); renderer; renderer = renderer->nextInPreOrder())
   1090         ASSERT(!renderer->needsLayout());
   1091 #endif
   1092 
   1093     // FIXME: It should be not possible to remove the FrameView from the frame/page during layout
   1094     // however m_inLayout is not set for most of this function, so none of our RELEASE_ASSERTS
   1095     // in Frame/Page will fire. One of the post-layout tasks is disconnecting the Frame from
   1096     // the page in fast/frames/crash-remove-iframe-during-object-beforeload-2.html
   1097     // necessitating this check here.
   1098     ASSERT(frame());
   1099     // ASSERT(frame()->page());
   1100     if (frame() && frame()->page())
   1101         frame()->page()->chrome().client()->layoutUpdated(frame());
   1102 }
   1103 
   1104 void FrameView::layoutLazyBlocks()
   1105 {
   1106     // FIXME: This infinite recursion protection would seem to break plugins
   1107     // doing things that require lazy blocks to layout.
   1108     if (m_nestedLayoutCount != 1)
   1109         return;
   1110 
   1111     if (!renderView()->firstLazyBlock())
   1112         return;
   1113 
   1114     // First mark all lazy blocks as needing layout and perform another layout.
   1115     for (RenderLazyBlock* block = renderView()->firstLazyBlock(); block; block = block->next())
   1116         block->markForNestedLayout();
   1117 
   1118     layout();
   1119 
   1120     // FIXME: This is pretty awful if you start nesting lazy blocks, we should
   1121     // signal to the nested blocks to avoid doing work until the second pass.
   1122 
   1123     // Next walk all lazy blocks and find nested ones, these need another layout
   1124     // since the first one would not have placed them correctly inside the viewport.
   1125     for (RenderLazyBlock* block = renderView()->firstLazyBlock(); block; block = block->next()) {
   1126         if (!block->isNested())
   1127             continue;
   1128         block->setNeedsLayout();
   1129         layout();
   1130     }
   1131 }
   1132 
   1133 RenderBox* FrameView::embeddedContentBox() const
   1134 {
   1135     RenderView* renderView = this->renderView();
   1136     if (!renderView)
   1137         return 0;
   1138 
   1139     RenderObject* firstChild = renderView->firstChild();
   1140     if (!firstChild || !firstChild->isBox())
   1141         return 0;
   1142 
   1143     // Curently only embedded SVG documents participate in the size-negotiation logic.
   1144     if (firstChild->isSVGRoot())
   1145         return toRenderBox(firstChild);
   1146 
   1147     return 0;
   1148 }
   1149 
   1150 void FrameView::addWidgetToUpdate(RenderObject* object)
   1151 {
   1152     if (!m_widgetUpdateSet)
   1153         m_widgetUpdateSet = adoptPtr(new RenderObjectSet);
   1154 
   1155     // Tell the DOM element that it needs a widget update.
   1156     Node* node = object->node();
   1157     if (node->hasTagName(objectTag) || node->hasTagName(embedTag)) {
   1158         HTMLPlugInImageElement* pluginElement = toHTMLPlugInImageElement(node);
   1159         pluginElement->setNeedsWidgetUpdate(true);
   1160     }
   1161 
   1162     m_widgetUpdateSet->add(object);
   1163 }
   1164 
   1165 void FrameView::removeWidgetToUpdate(RenderObject* object)
   1166 {
   1167     if (!m_widgetUpdateSet)
   1168         return;
   1169 
   1170     m_widgetUpdateSet->remove(object);
   1171 }
   1172 
   1173 void FrameView::setMediaType(const AtomicString& mediaType)
   1174 {
   1175     m_mediaType = mediaType;
   1176 }
   1177 
   1178 AtomicString FrameView::mediaType() const
   1179 {
   1180     // See if we have an override type.
   1181     String overrideType;
   1182     InspectorInstrumentation::applyEmulatedMedia(m_frame.get(), &overrideType);
   1183     if (!overrideType.isNull())
   1184         return overrideType;
   1185     return m_mediaType;
   1186 }
   1187 
   1188 void FrameView::adjustMediaTypeForPrinting(bool printing)
   1189 {
   1190     if (printing) {
   1191         if (m_mediaTypeWhenNotPrinting.isNull())
   1192             m_mediaTypeWhenNotPrinting = mediaType();
   1193             setMediaType("print");
   1194     } else {
   1195         if (!m_mediaTypeWhenNotPrinting.isNull())
   1196             setMediaType(m_mediaTypeWhenNotPrinting);
   1197         m_mediaTypeWhenNotPrinting = nullAtom;
   1198     }
   1199 }
   1200 
   1201 bool FrameView::useSlowRepaints(bool considerOverlap) const
   1202 {
   1203     bool mustBeSlow = m_slowRepaintObjectCount > 0;
   1204 
   1205     if (contentsInCompositedLayer())
   1206         return mustBeSlow;
   1207 
   1208     // The chromium compositor does not support scrolling a non-composited frame within a composited page through
   1209     // the fast scrolling path, so force slow scrolling in that case.
   1210     if (m_frame->ownerElement() && !hasCompositedContent() && m_frame->page() && m_frame->page()->mainFrame()->view()->hasCompositedContent())
   1211         return true;
   1212 
   1213     bool isOverlapped = m_isOverlapped && considerOverlap;
   1214 
   1215     if (mustBeSlow || m_cannotBlitToWindow || isOverlapped || !m_contentIsOpaque)
   1216         return true;
   1217 
   1218     if (FrameView* parentView = parentFrameView())
   1219         return parentView->useSlowRepaints(considerOverlap);
   1220 
   1221     return false;
   1222 }
   1223 
   1224 bool FrameView::useSlowRepaintsIfNotOverlapped() const
   1225 {
   1226     return useSlowRepaints(false);
   1227 }
   1228 
   1229 void FrameView::updateCanBlitOnScrollRecursively()
   1230 {
   1231     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
   1232         if (FrameView* view = frame->view())
   1233             view->setCanBlitOnScroll(!view->useSlowRepaints());
   1234     }
   1235 }
   1236 
   1237 bool FrameView::contentsInCompositedLayer() const
   1238 {
   1239     RenderView* renderView = this->renderView();
   1240     if (renderView && renderView->isComposited()) {
   1241         GraphicsLayer* layer = renderView->layer()->backing()->graphicsLayer();
   1242         if (layer && layer->drawsContent())
   1243             return true;
   1244     }
   1245 
   1246     return false;
   1247 }
   1248 
   1249 void FrameView::setCannotBlitToWindow()
   1250 {
   1251     m_cannotBlitToWindow = true;
   1252     updateCanBlitOnScrollRecursively();
   1253 }
   1254 
   1255 void FrameView::addSlowRepaintObject()
   1256 {
   1257     if (!m_slowRepaintObjectCount++) {
   1258         updateCanBlitOnScrollRecursively();
   1259 
   1260         if (Page* page = m_frame->page()) {
   1261             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   1262                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
   1263         }
   1264     }
   1265 }
   1266 
   1267 void FrameView::removeSlowRepaintObject()
   1268 {
   1269     ASSERT(m_slowRepaintObjectCount > 0);
   1270     m_slowRepaintObjectCount--;
   1271     if (!m_slowRepaintObjectCount) {
   1272         updateCanBlitOnScrollRecursively();
   1273 
   1274         if (Page* page = m_frame->page()) {
   1275             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   1276                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
   1277         }
   1278     }
   1279 }
   1280 
   1281 void FrameView::addViewportConstrainedObject(RenderObject* object)
   1282 {
   1283     if (!m_viewportConstrainedObjects)
   1284         m_viewportConstrainedObjects = adoptPtr(new ViewportConstrainedObjectSet);
   1285 
   1286     if (!m_viewportConstrainedObjects->contains(object)) {
   1287         m_viewportConstrainedObjects->add(object);
   1288 
   1289         if (Page* page = m_frame->page()) {
   1290             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   1291                 scrollingCoordinator->frameViewFixedObjectsDidChange(this);
   1292         }
   1293     }
   1294 }
   1295 
   1296 void FrameView::removeViewportConstrainedObject(RenderObject* object)
   1297 {
   1298     if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->contains(object)) {
   1299         m_viewportConstrainedObjects->remove(object);
   1300         if (Page* page = m_frame->page()) {
   1301             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   1302                 scrollingCoordinator->frameViewFixedObjectsDidChange(this);
   1303         }
   1304 
   1305         // FIXME: In addFixedObject() we only call this if there's a platform widget,
   1306         // why isn't the same check being made here?
   1307         updateCanBlitOnScrollRecursively();
   1308     }
   1309 }
   1310 
   1311 LayoutRect FrameView::viewportConstrainedVisibleContentRect() const
   1312 {
   1313     LayoutRect viewportRect = visibleContentRect();
   1314     // Ignore overhang. No-op when not using rubber banding.
   1315     viewportRect.setLocation(clampScrollPosition(scrollPosition()));
   1316     return viewportRect;
   1317 }
   1318 
   1319 
   1320 IntSize FrameView::scrollOffsetForFixedPosition() const
   1321 {
   1322     return toIntSize(clampScrollPosition(scrollPosition()));
   1323 }
   1324 
   1325 IntPoint FrameView::lastKnownMousePosition() const
   1326 {
   1327     return m_frame ? m_frame->eventHandler()->lastKnownMousePosition() : IntPoint();
   1328 }
   1329 
   1330 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
   1331 {
   1332     if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty()) {
   1333         hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
   1334         return true;
   1335     }
   1336 
   1337     const bool isCompositedContentLayer = contentsInCompositedLayer();
   1338 
   1339     // Get the rects of the fixed objects visible in the rectToScroll
   1340     Region regionToUpdate;
   1341     ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
   1342     for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
   1343         RenderObject* renderer = *it;
   1344         if (!renderer->style()->hasViewportConstrainedPosition())
   1345             continue;
   1346 
   1347         if (renderer->isComposited())
   1348             continue;
   1349 
   1350         // Fixed items should always have layers.
   1351         ASSERT(renderer->hasLayer());
   1352         RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
   1353 
   1354         if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForBoundsOutOfView
   1355             || layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForNoVisibleContent) {
   1356             // Don't invalidate for invisible fixed layers.
   1357             continue;
   1358         }
   1359 
   1360         if (layer->hasAncestorWithFilterOutsets()) {
   1361             // If the fixed layer has a blur/drop-shadow filter applied on at least one of its parents, we cannot
   1362             // scroll using the fast path, otherwise the outsets of the filter will be moved around the page.
   1363             return false;
   1364         }
   1365         IntRect updateRect = pixelSnappedIntRect(layer->repaintRectIncludingNonCompositingDescendants());
   1366         updateRect = contentsToRootView(updateRect);
   1367         if (!isCompositedContentLayer && clipsRepaints())
   1368             updateRect.intersect(rectToScroll);
   1369         if (!updateRect.isEmpty())
   1370             regionToUpdate.unite(updateRect);
   1371     }
   1372 
   1373     // 1) scroll
   1374     hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
   1375 
   1376     // 2) update the area of fixed objects that has been invalidated
   1377     Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
   1378     size_t viewportConstrainedObjectsCount = subRectsToUpdate.size();
   1379     for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) {
   1380         IntRect updateRect = subRectsToUpdate[i];
   1381         IntRect scrolledRect = updateRect;
   1382         scrolledRect.move(scrollDelta);
   1383         updateRect.unite(scrolledRect);
   1384         if (isCompositedContentLayer) {
   1385             updateRect = rootViewToContents(updateRect);
   1386             ASSERT(renderView());
   1387             renderView()->layer()->setBackingNeedsRepaintInRect(updateRect);
   1388             continue;
   1389         }
   1390         if (clipsRepaints())
   1391             updateRect.intersect(rectToScroll);
   1392         hostWindow()->invalidateContentsAndRootView(updateRect);
   1393     }
   1394 
   1395     return true;
   1396 }
   1397 
   1398 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
   1399 {
   1400     if (contentsInCompositedLayer()) {
   1401         IntRect updateRect = visibleContentRect();
   1402         ASSERT(renderView());
   1403         renderView()->layer()->setBackingNeedsRepaintInRect(updateRect);
   1404     }
   1405     if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
   1406         if (isEnclosedInCompositingLayer()) {
   1407             LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
   1408                             frameRenderer->borderTop() + frameRenderer->paddingTop(),
   1409                             visibleWidth(), visibleHeight());
   1410             frameRenderer->repaintRectangle(rect);
   1411             return;
   1412         }
   1413     }
   1414 
   1415     ScrollView::scrollContentsSlowPath(updateRect);
   1416 }
   1417 
   1418 // Note that this gets called at painting time.
   1419 void FrameView::setIsOverlapped(bool isOverlapped)
   1420 {
   1421     if (isOverlapped == m_isOverlapped)
   1422         return;
   1423 
   1424     m_isOverlapped = isOverlapped;
   1425     updateCanBlitOnScrollRecursively();
   1426 }
   1427 
   1428 bool FrameView::isOverlappedIncludingAncestors() const
   1429 {
   1430     if (isOverlapped())
   1431         return true;
   1432 
   1433     if (FrameView* parentView = parentFrameView()) {
   1434         if (parentView->isOverlapped())
   1435             return true;
   1436     }
   1437 
   1438     return false;
   1439 }
   1440 
   1441 void FrameView::setContentIsOpaque(bool contentIsOpaque)
   1442 {
   1443     if (contentIsOpaque == m_contentIsOpaque)
   1444         return;
   1445 
   1446     m_contentIsOpaque = contentIsOpaque;
   1447     updateCanBlitOnScrollRecursively();
   1448 }
   1449 
   1450 void FrameView::restoreScrollbar()
   1451 {
   1452     setScrollbarsSuppressed(false);
   1453 }
   1454 
   1455 bool FrameView::scrollToFragment(const KURL& url)
   1456 {
   1457     // If our URL has no ref, then we have no place we need to jump to.
   1458     // OTOH If CSS target was set previously, we want to set it to 0, recalc
   1459     // and possibly repaint because :target pseudo class may have been
   1460     // set (see bug 11321).
   1461     if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget())
   1462         return false;
   1463 
   1464     String fragmentIdentifier = url.fragmentIdentifier();
   1465     if (scrollToAnchor(fragmentIdentifier))
   1466         return true;
   1467 
   1468     // Try again after decoding the ref, based on the document's encoding.
   1469     if (TextResourceDecoder* decoder = m_frame->document()->decoder())
   1470         return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding()));
   1471 
   1472     return false;
   1473 }
   1474 
   1475 bool FrameView::scrollToAnchor(const String& name)
   1476 {
   1477     ASSERT(m_frame->document());
   1478 
   1479     if (!m_frame->document()->haveStylesheetsLoaded()) {
   1480         m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
   1481         return false;
   1482     }
   1483 
   1484     m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false);
   1485 
   1486     Element* anchorNode = m_frame->document()->findAnchor(name);
   1487 
   1488     // Setting to null will clear the current target.
   1489     m_frame->document()->setCSSTarget(anchorNode);
   1490 
   1491     if (m_frame->document()->isSVGDocument()) {
   1492         if (SVGSVGElement* svg = toSVGDocument(m_frame->document())->rootElement()) {
   1493             svg->setupInitialView(name, anchorNode);
   1494             if (!anchorNode)
   1495                 return true;
   1496         }
   1497     }
   1498 
   1499     // Implement the rule that "" and "top" both mean top of page as in other browsers.
   1500     if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top")))
   1501         return false;
   1502 
   1503     maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document());
   1504 
   1505     // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
   1506     if (anchorNode && anchorNode->isFocusable())
   1507         m_frame->document()->setFocusedElement(anchorNode);
   1508 
   1509     return true;
   1510 }
   1511 
   1512 void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
   1513 {
   1514     m_maintainScrollPositionAnchor = anchorNode;
   1515     if (!m_maintainScrollPositionAnchor)
   1516         return;
   1517 
   1518     // We need to update the layout before scrolling, otherwise we could
   1519     // really mess things up if an anchor scroll comes at a bad moment.
   1520     m_frame->document()->updateStyleIfNeeded();
   1521     // Only do a layout if changes have occurred that make it necessary.
   1522     RenderView* renderView = this->renderView();
   1523     if (renderView && renderView->needsLayout())
   1524         layout();
   1525     else
   1526         scrollToAnchor();
   1527 }
   1528 
   1529 void FrameView::scrollElementToRect(Element* element, const IntRect& rect)
   1530 {
   1531     m_frame->document()->updateLayoutIgnorePendingStylesheets();
   1532 
   1533     LayoutRect bounds = element->boundingBox();
   1534     int centeringOffsetX = (rect.width() - bounds.width()) / 2;
   1535     int centeringOffsetY = (rect.height() - bounds.height()) / 2;
   1536     setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y()));
   1537 }
   1538 
   1539 void FrameView::setScrollPosition(const IntPoint& scrollPoint)
   1540 {
   1541     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
   1542     m_maintainScrollPositionAnchor = 0;
   1543 
   1544     IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
   1545 
   1546     if (newScrollPosition == scrollPosition())
   1547         return;
   1548 
   1549     Page* page = m_frame->page();
   1550     if (page && RuntimeEnabledFeatures::programmaticScrollNotificationsEnabled())
   1551         page->chrome().client()->didProgrammaticallyScroll(m_frame.get(), newScrollPosition);
   1552 
   1553     if (requestScrollPositionUpdate(newScrollPosition))
   1554         return;
   1555 
   1556     ScrollView::setScrollPosition(newScrollPosition);
   1557 }
   1558 
   1559 void FrameView::setScrollPositionNonProgrammatically(const IntPoint& scrollPoint)
   1560 {
   1561     IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
   1562 
   1563     if (newScrollPosition == scrollPosition())
   1564         return;
   1565 
   1566     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, false);
   1567     notifyScrollPositionChanged(newScrollPosition);
   1568 }
   1569 
   1570 void FrameView::setViewportConstrainedObjectsNeedLayout()
   1571 {
   1572     if (!hasViewportConstrainedObjects())
   1573         return;
   1574 
   1575     ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
   1576     for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
   1577         RenderObject* renderer = *it;
   1578         renderer->setNeedsLayout();
   1579     }
   1580 }
   1581 
   1582 
   1583 void FrameView::scrollPositionChanged()
   1584 {
   1585     frame()->eventHandler()->sendScrollEvent();
   1586     frame()->eventHandler()->dispatchFakeMouseMoveEventSoon();
   1587 
   1588     if (RenderView* renderView = this->renderView()) {
   1589         if (renderView->usesCompositing())
   1590             renderView->compositor()->frameViewDidScroll();
   1591 
   1592         renderView->markLazyBlocksForLayout();
   1593     }
   1594 }
   1595 
   1596 void FrameView::repaintFixedElementsAfterScrolling()
   1597 {
   1598     // For fixed position elements, update widget positions and compositing layers after scrolling,
   1599     // but only if we're not inside of layout.
   1600     if (!m_nestedLayoutCount && hasViewportConstrainedObjects()) {
   1601         if (RenderView* renderView = this->renderView()) {
   1602             renderView->updateWidgetPositions();
   1603             renderView->layer()->updateLayerPositionsAfterDocumentScroll();
   1604         }
   1605     }
   1606 }
   1607 
   1608 void FrameView::updateFixedElementsAfterScrolling()
   1609 {
   1610     if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) {
   1611         if (RenderView* renderView = this->renderView())
   1612             renderView->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
   1613     }
   1614 }
   1615 
   1616 bool FrameView::shouldRubberBandInDirection(ScrollDirection direction) const
   1617 {
   1618     Page* page = frame() ? frame()->page() : 0;
   1619     if (!page)
   1620         return ScrollView::shouldRubberBandInDirection(direction);
   1621     return page->chrome().client()->shouldRubberBandInDirection(direction);
   1622 }
   1623 
   1624 bool FrameView::isRubberBandInProgress() const
   1625 {
   1626     if (scrollbarsSuppressed())
   1627         return false;
   1628 
   1629     // If the main thread updates the scroll position for this FrameView, we should return
   1630     // ScrollAnimator::isRubberBandInProgress().
   1631     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
   1632         return scrollAnimator->isRubberBandInProgress();
   1633 
   1634     return false;
   1635 }
   1636 
   1637 bool FrameView::requestScrollPositionUpdate(const IntPoint& position)
   1638 {
   1639     return false;
   1640 }
   1641 
   1642 HostWindow* FrameView::hostWindow() const
   1643 {
   1644     Page* page = frame() ? frame()->page() : 0;
   1645     if (!page)
   1646         return 0;
   1647     return &page->chrome();
   1648 }
   1649 
   1650 const unsigned cRepaintRectUnionThreshold = 25;
   1651 
   1652 void FrameView::repaintContentRectangle(const IntRect& r)
   1653 {
   1654     ASSERT(!m_frame->ownerElement());
   1655 
   1656     if (m_isTrackingRepaints) {
   1657         IntRect repaintRect = r;
   1658         repaintRect.move(-scrollOffset());
   1659         m_trackedRepaintRects.append(repaintRect);
   1660     }
   1661 
   1662     double delay = m_deferringRepaints ? 0 : adjustedDeferredRepaintDelay();
   1663     if (m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) {
   1664         IntRect paintRect = r;
   1665         if (clipsRepaints() && !paintsEntireContents())
   1666             paintRect.intersect(visibleContentRect());
   1667         if (paintRect.isEmpty())
   1668             return;
   1669         if (m_repaintCount == cRepaintRectUnionThreshold) {
   1670             IntRect unionedRect;
   1671             for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i)
   1672                 unionedRect.unite(pixelSnappedIntRect(m_repaintRects[i]));
   1673             m_repaintRects.clear();
   1674             m_repaintRects.append(unionedRect);
   1675         }
   1676         if (m_repaintCount < cRepaintRectUnionThreshold)
   1677             m_repaintRects.append(paintRect);
   1678         else
   1679             m_repaintRects[0].unite(paintRect);
   1680         m_repaintCount++;
   1681 
   1682         if (!m_deferringRepaints)
   1683             startDeferredRepaintTimer(delay);
   1684 
   1685         return;
   1686     }
   1687 
   1688     if (!shouldUpdate())
   1689         return;
   1690 
   1691     ScrollView::repaintContentRectangle(r);
   1692 }
   1693 
   1694 void FrameView::contentsResized()
   1695 {
   1696     ScrollView::contentsResized();
   1697     setNeedsLayout();
   1698 }
   1699 
   1700 void FrameView::visibleContentsResized()
   1701 {
   1702     // We check to make sure the view is attached to a frame() as this method can
   1703     // be triggered before the view is attached by Frame::createView(...) setting
   1704     // various values such as setScrollBarModes(...) for example.  An ASSERT is
   1705     // triggered when a view is layout before being attached to a frame().
   1706     if (!frame()->view())
   1707         return;
   1708 
   1709     if (!useFixedLayout() && needsLayout())
   1710         layout();
   1711 
   1712     if (RenderView* renderView = this->renderView()) {
   1713         if (renderView->usesCompositing())
   1714             renderView->compositor()->frameViewDidChangeSize();
   1715     }
   1716 }
   1717 
   1718 void FrameView::beginDeferredRepaints()
   1719 {
   1720     Page* page = m_frame->page();
   1721     if (page->mainFrame() != m_frame) {
   1722         page->mainFrame()->view()->beginDeferredRepaints();
   1723         return;
   1724     }
   1725 
   1726     m_deferringRepaints++;
   1727 }
   1728 
   1729 void FrameView::endDeferredRepaints()
   1730 {
   1731     Page* page = m_frame->page();
   1732     if (page->mainFrame() != m_frame) {
   1733         page->mainFrame()->view()->endDeferredRepaints();
   1734         return;
   1735     }
   1736 
   1737     ASSERT(m_deferringRepaints > 0);
   1738 
   1739     if (--m_deferringRepaints)
   1740         return;
   1741 
   1742     if (m_deferredRepaintTimer.isActive())
   1743         return;
   1744 
   1745     if (double delay = adjustedDeferredRepaintDelay()) {
   1746         startDeferredRepaintTimer(delay);
   1747         return;
   1748     }
   1749 
   1750     doDeferredRepaints();
   1751 }
   1752 
   1753 void FrameView::startDeferredRepaintTimer(double delay)
   1754 {
   1755     if (m_deferredRepaintTimer.isActive())
   1756         return;
   1757 
   1758     if (m_disableRepaints)
   1759         return;
   1760 
   1761     m_deferredRepaintTimer.startOneShot(delay);
   1762 }
   1763 
   1764 void FrameView::handleLoadCompleted()
   1765 {
   1766     // Once loading has completed, allow autoSize one last opportunity to
   1767     // reduce the size of the frame.
   1768     autoSizeIfEnabled();
   1769     if (shouldUseLoadTimeDeferredRepaintDelay())
   1770         return;
   1771     m_deferredRepaintDelay = s_normalDeferredRepaintDelay;
   1772     flushDeferredRepaints();
   1773 }
   1774 
   1775 void FrameView::flushDeferredRepaints()
   1776 {
   1777     if (!m_deferredRepaintTimer.isActive())
   1778         return;
   1779     m_deferredRepaintTimer.stop();
   1780     doDeferredRepaints();
   1781 }
   1782 
   1783 void FrameView::doDeferredRepaints()
   1784 {
   1785     if (m_disableRepaints)
   1786         return;
   1787 
   1788     ASSERT(!m_deferringRepaints);
   1789     if (!shouldUpdate()) {
   1790         m_repaintRects.clear();
   1791         m_repaintCount = 0;
   1792         return;
   1793     }
   1794     unsigned size = m_repaintRects.size();
   1795     for (unsigned i = 0; i < size; i++) {
   1796         ScrollView::repaintContentRectangle(pixelSnappedIntRect(m_repaintRects[i]));
   1797     }
   1798     m_repaintRects.clear();
   1799     m_repaintCount = 0;
   1800 
   1801     updateDeferredRepaintDelayAfterRepaint();
   1802 }
   1803 
   1804 bool FrameView::shouldUseLoadTimeDeferredRepaintDelay() const
   1805 {
   1806     // Don't defer after the initial load of the page has been completed.
   1807     if (m_frame->tree()->top()->loader()->isComplete())
   1808         return false;
   1809     Document* document = m_frame->document();
   1810     if (!document)
   1811         return false;
   1812     if (document->parsing())
   1813         return true;
   1814     if (document->fetcher()->requestCount())
   1815         return true;
   1816     return false;
   1817 }
   1818 
   1819 void FrameView::updateDeferredRepaintDelayAfterRepaint()
   1820 {
   1821     if (!shouldUseLoadTimeDeferredRepaintDelay()) {
   1822         m_deferredRepaintDelay = s_normalDeferredRepaintDelay;
   1823         return;
   1824     }
   1825     double incrementedRepaintDelay = m_deferredRepaintDelay + s_deferredRepaintDelayIncrementDuringLoading;
   1826     m_deferredRepaintDelay = std::min(incrementedRepaintDelay, s_maxDeferredRepaintDelayDuringLoading);
   1827 }
   1828 
   1829 void FrameView::resetDeferredRepaintDelay()
   1830 {
   1831     m_deferredRepaintDelay = 0;
   1832     if (m_deferredRepaintTimer.isActive()) {
   1833         m_deferredRepaintTimer.stop();
   1834         if (!m_deferringRepaints)
   1835             doDeferredRepaints();
   1836     }
   1837 }
   1838 
   1839 double FrameView::adjustedDeferredRepaintDelay() const
   1840 {
   1841     ASSERT(!m_deferringRepaints);
   1842     if (!m_deferredRepaintDelay)
   1843         return 0;
   1844     double timeSinceLastPaint = currentTime() - m_lastPaintTime;
   1845     return max(0., m_deferredRepaintDelay - timeSinceLastPaint);
   1846 }
   1847 
   1848 void FrameView::deferredRepaintTimerFired(Timer<FrameView>*)
   1849 {
   1850     doDeferredRepaints();
   1851 }
   1852 
   1853 void FrameView::beginDisableRepaints()
   1854 {
   1855     m_disableRepaints++;
   1856 }
   1857 
   1858 void FrameView::endDisableRepaints()
   1859 {
   1860     ASSERT(m_disableRepaints > 0);
   1861     m_disableRepaints--;
   1862 }
   1863 
   1864 void FrameView::layoutTimerFired(Timer<FrameView>*)
   1865 {
   1866     layout();
   1867 }
   1868 
   1869 void FrameView::scheduleRelayout()
   1870 {
   1871     ASSERT(m_frame->view() == this);
   1872 
   1873     if (m_layoutRoot) {
   1874         m_layoutRoot->markContainingBlocksForLayout(false);
   1875         m_layoutRoot = 0;
   1876     }
   1877     if (!m_layoutSchedulingEnabled)
   1878         return;
   1879     if (!needsLayout())
   1880         return;
   1881     if (!m_frame->document()->shouldScheduleLayout())
   1882         return;
   1883     InspectorInstrumentation::didInvalidateLayout(m_frame.get());
   1884 
   1885     // When frame seamless is enabled, the contents of the frame could affect the layout of the parent frames.
   1886     // Also invalidate parent frame starting from the owner element of this frame.
   1887     if (m_frame->ownerRenderer() && frame()->document()->shouldDisplaySeamlesslyWithParent())
   1888         m_frame->ownerRenderer()->setNeedsLayout(MarkContainingBlockChain);
   1889 
   1890     int delay = m_frame->document()->minimumLayoutDelay();
   1891     if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
   1892         unscheduleRelayout();
   1893     if (m_layoutTimer.isActive())
   1894         return;
   1895 
   1896     m_delayedLayout = delay != 0;
   1897     m_layoutTimer.startOneShot(delay * 0.001);
   1898 }
   1899 
   1900 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
   1901 {
   1902     for (RenderObject* r = descendant; r; r = r->container()) {
   1903         if (r == ancestor)
   1904             return true;
   1905     }
   1906     return false;
   1907 }
   1908 
   1909 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
   1910 {
   1911     ASSERT(m_frame->view() == this);
   1912 
   1913     RenderView* renderView = this->renderView();
   1914     if (renderView && renderView->needsLayout()) {
   1915         if (relayoutRoot)
   1916             relayoutRoot->markContainingBlocksForLayout(false);
   1917         return;
   1918     }
   1919 
   1920     if (layoutPending() || !m_layoutSchedulingEnabled) {
   1921         if (m_layoutRoot != relayoutRoot) {
   1922             if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) {
   1923                 // Keep the current root
   1924                 relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot);
   1925                 ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
   1926             } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) {
   1927                 // Re-root at relayoutRoot
   1928                 m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
   1929                 m_layoutRoot = relayoutRoot;
   1930                 ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
   1931                 InspectorInstrumentation::didInvalidateLayout(m_frame.get());
   1932             } else {
   1933                 // Just do a full relayout
   1934                 if (m_layoutRoot)
   1935                     m_layoutRoot->markContainingBlocksForLayout(false);
   1936                 m_layoutRoot = 0;
   1937                 relayoutRoot->markContainingBlocksForLayout(false);
   1938                 InspectorInstrumentation::didInvalidateLayout(m_frame.get());
   1939             }
   1940         }
   1941     } else if (m_layoutSchedulingEnabled) {
   1942         int delay = m_frame->document()->minimumLayoutDelay();
   1943         m_layoutRoot = relayoutRoot;
   1944         ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
   1945         InspectorInstrumentation::didInvalidateLayout(m_frame.get());
   1946         m_delayedLayout = delay != 0;
   1947         m_layoutTimer.startOneShot(delay * 0.001);
   1948     }
   1949 }
   1950 
   1951 bool FrameView::layoutPending() const
   1952 {
   1953     return m_layoutTimer.isActive();
   1954 }
   1955 
   1956 bool FrameView::needsLayout() const
   1957 {
   1958     // This can return true in cases where the document does not have a body yet.
   1959     // Document::shouldScheduleLayout takes care of preventing us from scheduling
   1960     // layout in that case.
   1961     if (!m_frame)
   1962         return false;
   1963 
   1964     RenderView* renderView = this->renderView();
   1965     return layoutPending()
   1966         || (renderView && renderView->needsLayout())
   1967         || m_layoutRoot
   1968         || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred);
   1969 }
   1970 
   1971 void FrameView::setNeedsLayout()
   1972 {
   1973     if (m_deferSetNeedsLayouts) {
   1974         m_setNeedsLayoutWasDeferred = true;
   1975         return;
   1976     }
   1977 
   1978     if (RenderView* renderView = this->renderView())
   1979         renderView->setNeedsLayout();
   1980 }
   1981 
   1982 void FrameView::unscheduleRelayout()
   1983 {
   1984     if (!m_layoutTimer.isActive())
   1985         return;
   1986 
   1987     m_layoutTimer.stop();
   1988     m_delayedLayout = false;
   1989 }
   1990 
   1991 void FrameView::serviceScriptedAnimations(double monotonicAnimationStartTime)
   1992 {
   1993     for (RefPtr<Frame> frame = m_frame; frame; frame = frame->tree()->traverseNext()) {
   1994         frame->view()->serviceScrollAnimations();
   1995         if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
   1996             frame->animation()->serviceAnimations();
   1997         if (RuntimeEnabledFeatures::webAnimationsEnabled())
   1998             frame->document()->timeline()->serviceAnimations(monotonicAnimationStartTime);
   1999     }
   2000 
   2001     Vector<RefPtr<Document> > documents;
   2002     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext())
   2003         documents.append(frame->document());
   2004 
   2005     for (size_t i = 0; i < documents.size(); ++i)
   2006         documents[i]->serviceScriptedAnimations(monotonicAnimationStartTime);
   2007 }
   2008 
   2009 bool FrameView::isTransparent() const
   2010 {
   2011     return m_isTransparent;
   2012 }
   2013 
   2014 void FrameView::setTransparent(bool isTransparent)
   2015 {
   2016     m_isTransparent = isTransparent;
   2017     if (renderView() && renderView()->layer()->backing())
   2018         renderView()->layer()->backing()->updateContentsOpaque();
   2019 }
   2020 
   2021 bool FrameView::hasOpaqueBackground() const
   2022 {
   2023     return !m_isTransparent && !m_baseBackgroundColor.hasAlpha();
   2024 }
   2025 
   2026 Color FrameView::baseBackgroundColor() const
   2027 {
   2028     return m_baseBackgroundColor;
   2029 }
   2030 
   2031 void FrameView::setBaseBackgroundColor(const StyleColor& backgroundColor)
   2032 {
   2033     if (!backgroundColor.isValid())
   2034         m_baseBackgroundColor = Color::white;
   2035     else
   2036         m_baseBackgroundColor = backgroundColor.color();
   2037 
   2038     if (RenderLayerBacking* backing = renderView() ? renderView()->layer()->backing() : 0) {
   2039         backing->updateContentsOpaque();
   2040         if (backing->graphicsLayer())
   2041             backing->graphicsLayer()->setNeedsDisplay();
   2042     }
   2043     recalculateScrollbarOverlayStyle();
   2044 }
   2045 
   2046 void FrameView::updateBackgroundRecursively(const StyleColor& backgroundColor, bool transparent)
   2047 {
   2048     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
   2049         if (FrameView* view = frame->view()) {
   2050             view->setTransparent(transparent);
   2051             view->setBaseBackgroundColor(backgroundColor);
   2052         }
   2053     }
   2054 }
   2055 
   2056 bool FrameView::shouldUpdateWhileOffscreen() const
   2057 {
   2058     return m_shouldUpdateWhileOffscreen;
   2059 }
   2060 
   2061 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
   2062 {
   2063     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
   2064 }
   2065 
   2066 bool FrameView::shouldUpdate() const
   2067 {
   2068     if (isOffscreen() && !shouldUpdateWhileOffscreen())
   2069         return false;
   2070     return true;
   2071 }
   2072 
   2073 void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget)
   2074 {
   2075     m_actionScheduler->scheduleEvent(event, eventTarget);
   2076 }
   2077 
   2078 void FrameView::pauseScheduledEvents()
   2079 {
   2080     m_actionScheduler->pause();
   2081 }
   2082 
   2083 void FrameView::resumeScheduledEvents()
   2084 {
   2085     m_actionScheduler->resume();
   2086 }
   2087 
   2088 void FrameView::scrollToAnchor()
   2089 {
   2090     RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
   2091     if (!anchorNode)
   2092         return;
   2093 
   2094     if (!anchorNode->renderer())
   2095         return;
   2096 
   2097     LayoutRect rect;
   2098     if (anchorNode != m_frame->document())
   2099         rect = anchorNode->boundingBox();
   2100 
   2101     // Scroll nested layers and frames to reveal the anchor.
   2102     // Align to the top and to the closest side (this matches other browsers).
   2103     anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
   2104 
   2105     if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
   2106         cache->handleScrolledToAnchor(anchorNode.get());
   2107 
   2108     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
   2109     m_maintainScrollPositionAnchor = anchorNode;
   2110 }
   2111 
   2112 void FrameView::updateWidget(RenderObject* object)
   2113 {
   2114     ASSERT(!object->node() || object->node()->isElementNode());
   2115     Element* ownerElement = toElement(object->node());
   2116     // The object may have already been destroyed (thus node cleared),
   2117     // but FrameView holds a manual ref, so it won't have been deleted.
   2118     ASSERT(m_widgetUpdateSet->contains(object));
   2119     if (!ownerElement)
   2120         return;
   2121 
   2122     if (object->isEmbeddedObject()) {
   2123         RenderEmbeddedObject* embeddedObject = static_cast<RenderEmbeddedObject*>(object);
   2124         // No need to update if it's already crashed or known to be missing.
   2125         if (embeddedObject->showsUnavailablePluginIndicator())
   2126             return;
   2127 
   2128         // FIXME: This could turn into a real virtual dispatch if we defined
   2129         // updateWidget(PluginCreationOption) on HTMLElement.
   2130         if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag) || ownerElement->hasTagName(appletTag)) {
   2131             HTMLPlugInImageElement* pluginElement = toHTMLPlugInImageElement(ownerElement);
   2132             if (pluginElement->needsWidgetUpdate())
   2133                 pluginElement->updateWidget(CreateAnyWidgetType);
   2134         } else
   2135             ASSERT_NOT_REACHED();
   2136 
   2137         // Caution: it's possible the object was destroyed again, since loading a
   2138         // plugin may run any arbitrary JavaScript.
   2139         embeddedObject->updateWidgetPosition();
   2140     }
   2141 }
   2142 
   2143 bool FrameView::updateWidgets()
   2144 {
   2145     if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
   2146         return true;
   2147 
   2148     size_t size = m_widgetUpdateSet->size();
   2149 
   2150     Vector<RenderObject*> objects;
   2151     objects.reserveInitialCapacity(size);
   2152 
   2153     RenderObjectSet::const_iterator end = m_widgetUpdateSet->end();
   2154     for (RenderObjectSet::const_iterator it = m_widgetUpdateSet->begin(); it != end; ++it) {
   2155         RenderObject* object = *it;
   2156         objects.uncheckedAppend(object);
   2157         if (object->isEmbeddedObject()) {
   2158             RenderEmbeddedObject* embeddedObject = static_cast<RenderEmbeddedObject*>(object);
   2159             embeddedObject->ref();
   2160         }
   2161     }
   2162 
   2163     for (size_t i = 0; i < size; ++i) {
   2164         RenderObject* object = objects[i];
   2165         updateWidget(object);
   2166         m_widgetUpdateSet->remove(object);
   2167     }
   2168 
   2169     for (size_t i = 0; i < size; ++i) {
   2170         RenderObject* object = objects[i];
   2171         if (object->isEmbeddedObject()) {
   2172             RenderEmbeddedObject* embeddedObject = static_cast<RenderEmbeddedObject*>(object);
   2173             embeddedObject->deref();
   2174         }
   2175     }
   2176 
   2177     return m_widgetUpdateSet->isEmpty();
   2178 }
   2179 
   2180 void FrameView::flushAnyPendingPostLayoutTasks()
   2181 {
   2182     if (!m_postLayoutTasksTimer.isActive())
   2183         return;
   2184 
   2185     performPostLayoutTasks();
   2186 }
   2187 
   2188 void FrameView::performPostLayoutTasks()
   2189 {
   2190     // updateWidgets() call below can blow us away from underneath.
   2191     RefPtr<FrameView> protect(this);
   2192 
   2193     m_postLayoutTasksTimer.stop();
   2194 
   2195     m_frame->selection()->setCaretRectNeedsUpdate();
   2196     m_frame->selection()->updateAppearance();
   2197 
   2198     LayoutMilestones milestonesOfInterest = 0;
   2199     LayoutMilestones milestonesAchieved = 0;
   2200     Page* page = m_frame->page();
   2201     if (page)
   2202         milestonesOfInterest = page->layoutMilestones();
   2203 
   2204     if (m_nestedLayoutCount <= 1) {
   2205         if (m_firstLayoutCallbackPending) {
   2206             m_firstLayoutCallbackPending = false;
   2207             m_frame->loader()->didFirstLayout();
   2208             if (milestonesOfInterest & DidFirstLayout)
   2209                 milestonesAchieved |= DidFirstLayout;
   2210             if (page) {
   2211                 if (page->mainFrame() == m_frame)
   2212                     page->startCountingRelevantRepaintedObjects();
   2213             }
   2214         }
   2215 
   2216         // Ensure that we always send this eventually.
   2217         if (!m_frame->document()->parsing() && m_frame->loader()->stateMachine()->committedFirstRealDocumentLoad())
   2218             m_isVisuallyNonEmpty = true;
   2219 
   2220         // If the layout was done with pending sheets, we are not in fact visually non-empty yet.
   2221         if (m_isVisuallyNonEmpty && !m_frame->document()->didLayoutWithPendingStylesheets() && m_firstVisuallyNonEmptyLayoutCallbackPending) {
   2222             m_firstVisuallyNonEmptyLayoutCallbackPending = false;
   2223             if (milestonesOfInterest & DidFirstVisuallyNonEmptyLayout)
   2224                 milestonesAchieved |= DidFirstVisuallyNonEmptyLayout;
   2225         }
   2226     }
   2227 
   2228     m_frame->loader()->didLayout(milestonesAchieved);
   2229     m_frame->document()->fontloader()->didLayout();
   2230 
   2231     RenderView* renderView = this->renderView();
   2232     if (renderView)
   2233         renderView->updateWidgetPositions();
   2234 
   2235     for (unsigned i = 0; i < maxUpdateWidgetsIterations; i++) {
   2236         if (updateWidgets())
   2237             break;
   2238     }
   2239 
   2240     if (page) {
   2241         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   2242             scrollingCoordinator->frameViewLayoutUpdated(this);
   2243     }
   2244 
   2245     scrollToAnchor();
   2246 
   2247     m_actionScheduler->resume();
   2248 
   2249     // Refetch render view since it can be destroyed by updateWidget() call above.
   2250     renderView = this->renderView();
   2251     if (renderView && !renderView->printing()) {
   2252         IntSize currentSize = layoutSize(IncludeScrollbars);
   2253         float currentZoomFactor = renderView->style()->zoom();
   2254         bool resized = !m_firstLayout && (currentSize != m_lastViewportSize || currentZoomFactor != m_lastZoomFactor);
   2255         m_lastViewportSize = currentSize;
   2256         m_lastZoomFactor = currentZoomFactor;
   2257         if (resized) {
   2258             m_frame->eventHandler()->sendResizeEvent();
   2259             if (page && page->mainFrame() == m_frame)
   2260                 InspectorInstrumentation::didResizeMainFrame(page);
   2261         }
   2262     }
   2263 }
   2264 
   2265 void FrameView::postLayoutTimerFired(Timer<FrameView>*)
   2266 {
   2267     performPostLayoutTasks();
   2268 }
   2269 
   2270 void FrameView::autoSizeIfEnabled()
   2271 {
   2272     if (!m_shouldAutoSize)
   2273         return;
   2274 
   2275     if (m_inAutoSize)
   2276         return;
   2277 
   2278     TemporaryChange<bool> changeInAutoSize(m_inAutoSize, true);
   2279 
   2280     Document* document = frame()->document();
   2281     if (!document)
   2282         return;
   2283 
   2284     RenderView* documentView = document->renderView();
   2285     Element* documentElement = document->documentElement();
   2286     if (!documentView || !documentElement)
   2287         return;
   2288 
   2289     RenderBox* documentRenderBox = documentElement->renderBox();
   2290     if (!documentRenderBox)
   2291         return;
   2292 
   2293     // If this is the first time we run autosize, start from small height and
   2294     // allow it to grow.
   2295     if (!m_didRunAutosize)
   2296         resize(frameRect().width(), m_minAutoSize.height());
   2297 
   2298     IntSize size = frameRect().size();
   2299 
   2300     // Do the resizing twice. The first time is basically a rough calculation using the preferred width
   2301     // which may result in a height change during the second iteration.
   2302     for (int i = 0; i < 2; i++) {
   2303         // Update various sizes including contentsSize, scrollHeight, etc.
   2304         document->updateLayoutIgnorePendingStylesheets();
   2305         int width = documentView->minPreferredLogicalWidth();
   2306         int height = documentRenderBox->scrollHeight();
   2307         IntSize newSize(width, height);
   2308 
   2309         // Check to see if a scrollbar is needed for a given dimension and
   2310         // if so, increase the other dimension to account for the scrollbar.
   2311         // Since the dimensions are only for the view rectangle, once a
   2312         // dimension exceeds the maximum, there is no need to increase it further.
   2313         if (newSize.width() > m_maxAutoSize.width()) {
   2314             RefPtr<Scrollbar> localHorizontalScrollbar = horizontalScrollbar();
   2315             if (!localHorizontalScrollbar)
   2316                 localHorizontalScrollbar = createScrollbar(HorizontalScrollbar);
   2317             if (!localHorizontalScrollbar->isOverlayScrollbar())
   2318                 newSize.setHeight(newSize.height() + localHorizontalScrollbar->height());
   2319 
   2320             // Don't bother checking for a vertical scrollbar because the width is at
   2321             // already greater the maximum.
   2322         } else if (newSize.height() > m_maxAutoSize.height()) {
   2323             RefPtr<Scrollbar> localVerticalScrollbar = verticalScrollbar();
   2324             if (!localVerticalScrollbar)
   2325                 localVerticalScrollbar = createScrollbar(VerticalScrollbar);
   2326             if (!localVerticalScrollbar->isOverlayScrollbar())
   2327                 newSize.setWidth(newSize.width() + localVerticalScrollbar->width());
   2328 
   2329             // Don't bother checking for a horizontal scrollbar because the height is
   2330             // already greater the maximum.
   2331         }
   2332 
   2333         // Ensure the size is at least the min bounds.
   2334         newSize = newSize.expandedTo(m_minAutoSize);
   2335 
   2336         // Bound the dimensions by the max bounds and determine what scrollbars to show.
   2337         ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff;
   2338         if (newSize.width() > m_maxAutoSize.width()) {
   2339             newSize.setWidth(m_maxAutoSize.width());
   2340             horizonalScrollbarMode = ScrollbarAlwaysOn;
   2341         }
   2342         ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff;
   2343         if (newSize.height() > m_maxAutoSize.height()) {
   2344             newSize.setHeight(m_maxAutoSize.height());
   2345             verticalScrollbarMode = ScrollbarAlwaysOn;
   2346         }
   2347 
   2348         if (newSize == size)
   2349             continue;
   2350 
   2351         // While loading only allow the size to increase (to avoid twitching during intermediate smaller states)
   2352         // unless autoresize has just been turned on or the maximum size is smaller than the current size.
   2353         if (m_didRunAutosize && size.height() <= m_maxAutoSize.height() && size.width() <= m_maxAutoSize.width()
   2354             && !frame()->loader()->isComplete() && (newSize.height() < size.height() || newSize.width() < size.width()))
   2355             break;
   2356 
   2357         resize(newSize.width(), newSize.height());
   2358         // Force the scrollbar state to avoid the scrollbar code adding them and causing them to be needed. For example,
   2359         // a vertical scrollbar may cause text to wrap and thus increase the height (which is the only reason the scollbar is needed).
   2360         setVerticalScrollbarLock(false);
   2361         setHorizontalScrollbarLock(false);
   2362         setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true);
   2363     }
   2364     m_didRunAutosize = true;
   2365 }
   2366 
   2367 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
   2368 {
   2369     if (!m_viewportRenderer)
   2370         return;
   2371 
   2372     if (m_overflowStatusDirty) {
   2373         m_horizontalOverflow = horizontalOverflow;
   2374         m_verticalOverflow = verticalOverflow;
   2375         m_overflowStatusDirty = false;
   2376         return;
   2377     }
   2378 
   2379     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
   2380     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
   2381 
   2382     if (horizontalOverflowChanged || verticalOverflowChanged) {
   2383         m_horizontalOverflow = horizontalOverflow;
   2384         m_verticalOverflow = verticalOverflow;
   2385 
   2386         m_actionScheduler->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
   2387             verticalOverflowChanged, verticalOverflow),
   2388             m_viewportRenderer->node());
   2389     }
   2390 
   2391 }
   2392 
   2393 const Pagination& FrameView::pagination() const
   2394 {
   2395     if (m_pagination != Pagination())
   2396         return m_pagination;
   2397 
   2398     if (Page* page = m_frame->page()) {
   2399         if (page->mainFrame() == m_frame)
   2400             return page->pagination();
   2401     }
   2402 
   2403     return m_pagination;
   2404 }
   2405 
   2406 void FrameView::setPagination(const Pagination& pagination)
   2407 {
   2408     if (m_pagination == pagination)
   2409         return;
   2410 
   2411     m_pagination = pagination;
   2412 
   2413     if (m_frame)
   2414         m_frame->document()->styleResolverChanged(DeferRecalcStyle);
   2415 }
   2416 
   2417 IntRect FrameView::windowClipRect(bool clipToContents) const
   2418 {
   2419     ASSERT(m_frame->view() == this);
   2420 
   2421     if (paintsEntireContents())
   2422         return IntRect(IntPoint(), contentsSize());
   2423 
   2424     // Set our clip rect to be our contents.
   2425     IntRect clipRect = contentsToWindow(visibleContentRect(clipToContents ? ExcludeScrollbars : IncludeScrollbars));
   2426     if (!m_frame || !m_frame->ownerElement())
   2427         return clipRect;
   2428 
   2429     // Take our owner element and get its clip rect.
   2430     HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement();
   2431     FrameView* parentView = ownerElement->document()->view();
   2432     if (parentView)
   2433         clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement, true));
   2434     return clipRect;
   2435 }
   2436 
   2437 IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement, bool clipToLayerContents) const
   2438 {
   2439     // The renderer can sometimes be null when style="display:none" interacts
   2440     // with external content and plugins.
   2441     if (!ownerElement->renderer())
   2442         return windowClipRect();
   2443 
   2444     // If we have no layer, just return our window clip rect.
   2445     const RenderLayer* enclosingLayer = ownerElement->renderer()->enclosingLayer();
   2446     if (!enclosingLayer)
   2447         return windowClipRect();
   2448 
   2449     // Apply the clip from the layer.
   2450     IntRect clipRect;
   2451     if (clipToLayerContents)
   2452         clipRect = pixelSnappedIntRect(enclosingLayer->childrenClipRect());
   2453     else
   2454         clipRect = pixelSnappedIntRect(enclosingLayer->selfClipRect());
   2455     clipRect = contentsToWindow(clipRect);
   2456     return intersection(clipRect, windowClipRect());
   2457 }
   2458 
   2459 bool FrameView::isActive() const
   2460 {
   2461     Page* page = frame()->page();
   2462     return page && page->focusController().isActive();
   2463 }
   2464 
   2465 void FrameView::scrollTo(const IntSize& newOffset)
   2466 {
   2467     LayoutSize offset = scrollOffset();
   2468     ScrollView::scrollTo(newOffset);
   2469     if (offset != scrollOffset())
   2470         scrollPositionChanged();
   2471     frame()->loader()->client()->didChangeScrollOffset();
   2472 }
   2473 
   2474 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
   2475 {
   2476     // Add in our offset within the FrameView.
   2477     IntRect dirtyRect = rect;
   2478     dirtyRect.moveBy(scrollbar->location());
   2479     invalidateRect(dirtyRect);
   2480 }
   2481 
   2482 void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
   2483 {
   2484     tickmarks = frame()->document()->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch);
   2485 }
   2486 
   2487 IntRect FrameView::windowResizerRect() const
   2488 {
   2489     Page* page = frame() ? frame()->page() : 0;
   2490     if (!page)
   2491         return IntRect();
   2492     return page->chrome().windowResizerRect();
   2493 }
   2494 
   2495 void FrameView::setVisibleContentScaleFactor(float visibleContentScaleFactor)
   2496 {
   2497     if (m_visibleContentScaleFactor == visibleContentScaleFactor)
   2498         return;
   2499 
   2500     m_visibleContentScaleFactor = visibleContentScaleFactor;
   2501     updateScrollbars(scrollOffset());
   2502 }
   2503 
   2504 bool FrameView::scrollbarsCanBeActive() const
   2505 {
   2506     if (!m_frame)
   2507         return false;
   2508 
   2509     if (m_frame->view() != this)
   2510         return false;
   2511 
   2512     return !!m_frame->document();
   2513 }
   2514 
   2515 ScrollableArea* FrameView::enclosingScrollableArea() const
   2516 {
   2517     // FIXME: Walk up the frame tree and look for a scrollable parent frame or RenderLayer.
   2518     return 0;
   2519 }
   2520 
   2521 IntRect FrameView::scrollableAreaBoundingBox() const
   2522 {
   2523     RenderPart* ownerRenderer = frame()->ownerRenderer();
   2524     if (!ownerRenderer)
   2525         return frameRect();
   2526 
   2527     return ownerRenderer->absoluteContentQuad().enclosingBoundingBox();
   2528 }
   2529 
   2530 bool FrameView::isScrollable()
   2531 {
   2532     // Check for:
   2533     // 1) If there an actual overflow.
   2534     // 2) display:none or visibility:hidden set to self or inherited.
   2535     // 3) overflow{-x,-y}: hidden;
   2536     // 4) scrolling: no;
   2537 
   2538     // Covers #1
   2539     IntSize contentsSize = this->contentsSize();
   2540     IntSize visibleContentSize = visibleContentRect().size();
   2541     if ((contentsSize.height() <= visibleContentSize.height() && contentsSize.width() <= visibleContentSize.width()))
   2542         return false;
   2543 
   2544     // Covers #2.
   2545     HTMLFrameOwnerElement* owner = m_frame->ownerElement();
   2546     if (owner && (!owner->renderer() || !owner->renderer()->visibleToHitTesting()))
   2547         return false;
   2548 
   2549     // Cover #3 and #4.
   2550     ScrollbarMode horizontalMode;
   2551     ScrollbarMode verticalMode;
   2552     calculateScrollbarModesForLayout(horizontalMode, verticalMode, RulesFromWebContentOnly);
   2553     if (horizontalMode == ScrollbarAlwaysOff && verticalMode == ScrollbarAlwaysOff)
   2554         return false;
   2555 
   2556     return true;
   2557 }
   2558 
   2559 void FrameView::updateScrollableAreaSet()
   2560 {
   2561     // That ensures that only inner frames are cached.
   2562     FrameView* parentFrameView = this->parentFrameView();
   2563     if (!parentFrameView)
   2564         return;
   2565 
   2566     if (!isScrollable()) {
   2567         parentFrameView->removeScrollableArea(this);
   2568         return;
   2569     }
   2570 
   2571     parentFrameView->addScrollableArea(this);
   2572 }
   2573 
   2574 bool FrameView::shouldSuspendScrollAnimations() const
   2575 {
   2576     return m_frame->loader()->state() != FrameStateComplete;
   2577 }
   2578 
   2579 void FrameView::scrollbarStyleChanged(int newStyle, bool forceUpdate)
   2580 {
   2581     Page* page = m_frame->page();
   2582     if (!page)
   2583         return;
   2584     if (page->mainFrame() != m_frame)
   2585         return;
   2586 
   2587     if (forceUpdate)
   2588         ScrollView::scrollbarStyleChanged(newStyle, forceUpdate);
   2589 }
   2590 
   2591 void FrameView::setAnimatorsAreActive()
   2592 {
   2593     Page* page = m_frame->page();
   2594     if (!page)
   2595         return;
   2596 
   2597     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
   2598         scrollAnimator->setIsActive();
   2599 
   2600     if (!m_scrollableAreas)
   2601         return;
   2602 
   2603     for (HashSet<ScrollableArea*>::const_iterator it = m_scrollableAreas->begin(), end = m_scrollableAreas->end(); it != end; ++it) {
   2604         ScrollableArea* scrollableArea = *it;
   2605 
   2606         ASSERT(scrollableArea->scrollbarsCanBeActive());
   2607         scrollableArea->scrollAnimator()->setIsActive();
   2608     }
   2609 }
   2610 
   2611 void FrameView::notifyPageThatContentAreaWillPaint() const
   2612 {
   2613     Page* page = m_frame->page();
   2614     if (!page)
   2615         return;
   2616 
   2617     contentAreaWillPaint();
   2618 
   2619     if (!m_scrollableAreas)
   2620         return;
   2621 
   2622     for (HashSet<ScrollableArea*>::const_iterator it = m_scrollableAreas->begin(), end = m_scrollableAreas->end(); it != end; ++it) {
   2623         ScrollableArea* scrollableArea = *it;
   2624 
   2625         if (!scrollableArea->scrollbarsCanBeActive())
   2626             continue;
   2627 
   2628         scrollableArea->contentAreaWillPaint();
   2629     }
   2630 }
   2631 
   2632 bool FrameView::scrollAnimatorEnabled() const
   2633 {
   2634     if (Page* page = m_frame->page())
   2635         return page->settings()->scrollAnimatorEnabled();
   2636     return false;
   2637 }
   2638 
   2639 void FrameView::updateAnnotatedRegions()
   2640 {
   2641     Document* document = m_frame->document();
   2642     if (!document->hasAnnotatedRegions())
   2643         return;
   2644     Vector<AnnotatedRegionValue> newRegions;
   2645     document->renderBox()->collectAnnotatedRegions(newRegions);
   2646     if (newRegions == document->annotatedRegions())
   2647         return;
   2648     document->setAnnotatedRegions(newRegions);
   2649     Page* page = m_frame->page();
   2650     if (!page)
   2651         return;
   2652     page->chrome().client()->annotatedRegionsChanged();
   2653 }
   2654 
   2655 void FrameView::updateScrollCorner()
   2656 {
   2657     RefPtr<RenderStyle> cornerStyle;
   2658     IntRect cornerRect = scrollCornerRect();
   2659     Document* doc = m_frame->document();
   2660 
   2661     if (doc && !cornerRect.isEmpty()) {
   2662         // Try the <body> element first as a scroll corner source.
   2663         if (Element* body = doc->body()) {
   2664             if (RenderObject* renderer = body->renderer())
   2665                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
   2666         }
   2667 
   2668         if (!cornerStyle) {
   2669             // If the <body> didn't have a custom style, then the root element might.
   2670             if (Element* docElement = doc->documentElement()) {
   2671                 if (RenderObject* renderer = docElement->renderer())
   2672                     cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
   2673             }
   2674         }
   2675 
   2676         if (!cornerStyle) {
   2677             // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
   2678             if (RenderPart* renderer = m_frame->ownerRenderer())
   2679                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
   2680         }
   2681     }
   2682 
   2683     if (cornerStyle) {
   2684         if (!m_scrollCorner)
   2685             m_scrollCorner = RenderScrollbarPart::createAnonymous(doc);
   2686         m_scrollCorner->setStyle(cornerStyle.release());
   2687         invalidateScrollCorner(cornerRect);
   2688     } else if (m_scrollCorner) {
   2689         m_scrollCorner->destroy();
   2690         m_scrollCorner = 0;
   2691     }
   2692 
   2693     ScrollView::updateScrollCorner();
   2694 }
   2695 
   2696 void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
   2697 {
   2698     if (context->updatingControlTints()) {
   2699         updateScrollCorner();
   2700         return;
   2701     }
   2702 
   2703     if (m_scrollCorner) {
   2704         bool needsBackgorund = m_frame->page() && m_frame->page()->mainFrame() == m_frame;
   2705         if (needsBackgorund)
   2706             context->fillRect(cornerRect, baseBackgroundColor());
   2707         m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect);
   2708         return;
   2709     }
   2710 
   2711     ScrollView::paintScrollCorner(context, cornerRect);
   2712 }
   2713 
   2714 void FrameView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
   2715 {
   2716     bool needsBackgorund = bar->isCustomScrollbar() && (m_frame->page() && m_frame->page()->mainFrame() == m_frame);
   2717     if (needsBackgorund) {
   2718         IntRect toFill = bar->frameRect();
   2719         toFill.intersect(rect);
   2720         context->fillRect(toFill, baseBackgroundColor());
   2721     }
   2722 
   2723     ScrollView::paintScrollbar(context, bar, rect);
   2724 }
   2725 
   2726 StyleColor FrameView::documentBackgroundColor() const
   2727 {
   2728     // <https://bugs.webkit.org/show_bug.cgi?id=59540> We blend the background color of
   2729     // the document and the body against the base background color of the frame view.
   2730     // Background images are unfortunately impractical to include.
   2731 
   2732     // Return invalid Color objects whenever there is insufficient information.
   2733     if (!frame()->document())
   2734         return Color();
   2735 
   2736     Element* htmlElement = frame()->document()->documentElement();
   2737     Element* bodyElement = frame()->document()->body();
   2738 
   2739     // Start with invalid colors.
   2740     StyleColor htmlBackgroundColor;
   2741     StyleColor bodyBackgroundColor;
   2742     if (htmlElement && htmlElement->renderer())
   2743         htmlBackgroundColor = htmlElement->renderer()->resolveStyleColor(CSSPropertyBackgroundColor);
   2744     if (bodyElement && bodyElement->renderer())
   2745         bodyBackgroundColor = bodyElement->renderer()->resolveStyleColor(CSSPropertyBackgroundColor);
   2746 
   2747     if (!bodyBackgroundColor.isValid()) {
   2748         if (!htmlBackgroundColor.isValid())
   2749             return StyleColor();
   2750         return baseBackgroundColor().blend(htmlBackgroundColor.color());
   2751     }
   2752 
   2753     if (!htmlBackgroundColor.isValid())
   2754         return baseBackgroundColor().blend(bodyBackgroundColor.color());
   2755 
   2756     // We take the aggregate of the base background color
   2757     // the <html> background color, and the <body>
   2758     // background color to find the document color. The
   2759     // addition of the base background color is not
   2760     // technically part of the document background, but it
   2761     // otherwise poses problems when the aggregate is not
   2762     // fully opaque.
   2763     return baseBackgroundColor().blend(htmlBackgroundColor.color()).blend(bodyBackgroundColor.color());
   2764 }
   2765 
   2766 bool FrameView::hasCustomScrollbars() const
   2767 {
   2768     const HashSet<RefPtr<Widget> >* viewChildren = children();
   2769     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
   2770     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
   2771         Widget* widget = current->get();
   2772         if (widget->isFrameView()) {
   2773             if (toFrameView(widget)->hasCustomScrollbars())
   2774                 return true;
   2775         } else if (widget->isScrollbar()) {
   2776             Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
   2777             if (scrollbar->isCustomScrollbar())
   2778                 return true;
   2779         }
   2780     }
   2781 
   2782     return false;
   2783 }
   2784 
   2785 FrameView* FrameView::parentFrameView() const
   2786 {
   2787     if (!parent())
   2788         return 0;
   2789 
   2790     if (Frame* parentFrame = m_frame->tree()->parent())
   2791         return parentFrame->view();
   2792 
   2793     return 0;
   2794 }
   2795 
   2796 void FrameView::updateControlTints()
   2797 {
   2798     // This is called when control tints are changed from aqua/graphite to clear and vice versa.
   2799     // We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
   2800     // This is only done if the theme supports control tinting. It's up to the theme and platform
   2801     // to define when controls get the tint and to call this function when that changes.
   2802 
   2803     // Optimize the common case where we bring a window to the front while it's still empty.
   2804     if (!m_frame || m_frame->document()->url().isEmpty())
   2805         return;
   2806 
   2807     RenderView* renderView = this->renderView();
   2808     if ((renderView && renderView->theme()->supportsControlTints()) || hasCustomScrollbars())
   2809         paintControlTints();
   2810 }
   2811 
   2812 void FrameView::paintControlTints()
   2813 {
   2814     if (needsLayout())
   2815         layout();
   2816     // FIXME: The use of paint seems like overkill: crbug.com/236892
   2817     GraphicsContext context(0); // NULL canvas to get a non-painting context.
   2818     context.setUpdatingControlTints(true);
   2819     paint(&context, frameRect());
   2820 }
   2821 
   2822 bool FrameView::wasScrolledByUser() const
   2823 {
   2824     return m_wasScrolledByUser;
   2825 }
   2826 
   2827 void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
   2828 {
   2829     if (m_inProgrammaticScroll)
   2830         return;
   2831     m_maintainScrollPositionAnchor = 0;
   2832     m_wasScrolledByUser = wasScrolledByUser;
   2833 }
   2834 
   2835 void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
   2836 {
   2837     if (!frame())
   2838         return;
   2839 
   2840     Document* document = m_frame->document();
   2841 
   2842 #ifndef NDEBUG
   2843     bool fillWithRed;
   2844     if (document->printing())
   2845         fillWithRed = false; // Printing, don't fill with red (can't remember why).
   2846     else if (m_frame->ownerElement())
   2847         fillWithRed = false; // Subframe, don't fill with red.
   2848     else if (isTransparent())
   2849         fillWithRed = false; // Transparent, don't fill with red.
   2850     else if (m_paintBehavior & PaintBehaviorSelectionOnly)
   2851         fillWithRed = false; // Selections are transparent, don't fill with red.
   2852     else if (m_nodeToDraw)
   2853         fillWithRed = false; // Element images are transparent, don't fill with red.
   2854     else
   2855         fillWithRed = true;
   2856 
   2857     if (fillWithRed)
   2858         p->fillRect(rect, Color(0xFF, 0, 0));
   2859 #endif
   2860 
   2861     RenderView* renderView = this->renderView();
   2862     if (!renderView) {
   2863         LOG_ERROR("called FrameView::paint with nil renderer");
   2864         return;
   2865     }
   2866 
   2867     ASSERT(!needsLayout());
   2868     if (needsLayout())
   2869         return;
   2870 
   2871     InspectorInstrumentation::willPaint(renderView);
   2872 
   2873     bool isTopLevelPainter = !sCurrentPaintTimeStamp;
   2874     if (isTopLevelPainter)
   2875         sCurrentPaintTimeStamp = currentTime();
   2876 
   2877     FontCachePurgePreventer fontCachePurgePreventer;
   2878 
   2879     PaintBehavior oldPaintBehavior = m_paintBehavior;
   2880 
   2881     if (FrameView* parentView = parentFrameView()) {
   2882         if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers)
   2883             m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
   2884     }
   2885 
   2886     if (m_paintBehavior == PaintBehaviorNormal)
   2887         document->markers()->invalidateRenderedRectsForMarkersInRect(rect);
   2888 
   2889     if (document->printing())
   2890         m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
   2891 
   2892     ASSERT(!m_isPainting);
   2893     m_isPainting = true;
   2894 
   2895     // m_nodeToDraw is used to draw only one element (and its descendants)
   2896     RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
   2897     RenderLayer* rootLayer = renderView->layer();
   2898 
   2899 #ifndef NDEBUG
   2900     RenderObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(rootLayer->renderer());
   2901 #endif
   2902 
   2903     rootLayer->paint(p, rect, m_paintBehavior, eltRenderer);
   2904 
   2905     if (rootLayer->containsDirtyOverlayScrollbars())
   2906         rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, eltRenderer);
   2907 
   2908     m_isPainting = false;
   2909 
   2910     m_paintBehavior = oldPaintBehavior;
   2911     m_lastPaintTime = currentTime();
   2912 
   2913     // Regions may have changed as a result of the visibility/z-index of element changing.
   2914     if (document->annotatedRegionsDirty())
   2915         updateAnnotatedRegions();
   2916 
   2917     if (isTopLevelPainter)
   2918         sCurrentPaintTimeStamp = 0;
   2919 
   2920     InspectorInstrumentation::didPaint(renderView, p, rect);
   2921 }
   2922 
   2923 void FrameView::setPaintBehavior(PaintBehavior behavior)
   2924 {
   2925     m_paintBehavior = behavior;
   2926 }
   2927 
   2928 PaintBehavior FrameView::paintBehavior() const
   2929 {
   2930     return m_paintBehavior;
   2931 }
   2932 
   2933 bool FrameView::isPainting() const
   2934 {
   2935     return m_isPainting;
   2936 }
   2937 
   2938 void FrameView::setNodeToDraw(Node* node)
   2939 {
   2940     m_nodeToDraw = node;
   2941 }
   2942 
   2943 void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
   2944 {
   2945     if (context->paintingDisabled())
   2946         return;
   2947 
   2948     if (m_frame->document()->printing())
   2949         return;
   2950 
   2951     Page* page = m_frame->page();
   2952     if (page->mainFrame() == m_frame) {
   2953         if (page->chrome().client()->paintCustomOverhangArea(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect))
   2954             return;
   2955     }
   2956 
   2957     ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
   2958 }
   2959 
   2960 void FrameView::updateLayoutAndStyleIfNeededRecursive()
   2961 {
   2962     // We have to crawl our entire tree looking for any FrameViews that need
   2963     // layout and make sure they are up to date.
   2964     // Mac actually tests for intersection with the dirty region and tries not to
   2965     // update layout for frames that are outside the dirty region.  Not only does this seem
   2966     // pointless (since those frames will have set a zero timer to layout anyway), but
   2967     // it is also incorrect, since if two frames overlap, the first could be excluded from the dirty
   2968     // region but then become included later by the second frame adding rects to the dirty region
   2969     // when it lays out.
   2970 
   2971     m_frame->document()->updateStyleIfNeeded();
   2972 
   2973     if (needsLayout())
   2974         layout();
   2975 
   2976     // Grab a copy of the children() set, as it may be mutated by the following updateLayoutAndStyleIfNeededRecursive
   2977     // calls, as they can potentially re-enter a layout of the parent frame view, which may add/remove scrollbars
   2978     // and thus mutates the children() set.
   2979     Vector<RefPtr<FrameView> > frameViews;
   2980     collectFrameViewChildren(this, frameViews);
   2981 
   2982     const Vector<RefPtr<FrameView> >::iterator end = frameViews.end();
   2983     for (Vector<RefPtr<FrameView> >::iterator it = frameViews.begin(); it != end; ++it)
   2984         (*it)->updateLayoutAndStyleIfNeededRecursive();
   2985 
   2986     // updateLayoutAndStyleIfNeededRecursive is called when we need to make sure style and layout are up-to-date before
   2987     // painting, so we need to flush out any deferred repaints too.
   2988     flushDeferredRepaints();
   2989 
   2990     // When seamless is on, child frame can mark parent frame dirty. In such case, child frame
   2991     // needs to call layout on parent frame recursively.
   2992     // This assert ensures that parent frames are clean, when child frames finished updating layout and style.
   2993     ASSERT(!needsLayout());
   2994 }
   2995 
   2996 void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize)
   2997 {
   2998     ASSERT(!enable || !minSize.isEmpty());
   2999     ASSERT(minSize.width() <= maxSize.width());
   3000     ASSERT(minSize.height() <= maxSize.height());
   3001 
   3002     if (m_shouldAutoSize == enable && m_minAutoSize == minSize && m_maxAutoSize == maxSize)
   3003         return;
   3004 
   3005     m_shouldAutoSize = enable;
   3006     m_minAutoSize = minSize;
   3007     m_maxAutoSize = maxSize;
   3008     m_didRunAutosize = false;
   3009 
   3010     setNeedsLayout();
   3011     scheduleRelayout();
   3012     if (m_shouldAutoSize)
   3013         return;
   3014 
   3015     // Since autosize mode forces the scrollbar mode, change them to being auto.
   3016     setVerticalScrollbarLock(false);
   3017     setHorizontalScrollbarLock(false);
   3018     setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
   3019 }
   3020 
   3021 void FrameView::forceLayout(bool allowSubtree)
   3022 {
   3023     layout(allowSubtree);
   3024 }
   3025 
   3026 void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor, AdjustViewSizeOrNot shouldAdjustViewSize)
   3027 {
   3028     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
   3029     // the state of things before and after the layout
   3030     if (RenderView* renderView = this->renderView()) {
   3031         float pageLogicalWidth = renderView->style()->isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
   3032         float pageLogicalHeight = renderView->style()->isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
   3033 
   3034         LayoutUnit flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
   3035         LayoutUnit flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
   3036         renderView->setLogicalWidth(flooredPageLogicalWidth);
   3037         renderView->setPageLogicalHeight(flooredPageLogicalHeight);
   3038         renderView->setNeedsLayoutAndPrefWidthsRecalc();
   3039         forceLayout();
   3040 
   3041         // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
   3042         // page width when shrunk, we will lay out at maximum shrink and clip extra content.
   3043         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
   3044         // implementation should not do this!
   3045         bool horizontalWritingMode = renderView->style()->isHorizontalWritingMode();
   3046         const LayoutRect& documentRect = renderView->documentRect();
   3047         LayoutUnit docLogicalWidth = horizontalWritingMode ? documentRect.width() : documentRect.height();
   3048         if (docLogicalWidth > pageLogicalWidth) {
   3049             int expectedPageWidth = std::min<float>(documentRect.width(), pageSize.width() * maximumShrinkFactor);
   3050             int expectedPageHeight = std::min<float>(documentRect.height(), pageSize.height() * maximumShrinkFactor);
   3051             FloatSize maxPageSize = m_frame->resizePageRectsKeepingRatio(FloatSize(originalPageSize.width(), originalPageSize.height()), FloatSize(expectedPageWidth, expectedPageHeight));
   3052             pageLogicalWidth = horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
   3053             pageLogicalHeight = horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();
   3054 
   3055             flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
   3056             flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
   3057             renderView->setLogicalWidth(flooredPageLogicalWidth);
   3058             renderView->setPageLogicalHeight(flooredPageLogicalHeight);
   3059             renderView->setNeedsLayoutAndPrefWidthsRecalc();
   3060             forceLayout();
   3061 
   3062             const LayoutRect& updatedDocumentRect = renderView->documentRect();
   3063             LayoutUnit docLogicalHeight = horizontalWritingMode ? updatedDocumentRect.height() : updatedDocumentRect.width();
   3064             LayoutUnit docLogicalTop = horizontalWritingMode ? updatedDocumentRect.y() : updatedDocumentRect.x();
   3065             LayoutUnit docLogicalRight = horizontalWritingMode ? updatedDocumentRect.maxX() : updatedDocumentRect.maxY();
   3066             LayoutUnit clippedLogicalLeft = 0;
   3067             if (!renderView->style()->isLeftToRightDirection())
   3068                 clippedLogicalLeft = docLogicalRight - pageLogicalWidth;
   3069             LayoutRect overflow(clippedLogicalLeft, docLogicalTop, pageLogicalWidth, docLogicalHeight);
   3070 
   3071             if (!horizontalWritingMode)
   3072                 overflow = overflow.transposedRect();
   3073             renderView->clearLayoutOverflow();
   3074             renderView->addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
   3075         }
   3076     }
   3077 
   3078     if (shouldAdjustViewSize)
   3079         adjustViewSize();
   3080 }
   3081 
   3082 IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
   3083 {
   3084     IntRect rect = pixelSnappedIntRect(enclosingLayoutRect(renderer->localToAbsoluteQuad(FloatRect(rendererRect)).boundingBox()));
   3085 
   3086     // Convert from page ("absolute") to FrameView coordinates.
   3087     rect.moveBy(-scrollPosition());
   3088 
   3089     return rect;
   3090 }
   3091 
   3092 IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect& viewRect) const
   3093 {
   3094     IntRect rect = viewRect;
   3095 
   3096     // Convert from FrameView coords into page ("absolute") coordinates.
   3097     rect.moveBy(scrollPosition());
   3098 
   3099     // FIXME: we don't have a way to map an absolute rect down to a local quad, so just
   3100     // move the rect for now.
   3101     rect.setLocation(roundedIntPoint(renderer->absoluteToLocal(rect.location(), UseTransforms)));
   3102     return rect;
   3103 }
   3104 
   3105 IntPoint FrameView::convertFromRenderer(const RenderObject* renderer, const IntPoint& rendererPoint) const
   3106 {
   3107     IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, UseTransforms));
   3108 
   3109     // Convert from page ("absolute") to FrameView coordinates.
   3110     point.moveBy(-scrollPosition());
   3111     return point;
   3112 }
   3113 
   3114 IntPoint FrameView::convertToRenderer(const RenderObject* renderer, const IntPoint& viewPoint) const
   3115 {
   3116     IntPoint point = viewPoint;
   3117 
   3118     // Convert from FrameView coords into page ("absolute") coordinates.
   3119     point += IntSize(scrollX(), scrollY());
   3120 
   3121     return roundedIntPoint(renderer->absoluteToLocal(point, UseTransforms));
   3122 }
   3123 
   3124 IntRect FrameView::convertToContainingView(const IntRect& localRect) const
   3125 {
   3126     if (const ScrollView* parentScrollView = parent()) {
   3127         if (parentScrollView->isFrameView()) {
   3128             const FrameView* parentView = toFrameView(parentScrollView);
   3129             // Get our renderer in the parent view
   3130             RenderPart* renderer = m_frame->ownerRenderer();
   3131             if (!renderer)
   3132                 return localRect;
   3133 
   3134             IntRect rect(localRect);
   3135             // Add borders and padding??
   3136             rect.move(renderer->borderLeft() + renderer->paddingLeft(),
   3137                       renderer->borderTop() + renderer->paddingTop());
   3138             return parentView->convertFromRenderer(renderer, rect);
   3139         }
   3140 
   3141         return Widget::convertToContainingView(localRect);
   3142     }
   3143 
   3144     return localRect;
   3145 }
   3146 
   3147 IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
   3148 {
   3149     if (const ScrollView* parentScrollView = parent()) {
   3150         if (parentScrollView->isFrameView()) {
   3151             const FrameView* parentView = toFrameView(parentScrollView);
   3152 
   3153             // Get our renderer in the parent view
   3154             RenderPart* renderer = m_frame->ownerRenderer();
   3155             if (!renderer)
   3156                 return parentRect;
   3157 
   3158             IntRect rect = parentView->convertToRenderer(renderer, parentRect);
   3159             // Subtract borders and padding
   3160             rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
   3161                       -renderer->borderTop() - renderer->paddingTop());
   3162             return rect;
   3163         }
   3164 
   3165         return Widget::convertFromContainingView(parentRect);
   3166     }
   3167 
   3168     return parentRect;
   3169 }
   3170 
   3171 IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
   3172 {
   3173     if (const ScrollView* parentScrollView = parent()) {
   3174         if (parentScrollView->isFrameView()) {
   3175             const FrameView* parentView = toFrameView(parentScrollView);
   3176 
   3177             // Get our renderer in the parent view
   3178             RenderPart* renderer = m_frame->ownerRenderer();
   3179             if (!renderer)
   3180                 return localPoint;
   3181 
   3182             IntPoint point(localPoint);
   3183 
   3184             // Add borders and padding
   3185             point.move(renderer->borderLeft() + renderer->paddingLeft(),
   3186                        renderer->borderTop() + renderer->paddingTop());
   3187             return parentView->convertFromRenderer(renderer, point);
   3188         }
   3189 
   3190         return Widget::convertToContainingView(localPoint);
   3191     }
   3192 
   3193     return localPoint;
   3194 }
   3195 
   3196 IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
   3197 {
   3198     if (const ScrollView* parentScrollView = parent()) {
   3199         if (parentScrollView->isFrameView()) {
   3200             const FrameView* parentView = toFrameView(parentScrollView);
   3201 
   3202             // Get our renderer in the parent view
   3203             RenderPart* renderer = m_frame->ownerRenderer();
   3204             if (!renderer)
   3205                 return parentPoint;
   3206 
   3207             IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
   3208             // Subtract borders and padding
   3209             point.move(-renderer->borderLeft() - renderer->paddingLeft(),
   3210                        -renderer->borderTop() - renderer->paddingTop());
   3211             return point;
   3212         }
   3213 
   3214         return Widget::convertFromContainingView(parentPoint);
   3215     }
   3216 
   3217     return parentPoint;
   3218 }
   3219 
   3220 // Normal delay
   3221 void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
   3222 {
   3223     s_normalDeferredRepaintDelay = p;
   3224 }
   3225 
   3226 // Negative value would mean that first few repaints happen without a delay
   3227 void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p)
   3228 {
   3229     s_initialDeferredRepaintDelayDuringLoading = p;
   3230 }
   3231 
   3232 // The delay grows on each repaint to this maximum value
   3233 void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p)
   3234 {
   3235     s_maxDeferredRepaintDelayDuringLoading = p;
   3236 }
   3237 
   3238 // On each repaint the delay increases by this amount
   3239 void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p)
   3240 {
   3241     s_deferredRepaintDelayIncrementDuringLoading = p;
   3242 }
   3243 
   3244 void FrameView::setTracksRepaints(bool trackRepaints)
   3245 {
   3246     if (trackRepaints == m_isTrackingRepaints)
   3247         return;
   3248 
   3249     for (Frame* frame = m_frame->tree()->top(); frame; frame = frame->tree()->traverseNext()) {
   3250         if (RenderView* renderView = frame->contentRenderer())
   3251             renderView->compositor()->setTracksRepaints(trackRepaints);
   3252     }
   3253 
   3254     resetTrackedRepaints();
   3255     m_isTrackingRepaints = trackRepaints;
   3256 }
   3257 
   3258 void FrameView::resetTrackedRepaints()
   3259 {
   3260     m_trackedRepaintRects.clear();
   3261     if (RenderView* renderView = this->renderView())
   3262         renderView->compositor()->resetTrackedRepaintRects();
   3263 }
   3264 
   3265 String FrameView::trackedRepaintRectsAsText() const
   3266 {
   3267     TextStream ts;
   3268     if (!m_trackedRepaintRects.isEmpty()) {
   3269         ts << "(repaint rects\n";
   3270         for (size_t i = 0; i < m_trackedRepaintRects.size(); ++i)
   3271             ts << "  (rect " << m_trackedRepaintRects[i].x() << " " << m_trackedRepaintRects[i].y() << " " << m_trackedRepaintRects[i].width() << " " << m_trackedRepaintRects[i].height() << ")\n";
   3272         ts << ")\n";
   3273     }
   3274     return ts.release();
   3275 }
   3276 
   3277 void FrameView::addResizerArea(RenderLayer* resizerLayer)
   3278 {
   3279     if (!m_resizerAreas)
   3280         m_resizerAreas = adoptPtr(new ResizerAreaSet);
   3281     m_resizerAreas->add(resizerLayer);
   3282 }
   3283 
   3284 void FrameView::removeResizerArea(RenderLayer* resizerLayer)
   3285 {
   3286     if (!m_resizerAreas)
   3287         return;
   3288 
   3289     ResizerAreaSet::iterator it = m_resizerAreas->find(resizerLayer);
   3290     if (it != m_resizerAreas->end())
   3291         m_resizerAreas->remove(it);
   3292 }
   3293 
   3294 bool FrameView::addScrollableArea(ScrollableArea* scrollableArea)
   3295 {
   3296     if (!m_scrollableAreas)
   3297         m_scrollableAreas = adoptPtr(new ScrollableAreaSet);
   3298     return m_scrollableAreas->add(scrollableArea).isNewEntry;
   3299 }
   3300 
   3301 bool FrameView::removeScrollableArea(ScrollableArea* scrollableArea)
   3302 {
   3303     if (!m_scrollableAreas)
   3304         return false;
   3305 
   3306     ScrollableAreaSet::iterator it = m_scrollableAreas->find(scrollableArea);
   3307     if (it == m_scrollableAreas->end())
   3308         return false;
   3309 
   3310     m_scrollableAreas->remove(it);
   3311     return true;
   3312 }
   3313 
   3314 bool FrameView::containsScrollableArea(ScrollableArea* scrollableArea) const
   3315 {
   3316     if (!m_scrollableAreas)
   3317         return false;
   3318     return m_scrollableAreas->contains(scrollableArea);
   3319 }
   3320 
   3321 void FrameView::removeChild(Widget* widget)
   3322 {
   3323     if (widget->isFrameView())
   3324         removeScrollableArea(toFrameView(widget));
   3325 
   3326     ScrollView::removeChild(widget);
   3327 }
   3328 
   3329 bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent)
   3330 {
   3331     // Note that to allow for rubber-band over-scroll behavior, even non-scrollable views
   3332     // should handle wheel events.
   3333 #if !ENABLE(RUBBER_BANDING)
   3334     if (!isScrollable())
   3335         return false;
   3336 #endif
   3337 
   3338     // We don't allow mouse wheeling to happen in a ScrollView that has had its scrollbars explicitly disabled.
   3339     if (!canHaveScrollbars())
   3340         return false;
   3341 
   3342     return ScrollableArea::handleWheelEvent(wheelEvent);
   3343 }
   3344 
   3345 
   3346 bool FrameView::isVerticalDocument() const
   3347 {
   3348     RenderView* renderView = this->renderView();
   3349     if (!renderView)
   3350         return true;
   3351 
   3352     return renderView->style()->isHorizontalWritingMode();
   3353 }
   3354 
   3355 bool FrameView::isFlippedDocument() const
   3356 {
   3357     RenderView* renderView = this->renderView();
   3358     if (!renderView)
   3359         return false;
   3360 
   3361     return renderView->style()->isFlippedBlocksWritingMode();
   3362 }
   3363 
   3364 AXObjectCache* FrameView::axObjectCache() const
   3365 {
   3366     if (frame() && frame()->document())
   3367         return frame()->document()->existingAXObjectCache();
   3368     return 0;
   3369 }
   3370 
   3371 } // namespace WebCore
   3372