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