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