OSDN Git Service

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