Merge "[CherryPick] Refactoring: Move the content of HTMLInputElement::subtreeHasChan...
[framework/web/webkit-efl.git] / Source / 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 "BackForwardController.h"
32 #include "CachedResourceLoader.h"
33 #include "Chrome.h"
34 #include "ChromeClient.h"
35 #include "DocumentMarkerController.h"
36 #include "EventHandler.h"
37 #include "FloatRect.h"
38 #include "FocusController.h"
39 #include "FontCache.h"
40 #include "Frame.h"
41 #include "FrameActionScheduler.h"
42 #include "FrameLoader.h"
43 #include "FrameLoaderClient.h"
44 #include "FrameTree.h"
45 #include "GraphicsContext.h"
46 #include "HTMLDocument.h"
47 #include "HTMLFrameElement.h"
48 #include "HTMLFrameSetElement.h"
49 #include "HTMLNames.h"
50 #include "HTMLPlugInImageElement.h"
51 #include "InspectorClient.h"
52 #include "InspectorController.h"
53 #include "InspectorInstrumentation.h"
54 #include "OverflowEvent.h"
55 #include "RenderArena.h"
56 #include "RenderEmbeddedObject.h"
57 #include "RenderFullScreen.h"
58 #include "RenderIFrame.h"
59 #include "RenderLayer.h"
60 #include "RenderPart.h"
61 #include "RenderScrollbar.h"
62 #include "RenderScrollbarPart.h"
63 #include "RenderTheme.h"
64 #include "RenderView.h"
65 #include "ScrollAnimator.h"
66 #include "ScrollingCoordinator.h"
67 #include "Settings.h"
68 #include "StyleResolver.h"
69 #include "TextResourceDecoder.h"
70
71 #include <wtf/CurrentTime.h>
72 #include <wtf/TemporaryChange.h>
73 #include <wtf/UnusedParam.h>
74
75 #if USE(ACCELERATED_COMPOSITING)
76 #include "RenderLayerCompositor.h"
77 #include "TiledBacking.h"
78 #endif
79
80 #if ENABLE(SVG)
81 #include "RenderSVGRoot.h"
82 #include "SVGDocument.h"
83 #include "SVGSVGElement.h"
84 #endif
85
86 #if USE(TILED_BACKING_STORE)
87 #include "TiledBackingStore.h"
88 #endif
89
90 #if ENABLE(TEXT_AUTOSIZING)
91 #include "TextAutosizer.h"
92 #endif
93
94 #if ENABLE(TIZEN_BLOCK_SENDING_RESIZE_EVENT_WHILE_LOADING)
95 #include "DocumentLoader.h"
96 #endif
97
98 namespace WebCore {
99
100 using namespace HTMLNames;
101
102 double FrameView::sCurrentPaintTimeStamp = 0.0;
103
104 // REPAINT_THROTTLING now chooses default values for throttling parameters.
105 // Should be removed when applications start using runtime configuration.
106 #if ENABLE(REPAINT_THROTTLING)
107 // Normal delay
108 double FrameView::s_deferredRepaintDelay = 0.025;
109 // Negative value would mean that first few repaints happen without a delay
110 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
111 // The delay grows on each repaint to this maximum value
112 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 2.5;
113 // On each repaint the delay increses by this amount
114 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5;
115 #else
116 // FIXME: Repaint throttling could be good to have on all platform.
117 // The balance between CPU use and repaint frequency will need some tuning for desktop.
118 // More hooks may be needed to reset the delay on things like GIF and CSS animations.
119 double FrameView::s_deferredRepaintDelay = 0;
120 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
121 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0;
122 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0;
123 #endif
124
125 // The maximum number of updateWidgets iterations that should be done before returning.
126 static const unsigned maxUpdateWidgetsIterations = 2;
127
128 static inline RenderView* rootRenderer(const FrameView* view)
129 {
130     return view->frame() ? view->frame()->contentRenderer() : 0;
131 }
132
133 static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLayer* layer, bool isRelayoutingSubtree, bool didFullRepaint)
134 {
135     RenderLayer::UpdateLayerPositionsFlags flags = RenderLayer::defaultFlags;
136     if (didFullRepaint)
137         flags &= ~RenderLayer::CheckForRepaint;
138     if (isRelayoutingSubtree && layer->isPaginated())
139         flags |= RenderLayer::UpdatePagination;
140     return flags;
141 }
142
143 FrameView::FrameView(Frame* frame)
144     : m_frame(frame)
145     , m_canHaveScrollbars(true)
146     , m_slowRepaintObjectCount(0)
147     , m_layoutTimer(this, &FrameView::layoutTimerFired)
148     , m_layoutRoot(0)
149     , m_inSynchronousPostLayout(false)
150     , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
151     , m_isTransparent(false)
152     , m_baseBackgroundColor(Color::white)
153     , m_mediaType("screen")
154     , m_actionScheduler(adoptPtr(new FrameActionScheduler))
155     , m_overflowStatusDirty(true)
156     , m_viewportRenderer(0)
157     , m_wasScrolledByUser(false)
158     , m_inProgrammaticScroll(false)
159     , m_safeToPropagateScrollToParent(true)
160     , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired)
161     , m_disableRepaints(0)
162     , m_isTrackingRepaints(false)
163     , m_shouldUpdateWhileOffscreen(true)
164     , m_deferSetNeedsLayouts(0)
165     , m_setNeedsLayoutWasDeferred(false)
166     , m_scrollCorner(0)
167     , m_shouldAutoSize(false)
168     , m_inAutoSize(false)
169     , m_didRunAutosize(false)
170 {
171     init();
172
173     // FIXME: Can m_frame ever be null here?
174     if (!m_frame)
175         return;
176
177     Page* page = m_frame->page();
178     if (!page)
179         return;
180
181     if (m_frame == page->mainFrame()) {
182         ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
183         ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
184     }
185 }
186
187 PassRefPtr<FrameView> FrameView::create(Frame* frame)
188 {
189     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
190     view->show();
191     return view.release();
192 }
193
194 PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize)
195 {
196     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
197     view->Widget::setFrameRect(IntRect(view->location(), initialSize));
198     view->show();
199     return view.release();
200 }
201
202 FrameView::~FrameView()
203 {
204     if (m_postLayoutTasksTimer.isActive()) {
205         m_postLayoutTasksTimer.stop();
206         m_actionScheduler->clear();
207     }
208     
209     if (AXObjectCache::accessibilityEnabled() && axObjectCache())
210         axObjectCache()->remove(this);
211     
212     resetScrollbars();
213
214     // Custom scrollbars should already be destroyed at this point
215     ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
216     ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
217
218     setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
219     setHasVerticalScrollbar(false);
220     
221     ASSERT(!m_scrollCorner);
222     ASSERT(m_actionScheduler->isEmpty());
223
224     if (m_frame) {
225         ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
226         RenderPart* renderer = m_frame->ownerRenderer();
227         if (renderer && renderer->widget() == this)
228             renderer->setWidget(0);
229     }
230 }
231
232 void FrameView::reset()
233 {
234     m_cannotBlitToWindow = false;
235     m_isOverlapped = false;
236     m_contentIsOpaque = false;
237     m_borderX = 30;
238     m_borderY = 30;
239     m_layoutTimer.stop();
240     m_layoutRoot = 0;
241     m_delayedLayout = false;
242     m_doFullRepaint = true;
243     m_layoutSchedulingEnabled = true;
244     m_inLayout = false;
245     m_inSynchronousPostLayout = false;
246     m_layoutCount = 0;
247     m_nestedLayoutCount = 0;
248     m_postLayoutTasksTimer.stop();
249     m_firstLayout = true;
250     m_firstLayoutCallbackPending = false;
251     m_wasScrolledByUser = false;
252     m_safeToPropagateScrollToParent = true;
253     m_lastViewportSize = IntSize();
254     m_lastZoomFactor = 1.0f;
255     m_deferringRepaints = 0;
256     m_repaintCount = 0;
257     m_repaintRects.clear();
258     m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading;
259     m_deferredRepaintTimer.stop();
260     m_isTrackingRepaints = false;
261     m_trackedRepaintRects.clear();
262     m_lastPaintTime = 0;
263     m_paintBehavior = PaintBehaviorNormal;
264     m_isPainting = false;
265     m_visuallyNonEmptyCharacterCount = 0;
266     m_visuallyNonEmptyPixelCount = 0;
267     m_isVisuallyNonEmpty = false;
268     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
269     m_maintainScrollPositionAnchor = 0;
270     m_disableRepaints = 0;
271 }
272
273 bool FrameView::isFrameView() const 
274
275     return true; 
276 }
277
278 void FrameView::clearFrame()
279 {
280     m_frame = 0;
281 }
282
283 #if ENABLE(TIZEN_ELEMENTS_NESTED_IN_FLATTENED_FRAME_FIX)
284 bool FrameView::inFlattenFrame()
285 {
286     return (m_frame && m_frame->ownerElement() && (m_frame->ownerElement()->hasTagName(iframeTag) || m_frame->ownerElement()->hasTagName(frameTag) ) && m_frame->settings() && m_frame->settings()->frameFlatteningEnabled());
287 }
288 #endif
289
290 void FrameView::resetScrollbars()
291 {
292     // Reset the document's scrollbars back to our defaults before we yield the floor.
293     m_firstLayout = true;
294     setScrollbarsSuppressed(true);
295     if (m_canHaveScrollbars)
296         setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
297     else
298         setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
299     setScrollbarsSuppressed(false);
300 }
301
302 void FrameView::resetScrollbarsAndClearContentsSize()
303 {
304     resetScrollbars();
305
306     setScrollbarsSuppressed(true);
307     setContentsSize(IntSize());
308     setScrollbarsSuppressed(false);
309 }
310
311 void FrameView::init()
312 {
313     reset();
314
315     m_margins = LayoutSize(-1, -1); // undefined
316     m_size = LayoutSize();
317
318     // Propagate the marginwidth/height and scrolling modes to the view.
319     Element* ownerElement = m_frame ? m_frame->ownerElement() : 0;
320     if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
321         HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
322         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
323             setCanHaveScrollbars(false);
324         LayoutUnit marginWidth = frameElt->marginWidth();
325         LayoutUnit marginHeight = frameElt->marginHeight();
326         if (marginWidth != -1)
327             setMarginWidth(marginWidth);
328         if (marginHeight != -1)
329             setMarginHeight(marginHeight);
330     }
331 }
332
333 void FrameView::detachCustomScrollbars()
334 {
335     Scrollbar* horizontalBar = horizontalScrollbar();
336     if (horizontalBar && horizontalBar->isCustomScrollbar())
337         setHasHorizontalScrollbar(false);
338
339     Scrollbar* verticalBar = verticalScrollbar();
340     if (verticalBar && verticalBar->isCustomScrollbar())
341         setHasVerticalScrollbar(false);
342
343     if (m_scrollCorner) {
344         m_scrollCorner->destroy();
345         m_scrollCorner = 0;
346     }
347 }
348
349 void FrameView::recalculateScrollbarOverlayStyle()
350 {
351     ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
352     ScrollbarOverlayStyle overlayStyle = ScrollbarOverlayStyleDefault;
353
354     Color backgroundColor = documentBackgroundColor();
355 #if USE(ACCELERATED_COMPOSITING)
356     if (RenderView* root = rootRenderer(this)) {
357         RenderLayerCompositor* compositor = root->compositor();
358         compositor->documentBackgroundColorDidChange();
359     }
360 #endif
361
362     if (backgroundColor.isValid()) {
363         // Reduce the background color from RGB to a lightness value
364         // and determine which scrollbar style to use based on a lightness
365         // heuristic.
366         double hue, saturation, lightness;
367         backgroundColor.getHSL(hue, saturation, lightness);
368         if (lightness <= .5)
369             overlayStyle = ScrollbarOverlayStyleLight;
370     }
371
372     if (oldOverlayStyle != overlayStyle)
373         setScrollbarOverlayStyle(overlayStyle);
374 }
375
376 void FrameView::clear()
377 {
378     setCanBlitOnScroll(true);
379     
380     reset();
381
382     if (m_frame) {
383         if (RenderPart* renderer = m_frame->ownerRenderer())
384             renderer->viewCleared();
385     }
386
387     setScrollbarsSuppressed(true);
388 }
389
390 bool FrameView::didFirstLayout() const
391 {
392     return !m_firstLayout;
393 }
394
395 void FrameView::invalidateRect(const IntRect& rect)
396 {
397     if (!parent()) {
398         if (hostWindow())
399             hostWindow()->invalidateContentsAndRootView(rect, false /*immediate*/);
400         return;
401     }
402
403     if (!m_frame)
404         return;
405
406     RenderPart* renderer = m_frame->ownerRenderer();
407     if (!renderer)
408         return;
409
410     IntRect repaintRect = rect;
411     repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
412                      renderer->borderTop() + renderer->paddingTop());
413     renderer->repaintRectangle(repaintRect);
414 }
415
416 void FrameView::setFrameRect(const IntRect& newRect)
417 {
418     IntRect oldRect = frameRect();
419     if (newRect == oldRect)
420         return;
421
422     ScrollView::setFrameRect(newRect);
423
424     updateScrollableAreaSet();
425
426 #if USE(ACCELERATED_COMPOSITING)
427     if (RenderView* root = rootRenderer(this)) {
428         if (root->usesCompositing())
429             root->compositor()->frameViewDidChangeSize();
430     }
431 #endif
432 }
433
434 #if ENABLE(REQUEST_ANIMATION_FRAME)
435 bool FrameView::scheduleAnimation()
436 {
437     if (hostWindow()) {
438         hostWindow()->scheduleAnimation();
439         return true;
440     }
441     return false;
442 }
443 #endif
444
445 void FrameView::setMarginWidth(LayoutUnit w)
446 {
447     // make it update the rendering area when set
448     m_margins.setWidth(w);
449 }
450
451 void FrameView::setMarginHeight(LayoutUnit h)
452 {
453     // make it update the rendering area when set
454     m_margins.setHeight(h);
455 }
456
457 bool FrameView::avoidScrollbarCreation() const
458 {
459     ASSERT(m_frame);
460
461     // with frame flattening no subframe can have scrollbars
462     // but we also cannot turn scrollbars off as we determine
463     // our flattening policy using that.
464
465     if (!m_frame->ownerElement())
466         return false;
467
468     if (!m_frame->settings() || m_frame->settings()->frameFlatteningEnabled())
469         return true;
470
471     return false;
472 }
473
474 void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
475 {
476     m_canHaveScrollbars = canHaveScrollbars;
477     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
478 }
479
480 void FrameView::updateCanHaveScrollbars()
481 {
482     ScrollbarMode hMode;
483     ScrollbarMode vMode;
484     scrollbarModes(hMode, vMode);
485     if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
486         setCanHaveScrollbars(false);
487     else
488         setCanHaveScrollbars(true);
489 }
490
491 PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
492 {
493 #if ENABLE(TIZEN_DISABLE_CUSTOM_SCROLLBAR)
494     if (m_frame->page() && m_frame->page()->mainFrame() == m_frame)
495         return ScrollView::createScrollbar(orientation);
496 #endif
497
498     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
499     Document* doc = m_frame->document();
500
501     // Try the <body> element first as a scrollbar source.
502     Element* body = doc ? doc->body() : 0;
503     if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR))
504         return RenderScrollbar::createCustomScrollbar(this, orientation, body);
505     
506     // If the <body> didn't have a custom style, then the root element might.
507     Element* docElement = doc ? doc->documentElement() : 0;
508     if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(SCROLLBAR))
509         return RenderScrollbar::createCustomScrollbar(this, orientation, docElement);
510         
511     // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
512     RenderPart* frameRenderer = m_frame->ownerRenderer();
513     if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR))
514         return RenderScrollbar::createCustomScrollbar(this, orientation, 0, m_frame.get());
515     
516     // Nobody set a custom style, so we just use a native scrollbar.
517     return ScrollView::createScrollbar(orientation);
518 }
519
520 void FrameView::setContentsSize(const IntSize& size)
521 {
522     if (size == contentsSize())
523         return;
524
525     m_deferSetNeedsLayouts++;
526     ScrollView::setContentsSize(size);
527
528     ScrollView::contentsResized();
529
530     Page* page = frame() ? frame()->page() : 0;
531     if (!page)
532         return;
533
534     updateScrollableAreaSet();
535
536     page->chrome()->contentsSizeChanged(frame(), size); //notify only
537
538     m_deferSetNeedsLayouts--;
539     
540     if (!m_deferSetNeedsLayouts)
541         m_setNeedsLayoutWasDeferred = false; // FIXME: Find a way to make the deferred layout actually happen.
542 }
543
544 void FrameView::adjustViewSize()
545 {
546     RenderView* root = rootRenderer(this);
547     if (!root)
548         return;
549
550     ASSERT(m_frame->view() == this);
551
552     const IntRect rect = root->documentRect();
553     const IntSize& size = rect.size();
554     ScrollView::setScrollOrigin(IntPoint(-rect.x(), -rect.y()), !m_frame->document()->printing(), size == contentsSize());
555 #if ENABLE(TIZEN_ADJUST_CONTENTS_SIZE_FOR_MINUS_X_WORKAROUND)
556     // FIXME: In the case <html> starts at non-zero position (for example, the contents overflow to left of the <html> by dir=RTL (right-to-left)),
557     // the contents size should not include the left area of <html> because the leftmost paint position is (0,0) of the <html>.
558     // So, in here, I adjusted the contents size not to include the left area of <html>.
559     // It's not reasonable patch for Desktop browsers because it works wrong when the viewport size is changed.
560     // But now the TIZEN is only for Mobile, it works for now. (But need to be fixed ASAP)
561     if (rect.x() < 0)
562         setContentsSize(IntSize(size.width() + rect.x(), size.height()));
563     else
564 #endif
565     setContentsSize(size);
566 }
567
568 void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
569 {
570     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
571     // overflow:hidden and overflow:scroll on <body> as applying to the document's
572     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
573     // use the root element.
574
575     // To combat the inability to scroll on a page with overflow:hidden on the root when scaled, disregard hidden when
576     // there is a frameScaleFactor that is greater than one on the main frame.
577
578     bool overrideHidden = m_frame->page() && m_frame->page()->mainFrame() == m_frame && m_frame->frameScaleFactor() > 1;
579
580     EOverflow overflowX = o->style()->overflowX();
581     EOverflow overflowY = o->style()->overflowY();
582
583 #if ENABLE(SVG)
584     if (o->isSVGRoot()) {
585         // overflow is ignored in stand-alone SVG documents.
586         if (!toRenderSVGRoot(o)->isEmbeddedThroughFrameContainingSVGDocument())
587             return;
588         overflowX = OHIDDEN;
589         overflowY = OHIDDEN;
590     }
591 #endif
592
593     switch (overflowX) {
594         case OHIDDEN:
595             if (overrideHidden)
596                 hMode = ScrollbarAuto;
597             else
598                 hMode = ScrollbarAlwaysOff;
599             break;
600         case OSCROLL:
601             hMode = ScrollbarAlwaysOn;
602             break;
603         case OAUTO:
604             hMode = ScrollbarAuto;
605             break;
606         default:
607             // Don't set it at all.
608             ;
609     }
610     
611      switch (overflowY) {
612         case OHIDDEN:
613             if (overrideHidden)
614                 vMode = ScrollbarAuto;
615             else
616                 vMode = ScrollbarAlwaysOff;
617             break;
618         case OSCROLL:
619             vMode = ScrollbarAlwaysOn;
620             break;
621         case OAUTO:
622             vMode = ScrollbarAuto;
623             break;
624         default:
625             // Don't set it at all.
626             ;
627     }
628
629     m_viewportRenderer = o;
630 }
631
632 void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
633 {
634     m_viewportRenderer = 0;
635
636     const HTMLFrameOwnerElement* owner = m_frame->ownerElement();
637     if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
638         hMode = ScrollbarAlwaysOff;
639         vMode = ScrollbarAlwaysOff;
640         return;
641     }  
642     
643     if (m_canHaveScrollbars || strategy == RulesFromWebContentOnly) {
644         hMode = ScrollbarAuto;
645         vMode = ScrollbarAuto;
646     } else {
647         hMode = ScrollbarAlwaysOff;
648         vMode = ScrollbarAlwaysOff;
649     }
650     
651     if (!m_layoutRoot) {
652         Document* document = m_frame->document();
653         Node* documentElement = document->documentElement();
654         RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
655         Node* body = document->body();
656         if (body && body->renderer()) {
657             if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) {
658                 vMode = ScrollbarAlwaysOff;
659                 hMode = ScrollbarAlwaysOff;
660             } else if (body->hasTagName(bodyTag)) {
661                 // It's sufficient to just check the X overflow,
662                 // since it's illegal to have visible in only one direction.
663                 RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
664                 applyOverflowToViewport(o, hMode, vMode);
665             }
666         } else if (rootRenderer)
667             applyOverflowToViewport(rootRenderer, hMode, vMode);
668     }    
669 }
670
671 #if USE(ACCELERATED_COMPOSITING)
672 void FrameView::updateCompositingLayersAfterStyleChange()
673 {
674     RenderView* root = rootRenderer(this);
675     if (!root)
676         return;
677
678     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
679     root->compositor()->cacheAcceleratedCompositingFlags();
680     root->compositor()->updateCompositingLayers(CompositingUpdateAfterStyleChange);
681 }
682
683 void FrameView::updateCompositingLayersAfterLayout()
684 {
685     RenderView* root = rootRenderer(this);
686     if (!root)
687         return;
688
689     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
690     root->compositor()->cacheAcceleratedCompositingFlags();
691     root->compositor()->updateCompositingLayers(CompositingUpdateAfterLayout);
692 }
693
694 void FrameView::clearBackingStores()
695 {
696     RenderView* root = rootRenderer(this);
697     if (!root)
698         return;
699
700     RenderLayerCompositor* compositor = root->compositor();
701     ASSERT(compositor->inCompositingMode());
702     compositor->enableCompositingMode(false);
703     compositor->clearBackingForAllLayers();
704 }
705
706 void FrameView::restoreBackingStores()
707 {
708     RenderView* root = rootRenderer(this);
709     if (!root)
710         return;
711
712     RenderLayerCompositor* compositor = root->compositor();
713     compositor->enableCompositingMode(true);
714     compositor->updateCompositingLayers(CompositingUpdateAfterLayout);
715 }
716
717 GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
718 {
719     RenderView* root = rootRenderer(this);
720     if (!root)
721         return 0;
722     return root->compositor()->layerForHorizontalScrollbar();
723 }
724
725 GraphicsLayer* FrameView::layerForVerticalScrollbar() const
726 {
727     RenderView* root = rootRenderer(this);
728     if (!root)
729         return 0;
730     return root->compositor()->layerForVerticalScrollbar();
731 }
732
733 GraphicsLayer* FrameView::layerForScrollCorner() const
734 {
735     RenderView* root = rootRenderer(this);
736     if (!root)
737         return 0;
738     return root->compositor()->layerForScrollCorner();
739 }
740
741 TiledBacking* FrameView::tiledBacking()
742 {
743     RenderView* root = rootRenderer(this);
744     if (!root)
745         return 0;
746
747     RenderLayerBacking* backing = root->layer()->backing();
748     if (!backing)
749         return 0;
750
751     return backing->graphicsLayer()->tiledBacking();
752 }
753
754 #if ENABLE(RUBBER_BANDING)
755 GraphicsLayer* FrameView::layerForOverhangAreas() const
756 {
757     RenderView* root = rootRenderer(this);
758     if (!root)
759         return 0;
760     return root->compositor()->layerForOverhangAreas();
761 }
762 #endif
763
764 bool FrameView::syncCompositingStateForThisFrame(Frame* rootFrameForSync)
765 {
766     RenderView* root = rootRenderer(this);
767     if (!root)
768         return true; // We don't want to keep trying to update layers if we have no renderer.
769
770     ASSERT(m_frame->view() == this);
771
772     // If we sync compositing layers when a layout is pending, we may cause painting of compositing
773     // layer content to occur before layout has happened, which will cause paintContents() to bail.
774     if (needsLayout())
775         return false;
776
777     // If we sync compositing layers and allow the repaint to be deferred, there is time for a
778     // visible flash to occur. Instead, stop the deferred repaint timer and repaint immediately.
779     stopDelayingDeferredRepaints();
780
781     root->compositor()->flushPendingLayerChanges(rootFrameForSync == m_frame);
782
783     return true;
784 }
785
786 void FrameView::setNeedsOneShotDrawingSynchronization()
787 {
788     Page* page = frame() ? frame()->page() : 0;
789     if (page)
790         page->chrome()->client()->setNeedsOneShotDrawingSynchronization();
791 }
792
793 #endif // USE(ACCELERATED_COMPOSITING)
794
795 bool FrameView::hasCompositedContent() const
796 {
797 #if USE(ACCELERATED_COMPOSITING)
798     if (RenderView* root = rootRenderer(this))
799         return root->compositor()->inCompositingMode();
800 #endif
801     return false;
802 }
803
804 bool FrameView::hasCompositedContentIncludingDescendants() const
805 {
806 #if USE(ACCELERATED_COMPOSITING)
807     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
808         RenderView* renderView = frame->contentRenderer();
809         RenderLayerCompositor* compositor = renderView ? renderView->compositor() : 0;
810         if (compositor) {
811             if (compositor->inCompositingMode())
812                 return true;
813
814             if (!RenderLayerCompositor::allowsIndependentlyCompositedFrames(this))
815                 break;
816         }
817     }
818 #endif
819     return false;
820 }
821
822 bool FrameView::hasCompositingAncestor() const
823 {
824 #if USE(ACCELERATED_COMPOSITING)
825     for (Frame* frame = m_frame->tree()->parent(); frame; frame = frame->tree()->parent()) {
826         if (FrameView* view = frame->view()) {
827             if (view->hasCompositedContent())
828                 return true;
829         }
830     }
831 #endif
832     return false;
833 }
834
835 // Sometimes (for plug-ins) we need to eagerly go into compositing mode.
836 void FrameView::enterCompositingMode()
837 {
838 #if USE(ACCELERATED_COMPOSITING)
839     if (RenderView* root = rootRenderer(this)) {
840         root->compositor()->enableCompositingMode();
841         if (!needsLayout())
842             root->compositor()->scheduleCompositingLayerUpdate();
843     }
844 #endif
845 }
846
847 bool FrameView::isEnclosedInCompositingLayer() const
848 {
849 #if USE(ACCELERATED_COMPOSITING)
850     RenderObject* frameOwnerRenderer = m_frame->ownerRenderer();
851     if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
852         return true;
853
854     if (FrameView* parentView = parentFrameView())
855         return parentView->isEnclosedInCompositingLayer();
856 #endif
857     return false;
858 }
859     
860 bool FrameView::syncCompositingStateIncludingSubframes()
861 {
862 #if USE(ACCELERATED_COMPOSITING)
863     bool allFramesSynced = syncCompositingStateForThisFrame(m_frame.get());
864     
865     for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->traverseNext(m_frame.get())) {
866         bool synced = child->view()->syncCompositingStateForThisFrame(m_frame.get());
867         allFramesSynced &= synced;
868     }
869     return allFramesSynced;
870 #else // USE(ACCELERATED_COMPOSITING)
871     return true;
872 #endif
873 }
874
875 bool FrameView::isSoftwareRenderable() const
876 {
877 #if USE(ACCELERATED_COMPOSITING)
878     RenderView* root = rootRenderer(this);
879     if (!root)
880         return true;
881
882     return !root->compositor()->has3DContent();
883 #else
884     return true;
885 #endif
886 }
887
888 void FrameView::didMoveOnscreen()
889 {
890 #if USE(ACCELERATED_COMPOSITING)
891     if (TiledBacking* tiledBacking = this->tiledBacking())
892         tiledBacking->setIsInWindow(true);
893 #endif
894
895     if (RenderView* root = rootRenderer(this))
896         root->didMoveOnscreen();
897     contentAreaDidShow();
898 }
899
900 void FrameView::willMoveOffscreen()
901 {
902 #if USE(ACCELERATED_COMPOSITING)
903     if (TiledBacking* tiledBacking = this->tiledBacking())
904         tiledBacking->setIsInWindow(false);
905 #endif
906
907     if (RenderView* root = rootRenderer(this))
908         root->willMoveOffscreen();
909     contentAreaDidHide();
910 }
911
912 RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
913 {
914     return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
915 }
916
917 static inline void collectFrameViewChildren(FrameView* frameView, Vector<RefPtr<FrameView> >& frameViews)
918 {
919     const HashSet<RefPtr<Widget> >* viewChildren = frameView->children();
920     ASSERT(viewChildren);
921
922     const HashSet<RefPtr<Widget> >::iterator end = viewChildren->end();
923     for (HashSet<RefPtr<Widget> >::iterator current = viewChildren->begin(); current != end; ++current) {
924         Widget* widget = (*current).get();
925         if (widget->isFrameView())
926             frameViews.append(static_cast<FrameView*>(widget));
927     }
928 }
929
930 inline void FrameView::forceLayoutParentViewIfNeeded()
931 {
932 #if ENABLE(SVG)
933     RenderPart* ownerRenderer = m_frame->ownerRenderer();
934     if (!ownerRenderer || !ownerRenderer->frame())
935         return;
936
937     RenderBox* contentBox = embeddedContentBox();
938     if (!contentBox)
939         return;
940
941     RenderSVGRoot* svgRoot = toRenderSVGRoot(contentBox);
942     if (svgRoot->everHadLayout() && !svgRoot->needsLayout())
943         return;
944
945     // If the embedded SVG document appears the first time, the ownerRenderer has already finished
946     // layout without knowing about the existence of the embedded SVG document, because RenderReplaced
947     // embeddedContentBox() returns 0, as long as the embedded document isn't loaded yet. Before
948     // bothering to lay out the SVG document, mark the ownerRenderer needing layout and ask its
949     // FrameView for a layout. After that the RenderEmbeddedObject (ownerRenderer) carries the
950     // correct size, which RenderSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying
951     // out for the first time, or when the RenderSVGRoot size has changed dynamically (eg. via <script>).
952     RefPtr<FrameView> frameView = ownerRenderer->frame()->view();
953
954     // Mark the owner renderer as needing layout.
955     ownerRenderer->setNeedsLayoutAndPrefWidthsRecalc();
956
957     // Synchronously enter layout, to layout the view containing the host object/embed/iframe.
958     ASSERT(frameView);
959     frameView->layout();
960 #endif
961 }
962
963 void FrameView::layout(bool allowSubtree)
964 {
965     if (m_inLayout)
966         return;
967
968     // Protect the view from being deleted during layout (in recalcStyle)
969     RefPtr<FrameView> protector(this);
970
971     bool inChildFrameLayoutWithFrameFlattening = isInChildFrameWithFrameFlattening();
972
973     if (inChildFrameLayoutWithFrameFlattening) {
974         if (doLayoutWithFrameFlattening(allowSubtree))
975             return;
976     }
977
978     m_layoutTimer.stop();
979     m_delayedLayout = false;
980     m_setNeedsLayoutWasDeferred = false;
981
982     if (!m_frame) {
983         // FIXME: Do we need to set m_size.width here?
984         // FIXME: Should we set m_size.height here too?
985         m_size.setWidth(layoutWidth());
986         return;
987     }
988     
989     // we shouldn't enter layout() while painting
990     ASSERT(!isPainting());
991     if (isPainting())
992         return;
993
994     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(m_frame.get());
995
996     if (!allowSubtree && m_layoutRoot) {
997         m_layoutRoot->markContainingBlocksForLayout(false);
998         m_layoutRoot = 0;
999     }
1000
1001     ASSERT(m_frame->view() == this);
1002
1003     Document* document = m_frame->document();
1004     ASSERT(!document->inPageCache());
1005     bool subtree;
1006     RenderObject* root;
1007
1008     {
1009         TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
1010
1011         if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive() && !inChildFrameLayoutWithFrameFlattening) {
1012             // This is a new top-level layout. If there are any remaining tasks from the previous
1013             // layout, finish them now.
1014             m_inSynchronousPostLayout = true;
1015             performPostLayoutTasks();
1016             m_inSynchronousPostLayout = false;
1017         }
1018
1019         // Viewport-dependent media queries may cause us to need completely different style information.
1020         // Check that here.
1021         if (document->styleResolver()->affectedByViewportChange()) {
1022             document->styleResolverChanged(RecalcStyleImmediately);
1023             InspectorInstrumentation::mediaQueryResultChanged(document);
1024         } else
1025             document->evaluateMediaQueryList();
1026
1027         // Always ensure our style info is up-to-date. This can happen in situations where
1028         // the layout beats any sort of style recalc update that needs to occur.
1029         document->updateStyleIfNeeded();
1030
1031         subtree = m_layoutRoot;
1032
1033         // If there is only one ref to this view left, then its going to be destroyed as soon as we exit, 
1034         // so there's no point to continuing to layout
1035         if (protector->hasOneRef())
1036             return;
1037
1038         root = subtree ? m_layoutRoot : document->renderer();
1039         if (!root) {
1040             // FIXME: Do we need to set m_size here?
1041             return;
1042         }
1043     } // Reset m_layoutSchedulingEnabled to its previous value.
1044     // The only reason the scoping was closed here is allow fontCachePurgePreventer
1045     // to outlive the change and reset of m_layoutSchedulingEnabled.
1046
1047     FontCachePurgePreventer fontCachePurgePreventer;
1048     RenderLayer* layer;
1049     {
1050         TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
1051
1052         m_nestedLayoutCount++;
1053
1054         if (!m_layoutRoot) {
1055             Document* document = m_frame->document();
1056             Node* body = document->body();
1057             if (body && body->renderer()) {
1058                 if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) {
1059                     body->renderer()->setChildNeedsLayout(true);
1060                 } else if (body->hasTagName(bodyTag)) {
1061                     if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewport())
1062                         body->renderer()->setChildNeedsLayout(true);
1063                 }
1064             }
1065
1066 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
1067             if (m_firstLayout && !m_frame->ownerElement())
1068                 printf("Elapsed time before first layout: %d\n", document->elapsedTime());
1069 #endif        
1070         }
1071
1072         autoSizeIfEnabled();
1073
1074         ScrollbarMode hMode;
1075         ScrollbarMode vMode;    
1076         calculateScrollbarModesForLayout(hMode, vMode);
1077
1078         m_doFullRepaint = !subtree && (m_firstLayout || toRenderView(root)->printing());
1079
1080         if (!subtree) {
1081             // Now set our scrollbar state for the layout.
1082             ScrollbarMode currentHMode = horizontalScrollbarMode();
1083             ScrollbarMode currentVMode = verticalScrollbarMode();
1084
1085             if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
1086                 if (m_firstLayout) {
1087                     setScrollbarsSuppressed(true);
1088
1089                     m_firstLayout = false;
1090                     m_firstLayoutCallbackPending = true;
1091                     if (useFixedLayout() && !fixedLayoutSize().isEmpty() && delegatesScrolling())
1092                         m_lastViewportSize = fixedLayoutSize();
1093                     else
1094                         m_lastViewportSize = visibleContentRect(true /*includeScrollbars*/).size();
1095                     m_lastZoomFactor = root->style()->zoom();
1096
1097                     // Set the initial vMode to AlwaysOn if we're auto.
1098                     if (vMode == ScrollbarAuto)
1099                         setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
1100                     // Set the initial hMode to AlwaysOff if we're auto.
1101                     if (hMode == ScrollbarAuto)
1102                         setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
1103
1104                     setScrollbarModes(hMode, vMode);
1105                     setScrollbarsSuppressed(false, true);
1106                 } else
1107                     setScrollbarModes(hMode, vMode);
1108             }
1109
1110             LayoutSize oldSize = m_size;
1111
1112             m_size = LayoutSize(layoutWidth(), layoutHeight());
1113
1114             if (oldSize != m_size) {
1115                 m_doFullRepaint = true;
1116                 if (!m_firstLayout) {
1117                     RenderBox* rootRenderer = document->documentElement() ? document->documentElement()->renderBox() : 0;
1118                     RenderBox* bodyRenderer = rootRenderer && document->body() ? document->body()->renderBox() : 0;
1119                     if (bodyRenderer && bodyRenderer->stretchesToViewport())
1120                         bodyRenderer->setChildNeedsLayout(true);
1121                     else if (rootRenderer && rootRenderer->stretchesToViewport())
1122                         rootRenderer->setChildNeedsLayout(true);
1123                 }
1124             }
1125         }
1126
1127         layer = root->enclosingLayer();
1128
1129         m_actionScheduler->pause();
1130
1131         {
1132             bool disableLayoutState = false;
1133             if (subtree) {
1134                 RenderView* view = root->view();
1135                 disableLayoutState = view->shouldDisableLayoutStateForSubtree(root);
1136                 view->pushLayoutState(root);
1137             }
1138             LayoutStateDisabler layoutStateDisabler(disableLayoutState ? root->view() : 0);
1139
1140             m_inLayout = true;
1141             beginDeferredRepaints();
1142             forceLayoutParentViewIfNeeded();
1143             root->layout();
1144 #if ENABLE(TEXT_AUTOSIZING)
1145             bool autosized = document->textAutosizer()->processSubtree(root);
1146             if (autosized && root->needsLayout())
1147                 root->layout();
1148 #endif
1149             endDeferredRepaints();
1150             m_inLayout = false;
1151
1152             if (subtree)
1153                 root->view()->popLayoutState(root);
1154         }
1155         m_layoutRoot = 0;
1156     } // Reset m_layoutSchedulingEnabled to its previous value.
1157
1158     if (!subtree && !toRenderView(root)->printing())
1159         adjustViewSize();
1160
1161     // Now update the positions of all layers.
1162     beginDeferredRepaints();
1163     bool hasLayerOffset;
1164     LayoutPoint offsetFromRoot = layer->computeOffsetFromRoot(hasLayerOffset);
1165     if (m_doFullRepaint)
1166         root->view()->repaint(); // FIXME: This isn't really right, since the RenderView doesn't fully encompass the visibleContentRect(). It just happens
1167                                  // to work out most of the time, since first layouts and printing don't have you scrolled anywhere.
1168
1169     layer->updateLayerPositions(hasLayerOffset ? &offsetFromRoot : 0, updateLayerPositionFlags(layer, subtree, m_doFullRepaint));
1170     endDeferredRepaints();
1171
1172 #if USE(ACCELERATED_COMPOSITING)
1173     updateCompositingLayersAfterLayout();
1174 #endif
1175     
1176     m_layoutCount++;
1177
1178 #if PLATFORM(MAC) || PLATFORM(CHROMIUM)
1179     if (AXObjectCache::accessibilityEnabled())
1180         root->document()->axObjectCache()->postNotification(root, AXObjectCache::AXLayoutComplete, true);
1181 #endif
1182 #if ENABLE(DASHBOARD_SUPPORT)
1183     updateDashboardRegions();
1184 #endif
1185
1186     ASSERT(!root->needsLayout());
1187
1188     updateCanBlitOnScrollRecursively();
1189
1190     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
1191         updateOverflowStatus(layoutWidth() < contentsWidth(),
1192                              layoutHeight() < contentsHeight());
1193
1194     if (!m_postLayoutTasksTimer.isActive()) {
1195         if (!m_inSynchronousPostLayout) {
1196             if (inChildFrameLayoutWithFrameFlattening) {
1197                 if (RenderView* root = rootRenderer(this))
1198                     root->updateWidgetPositions();
1199             } else {
1200                 m_inSynchronousPostLayout = true;
1201                 // Calls resumeScheduledEvents()
1202                 performPostLayoutTasks();
1203                 m_inSynchronousPostLayout = false;
1204             }
1205         }
1206         
1207         if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout || inChildFrameLayoutWithFrameFlattening)) {
1208             // If we need layout or are already in a synchronous call to postLayoutTasks(), 
1209             // defer widget updates and event dispatch until after we return. postLayoutTasks()
1210             // can make us need to update again, and we can get stuck in a nasty cycle unless
1211             // we call it through the timer here.
1212             m_postLayoutTasksTimer.startOneShot(0);
1213             if (needsLayout()) {
1214                 m_actionScheduler->pause();
1215                 layout();
1216             }
1217         }
1218     } else {
1219         m_actionScheduler->resume();
1220     }
1221
1222     InspectorInstrumentation::didLayout(cookie);
1223
1224     m_nestedLayoutCount--;
1225     if (m_nestedLayoutCount)
1226         return;
1227
1228     Page* page = frame() ? frame()->page() : 0;
1229     if (!page)
1230         return;
1231
1232     page->chrome()->client()->layoutUpdated(frame());
1233 }
1234
1235 RenderBox* FrameView::embeddedContentBox() const
1236 {
1237 #if ENABLE(SVG)
1238     RenderView* root = rootRenderer(this);
1239     if (!root)
1240         return 0;
1241
1242     RenderObject* rootChild = root->firstChild();
1243     if (!rootChild || !rootChild->isBox())
1244         return 0;
1245
1246     // Curently only embedded SVG documents participate in the size-negotiation logic.
1247     if (rootChild->isSVGRoot())
1248         return toRenderBox(rootChild);
1249 #endif
1250
1251     return 0;
1252 }
1253
1254 void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object)
1255 {
1256     if (!m_widgetUpdateSet)
1257         m_widgetUpdateSet = adoptPtr(new RenderEmbeddedObjectSet);
1258
1259     // Tell the DOM element that it needs a widget update.
1260     Node* node = object->node();
1261     if (node->hasTagName(objectTag) || node->hasTagName(embedTag)) {
1262         HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(node);
1263         pluginElement->setNeedsWidgetUpdate(true);
1264     }
1265
1266     m_widgetUpdateSet->add(object);
1267 }
1268
1269 void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object)
1270 {
1271     if (!m_widgetUpdateSet)
1272         return;
1273
1274     m_widgetUpdateSet->remove(object);
1275 }
1276
1277 void FrameView::setMediaType(const String& mediaType)
1278 {
1279     m_mediaType = mediaType;
1280 }
1281
1282 String FrameView::mediaType() const
1283 {
1284     // See if we have an override type.
1285     String overrideType = m_frame->loader()->client()->overrideMediaType();
1286     if (!overrideType.isNull())
1287         return overrideType;
1288     return m_mediaType;
1289 }
1290
1291 void FrameView::adjustMediaTypeForPrinting(bool printing)
1292 {
1293     if (printing) {
1294         if (m_mediaTypeWhenNotPrinting.isNull())
1295             m_mediaTypeWhenNotPrinting = mediaType();
1296             setMediaType("print");
1297     } else {
1298         if (!m_mediaTypeWhenNotPrinting.isNull())
1299             setMediaType(m_mediaTypeWhenNotPrinting);
1300         m_mediaTypeWhenNotPrinting = String();
1301     }
1302 }
1303
1304 bool FrameView::useSlowRepaints(bool considerOverlap) const
1305 {
1306     bool mustBeSlow = m_slowRepaintObjectCount > 0 || (platformWidget() && hasFixedObjects());
1307
1308     // FIXME: WidgetMac.mm makes the assumption that useSlowRepaints ==
1309     // m_contentIsOpaque, so don't take the fast path for composited layers
1310     // if they are a platform widget in order to get painting correctness
1311     // for transparent layers. See the comment in WidgetMac::paint.
1312     if (contentsInCompositedLayer() && !platformWidget())
1313         return mustBeSlow;
1314
1315 #if PLATFORM(CHROMIUM)
1316     // The chromium compositor does not support scrolling a non-composited frame within a composited page through
1317     // the fast scrolling path, so force slow scrolling in that case.
1318     if (m_frame->ownerElement() && !hasCompositedContent() && m_frame->page() && m_frame->page()->mainFrame()->view()->hasCompositedContent())
1319         return true;
1320 #endif
1321
1322     bool isOverlapped = m_isOverlapped && considerOverlap;
1323
1324     if (mustBeSlow || m_cannotBlitToWindow || isOverlapped || !m_contentIsOpaque)
1325         return true;
1326
1327     if (FrameView* parentView = parentFrameView())
1328         return parentView->useSlowRepaints(considerOverlap);
1329
1330     return false;
1331 }
1332
1333 bool FrameView::useSlowRepaintsIfNotOverlapped() const
1334 {
1335     return useSlowRepaints(false);
1336 }
1337
1338 void FrameView::updateCanBlitOnScrollRecursively()
1339 {
1340     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
1341         if (FrameView* view = frame->view())
1342             view->setCanBlitOnScroll(!view->useSlowRepaints());
1343     }
1344 }
1345
1346 bool FrameView::contentsInCompositedLayer() const
1347 {
1348 #if USE(ACCELERATED_COMPOSITING)
1349     RenderView* root = rootRenderer(this);
1350     if (root && root->isComposited()) {
1351         GraphicsLayer* layer = root->layer()->backing()->graphicsLayer();
1352         if (layer && layer->drawsContent())
1353             return true;
1354     }
1355 #endif
1356     return false;
1357 }
1358
1359 void FrameView::setCannotBlitToWindow()
1360 {
1361     m_cannotBlitToWindow = true;
1362     updateCanBlitOnScrollRecursively();
1363 }
1364
1365 void FrameView::addSlowRepaintObject()
1366 {
1367     if (!m_slowRepaintObjectCount++) {
1368         updateCanBlitOnScrollRecursively();
1369
1370         if (Page* page = m_frame->page()) {
1371             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1372                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
1373         }
1374     }
1375 }
1376
1377 void FrameView::removeSlowRepaintObject()
1378 {
1379     ASSERT(m_slowRepaintObjectCount > 0);
1380     m_slowRepaintObjectCount--;
1381     if (!m_slowRepaintObjectCount) {
1382         updateCanBlitOnScrollRecursively();
1383
1384         if (Page* page = m_frame->page()) {
1385             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1386                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
1387         }
1388     }
1389 }
1390
1391 void FrameView::addFixedObject(RenderObject* object)
1392 {
1393     if (!m_fixedObjects)
1394         m_fixedObjects = adoptPtr(new FixedObjectSet);
1395
1396     if (!m_fixedObjects->contains(object)) {
1397         m_fixedObjects->add(object);
1398         if (platformWidget())
1399             updateCanBlitOnScrollRecursively();
1400
1401         if (Page* page = m_frame->page()) {
1402             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1403                 scrollingCoordinator->frameViewFixedObjectsDidChange(this);
1404         }
1405     }
1406 }
1407
1408 void FrameView::removeFixedObject(RenderObject* object)
1409 {
1410     ASSERT(hasFixedObjects());
1411
1412     if (m_fixedObjects->contains(object)) {
1413         m_fixedObjects->remove(object);
1414         if (Page* page = m_frame->page()) {
1415             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1416                 scrollingCoordinator->frameViewFixedObjectsDidChange(this);
1417         }
1418
1419         // FIXME: In addFixedObject() we only call this if there's a platform widget,
1420         // why isn't the same check being made here?
1421         updateCanBlitOnScrollRecursively();
1422     }
1423 }
1424
1425 static int fixedPositionScrollOffset(int scrollPosition, int maxValue, int scrollOrigin, float dragFactor)
1426 {
1427     if (!maxValue)
1428         return 0;
1429
1430     if (!scrollOrigin) {
1431         if (scrollPosition < 0)
1432             scrollPosition = 0;
1433         else if (scrollPosition > maxValue)
1434             scrollPosition = maxValue;
1435     } else {
1436         if (scrollPosition > 0)
1437             scrollPosition = 0;
1438         else if (scrollPosition < -maxValue)
1439             scrollPosition = -maxValue;
1440     }
1441     
1442     return scrollPosition * dragFactor;
1443 }
1444
1445 IntSize FrameView::scrollOffsetForFixedPosition() const
1446 {
1447     IntRect visibleContentRect = this->visibleContentRect();
1448     IntSize contentsSize = this->contentsSize();
1449     IntPoint scrollPosition = this->scrollPosition();
1450     IntPoint scrollOrigin = this->scrollOrigin();
1451     
1452 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
1453     // When showing IME, the fixed position element can be scrolled over maxOffset.
1454     IntSize maxOffset(contentsSize.width(), contentsSize.height());
1455 #else
1456     IntSize maxOffset(contentsSize.width() - visibleContentRect.width(), contentsSize.height() - visibleContentRect.height());
1457 #endif
1458     
1459     float frameScaleFactor = m_frame ? m_frame->frameScaleFactor() : 1;
1460
1461 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
1462     FloatSize dragFactor = fixedElementsLayoutRelativeToFrame() ? FloatSize(1, 1) : FloatSize(
1463         (contentsSize.width() * frameScaleFactor) / maxOffset.width(),
1464         (contentsSize.height() * frameScaleFactor) / maxOffset.height());
1465 #else
1466     FloatSize dragFactor = fixedElementsLayoutRelativeToFrame() ? FloatSize(1, 1) : FloatSize(
1467         (contentsSize.width() - visibleContentRect.width() * frameScaleFactor) / maxOffset.width(),
1468         (contentsSize.height() - visibleContentRect.height() * frameScaleFactor) / maxOffset.height());
1469 #endif
1470
1471     int x = fixedPositionScrollOffset(scrollPosition.x(), maxOffset.width(), scrollOrigin.x(), dragFactor.width() / frameScaleFactor);
1472     int y = fixedPositionScrollOffset(scrollPosition.y(), maxOffset.height(), scrollOrigin.y(), dragFactor.height() / frameScaleFactor);
1473
1474     return IntSize(x, y);
1475 }
1476
1477 bool FrameView::fixedElementsLayoutRelativeToFrame() const
1478 {
1479     ASSERT(m_frame);
1480     if (!m_frame->settings())
1481         return false;
1482
1483     return m_frame->settings()->fixedElementsLayoutRelativeToFrame();
1484 }
1485
1486 IntPoint FrameView::currentMousePosition() const
1487 {
1488     return m_frame ? m_frame->eventHandler()->currentMousePosition() : IntPoint();
1489 }
1490
1491 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
1492 {
1493     if (!m_fixedObjects || m_fixedObjects->isEmpty()) {
1494         hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1495         return true;
1496     }
1497
1498     const bool isCompositedContentLayer = contentsInCompositedLayer();
1499
1500     // Get the rects of the fixed objects visible in the rectToScroll
1501     Region regionToUpdate;
1502     FixedObjectSet::const_iterator end = m_fixedObjects->end();
1503     for (FixedObjectSet::const_iterator it = m_fixedObjects->begin(); it != end; ++it) {
1504         RenderObject* renderer = *it;
1505         if (renderer->style()->position() != FixedPosition)
1506             continue;
1507 #if USE(ACCELERATED_COMPOSITING)
1508         if (renderer->isComposited())
1509             continue;
1510 #endif
1511     
1512         // Fixed items should always have layers.
1513         ASSERT(renderer->hasLayer());
1514         RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1515         
1516 #if ENABLE(CSS_FILTERS)
1517         if (layer->hasAncestorWithFilterOutsets()) {
1518             // If the fixed layer has a blur/drop-shadow filter applied on at least one of its parents, we cannot 
1519             // scroll using the fast path, otherwise the outsets of the filter will be moved around the page.
1520             return false;
1521         }
1522 #endif
1523         IntRect updateRect = pixelSnappedIntRect(layer->repaintRectIncludingNonCompositingDescendants());
1524         updateRect = contentsToRootView(updateRect);
1525         if (!isCompositedContentLayer && clipsRepaints())
1526             updateRect.intersect(rectToScroll);
1527         if (!updateRect.isEmpty())
1528             regionToUpdate.unite(updateRect);
1529     }
1530
1531     // The area to be painted by fixed objects exceeds 50% of the area of the view, we cannot use the fast path.
1532     if (regionToUpdate.totalArea() > (clipRect.width() * clipRect.height() * 0.5))
1533         return false;
1534
1535     // 1) scroll
1536     hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1537
1538     // 2) update the area of fixed objects that has been invalidated
1539     Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
1540     size_t fixObjectsCount = subRectsToUpdate.size();
1541     for (size_t i = 0; i < fixObjectsCount; ++i) {
1542         IntRect updateRect = subRectsToUpdate[i];
1543         IntRect scrolledRect = updateRect;
1544         scrolledRect.move(scrollDelta);
1545         updateRect.unite(scrolledRect);
1546 #if USE(ACCELERATED_COMPOSITING)
1547         if (isCompositedContentLayer) {
1548             updateRect = rootViewToContents(updateRect);
1549             RenderView* root = rootRenderer(this);
1550             ASSERT(root);
1551             root->layer()->setBackingNeedsRepaintInRect(updateRect);
1552             continue;
1553         }
1554 #endif
1555         if (clipsRepaints())
1556             updateRect.intersect(rectToScroll);
1557         hostWindow()->invalidateContentsAndRootView(updateRect, false);
1558     }
1559
1560     return true;
1561 }
1562
1563 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
1564 {
1565 #if USE(ACCELERATED_COMPOSITING)
1566     if (contentsInCompositedLayer()) {
1567         RenderView* root = rootRenderer(this);
1568         ASSERT(root);
1569
1570         IntRect updateRect = visibleContentRect();
1571
1572         // Make sure to "apply" the scale factor here since we're converting from frame view
1573         // coordinates to layer backing coordinates.
1574         updateRect.scale(1 / m_frame->frameScaleFactor());
1575
1576         root->layer()->setBackingNeedsRepaintInRect(updateRect);
1577     }
1578     if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
1579         if (isEnclosedInCompositingLayer()) {
1580             LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
1581                             frameRenderer->borderTop() + frameRenderer->paddingTop(),
1582                             visibleWidth(), visibleHeight());
1583             frameRenderer->repaintRectangle(rect);
1584             return;
1585         }
1586     }
1587 #endif
1588
1589     ScrollView::scrollContentsSlowPath(updateRect);
1590 }
1591
1592 // Note that this gets called at painting time.
1593 void FrameView::setIsOverlapped(bool isOverlapped)
1594 {
1595     if (isOverlapped == m_isOverlapped)
1596         return;
1597
1598     m_isOverlapped = isOverlapped;
1599     updateCanBlitOnScrollRecursively();
1600     
1601 #if USE(ACCELERATED_COMPOSITING)
1602     if (hasCompositedContentIncludingDescendants()) {
1603         // Overlap can affect compositing tests, so if it changes, we need to trigger
1604         // a layer update in the parent document.
1605         if (Frame* parentFrame = m_frame->tree()->parent()) {
1606             if (RenderView* parentView = parentFrame->contentRenderer()) {
1607                 RenderLayerCompositor* compositor = parentView->compositor();
1608                 compositor->setCompositingLayersNeedRebuild();
1609                 compositor->scheduleCompositingLayerUpdate();
1610             }
1611         }
1612
1613         if (RenderLayerCompositor::allowsIndependentlyCompositedFrames(this)) {
1614             // We also need to trigger reevaluation for this and all descendant frames,
1615             // since a frame uses compositing if any ancestor is compositing.
1616             for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
1617                 if (RenderView* view = frame->contentRenderer()) {
1618                     RenderLayerCompositor* compositor = view->compositor();
1619                     compositor->setCompositingLayersNeedRebuild();
1620                     compositor->scheduleCompositingLayerUpdate();
1621                 }
1622             }
1623         }
1624     }
1625 #endif
1626 }
1627
1628 bool FrameView::isOverlappedIncludingAncestors() const
1629 {
1630     if (isOverlapped())
1631         return true;
1632
1633     if (FrameView* parentView = parentFrameView()) {
1634         if (parentView->isOverlapped())
1635             return true;
1636     }
1637
1638     return false;
1639 }
1640
1641 void FrameView::setContentIsOpaque(bool contentIsOpaque)
1642 {
1643     if (contentIsOpaque == m_contentIsOpaque)
1644         return;
1645
1646     m_contentIsOpaque = contentIsOpaque;
1647     updateCanBlitOnScrollRecursively();
1648 }
1649
1650 void FrameView::restoreScrollbar()
1651 {
1652     setScrollbarsSuppressed(false);
1653 }
1654
1655 bool FrameView::scrollToFragment(const KURL& url)
1656 {
1657     // If our URL has no ref, then we have no place we need to jump to.
1658     // OTOH If CSS target was set previously, we want to set it to 0, recalc
1659     // and possibly repaint because :target pseudo class may have been
1660     // set (see bug 11321).
1661     if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget())
1662         return false;
1663
1664     String fragmentIdentifier = url.fragmentIdentifier();
1665     if (scrollToAnchor(fragmentIdentifier))
1666         return true;
1667
1668     // Try again after decoding the ref, based on the document's encoding.
1669     if (TextResourceDecoder* decoder = m_frame->document()->decoder())
1670         return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding()));
1671
1672     return false;
1673 }
1674
1675 bool FrameView::scrollToAnchor(const String& name)
1676 {
1677     ASSERT(m_frame->document());
1678
1679     if (!m_frame->document()->haveStylesheetsLoaded()) {
1680         m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
1681         return false;
1682     }
1683
1684     m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false);
1685
1686     Element* anchorNode = m_frame->document()->findAnchor(name);
1687
1688     // Setting to null will clear the current target.
1689     m_frame->document()->setCSSTarget(anchorNode);
1690
1691 #if ENABLE(SVG)
1692     if (m_frame->document()->isSVGDocument()) {
1693         if (SVGSVGElement* svg = static_cast<SVGDocument*>(m_frame->document())->rootElement()) {
1694             svg->setupInitialView(name, anchorNode);
1695             if (!anchorNode)
1696                 return true;
1697         }
1698     }
1699 #endif
1700   
1701     // Implement the rule that "" and "top" both mean top of page as in other browsers.
1702     if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top")))
1703         return false;
1704
1705     maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document());
1706     return true;
1707 }
1708
1709 void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
1710 {
1711     m_maintainScrollPositionAnchor = anchorNode;
1712     if (!m_maintainScrollPositionAnchor)
1713         return;
1714
1715     // We need to update the layout before scrolling, otherwise we could
1716     // really mess things up if an anchor scroll comes at a bad moment.
1717     m_frame->document()->updateStyleIfNeeded();
1718     // Only do a layout if changes have occurred that make it necessary.
1719     RenderView* root = rootRenderer(this);
1720     if (root && root->needsLayout())
1721         layout();
1722     else
1723         scrollToAnchor();
1724 }
1725
1726 void FrameView::scrollElementToRect(Element* element, const IntRect& rect)
1727 {
1728     m_frame->document()->updateLayoutIgnorePendingStylesheets();
1729
1730     LayoutRect bounds = element->getRect();
1731     int centeringOffsetX = (rect.width() - bounds.width()) / 2;
1732     int centeringOffsetY = (rect.height() - bounds.height()) / 2;
1733     setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y()));
1734 }
1735
1736 void FrameView::setScrollPosition(const IntPoint& scrollPoint)
1737 {
1738     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
1739     m_maintainScrollPositionAnchor = 0;
1740
1741     if (requestScrollPositionUpdate(scrollPoint))
1742         return;
1743
1744     ScrollView::setScrollPosition(scrollPoint);
1745 }
1746
1747 void FrameView::delegatesScrollingDidChange()
1748 {
1749 #if USE(ACCELERATED_COMPOSITING)
1750     // When we switch to delgatesScrolling mode, we should destroy the scrolling/clipping layers in RenderLayerCompositor.
1751     if (hasCompositedContent())
1752         clearBackingStores();
1753 #endif
1754 }
1755
1756 void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect)
1757 {
1758     bool visibleContentSizeDidChange = false;
1759     if (visibleContentRect.size() != this->fixedVisibleContentRect().size()) {
1760         // When the viewport size changes or the content is scaled, we need to
1761         // reposition the fixed positioned elements.
1762         if (RenderView* root = rootRenderer(this))
1763             root->setFixedPositionedObjectsNeedLayout();
1764         visibleContentSizeDidChange = true;
1765     }
1766
1767     IntSize offset = scrollOffset();
1768     ScrollView::setFixedVisibleContentRect(visibleContentRect);
1769     if (offset != scrollOffset()) {
1770         if (m_frame->page()->settings()->acceleratedCompositingForFixedPositionEnabled())
1771             updateFixedElementsAfterScrolling();
1772         scrollAnimator()->setCurrentPosition(scrollPosition());
1773         scrollPositionChanged();
1774     }
1775     if (visibleContentSizeDidChange) {
1776         // Update the scroll-bars to calculate new page-step size.
1777         updateScrollbars(scrollOffset());
1778     }
1779     frame()->loader()->client()->didChangeScrollOffset();
1780 }
1781
1782 void FrameView::scrollPositionChangedViaPlatformWidget()
1783 {
1784     repaintFixedElementsAfterScrolling();
1785     updateFixedElementsAfterScrolling();
1786     scrollPositionChanged();
1787 }
1788
1789 void FrameView::scrollPositionChanged()
1790 {
1791     frame()->eventHandler()->sendScrollEvent();
1792     frame()->eventHandler()->dispatchFakeMouseMoveEventSoon();
1793
1794 #if USE(ACCELERATED_COMPOSITING)
1795     if (RenderView* root = rootRenderer(this)) {
1796         if (root->usesCompositing())
1797             root->compositor()->frameViewDidScroll();
1798     }
1799 #endif
1800 }
1801
1802 void FrameView::repaintFixedElementsAfterScrolling()
1803 {
1804     // For fixed position elements, update widget positions and compositing layers after scrolling,
1805     // but only if we're not inside of layout.
1806     if (!m_nestedLayoutCount && hasFixedObjects()) {
1807         if (RenderView* root = rootRenderer(this)) {
1808             root->updateWidgetPositions();
1809             root->layer()->updateLayerPositionsAfterScroll();
1810         }
1811     }
1812 }
1813
1814 void FrameView::updateFixedElementsAfterScrolling()
1815 {
1816 #if USE(ACCELERATED_COMPOSITING)
1817     if (m_nestedLayoutCount <= 1 && hasFixedObjects()) {
1818         if (RenderView* root = rootRenderer(this)) {
1819             root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
1820         }
1821     }
1822 #endif
1823 }
1824
1825 bool FrameView::shouldRubberBandInDirection(ScrollDirection direction) const
1826 {
1827     Page* page = frame() ? frame()->page() : 0;
1828     if (!page)
1829         return ScrollView::shouldRubberBandInDirection(direction);
1830     return page->chrome()->client()->shouldRubberBandInDirection(direction);
1831 }
1832
1833 bool FrameView::requestScrollPositionUpdate(const IntPoint& position)
1834 {
1835 #if ENABLE(THREADED_SCROLLING)
1836     if (Page* page = m_frame->page()) {
1837         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1838             return scrollingCoordinator->requestScrollPositionUpdate(this, position);
1839     }
1840 #else
1841     UNUSED_PARAM(position);
1842 #endif
1843
1844     return false;
1845 }
1846
1847 #if ENABLE(TIZEN_WEBKIT2_HISTORICAL_RESTORE_VISIBLE_CONTENT_RECT)
1848 void FrameView::requestVisibleContentRectRestore(const IntPoint& position, float scale)
1849 {
1850     Page* page = m_frame->page();
1851     if (!page)
1852         return;
1853     if (page->mainFrame() != m_frame)
1854         return;
1855     page->chrome()->client()->requestVisibleContentRectRestore(position, scale);
1856 }
1857 #endif
1858
1859 HostWindow* FrameView::hostWindow() const
1860 {
1861     Page* page = frame() ? frame()->page() : 0;
1862     if (!page)
1863         return 0;
1864     return page->chrome();
1865 }
1866
1867 const unsigned cRepaintRectUnionThreshold = 25;
1868
1869 void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
1870 {
1871     ASSERT(!m_frame->ownerElement());
1872
1873     if (m_isTrackingRepaints) {
1874         IntRect repaintRect = r;
1875         repaintRect.move(-scrollOffset());
1876         m_trackedRepaintRects.append(repaintRect);
1877     }
1878
1879     double delay = m_deferringRepaints ? 0 : adjustedDeferredRepaintDelay();
1880     if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
1881         IntRect paintRect = r;
1882         if (clipsRepaints() && !paintsEntireContents())
1883             paintRect.intersect(visibleContentRect());
1884         if (paintRect.isEmpty())
1885             return;
1886         if (m_repaintCount == cRepaintRectUnionThreshold) {
1887             IntRect unionedRect;
1888             for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i)
1889                 unionedRect.unite(pixelSnappedIntRect(m_repaintRects[i]));
1890             m_repaintRects.clear();
1891             m_repaintRects.append(unionedRect);
1892         }
1893         if (m_repaintCount < cRepaintRectUnionThreshold)
1894             m_repaintRects.append(paintRect);
1895         else
1896             m_repaintRects[0].unite(paintRect);
1897         m_repaintCount++;
1898
1899         if (!m_deferringRepaints)
1900             startDeferredRepaintTimer(delay);
1901
1902         return;
1903     }
1904     
1905     if (!shouldUpdate(immediate))
1906         return;
1907
1908 #if USE(TILED_BACKING_STORE)
1909     if (frame()->tiledBackingStore()) {
1910         frame()->tiledBackingStore()->invalidate(r);
1911         return;
1912     }
1913 #endif
1914     ScrollView::repaintContentRectangle(r, immediate);
1915 }
1916
1917 void FrameView::contentsResized()
1918 {
1919     ScrollView::contentsResized();
1920     setNeedsLayout();
1921 }
1922
1923 void FrameView::visibleContentsResized()
1924 {
1925     // We check to make sure the view is attached to a frame() as this method can
1926     // be triggered before the view is attached by Frame::createView(...) setting
1927     // various values such as setScrollBarModes(...) for example.  An ASSERT is
1928     // triggered when a view is layout before being attached to a frame().
1929     if (!frame()->view())
1930         return;
1931
1932     if (needsLayout())
1933         layout();
1934
1935 #if USE(ACCELERATED_COMPOSITING)
1936     if (RenderView* root = rootRenderer(this)) {
1937         if (root->usesCompositing())
1938             root->compositor()->frameViewDidChangeSize();
1939     }
1940 #endif
1941 }
1942
1943 void FrameView::beginDeferredRepaints()
1944 {
1945     Page* page = m_frame->page();
1946     if (page->mainFrame() != m_frame) {
1947         page->mainFrame()->view()->beginDeferredRepaints();
1948         return;
1949     }
1950
1951     m_deferringRepaints++;
1952 }
1953
1954 void FrameView::endDeferredRepaints()
1955 {
1956     Page* page = m_frame->page();
1957     if (page->mainFrame() != m_frame) {
1958         page->mainFrame()->view()->endDeferredRepaints();
1959         return;
1960     }
1961
1962     ASSERT(m_deferringRepaints > 0);
1963
1964     if (--m_deferringRepaints)
1965         return;
1966
1967     if (m_deferredRepaintTimer.isActive())
1968         return;
1969
1970     if (double delay = adjustedDeferredRepaintDelay()) {
1971         startDeferredRepaintTimer(delay);
1972         return;
1973     }
1974     
1975     doDeferredRepaints();
1976 }
1977
1978 void FrameView::startDeferredRepaintTimer(double delay)
1979 {
1980     if (m_deferredRepaintTimer.isActive())
1981         return;
1982
1983     if (m_disableRepaints)
1984         return;
1985
1986     m_deferredRepaintTimer.startOneShot(delay);
1987 }
1988
1989 void FrameView::checkStopDelayingDeferredRepaints()
1990 {
1991     Document* document = m_frame->document();
1992     if (document && (document->parsing() || document->cachedResourceLoader()->requestCount()))
1993         return;
1994
1995     stopDelayingDeferredRepaints();
1996 }
1997     
1998 void FrameView::stopDelayingDeferredRepaints()
1999 {
2000     if (!m_deferredRepaintTimer.isActive())
2001         return;
2002
2003     m_deferredRepaintTimer.stop();
2004
2005     doDeferredRepaints();
2006 }
2007     
2008 void FrameView::doDeferredRepaints()
2009 {
2010     if (m_disableRepaints)
2011         return;
2012
2013     ASSERT(!m_deferringRepaints);
2014     if (!shouldUpdate()) {
2015         m_repaintRects.clear();
2016         m_repaintCount = 0;
2017         return;
2018     }
2019     unsigned size = m_repaintRects.size();
2020     for (unsigned i = 0; i < size; i++) {
2021 #if USE(TILED_BACKING_STORE)
2022         if (frame()->tiledBackingStore()) {
2023             frame()->tiledBackingStore()->invalidate(pixelSnappedIntRect(m_repaintRects[i]));
2024             continue;
2025         }
2026 #endif
2027         ScrollView::repaintContentRectangle(pixelSnappedIntRect(m_repaintRects[i]), false);
2028     }
2029     m_repaintRects.clear();
2030     m_repaintCount = 0;
2031     
2032     updateDeferredRepaintDelay();
2033 }
2034
2035 void FrameView::updateDeferredRepaintDelay()
2036 {
2037     Document* document = m_frame->document();
2038     if (!document || (!document->parsing() && !document->cachedResourceLoader()->requestCount())) {
2039         m_deferredRepaintDelay = s_deferredRepaintDelay;
2040         return;
2041     }
2042     if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) {
2043         m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading;
2044         if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading)
2045             m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading;
2046     }
2047 }
2048
2049 void FrameView::resetDeferredRepaintDelay()
2050 {
2051     m_deferredRepaintDelay = 0;
2052     if (m_deferredRepaintTimer.isActive()) {
2053         m_deferredRepaintTimer.stop();
2054         if (!m_deferringRepaints)
2055             doDeferredRepaints();
2056     }
2057 }
2058
2059 double FrameView::adjustedDeferredRepaintDelay() const
2060 {
2061     ASSERT(!m_deferringRepaints);
2062     if (!m_deferredRepaintDelay)
2063         return 0;
2064     double timeSinceLastPaint = currentTime() - m_lastPaintTime;
2065     return max(0., m_deferredRepaintDelay - timeSinceLastPaint);
2066 }
2067     
2068 void FrameView::deferredRepaintTimerFired(Timer<FrameView>*)
2069 {
2070     doDeferredRepaints();
2071 }
2072
2073 void FrameView::beginDisableRepaints()
2074 {
2075     m_disableRepaints++;
2076 }
2077
2078 void FrameView::endDisableRepaints()
2079 {
2080     ASSERT(m_disableRepaints > 0);
2081     m_disableRepaints--;
2082 }
2083
2084 void FrameView::layoutTimerFired(Timer<FrameView>*)
2085 {
2086 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2087     if (!m_frame->document()->ownerElement())
2088         printf("Layout timer fired at %d\n", m_frame->document()->elapsedTime());
2089 #endif
2090     layout();
2091 }
2092
2093 void FrameView::scheduleRelayout()
2094 {
2095     // FIXME: We should assert the page is not in the page cache, but that is causing
2096     // too many false assertions.  See <rdar://problem/7218118>.
2097     ASSERT(m_frame->view() == this);
2098
2099     if (m_layoutRoot) {
2100         m_layoutRoot->markContainingBlocksForLayout(false);
2101         m_layoutRoot = 0;
2102     }
2103     if (!m_layoutSchedulingEnabled)
2104         return;
2105     if (!needsLayout())
2106         return;
2107     if (!m_frame->document()->shouldScheduleLayout())
2108         return;
2109
2110     // When frame flattening is enabled, the contents of the frame could affect the layout of the parent frames.
2111     // Also invalidate parent frame starting from the owner element of this frame.
2112     if (m_frame->ownerRenderer() && isInChildFrameWithFrameFlattening())
2113         m_frame->ownerRenderer()->setNeedsLayout(true, MarkContainingBlockChain);
2114
2115     int delay = m_frame->document()->minimumLayoutDelay();
2116     if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
2117         unscheduleRelayout();
2118     if (m_layoutTimer.isActive())
2119         return;
2120
2121     m_delayedLayout = delay != 0;
2122
2123 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2124     if (!m_frame->document()->ownerElement())
2125         printf("Scheduling layout for %d\n", delay);
2126 #endif
2127
2128     m_layoutTimer.startOneShot(delay * 0.001);
2129 }
2130
2131 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
2132 {
2133     for (RenderObject* r = descendant; r; r = r->container()) {
2134         if (r == ancestor)
2135             return true;
2136     }
2137     return false;
2138 }
2139
2140 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
2141 {
2142     ASSERT(m_frame->view() == this);
2143
2144     RenderView* root = rootRenderer(this);
2145     if (root && root->needsLayout()) {
2146         if (relayoutRoot)
2147             relayoutRoot->markContainingBlocksForLayout(false);
2148         return;
2149     }
2150
2151     if (layoutPending() || !m_layoutSchedulingEnabled) {
2152         if (m_layoutRoot != relayoutRoot) {
2153             if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) {
2154                 // Keep the current root
2155                 relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot);
2156                 ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
2157             } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) {
2158                 // Re-root at relayoutRoot
2159                 m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
2160                 m_layoutRoot = relayoutRoot;
2161                 ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
2162             } else {
2163                 // Just do a full relayout
2164                 if (m_layoutRoot)
2165                     m_layoutRoot->markContainingBlocksForLayout(false);
2166                 m_layoutRoot = 0;
2167                 relayoutRoot->markContainingBlocksForLayout(false);
2168             }
2169         }
2170     } else if (m_layoutSchedulingEnabled) {
2171         int delay = m_frame->document()->minimumLayoutDelay();
2172         m_layoutRoot = relayoutRoot;
2173         ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
2174         m_delayedLayout = delay != 0;
2175         m_layoutTimer.startOneShot(delay * 0.001);
2176     }
2177 }
2178
2179 bool FrameView::layoutPending() const
2180 {
2181     return m_layoutTimer.isActive();
2182 }
2183
2184 bool FrameView::needsLayout() const
2185 {
2186     // This can return true in cases where the document does not have a body yet.
2187     // Document::shouldScheduleLayout takes care of preventing us from scheduling
2188     // layout in that case.
2189     if (!m_frame)
2190         return false;
2191
2192     RenderView* root = rootRenderer(this);
2193     return layoutPending()
2194         || (root && root->needsLayout())
2195         || m_layoutRoot
2196         || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred);
2197 }
2198
2199 void FrameView::setNeedsLayout()
2200 {
2201     if (m_deferSetNeedsLayouts) {
2202         m_setNeedsLayoutWasDeferred = true;
2203         return;
2204     }
2205
2206     if (RenderView* root = rootRenderer(this))
2207         root->setNeedsLayout(true);
2208 }
2209
2210 void FrameView::unscheduleRelayout()
2211 {
2212     if (!m_layoutTimer.isActive())
2213         return;
2214
2215 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2216     if (!m_frame->document()->ownerElement())
2217         printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
2218 #endif
2219     
2220     m_layoutTimer.stop();
2221     m_delayedLayout = false;
2222 }
2223
2224 #if ENABLE(REQUEST_ANIMATION_FRAME)
2225 void FrameView::serviceScriptedAnimations(DOMTimeStamp time)
2226 {
2227     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext()) {
2228         frame->view()->serviceScrollAnimations();
2229         frame->animation()->serviceAnimations();
2230     }
2231
2232     Vector<RefPtr<Document> > documents;
2233     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext())
2234         documents.append(frame->document());
2235
2236     for (size_t i = 0; i < documents.size(); ++i)
2237         documents[i]->serviceScriptedAnimations(time);
2238 }
2239 #endif
2240
2241 bool FrameView::isTransparent() const
2242 {
2243     return m_isTransparent;
2244 }
2245
2246 void FrameView::setTransparent(bool isTransparent)
2247 {
2248     m_isTransparent = isTransparent;
2249 }
2250
2251 Color FrameView::baseBackgroundColor() const
2252 {
2253     return m_baseBackgroundColor;
2254 }
2255
2256 void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
2257 {
2258     if (!backgroundColor.isValid())
2259         m_baseBackgroundColor = Color::white;
2260     else
2261         m_baseBackgroundColor = backgroundColor;
2262
2263     recalculateScrollbarOverlayStyle();
2264 }
2265
2266 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
2267 {
2268     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
2269         if (FrameView* view = frame->view()) {
2270             view->setTransparent(transparent);
2271             view->setBaseBackgroundColor(backgroundColor);
2272         }
2273     }
2274 }
2275
2276 bool FrameView::shouldUpdateWhileOffscreen() const
2277 {
2278     return m_shouldUpdateWhileOffscreen;
2279 }
2280
2281 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
2282 {
2283     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
2284 }
2285
2286 bool FrameView::shouldUpdate(bool immediateRequested) const
2287 {
2288     if (!immediateRequested && isOffscreen() && !shouldUpdateWhileOffscreen())
2289         return false;
2290     return true;
2291 }
2292
2293 void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget)
2294 {
2295     m_actionScheduler->scheduleEvent(event, eventTarget);
2296 }
2297
2298 void FrameView::pauseScheduledEvents()
2299 {
2300     m_actionScheduler->pause();
2301 }
2302
2303 void FrameView::resumeScheduledEvents()
2304 {
2305     m_actionScheduler->resume();
2306 }
2307
2308 void FrameView::scrollToAnchor()
2309 {
2310     RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
2311     if (!anchorNode)
2312         return;
2313
2314     if (!anchorNode->renderer())
2315         return;
2316
2317     LayoutRect rect;
2318     if (anchorNode != m_frame->document())
2319         rect = anchorNode->getRect();
2320
2321     // Scroll nested layers and frames to reveal the anchor.
2322     // Align to the top and to the closest side (this matches other browsers).
2323     anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
2324
2325     if (AXObjectCache::accessibilityEnabled())
2326         m_frame->document()->axObjectCache()->handleScrolledToAnchor(anchorNode.get());
2327
2328     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
2329     m_maintainScrollPositionAnchor = anchorNode;
2330 }
2331
2332 void FrameView::updateWidget(RenderEmbeddedObject* object)
2333 {
2334     ASSERT(!object->node() || object->node()->isElementNode());
2335     Element* ownerElement = static_cast<Element*>(object->node());
2336     // The object may have already been destroyed (thus node cleared),
2337     // but FrameView holds a manual ref, so it won't have been deleted.
2338     ASSERT(m_widgetUpdateSet->contains(object));
2339     if (!ownerElement)
2340         return;
2341
2342     // No need to update if it's already crashed or known to be missing.
2343     if (object->showsUnavailablePluginIndicator())
2344         return;
2345
2346     // FIXME: This could turn into a real virtual dispatch if we defined
2347     // updateWidget(PluginCreationOption) on HTMLElement.
2348     if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag) || ownerElement->hasTagName(appletTag)) {
2349         HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(ownerElement);
2350         if (pluginElement->needsWidgetUpdate())
2351             pluginElement->updateWidget(CreateAnyWidgetType);
2352     }
2353     // FIXME: It is not clear that Media elements need or want this updateWidget() call.
2354 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
2355     else if (ownerElement->isMediaElement())
2356         static_cast<HTMLMediaElement*>(ownerElement)->updateWidget(CreateAnyWidgetType);
2357 #endif
2358     else
2359         ASSERT_NOT_REACHED();
2360
2361     // Caution: it's possible the object was destroyed again, since loading a
2362     // plugin may run any arbitrary javascript.
2363     object->updateWidgetPosition();
2364 }
2365
2366 bool FrameView::updateWidgets()
2367 {
2368     if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
2369         return true;
2370     
2371     size_t size = m_widgetUpdateSet->size();
2372
2373     Vector<RenderEmbeddedObject*> objects;
2374     objects.reserveCapacity(size);
2375
2376     RenderEmbeddedObjectSet::const_iterator end = m_widgetUpdateSet->end();
2377     for (RenderEmbeddedObjectSet::const_iterator it = m_widgetUpdateSet->begin(); it != end; ++it) {
2378         objects.uncheckedAppend(*it);
2379         (*it)->ref();
2380     }
2381
2382     for (size_t i = 0; i < size; ++i) {
2383         RenderEmbeddedObject* object = objects[i];
2384         updateWidget(object);
2385         m_widgetUpdateSet->remove(object);
2386     }
2387
2388     RenderArena* arena = m_frame->document()->renderArena();
2389     for (size_t i = 0; i < size; ++i)
2390         objects[i]->deref(arena);
2391     
2392     return m_widgetUpdateSet->isEmpty();
2393 }
2394
2395 void FrameView::flushAnyPendingPostLayoutTasks()
2396 {
2397     if (!m_postLayoutTasksTimer.isActive())
2398         return;
2399
2400     performPostLayoutTasks();
2401 }
2402
2403 void FrameView::performPostLayoutTasks()
2404 {
2405     m_postLayoutTasksTimer.stop();
2406
2407     m_frame->selection()->setCaretRectNeedsUpdate();
2408     m_frame->selection()->updateAppearance();
2409
2410     if (m_nestedLayoutCount <= 1) {
2411         if (m_firstLayoutCallbackPending) {
2412             m_firstLayoutCallbackPending = false;
2413             m_frame->loader()->didFirstLayout();
2414             if (Page* page = m_frame->page()) {
2415                 if (page->mainFrame() == m_frame)
2416                     page->startCountingRelevantRepaintedObjects();
2417             }
2418         }
2419
2420         // Ensure that we always send this eventually.
2421         if (!m_frame->document()->parsing() && m_frame->loader()->stateMachine()->committedFirstRealDocumentLoad())
2422             m_isVisuallyNonEmpty = true;
2423
2424         // If the layout was done with pending sheets, we are not in fact visually non-empty yet.
2425         if (m_isVisuallyNonEmpty && !m_frame->document()->didLayoutWithPendingStylesheets() && m_firstVisuallyNonEmptyLayoutCallbackPending) {
2426             m_firstVisuallyNonEmptyLayoutCallbackPending = false;
2427             m_frame->loader()->didFirstVisuallyNonEmptyLayout();
2428         }
2429     }
2430
2431     m_frame->loader()->client()->dispatchDidLayout();
2432
2433     RenderView* root = rootRenderer(this);
2434     if (root)
2435         root->updateWidgetPositions();
2436     
2437     for (unsigned i = 0; i < maxUpdateWidgetsIterations; i++) {
2438         if (updateWidgets())
2439             break;
2440     }
2441
2442     if (Page* page = m_frame->page()) {
2443         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
2444             scrollingCoordinator->frameViewLayoutUpdated(this);
2445     }
2446
2447 #if USE(ACCELERATED_COMPOSITING)
2448     if (TiledBacking* tiledBacking = this->tiledBacking())
2449         tiledBacking->setCanHaveScrollbars(canHaveScrollbars());
2450 #endif
2451
2452     scrollToAnchor();
2453
2454     m_actionScheduler->resume();
2455
2456     if (root && !root->printing()) {
2457         IntSize currentSize;
2458         if (useFixedLayout() && !fixedLayoutSize().isEmpty() && delegatesScrolling())
2459             currentSize = fixedLayoutSize();
2460         else
2461             currentSize = visibleContentRect(true /*includeScrollbars*/).size();
2462         float currentZoomFactor = root->style()->zoom();
2463         bool resized = !m_firstLayout && (currentSize != m_lastViewportSize || currentZoomFactor != m_lastZoomFactor);
2464         m_lastViewportSize = currentSize;
2465         m_lastZoomFactor = currentZoomFactor;
2466 #if ENABLE(TIZEN_BLOCK_SENDING_RESIZE_EVENT_WHILE_LOADING)
2467         DocumentLoader* documentLoader = m_frame->loader()->documentLoader();
2468         if (resized && (!documentLoader || !documentLoader->isLoadingInAPISense())) {
2469 #else
2470         if (resized) {
2471 #endif
2472             m_frame->eventHandler()->sendResizeEvent();
2473
2474 #if ENABLE(INSPECTOR)
2475             if (InspectorInstrumentation::hasFrontends()) {
2476                 if (Page* page = m_frame->page()) {
2477                     if (page->mainFrame() == m_frame) {
2478                         if (InspectorClient* inspectorClient = page->inspectorController()->inspectorClient())
2479                             inspectorClient->didResizeMainFrame(m_frame.get());
2480                     }
2481                 }
2482             }
2483 #endif
2484         }
2485     }
2486 }
2487
2488 void FrameView::postLayoutTimerFired(Timer<FrameView>*)
2489 {
2490     performPostLayoutTasks();
2491 }
2492
2493 void FrameView::autoSizeIfEnabled()
2494 {
2495     if (!m_shouldAutoSize)
2496         return;
2497
2498     if (m_inAutoSize)
2499         return;
2500
2501     TemporaryChange<bool> changeInAutoSize(m_inAutoSize, true);
2502
2503     Document* document = frame()->document();
2504     if (!document)
2505         return;
2506
2507     RenderView* documentView = document->renderView();
2508     Element* documentElement = document->documentElement();
2509     if (!documentView || !documentElement)
2510         return;
2511
2512     RenderBox* documentRenderBox = documentElement->renderBox();
2513     if (!documentRenderBox)
2514         return;
2515
2516     // If this is the first time we run autosize, start from small height and
2517     // allow it to grow.
2518     if (!m_didRunAutosize)
2519         resize(frameRect().width(), m_minAutoSize.height());
2520
2521     IntSize size = frameRect().size();
2522
2523     // Do the resizing twice. The first time is basically a rough calculation using the preferred width
2524     // which may result in a height change during the second iteration.
2525     for (int i = 0; i < 2; i++) {
2526         // Update various sizes including contentsSize, scrollHeight, etc.
2527         document->updateLayoutIgnorePendingStylesheets();
2528         int width = documentView->minPreferredLogicalWidth();
2529         int height = documentRenderBox->scrollHeight();
2530         IntSize newSize(width, height);
2531
2532         // Check to see if a scrollbar is needed for a given dimension and
2533         // if so, increase the other dimension to account for the scrollbar.
2534         // Since the dimensions are only for the view rectangle, once a
2535         // dimension exceeds the maximum, there is no need to increase it further.
2536         if (newSize.width() > m_maxAutoSize.width()) {
2537             RefPtr<Scrollbar> localHorizontalScrollbar = horizontalScrollbar();
2538             if (!localHorizontalScrollbar)
2539                 localHorizontalScrollbar = createScrollbar(HorizontalScrollbar);
2540             if (!localHorizontalScrollbar->isOverlayScrollbar())
2541                 newSize.setHeight(newSize.height() + localHorizontalScrollbar->height());
2542
2543             // Don't bother checking for a vertical scrollbar because the width is at
2544             // already greater the maximum.
2545         } else if (newSize.height() > m_maxAutoSize.height()) {
2546             RefPtr<Scrollbar> localVerticalScrollbar = verticalScrollbar();
2547             if (!localVerticalScrollbar)
2548                 localVerticalScrollbar = createScrollbar(VerticalScrollbar);
2549             if (!localVerticalScrollbar->isOverlayScrollbar())
2550                 newSize.setWidth(newSize.width() + localVerticalScrollbar->width());
2551
2552             // Don't bother checking for a horizontal scrollbar because the height is
2553             // already greater the maximum.
2554         }
2555
2556         // Ensure the size is at least the min bounds.
2557         newSize = newSize.expandedTo(m_minAutoSize);
2558
2559         // Bound the dimensions by the max bounds and determine what scrollbars to show.
2560         ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff;
2561         if (newSize.width() > m_maxAutoSize.width()) {
2562             newSize.setWidth(m_maxAutoSize.width());
2563             horizonalScrollbarMode = ScrollbarAlwaysOn;
2564         }
2565         ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff;
2566         if (newSize.height() > m_maxAutoSize.height()) {
2567             newSize.setHeight(m_maxAutoSize.height());
2568             verticalScrollbarMode = ScrollbarAlwaysOn;
2569         }
2570
2571         if (newSize == size)
2572             continue;
2573
2574         // Avoid doing resizing to a smaller size while the frame is loading to avoid switching to a small size
2575         // during an intermediate state (and then changing back to a bigger size as the load progresses).
2576         if (!frame()->loader()->isComplete() && (newSize.height() < size.height() || newSize.width() < size.width()))
2577             break;
2578         else if (document->processingLoadEvent())
2579             newSize = newSize.expandedTo(size);
2580         resize(newSize.width(), newSize.height());
2581         // Force the scrollbar state to avoid the scrollbar code adding them and causing them to be needed. For example,
2582         // a vertical scrollbar may cause text to wrap and thus increase the height (which is the only reason the scollbar is needed).
2583         setVerticalScrollbarLock(false);
2584         setHorizontalScrollbarLock(false);
2585         setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true);
2586     }
2587     m_didRunAutosize = true;
2588 }
2589
2590 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
2591 {
2592     if (!m_viewportRenderer)
2593         return;
2594     
2595     if (m_overflowStatusDirty) {
2596         m_horizontalOverflow = horizontalOverflow;
2597         m_verticalOverflow = verticalOverflow;
2598         m_overflowStatusDirty = false;
2599         return;
2600     }
2601     
2602     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
2603     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
2604     
2605     if (horizontalOverflowChanged || verticalOverflowChanged) {
2606         m_horizontalOverflow = horizontalOverflow;
2607         m_verticalOverflow = verticalOverflow;
2608         
2609         m_actionScheduler->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
2610             verticalOverflowChanged, verticalOverflow),
2611             m_viewportRenderer->node());
2612     }
2613     
2614 }
2615
2616 IntRect FrameView::windowClipRect(bool clipToContents) const
2617 {
2618     ASSERT(m_frame->view() == this);
2619
2620     if (paintsEntireContents())
2621         return IntRect(IntPoint(), contentsSize());
2622
2623     // Set our clip rect to be our contents.
2624     IntRect clipRect = contentsToWindow(visibleContentRect(!clipToContents));
2625     if (!m_frame || !m_frame->ownerElement())
2626         return clipRect;
2627
2628     // Take our owner element and get its clip rect.
2629     HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement();
2630     FrameView* parentView = ownerElement->document()->view();
2631     if (parentView)
2632         clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement, true));
2633     return clipRect;
2634 }
2635
2636 IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement, bool clipToLayerContents) const
2637 {
2638     // The renderer can sometimes be null when style="display:none" interacts
2639     // with external content and plugins.
2640     if (!ownerElement->renderer())
2641         return windowClipRect();
2642
2643     // If we have no layer, just return our window clip rect.
2644     const RenderLayer* enclosingLayer = ownerElement->renderer()->enclosingLayer();
2645     if (!enclosingLayer)
2646         return windowClipRect();
2647
2648     // Apply the clip from the layer.
2649     IntRect clipRect;
2650     if (clipToLayerContents)
2651         clipRect = pixelSnappedIntRect(enclosingLayer->childrenClipRect());
2652     else
2653         clipRect = pixelSnappedIntRect(enclosingLayer->selfClipRect());
2654     clipRect = contentsToWindow(clipRect); 
2655     return intersection(clipRect, windowClipRect());
2656 }
2657
2658 bool FrameView::isActive() const
2659 {
2660     Page* page = frame()->page();
2661     return page && page->focusController()->isActive();
2662 }
2663
2664 void FrameView::scrollTo(const IntSize& newOffset)
2665 {
2666     LayoutSize offset = scrollOffset();
2667     ScrollView::scrollTo(newOffset);
2668     if (offset != scrollOffset())
2669         scrollPositionChanged();
2670     frame()->loader()->client()->didChangeScrollOffset();
2671 }
2672
2673 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
2674 {
2675     // Add in our offset within the FrameView.
2676     IntRect dirtyRect = rect;
2677     dirtyRect.moveBy(scrollbar->location());
2678     invalidateRect(dirtyRect);
2679 }
2680
2681 void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
2682 {
2683     tickmarks = frame()->document()->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch);
2684 }
2685
2686 IntRect FrameView::windowResizerRect() const
2687 {
2688     Page* page = frame() ? frame()->page() : 0;
2689     if (!page)
2690         return IntRect();
2691     return page->chrome()->windowResizerRect();
2692 }
2693
2694 void FrameView::setVisibleScrollerThumbRect(const IntRect& scrollerThumb)
2695 {
2696     Page* page = m_frame->page();
2697     if (!page)
2698         return;
2699     if (page->mainFrame() != m_frame)
2700         return;
2701     page->chrome()->client()->notifyScrollerThumbIsVisibleInRect(scrollerThumb);
2702 }
2703
2704 bool FrameView::isOnActivePage() const
2705 {
2706     if (!m_frame)
2707         return false;
2708     if (m_frame->view() != this)
2709         return false;
2710     if (Document* document = m_frame->document())
2711         return !document->inPageCache();
2712     return false;
2713 }
2714
2715 ScrollableArea* FrameView::enclosingScrollableArea() const
2716 {
2717     // FIXME: Walk up the frame tree and look for a scrollable parent frame or RenderLayer.
2718     return 0;
2719 }
2720
2721 IntRect FrameView::scrollableAreaBoundingBox() const
2722 {
2723     // FIXME: This isn't correct for transformed frames. We probably need to ask the renderer instead.
2724     return frameRect();
2725 }
2726
2727 void FrameView::updateScrollableAreaSet()
2728 {
2729     // That ensures that only inner frames are cached.
2730     if (!parentFrameView())
2731         return;
2732
2733     // Check for:
2734     // 1) display:none or visibility:hidden set to self or inherited.
2735     // 2) overflow{-x,-y}: hidden;
2736     // 3) scrolling: no;
2737
2738     // Covers #1.
2739     HTMLFrameOwnerElement* owner = m_frame->ownerElement();
2740     if (!owner || !owner->renderer() || !owner->renderer()->visibleToHitTesting()) {
2741         parentFrameView()->removeScrollableArea(this);
2742         return;
2743     }
2744
2745     IntSize contentSize = contentsSize();
2746     IntSize visibleContentSize = visibleContentRect().size();
2747     if ((contentSize.height() <= visibleContentSize.height() && contentSize.width() <= visibleContentSize.width())) {
2748         parentFrameView()->removeScrollableArea(this);
2749         return;
2750     }
2751
2752     // Cover #2 and #3.
2753     ScrollbarMode horizontalMode;
2754     ScrollbarMode verticalMode;
2755     calculateScrollbarModesForLayout(horizontalMode, verticalMode, RulesFromWebContentOnly);
2756     if (horizontalMode == ScrollbarAlwaysOff && verticalMode == ScrollbarAlwaysOff) {
2757         parentFrameView()->removeScrollableArea(this);
2758         return;
2759     }
2760
2761     parentFrameView()->addScrollableArea(this);
2762 }
2763
2764 bool FrameView::shouldSuspendScrollAnimations() const
2765 {
2766     return m_frame->loader()->state() != FrameStateComplete;
2767 }
2768
2769 void FrameView::scrollbarStyleChanged(int newStyle, bool forceUpdate)
2770 {
2771     Page* page = m_frame->page();
2772     if (!page)
2773         return;
2774     if (page->mainFrame() != m_frame)
2775         return;
2776     page->chrome()->client()->recommendedScrollbarStyleDidChange(newStyle);
2777
2778     if (forceUpdate)
2779         ScrollView::scrollbarStyleChanged(newStyle, forceUpdate);
2780 }
2781
2782 void FrameView::setAnimatorsAreActive()
2783 {
2784     Page* page = m_frame->page();
2785     if (!page)
2786         return;
2787
2788     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
2789         scrollAnimator->setIsActive();
2790
2791     if (!m_scrollableAreas)
2792         return;
2793
2794     for (HashSet<ScrollableArea*>::const_iterator it = m_scrollableAreas->begin(), end = m_scrollableAreas->end(); it != end; ++it) {
2795         ScrollableArea* scrollableArea = *it;
2796
2797         ASSERT(scrollableArea->isOnActivePage());
2798         scrollableArea->scrollAnimator()->setIsActive();
2799     }
2800 }
2801
2802 void FrameView::notifyPageThatContentAreaWillPaint() const
2803 {
2804     Page* page = m_frame->page();
2805     if (!page)
2806         return;
2807
2808     contentAreaWillPaint();
2809
2810     if (!m_scrollableAreas)
2811         return;
2812
2813     for (HashSet<ScrollableArea*>::const_iterator it = m_scrollableAreas->begin(), end = m_scrollableAreas->end(); it != end; ++it) {
2814         ScrollableArea* scrollableArea = *it;
2815
2816         if (!scrollableArea->isOnActivePage())
2817             continue;
2818
2819         scrollableArea->contentAreaWillPaint();
2820     }
2821 }
2822
2823 bool FrameView::scrollAnimatorEnabled() const
2824 {
2825 #if ENABLE(SMOOTH_SCROLLING)
2826     if (Page* page = m_frame->page())
2827         return page->settings()->scrollAnimatorEnabled();
2828 #endif
2829
2830     return false;
2831 }
2832
2833 #if ENABLE(DASHBOARD_SUPPORT)
2834 void FrameView::updateDashboardRegions()
2835 {
2836     Document* document = m_frame->document();
2837     if (!document->hasDashboardRegions())
2838         return;
2839     Vector<DashboardRegionValue> newRegions;
2840     document->renderBox()->collectDashboardRegions(newRegions);
2841     if (newRegions == document->dashboardRegions())
2842         return;
2843     document->setDashboardRegions(newRegions);
2844     Page* page = m_frame->page();
2845     if (!page)
2846         return;
2847     page->chrome()->client()->dashboardRegionsChanged();
2848 }
2849 #endif
2850
2851 void FrameView::updateScrollCorner()
2852 {
2853     RenderObject* renderer = 0;
2854     RefPtr<RenderStyle> cornerStyle;
2855     IntRect cornerRect = scrollCornerRect();
2856     
2857     if (!cornerRect.isEmpty()) {
2858         // Try the <body> element first as a scroll corner source.
2859         Document* doc = m_frame->document();
2860         Element* body = doc ? doc->body() : 0;
2861         if (body && body->renderer()) {
2862             renderer = body->renderer();
2863             cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
2864         }
2865         
2866         if (!cornerStyle) {
2867             // If the <body> didn't have a custom style, then the root element might.
2868             Element* docElement = doc ? doc->documentElement() : 0;
2869             if (docElement && docElement->renderer()) {
2870                 renderer = docElement->renderer();
2871                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
2872             }
2873         }
2874         
2875         if (!cornerStyle) {
2876             // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
2877             if (RenderPart* renderer = m_frame->ownerRenderer())
2878                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
2879         }
2880     }
2881
2882     if (cornerStyle) {
2883         if (!m_scrollCorner)
2884             m_scrollCorner = new (renderer->renderArena()) RenderScrollbarPart(renderer->document());
2885         m_scrollCorner->setStyle(cornerStyle.release());
2886         invalidateScrollCorner(cornerRect);
2887     } else if (m_scrollCorner) {
2888         m_scrollCorner->destroy();
2889         m_scrollCorner = 0;
2890     }
2891
2892     ScrollView::updateScrollCorner();
2893 }
2894
2895 void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
2896 {
2897     if (context->updatingControlTints()) {
2898         updateScrollCorner();
2899         return;
2900     }
2901
2902     if (m_scrollCorner) {
2903         bool needsBackgorund = m_frame->page() && m_frame->page()->mainFrame() == m_frame;
2904         if (needsBackgorund)
2905             context->fillRect(cornerRect, baseBackgroundColor(), ColorSpaceDeviceRGB);
2906         m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect);
2907         return;
2908     }
2909
2910     ScrollView::paintScrollCorner(context, cornerRect);
2911 }
2912
2913 void FrameView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
2914 {
2915     bool needsBackgorund = bar->isCustomScrollbar() && (m_frame->page() && m_frame->page()->mainFrame() == m_frame);
2916     if (needsBackgorund) {
2917         IntRect toFill = bar->frameRect();
2918         toFill.intersect(rect);
2919         context->fillRect(toFill, baseBackgroundColor(), ColorSpaceDeviceRGB);
2920     }
2921
2922     ScrollView::paintScrollbar(context, bar, rect);
2923 }
2924
2925 Color FrameView::documentBackgroundColor() const
2926 {
2927     // <https://bugs.webkit.org/show_bug.cgi?id=59540> We blend the background color of
2928     // the document and the body against the base background color of the frame view.
2929     // Background images are unfortunately impractical to include.
2930
2931     // Return invalid Color objects whenever there is insufficient information.
2932     if (!frame()->document())
2933         return Color();
2934
2935     Element* htmlElement = frame()->document()->documentElement();
2936     Element* bodyElement = frame()->document()->body();
2937
2938     // Start with invalid colors.
2939     Color htmlBackgroundColor;
2940     Color bodyBackgroundColor;
2941     if (htmlElement && htmlElement->renderer())
2942         htmlBackgroundColor = htmlElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor);
2943     if (bodyElement && bodyElement->renderer())
2944         bodyBackgroundColor = bodyElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor);
2945
2946     if (!bodyBackgroundColor.isValid()) {
2947         if (!htmlBackgroundColor.isValid())
2948             return Color();
2949         return baseBackgroundColor().blend(htmlBackgroundColor);
2950     }
2951
2952     if (!htmlBackgroundColor.isValid())
2953         return baseBackgroundColor().blend(bodyBackgroundColor);
2954
2955     // We take the aggregate of the base background color
2956     // the <html> background color, and the <body>
2957     // background color to find the document color. The
2958     // addition of the base background color is not
2959     // technically part of the document background, but it
2960     // otherwise poses problems when the aggregate is not
2961     // fully opaque.
2962     return baseBackgroundColor().blend(htmlBackgroundColor).blend(bodyBackgroundColor);
2963 }
2964
2965 bool FrameView::hasCustomScrollbars() const
2966 {
2967     const HashSet<RefPtr<Widget> >* viewChildren = children();
2968     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
2969     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
2970         Widget* widget = current->get();
2971         if (widget->isFrameView()) {
2972             if (static_cast<FrameView*>(widget)->hasCustomScrollbars())
2973                 return true;
2974         } else if (widget->isScrollbar()) {
2975             Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
2976             if (scrollbar->isCustomScrollbar())
2977                 return true;
2978         }
2979     }
2980
2981     return false;
2982 }
2983
2984 FrameView* FrameView::parentFrameView() const
2985 {
2986     if (Frame* parentFrame = m_frame->tree()->parent())
2987         return parentFrame->view();
2988
2989     return 0;
2990 }
2991
2992 bool FrameView::isInChildFrameWithFrameFlattening() const
2993 {
2994     if (!parent() || !m_frame->ownerElement())
2995         return false;
2996
2997     // Frame flattening applies when the owner element is either in a frameset or
2998     // an iframe with flattening parameters.
2999     if (m_frame->ownerElement()->hasTagName(iframeTag)) {
3000         RenderIFrame* iframeRenderer = toRenderIFrame(m_frame->ownerElement()->renderPart());
3001         if (iframeRenderer->flattenFrame() || iframeRenderer->isSeamless())
3002             return true;
3003     }
3004
3005     if (!m_frame->settings() || !m_frame->settings()->frameFlatteningEnabled())
3006         return false;
3007
3008     if (m_frame->ownerElement()->hasTagName(frameTag))
3009         return true;
3010
3011     return false;
3012 }
3013
3014 bool FrameView::doLayoutWithFrameFlattening(bool allowSubtree)
3015 {
3016     // Try initiating layout from the topmost parent.
3017     FrameView* parentView = parentFrameView();
3018
3019     if (!parentView)
3020         return false;
3021
3022     // In the middle of parent layout, no need to restart from topmost.
3023     if (parentView->m_nestedLayoutCount)
3024         return false;
3025
3026     // Parent tree is clean. Starting layout from it would have no effect.
3027     if (!parentView->needsLayout())
3028         return false;
3029
3030     while (parentView->parentFrameView())
3031         parentView = parentView->parentFrameView();
3032
3033     parentView->layout(allowSubtree);
3034
3035     RenderObject* root = m_layoutRoot ? m_layoutRoot : m_frame->document()->renderer();
3036     ASSERT_UNUSED(root, !root->needsLayout());
3037
3038     return true;
3039 }
3040
3041 void FrameView::updateControlTints()
3042 {
3043     // This is called when control tints are changed from aqua/graphite to clear and vice versa.
3044     // We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
3045     // This is only done if the theme supports control tinting. It's up to the theme and platform
3046     // to define when controls get the tint and to call this function when that changes.
3047     
3048     // Optimize the common case where we bring a window to the front while it's still empty.
3049     if (!m_frame || m_frame->document()->url().isEmpty())
3050         return;
3051
3052     RenderView* root = rootRenderer(this);
3053     if ((root && root->theme()->supportsControlTints()) || hasCustomScrollbars())
3054         paintControlTints();
3055 }
3056
3057 void FrameView::paintControlTints()
3058 {
3059     if (needsLayout())
3060         layout();
3061     PlatformGraphicsContext* const noContext = 0;
3062     GraphicsContext context(noContext);
3063     context.setUpdatingControlTints(true);
3064     if (platformWidget())
3065         paintContents(&context, visibleContentRect());
3066     else
3067         paint(&context, frameRect());
3068 }
3069
3070 bool FrameView::wasScrolledByUser() const
3071 {
3072     return m_wasScrolledByUser;
3073 }
3074
3075 void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
3076 {
3077     if (m_inProgrammaticScroll)
3078         return;
3079     m_maintainScrollPositionAnchor = 0;
3080     m_wasScrolledByUser = wasScrolledByUser;
3081 }
3082
3083 void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
3084 {
3085     if (!frame())
3086         return;
3087
3088     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_frame.get(), p, rect);
3089
3090     Document* document = m_frame->document();
3091
3092 #ifndef NDEBUG
3093     bool fillWithRed;
3094     if (document->printing())
3095         fillWithRed = false; // Printing, don't fill with red (can't remember why).
3096     else if (m_frame->ownerElement())
3097         fillWithRed = false; // Subframe, don't fill with red.
3098     else if (isTransparent())
3099         fillWithRed = false; // Transparent, don't fill with red.
3100     else if (m_paintBehavior & PaintBehaviorSelectionOnly)
3101         fillWithRed = false; // Selections are transparent, don't fill with red.
3102     else if (m_nodeToDraw)
3103         fillWithRed = false; // Element images are transparent, don't fill with red.
3104     else
3105         fillWithRed = true;
3106     
3107     if (fillWithRed)
3108         p->fillRect(rect, Color(0xFF, 0, 0), ColorSpaceDeviceRGB);
3109 #endif
3110
3111     Page* page = m_frame->page();
3112     if (page->mainFrame() == m_frame && page->pagination().mode != Page::Pagination::Unpaginated)
3113         p->fillRect(rect, baseBackgroundColor(), ColorSpaceDeviceRGB);
3114     
3115     RenderView* root = rootRenderer(this);
3116     if (!root) {
3117         LOG_ERROR("called FrameView::paint with nil renderer");
3118         return;
3119     }
3120
3121     ASSERT(!needsLayout());
3122     if (needsLayout())
3123         return;
3124
3125     bool isTopLevelPainter = !sCurrentPaintTimeStamp;
3126     if (isTopLevelPainter)
3127         sCurrentPaintTimeStamp = currentTime();
3128
3129     FontCachePurgePreventer fontCachePurgePreventer;
3130
3131 #if USE(ACCELERATED_COMPOSITING)
3132     if (!p->paintingDisabled() && !document->printing())
3133         syncCompositingStateForThisFrame(m_frame.get());
3134 #endif
3135
3136     PaintBehavior oldPaintBehavior = m_paintBehavior;
3137     
3138     if (FrameView* parentView = parentFrameView()) {
3139         if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers)
3140             m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
3141     }
3142     
3143     if (m_paintBehavior == PaintBehaviorNormal)
3144         document->markers()->invalidateRenderedRectsForMarkersInRect(rect);
3145
3146     if (document->printing())
3147         m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
3148
3149     bool flatteningPaint = m_paintBehavior & PaintBehaviorFlattenCompositingLayers;
3150     bool isRootFrame = !m_frame->ownerElement();
3151     if (flatteningPaint && isRootFrame)
3152         notifyWidgetsInAllFrames(WillPaintFlattened);
3153
3154     ASSERT(!m_isPainting);
3155     m_isPainting = true;
3156
3157     // m_nodeToDraw is used to draw only one element (and its descendants)
3158     RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
3159     RenderLayer* rootLayer = root->layer();
3160
3161     rootLayer->paint(p, rect, m_paintBehavior, eltRenderer);
3162
3163     if (rootLayer->containsDirtyOverlayScrollbars())
3164         rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, eltRenderer);
3165
3166     m_isPainting = false;
3167
3168     if (flatteningPaint && isRootFrame)
3169         notifyWidgetsInAllFrames(DidPaintFlattened);
3170
3171     m_paintBehavior = oldPaintBehavior;
3172     m_lastPaintTime = currentTime();
3173
3174 #if ENABLE(DASHBOARD_SUPPORT)
3175     // Regions may have changed as a result of the visibility/z-index of element changing.
3176     if (document->dashboardRegionsDirty())
3177         updateDashboardRegions();
3178 #endif
3179
3180     if (isTopLevelPainter)
3181         sCurrentPaintTimeStamp = 0;
3182
3183     InspectorInstrumentation::didPaint(cookie);
3184 }
3185
3186 void FrameView::setPaintBehavior(PaintBehavior behavior)
3187 {
3188     m_paintBehavior = behavior;
3189 }
3190
3191 PaintBehavior FrameView::paintBehavior() const
3192 {
3193     return m_paintBehavior;
3194 }
3195
3196 bool FrameView::isPainting() const
3197 {
3198     return m_isPainting;
3199 }
3200
3201 void FrameView::setNodeToDraw(Node* node)
3202 {
3203     m_nodeToDraw = node;
3204 }
3205
3206 void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
3207 {
3208     if (context->paintingDisabled())
3209         return;
3210
3211     if (m_frame->document()->printing())
3212         return;
3213
3214     Page* page = m_frame->page();
3215     if (page->mainFrame() == m_frame) {
3216         if (page->chrome()->client()->paintCustomOverhangArea(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect))
3217             return;
3218     }
3219
3220     ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
3221 }
3222
3223 void FrameView::updateLayoutAndStyleIfNeededRecursive()
3224 {
3225     // We have to crawl our entire tree looking for any FrameViews that need
3226     // layout and make sure they are up to date.
3227     // Mac actually tests for intersection with the dirty region and tries not to
3228     // update layout for frames that are outside the dirty region.  Not only does this seem
3229     // pointless (since those frames will have set a zero timer to layout anyway), but
3230     // it is also incorrect, since if two frames overlap, the first could be excluded from the dirty
3231     // region but then become included later by the second frame adding rects to the dirty region
3232     // when it lays out.
3233
3234     m_frame->document()->updateStyleIfNeeded();
3235
3236     if (needsLayout())
3237         layout();
3238
3239     // Grab a copy of the children() set, as it may be mutated by the following updateLayoutAndStyleIfNeededRecursive
3240     // calls, as they can potentially re-enter a layout of the parent frame view, which may add/remove scrollbars
3241     // and thus mutates the children() set.
3242     Vector<RefPtr<FrameView> > frameViews;
3243     collectFrameViewChildren(this, frameViews);
3244
3245     const Vector<RefPtr<FrameView> >::iterator end = frameViews.end();
3246     for (Vector<RefPtr<FrameView> >::iterator it = frameViews.begin(); it != end; ++it)
3247         (*it)->updateLayoutAndStyleIfNeededRecursive();
3248
3249     // updateLayoutAndStyleIfNeededRecursive is called when we need to make sure style and layout are up-to-date before
3250     // painting, so we need to flush out any deferred repaints too.
3251     flushDeferredRepaints();
3252
3253     // When frame flattening is on, child frame can mark parent frame dirty. In such case, child frame
3254     // needs to call layout on parent frame recursively.
3255     // This assert ensures that parent frames are clean, when child frames finished updating layout and style.
3256     ASSERT(!needsLayout());
3257 }
3258     
3259 void FrameView::flushDeferredRepaints()
3260 {
3261     if (!m_deferredRepaintTimer.isActive())
3262         return;
3263     m_deferredRepaintTimer.stop();
3264     doDeferredRepaints();
3265 }
3266
3267 void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize)
3268 {
3269     ASSERT(!enable || !minSize.isEmpty());
3270     ASSERT(minSize.width() <= maxSize.width());
3271     ASSERT(minSize.height() <= maxSize.height());
3272
3273     if (m_shouldAutoSize == enable && m_minAutoSize == minSize && m_maxAutoSize == maxSize)
3274         return;
3275
3276     m_shouldAutoSize = enable;
3277     m_minAutoSize = minSize;
3278     m_maxAutoSize = maxSize;
3279     m_didRunAutosize = false;
3280
3281     setNeedsLayout();
3282     scheduleRelayout();
3283     if (m_shouldAutoSize)
3284         return;
3285
3286     // Since autosize mode forces the scrollbar mode, change them to being auto.
3287     setVerticalScrollbarLock(false);
3288     setHorizontalScrollbarLock(false);
3289     setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
3290 }
3291
3292 void FrameView::forceLayout(bool allowSubtree)
3293 {
3294     layout(allowSubtree);
3295 }
3296
3297 void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor, AdjustViewSizeOrNot shouldAdjustViewSize)
3298 {
3299     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
3300     // the state of things before and after the layout
3301     if (RenderView* root = rootRenderer(this)) {
3302         float pageLogicalWidth = root->style()->isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
3303         float pageLogicalHeight = root->style()->isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
3304
3305         LayoutUnit flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
3306         LayoutUnit flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
3307         root->setLogicalWidth(flooredPageLogicalWidth);
3308         root->setPageLogicalHeight(flooredPageLogicalHeight);
3309         root->setNeedsLayoutAndPrefWidthsRecalc();
3310         forceLayout();
3311
3312         // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
3313         // page width when shrunk, we will lay out at maximum shrink and clip extra content.
3314         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
3315         // implementation should not do this!
3316         bool horizontalWritingMode = root->style()->isHorizontalWritingMode();
3317         const LayoutRect& documentRect = root->documentRect();
3318         LayoutUnit docLogicalWidth = horizontalWritingMode ? documentRect.width() : documentRect.height();
3319         if (docLogicalWidth > pageLogicalWidth) {
3320             int expectedPageWidth = std::min<float>(documentRect.width(), pageSize.width() * maximumShrinkFactor);
3321             int expectedPageHeight = std::min<float>(documentRect.height(), pageSize.height() * maximumShrinkFactor);
3322             FloatSize maxPageSize = m_frame->resizePageRectsKeepingRatio(FloatSize(originalPageSize.width(), originalPageSize.height()), FloatSize(expectedPageWidth, expectedPageHeight));
3323             pageLogicalWidth = horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
3324             pageLogicalHeight = horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();
3325
3326             flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
3327             flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
3328             root->setLogicalWidth(flooredPageLogicalWidth);
3329             root->setPageLogicalHeight(flooredPageLogicalHeight);
3330             root->setNeedsLayoutAndPrefWidthsRecalc();
3331             forceLayout();
3332
3333             const LayoutRect& updatedDocumentRect = root->documentRect();
3334             LayoutUnit docLogicalHeight = horizontalWritingMode ? updatedDocumentRect.height() : updatedDocumentRect.width();
3335             LayoutUnit docLogicalTop = horizontalWritingMode ? updatedDocumentRect.y() : updatedDocumentRect.x();
3336             LayoutUnit docLogicalRight = horizontalWritingMode ? updatedDocumentRect.maxX() : updatedDocumentRect.maxY();
3337             LayoutUnit clippedLogicalLeft = 0;
3338             if (!root->style()->isLeftToRightDirection())
3339                 clippedLogicalLeft = docLogicalRight - pageLogicalWidth;
3340             LayoutRect overflow(clippedLogicalLeft, docLogicalTop, pageLogicalWidth, docLogicalHeight);
3341
3342             if (!horizontalWritingMode)
3343                 overflow = overflow.transposedRect();
3344             root->clearLayoutOverflow();
3345             root->addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
3346         }
3347     }
3348
3349     if (shouldAdjustViewSize)
3350         adjustViewSize();
3351 }
3352
3353 void FrameView::adjustPageHeightDeprecated(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
3354 {
3355     if (RenderView* root = rootRenderer(this)) {
3356         // Use a context with painting disabled.
3357         GraphicsContext context((PlatformGraphicsContext*)0);
3358         root->setTruncatedAt(static_cast<int>(floorf(oldBottom)));
3359         IntRect dirtyRect(0, static_cast<int>(floorf(oldTop)), root->layoutOverflowRect().maxX(), static_cast<int>(ceilf(oldBottom - oldTop)));
3360         root->setPrintRect(dirtyRect);
3361         root->layer()->paint(&context, dirtyRect);
3362         *newBottom = root->bestTruncatedAt();
3363         if (*newBottom == 0)
3364             *newBottom = oldBottom;
3365         root->setPrintRect(IntRect());
3366     } else
3367         *newBottom = oldBottom;
3368 }
3369
3370 IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
3371 {
3372     IntRect rect = renderer->localToAbsoluteQuad(FloatRect(rendererRect)).enclosingBoundingBox();
3373
3374     // Convert from page ("absolute") to FrameView coordinates.
3375     if (!delegatesScrolling())
3376         rect.moveBy(-scrollPosition());
3377
3378     return rect;
3379 }
3380
3381 IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect& viewRect) const
3382 {
3383     IntRect rect = viewRect;
3384     
3385     // Convert from FrameView coords into page ("absolute") coordinates.
3386     if (!delegatesScrolling())
3387         rect.moveBy(scrollPosition());
3388
3389     // FIXME: we don't have a way to map an absolute rect down to a local quad, so just
3390     // move the rect for now.
3391     rect.setLocation(roundedIntPoint(renderer->absoluteToLocal(rect.location(), false, true /* use transforms */)));
3392     return rect;
3393 }
3394
3395 IntPoint FrameView::convertFromRenderer(const RenderObject* renderer, const IntPoint& rendererPoint) const
3396 {
3397     IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, false, true /* use transforms */));
3398
3399     // Convert from page ("absolute") to FrameView coordinates.
3400     if (!delegatesScrolling())
3401         point.moveBy(-scrollPosition());
3402     return point;
3403 }
3404
3405 IntPoint FrameView::convertToRenderer(const RenderObject* renderer, const IntPoint& viewPoint) const
3406 {
3407     IntPoint point = viewPoint;
3408
3409     // Convert from FrameView coords into page ("absolute") coordinates.
3410     if (!delegatesScrolling())
3411         point += IntSize(scrollX(), scrollY());
3412
3413     return roundedIntPoint(renderer->absoluteToLocal(point, false, true /* use transforms */));
3414 }
3415
3416 IntRect FrameView::convertToContainingView(const IntRect& localRect) const
3417 {
3418     if (const ScrollView* parentScrollView = parent()) {
3419         if (parentScrollView->isFrameView()) {
3420             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
3421             // Get our renderer in the parent view
3422             RenderPart* renderer = m_frame->ownerRenderer();
3423             if (!renderer)
3424                 return localRect;
3425                 
3426             IntRect rect(localRect);
3427             // Add borders and padding??
3428             rect.move(renderer->borderLeft() + renderer->paddingLeft(),
3429                       renderer->borderTop() + renderer->paddingTop());
3430             return parentView->convertFromRenderer(renderer, rect);
3431         }
3432         
3433         return Widget::convertToContainingView(localRect);
3434     }
3435     
3436     return localRect;
3437 }
3438
3439 IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
3440 {
3441     if (const ScrollView* parentScrollView = parent()) {
3442         if (parentScrollView->isFrameView()) {
3443             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
3444
3445             // Get our renderer in the parent view
3446             RenderPart* renderer = m_frame->ownerRenderer();
3447             if (!renderer)
3448                 return parentRect;
3449
3450             IntRect rect = parentView->convertToRenderer(renderer, parentRect);
3451             // Subtract borders and padding
3452             rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
3453                       -renderer->borderTop() - renderer->paddingTop());
3454             return rect;
3455         }
3456         
3457         return Widget::convertFromContainingView(parentRect);
3458     }
3459     
3460     return parentRect;
3461 }
3462
3463 IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
3464 {
3465     if (const ScrollView* parentScrollView = parent()) {
3466         if (parentScrollView->isFrameView()) {
3467             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
3468
3469             // Get our renderer in the parent view
3470             RenderPart* renderer = m_frame->ownerRenderer();
3471             if (!renderer)
3472                 return localPoint;
3473                 
3474             IntPoint point(localPoint);
3475
3476             // Add borders and padding
3477             point.move(renderer->borderLeft() + renderer->paddingLeft(),
3478                        renderer->borderTop() + renderer->paddingTop());
3479             return parentView->convertFromRenderer(renderer, point);
3480         }
3481         
3482         return Widget::convertToContainingView(localPoint);
3483     }
3484     
3485     return localPoint;
3486 }
3487
3488 IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
3489 {
3490     if (const ScrollView* parentScrollView = parent()) {
3491         if (parentScrollView->isFrameView()) {
3492             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
3493
3494             // Get our renderer in the parent view
3495             RenderPart* renderer = m_frame->ownerRenderer();
3496             if (!renderer)
3497                 return parentPoint;
3498
3499             IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
3500             // Subtract borders and padding
3501             point.move(-renderer->borderLeft() - renderer->paddingLeft(),
3502                        -renderer->borderTop() - renderer->paddingTop());
3503             return point;
3504         }
3505         
3506         return Widget::convertFromContainingView(parentPoint);
3507     }
3508     
3509     return parentPoint;
3510 }
3511
3512 // Normal delay
3513 void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
3514 {
3515     s_deferredRepaintDelay = p;
3516 }
3517
3518 // Negative value would mean that first few repaints happen without a delay
3519 void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p)
3520 {
3521     s_initialDeferredRepaintDelayDuringLoading = p;
3522 }
3523
3524 // The delay grows on each repaint to this maximum value
3525 void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p)
3526 {
3527     s_maxDeferredRepaintDelayDuringLoading = p;
3528 }
3529
3530 // On each repaint the delay increases by this amount
3531 void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p)
3532 {
3533     s_deferredRepaintDelayIncrementDuringLoading = p;
3534 }
3535
3536 void FrameView::setTracksRepaints(bool trackRepaints)
3537 {
3538     if (trackRepaints == m_isTrackingRepaints)
3539         return;
3540     
3541     m_trackedRepaintRects.clear();
3542     m_isTrackingRepaints = trackRepaints;
3543 }
3544
3545 void FrameView::addScrollableArea(ScrollableArea* scrollableArea)
3546 {
3547     if (!m_scrollableAreas)
3548         m_scrollableAreas = adoptPtr(new ScrollableAreaSet);
3549     m_scrollableAreas->add(scrollableArea);
3550 }
3551
3552 void FrameView::removeScrollableArea(ScrollableArea* scrollableArea)
3553 {
3554     if (!m_scrollableAreas)
3555         return;
3556     m_scrollableAreas->remove(scrollableArea);
3557 }
3558
3559 bool FrameView::containsScrollableArea(ScrollableArea* scrollableArea) const
3560 {
3561     if (!m_scrollableAreas)
3562         return false;
3563     return m_scrollableAreas->contains(scrollableArea);
3564 }
3565
3566 void FrameView::removeChild(Widget* widget)
3567 {
3568     if (widget->isFrameView())
3569         removeScrollableArea(static_cast<FrameView*>(widget));
3570
3571     ScrollView::removeChild(widget);
3572 }
3573
3574 bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent)
3575 {
3576     // We don't allow mouse wheeling to happen in a ScrollView that has had its scrollbars explicitly disabled.
3577     if (!canHaveScrollbars())
3578         return false;
3579
3580 #if !PLATFORM(WX)
3581     if (platformWidget())
3582         return false;
3583 #endif
3584
3585 #if ENABLE(THREADED_SCROLLING)
3586     if (Page* page = m_frame->page()) {
3587         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
3588             if (scrollingCoordinator->coordinatesScrollingForFrameView(this))
3589                 return scrollingCoordinator->handleWheelEvent(this, wheelEvent);
3590         }
3591     }
3592 #endif
3593
3594     return ScrollableArea::handleWheelEvent(wheelEvent);
3595 }
3596
3597
3598 bool FrameView::isVerticalDocument() const
3599 {
3600     RenderView* root = rootRenderer(this);
3601     if (!root)
3602         return true;
3603
3604     return root->style()->isHorizontalWritingMode();
3605 }
3606
3607 bool FrameView::isFlippedDocument() const
3608 {
3609     RenderView* root = rootRenderer(this);
3610     if (!root)
3611         return false;
3612
3613     return root->style()->isFlippedBlocksWritingMode();
3614 }
3615
3616 void FrameView::notifyWidgetsInAllFrames(WidgetNotification notification)
3617 {
3618     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
3619         if (RenderView* root = frame->contentRenderer())
3620             root->notifyWidgets(notification);
3621     }
3622 }
3623     
3624 AXObjectCache* FrameView::axObjectCache() const
3625 {
3626     if (frame() && frame()->document() && frame()->document()->axObjectCacheExists())
3627         return frame()->document()->axObjectCache();
3628     return 0;
3629 }
3630     
3631 } // namespace WebCore