OSDN Git Service

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