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