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