OSDN Git Service

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