Home | History | Annotate | Download | only in page
      1 /*
      2  * Copyright (C) 1998, 1999 Torben Weis <weis (at) kde.org>
      3  *                     1999 Lars Knoll <knoll (at) kde.org>
      4  *                     1999 Antti Koivisto <koivisto (at) kde.org>
      5  *                     2000 Dirk Mueller <mueller (at) kde.org>
      6  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
      7  *           (C) 2006 Graham Dennis (graham.dennis (at) gmail.com)
      8  *           (C) 2006 Alexey Proskuryakov (ap (at) nypop.com)
      9  * Copyright (C) 2009 Google Inc. All rights reserved.
     10  *
     11  * This library is free software; you can redistribute it and/or
     12  * modify it under the terms of the GNU Library General Public
     13  * License as published by the Free Software Foundation; either
     14  * version 2 of the License, or (at your option) any later version.
     15  *
     16  * This library is distributed in the hope that it will be useful,
     17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19  * Library General Public License for more details.
     20  *
     21  * You should have received a copy of the GNU Library General Public License
     22  * along with this library; see the file COPYING.LIB.  If not, write to
     23  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     24  * Boston, MA 02110-1301, USA.
     25  */
     26 
     27 #include "config.h"
     28 #include "FrameView.h"
     29 
     30 #include "AXObjectCache.h"
     31 #include "CSSStyleSelector.h"
     32 #include "CachedResourceLoader.h"
     33 #include "Chrome.h"
     34 #include "ChromeClient.h"
     35 #include "DocumentMarkerController.h"
     36 #include "EventHandler.h"
     37 #include "FloatRect.h"
     38 #include "FocusController.h"
     39 #include "Frame.h"
     40 #include "FrameActionScheduler.h"
     41 #include "FrameLoader.h"
     42 #include "FrameLoaderClient.h"
     43 #include "FrameTree.h"
     44 #include "GraphicsContext.h"
     45 #include "HTMLDocument.h"
     46 #include "HTMLFrameElement.h"
     47 #include "HTMLFrameSetElement.h"
     48 #include "HTMLNames.h"
     49 #include "HTMLPlugInImageElement.h"
     50 #include "InspectorInstrumentation.h"
     51 #include "OverflowEvent.h"
     52 #include "RenderEmbeddedObject.h"
     53 #include "RenderFullScreen.h"
     54 #include "RenderLayer.h"
     55 #include "RenderPart.h"
     56 #include "RenderScrollbar.h"
     57 #include "RenderScrollbarPart.h"
     58 #include "RenderTheme.h"
     59 #include "RenderView.h"
     60 #include "ScrollAnimator.h"
     61 #include "Settings.h"
     62 #include "TextResourceDecoder.h"
     63 #include <wtf/CurrentTime.h>
     64 
     65 #if USE(ACCELERATED_COMPOSITING)
     66 #include "RenderLayerCompositor.h"
     67 #endif
     68 
     69 #if ENABLE(SVG)
     70 #include "SVGDocument.h"
     71 #include "SVGLocatable.h"
     72 #include "SVGNames.h"
     73 #include "SVGPreserveAspectRatio.h"
     74 #include "SVGSVGElement.h"
     75 #include "SVGViewElement.h"
     76 #include "SVGViewSpec.h"
     77 #endif
     78 
     79 #if ENABLE(TILED_BACKING_STORE)
     80 #include "TiledBackingStore.h"
     81 #endif
     82 
     83 #if PLATFORM(ANDROID)
     84 #include "WebCoreFrameBridge.h"
     85 #endif
     86 
     87 namespace WebCore {
     88 
     89 using namespace HTMLNames;
     90 
     91 double FrameView::sCurrentPaintTimeStamp = 0.0;
     92 
     93 // REPAINT_THROTTLING now chooses default values for throttling parameters.
     94 // Should be removed when applications start using runtime configuration.
     95 #if ENABLE(REPAINT_THROTTLING)
     96 // Normal delay
     97 double FrameView::s_deferredRepaintDelay = 0.025;
     98 // Negative value would mean that first few repaints happen without a delay
     99 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
    100 // The delay grows on each repaint to this maximum value
    101 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 2.5;
    102 // On each repaint the delay increses by this amount
    103 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5;
    104 #else
    105 // FIXME: Repaint throttling could be good to have on all platform.
    106 // The balance between CPU use and repaint frequency will need some tuning for desktop.
    107 // More hooks may be needed to reset the delay on things like GIF and CSS animations.
    108 double FrameView::s_deferredRepaintDelay = 0;
    109 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
    110 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0;
    111 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0;
    112 #endif
    113 
    114 // The maximum number of updateWidgets iterations that should be done before returning.
    115 static const unsigned maxUpdateWidgetsIterations = 2;
    116 
    117 FrameView::FrameView(Frame* frame)
    118     : m_frame(frame)
    119     , m_canHaveScrollbars(true)
    120     , m_slowRepaintObjectCount(0)
    121     , m_fixedObjectCount(0)
    122     , m_layoutTimer(this, &FrameView::layoutTimerFired)
    123     , m_layoutRoot(0)
    124     , m_hasPendingPostLayoutTasks(false)
    125     , m_inSynchronousPostLayout(false)
    126     , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
    127     , m_isTransparent(false)
    128     , m_baseBackgroundColor(Color::white)
    129     , m_mediaType("screen")
    130     , m_actionScheduler(new FrameActionScheduler())
    131     , m_overflowStatusDirty(true)
    132     , m_viewportRenderer(0)
    133     , m_wasScrolledByUser(false)
    134     , m_inProgrammaticScroll(false)
    135     , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired)
    136     , m_shouldUpdateWhileOffscreen(true)
    137     , m_deferSetNeedsLayouts(0)
    138     , m_setNeedsLayoutWasDeferred(false)
    139     , m_scrollCorner(0)
    140 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
    141     , m_hasOverflowScroll(false)
    142 #endif
    143 {
    144     init();
    145 
    146     if (m_frame) {
    147         if (Page* page = m_frame->page()) {
    148             m_page = page;
    149             m_page->addScrollableArea(this);
    150 
    151             if (m_frame == m_page->mainFrame()) {
    152                 ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
    153                 ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
    154             }
    155         }
    156     }
    157 }
    158 
    159 PassRefPtr<FrameView> FrameView::create(Frame* frame)
    160 {
    161     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
    162     view->show();
    163     return view.release();
    164 }
    165 
    166 PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize)
    167 {
    168     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
    169     view->Widget::setFrameRect(IntRect(view->pos(), initialSize));
    170     view->setInitialBoundsSize(initialSize);
    171     view->show();
    172     return view.release();
    173 }
    174 
    175 FrameView::~FrameView()
    176 {
    177     if (m_hasPendingPostLayoutTasks) {
    178         m_postLayoutTasksTimer.stop();
    179         m_actionScheduler->clear();
    180     }
    181 
    182     if (AXObjectCache::accessibilityEnabled() && axObjectCache())
    183         axObjectCache()->remove(this);
    184 
    185     resetScrollbars();
    186 
    187     // Custom scrollbars should already be destroyed at this point
    188     ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
    189     ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
    190 
    191     setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
    192     setHasVerticalScrollbar(false);
    193 
    194     ASSERT(!m_scrollCorner);
    195     ASSERT(m_actionScheduler->isEmpty());
    196 
    197     if (m_page)
    198         m_page->removeScrollableArea(this);
    199 
    200     if (m_frame) {
    201         ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
    202         RenderPart* renderer = m_frame->ownerRenderer();
    203         if (renderer && renderer->widget() == this)
    204             renderer->setWidget(0);
    205     }
    206 }
    207 
    208 void FrameView::reset()
    209 {
    210     m_useSlowRepaints = false;
    211     m_isOverlapped = false;
    212     m_contentIsOpaque = false;
    213     m_borderX = 30;
    214     m_borderY = 30;
    215     m_layoutTimer.stop();
    216     m_layoutRoot = 0;
    217     m_delayedLayout = false;
    218     m_doFullRepaint = true;
    219     m_layoutSchedulingEnabled = true;
    220     m_inLayout = false;
    221     m_inSynchronousPostLayout = false;
    222     m_hasPendingPostLayoutTasks = false;
    223     m_layoutCount = 0;
    224     m_nestedLayoutCount = 0;
    225     m_postLayoutTasksTimer.stop();
    226     m_firstLayout = true;
    227     m_firstLayoutCallbackPending = false;
    228     m_wasScrolledByUser = false;
    229     m_lastLayoutSize = IntSize();
    230     m_lastZoomFactor = 1.0f;
    231     m_deferringRepaints = 0;
    232     m_repaintCount = 0;
    233     m_repaintRects.clear();
    234     m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading;
    235     m_deferredRepaintTimer.stop();
    236     m_lastPaintTime = 0;
    237     m_paintBehavior = PaintBehaviorNormal;
    238     m_isPainting = false;
    239     m_isVisuallyNonEmpty = false;
    240     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
    241     m_maintainScrollPositionAnchor = 0;
    242 }
    243 
    244 bool FrameView::isFrameView() const
    245 {
    246     return true;
    247 }
    248 
    249 void FrameView::clearFrame()
    250 {
    251     m_frame = 0;
    252 }
    253 
    254 void FrameView::resetScrollbars()
    255 {
    256     // Reset the document's scrollbars back to our defaults before we yield the floor.
    257     m_firstLayout = true;
    258     setScrollbarsSuppressed(true);
    259     if (m_canHaveScrollbars)
    260         setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
    261     else
    262         setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
    263     setScrollbarsSuppressed(false);
    264 }
    265 
    266 void FrameView::resetScrollbarsAndClearContentsSize()
    267 {
    268     // Since the contents size is being cleared, the scroll position will lost as a consequence.
    269     // Cache the scroll position so it can be restored by the page cache if necessary.
    270     cacheCurrentScrollPosition();
    271 
    272     resetScrollbars();
    273 
    274     setScrollbarsSuppressed(true);
    275     setContentsSize(IntSize());
    276     setScrollbarsSuppressed(false);
    277 }
    278 
    279 void FrameView::init()
    280 {
    281     reset();
    282 
    283     m_margins = IntSize(-1, -1); // undefined
    284     m_size = IntSize();
    285 
    286     // Propagate the marginwidth/height and scrolling modes to the view.
    287     Element* ownerElement = m_frame ? m_frame->ownerElement() : 0;
    288     if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
    289         HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
    290         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
    291             setCanHaveScrollbars(false);
    292         int marginWidth = frameElt->marginWidth();
    293         int marginHeight = frameElt->marginHeight();
    294         if (marginWidth != -1)
    295             setMarginWidth(marginWidth);
    296         if (marginHeight != -1)
    297             setMarginHeight(marginHeight);
    298     }
    299 }
    300 
    301 void FrameView::detachCustomScrollbars()
    302 {
    303     if (!m_frame)
    304         return;
    305 
    306     Scrollbar* horizontalBar = horizontalScrollbar();
    307     if (horizontalBar && horizontalBar->isCustomScrollbar())
    308         setHasHorizontalScrollbar(false);
    309 
    310     Scrollbar* verticalBar = verticalScrollbar();
    311     if (verticalBar && verticalBar->isCustomScrollbar())
    312         setHasVerticalScrollbar(false);
    313 
    314     if (m_scrollCorner) {
    315         m_scrollCorner->destroy();
    316         m_scrollCorner = 0;
    317     }
    318 }
    319 
    320 void FrameView::clear()
    321 {
    322     setCanBlitOnScroll(true);
    323 
    324     reset();
    325 
    326     if (m_frame) {
    327         if (RenderPart* renderer = m_frame->ownerRenderer())
    328             renderer->viewCleared();
    329     }
    330 
    331     setScrollbarsSuppressed(true);
    332 }
    333 
    334 bool FrameView::didFirstLayout() const
    335 {
    336     return !m_firstLayout;
    337 }
    338 
    339 void FrameView::invalidateRect(const IntRect& rect)
    340 {
    341     if (!parent()) {
    342         if (hostWindow())
    343             hostWindow()->invalidateContentsAndWindow(rect, false /*immediate*/);
    344         return;
    345     }
    346 
    347     if (!m_frame)
    348         return;
    349 
    350     RenderPart* renderer = m_frame->ownerRenderer();
    351     if (!renderer)
    352         return;
    353 
    354     IntRect repaintRect = rect;
    355     repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
    356                      renderer->borderTop() + renderer->paddingTop());
    357     renderer->repaintRectangle(repaintRect);
    358 }
    359 
    360 void FrameView::setFrameRect(const IntRect& newRect)
    361 {
    362     IntRect oldRect = frameRect();
    363     if (newRect == oldRect)
    364         return;
    365 
    366     ScrollView::setFrameRect(newRect);
    367 
    368 #if USE(ACCELERATED_COMPOSITING)
    369     if (RenderView* root = m_frame->contentRenderer()) {
    370         if (root->usesCompositing())
    371             root->compositor()->frameViewDidChangeSize();
    372     }
    373 #endif
    374 }
    375 
    376 #if ENABLE(REQUEST_ANIMATION_FRAME)
    377 void FrameView::scheduleAnimation()
    378 {
    379     if (hostWindow())
    380         hostWindow()->scheduleAnimation();
    381 }
    382 #endif
    383 
    384 void FrameView::setMarginWidth(int w)
    385 {
    386     // make it update the rendering area when set
    387     m_margins.setWidth(w);
    388 }
    389 
    390 void FrameView::setMarginHeight(int h)
    391 {
    392     // make it update the rendering area when set
    393     m_margins.setHeight(h);
    394 }
    395 
    396 bool FrameView::avoidScrollbarCreation() const
    397 {
    398     ASSERT(m_frame);
    399 
    400     // with frame flattening no subframe can have scrollbars
    401     // but we also cannot turn scrollbars of as we determine
    402     // our flattening policy using that.
    403 
    404     if (!m_frame->ownerElement())
    405         return false;
    406 
    407     if (!m_frame->settings() || m_frame->settings()->frameFlatteningEnabled())
    408         return true;
    409 
    410     return false;
    411 }
    412 
    413 void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
    414 {
    415     m_canHaveScrollbars = canHaveScrollbars;
    416     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
    417 }
    418 
    419 void FrameView::updateCanHaveScrollbars()
    420 {
    421     ScrollbarMode hMode;
    422     ScrollbarMode vMode;
    423     scrollbarModes(hMode, vMode);
    424     if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
    425         setCanHaveScrollbars(false);
    426     else
    427         setCanHaveScrollbars(true);
    428 }
    429 
    430 PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
    431 {
    432     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
    433     Document* doc = m_frame->document();
    434 
    435     // Try the <body> element first as a scrollbar source.
    436     Element* body = doc ? doc->body() : 0;
    437     if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR))
    438         return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderer()->enclosingBox());
    439 
    440     // If the <body> didn't have a custom style, then the root element might.
    441     Element* docElement = doc ? doc->documentElement() : 0;
    442     if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(SCROLLBAR))
    443         return RenderScrollbar::createCustomScrollbar(this, orientation, docElement->renderBox());
    444 
    445     // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
    446     RenderPart* frameRenderer = m_frame->ownerRenderer();
    447     if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR))
    448         return RenderScrollbar::createCustomScrollbar(this, orientation, 0, m_frame.get());
    449 
    450     // Nobody set a custom style, so we just use a native scrollbar.
    451     return ScrollView::createScrollbar(orientation);
    452 }
    453 
    454 void FrameView::setContentsSize(const IntSize& size)
    455 {
    456     if (size == contentsSize())
    457         return;
    458 
    459     m_deferSetNeedsLayouts++;
    460 
    461     ScrollView::setContentsSize(size);
    462     scrollAnimator()->contentsResized();
    463 
    464     Page* page = frame() ? frame()->page() : 0;
    465     if (!page)
    466         return;
    467 
    468     page->chrome()->contentsSizeChanged(frame(), size); //notify only
    469 
    470     m_deferSetNeedsLayouts--;
    471 
    472     if (!m_deferSetNeedsLayouts)
    473         m_setNeedsLayoutWasDeferred = false; // FIXME: Find a way to make the deferred layout actually happen.
    474 }
    475 
    476 void FrameView::adjustViewSize()
    477 {
    478     ASSERT(m_frame->view() == this);
    479     RenderView* root = m_frame->contentRenderer();
    480     if (!root)
    481         return;
    482 
    483     IntSize size = IntSize(root->docWidth(), root->docHeight());
    484 
    485     ScrollView::setScrollOrigin(IntPoint(-root->docLeft(), -root->docTop()), !m_frame->document()->printing(), size == contentsSize());
    486 
    487     setContentsSize(size);
    488 }
    489 
    490 void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
    491 {
    492     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
    493     // overflow:hidden and overflow:scroll on <body> as applying to the document's
    494     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
    495     // use the root element.
    496     switch (o->style()->overflowX()) {
    497         case OHIDDEN:
    498             hMode = ScrollbarAlwaysOff;
    499             break;
    500         case OSCROLL:
    501             hMode = ScrollbarAlwaysOn;
    502             break;
    503         case OAUTO:
    504             hMode = ScrollbarAuto;
    505             break;
    506         default:
    507             // Don't set it at all.
    508             ;
    509     }
    510 
    511      switch (o->style()->overflowY()) {
    512         case OHIDDEN:
    513             vMode = ScrollbarAlwaysOff;
    514             break;
    515         case OSCROLL:
    516             vMode = ScrollbarAlwaysOn;
    517             break;
    518         case OAUTO:
    519             vMode = ScrollbarAuto;
    520             break;
    521         default:
    522             // Don't set it at all.
    523             ;
    524     }
    525 
    526     m_viewportRenderer = o;
    527 }
    528 
    529 void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode)
    530 {
    531     m_viewportRenderer = 0;
    532 
    533     const HTMLFrameOwnerElement* owner = m_frame->ownerElement();
    534     if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
    535         hMode = ScrollbarAlwaysOff;
    536         vMode = ScrollbarAlwaysOff;
    537         return;
    538     }
    539 
    540     if (m_canHaveScrollbars) {
    541         hMode = ScrollbarAuto;
    542         vMode = ScrollbarAuto;
    543     } else {
    544         hMode = ScrollbarAlwaysOff;
    545         vMode = ScrollbarAlwaysOff;
    546     }
    547 
    548     if (!m_layoutRoot) {
    549         Document* document = m_frame->document();
    550         Node* documentElement = document->documentElement();
    551         RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
    552         Node* body = document->body();
    553         if (body && body->renderer()) {
    554             if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) {
    555                 vMode = ScrollbarAlwaysOff;
    556                 hMode = ScrollbarAlwaysOff;
    557             } else if (body->hasTagName(bodyTag)) {
    558                 // It's sufficient to just check the X overflow,
    559                 // since it's illegal to have visible in only one direction.
    560                 RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
    561                 applyOverflowToViewport(o, hMode, vMode);
    562             }
    563         } else if (rootRenderer) {
    564 #if ENABLE(SVG)
    565             if (!documentElement->isSVGElement())
    566                 applyOverflowToViewport(rootRenderer, hMode, vMode);
    567 #else
    568             applyOverflowToViewport(rootRenderer, hMode, vMode);
    569 #endif
    570         }
    571     }
    572 }
    573 
    574 #if ENABLE(FULLSCREEN_API) && USE(ACCELERATED_COMPOSITING)
    575 static bool isDocumentRunningFullScreenAnimation(Document* document)
    576 {
    577     return document->webkitIsFullScreen() && document->fullScreenRenderer() && document->fullScreenRenderer()->isAnimating();
    578 }
    579 #endif
    580 
    581 #if USE(ACCELERATED_COMPOSITING)
    582 void FrameView::updateCompositingLayers()
    583 {
    584     RenderView* view = m_frame->contentRenderer();
    585     if (!view)
    586         return;
    587 
    588     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
    589     view->compositor()->cacheAcceleratedCompositingFlags();
    590     view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange);
    591 
    592 #if ENABLE(FULLSCREEN_API)
    593     Document* document = m_frame->document();
    594     if (isDocumentRunningFullScreenAnimation(document))
    595         view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange, document->fullScreenRenderer()->layer());
    596 #endif
    597 }
    598 
    599 GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
    600 {
    601     RenderView* view = m_frame->contentRenderer();
    602     if (!view)
    603         return 0;
    604     return view->compositor()->layerForHorizontalScrollbar();
    605 }
    606 
    607 GraphicsLayer* FrameView::layerForVerticalScrollbar() const
    608 {
    609     RenderView* view = m_frame->contentRenderer();
    610     if (!view)
    611         return 0;
    612     return view->compositor()->layerForVerticalScrollbar();
    613 }
    614 
    615 GraphicsLayer* FrameView::layerForScrollCorner() const
    616 {
    617     RenderView* view = m_frame->contentRenderer();
    618     if (!view)
    619         return 0;
    620     return view->compositor()->layerForScrollCorner();
    621 }
    622 
    623 bool FrameView::syncCompositingStateForThisFrame()
    624 {
    625     ASSERT(m_frame->view() == this);
    626     RenderView* view = m_frame->contentRenderer();
    627     if (!view)
    628         return true; // We don't want to keep trying to update layers if we have no renderer.
    629 
    630     // If we sync compositing layers when a layout is pending, we may cause painting of compositing
    631     // layer content to occur before layout has happened, which will cause paintContents() to bail.
    632     if (needsLayout())
    633         return false;
    634 
    635     if (GraphicsLayer* graphicsLayer = view->compositor()->layerForHorizontalScrollbar())
    636         graphicsLayer->syncCompositingStateForThisLayerOnly();
    637     if (GraphicsLayer* graphicsLayer = view->compositor()->layerForVerticalScrollbar())
    638         graphicsLayer->syncCompositingStateForThisLayerOnly();
    639     if (GraphicsLayer* graphicsLayer = view->compositor()->layerForScrollCorner())
    640         graphicsLayer->syncCompositingStateForThisLayerOnly();
    641 
    642     view->compositor()->flushPendingLayerChanges();
    643 
    644 #if ENABLE(FULLSCREEN_API)
    645     // The fullScreenRenderer's graphicsLayer  has been re-parented, and the above recursive syncCompositingState
    646     // call will not cause the subtree under it to repaint.  Explicitly call the syncCompositingState on
    647     // the fullScreenRenderer's graphicsLayer here:
    648     Document* document = m_frame->document();
    649     if (isDocumentRunningFullScreenAnimation(document)) {
    650 #if PLATFORM(ANDROID)
    651         // We don't create an extra layer for the full screen video.
    652         if (!document->fullScreenRenderer()->layer()
    653             || !document->fullScreenRenderer()->layer()->backing())
    654             return true;
    655 #endif
    656         RenderLayerBacking* backing = document->fullScreenRenderer()->layer()->backing();
    657         if (GraphicsLayer* fullScreenLayer = backing->graphicsLayer())
    658             fullScreenLayer->syncCompositingState();
    659     }
    660 #endif
    661     return true;
    662 }
    663 
    664 void FrameView::setNeedsOneShotDrawingSynchronization()
    665 {
    666     Page* page = frame() ? frame()->page() : 0;
    667     if (page)
    668         page->chrome()->client()->setNeedsOneShotDrawingSynchronization();
    669 }
    670 
    671 #endif // USE(ACCELERATED_COMPOSITING)
    672 
    673 bool FrameView::hasCompositedContent() const
    674 {
    675 #if USE(ACCELERATED_COMPOSITING)
    676     if (RenderView* view = m_frame->contentRenderer())
    677         return view->compositor()->inCompositingMode();
    678 #endif
    679     return false;
    680 }
    681 
    682 bool FrameView::hasCompositedContentIncludingDescendants() const
    683 {
    684 #if USE(ACCELERATED_COMPOSITING)
    685     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
    686         RenderView* renderView = frame->contentRenderer();
    687         RenderLayerCompositor* compositor = renderView ? renderView->compositor() : 0;
    688         if (compositor) {
    689             if (compositor->inCompositingMode())
    690                 return true;
    691 
    692             if (!RenderLayerCompositor::allowsIndependentlyCompositedFrames(this))
    693                 break;
    694         }
    695     }
    696 #endif
    697     return false;
    698 }
    699 
    700 bool FrameView::hasCompositingAncestor() const
    701 {
    702 #if USE(ACCELERATED_COMPOSITING)
    703     for (Frame* frame = m_frame->tree()->parent(); frame; frame = frame->tree()->parent()) {
    704         if (FrameView* view = frame->view()) {
    705             if (view->hasCompositedContent())
    706                 return true;
    707         }
    708     }
    709 #endif
    710     return false;
    711 }
    712 
    713 // Sometimes (for plug-ins) we need to eagerly go into compositing mode.
    714 void FrameView::enterCompositingMode()
    715 {
    716 #if USE(ACCELERATED_COMPOSITING)
    717     if (RenderView* view = m_frame->contentRenderer()) {
    718         view->compositor()->enableCompositingMode();
    719         if (!needsLayout())
    720             view->compositor()->scheduleCompositingLayerUpdate();
    721     }
    722 #endif
    723 }
    724 
    725 bool FrameView::isEnclosedInCompositingLayer() const
    726 {
    727 #if USE(ACCELERATED_COMPOSITING)
    728     RenderObject* frameOwnerRenderer = m_frame->ownerRenderer();
    729     if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
    730         return true;
    731 
    732     if (FrameView* parentView = parentFrameView())
    733         return parentView->isEnclosedInCompositingLayer();
    734 #endif
    735     return false;
    736 }
    737 
    738 bool FrameView::syncCompositingStateIncludingSubframes()
    739 {
    740 #if USE(ACCELERATED_COMPOSITING)
    741     bool allFramesSynced = syncCompositingStateForThisFrame();
    742 
    743     for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->traverseNext(m_frame.get())) {
    744         bool synced = child->view()->syncCompositingStateForThisFrame();
    745         allFramesSynced &= synced;
    746     }
    747     return allFramesSynced;
    748 #else // USE(ACCELERATED_COMPOSITING)
    749     return true;
    750 #endif
    751 }
    752 
    753 bool FrameView::isSoftwareRenderable() const
    754 {
    755 #if USE(ACCELERATED_COMPOSITING)
    756     RenderView* view = m_frame->contentRenderer();
    757     if (!view)
    758         return true;
    759 
    760     return !view->compositor()->has3DContent();
    761 #else
    762     return true;
    763 #endif
    764 }
    765 
    766 void FrameView::didMoveOnscreen()
    767 {
    768     RenderView* view = m_frame->contentRenderer();
    769     if (view)
    770         view->didMoveOnscreen();
    771     scrollAnimator()->contentAreaDidShow();
    772 }
    773 
    774 void FrameView::willMoveOffscreen()
    775 {
    776     RenderView* view = m_frame->contentRenderer();
    777     if (view)
    778         view->willMoveOffscreen();
    779     scrollAnimator()->contentAreaDidHide();
    780 }
    781 
    782 RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
    783 {
    784     return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
    785 }
    786 
    787 void FrameView::layout(bool allowSubtree)
    788 {
    789     if (m_inLayout)
    790         return;
    791 
    792     bool inSubframeLayoutWithFrameFlattening = parent() && m_frame->settings() && m_frame->settings()->frameFlatteningEnabled();
    793 
    794     if (inSubframeLayoutWithFrameFlattening) {
    795         if (parent()->isFrameView()) {
    796             FrameView* parentView =   static_cast<FrameView*>(parent());
    797             if (!parentView->m_nestedLayoutCount) {
    798                 while (parentView->parent() && parentView->parent()->isFrameView())
    799                     parentView = static_cast<FrameView*>(parentView->parent());
    800                 parentView->layout(allowSubtree);
    801                 return;
    802             }
    803         }
    804     }
    805 
    806     m_layoutTimer.stop();
    807     m_delayedLayout = false;
    808     m_setNeedsLayoutWasDeferred = false;
    809 
    810     // Protect the view from being deleted during layout (in recalcStyle)
    811     RefPtr<FrameView> protector(this);
    812 
    813     if (!m_frame) {
    814         // FIXME: Do we need to set m_size.width here?
    815         // FIXME: Should we set m_size.height here too?
    816         m_size.setWidth(layoutWidth());
    817         return;
    818     }
    819 
    820     // we shouldn't enter layout() while painting
    821     ASSERT(!isPainting());
    822     if (isPainting())
    823         return;
    824 
    825     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(m_frame.get());
    826 
    827     if (!allowSubtree && m_layoutRoot) {
    828         m_layoutRoot->markContainingBlocksForLayout(false);
    829         m_layoutRoot = 0;
    830     }
    831 
    832     ASSERT(m_frame->view() == this);
    833 
    834     Document* document = m_frame->document();
    835 
    836     m_layoutSchedulingEnabled = false;
    837 
    838     if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_hasPendingPostLayoutTasks && !inSubframeLayoutWithFrameFlattening) {
    839         // This is a new top-level layout. If there are any remaining tasks from the previous
    840         // layout, finish them now.
    841         m_inSynchronousPostLayout = true;
    842         m_postLayoutTasksTimer.stop();
    843         performPostLayoutTasks();
    844         m_inSynchronousPostLayout = false;
    845     }
    846 
    847     // Viewport-dependent media queries may cause us to need completely different style information.
    848     // Check that here.
    849     if (document->styleSelector()->affectedByViewportChange())
    850         document->styleSelectorChanged(RecalcStyleImmediately);
    851 
    852     // Always ensure our style info is up-to-date.  This can happen in situations where
    853     // the layout beats any sort of style recalc update that needs to occur.
    854     document->updateStyleIfNeeded();
    855 
    856     bool subtree = m_layoutRoot;
    857 
    858     // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
    859     // so there's no point to continuing to layout
    860     if (protector->hasOneRef())
    861         return;
    862 
    863     RenderObject* root = subtree ? m_layoutRoot : document->renderer();
    864     if (!root) {
    865         // FIXME: Do we need to set m_size here?
    866         m_layoutSchedulingEnabled = true;
    867         return;
    868     }
    869 
    870     m_nestedLayoutCount++;
    871 
    872     if (!m_layoutRoot) {
    873         Document* document = m_frame->document();
    874         Node* documentElement = document->documentElement();
    875         RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
    876         Node* body = document->body();
    877         if (body && body->renderer()) {
    878             if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) {
    879                 body->renderer()->setChildNeedsLayout(true);
    880             } else if (body->hasTagName(bodyTag)) {
    881                 if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewport())
    882                     body->renderer()->setChildNeedsLayout(true);
    883             }
    884         } else if (rootRenderer) {
    885 #if ENABLE(SVG)
    886             if (documentElement->isSVGElement()) {
    887                 if (!m_firstLayout && (m_size.width() != layoutWidth() || m_size.height() != layoutHeight()))
    888                     rootRenderer->setChildNeedsLayout(true);
    889             }
    890 #endif
    891         }
    892 
    893 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
    894         if (m_firstLayout && !m_frame->ownerElement())
    895             printf("Elapsed time before first layout: %d\n", document->elapsedTime());
    896 #endif
    897     }
    898 
    899     ScrollbarMode hMode;
    900     ScrollbarMode vMode;
    901     calculateScrollbarModesForLayout(hMode, vMode);
    902 
    903     m_doFullRepaint = !subtree && (m_firstLayout || toRenderView(root)->printing());
    904 
    905     if (!subtree) {
    906         // Now set our scrollbar state for the layout.
    907         ScrollbarMode currentHMode = horizontalScrollbarMode();
    908         ScrollbarMode currentVMode = verticalScrollbarMode();
    909 
    910         if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
    911             if (m_firstLayout) {
    912                 setScrollbarsSuppressed(true);
    913 
    914                 m_firstLayout = false;
    915                 m_firstLayoutCallbackPending = true;
    916                 m_lastLayoutSize = IntSize(width(), height());
    917                 m_lastZoomFactor = root->style()->zoom();
    918 
    919                 // Set the initial vMode to AlwaysOn if we're auto.
    920                 if (vMode == ScrollbarAuto)
    921                     setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
    922                 // Set the initial hMode to AlwaysOff if we're auto.
    923                 if (hMode == ScrollbarAuto)
    924                     setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
    925 
    926                 setScrollbarModes(hMode, vMode);
    927                 setScrollbarsSuppressed(false, true);
    928             } else
    929                 setScrollbarModes(hMode, vMode);
    930         }
    931 
    932         IntSize oldSize = m_size;
    933 
    934         m_size = IntSize(layoutWidth(), layoutHeight());
    935 
    936         if (oldSize != m_size) {
    937             m_doFullRepaint = true;
    938             if (!m_firstLayout) {
    939                 RenderBox* rootRenderer = document->documentElement() ? document->documentElement()->renderBox() : 0;
    940                 RenderBox* bodyRenderer = rootRenderer && document->body() ? document->body()->renderBox() : 0;
    941                 if (bodyRenderer && bodyRenderer->stretchesToViewport())
    942                     bodyRenderer->setChildNeedsLayout(true);
    943                 else if (rootRenderer && rootRenderer->stretchesToViewport())
    944                     rootRenderer->setChildNeedsLayout(true);
    945             }
    946         }
    947     }
    948 
    949     RenderLayer* layer = root->enclosingLayer();
    950 
    951     m_actionScheduler->pause();
    952 
    953     bool disableLayoutState = false;
    954     if (subtree) {
    955         RenderView* view = root->view();
    956         disableLayoutState = view->shouldDisableLayoutStateForSubtree(root);
    957         view->pushLayoutState(root);
    958         if (disableLayoutState)
    959             view->disableLayoutState();
    960     }
    961 
    962     m_inLayout = true;
    963     beginDeferredRepaints();
    964     root->layout();
    965     endDeferredRepaints();
    966     m_inLayout = false;
    967 
    968     if (subtree) {
    969         RenderView* view = root->view();
    970         view->popLayoutState(root);
    971         if (disableLayoutState)
    972             view->enableLayoutState();
    973     }
    974     m_layoutRoot = 0;
    975 
    976     m_layoutSchedulingEnabled = true;
    977 
    978     if (!subtree && !toRenderView(root)->printing())
    979         adjustViewSize();
    980 
    981     // Now update the positions of all layers.
    982     beginDeferredRepaints();
    983     IntPoint cachedOffset;
    984     if (m_doFullRepaint)
    985         root->view()->repaint(); // FIXME: This isn't really right, since the RenderView doesn't fully encompass the visibleContentRect(). It just happens
    986                                  // to work out most of the time, since first layouts and printing don't have you scrolled anywhere.
    987     layer->updateLayerPositions((m_doFullRepaint ? 0 : RenderLayer::CheckForRepaint)
    988                                 | RenderLayer::IsCompositingUpdateRoot
    989                                 | RenderLayer::UpdateCompositingLayers,
    990                                 subtree ? 0 : &cachedOffset);
    991     endDeferredRepaints();
    992 
    993 #if USE(ACCELERATED_COMPOSITING)
    994     updateCompositingLayers();
    995 #endif
    996 
    997     m_layoutCount++;
    998 
    999 #if PLATFORM(MAC) || PLATFORM(CHROMIUM)
   1000     if (AXObjectCache::accessibilityEnabled())
   1001         root->document()->axObjectCache()->postNotification(root, AXObjectCache::AXLayoutComplete, true);
   1002 #endif
   1003 #if ENABLE(DASHBOARD_SUPPORT)
   1004     updateDashboardRegions();
   1005 #endif
   1006 
   1007     ASSERT(!root->needsLayout());
   1008 
   1009     updateCanBlitOnScrollRecursively();
   1010 
   1011     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
   1012         updateOverflowStatus(layoutWidth() < contentsWidth(),
   1013                              layoutHeight() < contentsHeight());
   1014 
   1015     if (!m_hasPendingPostLayoutTasks) {
   1016         if (!m_inSynchronousPostLayout && !inSubframeLayoutWithFrameFlattening) {
   1017             m_inSynchronousPostLayout = true;
   1018             // Calls resumeScheduledEvents()
   1019             performPostLayoutTasks();
   1020             m_inSynchronousPostLayout = false;
   1021         }
   1022 
   1023         if (!m_hasPendingPostLayoutTasks && (needsLayout() || m_inSynchronousPostLayout || inSubframeLayoutWithFrameFlattening)) {
   1024             // If we need layout or are already in a synchronous call to postLayoutTasks(),
   1025             // defer widget updates and event dispatch until after we return. postLayoutTasks()
   1026             // can make us need to update again, and we can get stuck in a nasty cycle unless
   1027             // we call it through the timer here.
   1028             m_hasPendingPostLayoutTasks = true;
   1029             m_postLayoutTasksTimer.startOneShot(0);
   1030             if (needsLayout()) {
   1031                 m_actionScheduler->pause();
   1032                 layout();
   1033             }
   1034         }
   1035     } else {
   1036         m_actionScheduler->resume();
   1037     }
   1038 
   1039     InspectorInstrumentation::didLayout(cookie);
   1040 
   1041     m_nestedLayoutCount--;
   1042 #if ENABLE(ANDROID_OVERFLOW_SCROLL)
   1043     // Reset to false each time we layout in case the overflow status changed.
   1044     bool hasOverflowScroll = false;
   1045     RenderObject* ownerRenderer = m_frame->ownerRenderer();
   1046     if (ownerRenderer && ownerRenderer->isRenderIFrame()) {
   1047         RenderLayer* layer = ownerRenderer->enclosingLayer();
   1048         if (layer) {
   1049             // Some sites use tiny iframes for loading so don't composite those.
   1050             if (canHaveScrollbars() && layoutWidth() > 1 && layoutHeight() > 1)
   1051                 hasOverflowScroll = layoutWidth() < contentsWidth() || layoutHeight() < contentsHeight();
   1052         }
   1053     }
   1054     if (RenderView* view = m_frame->contentRenderer()) {
   1055         if (hasOverflowScroll != m_hasOverflowScroll) {
   1056             if (hasOverflowScroll)
   1057                 enterCompositingMode();
   1058             else
   1059                 // We are leaving overflow mode so we need to update the layer
   1060                 // tree in case that is the reason we were composited.
   1061                 view->compositor()->scheduleCompositingLayerUpdate();
   1062         }
   1063     }
   1064     m_hasOverflowScroll = hasOverflowScroll;
   1065 #endif
   1066 }
   1067 
   1068 void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object)
   1069 {
   1070     if (!m_widgetUpdateSet)
   1071         m_widgetUpdateSet.set(new RenderEmbeddedObjectSet);
   1072 
   1073     m_widgetUpdateSet->add(object);
   1074 }
   1075 
   1076 void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object)
   1077 {
   1078     if (!m_widgetUpdateSet)
   1079         return;
   1080 
   1081     m_widgetUpdateSet->remove(object);
   1082 }
   1083 
   1084 void FrameView::setMediaType(const String& mediaType)
   1085 {
   1086     m_mediaType = mediaType;
   1087 }
   1088 
   1089 String FrameView::mediaType() const
   1090 {
   1091     // See if we have an override type.
   1092     String overrideType = m_frame->loader()->client()->overrideMediaType();
   1093     if (!overrideType.isNull())
   1094         return overrideType;
   1095     return m_mediaType;
   1096 }
   1097 
   1098 void FrameView::adjustMediaTypeForPrinting(bool printing)
   1099 {
   1100     if (printing) {
   1101         if (m_mediaTypeWhenNotPrinting.isNull())
   1102             m_mediaTypeWhenNotPrinting = mediaType();
   1103             setMediaType("print");
   1104     } else {
   1105         if (!m_mediaTypeWhenNotPrinting.isNull())
   1106             setMediaType(m_mediaTypeWhenNotPrinting);
   1107         m_mediaTypeWhenNotPrinting = String();
   1108     }
   1109 }
   1110 
   1111 bool FrameView::useSlowRepaints() const
   1112 {
   1113     if (m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque)
   1114         return true;
   1115 
   1116     if (FrameView* parentView = parentFrameView())
   1117         return parentView->useSlowRepaints();
   1118 
   1119     return false;
   1120 }
   1121 
   1122 bool FrameView::useSlowRepaintsIfNotOverlapped() const
   1123 {
   1124     if (m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque)
   1125         return true;
   1126 
   1127     if (FrameView* parentView = parentFrameView())
   1128         return parentView->useSlowRepaintsIfNotOverlapped();
   1129 
   1130     return false;
   1131 }
   1132 
   1133 void FrameView::updateCanBlitOnScrollRecursively()
   1134 {
   1135     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
   1136         if (FrameView* view = frame->view())
   1137             view->setCanBlitOnScroll(!view->useSlowRepaints());
   1138     }
   1139 }
   1140 
   1141 void FrameView::setUseSlowRepaints()
   1142 {
   1143     m_useSlowRepaints = true;
   1144     updateCanBlitOnScrollRecursively();
   1145 }
   1146 
   1147 void FrameView::addSlowRepaintObject()
   1148 {
   1149     if (!m_slowRepaintObjectCount)
   1150         updateCanBlitOnScrollRecursively();
   1151     m_slowRepaintObjectCount++;
   1152 }
   1153 
   1154 void FrameView::removeSlowRepaintObject()
   1155 {
   1156     ASSERT(m_slowRepaintObjectCount > 0);
   1157     m_slowRepaintObjectCount--;
   1158     if (!m_slowRepaintObjectCount)
   1159         updateCanBlitOnScrollRecursively();
   1160 }
   1161 
   1162 void FrameView::addFixedObject()
   1163 {
   1164     if (!m_fixedObjectCount && platformWidget())
   1165         updateCanBlitOnScrollRecursively();
   1166     ++m_fixedObjectCount;
   1167 }
   1168 
   1169 void FrameView::removeFixedObject()
   1170 {
   1171     ASSERT(m_fixedObjectCount > 0);
   1172     --m_fixedObjectCount;
   1173     if (!m_fixedObjectCount)
   1174         updateCanBlitOnScrollRecursively();
   1175 }
   1176 
   1177 #if PLATFORM(ANDROID)
   1178 // When the screen size change, fixed positioned element should be updated.
   1179 void FrameView::updatePositionedObjects()
   1180 {
   1181     RenderBlock::PositionedObjectsListHashSet* positionedObjects = 0;
   1182     if (RenderView* root = m_frame->contentRenderer())
   1183         positionedObjects = root->positionedObjects();
   1184 
   1185     if (!positionedObjects || positionedObjects->isEmpty())
   1186         return;
   1187 
   1188     RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
   1189     for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
   1190         RenderBox* renderBox = *it;
   1191         if (renderBox->style()->position() != FixedPosition)
   1192             continue;
   1193 
   1194         renderBox->computeLogicalWidth();
   1195         renderBox->computeLogicalHeight();
   1196     }
   1197 }
   1198 #endif
   1199 
   1200 int FrameView::scrollXForFixedPosition() const
   1201 {
   1202     int visibleContentWidth = visibleContentRect().width();
   1203     int maxX = contentsWidth() - visibleContentWidth;
   1204 
   1205     if (maxX == 0)
   1206         return 0;
   1207 
   1208     int x = scrollX();
   1209 
   1210     if (x < 0)
   1211         x = 0;
   1212     else if (x > maxX)
   1213         x = maxX;
   1214 
   1215     if (!m_frame)
   1216         return x;
   1217 
   1218     float pageScaleFactor = m_frame->pageScaleFactor();
   1219 
   1220     // When the page is scaled, the scaled "viewport" with respect to which fixed object are positioned
   1221     // doesn't move as fast as the content view, so that when the content is scrolled all the way to the
   1222     // end, the bottom of the scaled "viewport" touches the bottom of the real viewport.
   1223     float dragFactor = (contentsWidth() - visibleContentWidth * pageScaleFactor) / maxX;
   1224 
   1225     return x * dragFactor / pageScaleFactor;
   1226 }
   1227 
   1228 int FrameView::scrollYForFixedPosition() const
   1229 {
   1230     int visibleContentHeight = visibleContentRect().height();
   1231 
   1232     int maxY = contentsHeight() - visibleContentHeight;
   1233     if (maxY == 0)
   1234         return 0;
   1235 
   1236     int y = scrollY();
   1237 
   1238     if (y < 0)
   1239         y = 0;
   1240     else if (y > maxY)
   1241         y = maxY;
   1242 
   1243     if (!m_frame)
   1244         return y;
   1245 
   1246     float pageScaleFactor = m_frame->pageScaleFactor();
   1247     float dragFactor = (contentsHeight() - visibleContentHeight * pageScaleFactor) / maxY;
   1248 
   1249     return y * dragFactor / pageScaleFactor;
   1250 }
   1251 
   1252 IntSize FrameView::scrollOffsetForFixedPosition() const
   1253 {
   1254     return IntSize(scrollXForFixedPosition(), scrollYForFixedPosition());
   1255 }
   1256 
   1257 IntPoint FrameView::currentMousePosition() const
   1258 {
   1259     return m_frame ? m_frame->eventHandler()->currentMousePosition() : IntPoint();
   1260 }
   1261 
   1262 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
   1263 {
   1264     const size_t fixedObjectThreshold = 5;
   1265 
   1266     RenderBlock::PositionedObjectsListHashSet* positionedObjects = 0;
   1267     if (RenderView* root = m_frame->contentRenderer())
   1268         positionedObjects = root->positionedObjects();
   1269 
   1270     if (!positionedObjects || positionedObjects->isEmpty()) {
   1271         hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
   1272         return true;
   1273     }
   1274 
   1275     // Get the rects of the fixed objects visible in the rectToScroll
   1276     Vector<IntRect, fixedObjectThreshold> subRectToUpdate;
   1277     bool updateInvalidatedSubRect = true;
   1278     RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
   1279     for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
   1280         RenderBox* renderBox = *it;
   1281         if (renderBox->style()->position() != FixedPosition)
   1282             continue;
   1283         IntRect updateRect = renderBox->layer()->repaintRectIncludingDescendants();
   1284         updateRect = contentsToWindow(updateRect);
   1285         if (clipsRepaints())
   1286             updateRect.intersect(rectToScroll);
   1287         if (!updateRect.isEmpty()) {
   1288             if (subRectToUpdate.size() >= fixedObjectThreshold) {
   1289                 updateInvalidatedSubRect = false;
   1290                 break;
   1291             }
   1292             subRectToUpdate.append(updateRect);
   1293         }
   1294     }
   1295 
   1296     // Scroll the view
   1297     if (updateInvalidatedSubRect) {
   1298         // 1) scroll
   1299         hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
   1300 
   1301         // 2) update the area of fixed objects that has been invalidated
   1302         size_t fixObjectsCount = subRectToUpdate.size();
   1303         for (size_t i = 0; i < fixObjectsCount; ++i) {
   1304             IntRect updateRect = subRectToUpdate[i];
   1305             IntRect scrolledRect = updateRect;
   1306             scrolledRect.move(scrollDelta);
   1307             updateRect.unite(scrolledRect);
   1308             if (clipsRepaints())
   1309                 updateRect.intersect(rectToScroll);
   1310             hostWindow()->invalidateContentsAndWindow(updateRect, false);
   1311         }
   1312         return true;
   1313     }
   1314 
   1315     // the number of fixed objects exceed the threshold, we cannot use the fast path
   1316     return false;
   1317 }
   1318 
   1319 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
   1320 {
   1321 #if USE(ACCELERATED_COMPOSITING)
   1322     if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
   1323         if (frameRenderer->containerForRepaint()) {
   1324             IntRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
   1325                          frameRenderer->borderTop() + frameRenderer->paddingTop(),
   1326                          visibleWidth(), visibleHeight());
   1327             frameRenderer->repaintRectangle(rect);
   1328             return;
   1329         }
   1330     }
   1331 #endif
   1332 
   1333     ScrollView::scrollContentsSlowPath(updateRect);
   1334 }
   1335 
   1336 // Note that this gets called at painting time.
   1337 void FrameView::setIsOverlapped(bool isOverlapped)
   1338 {
   1339     if (isOverlapped == m_isOverlapped)
   1340         return;
   1341 
   1342     m_isOverlapped = isOverlapped;
   1343     updateCanBlitOnScrollRecursively();
   1344 
   1345 #if USE(ACCELERATED_COMPOSITING)
   1346     if (hasCompositedContentIncludingDescendants()) {
   1347         // Overlap can affect compositing tests, so if it changes, we need to trigger
   1348         // a layer update in the parent document.
   1349         if (Frame* parentFrame = m_frame->tree()->parent()) {
   1350             if (RenderView* parentView = parentFrame->contentRenderer()) {
   1351                 RenderLayerCompositor* compositor = parentView->compositor();
   1352                 compositor->setCompositingLayersNeedRebuild();
   1353                 compositor->scheduleCompositingLayerUpdate();
   1354             }
   1355         }
   1356 
   1357         if (RenderLayerCompositor::allowsIndependentlyCompositedFrames(this)) {
   1358             // We also need to trigger reevaluation for this and all descendant frames,
   1359             // since a frame uses compositing if any ancestor is compositing.
   1360             for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
   1361                 if (RenderView* view = frame->contentRenderer()) {
   1362                     RenderLayerCompositor* compositor = view->compositor();
   1363                     compositor->setCompositingLayersNeedRebuild();
   1364                     compositor->scheduleCompositingLayerUpdate();
   1365                 }
   1366             }
   1367         }
   1368     }
   1369 #endif
   1370 }
   1371 
   1372 bool FrameView::isOverlappedIncludingAncestors() const
   1373 {
   1374     if (isOverlapped())
   1375         return true;
   1376 
   1377     if (FrameView* parentView = parentFrameView()) {
   1378         if (parentView->isOverlapped())
   1379             return true;
   1380     }
   1381 
   1382     return false;
   1383 }
   1384 
   1385 void FrameView::setContentIsOpaque(bool contentIsOpaque)
   1386 {
   1387     if (contentIsOpaque == m_contentIsOpaque)
   1388         return;
   1389 
   1390     m_contentIsOpaque = contentIsOpaque;
   1391     updateCanBlitOnScrollRecursively();
   1392 }
   1393 
   1394 void FrameView::restoreScrollbar()
   1395 {
   1396     setScrollbarsSuppressed(false);
   1397 }
   1398 
   1399 bool FrameView::scrollToFragment(const KURL& url)
   1400 {
   1401     // If our URL has no ref, then we have no place we need to jump to.
   1402     // OTOH If CSS target was set previously, we want to set it to 0, recalc
   1403     // and possibly repaint because :target pseudo class may have been
   1404     // set (see bug 11321).
   1405     if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget())
   1406         return false;
   1407 
   1408     String fragmentIdentifier = url.fragmentIdentifier();
   1409     if (scrollToAnchor(fragmentIdentifier))
   1410         return true;
   1411 
   1412     // Try again after decoding the ref, based on the document's encoding.
   1413     if (TextResourceDecoder* decoder = m_frame->document()->decoder())
   1414         return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding()));
   1415 
   1416     return false;
   1417 }
   1418 
   1419 bool FrameView::scrollToAnchor(const String& name)
   1420 {
   1421     ASSERT(m_frame->document());
   1422 
   1423     if (!m_frame->document()->haveStylesheetsLoaded()) {
   1424         m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
   1425         return false;
   1426     }
   1427 
   1428     m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false);
   1429 
   1430     Element* anchorNode = m_frame->document()->findAnchor(name);
   1431 
   1432 #if ENABLE(SVG)
   1433     if (m_frame->document()->isSVGDocument()) {
   1434         if (name.startsWith("xpointer(")) {
   1435             // We need to parse the xpointer reference here
   1436         } else if (name.startsWith("svgView(")) {
   1437             RefPtr<SVGSVGElement> svg = static_cast<SVGDocument*>(m_frame->document())->rootElement();
   1438             if (!svg->currentView()->parseViewSpec(name))
   1439                 return false;
   1440             svg->setUseCurrentView(true);
   1441         } else {
   1442             if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) {
   1443                 RefPtr<SVGViewElement> viewElement = anchorNode->hasTagName(SVGNames::viewTag) ? static_cast<SVGViewElement*>(anchorNode) : 0;
   1444                 if (viewElement.get()) {
   1445                     SVGElement* element = SVGLocatable::nearestViewportElement(viewElement.get());
   1446                     if (element->hasTagName(SVGNames::svgTag)) {
   1447                         RefPtr<SVGSVGElement> svg = static_cast<SVGSVGElement*>(element);
   1448                         svg->inheritViewAttributes(viewElement.get());
   1449                     }
   1450                 }
   1451             }
   1452         }
   1453         // FIXME: need to decide which <svg> to focus on, and zoom to that one
   1454         // FIXME: need to actually "highlight" the viewTarget(s)
   1455     }
   1456 #endif
   1457 
   1458     m_frame->document()->setCSSTarget(anchorNode); // Setting to null will clear the current target.
   1459 
   1460     // Implement the rule that "" and "top" both mean top of page as in other browsers.
   1461     if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top")))
   1462         return false;
   1463 
   1464     maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document());
   1465     return true;
   1466 }
   1467 
   1468 void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
   1469 {
   1470     m_maintainScrollPositionAnchor = anchorNode;
   1471     if (!m_maintainScrollPositionAnchor)
   1472         return;
   1473 
   1474     // We need to update the layout before scrolling, otherwise we could
   1475     // really mess things up if an anchor scroll comes at a bad moment.
   1476     m_frame->document()->updateStyleIfNeeded();
   1477     // Only do a layout if changes have occurred that make it necessary.
   1478     if (m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout())
   1479         layout();
   1480     else
   1481         scrollToAnchor();
   1482 }
   1483 
   1484 void FrameView::setScrollPosition(const IntPoint& scrollPoint)
   1485 {
   1486     bool wasInProgrammaticScroll = m_inProgrammaticScroll;
   1487     m_inProgrammaticScroll = true;
   1488     m_maintainScrollPositionAnchor = 0;
   1489     ScrollView::setScrollPosition(scrollPoint);
   1490     m_inProgrammaticScroll = wasInProgrammaticScroll;
   1491 }
   1492 
   1493 void FrameView::scrollPositionChangedViaPlatformWidget()
   1494 {
   1495     repaintFixedElementsAfterScrolling();
   1496     scrollPositionChanged();
   1497 }
   1498 
   1499 void FrameView::scrollPositionChanged()
   1500 {
   1501     frame()->eventHandler()->sendScrollEvent();
   1502 
   1503 #if USE(ACCELERATED_COMPOSITING)
   1504     if (RenderView* root = m_frame->contentRenderer()) {
   1505         if (root->usesCompositing())
   1506             root->compositor()->frameViewDidScroll(scrollPosition());
   1507     }
   1508 #endif
   1509 }
   1510 
   1511 void FrameView::repaintFixedElementsAfterScrolling()
   1512 {
   1513     // For fixed position elements, update widget positions and compositing layers after scrolling,
   1514     // but only if we're not inside of layout.
   1515     if (!m_nestedLayoutCount && hasFixedObjects()) {
   1516         if (RenderView* root = m_frame->contentRenderer()) {
   1517             root->updateWidgetPositions();
   1518             root->layer()->updateRepaintRectsAfterScroll();
   1519 #if USE(ACCELERATED_COMPOSITING)
   1520             root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
   1521 #endif
   1522         }
   1523     }
   1524 }
   1525 
   1526 HostWindow* FrameView::hostWindow() const
   1527 {
   1528     Page* page = frame() ? frame()->page() : 0;
   1529     if (!page)
   1530         return 0;
   1531     return page->chrome();
   1532 }
   1533 
   1534 const unsigned cRepaintRectUnionThreshold = 25;
   1535 
   1536 void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
   1537 {
   1538     ASSERT(!m_frame->ownerElement());
   1539 
   1540     double delay = m_deferringRepaints ? 0 : adjustedDeferredRepaintDelay();
   1541     if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
   1542         IntRect paintRect = r;
   1543         if (clipsRepaints() && !paintsEntireContents())
   1544             paintRect.intersect(visibleContentRect());
   1545 #ifdef ANDROID_CAPTURE_OFFSCREEN_PAINTS
   1546         if (r != paintRect)
   1547             ScrollView::platformOffscreenContentRectangle(visibleContentRect(), r);
   1548 #endif
   1549         if (paintRect.isEmpty())
   1550             return;
   1551         if (m_repaintCount == cRepaintRectUnionThreshold) {
   1552             IntRect unionedRect;
   1553             for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i)
   1554                 unionedRect.unite(m_repaintRects[i]);
   1555             m_repaintRects.clear();
   1556             m_repaintRects.append(unionedRect);
   1557         }
   1558         if (m_repaintCount < cRepaintRectUnionThreshold)
   1559             m_repaintRects.append(paintRect);
   1560         else
   1561             m_repaintRects[0].unite(paintRect);
   1562         m_repaintCount++;
   1563 
   1564         if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive())
   1565              m_deferredRepaintTimer.startOneShot(delay);
   1566         return;
   1567     }
   1568 
   1569     if (!shouldUpdate(immediate))
   1570         return;
   1571 
   1572 #if ENABLE(TILED_BACKING_STORE)
   1573     if (frame()->tiledBackingStore()) {
   1574         frame()->tiledBackingStore()->invalidate(r);
   1575         return;
   1576     }
   1577 #endif
   1578     ScrollView::repaintContentRectangle(r, immediate);
   1579 }
   1580 
   1581 void FrameView::contentsResized()
   1582 {
   1583     scrollAnimator()->contentsResized();
   1584     setNeedsLayout();
   1585 }
   1586 
   1587 void FrameView::visibleContentsResized()
   1588 {
   1589     // We check to make sure the view is attached to a frame() as this method can
   1590     // be triggered before the view is attached by Frame::createView(...) setting
   1591     // various values such as setScrollBarModes(...) for example.  An ASSERT is
   1592     // triggered when a view is layout before being attached to a frame().
   1593     if (!frame()->view())
   1594         return;
   1595 
   1596     if (needsLayout())
   1597         layout();
   1598 
   1599 #if USE(ACCELERATED_COMPOSITING)
   1600     if (RenderView* root = m_frame->contentRenderer()) {
   1601         if (root->usesCompositing())
   1602             root->compositor()->frameViewDidChangeSize();
   1603     }
   1604 #endif
   1605 }
   1606 
   1607 void FrameView::beginDeferredRepaints()
   1608 {
   1609     Page* page = m_frame->page();
   1610     if (page->mainFrame() != m_frame)
   1611         return page->mainFrame()->view()->beginDeferredRepaints();
   1612 
   1613     m_deferringRepaints++;
   1614 }
   1615 
   1616 
   1617 void FrameView::endDeferredRepaints()
   1618 {
   1619     Page* page = m_frame->page();
   1620     if (page->mainFrame() != m_frame)
   1621         return page->mainFrame()->view()->endDeferredRepaints();
   1622 
   1623     ASSERT(m_deferringRepaints > 0);
   1624 
   1625     if (--m_deferringRepaints)
   1626         return;
   1627 
   1628     if (m_deferredRepaintTimer.isActive())
   1629         return;
   1630 
   1631     if (double delay = adjustedDeferredRepaintDelay()) {
   1632         m_deferredRepaintTimer.startOneShot(delay);
   1633         return;
   1634     }
   1635 
   1636     doDeferredRepaints();
   1637 }
   1638 
   1639 void FrameView::checkStopDelayingDeferredRepaints()
   1640 {
   1641     if (!m_deferredRepaintTimer.isActive())
   1642         return;
   1643 
   1644     Document* document = m_frame->document();
   1645     if (document && (document->parsing() || document->cachedResourceLoader()->requestCount()))
   1646         return;
   1647 
   1648     m_deferredRepaintTimer.stop();
   1649 
   1650     doDeferredRepaints();
   1651 }
   1652 
   1653 void FrameView::doDeferredRepaints()
   1654 {
   1655     ASSERT(!m_deferringRepaints);
   1656     if (!shouldUpdate()) {
   1657         m_repaintRects.clear();
   1658         m_repaintCount = 0;
   1659         return;
   1660     }
   1661     unsigned size = m_repaintRects.size();
   1662     for (unsigned i = 0; i < size; i++) {
   1663 #if ENABLE(TILED_BACKING_STORE)
   1664         if (frame()->tiledBackingStore()) {
   1665             frame()->tiledBackingStore()->invalidate(m_repaintRects[i]);
   1666             continue;
   1667         }
   1668 #endif
   1669         ScrollView::repaintContentRectangle(m_repaintRects[i], false);
   1670     }
   1671     m_repaintRects.clear();
   1672     m_repaintCount = 0;
   1673 
   1674     updateDeferredRepaintDelay();
   1675 }
   1676 
   1677 void FrameView::updateDeferredRepaintDelay()
   1678 {
   1679     Document* document = m_frame->document();
   1680     if (!document || (!document->parsing() && !document->cachedResourceLoader()->requestCount())) {
   1681         m_deferredRepaintDelay = s_deferredRepaintDelay;
   1682         return;
   1683     }
   1684     if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) {
   1685         m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading;
   1686         if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading)
   1687             m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading;
   1688     }
   1689 }
   1690 
   1691 void FrameView::resetDeferredRepaintDelay()
   1692 {
   1693     m_deferredRepaintDelay = 0;
   1694     if (m_deferredRepaintTimer.isActive()) {
   1695         m_deferredRepaintTimer.stop();
   1696         if (!m_deferringRepaints)
   1697             doDeferredRepaints();
   1698     }
   1699 }
   1700 
   1701 double FrameView::adjustedDeferredRepaintDelay() const
   1702 {
   1703     ASSERT(!m_deferringRepaints);
   1704     if (!m_deferredRepaintDelay)
   1705         return 0;
   1706     double timeSinceLastPaint = currentTime() - m_lastPaintTime;
   1707     return max(0., m_deferredRepaintDelay - timeSinceLastPaint);
   1708 }
   1709 
   1710 void FrameView::deferredRepaintTimerFired(Timer<FrameView>*)
   1711 {
   1712     doDeferredRepaints();
   1713 }
   1714 
   1715 void FrameView::layoutTimerFired(Timer<FrameView>*)
   1716 {
   1717 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
   1718     if (!m_frame->document()->ownerElement())
   1719         printf("Layout timer fired at %d\n", m_frame->document()->elapsedTime());
   1720 #endif
   1721     layout();
   1722 }
   1723 
   1724 void FrameView::scheduleRelayout()
   1725 {
   1726     // FIXME: We should assert the page is not in the page cache, but that is causing
   1727     // too many false assertions.  See <rdar://problem/7218118>.
   1728     ASSERT(m_frame->view() == this);
   1729 
   1730     if (m_layoutRoot) {
   1731         m_layoutRoot->markContainingBlocksForLayout(false);
   1732         m_layoutRoot = 0;
   1733     }
   1734     if (!m_layoutSchedulingEnabled)
   1735         return;
   1736     if (!needsLayout())
   1737         return;
   1738     if (!m_frame->document()->shouldScheduleLayout())
   1739         return;
   1740 
   1741     // When frame flattening is enabled, the contents of the frame affects layout of the parent frames.
   1742     // Also invalidate parent frame starting from the owner element of this frame.
   1743     if (m_frame->settings() && m_frame->settings()->frameFlatteningEnabled() && m_frame->ownerRenderer()) {
   1744         if (m_frame->ownerElement()->hasTagName(iframeTag) || m_frame->ownerElement()->hasTagName(frameTag))
   1745             m_frame->ownerRenderer()->setNeedsLayout(true, true);
   1746     }
   1747 
   1748 #ifdef ANDROID_FLATTEN_FRAMESET
   1749     if (m_frame->ownerRenderer() && m_frame->ownerElement()->hasTagName(frameTag))
   1750         m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
   1751 #endif
   1752 
   1753     int delay = m_frame->document()->minimumLayoutDelay();
   1754     if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
   1755         unscheduleRelayout();
   1756     if (m_layoutTimer.isActive())
   1757         return;
   1758 
   1759     m_delayedLayout = delay != 0;
   1760 
   1761 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
   1762     if (!m_frame->document()->ownerElement())
   1763         printf("Scheduling layout for %d\n", delay);
   1764 #endif
   1765 
   1766     m_layoutTimer.startOneShot(delay * 0.001);
   1767 }
   1768 
   1769 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
   1770 {
   1771     for (RenderObject* r = descendant; r; r = r->container()) {
   1772         if (r == ancestor)
   1773             return true;
   1774     }
   1775     return false;
   1776 }
   1777 
   1778 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
   1779 {
   1780     ASSERT(m_frame->view() == this);
   1781 
   1782     if (m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout()) {
   1783         if (relayoutRoot)
   1784             relayoutRoot->markContainingBlocksForLayout(false);
   1785         return;
   1786     }
   1787 
   1788     if (layoutPending() || !m_layoutSchedulingEnabled) {
   1789         if (m_layoutRoot != relayoutRoot) {
   1790             if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) {
   1791                 // Keep the current root
   1792                 relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot);
   1793                 ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
   1794             } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) {
   1795                 // Re-root at relayoutRoot
   1796                 m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
   1797                 m_layoutRoot = relayoutRoot;
   1798                 ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
   1799             } else {
   1800                 // Just do a full relayout
   1801                 if (m_layoutRoot)
   1802                     m_layoutRoot->markContainingBlocksForLayout(false);
   1803                 m_layoutRoot = 0;
   1804                 relayoutRoot->markContainingBlocksForLayout(false);
   1805             }
   1806         }
   1807     } else if (m_layoutSchedulingEnabled) {
   1808         int delay = m_frame->document()->minimumLayoutDelay();
   1809         m_layoutRoot = relayoutRoot;
   1810         ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
   1811         m_delayedLayout = delay != 0;
   1812         m_layoutTimer.startOneShot(delay * 0.001);
   1813     }
   1814 }
   1815 
   1816 bool FrameView::layoutPending() const
   1817 {
   1818     return m_layoutTimer.isActive();
   1819 }
   1820 
   1821 bool FrameView::needsLayout() const
   1822 {
   1823     // This can return true in cases where the document does not have a body yet.
   1824     // Document::shouldScheduleLayout takes care of preventing us from scheduling
   1825     // layout in that case.
   1826     if (!m_frame)
   1827         return false;
   1828     RenderView* root = m_frame->contentRenderer();
   1829     return layoutPending()
   1830         || (root && root->needsLayout())
   1831         || m_layoutRoot
   1832         || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred);
   1833 }
   1834 
   1835 void FrameView::setNeedsLayout()
   1836 {
   1837     if (m_deferSetNeedsLayouts) {
   1838         m_setNeedsLayoutWasDeferred = true;
   1839         return;
   1840     }
   1841     RenderView* root = m_frame->contentRenderer();
   1842     if (root)
   1843         root->setNeedsLayout(true);
   1844 }
   1845 
   1846 void FrameView::unscheduleRelayout()
   1847 {
   1848     m_postLayoutTasksTimer.stop();
   1849 
   1850     if (!m_layoutTimer.isActive())
   1851         return;
   1852 
   1853 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
   1854     if (!m_frame->document()->ownerElement())
   1855         printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
   1856 #endif
   1857 
   1858     m_layoutTimer.stop();
   1859     m_delayedLayout = false;
   1860 }
   1861 
   1862 #if ENABLE(REQUEST_ANIMATION_FRAME)
   1863 void FrameView::serviceScriptedAnimations(DOMTimeStamp time)
   1864 {
   1865     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext())
   1866         frame->document()->serviceScriptedAnimations(time);
   1867 }
   1868 #endif
   1869 
   1870 bool FrameView::isTransparent() const
   1871 {
   1872     return m_isTransparent;
   1873 }
   1874 
   1875 void FrameView::setTransparent(bool isTransparent)
   1876 {
   1877     m_isTransparent = isTransparent;
   1878 }
   1879 
   1880 Color FrameView::baseBackgroundColor() const
   1881 {
   1882     return m_baseBackgroundColor;
   1883 }
   1884 
   1885 void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
   1886 {
   1887     if (!backgroundColor.isValid())
   1888         m_baseBackgroundColor = Color::white;
   1889     else
   1890         m_baseBackgroundColor = backgroundColor;
   1891 }
   1892 
   1893 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
   1894 {
   1895     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
   1896         if (FrameView* view = frame->view()) {
   1897             view->setTransparent(transparent);
   1898             view->setBaseBackgroundColor(backgroundColor);
   1899         }
   1900     }
   1901 }
   1902 
   1903 bool FrameView::shouldUpdateWhileOffscreen() const
   1904 {
   1905     return m_shouldUpdateWhileOffscreen;
   1906 }
   1907 
   1908 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
   1909 {
   1910     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
   1911 }
   1912 
   1913 bool FrameView::shouldUpdate(bool immediateRequested) const
   1914 {
   1915     if (!immediateRequested && isOffscreen() && !shouldUpdateWhileOffscreen())
   1916         return false;
   1917     return true;
   1918 }
   1919 
   1920 void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget)
   1921 {
   1922     m_actionScheduler->scheduleEvent(event, eventTarget);
   1923 }
   1924 
   1925 void FrameView::pauseScheduledEvents()
   1926 {
   1927     m_actionScheduler->pause();
   1928 }
   1929 
   1930 void FrameView::resumeScheduledEvents()
   1931 {
   1932     m_actionScheduler->resume();
   1933 }
   1934 
   1935 void FrameView::scrollToAnchor()
   1936 {
   1937     RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
   1938     if (!anchorNode)
   1939         return;
   1940 
   1941     if (!anchorNode->renderer())
   1942         return;
   1943 
   1944     IntRect rect;
   1945     if (anchorNode != m_frame->document())
   1946         rect = anchorNode->getRect();
   1947 
   1948     // Scroll nested layers and frames to reveal the anchor.
   1949     // Align to the top and to the closest side (this matches other browsers).
   1950     anchorNode->renderer()->enclosingLayer()->scrollRectToVisible(rect, true, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
   1951 
   1952     if (AXObjectCache::accessibilityEnabled())
   1953         m_frame->document()->axObjectCache()->handleScrolledToAnchor(anchorNode.get());
   1954 
   1955     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
   1956     m_maintainScrollPositionAnchor = anchorNode;
   1957 }
   1958 
   1959 void FrameView::updateWidget(RenderEmbeddedObject* object)
   1960 {
   1961     ASSERT(!object->node() || object->node()->isElementNode());
   1962     Element* ownerElement = static_cast<Element*>(object->node());
   1963     // The object may have already been destroyed (thus node cleared),
   1964     // but FrameView holds a manual ref, so it won't have been deleted.
   1965     ASSERT(m_widgetUpdateSet->contains(object));
   1966     if (!ownerElement)
   1967         return;
   1968 
   1969     // No need to update if it's already crashed or known to be missing.
   1970     if (object->pluginCrashedOrWasMissing())
   1971         return;
   1972 
   1973     // FIXME: This could turn into a real virtual dispatch if we defined
   1974     // updateWidget(bool) on HTMLElement.
   1975     if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag))
   1976         static_cast<HTMLPlugInImageElement*>(ownerElement)->updateWidget(CreateAnyWidgetType);
   1977     // FIXME: It is not clear that Media elements need or want this updateWidget() call.
   1978 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
   1979     else if (ownerElement->hasTagName(videoTag) || ownerElement->hasTagName(audioTag))
   1980         static_cast<HTMLMediaElement*>(ownerElement)->updateWidget(CreateAnyWidgetType);
   1981 #endif
   1982     else
   1983         ASSERT_NOT_REACHED();
   1984 
   1985     // Caution: it's possible the object was destroyed again, since loading a
   1986     // plugin may run any arbitrary javascript.
   1987     object->updateWidgetPosition();
   1988 }
   1989 
   1990 bool FrameView::updateWidgets()
   1991 {
   1992     if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
   1993         return true;
   1994 
   1995     size_t size = m_widgetUpdateSet->size();
   1996 
   1997     Vector<RenderEmbeddedObject*> objects;
   1998     objects.reserveCapacity(size);
   1999 
   2000     RenderEmbeddedObjectSet::const_iterator end = m_widgetUpdateSet->end();
   2001     for (RenderEmbeddedObjectSet::const_iterator it = m_widgetUpdateSet->begin(); it != end; ++it) {
   2002         objects.uncheckedAppend(*it);
   2003         (*it)->ref();
   2004     }
   2005 
   2006     for (size_t i = 0; i < size; ++i) {
   2007         RenderEmbeddedObject* object = objects[i];
   2008         updateWidget(object);
   2009         m_widgetUpdateSet->remove(object);
   2010     }
   2011 
   2012     RenderArena* arena = m_frame->document()->renderArena();
   2013     for (size_t i = 0; i < size; ++i)
   2014         objects[i]->deref(arena);
   2015 
   2016     return m_widgetUpdateSet->isEmpty();
   2017 }
   2018 
   2019 void FrameView::flushAnyPendingPostLayoutTasks()
   2020 {
   2021     if (!m_hasPendingPostLayoutTasks)
   2022         return;
   2023 
   2024     m_postLayoutTasksTimer.stop();
   2025     performPostLayoutTasks();
   2026 }
   2027 
   2028 void FrameView::performPostLayoutTasks()
   2029 {
   2030     m_hasPendingPostLayoutTasks = false;
   2031 
   2032     m_frame->selection()->setCaretRectNeedsUpdate();
   2033     m_frame->selection()->updateAppearance();
   2034 
   2035     if (m_nestedLayoutCount <= 1) {
   2036         if (m_firstLayoutCallbackPending) {
   2037             m_firstLayoutCallbackPending = false;
   2038             m_frame->loader()->didFirstLayout();
   2039         }
   2040 
   2041         if (m_isVisuallyNonEmpty && m_firstVisuallyNonEmptyLayoutCallbackPending) {
   2042             m_firstVisuallyNonEmptyLayoutCallbackPending = false;
   2043             m_frame->loader()->didFirstVisuallyNonEmptyLayout();
   2044         }
   2045     }
   2046 
   2047     RenderView* root = m_frame->contentRenderer();
   2048 
   2049     root->updateWidgetPositions();
   2050 
   2051     for (unsigned i = 0; i < maxUpdateWidgetsIterations; i++) {
   2052         if (updateWidgets())
   2053             break;
   2054     }
   2055 
   2056     scrollToAnchor();
   2057 
   2058     m_actionScheduler->resume();
   2059 
   2060     if (!root->printing()) {
   2061         IntSize currentSize = IntSize(width(), height());
   2062         float currentZoomFactor = root->style()->zoom();
   2063         bool resized = !m_firstLayout && (currentSize != m_lastLayoutSize || currentZoomFactor != m_lastZoomFactor);
   2064         m_lastLayoutSize = currentSize;
   2065         m_lastZoomFactor = currentZoomFactor;
   2066         if (resized)
   2067             m_frame->eventHandler()->sendResizeEvent();
   2068     }
   2069 }
   2070 
   2071 void FrameView::postLayoutTimerFired(Timer<FrameView>*)
   2072 {
   2073     performPostLayoutTasks();
   2074 }
   2075 
   2076 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
   2077 {
   2078     if (!m_viewportRenderer)
   2079         return;
   2080 
   2081     if (m_overflowStatusDirty) {
   2082         m_horizontalOverflow = horizontalOverflow;
   2083         m_verticalOverflow = verticalOverflow;
   2084         m_overflowStatusDirty = false;
   2085         return;
   2086     }
   2087 
   2088     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
   2089     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
   2090 
   2091     if (horizontalOverflowChanged || verticalOverflowChanged) {
   2092         m_horizontalOverflow = horizontalOverflow;
   2093         m_verticalOverflow = verticalOverflow;
   2094 
   2095         m_actionScheduler->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
   2096             verticalOverflowChanged, verticalOverflow),
   2097             m_viewportRenderer->node());
   2098     }
   2099 
   2100 }
   2101 
   2102 IntRect FrameView::windowClipRect(bool clipToContents) const
   2103 {
   2104     ASSERT(m_frame->view() == this);
   2105 
   2106     if (paintsEntireContents())
   2107         return IntRect(IntPoint(0, 0), contentsSize());
   2108 
   2109     // Set our clip rect to be our contents.
   2110     IntRect clipRect = contentsToWindow(visibleContentRect(!clipToContents));
   2111     if (!m_frame || !m_frame->ownerElement())
   2112         return clipRect;
   2113 
   2114     // Take our owner element and get the clip rect from the enclosing layer.
   2115     Element* elt = m_frame->ownerElement();
   2116     RenderLayer* layer = elt->renderer()->enclosingLayer();
   2117     // FIXME: layer should never be null, but sometimes seems to be anyway.
   2118     if (!layer)
   2119         return clipRect;
   2120     FrameView* parentView = elt->document()->view();
   2121     clipRect.intersect(parentView->windowClipRectForLayer(layer, true));
   2122     return clipRect;
   2123 }
   2124 
   2125 IntRect FrameView::windowClipRectForLayer(const RenderLayer* layer, bool clipToLayerContents) const
   2126 {
   2127     // If we have no layer, just return our window clip rect.
   2128     if (!layer)
   2129         return windowClipRect();
   2130 
   2131     // Apply the clip from the layer.
   2132     IntRect clipRect;
   2133     if (clipToLayerContents)
   2134         clipRect = layer->childrenClipRect();
   2135     else
   2136         clipRect = layer->selfClipRect();
   2137     clipRect = contentsToWindow(clipRect);
   2138     return intersection(clipRect, windowClipRect());
   2139 }
   2140 
   2141 bool FrameView::isActive() const
   2142 {
   2143     Page* page = frame()->page();
   2144     return page && page->focusController()->isActive();
   2145 }
   2146 
   2147 void FrameView::scrollTo(const IntSize& newOffset)
   2148 {
   2149     IntSize offset = scrollOffset();
   2150     ScrollView::scrollTo(newOffset);
   2151     if (offset != scrollOffset())
   2152         scrollPositionChanged();
   2153     frame()->loader()->client()->didChangeScrollOffset();
   2154 }
   2155 
   2156 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
   2157 {
   2158     // Add in our offset within the FrameView.
   2159     IntRect dirtyRect = rect;
   2160     dirtyRect.move(scrollbar->x(), scrollbar->y());
   2161     invalidateRect(dirtyRect);
   2162 }
   2163 
   2164 void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
   2165 {
   2166     tickmarks = frame()->document()->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch);
   2167 }
   2168 
   2169 IntRect FrameView::windowResizerRect() const
   2170 {
   2171     Page* page = frame() ? frame()->page() : 0;
   2172     if (!page)
   2173         return IntRect();
   2174     return page->chrome()->windowResizerRect();
   2175 }
   2176 
   2177 void FrameView::didCompleteRubberBand(const IntSize& initialOverhang) const
   2178 {
   2179     Page* page = m_frame->page();
   2180     if (page->mainFrame() != m_frame)
   2181         return;
   2182     return page->chrome()->client()->didCompleteRubberBandForMainFrame(initialOverhang);
   2183 }
   2184 
   2185 void FrameView::scrollbarStyleChanged()
   2186 {
   2187     Page* page = m_frame->page();
   2188     ASSERT(page);
   2189     if (!page)
   2190         return;
   2191     page->setNeedsRecalcStyleInAllFrames();
   2192 }
   2193 
   2194 bool FrameView::shouldSuspendScrollAnimations() const
   2195 {
   2196     return m_frame->loader()->state() != FrameStateComplete;
   2197 }
   2198 
   2199 void FrameView::notifyPageThatContentAreaWillPaint() const
   2200 {
   2201     Page* page = m_frame->page();
   2202     const HashSet<ScrollableArea*>* scrollableAreas = page->scrollableAreaSet();
   2203     if (!scrollableAreas)
   2204         return;
   2205 
   2206     HashSet<ScrollableArea*>::const_iterator end = scrollableAreas->end();
   2207     for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(); it != end; ++it)
   2208         (*it)->scrollAnimator()->contentAreaWillPaint();
   2209 }
   2210 
   2211 #if ENABLE(DASHBOARD_SUPPORT)
   2212 void FrameView::updateDashboardRegions()
   2213 {
   2214     Document* document = m_frame->document();
   2215     if (!document->hasDashboardRegions())
   2216         return;
   2217     Vector<DashboardRegionValue> newRegions;
   2218     document->renderBox()->collectDashboardRegions(newRegions);
   2219     if (newRegions == document->dashboardRegions())
   2220         return;
   2221     document->setDashboardRegions(newRegions);
   2222     Page* page = m_frame->page();
   2223     if (!page)
   2224         return;
   2225     page->chrome()->client()->dashboardRegionsChanged();
   2226 }
   2227 #endif
   2228 
   2229 void FrameView::updateScrollCorner()
   2230 {
   2231     RenderObject* renderer = 0;
   2232     RefPtr<RenderStyle> cornerStyle;
   2233 
   2234     if (!scrollCornerRect().isEmpty()) {
   2235         // Try the <body> element first as a scroll corner source.
   2236         Document* doc = m_frame->document();
   2237         Element* body = doc ? doc->body() : 0;
   2238         if (body && body->renderer()) {
   2239             renderer = body->renderer();
   2240             cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
   2241         }
   2242 
   2243         if (!cornerStyle) {
   2244             // If the <body> didn't have a custom style, then the root element might.
   2245             Element* docElement = doc ? doc->documentElement() : 0;
   2246             if (docElement && docElement->renderer()) {
   2247                 renderer = docElement->renderer();
   2248                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
   2249             }
   2250         }
   2251 
   2252         if (!cornerStyle) {
   2253             // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
   2254             if (RenderPart* renderer = m_frame->ownerRenderer())
   2255                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
   2256         }
   2257     }
   2258 
   2259     if (cornerStyle) {
   2260         if (!m_scrollCorner)
   2261             m_scrollCorner = new (renderer->renderArena()) RenderScrollbarPart(renderer->document());
   2262         m_scrollCorner->setStyle(cornerStyle.release());
   2263         invalidateScrollCorner();
   2264     } else if (m_scrollCorner) {
   2265         m_scrollCorner->destroy();
   2266         m_scrollCorner = 0;
   2267     }
   2268 
   2269     ScrollView::updateScrollCorner();
   2270 }
   2271 
   2272 void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
   2273 {
   2274     if (context->updatingControlTints()) {
   2275         updateScrollCorner();
   2276         return;
   2277     }
   2278 
   2279     if (m_scrollCorner) {
   2280         m_scrollCorner->paintIntoRect(context, cornerRect.x(), cornerRect.y(), cornerRect);
   2281         return;
   2282     }
   2283 
   2284     ScrollView::paintScrollCorner(context, cornerRect);
   2285 }
   2286 
   2287 bool FrameView::hasCustomScrollbars() const
   2288 {
   2289     const HashSet<RefPtr<Widget> >* viewChildren = children();
   2290     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
   2291     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
   2292         Widget* widget = current->get();
   2293         if (widget->isFrameView()) {
   2294             if (static_cast<FrameView*>(widget)->hasCustomScrollbars())
   2295                 return true;
   2296         } else if (widget->isScrollbar()) {
   2297             Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
   2298             if (scrollbar->isCustomScrollbar())
   2299                 return true;
   2300         }
   2301     }
   2302 
   2303     return false;
   2304 }
   2305 
   2306 FrameView* FrameView::parentFrameView() const
   2307 {
   2308     if (Widget* parentView = parent()) {
   2309         if (parentView->isFrameView())
   2310             return static_cast<FrameView*>(parentView);
   2311     }
   2312     return 0;
   2313 }
   2314 
   2315 void FrameView::updateControlTints()
   2316 {
   2317     // This is called when control tints are changed from aqua/graphite to clear and vice versa.
   2318     // We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
   2319     // This is only done if the theme supports control tinting. It's up to the theme and platform
   2320     // to define when controls get the tint and to call this function when that changes.
   2321 
   2322     // Optimize the common case where we bring a window to the front while it's still empty.
   2323     if (!m_frame || m_frame->document()->url().isEmpty())
   2324         return;
   2325 
   2326     if ((m_frame->contentRenderer() && m_frame->contentRenderer()->theme()->supportsControlTints()) || hasCustomScrollbars())  {
   2327         if (needsLayout())
   2328             layout();
   2329         PlatformGraphicsContext* const noContext = 0;
   2330         GraphicsContext context(noContext);
   2331         context.setUpdatingControlTints(true);
   2332         if (platformWidget())
   2333             paintContents(&context, visibleContentRect());
   2334         else
   2335             paint(&context, frameRect());
   2336     }
   2337 }
   2338 
   2339 bool FrameView::wasScrolledByUser() const
   2340 {
   2341     return m_wasScrolledByUser;
   2342 }
   2343 
   2344 void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
   2345 {
   2346     if (m_inProgrammaticScroll)
   2347         return;
   2348     m_maintainScrollPositionAnchor = 0;
   2349     m_wasScrolledByUser = wasScrolledByUser;
   2350 }
   2351 
   2352 void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
   2353 {
   2354     if (!frame())
   2355         return;
   2356 
   2357     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_frame.get(), rect);
   2358 
   2359     Document* document = m_frame->document();
   2360 
   2361 #ifndef NDEBUG
   2362     bool fillWithRed;
   2363     if (document->printing())
   2364         fillWithRed = false; // Printing, don't fill with red (can't remember why).
   2365     else if (m_frame->ownerElement())
   2366         fillWithRed = false; // Subframe, don't fill with red.
   2367     else if (isTransparent())
   2368         fillWithRed = false; // Transparent, don't fill with red.
   2369     else if (m_paintBehavior & PaintBehaviorSelectionOnly)
   2370         fillWithRed = false; // Selections are transparent, don't fill with red.
   2371     else if (m_nodeToDraw)
   2372         fillWithRed = false; // Element images are transparent, don't fill with red.
   2373     else
   2374         fillWithRed = true;
   2375 
   2376     if (fillWithRed)
   2377         p->fillRect(rect, Color(0xFF, 0, 0), ColorSpaceDeviceRGB);
   2378 #endif
   2379 
   2380     bool isTopLevelPainter = !sCurrentPaintTimeStamp;
   2381     if (isTopLevelPainter)
   2382         sCurrentPaintTimeStamp = currentTime();
   2383 
   2384     RenderView* contentRenderer = frame()->contentRenderer();
   2385     if (!contentRenderer) {
   2386         LOG_ERROR("called FrameView::paint with nil renderer");
   2387         return;
   2388     }
   2389 
   2390     ASSERT(!needsLayout());
   2391     if (needsLayout())
   2392         return;
   2393 
   2394 #if USE(ACCELERATED_COMPOSITING)
   2395     if (!p->paintingDisabled())
   2396         syncCompositingStateForThisFrame();
   2397 #endif
   2398 
   2399     PaintBehavior oldPaintBehavior = m_paintBehavior;
   2400 
   2401     if (FrameView* parentView = parentFrameView()) {
   2402         if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers)
   2403             m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
   2404     }
   2405 
   2406     if (m_paintBehavior == PaintBehaviorNormal)
   2407         document->markers()->invalidateRenderedRectsForMarkersInRect(rect);
   2408 
   2409     if (document->printing())
   2410         m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
   2411 
   2412     bool flatteningPaint = m_paintBehavior & PaintBehaviorFlattenCompositingLayers;
   2413     bool isRootFrame = !m_frame->ownerElement();
   2414     if (flatteningPaint && isRootFrame)
   2415         notifyWidgetsInAllFrames(WillPaintFlattened);
   2416 
   2417     ASSERT(!m_isPainting);
   2418     m_isPainting = true;
   2419 
   2420     // m_nodeToDraw is used to draw only one element (and its descendants)
   2421     RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
   2422     RenderLayer* rootLayer = contentRenderer->layer();
   2423 
   2424     rootLayer->paint(p, rect, m_paintBehavior, eltRenderer);
   2425 
   2426     if (rootLayer->containsDirtyOverlayScrollbars())
   2427         rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, eltRenderer);
   2428 
   2429     m_isPainting = false;
   2430 
   2431     if (flatteningPaint && isRootFrame)
   2432         notifyWidgetsInAllFrames(DidPaintFlattened);
   2433 
   2434     m_paintBehavior = oldPaintBehavior;
   2435     m_lastPaintTime = currentTime();
   2436 
   2437 #if ENABLE(DASHBOARD_SUPPORT)
   2438     // Regions may have changed as a result of the visibility/z-index of element changing.
   2439     if (document->dashboardRegionsDirty())
   2440         updateDashboardRegions();
   2441 #endif
   2442 
   2443     if (isTopLevelPainter)
   2444         sCurrentPaintTimeStamp = 0;
   2445 
   2446     InspectorInstrumentation::didPaint(cookie);
   2447 }
   2448 
   2449 void FrameView::setPaintBehavior(PaintBehavior behavior)
   2450 {
   2451     m_paintBehavior = behavior;
   2452 }
   2453 
   2454 PaintBehavior FrameView::paintBehavior() const
   2455 {
   2456     return m_paintBehavior;
   2457 }
   2458 
   2459 bool FrameView::isPainting() const
   2460 {
   2461     return m_isPainting;
   2462 }
   2463 
   2464 void FrameView::setNodeToDraw(Node* node)
   2465 {
   2466     m_nodeToDraw = node;
   2467 }
   2468 
   2469 void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
   2470 {
   2471     if (context->paintingDisabled())
   2472         return;
   2473 
   2474     if (m_frame->document()->printing())
   2475         return;
   2476 
   2477     Page* page = m_frame->page();
   2478     if (page->mainFrame() == m_frame) {
   2479         if (page->chrome()->client()->paintCustomOverhangArea(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect))
   2480             return;
   2481     }
   2482 
   2483     return ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
   2484 }
   2485 
   2486 void FrameView::updateLayoutAndStyleIfNeededRecursive()
   2487 {
   2488     // We have to crawl our entire tree looking for any FrameViews that need
   2489     // layout and make sure they are up to date.
   2490     // Mac actually tests for intersection with the dirty region and tries not to
   2491     // update layout for frames that are outside the dirty region.  Not only does this seem
   2492     // pointless (since those frames will have set a zero timer to layout anyway), but
   2493     // it is also incorrect, since if two frames overlap, the first could be excluded from the dirty
   2494     // region but then become included later by the second frame adding rects to the dirty region
   2495     // when it lays out.
   2496 
   2497     m_frame->document()->updateStyleIfNeeded();
   2498 
   2499     if (needsLayout())
   2500         layout();
   2501 
   2502     const HashSet<RefPtr<Widget> >* viewChildren = children();
   2503     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
   2504     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
   2505         Widget* widget = (*current).get();
   2506         if (widget->isFrameView())
   2507             static_cast<FrameView*>(widget)->updateLayoutAndStyleIfNeededRecursive();
   2508     }
   2509 
   2510     // updateLayoutAndStyleIfNeededRecursive is called when we need to make sure style and layout are up-to-date before
   2511     // painting, so we need to flush out any deferred repaints too.
   2512     flushDeferredRepaints();
   2513 }
   2514 
   2515 void FrameView::flushDeferredRepaints()
   2516 {
   2517     if (!m_deferredRepaintTimer.isActive())
   2518         return;
   2519     m_deferredRepaintTimer.stop();
   2520     doDeferredRepaints();
   2521 }
   2522 
   2523 void FrameView::forceLayout(bool allowSubtree)
   2524 {
   2525     layout(allowSubtree);
   2526 }
   2527 
   2528 void FrameView::forceLayoutForPagination(const FloatSize& pageSize, float maximumShrinkFactor, Frame::AdjustViewSizeOrNot shouldAdjustViewSize)
   2529 {
   2530     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
   2531     // the state of things before and after the layout
   2532     RenderView *root = toRenderView(m_frame->document()->renderer());
   2533     if (root) {
   2534         float pageLogicalWidth = root->style()->isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
   2535         float pageLogicalHeight = root->style()->isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
   2536 
   2537         int flooredPageLogicalWidth = static_cast<int>(pageLogicalWidth);
   2538         root->setLogicalWidth(flooredPageLogicalWidth);
   2539         root->setPageLogicalHeight(pageLogicalHeight);
   2540         root->setNeedsLayoutAndPrefWidthsRecalc();
   2541         forceLayout();
   2542 
   2543         // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
   2544         // page width when shrunk, we will lay out at maximum shrink and clip extra content.
   2545         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
   2546         // implementation should not do this!
   2547         int docLogicalWidth = root->style()->isHorizontalWritingMode() ? root->docWidth() : root->docHeight();
   2548         if (docLogicalWidth > pageLogicalWidth) {
   2549             flooredPageLogicalWidth = std::min<int>(docLogicalWidth, pageLogicalWidth * maximumShrinkFactor);
   2550             if (pageLogicalHeight)
   2551                 root->setPageLogicalHeight(flooredPageLogicalWidth / pageSize.width() * pageSize.height());
   2552             root->setLogicalWidth(flooredPageLogicalWidth);
   2553             root->setNeedsLayoutAndPrefWidthsRecalc();
   2554             forceLayout();
   2555             int docLogicalHeight = root->style()->isHorizontalWritingMode() ? root->docHeight() : root->docWidth();
   2556             int docLogicalTop = root->style()->isHorizontalWritingMode() ? root->docTop() : root->docLeft();
   2557             int docLogicalRight = root->style()->isHorizontalWritingMode() ? root->docRight() : root->docBottom();
   2558             int clippedLogicalLeft = 0;
   2559             if (!root->style()->isLeftToRightDirection())
   2560                 clippedLogicalLeft = docLogicalRight - flooredPageLogicalWidth;
   2561             IntRect overflow(clippedLogicalLeft, docLogicalTop, flooredPageLogicalWidth, docLogicalHeight);
   2562             if (!root->style()->isHorizontalWritingMode())
   2563                 overflow = overflow.transposedRect();
   2564             root->clearLayoutOverflow();
   2565             root->addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
   2566         }
   2567     }
   2568 
   2569     if (shouldAdjustViewSize)
   2570         adjustViewSize();
   2571 }
   2572 
   2573 void FrameView::adjustPageHeightDeprecated(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
   2574 {
   2575     RenderView* root = m_frame->contentRenderer();
   2576     if (root) {
   2577         // Use a context with painting disabled.
   2578         GraphicsContext context((PlatformGraphicsContext*)0);
   2579         root->setTruncatedAt((int)floorf(oldBottom));
   2580         IntRect dirtyRect(0, (int)floorf(oldTop), root->maxXLayoutOverflow(), (int)ceilf(oldBottom - oldTop));
   2581         root->setPrintRect(dirtyRect);
   2582         root->layer()->paint(&context, dirtyRect);
   2583         *newBottom = root->bestTruncatedAt();
   2584         if (*newBottom == 0)
   2585             *newBottom = oldBottom;
   2586         root->setPrintRect(IntRect());
   2587     } else
   2588         *newBottom = oldBottom;
   2589 }
   2590 
   2591 IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
   2592 {
   2593     IntRect rect = renderer->localToAbsoluteQuad(FloatRect(rendererRect)).enclosingBoundingBox();
   2594 
   2595     // Convert from page ("absolute") to FrameView coordinates.
   2596     rect.move(-scrollX(), -scrollY());
   2597 
   2598     return rect;
   2599 }
   2600 
   2601 IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect& viewRect) const
   2602 {
   2603     IntRect rect = viewRect;
   2604 
   2605     // Convert from FrameView coords into page ("absolute") coordinates.
   2606     rect.move(scrollX(), scrollY());
   2607 
   2608     // FIXME: we don't have a way to map an absolute rect down to a local quad, so just
   2609     // move the rect for now.
   2610     rect.setLocation(roundedIntPoint(renderer->absoluteToLocal(rect.location(), false, true /* use transforms */)));
   2611     return rect;
   2612 }
   2613 
   2614 IntPoint FrameView::convertFromRenderer(const RenderObject* renderer, const IntPoint& rendererPoint) const
   2615 {
   2616     IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, false, true /* use transforms */));
   2617 
   2618     // Convert from page ("absolute") to FrameView coordinates.
   2619     point.move(-scrollX(), -scrollY());
   2620     return point;
   2621 }
   2622 
   2623 IntPoint FrameView::convertToRenderer(const RenderObject* renderer, const IntPoint& viewPoint) const
   2624 {
   2625     IntPoint point = viewPoint;
   2626 
   2627     // Convert from FrameView coords into page ("absolute") coordinates.
   2628     point += IntSize(scrollX(), scrollY());
   2629 
   2630     return roundedIntPoint(renderer->absoluteToLocal(point, false, true /* use transforms */));
   2631 }
   2632 
   2633 IntRect FrameView::convertToContainingView(const IntRect& localRect) const
   2634 {
   2635     if (const ScrollView* parentScrollView = parent()) {
   2636         if (parentScrollView->isFrameView()) {
   2637             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
   2638             // Get our renderer in the parent view
   2639             RenderPart* renderer = m_frame->ownerRenderer();
   2640             if (!renderer)
   2641                 return localRect;
   2642 
   2643             IntRect rect(localRect);
   2644             // Add borders and padding??
   2645             rect.move(renderer->borderLeft() + renderer->paddingLeft(),
   2646                       renderer->borderTop() + renderer->paddingTop());
   2647             return parentView->convertFromRenderer(renderer, rect);
   2648         }
   2649 
   2650         return Widget::convertToContainingView(localRect);
   2651     }
   2652 
   2653     return localRect;
   2654 }
   2655 
   2656 IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
   2657 {
   2658     if (const ScrollView* parentScrollView = parent()) {
   2659         if (parentScrollView->isFrameView()) {
   2660             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
   2661 
   2662             // Get our renderer in the parent view
   2663             RenderPart* renderer = m_frame->ownerRenderer();
   2664             if (!renderer)
   2665                 return parentRect;
   2666 
   2667             IntRect rect = parentView->convertToRenderer(renderer, parentRect);
   2668             // Subtract borders and padding
   2669             rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
   2670                       -renderer->borderTop() - renderer->paddingTop());
   2671             return rect;
   2672         }
   2673 
   2674         return Widget::convertFromContainingView(parentRect);
   2675     }
   2676 
   2677     return parentRect;
   2678 }
   2679 
   2680 IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
   2681 {
   2682     if (const ScrollView* parentScrollView = parent()) {
   2683         if (parentScrollView->isFrameView()) {
   2684             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
   2685 
   2686             // Get our renderer in the parent view
   2687             RenderPart* renderer = m_frame->ownerRenderer();
   2688             if (!renderer)
   2689                 return localPoint;
   2690 
   2691             IntPoint point(localPoint);
   2692 
   2693             // Add borders and padding
   2694             point.move(renderer->borderLeft() + renderer->paddingLeft(),
   2695                        renderer->borderTop() + renderer->paddingTop());
   2696             return parentView->convertFromRenderer(renderer, point);
   2697         }
   2698 
   2699         return Widget::convertToContainingView(localPoint);
   2700     }
   2701 
   2702     return localPoint;
   2703 }
   2704 
   2705 IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
   2706 {
   2707     if (const ScrollView* parentScrollView = parent()) {
   2708         if (parentScrollView->isFrameView()) {
   2709             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
   2710 
   2711             // Get our renderer in the parent view
   2712             RenderPart* renderer = m_frame->ownerRenderer();
   2713             if (!renderer)
   2714                 return parentPoint;
   2715 
   2716             IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
   2717             // Subtract borders and padding
   2718             point.move(-renderer->borderLeft() - renderer->paddingLeft(),
   2719                        -renderer->borderTop() - renderer->paddingTop());
   2720             return point;
   2721         }
   2722 
   2723         return Widget::convertFromContainingView(parentPoint);
   2724     }
   2725 
   2726     return parentPoint;
   2727 }
   2728 
   2729 // Normal delay
   2730 void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
   2731 {
   2732     s_deferredRepaintDelay = p;
   2733 }
   2734 
   2735 // Negative value would mean that first few repaints happen without a delay
   2736 void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p)
   2737 {
   2738     s_initialDeferredRepaintDelayDuringLoading = p;
   2739 }
   2740 
   2741 // The delay grows on each repaint to this maximum value
   2742 void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p)
   2743 {
   2744     s_maxDeferredRepaintDelayDuringLoading = p;
   2745 }
   2746 
   2747 // On each repaint the delay increases by this amount
   2748 void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p)
   2749 {
   2750     s_deferredRepaintDelayIncrementDuringLoading = p;
   2751 }
   2752 
   2753 bool FrameView::isVerticalDocument() const
   2754 {
   2755     if (!m_frame)
   2756         return true;
   2757     Document* doc = m_frame->document();
   2758     if (!doc)
   2759         return true;
   2760     RenderObject* renderView = doc->renderer();
   2761     if (!renderView)
   2762         return true;
   2763     return renderView->style()->isHorizontalWritingMode();
   2764 }
   2765 
   2766 bool FrameView::isFlippedDocument() const
   2767 {
   2768     if (!m_frame)
   2769         return false;
   2770     Document* doc = m_frame->document();
   2771     if (!doc)
   2772         return false;
   2773     RenderObject* renderView = doc->renderer();
   2774     if (!renderView)
   2775         return false;
   2776     return renderView->style()->isFlippedBlocksWritingMode();
   2777 }
   2778 
   2779 void FrameView::notifyWidgetsInAllFrames(WidgetNotification notification)
   2780 {
   2781     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
   2782         if (RenderView* root = frame->contentRenderer())
   2783             root->notifyWidgets(notification);
   2784     }
   2785 }
   2786 
   2787 AXObjectCache* FrameView::axObjectCache() const
   2788 {
   2789     if (frame() && frame()->document() && frame()->document()->axObjectCacheExists())
   2790         return frame()->document()->axObjectCache();
   2791     return 0;
   2792 }
   2793 
   2794 } // namespace WebCore
   2795