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