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