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