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