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