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