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