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