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