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