OSDN Git Service

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