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