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 "Chrome.h"
     33 #include "ChromeClient.h"
     34 #include "DocLoader.h"
     35 #include "EventHandler.h"
     36 #include "FloatRect.h"
     37 #include "FocusController.h"
     38 #include "Frame.h"
     39 #include "FrameLoader.h"
     40 #include "FrameLoaderClient.h"
     41 #include "FrameTree.h"
     42 #include "GraphicsContext.h"
     43 #include "HTMLDocument.h"
     44 #include "HTMLFrameElement.h"
     45 #include "HTMLFrameSetElement.h"
     46 #include "HTMLNames.h"
     47 #include "InspectorTimelineAgent.h"
     48 #include "OverflowEvent.h"
     49 #include "RenderEmbeddedObject.h"
     50 #include "RenderPart.h"
     51 #include "RenderScrollbar.h"
     52 #include "RenderScrollbarPart.h"
     53 #include "RenderTheme.h"
     54 #include "RenderView.h"
     55 #include "Settings.h"
     56 #include "TextResourceDecoder.h"
     57 #include <wtf/CurrentTime.h>
     58 
     59 #ifdef ANDROID_INSTRUMENT
     60 #include "FrameTree.h"
     61 #include "TimeCounter.h"
     62 #endif
     63 
     64 #if USE(ACCELERATED_COMPOSITING)
     65 #include "RenderLayerCompositor.h"
     66 #endif
     67 
     68 #if ENABLE(SVG)
     69 #include "SVGDocument.h"
     70 #include "SVGLocatable.h"
     71 #include "SVGNames.h"
     72 #include "SVGPreserveAspectRatio.h"
     73 #include "SVGSVGElement.h"
     74 #include "SVGViewElement.h"
     75 #include "SVGViewSpec.h"
     76 #endif
     77 
     78 #if PLATFORM(ANDROID)
     79 #include "WebCoreFrameBridge.h"
     80 #endif
     81 
     82 
     83 namespace WebCore {
     84 
     85 using namespace HTMLNames;
     86 
     87 double FrameView::sCurrentPaintTimeStamp = 0.0;
     88 
     89 #if ENABLE(REPAINT_THROTTLING)
     90 // Normal delay
     91 static const double deferredRepaintDelay = 0.025;
     92 // Negative value would mean that first few repaints happen without a delay
     93 static const double initialDeferredRepaintDelayDuringLoading = 0;
     94 // The delay grows on each repaint to this maximum value
     95 static const double maxDeferredRepaintDelayDuringLoading = 2.5;
     96 // On each repaint the delay increses by this amount
     97 static const double deferredRepaintDelayIncrementDuringLoading = 0.5;
     98 #else
     99 // FIXME: Repaint throttling could be good to have on all platform.
    100 // The balance between CPU use and repaint frequency will need some tuning for desktop.
    101 // More hooks may be needed to reset the delay on things like GIF and CSS animations.
    102 static const double deferredRepaintDelay = 0;
    103 static const double initialDeferredRepaintDelayDuringLoading = 0;
    104 static const double maxDeferredRepaintDelayDuringLoading = 0;
    105 static const double deferredRepaintDelayIncrementDuringLoading = 0;
    106 #endif
    107 
    108 // The maximum number of updateWidgets iterations that should be done before returning.
    109 static const unsigned maxUpdateWidgetsIterations = 2;
    110 
    111 struct ScheduledEvent : Noncopyable {
    112     RefPtr<Event> m_event;
    113     RefPtr<Node> m_eventTarget;
    114 };
    115 
    116 FrameView::FrameView(Frame* frame)
    117     : m_frame(frame)
    118     , m_canHaveScrollbars(true)
    119     , m_slowRepaintObjectCount(0)
    120     , m_layoutTimer(this, &FrameView::layoutTimerFired)
    121     , m_layoutRoot(0)
    122     , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
    123     , m_isTransparent(false)
    124     , m_baseBackgroundColor(Color::white)
    125     , m_mediaType("screen")
    126     , m_enqueueEvents(0)
    127     , m_overflowStatusDirty(true)
    128     , m_viewportRenderer(0)
    129     , m_wasScrolledByUser(false)
    130     , m_inProgrammaticScroll(false)
    131     , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired)
    132     , m_shouldUpdateWhileOffscreen(true)
    133     , m_deferSetNeedsLayouts(0)
    134     , m_setNeedsLayoutWasDeferred(false)
    135     , m_scrollCorner(0)
    136 {
    137     init();
    138 }
    139 
    140 PassRefPtr<FrameView> FrameView::create(Frame* frame)
    141 {
    142     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
    143     view->show();
    144     return view.release();
    145 }
    146 
    147 PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize)
    148 {
    149     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
    150     view->Widget::setFrameRect(IntRect(view->pos(), initialSize));
    151     view->show();
    152     return view.release();
    153 }
    154 
    155 FrameView::~FrameView()
    156 {
    157     if (m_postLayoutTasksTimer.isActive()) {
    158         m_postLayoutTasksTimer.stop();
    159         m_scheduledEvents.clear();
    160         m_enqueueEvents = 0;
    161     }
    162 
    163     resetScrollbars();
    164 
    165     // Custom scrollbars should already be destroyed at this point
    166     ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
    167     ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
    168 
    169     setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
    170     setHasVerticalScrollbar(false);
    171 
    172     ASSERT(!m_scrollCorner);
    173     ASSERT(m_scheduledEvents.isEmpty());
    174     ASSERT(!m_enqueueEvents);
    175 
    176     if (m_frame) {
    177         ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
    178         RenderPart* renderer = m_frame->ownerRenderer();
    179         if (renderer && renderer->widget() == this)
    180             renderer->setWidget(0);
    181     }
    182 }
    183 
    184 void FrameView::reset()
    185 {
    186     m_useSlowRepaints = false;
    187     m_isOverlapped = false;
    188     m_contentIsOpaque = false;
    189     m_borderX = 30;
    190     m_borderY = 30;
    191     m_layoutTimer.stop();
    192     m_layoutRoot = 0;
    193     m_delayedLayout = false;
    194     m_doFullRepaint = true;
    195     m_layoutSchedulingEnabled = true;
    196     m_midLayout = false;
    197     m_layoutCount = 0;
    198     m_nestedLayoutCount = 0;
    199     m_postLayoutTasksTimer.stop();
    200     m_firstLayout = true;
    201     m_firstLayoutCallbackPending = false;
    202     m_wasScrolledByUser = false;
    203     m_lastLayoutSize = IntSize();
    204     m_lastZoomFactor = 1.0f;
    205     m_deferringRepaints = 0;
    206     m_repaintCount = 0;
    207     m_repaintRects.clear();
    208     m_deferredRepaintDelay = initialDeferredRepaintDelayDuringLoading;
    209     m_deferredRepaintTimer.stop();
    210     m_lastPaintTime = 0;
    211     m_paintBehavior = PaintBehaviorNormal;
    212     m_isPainting = false;
    213     m_isVisuallyNonEmpty = false;
    214     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
    215     m_maintainScrollPositionAnchor = 0;
    216 }
    217 
    218 bool FrameView::isFrameView() const
    219 {
    220     return true;
    221 }
    222 
    223 void FrameView::clearFrame()
    224 {
    225     m_frame = 0;
    226 }
    227 
    228 void FrameView::resetScrollbars()
    229 {
    230     // Reset the document's scrollbars back to our defaults before we yield the floor.
    231     m_firstLayout = true;
    232     setScrollbarsSuppressed(true);
    233     if (m_canHaveScrollbars)
    234         setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
    235     else
    236         setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
    237     setScrollbarsSuppressed(false);
    238 }
    239 
    240 void FrameView::init()
    241 {
    242     reset();
    243 
    244     m_margins = IntSize(-1, -1); // undefined
    245     m_size = IntSize();
    246 
    247     // Propagate the marginwidth/height and scrolling modes to the view.
    248     Element* ownerElement = m_frame && m_frame->document() ? m_frame->document()->ownerElement() : 0;
    249     if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
    250         HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
    251         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
    252             setCanHaveScrollbars(false);
    253         int marginWidth = frameElt->getMarginWidth();
    254         int marginHeight = frameElt->getMarginHeight();
    255         if (marginWidth != -1)
    256             setMarginWidth(marginWidth);
    257         if (marginHeight != -1)
    258             setMarginHeight(marginHeight);
    259     }
    260 }
    261 
    262 void FrameView::detachCustomScrollbars()
    263 {
    264     if (!m_frame)
    265         return;
    266 
    267     Scrollbar* horizontalBar = horizontalScrollbar();
    268     if (horizontalBar && horizontalBar->isCustomScrollbar() && !toRenderScrollbar(horizontalBar)->owningRenderer()->isRenderPart())
    269         setHasHorizontalScrollbar(false);
    270 
    271     Scrollbar* verticalBar = verticalScrollbar();
    272     if (verticalBar && verticalBar->isCustomScrollbar() && !toRenderScrollbar(verticalBar)->owningRenderer()->isRenderPart())
    273         setHasVerticalScrollbar(false);
    274 
    275     if (m_scrollCorner) {
    276         m_scrollCorner->destroy();
    277         m_scrollCorner = 0;
    278     }
    279 }
    280 
    281 void FrameView::clear()
    282 {
    283     setCanBlitOnScroll(true);
    284 
    285     reset();
    286 
    287     if (m_frame) {
    288         if (RenderPart* renderer = m_frame->ownerRenderer())
    289             renderer->viewCleared();
    290     }
    291 
    292     setScrollbarsSuppressed(true);
    293 }
    294 
    295 bool FrameView::didFirstLayout() const
    296 {
    297     return !m_firstLayout;
    298 }
    299 
    300 void FrameView::invalidateRect(const IntRect& rect)
    301 {
    302     if (!parent()) {
    303         if (hostWindow())
    304             hostWindow()->repaint(rect, true);
    305         return;
    306     }
    307 
    308     if (!m_frame)
    309         return;
    310 
    311     RenderPart* renderer = m_frame->ownerRenderer();
    312     if (!renderer)
    313         return;
    314 
    315     IntRect repaintRect = rect;
    316     repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
    317                      renderer->borderTop() + renderer->paddingTop());
    318     renderer->repaintRectangle(repaintRect);
    319 }
    320 
    321 void FrameView::setMarginWidth(int w)
    322 {
    323     // make it update the rendering area when set
    324     m_margins.setWidth(w);
    325 }
    326 
    327 void FrameView::setMarginHeight(int h)
    328 {
    329     // make it update the rendering area when set
    330     m_margins.setHeight(h);
    331 }
    332 
    333 void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
    334 {
    335     m_canHaveScrollbars = canHaveScrollbars;
    336     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
    337 }
    338 
    339 void FrameView::updateCanHaveScrollbars()
    340 {
    341     ScrollbarMode hMode;
    342     ScrollbarMode vMode;
    343     scrollbarModes(hMode, vMode);
    344     if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
    345         m_canHaveScrollbars = false;
    346     else
    347         m_canHaveScrollbars = true;
    348 }
    349 
    350 PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
    351 {
    352     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
    353     Document* doc = m_frame->document();
    354 
    355     // Try the <body> element first as a scrollbar source.
    356     Element* body = doc ? doc->body() : 0;
    357     if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR))
    358         return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderer()->enclosingBox());
    359 
    360     // If the <body> didn't have a custom style, then the root element might.
    361     Element* docElement = doc ? doc->documentElement() : 0;
    362     if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(SCROLLBAR))
    363         return RenderScrollbar::createCustomScrollbar(this, orientation, docElement->renderBox());
    364 
    365     // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
    366     RenderPart* frameRenderer = m_frame->ownerRenderer();
    367     if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR))
    368         return RenderScrollbar::createCustomScrollbar(this, orientation, frameRenderer);
    369 
    370     // Nobody set a custom style, so we just use a native scrollbar.
    371     return ScrollView::createScrollbar(orientation);
    372 }
    373 
    374 void FrameView::setContentsSize(const IntSize& size)
    375 {
    376     if (size == contentsSize())
    377         return;
    378 
    379     m_deferSetNeedsLayouts++;
    380 
    381     ScrollView::setContentsSize(size);
    382 
    383     Page* page = frame() ? frame()->page() : 0;
    384     if (!page)
    385         return;
    386 
    387     page->chrome()->contentsSizeChanged(frame(), size); //notify only
    388 
    389     m_deferSetNeedsLayouts--;
    390 
    391     if (!m_deferSetNeedsLayouts)
    392         m_setNeedsLayoutWasDeferred = false; // FIXME: Find a way to make the deferred layout actually happen.
    393 }
    394 
    395 void FrameView::adjustViewSize()
    396 {
    397     ASSERT(m_frame->view() == this);
    398     RenderView* root = m_frame->contentRenderer();
    399     if (!root)
    400         return;
    401     setContentsSize(IntSize(root->rightLayoutOverflow(), root->bottomLayoutOverflow()));
    402 }
    403 
    404 void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
    405 {
    406     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
    407     // overflow:hidden and overflow:scroll on <body> as applying to the document's
    408     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
    409     // use the root element.
    410     switch (o->style()->overflowX()) {
    411         case OHIDDEN:
    412             hMode = ScrollbarAlwaysOff;
    413             break;
    414         case OSCROLL:
    415             hMode = ScrollbarAlwaysOn;
    416             break;
    417         case OAUTO:
    418             hMode = ScrollbarAuto;
    419             break;
    420         default:
    421             // Don't set it at all.
    422             ;
    423     }
    424 
    425      switch (o->style()->overflowY()) {
    426         case OHIDDEN:
    427             vMode = ScrollbarAlwaysOff;
    428             break;
    429         case OSCROLL:
    430             vMode = ScrollbarAlwaysOn;
    431             break;
    432         case OAUTO:
    433             vMode = ScrollbarAuto;
    434             break;
    435         default:
    436             // Don't set it at all.
    437             ;
    438     }
    439 
    440     m_viewportRenderer = o;
    441 }
    442 
    443 #if USE(ACCELERATED_COMPOSITING)
    444 void FrameView::updateCompositingLayers()
    445 {
    446     RenderView* view = m_frame->contentRenderer();
    447     if (!view)
    448         return;
    449 
    450     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
    451     view->compositor()->cacheAcceleratedCompositingFlags();
    452 
    453     if (!view->usesCompositing())
    454         return;
    455 
    456     view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange);
    457 }
    458 
    459 void FrameView::setNeedsOneShotDrawingSynchronization()
    460 {
    461     Page* page = frame() ? frame()->page() : 0;
    462     if (page)
    463         page->chrome()->client()->setNeedsOneShotDrawingSynchronization();
    464 }
    465 #endif // USE(ACCELERATED_COMPOSITING)
    466 
    467 bool FrameView::syncCompositingStateRecursive()
    468 {
    469 #if USE(ACCELERATED_COMPOSITING)
    470     ASSERT(m_frame->view() == this);
    471     RenderView* contentRenderer = m_frame->contentRenderer();
    472     if (!contentRenderer)
    473         return true;    // We don't want to keep trying to update layers if we have no renderer.
    474 
    475     if (m_layoutTimer.isActive()) {
    476         // Don't sync layers if there's a layout pending.
    477         return false;
    478     }
    479 
    480     if (GraphicsLayer* rootLayer = contentRenderer->compositor()->rootPlatformLayer())
    481         rootLayer->syncCompositingState();
    482 
    483     bool allSubframesSynced = true;
    484     const HashSet<RefPtr<Widget> >* viewChildren = children();
    485     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
    486     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
    487         Widget* widget = (*current).get();
    488         if (widget->isFrameView()) {
    489             bool synced = static_cast<FrameView*>(widget)->syncCompositingStateRecursive();
    490             allSubframesSynced &= synced;
    491         }
    492     }
    493     return allSubframesSynced;
    494 #else // USE(ACCELERATED_COMPOSITING)
    495     return true;
    496 #endif
    497 }
    498 
    499 void FrameView::didMoveOnscreen()
    500 {
    501     RenderView* view = m_frame->contentRenderer();
    502     if (view)
    503         view->didMoveOnscreen();
    504 }
    505 
    506 void FrameView::willMoveOffscreen()
    507 {
    508     RenderView* view = m_frame->contentRenderer();
    509     if (view)
    510         view->willMoveOffscreen();
    511 }
    512 
    513 RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
    514 {
    515     return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
    516 }
    517 
    518 void FrameView::layout(bool allowSubtree)
    519 {
    520     if (m_midLayout)
    521         return;
    522 
    523     m_layoutTimer.stop();
    524     m_delayedLayout = false;
    525     m_setNeedsLayoutWasDeferred = false;
    526 
    527     // Protect the view from being deleted during layout (in recalcStyle)
    528     RefPtr<FrameView> protector(this);
    529 
    530     if (!m_frame) {
    531         // FIXME: Do we need to set m_size.width here?
    532         // FIXME: Should we set m_size.height here too?
    533         m_size.setWidth(layoutWidth());
    534         return;
    535     }
    536 
    537     // we shouldn't enter layout() while painting
    538     ASSERT(!isPainting());
    539     if (isPainting())
    540         return;
    541 
    542 #if ENABLE(INSPECTOR)
    543     if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
    544         timelineAgent->willLayout();
    545 #endif
    546 
    547     if (!allowSubtree && m_layoutRoot) {
    548         m_layoutRoot->markContainingBlocksForLayout(false);
    549         m_layoutRoot = 0;
    550     }
    551 
    552     ASSERT(m_frame->view() == this);
    553     // This early return should be removed when rdar://5598072 is resolved. In the meantime, there is a
    554     // gigantic CrashTracer because of this issue, and the early return will hopefully cause graceful
    555     // failure instead.
    556     if (m_frame->view() != this)
    557         return;
    558 
    559     Document* document = m_frame->document();
    560 
    561     m_layoutSchedulingEnabled = false;
    562 
    563     if (!m_nestedLayoutCount && m_postLayoutTasksTimer.isActive()) {
    564         // This is a new top-level layout. If there are any remaining tasks from the previous
    565         // layout, finish them now.
    566         m_postLayoutTasksTimer.stop();
    567         performPostLayoutTasks();
    568     }
    569 
    570     // Viewport-dependent media queries may cause us to need completely different style information.
    571     // Check that here.
    572     if (document->styleSelector()->affectedByViewportChange())
    573         document->updateStyleSelector();
    574 
    575     // Always ensure our style info is up-to-date.  This can happen in situations where
    576     // the layout beats any sort of style recalc update that needs to occur.
    577     if (m_frame->needsReapplyStyles())
    578         m_frame->reapplyStyles();
    579     else if (document->childNeedsStyleRecalc())
    580         document->recalcStyle();
    581 
    582     bool subtree = m_layoutRoot;
    583 
    584     // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
    585     // so there's no point to continuing to layout
    586     if (protector->hasOneRef())
    587         return;
    588 
    589     RenderObject* root = subtree ? m_layoutRoot : document->renderer();
    590     if (!root) {
    591         // FIXME: Do we need to set m_size here?
    592         m_layoutSchedulingEnabled = true;
    593         return;
    594     }
    595 
    596 #ifdef ANDROID_INSTRUMENT
    597     if (!m_frame->tree() || !m_frame->tree()->parent())
    598         android::TimeCounter::start(android::TimeCounter::LayoutTimeCounter);
    599 #endif
    600 
    601     m_nestedLayoutCount++;
    602 
    603     ScrollbarMode hMode;
    604     ScrollbarMode vMode;
    605     if (m_canHaveScrollbars) {
    606         hMode = ScrollbarAuto;
    607         vMode = ScrollbarAuto;
    608     } else {
    609         hMode = ScrollbarAlwaysOff;
    610         vMode = ScrollbarAlwaysOff;
    611     }
    612 
    613     if (!subtree) {
    614         Node* documentElement = document->documentElement();
    615         RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
    616         Node* body = document->body();
    617         if (body && body->renderer()) {
    618             if (body->hasTagName(framesetTag) && !m_frame->settings()->frameSetFlatteningEnabled()) {
    619                 body->renderer()->setChildNeedsLayout(true);
    620                 vMode = ScrollbarAlwaysOff;
    621                 hMode = ScrollbarAlwaysOff;
    622             } else if (body->hasTagName(bodyTag)) {
    623                 if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewHeight())
    624                     body->renderer()->setChildNeedsLayout(true);
    625                 // It's sufficient to just check the X overflow,
    626                 // since it's illegal to have visible in only one direction.
    627                 RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
    628                 applyOverflowToViewport(o, hMode, vMode);
    629             }
    630         } else if (rootRenderer) {
    631 #if ENABLE(SVG)
    632             if (documentElement->isSVGElement()) {
    633                 if (!m_firstLayout && (m_size.width() != layoutWidth() || m_size.height() != layoutHeight()))
    634                     rootRenderer->setChildNeedsLayout(true);
    635             } else
    636                 applyOverflowToViewport(rootRenderer, hMode, vMode);
    637 #else
    638             applyOverflowToViewport(rootRenderer, hMode, vMode);
    639 #endif
    640         }
    641 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
    642         if (m_firstLayout && !document->ownerElement())
    643             printf("Elapsed time before first layout: %d\n", document->elapsedTime());
    644 #endif
    645     }
    646 
    647     m_doFullRepaint = !subtree && (m_firstLayout || toRenderView(root)->printing());
    648 
    649     if (!subtree) {
    650         // Now set our scrollbar state for the layout.
    651         ScrollbarMode currentHMode = horizontalScrollbarMode();
    652         ScrollbarMode currentVMode = verticalScrollbarMode();
    653 
    654         if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
    655             setScrollbarsSuppressed(true);
    656             if (m_firstLayout) {
    657                 m_firstLayout = false;
    658                 m_firstLayoutCallbackPending = true;
    659                 m_lastLayoutSize = IntSize(width(), height());
    660                 m_lastZoomFactor = root->style()->zoom();
    661 
    662                 // Set the initial vMode to AlwaysOn if we're auto.
    663                 if (vMode == ScrollbarAuto)
    664                     setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
    665                 // Set the initial hMode to AlwaysOff if we're auto.
    666                 if (hMode == ScrollbarAuto)
    667                     setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
    668             }
    669             setScrollbarModes(hMode, vMode);
    670             setScrollbarsSuppressed(false, true);
    671         }
    672 
    673         IntSize oldSize = m_size;
    674 
    675         m_size = IntSize(layoutWidth(), layoutHeight());
    676 
    677         if (oldSize != m_size)
    678             m_doFullRepaint = true;
    679     }
    680 
    681     RenderLayer* layer = root->enclosingLayer();
    682 
    683     pauseScheduledEvents();
    684 
    685     bool disableLayoutState = false;
    686     if (subtree) {
    687         RenderView* view = root->view();
    688         disableLayoutState = view->shouldDisableLayoutStateForSubtree(root);
    689         view->pushLayoutState(root);
    690         if (disableLayoutState)
    691             view->disableLayoutState();
    692     }
    693 
    694     m_midLayout = true;
    695     beginDeferredRepaints();
    696     root->layout();
    697     endDeferredRepaints();
    698     m_midLayout = false;
    699 
    700     if (subtree) {
    701         RenderView* view = root->view();
    702         view->popLayoutState();
    703         if (disableLayoutState)
    704             view->enableLayoutState();
    705     }
    706     m_layoutRoot = 0;
    707 
    708     m_frame->selection()->setNeedsLayout();
    709     m_frame->selection()->updateAppearance();
    710 
    711     m_layoutSchedulingEnabled = true;
    712 
    713     if (!subtree && !toRenderView(root)->printing())
    714         adjustViewSize();
    715 
    716     // Now update the positions of all layers.
    717     beginDeferredRepaints();
    718     layer->updateLayerPositions((m_doFullRepaint ? RenderLayer::DoFullRepaint : 0)
    719                                 | RenderLayer::CheckForRepaint
    720                                 | RenderLayer::IsCompositingUpdateRoot
    721                                 | RenderLayer::UpdateCompositingLayers);
    722     endDeferredRepaints();
    723 
    724 #if USE(ACCELERATED_COMPOSITING)
    725     updateCompositingLayers();
    726 #endif
    727 
    728     m_layoutCount++;
    729 
    730 #if PLATFORM(MAC)
    731     if (AXObjectCache::accessibilityEnabled())
    732         root->document()->axObjectCache()->postNotification(root, AXObjectCache::AXLayoutComplete, true);
    733 #endif
    734 #if ENABLE(DASHBOARD_SUPPORT)
    735     updateDashboardRegions();
    736 #endif
    737 
    738 #ifdef ANDROID_INSTRUMENT
    739     if (!m_frame->tree()->parent())
    740         android::TimeCounter::record(android::TimeCounter::LayoutTimeCounter, __FUNCTION__);
    741 #endif
    742     ASSERT(!root->needsLayout());
    743 
    744     setCanBlitOnScroll(!useSlowRepaints());
    745 
    746     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
    747         updateOverflowStatus(layoutWidth() < contentsWidth(),
    748                              layoutHeight() < contentsHeight());
    749 
    750     if (!m_postLayoutTasksTimer.isActive()) {
    751         // Calls resumeScheduledEvents()
    752         performPostLayoutTasks();
    753 
    754         if (!m_postLayoutTasksTimer.isActive() && needsLayout()) {
    755             // Post-layout widget updates or an event handler made us need layout again.
    756             // Lay out again, but this time defer widget updates and event dispatch until after
    757             // we return.
    758             m_postLayoutTasksTimer.startOneShot(0);
    759             pauseScheduledEvents();
    760             layout();
    761         }
    762     } else {
    763         resumeScheduledEvents();
    764         ASSERT(m_enqueueEvents);
    765     }
    766 
    767 #if ENABLE(INSPECTOR)
    768     if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
    769         timelineAgent->didLayout();
    770 #endif
    771 
    772     m_nestedLayoutCount--;
    773 }
    774 
    775 void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object)
    776 {
    777     if (!m_widgetUpdateSet)
    778         m_widgetUpdateSet.set(new RenderEmbeddedObjectSet);
    779 
    780     m_widgetUpdateSet->add(object);
    781 }
    782 
    783 void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object)
    784 {
    785     if (!m_widgetUpdateSet)
    786         return;
    787 
    788     m_widgetUpdateSet->remove(object);
    789 }
    790 
    791 void FrameView::setMediaType(const String& mediaType)
    792 {
    793     m_mediaType = mediaType;
    794 }
    795 
    796 String FrameView::mediaType() const
    797 {
    798     // See if we have an override type.
    799     String overrideType = m_frame->loader()->client()->overrideMediaType();
    800     if (!overrideType.isNull())
    801         return overrideType;
    802     return m_mediaType;
    803 }
    804 
    805 bool FrameView::useSlowRepaints() const
    806 {
    807     return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || m_isOverlapped || !m_contentIsOpaque;
    808 }
    809 
    810 bool FrameView::useSlowRepaintsIfNotOverlapped() const
    811 {
    812     return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque;
    813 }
    814 
    815 void FrameView::setUseSlowRepaints()
    816 {
    817     m_useSlowRepaints = true;
    818     setCanBlitOnScroll(false);
    819 }
    820 
    821 void FrameView::addSlowRepaintObject()
    822 {
    823     if (!m_slowRepaintObjectCount)
    824         setCanBlitOnScroll(false);
    825     m_slowRepaintObjectCount++;
    826 }
    827 
    828 void FrameView::removeSlowRepaintObject()
    829 {
    830     ASSERT(m_slowRepaintObjectCount > 0);
    831     m_slowRepaintObjectCount--;
    832     if (!m_slowRepaintObjectCount)
    833         setCanBlitOnScroll(!useSlowRepaints());
    834 }
    835 
    836 void FrameView::setIsOverlapped(bool isOverlapped)
    837 {
    838     if (isOverlapped == m_isOverlapped)
    839         return;
    840 
    841     m_isOverlapped = isOverlapped;
    842     setCanBlitOnScroll(!useSlowRepaints());
    843 }
    844 
    845 void FrameView::setContentIsOpaque(bool contentIsOpaque)
    846 {
    847     if (contentIsOpaque == m_contentIsOpaque)
    848         return;
    849 
    850     m_contentIsOpaque = contentIsOpaque;
    851     setCanBlitOnScroll(!useSlowRepaints());
    852 }
    853 
    854 void FrameView::restoreScrollbar()
    855 {
    856     setScrollbarsSuppressed(false);
    857 }
    858 
    859 bool FrameView::scrollToFragment(const KURL& url)
    860 {
    861     // If our URL has no ref, then we have no place we need to jump to.
    862     // OTOH If CSS target was set previously, we want to set it to 0, recalc
    863     // and possibly repaint because :target pseudo class may have been
    864     // set (see bug 11321).
    865     if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget())
    866         return false;
    867 
    868     String fragmentIdentifier = url.fragmentIdentifier();
    869     if (scrollToAnchor(fragmentIdentifier))
    870         return true;
    871 
    872     // Try again after decoding the ref, based on the document's encoding.
    873     if (TextResourceDecoder* decoder = m_frame->document()->decoder())
    874         return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding()));
    875 
    876     return false;
    877 }
    878 
    879 bool FrameView::scrollToAnchor(const String& name)
    880 {
    881     ASSERT(m_frame->document());
    882 
    883     if (!m_frame->document()->haveStylesheetsLoaded()) {
    884         m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
    885         return false;
    886     }
    887 
    888     m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false);
    889 
    890     Element* anchorNode = m_frame->document()->findAnchor(name);
    891 
    892 #if ENABLE(SVG)
    893     if (m_frame->document()->isSVGDocument()) {
    894         if (name.startsWith("xpointer(")) {
    895             // We need to parse the xpointer reference here
    896         } else if (name.startsWith("svgView(")) {
    897             RefPtr<SVGSVGElement> svg = static_cast<SVGDocument*>(m_frame->document())->rootElement();
    898             if (!svg->currentView()->parseViewSpec(name))
    899                 return false;
    900             svg->setUseCurrentView(true);
    901         } else {
    902             if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) {
    903                 RefPtr<SVGViewElement> viewElement = anchorNode->hasTagName(SVGNames::viewTag) ? static_cast<SVGViewElement*>(anchorNode) : 0;
    904                 if (viewElement.get()) {
    905                     RefPtr<SVGSVGElement> svg = static_cast<SVGSVGElement*>(SVGLocatable::nearestViewportElement(viewElement.get()));
    906                     svg->inheritViewAttributes(viewElement.get());
    907                 }
    908             }
    909         }
    910         // FIXME: need to decide which <svg> to focus on, and zoom to that one
    911         // FIXME: need to actually "highlight" the viewTarget(s)
    912     }
    913 #endif
    914 
    915     m_frame->document()->setCSSTarget(anchorNode); // Setting to null will clear the current target.
    916 
    917     // Implement the rule that "" and "top" both mean top of page as in other browsers.
    918     if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top")))
    919         return false;
    920 
    921 #ifdef ANDROID_SCROLL_ON_GOTO_ANCHOR
    922     // TODO(andreip): check with Grace if this is correct.
    923     android::WebFrame::getWebFrame(m_frame.get())->setUserInitiatedClick(true);
    924 #endif
    925     maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document());
    926 #ifdef ANDROID_SCROLL_ON_GOTO_ANCHOR
    927     android::WebFrame::getWebFrame(m_frame.get())->setUserInitiatedClick(false);
    928 #endif
    929     return true;
    930 }
    931 
    932 void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
    933 {
    934     m_maintainScrollPositionAnchor = anchorNode;
    935     if (!m_maintainScrollPositionAnchor)
    936         return;
    937 
    938     // We need to update the layout before scrolling, otherwise we could
    939     // really mess things up if an anchor scroll comes at a bad moment.
    940     m_frame->document()->updateStyleIfNeeded();
    941     // Only do a layout if changes have occurred that make it necessary.
    942     if (m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout())
    943         layout();
    944     else
    945         scrollToAnchor();
    946 }
    947 
    948 void FrameView::scrollRectIntoViewRecursively(const IntRect& r)
    949 {
    950     bool wasInProgrammaticScroll = m_inProgrammaticScroll;
    951     m_inProgrammaticScroll = true;
    952     m_maintainScrollPositionAnchor = 0;
    953     ScrollView::scrollRectIntoViewRecursively(r);
    954     m_inProgrammaticScroll = wasInProgrammaticScroll;
    955 }
    956 
    957 void FrameView::setScrollPosition(const IntPoint& scrollPoint)
    958 {
    959     bool wasInProgrammaticScroll = m_inProgrammaticScroll;
    960     m_inProgrammaticScroll = true;
    961     m_maintainScrollPositionAnchor = 0;
    962     ScrollView::setScrollPosition(scrollPoint);
    963     m_inProgrammaticScroll = wasInProgrammaticScroll;
    964 }
    965 
    966 void FrameView::scrollPositionChanged()
    967 {
    968     frame()->eventHandler()->sendScrollEvent();
    969 
    970     // For fixed position elements, update widget positions and compositing layers after scrolling,
    971     // but only if we're not inside of layout.
    972     // FIXME: we could skip this if we knew the page had no fixed position elements.
    973     if (!m_nestedLayoutCount) {
    974         if (RenderView* root = m_frame->contentRenderer()) {
    975             root->updateWidgetPositions();
    976 #if USE(ACCELERATED_COMPOSITING)
    977             if (root->usesCompositing())
    978                 root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
    979 #endif
    980         }
    981     }
    982 }
    983 
    984 HostWindow* FrameView::hostWindow() const
    985 {
    986     Page* page = frame() ? frame()->page() : 0;
    987     if (!page)
    988         return 0;
    989     return page->chrome();
    990 }
    991 
    992 const unsigned cRepaintRectUnionThreshold = 25;
    993 
    994 void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
    995 {
    996     ASSERT(!m_frame->document()->ownerElement());
    997 
    998     double delay = adjustedDeferredRepaintDelay();
    999     if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
   1000         IntRect paintRect = r;
   1001         if (!paintsEntireContents())
   1002             paintRect.intersect(visibleContentRect());
   1003 #ifdef ANDROID_CAPTURE_OFFSCREEN_PAINTS
   1004         if (r != paintRect)
   1005             ScrollView::platformOffscreenContentRectangle(visibleContentRect(), r);
   1006 #endif
   1007         if (paintRect.isEmpty())
   1008             return;
   1009         if (m_repaintCount == cRepaintRectUnionThreshold) {
   1010             IntRect unionedRect;
   1011             for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i)
   1012                 unionedRect.unite(m_repaintRects[i]);
   1013             m_repaintRects.clear();
   1014             m_repaintRects.append(unionedRect);
   1015         }
   1016         if (m_repaintCount < cRepaintRectUnionThreshold)
   1017             m_repaintRects.append(paintRect);
   1018         else
   1019             m_repaintRects[0].unite(paintRect);
   1020         m_repaintCount++;
   1021 
   1022         if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive())
   1023              m_deferredRepaintTimer.startOneShot(delay);
   1024         return;
   1025     }
   1026 
   1027     if (!immediate && isOffscreen() && !shouldUpdateWhileOffscreen())
   1028         return;
   1029 
   1030     ScrollView::repaintContentRectangle(r, immediate);
   1031 }
   1032 
   1033 void FrameView::visibleContentsResized()
   1034 {
   1035     // We check to make sure the view is attached to a frame() as this method can
   1036     // be triggered before the view is attached by Frame::createView(...) setting
   1037     // various values such as setScrollBarModes(...) for example.  An ASSERT is
   1038     // triggered when a view is layout before being attached to a frame().
   1039     if (!frame()->view())
   1040         return;
   1041 
   1042     if (needsLayout())
   1043         layout();
   1044 }
   1045 
   1046 void FrameView::beginDeferredRepaints()
   1047 {
   1048     Page* page = m_frame->page();
   1049     if (page->mainFrame() != m_frame)
   1050         return page->mainFrame()->view()->beginDeferredRepaints();
   1051 
   1052     m_deferringRepaints++;
   1053 }
   1054 
   1055 
   1056 void FrameView::endDeferredRepaints()
   1057 {
   1058     Page* page = m_frame->page();
   1059     if (page->mainFrame() != m_frame)
   1060         return page->mainFrame()->view()->endDeferredRepaints();
   1061 
   1062     ASSERT(m_deferringRepaints > 0);
   1063 
   1064     if (--m_deferringRepaints)
   1065         return;
   1066 
   1067     if (m_deferredRepaintTimer.isActive())
   1068         return;
   1069 
   1070     if (double delay = adjustedDeferredRepaintDelay()) {
   1071         m_deferredRepaintTimer.startOneShot(delay);
   1072         return;
   1073     }
   1074 
   1075     doDeferredRepaints();
   1076 }
   1077 
   1078 void FrameView::checkStopDelayingDeferredRepaints()
   1079 {
   1080     if (!m_deferredRepaintTimer.isActive())
   1081         return;
   1082 
   1083     Document* document = m_frame->document();
   1084     if (document && (document->parsing() || document->docLoader()->requestCount()))
   1085         return;
   1086 
   1087     m_deferredRepaintTimer.stop();
   1088 
   1089     doDeferredRepaints();
   1090 }
   1091 
   1092 void FrameView::doDeferredRepaints()
   1093 {
   1094     ASSERT(!m_deferringRepaints);
   1095     if (isOffscreen() && !shouldUpdateWhileOffscreen()) {
   1096         m_repaintRects.clear();
   1097         m_repaintCount = 0;
   1098         return;
   1099     }
   1100     unsigned size = m_repaintRects.size();
   1101     for (unsigned i = 0; i < size; i++)
   1102         ScrollView::repaintContentRectangle(m_repaintRects[i], false);
   1103     m_repaintRects.clear();
   1104     m_repaintCount = 0;
   1105 
   1106     updateDeferredRepaintDelay();
   1107 }
   1108 
   1109 void FrameView::updateDeferredRepaintDelay()
   1110 {
   1111     Document* document = m_frame->document();
   1112     if (!document || (!document->parsing() && !document->docLoader()->requestCount())) {
   1113         m_deferredRepaintDelay = deferredRepaintDelay;
   1114         return;
   1115     }
   1116     if (m_deferredRepaintDelay < maxDeferredRepaintDelayDuringLoading) {
   1117         m_deferredRepaintDelay += deferredRepaintDelayIncrementDuringLoading;
   1118         if (m_deferredRepaintDelay > maxDeferredRepaintDelayDuringLoading)
   1119             m_deferredRepaintDelay = maxDeferredRepaintDelayDuringLoading;
   1120     }
   1121 }
   1122 
   1123 void FrameView::resetDeferredRepaintDelay()
   1124 {
   1125     m_deferredRepaintDelay = 0;
   1126     if (m_deferredRepaintTimer.isActive()) {
   1127         m_deferredRepaintTimer.stop();
   1128         if (!m_deferringRepaints)
   1129             doDeferredRepaints();
   1130     }
   1131 }
   1132 
   1133 double FrameView::adjustedDeferredRepaintDelay() const
   1134 {
   1135     if (!m_deferredRepaintDelay)
   1136         return 0;
   1137     double timeSinceLastPaint = currentTime() - m_lastPaintTime;
   1138     return max(0., m_deferredRepaintDelay - timeSinceLastPaint);
   1139 }
   1140 
   1141 void FrameView::deferredRepaintTimerFired(Timer<FrameView>*)
   1142 {
   1143     doDeferredRepaints();
   1144 }
   1145 
   1146 void FrameView::layoutTimerFired(Timer<FrameView>*)
   1147 {
   1148 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
   1149     if (!m_frame->document()->ownerElement())
   1150         printf("Layout timer fired at %d\n", m_frame->document()->elapsedTime());
   1151 #endif
   1152     layout();
   1153 }
   1154 
   1155 void FrameView::scheduleRelayout()
   1156 {
   1157     // FIXME: We should assert the page is not in the page cache, but that is causing
   1158     // too many false assertions.  See <rdar://problem/7218118>.
   1159     ASSERT(m_frame->view() == this);
   1160 
   1161     if (m_layoutRoot) {
   1162         m_layoutRoot->markContainingBlocksForLayout(false);
   1163         m_layoutRoot = 0;
   1164     }
   1165     if (!m_layoutSchedulingEnabled)
   1166         return;
   1167     if (!needsLayout())
   1168         return;
   1169     if (!m_frame->document()->shouldScheduleLayout())
   1170         return;
   1171 
   1172 #if defined(FLATTEN_IFRAME) || defined(FLATTEN_FRAMESET)
   1173     // This is the Android frame flattening code. The common code below is not
   1174     // used as frameSetFlatteningEnabled() is false on Android.
   1175     if (m_frame->ownerRenderer())
   1176         m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
   1177 #endif
   1178 
   1179     // When frameset flattening is enabled, the contents of the frame affects layout of the parent frames.
   1180     // Also invalidate parent frame starting from the owner element of this frame.
   1181     if (m_frame->settings()->frameSetFlatteningEnabled() && m_frame->ownerRenderer())
   1182         m_frame->ownerRenderer()->setNeedsLayout(true, true);
   1183 
   1184     int delay = m_frame->document()->minimumLayoutDelay();
   1185     if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
   1186         unscheduleRelayout();
   1187     if (m_layoutTimer.isActive())
   1188         return;
   1189 
   1190     m_delayedLayout = delay != 0;
   1191 
   1192 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
   1193     if (!m_frame->document()->ownerElement())
   1194         printf("Scheduling layout for %d\n", delay);
   1195 #endif
   1196 
   1197     m_layoutTimer.startOneShot(delay * 0.001);
   1198 }
   1199 
   1200 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
   1201 {
   1202     for (RenderObject* r = descendant; r; r = r->container()) {
   1203         if (r == ancestor)
   1204             return true;
   1205     }
   1206     return false;
   1207 }
   1208 
   1209 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
   1210 {
   1211     ASSERT(m_frame->view() == this);
   1212 
   1213     if (!m_layoutSchedulingEnabled || (m_frame->contentRenderer()
   1214             && m_frame->contentRenderer()->needsLayout())) {
   1215         if (relayoutRoot)
   1216             relayoutRoot->markContainingBlocksForLayout(false);
   1217         return;
   1218     }
   1219 
   1220     if (layoutPending()) {
   1221         if (m_layoutRoot != relayoutRoot) {
   1222             if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) {
   1223                 // Keep the current root
   1224                 relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot);
   1225             } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) {
   1226                 // Re-root at relayoutRoot
   1227                 m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
   1228                 m_layoutRoot = relayoutRoot;
   1229             } else {
   1230                 // Just do a full relayout
   1231                 if (m_layoutRoot)
   1232                     m_layoutRoot->markContainingBlocksForLayout(false);
   1233                 m_layoutRoot = 0;
   1234                 relayoutRoot->markContainingBlocksForLayout(false);
   1235             }
   1236         }
   1237     } else {
   1238         int delay = m_frame->document()->minimumLayoutDelay();
   1239         m_layoutRoot = relayoutRoot;
   1240         m_delayedLayout = delay != 0;
   1241         m_layoutTimer.startOneShot(delay * 0.001);
   1242     }
   1243 }
   1244 
   1245 bool FrameView::layoutPending() const
   1246 {
   1247     return m_layoutTimer.isActive();
   1248 }
   1249 
   1250 bool FrameView::needsLayout() const
   1251 {
   1252     // This can return true in cases where the document does not have a body yet.
   1253     // Document::shouldScheduleLayout takes care of preventing us from scheduling
   1254     // layout in that case.
   1255     if (!m_frame)
   1256         return false;
   1257     RenderView* root = m_frame->contentRenderer();
   1258     Document* document = m_frame->document();
   1259     return layoutPending()
   1260         || (root && root->needsLayout())
   1261         || m_layoutRoot
   1262         || (document && document->childNeedsStyleRecalc()) // can occur when using WebKit ObjC interface
   1263         || m_frame->needsReapplyStyles()
   1264         || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred);
   1265 }
   1266 
   1267 void FrameView::setNeedsLayout()
   1268 {
   1269     if (m_deferSetNeedsLayouts) {
   1270         m_setNeedsLayoutWasDeferred = true;
   1271         return;
   1272     }
   1273     RenderView* root = m_frame->contentRenderer();
   1274     if (root)
   1275         root->setNeedsLayout(true);
   1276 }
   1277 
   1278 void FrameView::unscheduleRelayout()
   1279 {
   1280     if (!m_layoutTimer.isActive())
   1281         return;
   1282 
   1283 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
   1284     if (!m_frame->document()->ownerElement())
   1285         printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
   1286 #endif
   1287 
   1288     m_layoutTimer.stop();
   1289     m_delayedLayout = false;
   1290 }
   1291 
   1292 bool FrameView::isTransparent() const
   1293 {
   1294     return m_isTransparent;
   1295 }
   1296 
   1297 void FrameView::setTransparent(bool isTransparent)
   1298 {
   1299     m_isTransparent = isTransparent;
   1300 }
   1301 
   1302 Color FrameView::baseBackgroundColor() const
   1303 {
   1304     return m_baseBackgroundColor;
   1305 }
   1306 
   1307 void FrameView::setBaseBackgroundColor(Color bc)
   1308 {
   1309     if (!bc.isValid())
   1310         bc = Color::white;
   1311     m_baseBackgroundColor = bc;
   1312 }
   1313 
   1314 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
   1315 {
   1316     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
   1317         FrameView* view = frame->view();
   1318         if (!view)
   1319             continue;
   1320 
   1321         view->setTransparent(transparent);
   1322         view->setBaseBackgroundColor(backgroundColor);
   1323     }
   1324 }
   1325 
   1326 bool FrameView::shouldUpdateWhileOffscreen() const
   1327 {
   1328     return m_shouldUpdateWhileOffscreen;
   1329 }
   1330 
   1331 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
   1332 {
   1333     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
   1334 }
   1335 
   1336 void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget)
   1337 {
   1338     if (!m_enqueueEvents) {
   1339         ExceptionCode ec = 0;
   1340         eventTarget->dispatchEvent(event, ec);
   1341         return;
   1342     }
   1343 
   1344     ScheduledEvent* scheduledEvent = new ScheduledEvent;
   1345     scheduledEvent->m_event = event;
   1346     scheduledEvent->m_eventTarget = eventTarget;
   1347     m_scheduledEvents.append(scheduledEvent);
   1348 }
   1349 
   1350 void FrameView::pauseScheduledEvents()
   1351 {
   1352     ASSERT(m_scheduledEvents.isEmpty() || m_enqueueEvents);
   1353     m_enqueueEvents++;
   1354 }
   1355 
   1356 void FrameView::resumeScheduledEvents()
   1357 {
   1358     m_enqueueEvents--;
   1359     if (!m_enqueueEvents)
   1360         dispatchScheduledEvents();
   1361     ASSERT(m_scheduledEvents.isEmpty() || m_enqueueEvents);
   1362 }
   1363 
   1364 void FrameView::scrollToAnchor()
   1365 {
   1366     RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
   1367     if (!anchorNode)
   1368         return;
   1369 
   1370     if (!anchorNode->renderer())
   1371         return;
   1372 
   1373     IntRect rect;
   1374     if (anchorNode != m_frame->document())
   1375         rect = anchorNode->getRect();
   1376 
   1377     // Scroll nested layers and frames to reveal the anchor.
   1378     // Align to the top and to the closest side (this matches other browsers).
   1379     anchorNode->renderer()->enclosingLayer()->scrollRectToVisible(rect, true, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
   1380 
   1381     if (AXObjectCache::accessibilityEnabled())
   1382         m_frame->document()->axObjectCache()->handleScrolledToAnchor(anchorNode.get());
   1383 
   1384     // scrollRectToVisible can call into scrollRectIntoViewRecursively(), which resets m_maintainScrollPositionAnchor.
   1385     m_maintainScrollPositionAnchor = anchorNode;
   1386 }
   1387 
   1388 bool FrameView::updateWidgets()
   1389 {
   1390     if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
   1391         return true;
   1392 
   1393     Vector<RenderEmbeddedObject*> objectVector;
   1394     copyToVector(*m_widgetUpdateSet, objectVector);
   1395     size_t size = objectVector.size();
   1396     for (size_t i = 0; i < size; ++i) {
   1397         RenderEmbeddedObject* object = objectVector[i];
   1398         object->updateWidget(false);
   1399 
   1400         // updateWidget() can destroy the RenderPartObject, so we need to make sure it's
   1401         // alive by checking if it's still in m_widgetUpdateSet.
   1402         if (m_widgetUpdateSet->contains(object)) {
   1403             object->updateWidgetPosition();
   1404             m_widgetUpdateSet->remove(object);
   1405         }
   1406     }
   1407 
   1408     return m_widgetUpdateSet->isEmpty();
   1409 }
   1410 
   1411 void FrameView::performPostLayoutTasks()
   1412 {
   1413     if (m_firstLayoutCallbackPending) {
   1414         m_firstLayoutCallbackPending = false;
   1415         m_frame->loader()->didFirstLayout();
   1416     }
   1417 
   1418     if (m_isVisuallyNonEmpty && m_firstVisuallyNonEmptyLayoutCallbackPending) {
   1419         m_firstVisuallyNonEmptyLayoutCallbackPending = false;
   1420         m_frame->loader()->didFirstVisuallyNonEmptyLayout();
   1421     }
   1422 
   1423     RenderView* root = m_frame->contentRenderer();
   1424 
   1425     root->updateWidgetPositions();
   1426 
   1427     for (unsigned i = 0; i < maxUpdateWidgetsIterations; i++) {
   1428         if (updateWidgets())
   1429             break;
   1430     }
   1431 
   1432     scrollToAnchor();
   1433 
   1434     resumeScheduledEvents();
   1435 
   1436     if (!root->printing()) {
   1437         IntSize currentSize = IntSize(width(), height());
   1438         float currentZoomFactor = root->style()->zoom();
   1439         bool resized = !m_firstLayout && (currentSize != m_lastLayoutSize || currentZoomFactor != m_lastZoomFactor);
   1440         m_lastLayoutSize = currentSize;
   1441         m_lastZoomFactor = currentZoomFactor;
   1442         if (resized)
   1443             m_frame->eventHandler()->sendResizeEvent();
   1444     }
   1445 }
   1446 
   1447 void FrameView::postLayoutTimerFired(Timer<FrameView>*)
   1448 {
   1449     performPostLayoutTasks();
   1450 }
   1451 
   1452 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
   1453 {
   1454     if (!m_viewportRenderer)
   1455         return;
   1456 
   1457     if (m_overflowStatusDirty) {
   1458         m_horizontalOverflow = horizontalOverflow;
   1459         m_verticalOverflow = verticalOverflow;
   1460         m_overflowStatusDirty = false;
   1461         return;
   1462     }
   1463 
   1464     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
   1465     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
   1466 
   1467     if (horizontalOverflowChanged || verticalOverflowChanged) {
   1468         m_horizontalOverflow = horizontalOverflow;
   1469         m_verticalOverflow = verticalOverflow;
   1470 
   1471         scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
   1472             verticalOverflowChanged, verticalOverflow),
   1473             m_viewportRenderer->node());
   1474     }
   1475 
   1476 }
   1477 
   1478 void FrameView::dispatchScheduledEvents()
   1479 {
   1480     if (m_scheduledEvents.isEmpty())
   1481         return;
   1482 
   1483     Vector<ScheduledEvent*> scheduledEventsCopy = m_scheduledEvents;
   1484     m_scheduledEvents.clear();
   1485 
   1486     Vector<ScheduledEvent*>::iterator end = scheduledEventsCopy.end();
   1487     for (Vector<ScheduledEvent*>::iterator it = scheduledEventsCopy.begin(); it != end; ++it) {
   1488         ScheduledEvent* scheduledEvent = *it;
   1489 
   1490         ExceptionCode ec = 0;
   1491 
   1492         // Only dispatch events to nodes that are in the document
   1493         if (scheduledEvent->m_eventTarget->inDocument())
   1494             scheduledEvent->m_eventTarget->dispatchEvent(scheduledEvent->m_event, ec);
   1495 
   1496         delete scheduledEvent;
   1497     }
   1498 }
   1499 
   1500 IntRect FrameView::windowClipRect(bool clipToContents) const
   1501 {
   1502     ASSERT(m_frame->view() == this);
   1503 
   1504     // Set our clip rect to be our contents.
   1505     IntRect clipRect = contentsToWindow(visibleContentRect(!clipToContents));
   1506     if (!m_frame || !m_frame->document()->ownerElement())
   1507         return clipRect;
   1508 
   1509     // Take our owner element and get the clip rect from the enclosing layer.
   1510     Element* elt = m_frame->document()->ownerElement();
   1511     RenderLayer* layer = elt->renderer()->enclosingLayer();
   1512     // FIXME: layer should never be null, but sometimes seems to be anyway.
   1513     if (!layer)
   1514         return clipRect;
   1515     FrameView* parentView = elt->document()->view();
   1516     clipRect.intersect(parentView->windowClipRectForLayer(layer, true));
   1517     return clipRect;
   1518 }
   1519 
   1520 IntRect FrameView::windowClipRectForLayer(const RenderLayer* layer, bool clipToLayerContents) const
   1521 {
   1522     // If we have no layer, just return our window clip rect.
   1523     if (!layer)
   1524         return windowClipRect();
   1525 
   1526     // Apply the clip from the layer.
   1527     IntRect clipRect;
   1528     if (clipToLayerContents)
   1529         clipRect = layer->childrenClipRect();
   1530     else
   1531         clipRect = layer->selfClipRect();
   1532     clipRect = contentsToWindow(clipRect);
   1533     return intersection(clipRect, windowClipRect());
   1534 }
   1535 
   1536 bool FrameView::isActive() const
   1537 {
   1538     Page* page = frame()->page();
   1539     return page && page->focusController()->isActive();
   1540 }
   1541 
   1542 void FrameView::valueChanged(Scrollbar* bar)
   1543 {
   1544     // Figure out if we really moved.
   1545     IntSize offset = scrollOffset();
   1546     ScrollView::valueChanged(bar);
   1547     if (offset != scrollOffset())
   1548         frame()->eventHandler()->sendScrollEvent();
   1549     frame()->loader()->client()->didChangeScrollOffset();
   1550 }
   1551 
   1552 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
   1553 {
   1554     // Add in our offset within the FrameView.
   1555     IntRect dirtyRect = rect;
   1556     dirtyRect.move(scrollbar->x(), scrollbar->y());
   1557     invalidateRect(dirtyRect);
   1558 }
   1559 
   1560 void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
   1561 {
   1562     tickmarks = frame()->document()->renderedRectsForMarkers(DocumentMarker::TextMatch);
   1563 }
   1564 
   1565 IntRect FrameView::windowResizerRect() const
   1566 {
   1567     Page* page = frame() ? frame()->page() : 0;
   1568     if (!page)
   1569         return IntRect();
   1570     return page->chrome()->windowResizerRect();
   1571 }
   1572 
   1573 #if ENABLE(DASHBOARD_SUPPORT)
   1574 void FrameView::updateDashboardRegions()
   1575 {
   1576     Document* document = m_frame->document();
   1577     if (!document->hasDashboardRegions())
   1578         return;
   1579     Vector<DashboardRegionValue> newRegions;
   1580     document->renderBox()->collectDashboardRegions(newRegions);
   1581     if (newRegions == document->dashboardRegions())
   1582         return;
   1583     document->setDashboardRegions(newRegions);
   1584     Page* page = m_frame->page();
   1585     if (!page)
   1586         return;
   1587     page->chrome()->client()->dashboardRegionsChanged();
   1588 }
   1589 #endif
   1590 
   1591 void FrameView::invalidateScrollCorner()
   1592 {
   1593     invalidateRect(scrollCornerRect());
   1594 }
   1595 
   1596 void FrameView::updateScrollCorner()
   1597 {
   1598     RenderObject* renderer = 0;
   1599     RefPtr<RenderStyle> cornerStyle;
   1600 
   1601     if (!scrollCornerRect().isEmpty()) {
   1602         // Try the <body> element first as a scroll corner source.
   1603         Document* doc = m_frame->document();
   1604         Element* body = doc ? doc->body() : 0;
   1605         if (body && body->renderer()) {
   1606             renderer = body->renderer();
   1607             cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
   1608         }
   1609 
   1610         if (!cornerStyle) {
   1611             // If the <body> didn't have a custom style, then the root element might.
   1612             Element* docElement = doc ? doc->documentElement() : 0;
   1613             if (docElement && docElement->renderer()) {
   1614                 renderer = docElement->renderer();
   1615                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
   1616             }
   1617         }
   1618 
   1619         if (!cornerStyle) {
   1620             // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
   1621             if (RenderPart* renderer = m_frame->ownerRenderer())
   1622                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
   1623         }
   1624     }
   1625 
   1626     if (cornerStyle) {
   1627         if (!m_scrollCorner)
   1628             m_scrollCorner = new (renderer->renderArena()) RenderScrollbarPart(renderer->document());
   1629         m_scrollCorner->setStyle(cornerStyle.release());
   1630         invalidateRect(scrollCornerRect());
   1631     } else if (m_scrollCorner) {
   1632         m_scrollCorner->destroy();
   1633         m_scrollCorner = 0;
   1634     }
   1635 }
   1636 
   1637 void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
   1638 {
   1639     if (context->updatingControlTints()) {
   1640         updateScrollCorner();
   1641         return;
   1642     }
   1643 
   1644     if (m_scrollCorner) {
   1645         m_scrollCorner->paintIntoRect(context, cornerRect.x(), cornerRect.y(), cornerRect);
   1646         return;
   1647     }
   1648 
   1649     ScrollView::paintScrollCorner(context, cornerRect);
   1650 }
   1651 
   1652 bool FrameView::hasCustomScrollbars() const
   1653 {
   1654     const HashSet<RefPtr<Widget> >* viewChildren = children();
   1655     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
   1656     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
   1657         Widget* widget = current->get();
   1658         if (widget->isFrameView()) {
   1659             if (static_cast<FrameView*>(widget)->hasCustomScrollbars())
   1660                 return true;
   1661         } else if (widget->isScrollbar()) {
   1662             Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
   1663             if (scrollbar->isCustomScrollbar())
   1664                 return true;
   1665         }
   1666     }
   1667 
   1668     return false;
   1669 }
   1670 
   1671 void FrameView::updateControlTints()
   1672 {
   1673     // This is called when control tints are changed from aqua/graphite to clear and vice versa.
   1674     // We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
   1675     // This is only done if the theme supports control tinting. It's up to the theme and platform
   1676     // to define when controls get the tint and to call this function when that changes.
   1677 
   1678     // Optimize the common case where we bring a window to the front while it's still empty.
   1679     if (!m_frame || m_frame->loader()->url().isEmpty())
   1680         return;
   1681 
   1682     if ((m_frame->contentRenderer() && m_frame->contentRenderer()->theme()->supportsControlTints()) || hasCustomScrollbars())  {
   1683         if (needsLayout())
   1684             layout();
   1685         PlatformGraphicsContext* const noContext = 0;
   1686         GraphicsContext context(noContext);
   1687         context.setUpdatingControlTints(true);
   1688         if (platformWidget())
   1689             paintContents(&context, visibleContentRect());
   1690         else
   1691             paint(&context, frameRect());
   1692     }
   1693 }
   1694 
   1695 bool FrameView::wasScrolledByUser() const
   1696 {
   1697     return m_wasScrolledByUser;
   1698 }
   1699 
   1700 void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
   1701 {
   1702     if (m_inProgrammaticScroll)
   1703         return;
   1704     m_maintainScrollPositionAnchor = 0;
   1705     m_wasScrolledByUser = wasScrolledByUser;
   1706 }
   1707 
   1708 void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
   1709 {
   1710     if (!frame())
   1711         return;
   1712 
   1713 #if ENABLE(INSPECTOR)
   1714     if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
   1715         timelineAgent->willPaint(rect);
   1716 #endif
   1717 
   1718     Document* document = frame()->document();
   1719 
   1720 #ifndef NDEBUG
   1721     bool fillWithRed;
   1722     if (document->printing())
   1723         fillWithRed = false; // Printing, don't fill with red (can't remember why).
   1724     else if (document->ownerElement())
   1725         fillWithRed = false; // Subframe, don't fill with red.
   1726     else if (isTransparent())
   1727         fillWithRed = false; // Transparent, don't fill with red.
   1728     else if (m_paintBehavior & PaintBehaviorSelectionOnly)
   1729         fillWithRed = false; // Selections are transparent, don't fill with red.
   1730     else if (m_nodeToDraw)
   1731         fillWithRed = false; // Element images are transparent, don't fill with red.
   1732     else
   1733         fillWithRed = true;
   1734 
   1735     if (fillWithRed)
   1736         p->fillRect(rect, Color(0xFF, 0, 0), DeviceColorSpace);
   1737 #endif
   1738 
   1739     bool isTopLevelPainter = !sCurrentPaintTimeStamp;
   1740     if (isTopLevelPainter)
   1741         sCurrentPaintTimeStamp = currentTime();
   1742 
   1743     RenderView* contentRenderer = frame()->contentRenderer();
   1744     if (!contentRenderer) {
   1745         LOG_ERROR("called Frame::paint with nil renderer");
   1746         return;
   1747     }
   1748 
   1749     ASSERT(!needsLayout());
   1750     if (needsLayout())
   1751         return;
   1752 
   1753 #if USE(ACCELERATED_COMPOSITING)
   1754     if (!p->paintingDisabled()) {
   1755         if (GraphicsLayer* rootLayer = contentRenderer->compositor()->rootPlatformLayer())
   1756             rootLayer->syncCompositingState();
   1757     }
   1758 #endif
   1759 
   1760     ASSERT(!m_isPainting);
   1761 
   1762     m_isPainting = true;
   1763 
   1764     // m_nodeToDraw is used to draw only one element (and its descendants)
   1765     RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
   1766 
   1767     PaintBehavior paintBehavior = m_paintBehavior;
   1768     if (paintBehavior == PaintBehaviorNormal)
   1769         document->invalidateRenderedRectsForMarkersInRect(rect);
   1770 
   1771     if (document->printing())
   1772         paintBehavior |= PaintBehaviorFlattenCompositingLayers;
   1773 
   1774     contentRenderer->layer()->paint(p, rect, paintBehavior, eltRenderer);
   1775 
   1776     m_isPainting = false;
   1777     m_lastPaintTime = currentTime();
   1778 
   1779 #if ENABLE(DASHBOARD_SUPPORT)
   1780     // Regions may have changed as a result of the visibility/z-index of element changing.
   1781     if (document->dashboardRegionsDirty())
   1782         updateDashboardRegions();
   1783 #endif
   1784 
   1785     if (isTopLevelPainter)
   1786         sCurrentPaintTimeStamp = 0;
   1787 
   1788 #if ENABLE(INSPECTOR)
   1789     if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
   1790         timelineAgent->didPaint();
   1791 #endif
   1792 }
   1793 
   1794 void FrameView::setPaintBehavior(PaintBehavior behavior)
   1795 {
   1796     m_paintBehavior = behavior;
   1797 }
   1798 
   1799 bool FrameView::isPainting() const
   1800 {
   1801     return m_isPainting;
   1802 }
   1803 
   1804 void FrameView::setNodeToDraw(Node* node)
   1805 {
   1806     m_nodeToDraw = node;
   1807 }
   1808 
   1809 void FrameView::layoutIfNeededRecursive()
   1810 {
   1811     // We have to crawl our entire tree looking for any FrameViews that need
   1812     // layout and make sure they are up to date.
   1813     // Mac actually tests for intersection with the dirty region and tries not to
   1814     // update layout for frames that are outside the dirty region.  Not only does this seem
   1815     // pointless (since those frames will have set a zero timer to layout anyway), but
   1816     // it is also incorrect, since if two frames overlap, the first could be excluded from the dirty
   1817     // region but then become included later by the second frame adding rects to the dirty region
   1818     // when it lays out.
   1819 
   1820     if (needsLayout())
   1821         layout();
   1822 
   1823     const HashSet<RefPtr<Widget> >* viewChildren = children();
   1824     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
   1825     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
   1826         Widget* widget = (*current).get();
   1827         if (widget->isFrameView())
   1828             static_cast<FrameView*>(widget)->layoutIfNeededRecursive();
   1829     }
   1830 
   1831     // layoutIfNeededRecursive is called when we need to make sure layout is up-to-date before
   1832     // painting, so we need to flush out any deferred repaints too.
   1833     flushDeferredRepaints();
   1834 }
   1835 
   1836 void FrameView::flushDeferredRepaints()
   1837 {
   1838     if (!m_deferredRepaintTimer.isActive())
   1839         return;
   1840     m_deferredRepaintTimer.stop();
   1841     doDeferredRepaints();
   1842 }
   1843 
   1844 void FrameView::forceLayout(bool allowSubtree)
   1845 {
   1846     layout(allowSubtree);
   1847     // We cannot unschedule a pending relayout, since the force can be called with
   1848     // a tiny rectangle from a drawRect update.  By unscheduling we in effect
   1849     // "validate" and stop the necessary full repaint from occurring.  Basically any basic
   1850     // append/remove DHTML is broken by this call.  For now, I have removed the optimization
   1851     // until we have a better invalidation stategy. -dwh
   1852     //unscheduleRelayout();
   1853 }
   1854 
   1855 void FrameView::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth, bool _adjustViewSize)
   1856 {
   1857     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
   1858     // the state of things before and after the layout
   1859     RenderView *root = toRenderView(m_frame->document()->renderer());
   1860     if (root) {
   1861         // This magic is basically copied from khtmlview::print
   1862         int pageW = (int)ceilf(minPageWidth);
   1863         root->setWidth(pageW);
   1864         root->setNeedsLayoutAndPrefWidthsRecalc();
   1865         forceLayout();
   1866 
   1867         // If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the
   1868         // maximum page width, we will lay out to the maximum page width and clip extra content.
   1869         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
   1870         // implementation should not do this!
   1871         int rightmostPos = root->rightmostPosition();
   1872         if (rightmostPos > minPageWidth) {
   1873             pageW = std::min(rightmostPos, (int)ceilf(maxPageWidth));
   1874             root->setWidth(pageW);
   1875             root->setNeedsLayoutAndPrefWidthsRecalc();
   1876             forceLayout();
   1877         }
   1878     }
   1879 
   1880     if (_adjustViewSize)
   1881         adjustViewSize();
   1882 }
   1883 
   1884 void FrameView::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
   1885 {
   1886     RenderView* root = m_frame->contentRenderer();
   1887     if (root) {
   1888         // Use a context with painting disabled.
   1889         GraphicsContext context((PlatformGraphicsContext*)0);
   1890         root->setTruncatedAt((int)floorf(oldBottom));
   1891         IntRect dirtyRect(0, (int)floorf(oldTop), root->rightLayoutOverflow(), (int)ceilf(oldBottom - oldTop));
   1892         root->layer()->paint(&context, dirtyRect);
   1893         *newBottom = root->bestTruncatedAt();
   1894         if (*newBottom == 0)
   1895             *newBottom = oldBottom;
   1896     } else
   1897         *newBottom = oldBottom;
   1898 }
   1899 
   1900 IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
   1901 {
   1902     IntRect rect = renderer->localToAbsoluteQuad(FloatRect(rendererRect)).enclosingBoundingBox();
   1903 
   1904     // Convert from page ("absolute") to FrameView coordinates.
   1905     rect.move(-scrollX(), -scrollY());
   1906 
   1907     return rect;
   1908 }
   1909 
   1910 IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect& viewRect) const
   1911 {
   1912     IntRect rect = viewRect;
   1913 
   1914     // Convert from FrameView coords into page ("absolute") coordinates.
   1915     rect.move(scrollX(), scrollY());
   1916 
   1917     // FIXME: we don't have a way to map an absolute rect down to a local quad, so just
   1918     // move the rect for now.
   1919     rect.setLocation(roundedIntPoint(renderer->absoluteToLocal(rect.location(), false, true /* use transforms */)));
   1920     return rect;
   1921 }
   1922 
   1923 IntPoint FrameView::convertFromRenderer(const RenderObject* renderer, const IntPoint& rendererPoint) const
   1924 {
   1925     IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, false, true /* use transforms */));
   1926 
   1927     // Convert from page ("absolute") to FrameView coordinates.
   1928     point.move(-scrollX(), -scrollY());
   1929     return point;
   1930 }
   1931 
   1932 IntPoint FrameView::convertToRenderer(const RenderObject* renderer, const IntPoint& viewPoint) const
   1933 {
   1934     IntPoint point = viewPoint;
   1935 
   1936     // Convert from FrameView coords into page ("absolute") coordinates.
   1937     point += IntSize(scrollX(), scrollY());
   1938 
   1939     return roundedIntPoint(renderer->absoluteToLocal(point, false, true /* use transforms */));
   1940 }
   1941 
   1942 IntRect FrameView::convertToContainingView(const IntRect& localRect) const
   1943 {
   1944     if (const ScrollView* parentScrollView = parent()) {
   1945         if (parentScrollView->isFrameView()) {
   1946             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
   1947             // Get our renderer in the parent view
   1948             RenderPart* renderer = m_frame->ownerRenderer();
   1949             if (!renderer)
   1950                 return localRect;
   1951 
   1952             IntRect rect(localRect);
   1953             // Add borders and padding??
   1954             rect.move(renderer->borderLeft() + renderer->paddingLeft(),
   1955                       renderer->borderTop() + renderer->paddingTop());
   1956             return parentView->convertFromRenderer(renderer, rect);
   1957         }
   1958 
   1959         return Widget::convertToContainingView(localRect);
   1960     }
   1961 
   1962     return localRect;
   1963 }
   1964 
   1965 IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
   1966 {
   1967     if (const ScrollView* parentScrollView = parent()) {
   1968         if (parentScrollView->isFrameView()) {
   1969             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
   1970 
   1971             // Get our renderer in the parent view
   1972             RenderPart* renderer = m_frame->ownerRenderer();
   1973             if (!renderer)
   1974                 return parentRect;
   1975 
   1976             IntRect rect = parentView->convertToRenderer(renderer, parentRect);
   1977             // Subtract borders and padding
   1978             rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
   1979                       -renderer->borderTop() - renderer->paddingTop());
   1980             return rect;
   1981         }
   1982 
   1983         return Widget::convertFromContainingView(parentRect);
   1984     }
   1985 
   1986     return parentRect;
   1987 }
   1988 
   1989 IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
   1990 {
   1991     if (const ScrollView* parentScrollView = parent()) {
   1992         if (parentScrollView->isFrameView()) {
   1993             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
   1994 
   1995             // Get our renderer in the parent view
   1996             RenderPart* renderer = m_frame->ownerRenderer();
   1997             if (!renderer)
   1998                 return localPoint;
   1999 
   2000             IntPoint point(localPoint);
   2001 
   2002             // Add borders and padding
   2003             point.move(renderer->borderLeft() + renderer->paddingLeft(),
   2004                        renderer->borderTop() + renderer->paddingTop());
   2005             return parentView->convertFromRenderer(renderer, point);
   2006         }
   2007 
   2008         return Widget::convertToContainingView(localPoint);
   2009     }
   2010 
   2011     return localPoint;
   2012 }
   2013 
   2014 IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
   2015 {
   2016     if (const ScrollView* parentScrollView = parent()) {
   2017         if (parentScrollView->isFrameView()) {
   2018             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
   2019 
   2020             // Get our renderer in the parent view
   2021             RenderPart* renderer = m_frame->ownerRenderer();
   2022             if (!renderer)
   2023                 return parentPoint;
   2024 
   2025             IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
   2026             // Subtract borders and padding
   2027             point.move(-renderer->borderLeft() - renderer->paddingLeft(),
   2028                        -renderer->borderTop() - renderer->paddingTop());
   2029             return point;
   2030         }
   2031 
   2032         return Widget::convertFromContainingView(parentPoint);
   2033     }
   2034 
   2035     return parentPoint;
   2036 }
   2037 
   2038 } // namespace WebCore
   2039