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