Source/WebCore: WebCore changes for: REGRESSION (WebKit2): Cursor, hover states not...
[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     frame()->eventHandler()->dispatchFakeMouseMoveEventSoon();
1739
1740 #if USE(ACCELERATED_COMPOSITING)
1741     if (RenderView* root = rootRenderer(this)) {
1742         if (root->usesCompositing())
1743             root->compositor()->frameViewDidScroll(scrollPosition());
1744     }
1745 #endif
1746 }
1747
1748 void FrameView::repaintFixedElementsAfterScrolling()
1749 {
1750     // For fixed position elements, update widget positions and compositing layers after scrolling,
1751     // but only if we're not inside of layout.
1752     if (!m_nestedLayoutCount && hasFixedObjects()) {
1753         if (RenderView* root = rootRenderer(this)) {
1754             root->updateWidgetPositions();
1755             root->layer()->updateLayerPositionsAfterScroll();
1756 #if USE(ACCELERATED_COMPOSITING)
1757             root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
1758 #endif
1759         }
1760     }
1761 }
1762
1763 bool FrameView::shouldRubberBandInDirection(ScrollDirection direction) const
1764 {
1765     Page* page = frame() ? frame()->page() : 0;
1766     if (!page)
1767         return ScrollView::shouldRubberBandInDirection(direction);
1768     return page->chrome()->client()->shouldRubberBandInDirection(direction);
1769 }
1770
1771 HostWindow* FrameView::hostWindow() const
1772 {
1773     Page* page = frame() ? frame()->page() : 0;
1774     if (!page)
1775         return 0;
1776     return page->chrome();
1777 }
1778
1779 const unsigned cRepaintRectUnionThreshold = 25;
1780
1781 void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
1782 {
1783     ASSERT(!m_frame->ownerElement());
1784     
1785     if (m_isTrackingRepaints) {
1786         IntRect repaintRect = r;
1787         repaintRect.move(-scrollOffset());
1788         m_trackedRepaintRects.append(repaintRect);
1789     }
1790
1791     double delay = m_deferringRepaints ? 0 : adjustedDeferredRepaintDelay();
1792     if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
1793         IntRect paintRect = r;
1794         if (clipsRepaints() && !paintsEntireContents())
1795             paintRect.intersect(visibleContentRect());
1796         if (paintRect.isEmpty())
1797             return;
1798         if (m_repaintCount == cRepaintRectUnionThreshold) {
1799             IntRect unionedRect;
1800             for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i)
1801                 unionedRect.unite(m_repaintRects[i]);
1802             m_repaintRects.clear();
1803             m_repaintRects.append(unionedRect);
1804         }
1805         if (m_repaintCount < cRepaintRectUnionThreshold)
1806             m_repaintRects.append(paintRect);
1807         else
1808             m_repaintRects[0].unite(paintRect);
1809         m_repaintCount++;
1810     
1811         if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive())
1812              m_deferredRepaintTimer.startOneShot(delay);
1813         return;
1814     }
1815     
1816     if (!shouldUpdate(immediate))
1817         return;
1818
1819 #if USE(TILED_BACKING_STORE)
1820     if (frame()->tiledBackingStore()) {
1821         frame()->tiledBackingStore()->invalidate(r);
1822         return;
1823     }
1824 #endif
1825     ScrollView::repaintContentRectangle(r, immediate);
1826 }
1827
1828 void FrameView::contentsResized()
1829 {
1830     ScrollView::contentsResized();
1831     setNeedsLayout();
1832 }
1833
1834 void FrameView::visibleContentsResized()
1835 {
1836     // We check to make sure the view is attached to a frame() as this method can
1837     // be triggered before the view is attached by Frame::createView(...) setting
1838     // various values such as setScrollBarModes(...) for example.  An ASSERT is
1839     // triggered when a view is layout before being attached to a frame().
1840     if (!frame()->view())
1841         return;
1842
1843     if (needsLayout())
1844         layout();
1845
1846 #if USE(ACCELERATED_COMPOSITING)
1847     if (RenderView* root = rootRenderer(this)) {
1848         if (root->usesCompositing())
1849             root->compositor()->frameViewDidChangeSize();
1850     }
1851 #endif
1852 }
1853
1854 void FrameView::beginDeferredRepaints()
1855 {
1856     Page* page = m_frame->page();
1857     if (page->mainFrame() != m_frame) {
1858         page->mainFrame()->view()->beginDeferredRepaints();
1859         return;
1860     }
1861
1862     m_deferringRepaints++;
1863 }
1864
1865
1866 void FrameView::endDeferredRepaints()
1867 {
1868     Page* page = m_frame->page();
1869     if (page->mainFrame() != m_frame) {
1870         page->mainFrame()->view()->endDeferredRepaints();
1871         return;
1872     }
1873
1874     ASSERT(m_deferringRepaints > 0);
1875
1876     if (--m_deferringRepaints)
1877         return;
1878     
1879     if (m_deferredRepaintTimer.isActive())
1880         return;
1881
1882     if (double delay = adjustedDeferredRepaintDelay()) {
1883         m_deferredRepaintTimer.startOneShot(delay);
1884         return;
1885     }
1886     
1887     doDeferredRepaints();
1888 }
1889
1890 void FrameView::checkStopDelayingDeferredRepaints()
1891 {
1892     if (!m_deferredRepaintTimer.isActive())
1893         return;
1894
1895     Document* document = m_frame->document();
1896     if (document && (document->parsing() || document->cachedResourceLoader()->requestCount()))
1897         return;
1898     
1899     m_deferredRepaintTimer.stop();
1900
1901     doDeferredRepaints();
1902 }
1903     
1904 void FrameView::doDeferredRepaints()
1905 {
1906     ASSERT(!m_deferringRepaints);
1907     if (!shouldUpdate()) {
1908         m_repaintRects.clear();
1909         m_repaintCount = 0;
1910         return;
1911     }
1912     unsigned size = m_repaintRects.size();
1913     for (unsigned i = 0; i < size; i++) {
1914 #if USE(TILED_BACKING_STORE)
1915         if (frame()->tiledBackingStore()) {
1916             frame()->tiledBackingStore()->invalidate(m_repaintRects[i]);
1917             continue;
1918         }
1919 #endif
1920         ScrollView::repaintContentRectangle(m_repaintRects[i], false);
1921     }
1922     m_repaintRects.clear();
1923     m_repaintCount = 0;
1924     
1925     updateDeferredRepaintDelay();
1926 }
1927
1928 void FrameView::updateDeferredRepaintDelay()
1929 {
1930     Document* document = m_frame->document();
1931     if (!document || (!document->parsing() && !document->cachedResourceLoader()->requestCount())) {
1932         m_deferredRepaintDelay = s_deferredRepaintDelay;
1933         return;
1934     }
1935     if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) {
1936         m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading;
1937         if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading)
1938             m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading;
1939     }
1940 }
1941
1942 void FrameView::resetDeferredRepaintDelay()
1943 {
1944     m_deferredRepaintDelay = 0;
1945     if (m_deferredRepaintTimer.isActive()) {
1946         m_deferredRepaintTimer.stop();
1947         if (!m_deferringRepaints)
1948             doDeferredRepaints();
1949     }
1950 }
1951
1952 double FrameView::adjustedDeferredRepaintDelay() const
1953 {
1954     ASSERT(!m_deferringRepaints);
1955     if (!m_deferredRepaintDelay)
1956         return 0;
1957     double timeSinceLastPaint = currentTime() - m_lastPaintTime;
1958     return max(0., m_deferredRepaintDelay - timeSinceLastPaint);
1959 }
1960     
1961 void FrameView::deferredRepaintTimerFired(Timer<FrameView>*)
1962 {
1963     doDeferredRepaints();
1964 }    
1965
1966 void FrameView::layoutTimerFired(Timer<FrameView>*)
1967 {
1968 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1969     if (!m_frame->document()->ownerElement())
1970         printf("Layout timer fired at %d\n", m_frame->document()->elapsedTime());
1971 #endif
1972     layout();
1973 }
1974
1975 void FrameView::scheduleRelayout()
1976 {
1977     // FIXME: We should assert the page is not in the page cache, but that is causing
1978     // too many false assertions.  See <rdar://problem/7218118>.
1979     ASSERT(m_frame->view() == this);
1980
1981     if (m_layoutRoot) {
1982         m_layoutRoot->markContainingBlocksForLayout(false);
1983         m_layoutRoot = 0;
1984     }
1985     if (!m_layoutSchedulingEnabled)
1986         return;
1987     if (!needsLayout())
1988         return;
1989     if (!m_frame->document()->shouldScheduleLayout())
1990         return;
1991
1992     // When frame flattening is enabled, the contents of the frame affects layout of the parent frames.
1993     // Also invalidate parent frame starting from the owner element of this frame.
1994     if (m_frame->settings() && m_frame->settings()->frameFlatteningEnabled() && m_frame->ownerRenderer()) {
1995         if (m_frame->ownerElement()->hasTagName(iframeTag) || m_frame->ownerElement()->hasTagName(frameTag))
1996             m_frame->ownerRenderer()->setNeedsLayout(true, true);
1997     }
1998
1999     int delay = m_frame->document()->minimumLayoutDelay();
2000     if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
2001         unscheduleRelayout();
2002     if (m_layoutTimer.isActive())
2003         return;
2004
2005     m_delayedLayout = delay != 0;
2006
2007 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2008     if (!m_frame->document()->ownerElement())
2009         printf("Scheduling layout for %d\n", delay);
2010 #endif
2011
2012     m_layoutTimer.startOneShot(delay * 0.001);
2013 }
2014
2015 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
2016 {
2017     for (RenderObject* r = descendant; r; r = r->container()) {
2018         if (r == ancestor)
2019             return true;
2020     }
2021     return false;
2022 }
2023
2024 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
2025 {
2026     ASSERT(m_frame->view() == this);
2027
2028     RenderView* root = rootRenderer(this);
2029     if (root && root->needsLayout()) {
2030         if (relayoutRoot)
2031             relayoutRoot->markContainingBlocksForLayout(false);
2032         return;
2033     }
2034
2035     if (layoutPending() || !m_layoutSchedulingEnabled) {
2036         if (m_layoutRoot != relayoutRoot) {
2037             if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) {
2038                 // Keep the current root
2039                 relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot);
2040                 ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
2041             } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) {
2042                 // Re-root at relayoutRoot
2043                 m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
2044                 m_layoutRoot = relayoutRoot;
2045                 ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
2046             } else {
2047                 // Just do a full relayout
2048                 if (m_layoutRoot)
2049                     m_layoutRoot->markContainingBlocksForLayout(false);
2050                 m_layoutRoot = 0;
2051                 relayoutRoot->markContainingBlocksForLayout(false);
2052             }
2053         }
2054     } else if (m_layoutSchedulingEnabled) {
2055         int delay = m_frame->document()->minimumLayoutDelay();
2056         m_layoutRoot = relayoutRoot;
2057         ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
2058         m_delayedLayout = delay != 0;
2059         m_layoutTimer.startOneShot(delay * 0.001);
2060     }
2061 }
2062
2063 bool FrameView::layoutPending() const
2064 {
2065     return m_layoutTimer.isActive();
2066 }
2067
2068 bool FrameView::needsLayout() const
2069 {
2070     // This can return true in cases where the document does not have a body yet.
2071     // Document::shouldScheduleLayout takes care of preventing us from scheduling
2072     // layout in that case.
2073     if (!m_frame)
2074         return false;
2075
2076     RenderView* root = rootRenderer(this);
2077     return layoutPending()
2078         || (root && root->needsLayout())
2079         || m_layoutRoot
2080         || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred);
2081 }
2082
2083 void FrameView::setNeedsLayout()
2084 {
2085     if (m_deferSetNeedsLayouts) {
2086         m_setNeedsLayoutWasDeferred = true;
2087         return;
2088     }
2089
2090     if (RenderView* root = rootRenderer(this))
2091         root->setNeedsLayout(true);
2092 }
2093
2094 void FrameView::unscheduleRelayout()
2095 {
2096     m_postLayoutTasksTimer.stop();
2097
2098     if (!m_layoutTimer.isActive())
2099         return;
2100
2101 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2102     if (!m_frame->document()->ownerElement())
2103         printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
2104 #endif
2105     
2106     m_layoutTimer.stop();
2107     m_delayedLayout = false;
2108 }
2109
2110 #if ENABLE(REQUEST_ANIMATION_FRAME)
2111 void FrameView::serviceScriptedAnimations(DOMTimeStamp time)
2112 {
2113     Vector<RefPtr<Document> > documents;
2114
2115     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext())
2116         documents.append(frame->document());
2117
2118     for (size_t i = 0; i < documents.size(); ++i)
2119         documents[i]->serviceScriptedAnimations(time);
2120 }
2121 #endif
2122
2123 bool FrameView::isTransparent() const
2124 {
2125     return m_isTransparent;
2126 }
2127
2128 void FrameView::setTransparent(bool isTransparent)
2129 {
2130     m_isTransparent = isTransparent;
2131 }
2132
2133 Color FrameView::baseBackgroundColor() const
2134 {
2135     return m_baseBackgroundColor;
2136 }
2137
2138 void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
2139 {
2140     if (!backgroundColor.isValid())
2141         m_baseBackgroundColor = Color::white;
2142     else
2143         m_baseBackgroundColor = backgroundColor;
2144
2145     recalculateScrollbarOverlayStyle();
2146 }
2147
2148 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
2149 {
2150     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
2151         if (FrameView* view = frame->view()) {
2152             view->setTransparent(transparent);
2153             view->setBaseBackgroundColor(backgroundColor);
2154         }
2155     }
2156 }
2157
2158 bool FrameView::shouldUpdateWhileOffscreen() const
2159 {
2160     return m_shouldUpdateWhileOffscreen;
2161 }
2162
2163 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
2164 {
2165     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
2166 }
2167
2168 bool FrameView::shouldUpdate(bool immediateRequested) const
2169 {
2170     if (!immediateRequested && isOffscreen() && !shouldUpdateWhileOffscreen())
2171         return false;
2172     return true;
2173 }
2174
2175 void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget)
2176 {
2177     m_actionScheduler->scheduleEvent(event, eventTarget);
2178 }
2179
2180 void FrameView::pauseScheduledEvents()
2181 {
2182     m_actionScheduler->pause();
2183 }
2184
2185 void FrameView::resumeScheduledEvents()
2186 {
2187     m_actionScheduler->resume();
2188 }
2189
2190 void FrameView::scrollToAnchor()
2191 {
2192     RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
2193     if (!anchorNode)
2194         return;
2195
2196     if (!anchorNode->renderer())
2197         return;
2198
2199     LayoutRect rect;
2200     if (anchorNode != m_frame->document())
2201         rect = anchorNode->getRect();
2202
2203     // Scroll nested layers and frames to reveal the anchor.
2204     // Align to the top and to the closest side (this matches other browsers).
2205     anchorNode->renderer()->enclosingLayer()->scrollRectToVisible(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
2206
2207     if (AXObjectCache::accessibilityEnabled())
2208         m_frame->document()->axObjectCache()->handleScrolledToAnchor(anchorNode.get());
2209
2210     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
2211     m_maintainScrollPositionAnchor = anchorNode;
2212 }
2213
2214 void FrameView::updateWidget(RenderEmbeddedObject* object)
2215 {
2216     ASSERT(!object->node() || object->node()->isElementNode());
2217     Element* ownerElement = static_cast<Element*>(object->node());
2218     // The object may have already been destroyed (thus node cleared),
2219     // but FrameView holds a manual ref, so it won't have been deleted.
2220     ASSERT(m_widgetUpdateSet->contains(object));
2221     if (!ownerElement)
2222         return;
2223
2224     // No need to update if it's already crashed or known to be missing.
2225     if (object->pluginCrashedOrWasMissing())
2226         return;
2227
2228     // FIXME: This could turn into a real virtual dispatch if we defined
2229     // updateWidget(PluginCreationOption) on HTMLElement.
2230     if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag)) {
2231         HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(ownerElement);
2232         if (pluginElement->needsWidgetUpdate())
2233             pluginElement->updateWidget(CreateAnyWidgetType);
2234     }
2235     // FIXME: It is not clear that Media elements need or want this updateWidget() call.
2236 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
2237     else if (ownerElement->isMediaElement())
2238         static_cast<HTMLMediaElement*>(ownerElement)->updateWidget(CreateAnyWidgetType);
2239 #endif
2240     else
2241         ASSERT_NOT_REACHED();
2242
2243     // Caution: it's possible the object was destroyed again, since loading a
2244     // plugin may run any arbitrary javascript.
2245     object->updateWidgetPosition();
2246 }
2247
2248 bool FrameView::updateWidgets()
2249 {
2250     if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
2251         return true;
2252     
2253     size_t size = m_widgetUpdateSet->size();
2254
2255     Vector<RenderEmbeddedObject*> objects;
2256     objects.reserveCapacity(size);
2257
2258     RenderEmbeddedObjectSet::const_iterator end = m_widgetUpdateSet->end();
2259     for (RenderEmbeddedObjectSet::const_iterator it = m_widgetUpdateSet->begin(); it != end; ++it) {
2260         objects.uncheckedAppend(*it);
2261         (*it)->ref();
2262     }
2263
2264     for (size_t i = 0; i < size; ++i) {
2265         RenderEmbeddedObject* object = objects[i];
2266         updateWidget(object);
2267         m_widgetUpdateSet->remove(object);
2268     }
2269
2270     RenderArena* arena = m_frame->document()->renderArena();
2271     for (size_t i = 0; i < size; ++i)
2272         objects[i]->deref(arena);
2273     
2274     return m_widgetUpdateSet->isEmpty();
2275 }
2276
2277 void FrameView::flushAnyPendingPostLayoutTasks()
2278 {
2279     if (!m_hasPendingPostLayoutTasks)
2280         return;
2281
2282     m_postLayoutTasksTimer.stop();
2283     performPostLayoutTasks();
2284 }
2285
2286 void FrameView::performPostLayoutTasks()
2287 {
2288     m_hasPendingPostLayoutTasks = false;
2289
2290     m_frame->selection()->setCaretRectNeedsUpdate();
2291     m_frame->selection()->updateAppearance();
2292
2293     if (m_nestedLayoutCount <= 1) {
2294         if (m_firstLayoutCallbackPending) {
2295             m_firstLayoutCallbackPending = false;
2296             m_frame->loader()->didFirstLayout();
2297         }
2298
2299         // Ensure that we always send this eventually.
2300         if (!m_frame->document()->parsing() && m_frame->loader()->stateMachine()->committedFirstRealDocumentLoad())
2301             m_isVisuallyNonEmpty = true;
2302
2303         // If the layout was done with pending sheets, we are not in fact visually non-empty yet.
2304         if (m_isVisuallyNonEmpty && !m_frame->document()->didLayoutWithPendingStylesheets() && m_firstVisuallyNonEmptyLayoutCallbackPending) {
2305             m_firstVisuallyNonEmptyLayoutCallbackPending = false;
2306             m_frame->loader()->didFirstVisuallyNonEmptyLayout();
2307         }
2308     }
2309
2310     m_frame->loader()->client()->dispatchDidLayout();
2311
2312     RenderView* root = rootRenderer(this);
2313     root->updateWidgetPositions();
2314     
2315     for (unsigned i = 0; i < maxUpdateWidgetsIterations; i++) {
2316         if (updateWidgets())
2317             break;
2318     }
2319
2320     scrollToAnchor();
2321
2322     m_actionScheduler->resume();
2323
2324     if (!root->printing()) {
2325         LayoutSize currentSize = LayoutSize(width(), height());
2326         float currentZoomFactor = root->style()->zoom();
2327         bool resized = !m_firstLayout && (currentSize != m_lastLayoutSize || currentZoomFactor != m_lastZoomFactor);
2328         m_lastLayoutSize = currentSize;
2329         m_lastZoomFactor = currentZoomFactor;
2330         if (resized)
2331             m_frame->eventHandler()->sendResizeEvent();
2332     }
2333 }
2334
2335 void FrameView::postLayoutTimerFired(Timer<FrameView>*)
2336 {
2337     performPostLayoutTasks();
2338 }
2339
2340 void FrameView::autoSizeIfEnabled()
2341 {
2342     if (!m_shouldAutoSize)
2343         return;
2344
2345     if (m_inAutoSize)
2346         return;
2347
2348     TemporaryChange<bool> changeInAutoSize(m_inAutoSize, true);
2349
2350     Document* document = frame()->document();
2351     if (!document)
2352         return;
2353
2354     RenderView* documentView = document->renderView();
2355     Element* documentElement = document->documentElement();
2356     if (!documentView || !documentElement)
2357         return;
2358
2359     RenderBox* documentRenderBox = documentElement->renderBox();
2360     if (!documentRenderBox)
2361         return;
2362
2363     // Do the resizing twice. The first time is basically a rough calculation using the preferred width
2364     // which may result in a height change during the second iteration.
2365     for (int i = 0; i < 2; i++) {
2366         // Update various sizes including contentsSize, scrollHeight, etc.
2367         document->updateLayoutIgnorePendingStylesheets();
2368         IntSize size = frameRect().size();
2369         int width = documentView->minPreferredLogicalWidth();
2370         int height = documentRenderBox->scrollHeight();
2371         IntSize newSize(width, height);
2372
2373         // Ensure the size is at least the min bounds.
2374         newSize = newSize.expandedTo(m_minAutoSize);
2375
2376         // Check to see if a scrollbar is needed for a given dimension and
2377         // if so, increase the other dimension to account for the scrollbar.
2378         // Since the dimensions are only for the view rectangle, once a
2379         // dimension exceeds the maximum, there is no need to increase it further.
2380         if (newSize.width() > m_maxAutoSize.width()) {
2381             RefPtr<Scrollbar> localHorizontalScrollbar = horizontalScrollbar();
2382             if (!localHorizontalScrollbar)
2383                 localHorizontalScrollbar = createScrollbar(HorizontalScrollbar);
2384             if (!localHorizontalScrollbar->isOverlayScrollbar())
2385                 newSize.setHeight(newSize.height() + localHorizontalScrollbar->height());
2386
2387             // Don't bother checking for a vertical scrollbar because the width is at
2388             // already greater the maximum.
2389         } else if (newSize.height() > m_maxAutoSize.height()) {
2390             RefPtr<Scrollbar> localVerticalScrollbar = verticalScrollbar();
2391             if (!localVerticalScrollbar)
2392                 localVerticalScrollbar = createScrollbar(VerticalScrollbar);
2393             if (!localVerticalScrollbar->isOverlayScrollbar())
2394                 newSize.setWidth(newSize.width() + localVerticalScrollbar->width());
2395
2396             // Don't bother checking for a horizontal scrollbar because the height is
2397             // already greater the maximum.
2398         }
2399
2400         // Bound the dimensions by the max bounds and determine what scrollbars to show.
2401         ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff;
2402         if (newSize.width() > m_maxAutoSize.width()) {
2403             newSize.setWidth(m_maxAutoSize.width());
2404             horizonalScrollbarMode = ScrollbarAlwaysOn;
2405         }
2406         ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff;
2407         if (newSize.height() > m_maxAutoSize.height()) {
2408             newSize.setHeight(m_maxAutoSize.height());
2409             verticalScrollbarMode = ScrollbarAlwaysOn;
2410         }
2411
2412         if (newSize == size)
2413             continue;
2414
2415         // Avoid doing resizing to a smaller size while the frame is loading to avoid switching to a small size
2416         // during an intermediate state (and then changing back to a bigger size as the load progresses).
2417         if (!frame()->loader()->isComplete() && (newSize.height() < size.height() || newSize.width() < size.width()))
2418             break;
2419         resize(newSize.width(), newSize.height());
2420         // Force the scrollbar state to avoid the scrollbar code adding them and causing them to be needed. For example,
2421         // a vertical scrollbar may cause text to wrap and thus increase the height (which is the only reason the scollbar is needed).
2422         setVerticalScrollbarLock(false);
2423         setHorizontalScrollbarLock(false);
2424         setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true);
2425     }
2426 }
2427
2428 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
2429 {
2430     if (!m_viewportRenderer)
2431         return;
2432     
2433     if (m_overflowStatusDirty) {
2434         m_horizontalOverflow = horizontalOverflow;
2435         m_verticalOverflow = verticalOverflow;
2436         m_overflowStatusDirty = false;
2437         return;
2438     }
2439     
2440     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
2441     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
2442     
2443     if (horizontalOverflowChanged || verticalOverflowChanged) {
2444         m_horizontalOverflow = horizontalOverflow;
2445         m_verticalOverflow = verticalOverflow;
2446         
2447         m_actionScheduler->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
2448             verticalOverflowChanged, verticalOverflow),
2449             m_viewportRenderer->node());
2450     }
2451     
2452 }
2453
2454 IntRect FrameView::windowClipRect(bool clipToContents) const
2455 {
2456     ASSERT(m_frame->view() == this);
2457
2458     if (paintsEntireContents())
2459         return IntRect(IntPoint(), contentsSize());
2460
2461     // Set our clip rect to be our contents.
2462     IntRect clipRect = contentsToWindow(visibleContentRect(!clipToContents));
2463     if (!m_frame || !m_frame->ownerElement())
2464         return clipRect;
2465
2466     // Take our owner element and get the clip rect from the enclosing layer.
2467     Element* elt = m_frame->ownerElement();
2468     // The renderer can sometimes be null when style="display:none" interacts
2469     // with external content and plugins.
2470     RenderLayer* layer = elt->renderer() ? elt->renderer()->enclosingLayer() : 0;
2471     if (!layer)
2472         return clipRect;
2473     FrameView* parentView = elt->document()->view();
2474     clipRect.intersect(parentView->windowClipRectForLayer(layer, true));
2475     return clipRect;
2476 }
2477
2478 IntRect FrameView::windowClipRectForLayer(const RenderLayer* layer, bool clipToLayerContents) const
2479 {
2480     // If we have no layer, just return our window clip rect.
2481     if (!layer)
2482         return windowClipRect();
2483
2484     // Apply the clip from the layer.
2485     IntRect clipRect;
2486     if (clipToLayerContents)
2487         clipRect = layer->childrenClipRect();
2488     else
2489         clipRect = layer->selfClipRect();
2490     clipRect = contentsToWindow(clipRect); 
2491     return intersection(clipRect, windowClipRect());
2492 }
2493
2494 bool FrameView::isActive() const
2495 {
2496     Page* page = frame()->page();
2497     return page && page->focusController()->isActive();
2498 }
2499
2500 void FrameView::scrollTo(const IntSize& newOffset)
2501 {
2502     LayoutSize offset = scrollOffset();
2503     ScrollView::scrollTo(newOffset);
2504     if (offset != scrollOffset())
2505         scrollPositionChanged();
2506     frame()->loader()->client()->didChangeScrollOffset();
2507 }
2508
2509 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
2510 {
2511     // Add in our offset within the FrameView.
2512     IntRect dirtyRect = rect;
2513     dirtyRect.moveBy(scrollbar->location());
2514     invalidateRect(dirtyRect);
2515 }
2516
2517 void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
2518 {
2519     tickmarks = frame()->document()->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch);
2520 }
2521
2522 IntRect FrameView::windowResizerRect() const
2523 {
2524     Page* page = frame() ? frame()->page() : 0;
2525     if (!page)
2526         return IntRect();
2527     return page->chrome()->windowResizerRect();
2528 }
2529
2530 void FrameView::setVisibleScrollerThumbRect(const IntRect& scrollerThumb)
2531 {
2532     Page* page = m_frame->page();
2533     if (!page)
2534         return;
2535     if (page->mainFrame() != m_frame)
2536         return;
2537     page->chrome()->client()->notifyScrollerThumbIsVisibleInRect(scrollerThumb);
2538 }
2539
2540 bool FrameView::isOnActivePage() const
2541 {
2542     if (!m_frame)
2543         return false;
2544     if (m_frame->view() != this)
2545         return false;
2546     if (Document* document = m_frame->document())
2547         return !document->inPageCache();
2548     return false;
2549 }
2550
2551 ScrollableArea* FrameView::enclosingScrollableArea() const
2552 {
2553     // FIXME: Walk up the frame tree and look for a scrollable parent frame or RenderLayer.
2554     return 0;
2555 }
2556
2557 bool FrameView::shouldSuspendScrollAnimations() const
2558 {
2559     return m_frame->loader()->state() != FrameStateComplete;
2560 }
2561
2562 void FrameView::scrollbarStyleChanged(int newStyle, bool forceUpdate)
2563 {
2564     Page* page = m_frame->page();
2565     if (!page)
2566         return;
2567     if (page->mainFrame() != m_frame)
2568         return;
2569     page->chrome()->client()->recommendedScrollbarStyleDidChange(newStyle);
2570
2571     if (forceUpdate)
2572         ScrollView::scrollbarStyleChanged(newStyle, forceUpdate);
2573 }
2574
2575 void FrameView::setAnimatorsAreActive()
2576 {
2577     Page* page = m_frame->page();
2578     if (!page)
2579         return;
2580
2581     const HashSet<ScrollableArea*>* scrollableAreas = page->scrollableAreaSet();
2582     if (!scrollableAreas)
2583         return;
2584
2585     HashSet<ScrollableArea*>::const_iterator end = scrollableAreas->end(); 
2586     for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(); it != end; ++it) {
2587         // FIXME: This extra check to make sure the ScrollableArea is on an active page needs 
2588         // to be here as long as the ScrollableArea HashSet lives on Page. But it should really be
2589         // moved to the top-level Document or a similar class that really represents a single 
2590         // web page. https://bugs.webkit.org/show_bug.cgi?id=62762
2591         if ((*it)->isOnActivePage())
2592             (*it)->scrollAnimator()->setIsActive();
2593     }
2594 }
2595
2596 void FrameView::notifyPageThatContentAreaWillPaint() const
2597 {
2598     Page* page = m_frame->page();
2599     const HashSet<ScrollableArea*>* scrollableAreas = page->scrollableAreaSet();
2600     if (!scrollableAreas)
2601         return;
2602
2603     HashSet<ScrollableArea*>::const_iterator end = scrollableAreas->end(); 
2604     for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(); it != end; ++it)
2605         (*it)->contentAreaWillPaint();
2606 }
2607
2608 bool FrameView::scrollAnimatorEnabled() const
2609 {
2610 #if ENABLE(SMOOTH_SCROLLING)
2611     if (m_page && m_page->settings())
2612         return m_page->settings()->scrollAnimatorEnabled();
2613 #endif
2614     return false;
2615 }
2616
2617 #if ENABLE(DASHBOARD_SUPPORT)
2618 void FrameView::updateDashboardRegions()
2619 {
2620     Document* document = m_frame->document();
2621     if (!document->hasDashboardRegions())
2622         return;
2623     Vector<DashboardRegionValue> newRegions;
2624     document->renderBox()->collectDashboardRegions(newRegions);
2625     if (newRegions == document->dashboardRegions())
2626         return;
2627     document->setDashboardRegions(newRegions);
2628     Page* page = m_frame->page();
2629     if (!page)
2630         return;
2631     page->chrome()->client()->dashboardRegionsChanged();
2632 }
2633 #endif
2634
2635 void FrameView::updateScrollCorner()
2636 {
2637     RenderObject* renderer = 0;
2638     RefPtr<RenderStyle> cornerStyle;
2639     IntRect cornerRect = scrollCornerRect();
2640     
2641     if (!cornerRect.isEmpty()) {
2642         // Try the <body> element first as a scroll corner source.
2643         Document* doc = m_frame->document();
2644         Element* body = doc ? doc->body() : 0;
2645         if (body && body->renderer()) {
2646             renderer = body->renderer();
2647             cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
2648         }
2649         
2650         if (!cornerStyle) {
2651             // If the <body> didn't have a custom style, then the root element might.
2652             Element* docElement = doc ? doc->documentElement() : 0;
2653             if (docElement && docElement->renderer()) {
2654                 renderer = docElement->renderer();
2655                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
2656             }
2657         }
2658         
2659         if (!cornerStyle) {
2660             // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
2661             if (RenderPart* renderer = m_frame->ownerRenderer())
2662                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
2663         }
2664     }
2665
2666     if (cornerStyle) {
2667         if (!m_scrollCorner)
2668             m_scrollCorner = new (renderer->renderArena()) RenderScrollbarPart(renderer->document());
2669         m_scrollCorner->setStyle(cornerStyle.release());
2670         invalidateScrollCorner(cornerRect);
2671     } else if (m_scrollCorner) {
2672         m_scrollCorner->destroy();
2673         m_scrollCorner = 0;
2674     }
2675
2676     ScrollView::updateScrollCorner();
2677 }
2678
2679 void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
2680 {
2681     if (context->updatingControlTints()) {
2682         updateScrollCorner();
2683         return;
2684     }
2685
2686     if (m_scrollCorner) {
2687         m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect);
2688         return;
2689     }
2690
2691     ScrollView::paintScrollCorner(context, cornerRect);
2692 }
2693
2694 Color FrameView::documentBackgroundColor() const
2695 {
2696     // <https://bugs.webkit.org/show_bug.cgi?id=59540> We blend the background color of
2697     // the document and the body against the base background color of the frame view.
2698     // Background images are unfortunately impractical to include.
2699
2700     // Return invalid Color objects whenever there is insufficient information.
2701     if (!frame()->document())
2702         return Color();
2703
2704     Element* htmlElement = frame()->document()->documentElement();
2705     Element* bodyElement = frame()->document()->body();
2706
2707     // Start with invalid colors.
2708     Color htmlBackgroundColor;
2709     Color bodyBackgroundColor;
2710     if (htmlElement && htmlElement->renderer())
2711         htmlBackgroundColor = htmlElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor);
2712     if (bodyElement && bodyElement->renderer())
2713         bodyBackgroundColor = bodyElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor);
2714
2715     if (!bodyBackgroundColor.isValid()) {
2716         if (!htmlBackgroundColor.isValid())
2717             return Color();
2718         return baseBackgroundColor().blend(htmlBackgroundColor);
2719     }
2720
2721     if (!htmlBackgroundColor.isValid())
2722         return baseBackgroundColor().blend(bodyBackgroundColor);
2723
2724     // We take the aggregate of the base background color
2725     // the <html> background color, and the <body>
2726     // background color to find the document color. The
2727     // addition of the base background color is not
2728     // technically part of the document background, but it
2729     // otherwise poses problems when the aggregate is not
2730     // fully opaque.
2731     return baseBackgroundColor().blend(htmlBackgroundColor).blend(bodyBackgroundColor);
2732 }
2733
2734 bool FrameView::hasCustomScrollbars() const
2735 {
2736     const HashSet<RefPtr<Widget> >* viewChildren = children();
2737     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
2738     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
2739         Widget* widget = current->get();
2740         if (widget->isFrameView()) {
2741             if (static_cast<FrameView*>(widget)->hasCustomScrollbars())
2742                 return true;
2743         } else if (widget->isScrollbar()) {
2744             Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
2745             if (scrollbar->isCustomScrollbar())
2746                 return true;
2747         }
2748     }
2749
2750     return false;
2751 }
2752
2753 void FrameView::clearOwningRendererForCustomScrollbars(RenderBox* box)
2754 {
2755     const HashSet<RefPtr<Widget> >* viewChildren = children();
2756     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
2757     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
2758         Widget* widget = current->get();
2759         if (widget->isScrollbar()) {
2760             Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
2761             if (scrollbar->isCustomScrollbar()) {
2762                 RenderScrollbar* customScrollbar = toRenderScrollbar(scrollbar);
2763                 if (customScrollbar->owningRenderer() == box)
2764                     customScrollbar->clearOwningRenderer();
2765             }
2766         }
2767     }
2768 }
2769
2770 FrameView* FrameView::parentFrameView() const
2771 {
2772     if (Widget* parentView = parent()) {
2773         if (parentView->isFrameView())
2774             return static_cast<FrameView*>(parentView);
2775     }
2776     return 0;
2777 }
2778
2779 void FrameView::updateControlTints()
2780 {
2781     // This is called when control tints are changed from aqua/graphite to clear and vice versa.
2782     // We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
2783     // This is only done if the theme supports control tinting. It's up to the theme and platform
2784     // to define when controls get the tint and to call this function when that changes.
2785     
2786     // Optimize the common case where we bring a window to the front while it's still empty.
2787     if (!m_frame || m_frame->document()->url().isEmpty())
2788         return;
2789
2790     RenderView* root = rootRenderer(this);
2791     if ((root && root->theme()->supportsControlTints()) || hasCustomScrollbars())
2792         paintControlTints();
2793 }
2794
2795 void FrameView::paintControlTints()
2796 {
2797     if (needsLayout())
2798         layout();
2799     PlatformGraphicsContext* const noContext = 0;
2800     GraphicsContext context(noContext);
2801     context.setUpdatingControlTints(true);
2802     if (platformWidget())
2803         paintContents(&context, visibleContentRect());
2804     else
2805         paint(&context, frameRect());
2806 }
2807
2808 bool FrameView::wasScrolledByUser() const
2809 {
2810     return m_wasScrolledByUser;
2811 }
2812
2813 void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
2814 {
2815     if (m_inProgrammaticScroll)
2816         return;
2817     m_maintainScrollPositionAnchor = 0;
2818     m_wasScrolledByUser = wasScrolledByUser;
2819 }
2820
2821 void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
2822 {
2823     if (!frame())
2824         return;
2825
2826     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_frame.get(), rect);
2827
2828     Document* document = m_frame->document();
2829
2830 #ifndef NDEBUG
2831     bool fillWithRed;
2832     if (document->printing())
2833         fillWithRed = false; // Printing, don't fill with red (can't remember why).
2834     else if (m_frame->ownerElement())
2835         fillWithRed = false; // Subframe, don't fill with red.
2836     else if (isTransparent())
2837         fillWithRed = false; // Transparent, don't fill with red.
2838     else if (m_paintBehavior & PaintBehaviorSelectionOnly)
2839         fillWithRed = false; // Selections are transparent, don't fill with red.
2840     else if (m_nodeToDraw)
2841         fillWithRed = false; // Element images are transparent, don't fill with red.
2842     else
2843         fillWithRed = true;
2844     
2845     if (fillWithRed)
2846         p->fillRect(rect, Color(0xFF, 0, 0), ColorSpaceDeviceRGB);
2847 #endif
2848
2849     bool isTopLevelPainter = !sCurrentPaintTimeStamp;
2850     if (isTopLevelPainter)
2851         sCurrentPaintTimeStamp = currentTime();
2852     
2853     RenderView* root = rootRenderer(this);
2854     if (!root) {
2855         LOG_ERROR("called FrameView::paint with nil renderer");
2856         return;
2857     }
2858
2859     ASSERT(!needsLayout());
2860     if (needsLayout())
2861         return;
2862
2863     FontCachePurgePreventer fontCachePurgePreventer;
2864
2865 #if USE(ACCELERATED_COMPOSITING)
2866     if (!p->paintingDisabled())
2867         syncCompositingStateForThisFrame(m_frame.get());
2868 #endif
2869
2870     PaintBehavior oldPaintBehavior = m_paintBehavior;
2871     
2872     if (FrameView* parentView = parentFrameView()) {
2873         if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers)
2874             m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
2875     }
2876     
2877     if (m_paintBehavior == PaintBehaviorNormal)
2878         document->markers()->invalidateRenderedRectsForMarkersInRect(rect);
2879
2880     if (document->printing())
2881         m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
2882
2883     bool flatteningPaint = m_paintBehavior & PaintBehaviorFlattenCompositingLayers;
2884     bool isRootFrame = !m_frame->ownerElement();
2885     if (flatteningPaint && isRootFrame)
2886         notifyWidgetsInAllFrames(WillPaintFlattened);
2887
2888     ASSERT(!m_isPainting);
2889     m_isPainting = true;
2890
2891     // m_nodeToDraw is used to draw only one element (and its descendants)
2892     RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
2893     RenderLayer* rootLayer = root->layer();
2894
2895     rootLayer->paint(p, rect, m_paintBehavior, eltRenderer);
2896
2897     if (rootLayer->containsDirtyOverlayScrollbars())
2898         rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, eltRenderer);
2899
2900     m_isPainting = false;
2901
2902     if (flatteningPaint && isRootFrame)
2903         notifyWidgetsInAllFrames(DidPaintFlattened);
2904
2905     m_paintBehavior = oldPaintBehavior;
2906     m_lastPaintTime = currentTime();
2907
2908 #if ENABLE(DASHBOARD_SUPPORT)
2909     // Regions may have changed as a result of the visibility/z-index of element changing.
2910     if (document->dashboardRegionsDirty())
2911         updateDashboardRegions();
2912 #endif
2913
2914     if (isTopLevelPainter)
2915         sCurrentPaintTimeStamp = 0;
2916
2917     InspectorInstrumentation::didPaint(cookie);
2918 }
2919
2920 void FrameView::setPaintBehavior(PaintBehavior behavior)
2921 {
2922     m_paintBehavior = behavior;
2923 }
2924
2925 PaintBehavior FrameView::paintBehavior() const
2926 {
2927     return m_paintBehavior;
2928 }
2929
2930 bool FrameView::isPainting() const
2931 {
2932     return m_isPainting;
2933 }
2934
2935 void FrameView::setNodeToDraw(Node* node)
2936 {
2937     m_nodeToDraw = node;
2938 }
2939
2940 void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
2941 {
2942     if (context->paintingDisabled())
2943         return;
2944
2945     if (m_frame->document()->printing())
2946         return;
2947
2948     Page* page = m_frame->page();
2949     if (page->mainFrame() == m_frame) {
2950         if (page->chrome()->client()->paintCustomOverhangArea(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect))
2951             return;
2952     }
2953
2954     ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
2955 }
2956
2957 void FrameView::updateLayoutAndStyleIfNeededRecursive()
2958 {
2959     // We have to crawl our entire tree looking for any FrameViews that need
2960     // layout and make sure they are up to date.
2961     // Mac actually tests for intersection with the dirty region and tries not to
2962     // update layout for frames that are outside the dirty region.  Not only does this seem
2963     // pointless (since those frames will have set a zero timer to layout anyway), but
2964     // it is also incorrect, since if two frames overlap, the first could be excluded from the dirty
2965     // region but then become included later by the second frame adding rects to the dirty region
2966     // when it lays out.
2967
2968     m_frame->document()->updateStyleIfNeeded();
2969
2970     if (needsLayout())
2971         layout();
2972
2973     // Grab a copy of the children() set, as it may be mutated by the following updateLayoutAndStyleIfNeededRecursive
2974     // calls, as they can potentially re-enter a layout of the parent frame view, which may add/remove scrollbars
2975     // and thus mutates the children() set.
2976     Vector<RefPtr<FrameView> > frameViews;
2977     collectFrameViewChildren(this, frameViews);
2978
2979     const Vector<RefPtr<FrameView> >::iterator end = frameViews.end();
2980     for (Vector<RefPtr<FrameView> >::iterator it = frameViews.begin(); it != end; ++it)
2981         (*it)->updateLayoutAndStyleIfNeededRecursive();
2982
2983     // updateLayoutAndStyleIfNeededRecursive is called when we need to make sure style and layout are up-to-date before
2984     // painting, so we need to flush out any deferred repaints too.
2985     flushDeferredRepaints();
2986 }
2987     
2988 void FrameView::flushDeferredRepaints()
2989 {
2990     if (!m_deferredRepaintTimer.isActive())
2991         return;
2992     m_deferredRepaintTimer.stop();
2993     doDeferredRepaints();
2994 }
2995
2996 void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize)
2997 {
2998     ASSERT(!enable || !minSize.isEmpty());
2999     ASSERT(minSize.width() <= maxSize.width());
3000     ASSERT(minSize.height() <= maxSize.height());
3001
3002     if (m_shouldAutoSize == enable && m_minAutoSize == minSize && m_maxAutoSize == maxSize)
3003         return;
3004
3005     m_shouldAutoSize = enable;
3006     m_minAutoSize = minSize;
3007     m_maxAutoSize = maxSize;
3008
3009     if (!m_shouldAutoSize)
3010         return;
3011
3012     setNeedsLayout();
3013     scheduleRelayout();
3014 }
3015
3016 void FrameView::forceLayout(bool allowSubtree)
3017 {
3018     layout(allowSubtree);
3019 }
3020
3021 void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor, AdjustViewSizeOrNot shouldAdjustViewSize)
3022 {
3023     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
3024     // the state of things before and after the layout
3025     if (RenderView* root = rootRenderer(this)) {
3026         float pageLogicalWidth = root->style()->isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
3027         float pageLogicalHeight = root->style()->isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
3028
3029         LayoutUnit flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
3030         LayoutUnit flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
3031         root->setLogicalWidth(flooredPageLogicalWidth);
3032         root->setPageLogicalHeight(flooredPageLogicalHeight);
3033         root->setNeedsLayoutAndPrefWidthsRecalc();
3034         forceLayout();
3035
3036         // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
3037         // page width when shrunk, we will lay out at maximum shrink and clip extra content.
3038         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
3039         // implementation should not do this!
3040         bool horizontalWritingMode = root->style()->isHorizontalWritingMode();
3041         const LayoutRect& documentRect = root->documentRect();
3042         LayoutUnit docLogicalWidth = horizontalWritingMode ? documentRect.width() : documentRect.height();
3043         if (docLogicalWidth > pageLogicalWidth) {
3044             int expectedPageWidth = std::min<float>(documentRect.width(), pageSize.width() * maximumShrinkFactor);
3045             int expectedPageHeight = std::min<float>(documentRect.height(), pageSize.height() * maximumShrinkFactor);
3046             FloatSize maxPageSize = m_frame->resizePageRectsKeepingRatio(FloatSize(originalPageSize.width(), originalPageSize.height()), FloatSize(expectedPageWidth, expectedPageHeight));
3047             pageLogicalWidth = horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
3048             pageLogicalHeight = horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();
3049
3050             flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
3051             flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
3052             root->setLogicalWidth(flooredPageLogicalWidth);
3053             root->setPageLogicalHeight(flooredPageLogicalHeight);
3054             root->setNeedsLayoutAndPrefWidthsRecalc();
3055             forceLayout();
3056
3057             const LayoutRect& updatedDocumentRect = root->documentRect();
3058             LayoutUnit docLogicalHeight = horizontalWritingMode ? updatedDocumentRect.height() : updatedDocumentRect.width();
3059             LayoutUnit docLogicalTop = horizontalWritingMode ? updatedDocumentRect.y() : updatedDocumentRect.x();
3060             LayoutUnit docLogicalRight = horizontalWritingMode ? updatedDocumentRect.maxX() : updatedDocumentRect.maxY();
3061             LayoutUnit clippedLogicalLeft = 0;
3062             if (!root->style()->isLeftToRightDirection())
3063                 clippedLogicalLeft = docLogicalRight - pageLogicalWidth;
3064             LayoutRect overflow(clippedLogicalLeft, docLogicalTop, pageLogicalWidth, docLogicalHeight);
3065
3066             if (!horizontalWritingMode)
3067                 overflow = overflow.transposedRect();
3068             root->clearLayoutOverflow();
3069             root->addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
3070         }
3071     }
3072
3073     if (shouldAdjustViewSize)
3074         adjustViewSize();
3075 }
3076
3077 void FrameView::adjustPageHeightDeprecated(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
3078 {
3079     if (RenderView* root = rootRenderer(this)) {
3080         // Use a context with painting disabled.
3081         GraphicsContext context((PlatformGraphicsContext*)0);
3082         root->setTruncatedAt((int)floorf(oldBottom));
3083         IntRect dirtyRect(0, (int)floorf(oldTop), root->maxXLayoutOverflow(), (int)ceilf(oldBottom - oldTop));
3084         root->setPrintRect(dirtyRect);
3085         root->layer()->paint(&context, dirtyRect);
3086         *newBottom = root->bestTruncatedAt();
3087         if (*newBottom == 0)
3088             *newBottom = oldBottom;
3089         root->setPrintRect(IntRect());
3090     } else
3091         *newBottom = oldBottom;
3092 }
3093
3094 IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
3095 {
3096     IntRect rect = renderer->localToAbsoluteQuad(FloatRect(rendererRect)).enclosingBoundingBox();
3097
3098     // Convert from page ("absolute") to FrameView coordinates.
3099     rect.moveBy(-scrollPosition());
3100
3101     return rect;
3102 }
3103
3104 IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect& viewRect) const
3105 {
3106     IntRect rect = viewRect;
3107     
3108     // Convert from FrameView coords into page ("absolute") coordinates.
3109     rect.moveBy(scrollPosition());
3110
3111     // FIXME: we don't have a way to map an absolute rect down to a local quad, so just
3112     // move the rect for now.
3113     rect.setLocation(roundedIntPoint(renderer->absoluteToLocal(rect.location(), false, true /* use transforms */)));
3114     return rect;
3115 }
3116
3117 IntPoint FrameView::convertFromRenderer(const RenderObject* renderer, const IntPoint& rendererPoint) const
3118 {
3119     IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, false, true /* use transforms */));
3120
3121     // Convert from page ("absolute") to FrameView coordinates.
3122     point.moveBy(-scrollPosition());
3123     return point;
3124 }
3125
3126 IntPoint FrameView::convertToRenderer(const RenderObject* renderer, const IntPoint& viewPoint) const
3127 {
3128     IntPoint point = viewPoint;
3129     
3130     // Convert from FrameView coords into page ("absolute") coordinates.
3131     point += IntSize(scrollX(), scrollY());
3132
3133     return roundedIntPoint(renderer->absoluteToLocal(point, false, true /* use transforms */));
3134 }
3135
3136 IntRect FrameView::convertToContainingView(const IntRect& localRect) const
3137 {
3138     if (const ScrollView* parentScrollView = parent()) {
3139         if (parentScrollView->isFrameView()) {
3140             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
3141             // Get our renderer in the parent view
3142             RenderPart* renderer = m_frame->ownerRenderer();
3143             if (!renderer)
3144                 return localRect;
3145                 
3146             IntRect rect(localRect);
3147             // Add borders and padding??
3148             rect.move(renderer->borderLeft() + renderer->paddingLeft(),
3149                       renderer->borderTop() + renderer->paddingTop());
3150             return parentView->convertFromRenderer(renderer, rect);
3151         }
3152         
3153         return Widget::convertToContainingView(localRect);
3154     }
3155     
3156     return localRect;
3157 }
3158
3159 IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
3160 {
3161     if (const ScrollView* parentScrollView = parent()) {
3162         if (parentScrollView->isFrameView()) {
3163             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
3164
3165             // Get our renderer in the parent view
3166             RenderPart* renderer = m_frame->ownerRenderer();
3167             if (!renderer)
3168                 return parentRect;
3169
3170             IntRect rect = parentView->convertToRenderer(renderer, parentRect);
3171             // Subtract borders and padding
3172             rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
3173                       -renderer->borderTop() - renderer->paddingTop());
3174             return rect;
3175         }
3176         
3177         return Widget::convertFromContainingView(parentRect);
3178     }
3179     
3180     return parentRect;
3181 }
3182
3183 IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
3184 {
3185     if (const ScrollView* parentScrollView = parent()) {
3186         if (parentScrollView->isFrameView()) {
3187             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
3188
3189             // Get our renderer in the parent view
3190             RenderPart* renderer = m_frame->ownerRenderer();
3191             if (!renderer)
3192                 return localPoint;
3193                 
3194             IntPoint point(localPoint);
3195
3196             // Add borders and padding
3197             point.move(renderer->borderLeft() + renderer->paddingLeft(),
3198                        renderer->borderTop() + renderer->paddingTop());
3199             return parentView->convertFromRenderer(renderer, point);
3200         }
3201         
3202         return Widget::convertToContainingView(localPoint);
3203     }
3204     
3205     return localPoint;
3206 }
3207
3208 IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
3209 {
3210     if (const ScrollView* parentScrollView = parent()) {
3211         if (parentScrollView->isFrameView()) {
3212             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
3213
3214             // Get our renderer in the parent view
3215             RenderPart* renderer = m_frame->ownerRenderer();
3216             if (!renderer)
3217                 return parentPoint;
3218
3219             IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
3220             // Subtract borders and padding
3221             point.move(-renderer->borderLeft() - renderer->paddingLeft(),
3222                        -renderer->borderTop() - renderer->paddingTop());
3223             return point;
3224         }
3225         
3226         return Widget::convertFromContainingView(parentPoint);
3227     }
3228     
3229     return parentPoint;
3230 }
3231
3232 // Normal delay
3233 void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
3234 {
3235     s_deferredRepaintDelay = p;
3236 }
3237
3238 // Negative value would mean that first few repaints happen without a delay
3239 void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p)
3240 {
3241     s_initialDeferredRepaintDelayDuringLoading = p;
3242 }
3243
3244 // The delay grows on each repaint to this maximum value
3245 void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p)
3246 {
3247     s_maxDeferredRepaintDelayDuringLoading = p;
3248 }
3249
3250 // On each repaint the delay increases by this amount
3251 void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p)
3252 {
3253     s_deferredRepaintDelayIncrementDuringLoading = p;
3254 }
3255
3256 void FrameView::setTracksRepaints(bool trackRepaints)
3257 {
3258     if (trackRepaints == m_isTrackingRepaints)
3259         return;
3260     
3261     m_trackedRepaintRects.clear();
3262     m_isTrackingRepaints = trackRepaints;
3263 }
3264
3265 bool FrameView::isVerticalDocument() const
3266 {
3267     RenderView* root = rootRenderer(this);
3268     if (!root)
3269         return true;
3270
3271     return root->style()->isHorizontalWritingMode();
3272 }
3273
3274 bool FrameView::isFlippedDocument() const
3275 {
3276     RenderView* root = rootRenderer(this);
3277     if (!root)
3278         return false;
3279
3280     return root->style()->isFlippedBlocksWritingMode();
3281 }
3282
3283 void FrameView::notifyWidgetsInAllFrames(WidgetNotification notification)
3284 {
3285     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
3286         if (RenderView* root = frame->contentRenderer())
3287             root->notifyWidgets(notification);
3288     }
3289 }
3290     
3291 AXObjectCache* FrameView::axObjectCache() const
3292 {
3293     if (frame() && frame()->document() && frame()->document()->axObjectCacheExists())
3294         return frame()->document()->axObjectCache();
3295     return 0;
3296 }
3297     
3298 } // namespace WebCore