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