OSDN Git Service

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