8ecef0761c7981f4bff976858faf7d2e05e941af
[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-2017 Apple Inc. All rights reserved.
7  *           (C) 2006 Graham Dennis (graham.dennis@gmail.com)
8  *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9  * Copyright (C) 2009 Google Inc. All rights reserved.
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this library; see the file COPYING.LIB.  If not, write to
23  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA 02110-1301, USA.
25  */
26
27 #include "config.h"
28 #include "FrameView.h"
29
30 #include "AXObjectCache.h"
31 #include "BackForwardController.h"
32 #include "CSSAnimationController.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 "DeprecatedGlobalSettings.h"
40 #include "DocumentLoader.h"
41 #include "DocumentMarkerController.h"
42 #include "EventHandler.h"
43 #include "EventNames.h"
44 #include "FloatRect.h"
45 #include "FocusController.h"
46 #include "Frame.h"
47 #include "FrameLoader.h"
48 #include "FrameLoaderClient.h"
49 #include "FrameSelection.h"
50 #include "FrameTree.h"
51 #include "GraphicsContext.h"
52 #include "HTMLBodyElement.h"
53 #include "HTMLEmbedElement.h"
54 #include "HTMLFrameElement.h"
55 #include "HTMLFrameSetElement.h"
56 #include "HTMLHtmlElement.h"
57 #include "HTMLIFrameElement.h"
58 #include "HTMLNames.h"
59 #include "HTMLObjectElement.h"
60 #include "HTMLParserIdioms.h"
61 #include "HTMLPlugInImageElement.h"
62 #include "ImageDocument.h"
63 #include "InspectorClient.h"
64 #include "InspectorController.h"
65 #include "InspectorInstrumentation.h"
66 #include "Logging.h"
67 #include "MemoryCache.h"
68 #include "OverflowEvent.h"
69 #include "Page.h"
70 #include "PageCache.h"
71 #include "PageOverlayController.h"
72 #include "ProgressTracker.h"
73 #include "RenderEmbeddedObject.h"
74 #include "RenderFullScreen.h"
75 #include "RenderIFrame.h"
76 #include "RenderInline.h"
77 #include "RenderLayer.h"
78 #include "RenderLayerBacking.h"
79 #include "RenderLayerCompositor.h"
80 #include "RenderSVGRoot.h"
81 #include "RenderScrollbar.h"
82 #include "RenderScrollbarPart.h"
83 #include "RenderStyle.h"
84 #include "RenderText.h"
85 #include "RenderTheme.h"
86 #include "RenderView.h"
87 #include "RenderWidget.h"
88 #include "ResizeObserver.h"
89 #include "RuntimeEnabledFeatures.h"
90 #include "SVGDocument.h"
91 #include "SVGSVGElement.h"
92 #include "ScriptRunner.h"
93 #include "ScriptedAnimationController.h"
94 #include "ScrollAnimator.h"
95 #include "ScrollingCoordinator.h"
96 #include "Settings.h"
97 #include "StyleResolver.h"
98 #include "StyleScope.h"
99 #include "TextResourceDecoder.h"
100 #include "TiledBacking.h"
101 #include "VisualViewport.h"
102 #include "WheelEventTestTrigger.h"
103 #include <wtf/text/TextStream.h>
104
105 #include <wtf/IsoMallocInlines.h>
106 #include <wtf/MemoryPressureHandler.h>
107 #include <wtf/Ref.h>
108 #include <wtf/SetForScope.h>
109 #include <wtf/SystemTracing.h>
110
111 #if USE(COORDINATED_GRAPHICS)
112 #include "TiledBackingStore.h"
113 #endif
114
115 #if ENABLE(CSS_SCROLL_SNAP)
116 #include "AxisScrollSnapOffsets.h"
117 #endif
118
119 #if PLATFORM(IOS_FAMILY)
120 #include "DocumentLoader.h"
121 #include "LegacyTileCache.h"
122 #endif
123
124 #if PLATFORM(MAC)
125 #include "LocalDefaultSystemAppearance.h"
126 #endif
127
128 #define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(frame().page() && frame().page()->isAlwaysOnLoggingAllowed(), Layout, "%p - FrameView::" fmt, this, ##__VA_ARGS__)
129
130 namespace WebCore {
131
132 using namespace HTMLNames;
133
134 WTF_MAKE_ISO_ALLOCATED_IMPL(FrameView);
135
136 MonotonicTime FrameView::sCurrentPaintTimeStamp { };
137
138 // The maximum number of updateEmbeddedObjects iterations that should be done before returning.
139 static const unsigned maxUpdateEmbeddedObjectsIterations = 2;
140
141 static constexpr unsigned defaultSignificantRenderedTextCharacterThreshold = 3000;
142 static constexpr float defaultSignificantRenderedTextMeanLength = 50;
143 static constexpr unsigned mainArticleSignificantRenderedTextCharacterThreshold = 1500;
144 static constexpr float mainArticleSignificantRenderedTextMeanLength = 25;
145
146 static OptionSet<RenderLayer::UpdateLayerPositionsFlag> updateLayerPositionFlags(RenderLayer* layer, bool isRelayoutingSubtree, bool didFullRepaint)
147 {
148     auto flags = RenderLayer::updateLayerPositionsDefaultFlags();
149     if (didFullRepaint) {
150         flags.remove(RenderLayer::CheckForRepaint);
151         flags.add(RenderLayer::NeedsFullRepaintInBacking);
152     }
153     if (isRelayoutingSubtree && layer->enclosingPaginationLayer(RenderLayer::IncludeCompositedPaginatedLayers))
154         flags.add(RenderLayer::UpdatePagination);
155     return flags;
156 }
157
158 Pagination::Mode paginationModeForRenderStyle(const RenderStyle& style)
159 {
160     Overflow overflow = style.overflowY();
161     if (overflow != Overflow::PagedX && overflow != Overflow::PagedY)
162         return Pagination::Unpaginated;
163
164     bool isHorizontalWritingMode = style.isHorizontalWritingMode();
165     TextDirection textDirection = style.direction();
166     WritingMode writingMode = style.writingMode();
167
168     // paged-x always corresponds to LeftToRightPaginated or RightToLeftPaginated. If the WritingMode
169     // is horizontal, then we use TextDirection to choose between those options. If the WritingMode
170     // is vertical, then the direction of the verticality dictates the choice.
171     if (overflow == Overflow::PagedX) {
172         if ((isHorizontalWritingMode && textDirection == TextDirection::LTR) || writingMode == LeftToRightWritingMode)
173             return Pagination::LeftToRightPaginated;
174         return Pagination::RightToLeftPaginated;
175     }
176
177     // paged-y always corresponds to TopToBottomPaginated or BottomToTopPaginated. If the WritingMode
178     // is horizontal, then the direction of the horizontality dictates the choice. If the WritingMode
179     // is vertical, then we use TextDirection to choose between those options. 
180     if (writingMode == TopToBottomWritingMode || (!isHorizontalWritingMode && textDirection == TextDirection::RTL))
181         return Pagination::TopToBottomPaginated;
182     return Pagination::BottomToTopPaginated;
183 }
184
185 FrameView::FrameView(Frame& frame)
186     : m_frame(frame)
187     , m_layoutContext(*this)
188     , m_updateEmbeddedObjectsTimer(*this, &FrameView::updateEmbeddedObjectsTimerFired)
189     , m_updateWidgetPositionsTimer(*this, &FrameView::updateWidgetPositionsTimerFired)
190     , m_delayedScrollEventTimer(*this, &FrameView::sendScrollEvent)
191     , m_delayedScrollToFocusedElementTimer(*this, &FrameView::scrollToFocusedElementTimerFired)
192     , m_speculativeTilingEnableTimer(*this, &FrameView::speculativeTilingEnableTimerFired)
193 {
194     init();
195
196 #if ENABLE(RUBBER_BANDING)
197     ScrollElasticity verticalElasticity = ScrollElasticityNone;
198     ScrollElasticity horizontalElasticity = ScrollElasticityNone;
199     if (m_frame->isMainFrame()) {
200         verticalElasticity = m_frame->page() ? m_frame->page()->verticalScrollElasticity() : ScrollElasticityAllowed;
201         horizontalElasticity = m_frame->page() ? m_frame->page()->horizontalScrollElasticity() : ScrollElasticityAllowed;
202     } else if (m_frame->settings().rubberBandingForSubScrollableRegionsEnabled()) {
203         verticalElasticity = ScrollElasticityAutomatic;
204         horizontalElasticity = ScrollElasticityAutomatic;
205     }
206
207     ScrollableArea::setVerticalScrollElasticity(verticalElasticity);
208     ScrollableArea::setHorizontalScrollElasticity(horizontalElasticity);
209 #endif
210 }
211
212 Ref<FrameView> FrameView::create(Frame& frame)
213 {
214     Ref<FrameView> view = adoptRef(*new FrameView(frame));
215     if (frame.page() && frame.page()->isVisible())
216         view->show();
217     return view;
218 }
219
220 Ref<FrameView> FrameView::create(Frame& frame, const IntSize& initialSize)
221 {
222     Ref<FrameView> view = adoptRef(*new FrameView(frame));
223     view->Widget::setFrameRect(IntRect(view->location(), initialSize));
224     if (frame.page() && frame.page()->isVisible())
225         view->show();
226     return view;
227 }
228
229 FrameView::~FrameView()
230 {
231     removeFromAXObjectCache();
232     resetScrollbars();
233
234     // Custom scrollbars should already be destroyed at this point
235     ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
236     ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
237
238     setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
239     setHasVerticalScrollbar(false);
240     
241     ASSERT(!m_scrollCorner);
242
243     ASSERT(frame().view() != this || !frame().contentRenderer());
244 }
245
246 void FrameView::reset()
247 {
248     m_cannotBlitToWindow = false;
249     m_isOverlapped = false;
250     m_contentIsOpaque = false;
251     m_updateEmbeddedObjectsTimer.stop();
252     m_wasScrolledByUser = false;
253     m_delayedScrollEventTimer.stop();
254     m_shouldScrollToFocusedElement = false;
255     m_delayedScrollToFocusedElementTimer.stop();
256     m_lastViewportSize = IntSize();
257     m_lastZoomFactor = 1.0f;
258     m_isTrackingRepaints = false;
259     m_trackedRepaintRects.clear();
260     m_lastPaintTime = MonotonicTime();
261     m_paintBehavior = PaintBehavior::Normal;
262     m_isPainting = false;
263     m_needsDeferredScrollbarsUpdate = false;
264     m_maintainScrollPositionAnchor = nullptr;
265     resetLayoutMilestones();
266     layoutContext().reset();
267 }
268
269 void FrameView::resetLayoutMilestones()
270 {
271     m_firstLayoutCallbackPending = false;
272     m_isVisuallyNonEmpty = false;
273     m_hasReachedSignificantRenderedTextThreshold = false;
274     m_renderedSignificantAmountOfText = false;
275     m_visuallyNonEmptyCharacterCount = 0;
276     m_visuallyNonEmptyPixelCount = 0;
277     m_textRendererCountForVisuallyNonEmptyCharacters = 0;
278 }
279
280 void FrameView::removeFromAXObjectCache()
281 {
282     if (AXObjectCache* cache = axObjectCache()) {
283         if (HTMLFrameOwnerElement* owner = frame().ownerElement())
284             cache->childrenChanged(owner->renderer());
285         cache->remove(this);
286     }
287 }
288
289 void FrameView::resetScrollbars()
290 {
291     // FIXME: Do we really need this?
292     layoutContext().resetFirstLayoutFlag();
293     // Reset the document's scrollbars back to our defaults before we yield the floor.
294     setScrollbarsSuppressed(true);
295     if (m_canHaveScrollbars)
296         setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
297     else
298         setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
299     setScrollbarsSuppressed(false);
300 }
301
302 void FrameView::resetScrollbarsAndClearContentsSize()
303 {
304     resetScrollbars();
305
306     LOG(Layout, "FrameView %p resetScrollbarsAndClearContentsSize", this);
307
308     setScrollbarsSuppressed(true);
309     setContentsSize(IntSize());
310     setScrollbarsSuppressed(false);
311 }
312
313 void FrameView::init()
314 {
315     reset();
316
317     m_margins = LayoutSize(-1, -1); // undefined
318     m_size = LayoutSize();
319
320     // Propagate the marginwidth/height and scrolling modes to the view.
321     Element* ownerElement = frame().ownerElement();
322     if (is<HTMLFrameElementBase>(ownerElement)) {
323         HTMLFrameElementBase& frameElement = downcast<HTMLFrameElementBase>(*ownerElement);
324         if (frameElement.scrollingMode() == ScrollbarAlwaysOff)
325             setCanHaveScrollbars(false);
326         LayoutUnit marginWidth = frameElement.marginWidth();
327         LayoutUnit marginHeight = frameElement.marginHeight();
328         if (marginWidth != -1)
329             setMarginWidth(marginWidth);
330         if (marginHeight != -1)
331             setMarginHeight(marginHeight);
332     }
333
334     Page* page = frame().page();
335     if (page && page->chrome().client().shouldPaintEntireContents())
336         setPaintsEntireContents(true);
337 }
338     
339 void FrameView::prepareForDetach()
340 {
341     detachCustomScrollbars();
342     // When the view is no longer associated with a frame, it needs to be removed from the ax object cache
343     // right now, otherwise it won't be able to reach the topDocument()'s axObject cache later.
344     removeFromAXObjectCache();
345
346     if (frame().page()) {
347         if (ScrollingCoordinator* scrollingCoordinator = frame().page()->scrollingCoordinator())
348             scrollingCoordinator->willDestroyScrollableArea(*this);
349     }
350 }
351
352 void FrameView::detachCustomScrollbars()
353 {
354     Scrollbar* horizontalBar = horizontalScrollbar();
355     if (horizontalBar && horizontalBar->isCustomScrollbar())
356         setHasHorizontalScrollbar(false);
357
358     Scrollbar* verticalBar = verticalScrollbar();
359     if (verticalBar && verticalBar->isCustomScrollbar())
360         setHasVerticalScrollbar(false);
361
362     m_scrollCorner = nullptr;
363 }
364
365 void FrameView::recalculateScrollbarOverlayStyle()
366 {
367     ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
368     Optional<ScrollbarOverlayStyle> clientOverlayStyle = frame().page() ? frame().page()->chrome().client().preferredScrollbarOverlayStyle() : WTF::nullopt;
369     if (clientOverlayStyle) {
370         if (clientOverlayStyle.value() != oldOverlayStyle)
371             setScrollbarOverlayStyle(clientOverlayStyle.value());
372         return;
373     }
374
375     ScrollbarOverlayStyle computedOverlayStyle = ScrollbarOverlayStyleDefault;
376
377     Color backgroundColor = documentBackgroundColor();
378     if (backgroundColor.isValid()) {
379         // Reduce the background color from RGB to a lightness value
380         // and determine which scrollbar style to use based on a lightness
381         // heuristic.
382         double hue, saturation, lightness;
383         backgroundColor.getHSL(hue, saturation, lightness);
384         if (lightness <= .5 && backgroundColor.isVisible())
385             computedOverlayStyle = ScrollbarOverlayStyleLight;
386         else if (!backgroundColor.isVisible() && useDarkAppearance())
387             computedOverlayStyle = ScrollbarOverlayStyleLight;
388     }
389
390     if (oldOverlayStyle != computedOverlayStyle)
391         setScrollbarOverlayStyle(computedOverlayStyle);
392 }
393
394 #if ENABLE(DARK_MODE_CSS)
395 void FrameView::recalculateBaseBackgroundColor()
396 {
397     bool usingDarkAppearance = useDarkAppearance();
398     if (m_usesDarkAppearance == usingDarkAppearance)
399         return;
400
401     m_usesDarkAppearance = usingDarkAppearance;
402     Optional<Color> backgroundColor;
403     if (m_isTransparent)
404         backgroundColor = Color(Color::transparent);
405     updateBackgroundRecursively(backgroundColor);
406 }
407 #endif
408
409 void FrameView::clear()
410 {
411     setCanBlitOnScroll(true);
412     
413     reset();
414
415     setScrollbarsSuppressed(true);
416
417 #if PLATFORM(IOS_FAMILY)
418     // To avoid flashes of white, disable tile updates immediately when view is cleared at the beginning of a page load.
419     // Tiling will be re-enabled from UIKit via [WAKWindow setTilingMode:] when we have content to draw.
420     if (LegacyTileCache* tileCache = legacyTileCache())
421         tileCache->setTilingMode(LegacyTileCache::Disabled);
422 #endif
423 }
424
425 #if PLATFORM(IOS_FAMILY)
426 void FrameView::didReplaceMultipartContent()
427 {
428     // Re-enable tile updates that were disabled in clear().
429     if (LegacyTileCache* tileCache = legacyTileCache())
430         tileCache->setTilingMode(LegacyTileCache::Normal);
431 }
432 #endif
433
434 bool FrameView::didFirstLayout() const
435 {
436     return layoutContext().didFirstLayout();
437 }
438
439 void FrameView::invalidateRect(const IntRect& rect)
440 {
441     if (!parent()) {
442         if (auto* page = frame().page())
443             page->chrome().invalidateContentsAndRootView(rect);
444         return;
445     }
446
447     auto* renderer = frame().ownerRenderer();
448     if (!renderer)
449         return;
450
451     IntRect repaintRect = rect;
452     repaintRect.moveBy(roundedIntPoint(renderer->contentBoxLocation()));
453     renderer->repaintRectangle(repaintRect);
454 }
455
456 void FrameView::setFrameRect(const IntRect& newRect)
457 {
458     Ref<FrameView> protectedThis(*this);
459     IntRect oldRect = frameRect();
460     if (newRect == oldRect)
461         return;
462
463     // Every scroll that happens as the result of frame size change is programmatic.
464     auto oldScrollType = currentScrollType();
465     setCurrentScrollType(ScrollType::Programmatic);
466
467     ScrollView::setFrameRect(newRect);
468
469     updateScrollableAreaSet();
470
471     if (RenderView* renderView = this->renderView()) {
472         if (renderView->usesCompositing())
473             renderView->compositor().frameViewDidChangeSize();
474     }
475
476     if (frame().isMainFrame() && frame().page())
477         frame().page()->pageOverlayController().didChangeViewSize();
478
479     viewportContentsChanged();
480     setCurrentScrollType(oldScrollType);
481 }
482
483 bool FrameView::scheduleAnimation()
484 {
485     auto* page = frame().page();
486     if (!page)
487         return false;
488     page->chrome().scheduleAnimation();
489     return true;
490 }
491
492 void FrameView::setMarginWidth(LayoutUnit w)
493 {
494     // make it update the rendering area when set
495     m_margins.setWidth(w);
496 }
497
498 void FrameView::setMarginHeight(LayoutUnit h)
499 {
500     // make it update the rendering area when set
501     m_margins.setHeight(h);
502 }
503
504 FrameFlattening FrameView::effectiveFrameFlattening() const
505 {
506 #if PLATFORM(IOS_FAMILY)
507     // On iOS when async frame scrolling is enabled, it does not make sense to use full frame flattening.
508     // In that case, we just consider that frame flattening is disabled. This allows people to test
509     // frame scrolling on iOS by enabling "Async Frame Scrolling" via the Safari menu.
510     if (frame().settings().asyncFrameScrollingEnabled() && frame().settings().frameFlattening() == FrameFlattening::FullyEnabled)
511         return FrameFlattening::Disabled;
512 #endif
513     return frame().settings().frameFlattening();
514 }
515
516 bool FrameView::frameFlatteningEnabled() const
517 {
518     return effectiveFrameFlattening() != FrameFlattening::Disabled;
519 }
520
521 bool FrameView::isFrameFlatteningValidForThisFrame() const
522 {
523     if (!frameFlatteningEnabled())
524         return false;
525
526     HTMLFrameOwnerElement* owner = frame().ownerElement();
527     if (!owner)
528         return false;
529
530     // Frame flattening is valid only for <frame> and <iframe>.
531     return owner->hasTagName(frameTag) || owner->hasTagName(iframeTag);
532 }
533
534 bool FrameView::avoidScrollbarCreation() const
535 {
536     // with frame flattening no subframe can have scrollbars
537     // but we also cannot turn scrollbars off as we determine
538     // our flattening policy using that.
539     return isFrameFlatteningValidForThisFrame();
540 }
541
542 void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
543 {
544     m_canHaveScrollbars = canHaveScrollbars;
545     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
546 }
547
548 void FrameView::updateCanHaveScrollbars()
549 {
550     ScrollbarMode hMode;
551     ScrollbarMode vMode;
552     scrollbarModes(hMode, vMode);
553     if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
554         setCanHaveScrollbars(false);
555     else
556         setCanHaveScrollbars(true);
557 }
558
559 Ref<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
560 {
561     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
562     Document* doc = frame().document();
563
564     // Try the <body> element first as a scrollbar source.
565     HTMLElement* body = doc ? doc->bodyOrFrameset() : nullptr;
566     if (body && body->renderer() && body->renderer()->style().hasPseudoStyle(PseudoId::Scrollbar))
567         return RenderScrollbar::createCustomScrollbar(*this, orientation, body);
568     
569     // If the <body> didn't have a custom style, then the root element might.
570     Element* docElement = doc ? doc->documentElement() : nullptr;
571     if (docElement && docElement->renderer() && docElement->renderer()->style().hasPseudoStyle(PseudoId::Scrollbar))
572         return RenderScrollbar::createCustomScrollbar(*this, orientation, docElement);
573
574     // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
575     RenderWidget* frameRenderer = frame().ownerRenderer();
576     if (frameRenderer && frameRenderer->style().hasPseudoStyle(PseudoId::Scrollbar))
577         return RenderScrollbar::createCustomScrollbar(*this, orientation, nullptr, &frame());
578     
579     // Nobody set a custom style, so we just use a native scrollbar.
580     return ScrollView::createScrollbar(orientation);
581 }
582
583 void FrameView::didRestoreFromPageCache()
584 {
585     // When restoring from page cache, the main frame stays in place while subframes get swapped in.
586     // We update the scrollable area set to ensure that scrolling data structures get invalidated.
587     updateScrollableAreaSet();
588 }
589
590 void FrameView::willDestroyRenderTree()
591 {
592     detachCustomScrollbars();
593     layoutContext().clearSubtreeLayoutRoot();
594 }
595
596 void FrameView::didDestroyRenderTree()
597 {
598     ASSERT(!layoutContext().subtreeLayoutRoot());
599     ASSERT(m_widgetsInRenderTree.isEmpty());
600
601     // If the render tree is destroyed below FrameView::updateEmbeddedObjects(), there will still be a null sentinel in the set.
602     // Everything else should have removed itself as the tree was felled.
603     ASSERT(!m_embeddedObjectsToUpdate || m_embeddedObjectsToUpdate->isEmpty() || (m_embeddedObjectsToUpdate->size() == 1 && m_embeddedObjectsToUpdate->first() == nullptr));
604
605     ASSERT(!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty());
606     ASSERT(!m_slowRepaintObjects || m_slowRepaintObjects->isEmpty());
607
608     ASSERT(!frame().animation().hasAnimations());
609 }
610
611 void FrameView::setContentsSize(const IntSize& size)
612 {
613     if (size == contentsSize())
614         return;
615
616     layoutContext().disableSetNeedsLayout();
617
618     ScrollView::setContentsSize(size);
619     contentsResized();
620     
621     Page* page = frame().page();
622     if (!page)
623         return;
624
625     updateScrollableAreaSet();
626
627     page->chrome().contentsSizeChanged(frame(), size); // Notify only.
628
629     if (frame().isMainFrame()) {
630         page->pageOverlayController().didChangeDocumentSize();
631         PageCache::singleton().markPagesForContentsSizeChanged(*page);
632     }
633     layoutContext().enableSetNeedsLayout();
634 }
635
636 void FrameView::adjustViewSize()
637 {
638     RenderView* renderView = this->renderView();
639     if (!renderView)
640         return;
641
642     ASSERT(frame().view() == this);
643
644     const IntRect rect = renderView->documentRect();
645     const IntSize& size = rect.size();
646     ScrollView::setScrollOrigin(IntPoint(-rect.x(), -rect.y()), !frame().document()->printing(), size == contentsSize());
647
648     LOG_WITH_STREAM(Layout, stream << "FrameView " << this << " adjustViewSize: unscaled document rect changed to " << renderView->unscaledDocumentRect() << " (scaled to " << size << ")");
649
650     setContentsSize(size);
651 }
652
653 void FrameView::applyOverflowToViewport(const RenderElement& renderer, ScrollbarMode& hMode, ScrollbarMode& vMode)
654 {
655     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
656     // overflow:hidden and overflow:scroll on <body> as applying to the document's
657     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
658     // use the root element.
659
660     // To combat the inability to scroll on a page with overflow:hidden on the root when scaled, disregard hidden when
661     // there is a frameScaleFactor that is greater than one on the main frame. Also disregard hidden if there is a
662     // header or footer.
663
664     bool overrideHidden = frame().isMainFrame() && ((frame().frameScaleFactor() > 1) || headerHeight() || footerHeight());
665
666     Overflow overflowX = renderer.style().overflowX();
667     Overflow overflowY = renderer.style().overflowY();
668
669     if (is<RenderSVGRoot>(renderer)) {
670         // FIXME: evaluate if we can allow overflow for these cases too.
671         // Overflow is always hidden when stand-alone SVG documents are embedded.
672         if (downcast<RenderSVGRoot>(renderer).isEmbeddedThroughFrameContainingSVGDocument()) {
673             overflowX = Overflow::Hidden;
674             overflowY = Overflow::Hidden;
675         }
676     }
677
678     switch (overflowX) {
679     case Overflow::Hidden:
680         if (overrideHidden)
681             hMode = ScrollbarAuto;
682         else
683             hMode = ScrollbarAlwaysOff;
684         break;
685     case Overflow::Scroll:
686         hMode = ScrollbarAlwaysOn;
687         break;
688     case Overflow::Auto:
689         hMode = ScrollbarAuto;
690         break;
691     default:
692         // Don't set it at all.
693         ;
694     }
695
696     switch (overflowY) {
697     case Overflow::Hidden:
698         if (overrideHidden)
699             vMode = ScrollbarAuto;
700         else
701             vMode = ScrollbarAlwaysOff;
702         break;
703     case Overflow::Scroll:
704         vMode = ScrollbarAlwaysOn;
705         break;
706     case Overflow::Auto:
707         vMode = ScrollbarAuto;
708         break;
709     default:
710         // Don't set it at all. Values of Overflow::PagedX and Overflow::PagedY are handled by applyPaginationToViewPort().
711         ;
712     }
713 }
714
715 void FrameView::applyPaginationToViewport()
716 {
717     auto* document = frame().document();
718     auto* documentElement = document ? document->documentElement() : nullptr;
719     if (!documentElement || !documentElement->renderer()) {
720         setPagination(Pagination());
721         return;
722     }
723
724     auto& documentRenderer = *documentElement->renderer();
725     auto* documentOrBodyRenderer = &documentRenderer;
726
727     auto* body = document->body();
728     if (body && body->renderer()) {
729         documentOrBodyRenderer = documentRenderer.style().overflowX() == Overflow::Visible && is<HTMLHtmlElement>(*documentElement) ?
730             body->renderer() : &documentRenderer;
731     }
732
733     Pagination pagination;
734     Overflow overflowY = documentOrBodyRenderer->style().overflowY();
735     if (overflowY == Overflow::PagedX || overflowY == Overflow::PagedY) {
736         pagination.mode = WebCore::paginationModeForRenderStyle(documentOrBodyRenderer->style());
737         GapLength columnGapLength = documentOrBodyRenderer->style().columnGap();
738         pagination.gap = 0;
739         if (!columnGapLength.isNormal()) {
740             if (auto* containerForPaginationGap = is<RenderBox>(documentOrBodyRenderer) ? downcast<RenderBox>(documentOrBodyRenderer) : documentOrBodyRenderer->containingBlock())
741                 pagination.gap = valueForLength(columnGapLength.length(), containerForPaginationGap->availableLogicalWidth()).toUnsigned();
742         }
743     }
744     setPagination(pagination);
745 }
746
747 void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
748 {
749     m_viewportRendererType = ViewportRendererType::None;
750
751     const HTMLFrameOwnerElement* owner = frame().ownerElement();
752     if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
753         hMode = ScrollbarAlwaysOff;
754         vMode = ScrollbarAlwaysOff;
755         return;
756     }  
757     
758     if (m_canHaveScrollbars || strategy == RulesFromWebContentOnly) {
759         hMode = ScrollbarAuto;
760         vMode = ScrollbarAuto;
761     } else {
762         hMode = ScrollbarAlwaysOff;
763         vMode = ScrollbarAlwaysOff;
764     }
765     
766     if (layoutContext().subtreeLayoutRoot())
767         return;
768     
769     auto* document = frame().document();
770     if (!document)
771         return;
772
773     auto* documentElement = document->documentElement();
774     if (!documentElement)
775         return;
776
777     auto* bodyOrFrameset = document->bodyOrFrameset();
778     auto* rootRenderer = documentElement->renderer();
779     if (!bodyOrFrameset || !bodyOrFrameset->renderer()) {
780         if (rootRenderer) {
781             applyOverflowToViewport(*rootRenderer, hMode, vMode);
782             m_viewportRendererType = ViewportRendererType::Document;
783         }
784         return;
785     }
786     
787     if (is<HTMLFrameSetElement>(*bodyOrFrameset) && !frameFlatteningEnabled()) {
788         vMode = ScrollbarAlwaysOff;
789         hMode = ScrollbarAlwaysOff;
790         return;
791     }
792
793     if (is<HTMLBodyElement>(*bodyOrFrameset) && rootRenderer) {
794         // It's sufficient to just check the X overflow,
795         // since it's illegal to have visible in only one direction.
796         if (rootRenderer->style().overflowX() == Overflow::Visible && is<HTMLHtmlElement>(documentElement)) {
797             auto* bodyRenderer = bodyOrFrameset->renderer();
798             if (bodyRenderer) {
799                 applyOverflowToViewport(*bodyRenderer, hMode, vMode);
800                 m_viewportRendererType = ViewportRendererType::Body;
801             }
802         } else {
803             applyOverflowToViewport(*rootRenderer, hMode, vMode);
804             m_viewportRendererType = ViewportRendererType::Document;
805         }
806     }
807 }
808
809 void FrameView::willRecalcStyle()
810 {
811     RenderView* renderView = this->renderView();
812     if (!renderView)
813         return;
814
815     renderView->compositor().willRecalcStyle();
816 }
817
818 bool FrameView::updateCompositingLayersAfterStyleChange()
819 {
820     // If we expect to update compositing after an incipient layout, don't do so here.
821     if (!renderView() || needsLayout() || layoutContext().isInLayout())
822         return false;
823     return renderView()->compositor().didRecalcStyleWithNoPendingLayout();
824 }
825
826 void FrameView::updateCompositingLayersAfterLayout()
827 {
828     RenderView* renderView = this->renderView();
829     if (!renderView)
830         return;
831
832     renderView->compositor().updateCompositingLayers(CompositingUpdateType::AfterLayout);
833 }
834
835 GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
836 {
837     RenderView* renderView = this->renderView();
838     if (!renderView)
839         return nullptr;
840     return renderView->compositor().layerForHorizontalScrollbar();
841 }
842
843 GraphicsLayer* FrameView::layerForVerticalScrollbar() const
844 {
845     RenderView* renderView = this->renderView();
846     if (!renderView)
847         return nullptr;
848     return renderView->compositor().layerForVerticalScrollbar();
849 }
850
851 GraphicsLayer* FrameView::layerForScrollCorner() const
852 {
853     RenderView* renderView = this->renderView();
854     if (!renderView)
855         return nullptr;
856     return renderView->compositor().layerForScrollCorner();
857 }
858
859 TiledBacking* FrameView::tiledBacking() const
860 {
861     RenderView* renderView = this->renderView();
862     if (!renderView)
863         return nullptr;
864
865     RenderLayerBacking* backing = renderView->layer()->backing();
866     if (!backing)
867         return nullptr;
868
869     return backing->tiledBacking();
870 }
871
872 ScrollingNodeID FrameView::scrollingNodeID() const
873 {
874     RenderView* renderView = this->renderView();
875     if (!renderView)
876         return 0;
877
878     RenderLayerBacking* backing = renderView->layer()->backing();
879     if (!backing)
880         return 0;
881
882     return backing->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling);
883 }
884
885 ScrollableArea* FrameView::scrollableAreaForScrollLayerID(uint64_t nodeID) const
886 {
887     RenderView* renderView = this->renderView();
888     if (!renderView)
889         return nullptr;
890
891     return renderView->compositor().scrollableAreaForScrollLayerID(nodeID);
892 }
893
894 #if ENABLE(RUBBER_BANDING)
895 GraphicsLayer* FrameView::layerForOverhangAreas() const
896 {
897     RenderView* renderView = this->renderView();
898     if (!renderView)
899         return nullptr;
900     return renderView->compositor().layerForOverhangAreas();
901 }
902
903 GraphicsLayer* FrameView::setWantsLayerForTopOverHangArea(bool wantsLayer) const
904 {
905     RenderView* renderView = this->renderView();
906     if (!renderView)
907         return nullptr;
908
909     return renderView->compositor().updateLayerForTopOverhangArea(wantsLayer);
910 }
911
912 GraphicsLayer* FrameView::setWantsLayerForBottomOverHangArea(bool wantsLayer) const
913 {
914     RenderView* renderView = this->renderView();
915     if (!renderView)
916         return nullptr;
917
918     return renderView->compositor().updateLayerForBottomOverhangArea(wantsLayer);
919 }
920
921 #endif // ENABLE(RUBBER_BANDING)
922
923 #if ENABLE(CSS_SCROLL_SNAP)
924 void FrameView::updateSnapOffsets()
925 {
926     if (!frame().document())
927         return;
928
929     // FIXME: Should we allow specifying snap points through <html> tags too?
930     HTMLElement* body = frame().document()->bodyOrFrameset();
931     if (!renderView() || !body || !body->renderer())
932         return;
933     
934     updateSnapOffsetsForScrollableArea(*this, *body, *renderView(), body->renderer()->style());
935 }
936
937 bool FrameView::isScrollSnapInProgress() const
938 {
939     if (scrollbarsSuppressed())
940         return false;
941     
942     // If the scrolling thread updates the scroll position for this FrameView, then we should return
943     // ScrollingCoordinator::isScrollSnapInProgress().
944     if (Page* page = frame().page()) {
945         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
946             if (!scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously(*this))
947                 return scrollingCoordinator->isScrollSnapInProgress();
948         }
949     }
950     
951     // If the main thread updates the scroll position for this FrameView, we should return
952     // ScrollAnimator::isScrollSnapInProgress().
953     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
954         return scrollAnimator->isScrollSnapInProgress();
955     
956     return false;
957 }
958
959 void FrameView::updateScrollingCoordinatorScrollSnapProperties() const
960 {
961     renderView()->compositor().updateScrollSnapPropertiesWithFrameView(*this);
962 }
963 #endif
964
965 bool FrameView::flushCompositingStateForThisFrame(const Frame& rootFrameForFlush)
966 {
967     RenderView* renderView = this->renderView();
968     if (!renderView)
969         return true; // We don't want to keep trying to update layers if we have no renderer.
970
971     ASSERT(frame().view() == this);
972
973     // If we sync compositing layers when a layout is pending, we may cause painting of compositing
974     // layer content to occur before layout has happened, which will cause paintContents() to bail.
975     if (needsLayout())
976         return false;
977
978 #if PLATFORM(IOS_FAMILY)
979     if (LegacyTileCache* tileCache = legacyTileCache())
980         tileCache->doPendingRepaints();
981 #endif
982
983     renderView->compositor().flushPendingLayerChanges(&rootFrameForFlush == m_frame.ptr());
984
985     return true;
986 }
987
988 void FrameView::setNeedsOneShotDrawingSynchronization()
989 {
990     if (Page* page = frame().page())
991         page->chrome().client().setNeedsOneShotDrawingSynchronization();
992 }
993
994 GraphicsLayer* FrameView::graphicsLayerForPlatformWidget(PlatformWidget platformWidget)
995 {
996     // To find the Widget that corresponds with platformWidget we have to do a linear
997     // search of our child widgets.
998     const Widget* foundWidget = nullptr;
999     for (auto& widget : children()) {
1000         if (widget->platformWidget() != platformWidget)
1001             continue;
1002         foundWidget = widget.ptr();
1003         break;
1004     }
1005
1006     if (!foundWidget)
1007         return nullptr;
1008
1009     auto* renderWidget = RenderWidget::find(*foundWidget);
1010     if (!renderWidget)
1011         return nullptr;
1012
1013     auto* widgetLayer = renderWidget->layer();
1014     if (!widgetLayer || !widgetLayer->isComposited())
1015         return nullptr;
1016
1017     return widgetLayer->backing()->parentForSublayers();
1018 }
1019
1020 void FrameView::scheduleLayerFlushAllowingThrottling()
1021 {
1022     RenderView* view = this->renderView();
1023     if (!view)
1024         return;
1025     view->compositor().scheduleLayerFlush(true /* canThrottle */);
1026 }
1027
1028 LayoutRect FrameView::fixedScrollableAreaBoundsInflatedForScrolling(const LayoutRect& uninflatedBounds) const
1029 {
1030     LayoutPoint scrollPosition;
1031     LayoutSize topLeftExpansion;
1032     LayoutSize bottomRightExpansion;
1033
1034     if (frame().settings().visualViewportEnabled()) {
1035         // FIXME: this is wrong under zooming; uninflatedBounds is scaled but the scroll positions are not.
1036         scrollPosition = layoutViewportRect().location();
1037         topLeftExpansion = scrollPosition - unscaledMinimumScrollPosition();
1038         bottomRightExpansion = unscaledMaximumScrollPosition() - scrollPosition;
1039     } else {
1040         scrollPosition = scrollPositionRespectingCustomFixedPosition();
1041         topLeftExpansion = scrollPosition - minimumScrollPosition();
1042         bottomRightExpansion = maximumScrollPosition() - scrollPosition;
1043     }
1044
1045     return LayoutRect(uninflatedBounds.location() - topLeftExpansion, uninflatedBounds.size() + topLeftExpansion + bottomRightExpansion);
1046 }
1047
1048 LayoutPoint FrameView::scrollPositionRespectingCustomFixedPosition() const
1049 {
1050 #if PLATFORM(IOS_FAMILY)
1051     if (!frame().settings().visualViewportEnabled())
1052         return useCustomFixedPositionLayoutRect() ? customFixedPositionLayoutRect().location() : scrollPosition();
1053 #endif
1054
1055     return scrollPositionForFixedPosition();
1056 }
1057
1058 int FrameView::headerHeight() const
1059 {
1060     if (!frame().isMainFrame())
1061         return 0;
1062     Page* page = frame().page();
1063     return page ? page->headerHeight() : 0;
1064 }
1065
1066 int FrameView::footerHeight() const
1067 {
1068     if (!frame().isMainFrame())
1069         return 0;
1070     Page* page = frame().page();
1071     return page ? page->footerHeight() : 0;
1072 }
1073
1074 float FrameView::topContentInset(TopContentInsetType contentInsetTypeToReturn) const
1075 {
1076     if (platformWidget() && contentInsetTypeToReturn == TopContentInsetType::WebCoreOrPlatformContentInset)
1077         return platformTopContentInset();
1078
1079     if (!frame().isMainFrame())
1080         return 0;
1081     
1082     Page* page = frame().page();
1083     return page ? page->topContentInset() : 0;
1084 }
1085     
1086 void FrameView::topContentInsetDidChange(float newTopContentInset)
1087 {
1088     RenderView* renderView = this->renderView();
1089     if (!renderView)
1090         return;
1091
1092     if (platformWidget())
1093         platformSetTopContentInset(newTopContentInset);
1094     
1095     layoutContext().layout();
1096     // Every scroll that happens as the result of content inset change is programmatic.
1097     auto oldScrollType = currentScrollType();
1098     setCurrentScrollType(ScrollType::Programmatic);
1099
1100     updateScrollbars(scrollPosition());
1101     if (renderView->usesCompositing())
1102         renderView->compositor().frameViewDidChangeSize();
1103
1104     if (TiledBacking* tiledBacking = this->tiledBacking())
1105         tiledBacking->setTopContentInset(newTopContentInset);
1106
1107     setCurrentScrollType(oldScrollType);
1108 }
1109
1110 void FrameView::topContentDirectionDidChange()
1111 {
1112     m_needsDeferredScrollbarsUpdate = true;
1113 }
1114
1115 void FrameView::handleDeferredScrollbarsUpdateAfterDirectionChange()
1116 {
1117     if (!m_needsDeferredScrollbarsUpdate)
1118         return;
1119
1120     m_needsDeferredScrollbarsUpdate = false;
1121
1122     updateScrollbars(scrollPosition());
1123     positionScrollbarLayers();
1124 }
1125
1126 // Sometimes (for plug-ins) we need to eagerly go into compositing mode.
1127 void FrameView::enterCompositingMode()
1128 {
1129     if (RenderView* renderView = this->renderView()) {
1130         renderView->compositor().enableCompositingMode();
1131         if (!needsLayout())
1132             renderView->compositor().scheduleCompositingLayerUpdate();
1133     }
1134 }
1135
1136 bool FrameView::isEnclosedInCompositingLayer() const
1137 {
1138     auto frameOwnerRenderer = frame().ownerRenderer();
1139     if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
1140         return true;
1141
1142     if (FrameView* parentView = parentFrameView())
1143         return parentView->isEnclosedInCompositingLayer();
1144     return false;
1145 }
1146
1147 bool FrameView::flushCompositingStateIncludingSubframes()
1148 {
1149 #if PLATFORM(COCOA)
1150     InspectorInstrumentation::willComposite(frame());
1151 #endif
1152
1153     bool allFramesFlushed = flushCompositingStateForThisFrame(frame());
1154
1155     for (Frame* child = frame().tree().firstRenderedChild(); child; child = child->tree().traverseNextRendered(m_frame.ptr())) {
1156         if (!child->view())
1157             continue;
1158         bool flushed = child->view()->flushCompositingStateForThisFrame(frame());
1159         allFramesFlushed &= flushed;
1160     }
1161     return allFramesFlushed;
1162 }
1163
1164 bool FrameView::isSoftwareRenderable() const
1165 {
1166     RenderView* renderView = this->renderView();
1167     return !renderView || !renderView->compositor().has3DContent();
1168 }
1169
1170 void FrameView::setIsInWindow(bool isInWindow)
1171 {
1172     if (RenderView* renderView = this->renderView())
1173         renderView->setIsInWindow(isInWindow);
1174 }
1175
1176 void FrameView::forceLayoutParentViewIfNeeded()
1177 {
1178     RenderWidget* ownerRenderer = frame().ownerRenderer();
1179     if (!ownerRenderer)
1180         return;
1181
1182     RenderBox* contentBox = embeddedContentBox();
1183     if (!contentBox)
1184         return;
1185
1186     auto& svgRoot = downcast<RenderSVGRoot>(*contentBox);
1187     if (svgRoot.everHadLayout() && !svgRoot.needsLayout())
1188         return;
1189
1190     LOG(Layout, "FrameView %p forceLayoutParentViewIfNeeded scheduling layout on parent FrameView %p", this, &ownerRenderer->view().frameView());
1191
1192     // If the embedded SVG document appears the first time, the ownerRenderer has already finished
1193     // layout without knowing about the existence of the embedded SVG document, because RenderReplaced
1194     // embeddedContentBox() returns nullptr, as long as the embedded document isn't loaded yet. Before
1195     // bothering to lay out the SVG document, mark the ownerRenderer needing layout and ask its
1196     // FrameView for a layout. After that the RenderEmbeddedObject (ownerRenderer) carries the
1197     // correct size, which RenderSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying
1198     // out for the first time, or when the RenderSVGRoot size has changed dynamically (eg. via <script>).
1199
1200     ownerRenderer->setNeedsLayoutAndPrefWidthsRecalc();
1201     ownerRenderer->view().frameView().layoutContext().scheduleLayout();
1202 }
1203
1204 void FrameView::markRootOrBodyRendererDirty() const
1205 {
1206     auto& document = *frame().document();
1207     RenderBox* rootRenderer = document.documentElement() ? document.documentElement()->renderBox() : nullptr;
1208     auto* body = document.bodyOrFrameset();
1209     RenderBox* bodyRenderer = rootRenderer && body ? body->renderBox() : nullptr;
1210     if (bodyRenderer && bodyRenderer->stretchesToViewport())
1211         bodyRenderer->setChildNeedsLayout();
1212     else if (rootRenderer && rootRenderer->stretchesToViewport())
1213         rootRenderer->setChildNeedsLayout();
1214 }
1215
1216 void FrameView::adjustScrollbarsForLayout(bool isFirstLayout)
1217 {
1218     ScrollbarMode hMode;
1219     ScrollbarMode vMode;
1220     calculateScrollbarModesForLayout(hMode, vMode);
1221     if (isFirstLayout && !layoutContext().isLayoutNested()) {
1222         setScrollbarsSuppressed(true);
1223         // Set the initial vMode to AlwaysOn if we're auto.
1224         if (vMode == ScrollbarAuto)
1225             setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
1226         // Set the initial hMode to AlwaysOff if we're auto.
1227         if (hMode == ScrollbarAuto)
1228             setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
1229         ASSERT(frame().page());
1230         if (frame().page()->expectsWheelEventTriggers())
1231             scrollAnimator().setWheelEventTestTrigger(frame().page()->testTrigger());
1232         setScrollbarModes(hMode, vMode);
1233         setScrollbarsSuppressed(false, true);
1234     } else if (hMode != horizontalScrollbarMode() || vMode != verticalScrollbarMode())
1235         setScrollbarModes(hMode, vMode);
1236 }
1237
1238 void FrameView::willDoLayout(WeakPtr<RenderElement> layoutRoot)
1239 {
1240     bool subtreeLayout = !is<RenderView>(*layoutRoot);
1241     if (subtreeLayout)
1242         return;
1243     
1244     if (auto* body = frame().document()->bodyOrFrameset()) {
1245         if (is<HTMLFrameSetElement>(*body) && !frameFlatteningEnabled() && body->renderer())
1246             body->renderer()->setChildNeedsLayout();
1247     }
1248     auto firstLayout = !layoutContext().didFirstLayout();
1249     if (firstLayout) {
1250         m_lastViewportSize = sizeForResizeEvent();
1251         m_lastZoomFactor = layoutRoot->style().zoom();
1252         m_firstLayoutCallbackPending = true;
1253     }
1254     adjustScrollbarsForLayout(firstLayout);
1255         
1256     auto oldSize = m_size;
1257     LayoutSize newSize = layoutSize();
1258     if (oldSize != newSize) {
1259         m_size = newSize;
1260         LOG(Layout, "  layout size changed from %.3fx%.3f to %.3fx%.3f", oldSize.width().toFloat(), oldSize.height().toFloat(),     newSize.width().toFloat(), newSize.height().toFloat());
1261         layoutContext().setNeedsFullRepaint();
1262         if (!firstLayout)
1263             markRootOrBodyRendererDirty();
1264     }
1265     forceLayoutParentViewIfNeeded();
1266 }
1267
1268 void FrameView::didLayout(WeakPtr<RenderElement> layoutRoot)
1269 {
1270     renderView()->releaseProtectedRenderWidgets();
1271     auto* layoutRootEnclosingLayer = layoutRoot->enclosingLayer();
1272     layoutRootEnclosingLayer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layoutRootEnclosingLayer, !is<RenderView>(*layoutRoot), layoutContext().needsFullRepaint()));
1273
1274     updateCompositingLayersAfterLayout();
1275
1276 #if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK)
1277     if (auto* cache = frame().document()->existingAXObjectCache())
1278         cache->postNotification(layoutRoot.get(), AXObjectCache::AXLayoutComplete);
1279 #endif
1280
1281     frame().document()->invalidateRenderingDependentRegions(Document::AnnotationsAction::Update);
1282
1283     updateCanBlitOnScrollRecursively();
1284
1285     handleDeferredScrollUpdateAfterContentSizeChange();
1286
1287     handleDeferredScrollbarsUpdateAfterDirectionChange();
1288
1289     if (frame().document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
1290         updateOverflowStatus(layoutWidth() < contentsWidth(), layoutHeight() < contentsHeight());
1291
1292     frame().document()->markers().invalidateRectsForAllMarkers();
1293 }
1294
1295 bool FrameView::shouldDeferScrollUpdateAfterContentSizeChange()
1296 {
1297     return (layoutContext().layoutPhase() < FrameViewLayoutContext::LayoutPhase::InPostLayout) && (layoutContext().layoutPhase() != FrameViewLayoutContext::LayoutPhase::OutsideLayout);
1298 }
1299
1300 RenderBox* FrameView::embeddedContentBox() const
1301 {
1302     RenderView* renderView = this->renderView();
1303     if (!renderView)
1304         return nullptr;
1305
1306     RenderObject* firstChild = renderView->firstChild();
1307
1308     // Curently only embedded SVG documents participate in the size-negotiation logic.
1309     if (is<RenderSVGRoot>(firstChild))
1310         return downcast<RenderSVGRoot>(firstChild);
1311
1312     return nullptr;
1313 }
1314
1315 void FrameView::addEmbeddedObjectToUpdate(RenderEmbeddedObject& embeddedObject)
1316 {
1317     if (!m_embeddedObjectsToUpdate)
1318         m_embeddedObjectsToUpdate = std::make_unique<ListHashSet<RenderEmbeddedObject*>>();
1319
1320     HTMLFrameOwnerElement& element = embeddedObject.frameOwnerElement();
1321     if (is<HTMLObjectElement>(element) || is<HTMLEmbedElement>(element)) {
1322         // Tell the DOM element that it needs a widget update.
1323         HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
1324         if (!pluginElement.needsCheckForSizeChange())
1325             pluginElement.setNeedsWidgetUpdate(true);
1326     }
1327
1328     m_embeddedObjectsToUpdate->add(&embeddedObject);
1329 }
1330
1331 void FrameView::removeEmbeddedObjectToUpdate(RenderEmbeddedObject& embeddedObject)
1332 {
1333     if (!m_embeddedObjectsToUpdate)
1334         return;
1335
1336     m_embeddedObjectsToUpdate->remove(&embeddedObject);
1337 }
1338
1339 void FrameView::setMediaType(const String& mediaType)
1340 {
1341     m_mediaType = mediaType;
1342 }
1343
1344 String FrameView::mediaType() const
1345 {
1346     // See if we have an override type.
1347     String overrideType = frame().loader().client().overrideMediaType();
1348     InspectorInstrumentation::applyEmulatedMedia(frame(), overrideType);
1349     if (!overrideType.isNull())
1350         return overrideType;
1351     return m_mediaType;
1352 }
1353
1354 void FrameView::adjustMediaTypeForPrinting(bool printing)
1355 {
1356     if (printing) {
1357         if (m_mediaTypeWhenNotPrinting.isNull())
1358             m_mediaTypeWhenNotPrinting = mediaType();
1359         setMediaType("print");
1360     } else {
1361         if (!m_mediaTypeWhenNotPrinting.isNull())
1362             setMediaType(m_mediaTypeWhenNotPrinting);
1363         m_mediaTypeWhenNotPrinting = String();
1364     }
1365 }
1366
1367 bool FrameView::useSlowRepaints(bool considerOverlap) const
1368 {
1369     bool mustBeSlow = hasSlowRepaintObjects() || (platformWidget() && hasViewportConstrainedObjects());
1370
1371     // FIXME: WidgetMac.mm makes the assumption that useSlowRepaints ==
1372     // m_contentIsOpaque, so don't take the fast path for composited layers
1373     // if they are a platform widget in order to get painting correctness
1374     // for transparent layers. See the comment in WidgetMac::paint.
1375     if (usesCompositedScrolling() && !platformWidget())
1376         return mustBeSlow;
1377
1378     bool isOverlapped = m_isOverlapped && considerOverlap;
1379
1380     if (mustBeSlow || m_cannotBlitToWindow || isOverlapped || !m_contentIsOpaque)
1381         return true;
1382
1383     if (FrameView* parentView = parentFrameView())
1384         return parentView->useSlowRepaints(considerOverlap);
1385
1386     return false;
1387 }
1388
1389 bool FrameView::useSlowRepaintsIfNotOverlapped() const
1390 {
1391     return useSlowRepaints(false);
1392 }
1393
1394 void FrameView::updateCanBlitOnScrollRecursively()
1395 {
1396     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
1397         if (FrameView* view = frame->view())
1398             view->setCanBlitOnScroll(!view->useSlowRepaints());
1399     }
1400 }
1401
1402 bool FrameView::usesCompositedScrolling() const
1403 {
1404     RenderView* renderView = this->renderView();
1405     if (renderView && renderView->isComposited()) {
1406         GraphicsLayer* layer = renderView->layer()->backing()->graphicsLayer();
1407         if (layer && layer->drawsContent())
1408             return true;
1409     }
1410
1411     return false;
1412 }
1413
1414 bool FrameView::usesAsyncScrolling() const
1415 {
1416 #if ENABLE(ASYNC_SCROLLING)
1417     if (Page* page = frame().page()) {
1418         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1419             return scrollingCoordinator->coordinatesScrollingForFrameView(*this);
1420     }
1421 #endif
1422     return false;
1423 }
1424
1425 bool FrameView::usesMockScrollAnimator() const
1426 {
1427     return DeprecatedGlobalSettings::usesMockScrollAnimator();
1428 }
1429
1430 void FrameView::logMockScrollAnimatorMessage(const String& message) const
1431 {
1432     Document* document = frame().document();
1433     if (!document)
1434         return;
1435     StringBuilder builder;
1436     if (frame().isMainFrame())
1437         builder.appendLiteral("Main");
1438     builder.appendLiteral("FrameView: ");
1439     builder.append(message);
1440     document->addConsoleMessage(MessageSource::Other, MessageLevel::Debug, builder.toString());
1441 }
1442
1443 void FrameView::setCannotBlitToWindow()
1444 {
1445     m_cannotBlitToWindow = true;
1446     updateCanBlitOnScrollRecursively();
1447 }
1448
1449 void FrameView::addSlowRepaintObject(RenderElement& renderer)
1450 {
1451     bool hadSlowRepaintObjects = hasSlowRepaintObjects();
1452
1453     if (!m_slowRepaintObjects)
1454         m_slowRepaintObjects = std::make_unique<HashSet<const RenderElement*>>();
1455
1456     m_slowRepaintObjects->add(&renderer);
1457     if (hadSlowRepaintObjects)
1458         return;
1459
1460     updateCanBlitOnScrollRecursively();
1461
1462     if (auto* page = frame().page()) {
1463         if (auto* scrollingCoordinator = page->scrollingCoordinator())
1464             scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(*this);
1465     }
1466 }
1467
1468 void FrameView::removeSlowRepaintObject(RenderElement& renderer)
1469 {
1470     if (!m_slowRepaintObjects)
1471         return;
1472
1473     m_slowRepaintObjects->remove(&renderer);
1474     if (!m_slowRepaintObjects->isEmpty())
1475         return;
1476
1477     m_slowRepaintObjects = nullptr;
1478     updateCanBlitOnScrollRecursively();
1479
1480     if (auto* page = frame().page()) {
1481         if (auto* scrollingCoordinator = page->scrollingCoordinator())
1482             scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(*this);
1483     }
1484 }
1485
1486 void FrameView::addViewportConstrainedObject(RenderLayerModelObject* object)
1487 {
1488     if (!m_viewportConstrainedObjects)
1489         m_viewportConstrainedObjects = std::make_unique<ViewportConstrainedObjectSet>();
1490
1491     if (!m_viewportConstrainedObjects->contains(object)) {
1492         m_viewportConstrainedObjects->add(object);
1493         if (platformWidget())
1494             updateCanBlitOnScrollRecursively();
1495
1496         if (Page* page = frame().page()) {
1497             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1498                 scrollingCoordinator->frameViewFixedObjectsDidChange(*this);
1499         }
1500     }
1501 }
1502
1503 void FrameView::removeViewportConstrainedObject(RenderLayerModelObject* object)
1504 {
1505     if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->remove(object)) {
1506         if (Page* page = frame().page()) {
1507             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1508                 scrollingCoordinator->frameViewFixedObjectsDidChange(*this);
1509         }
1510
1511         // FIXME: In addFixedObject() we only call this if there's a platform widget,
1512         // why isn't the same check being made here?
1513         updateCanBlitOnScrollRecursively();
1514     }
1515 }
1516
1517 LayoutSize FrameView::expandedLayoutViewportSize(const LayoutSize& baseLayoutViewportSize, const LayoutSize& documentSize, double heightExpansionFactor)
1518 {
1519     if (!heightExpansionFactor)
1520         return baseLayoutViewportSize;
1521
1522     auto documentHeight = documentSize.height();
1523     auto layoutViewportHeight = baseLayoutViewportSize.height();
1524     if (layoutViewportHeight > documentHeight)
1525         return baseLayoutViewportSize;
1526
1527     return { baseLayoutViewportSize.width(), std::min<LayoutUnit>(documentHeight, (1 + heightExpansionFactor) * layoutViewportHeight) };
1528 }
1529
1530 LayoutRect FrameView::computeUpdatedLayoutViewportRect(const LayoutRect& layoutViewport, const LayoutRect& documentRect, const LayoutSize& unobscuredContentSize, const LayoutRect& unobscuredContentRect, const LayoutSize& baseLayoutViewportSize, const LayoutPoint& stableLayoutViewportOriginMin, const LayoutPoint& stableLayoutViewportOriginMax, LayoutViewportConstraint constraint)
1531 {
1532     LayoutRect layoutViewportRect = layoutViewport;
1533     
1534     // The layout viewport is never smaller than baseLayoutViewportSize, and never be smaller than the unobscuredContentRect.
1535     LayoutSize constrainedSize = baseLayoutViewportSize;
1536     layoutViewportRect.setSize(constrainedSize.expandedTo(unobscuredContentSize));
1537         
1538     LayoutPoint layoutViewportOrigin = computeLayoutViewportOrigin(unobscuredContentRect, stableLayoutViewportOriginMin, stableLayoutViewportOriginMax, layoutViewportRect, StickToViewportBounds);
1539
1540     // FIXME: Is this equivalent to calling computeLayoutViewportOrigin() with StickToDocumentBounds?
1541     if (constraint == LayoutViewportConstraint::ConstrainedToDocumentRect) {
1542         // The max stable layout viewport origin really depends on the size of the layout viewport itself, so we need to adjust the location of the layout viewport one final time to make sure it does not end up out of bounds of the document.
1543         // Without this adjustment (and with using the non-constrained unobscuredContentRect's size as the size of the layout viewport) the layout viewport can be pushed past the bounds of the document during rubber-banding, and cannot be pushed
1544         // back in until the user scrolls back in the other direction.
1545         layoutViewportOrigin.setX(clampTo<float>(layoutViewportOrigin.x().toFloat(), 0, documentRect.width() - layoutViewportRect.width()));
1546         layoutViewportOrigin.setY(clampTo<float>(layoutViewportOrigin.y().toFloat(), 0, documentRect.height() - layoutViewportRect.height()));
1547     }
1548     layoutViewportRect.setLocation(layoutViewportOrigin);
1549     
1550     return layoutViewportRect;
1551 }
1552
1553 // visualViewport and layoutViewport are both in content coordinates (unzoomed).
1554 LayoutPoint FrameView::computeLayoutViewportOrigin(const LayoutRect& visualViewport, const LayoutPoint& stableLayoutViewportOriginMin, const LayoutPoint& stableLayoutViewportOriginMax, const LayoutRect& layoutViewport, ScrollBehaviorForFixedElements fixedBehavior)
1555 {
1556     LayoutPoint layoutViewportOrigin = layoutViewport.location();
1557     bool allowRubberBanding = fixedBehavior == StickToViewportBounds;
1558
1559     if (visualViewport.width() > layoutViewport.width()) {
1560         layoutViewportOrigin.setX(visualViewport.x());
1561         if (!allowRubberBanding) {
1562             if (layoutViewportOrigin.x() < stableLayoutViewportOriginMin.x())
1563                 layoutViewportOrigin.setX(stableLayoutViewportOriginMin.x());
1564             else if (layoutViewportOrigin.x() > stableLayoutViewportOriginMax.x())
1565                 layoutViewportOrigin.setX(stableLayoutViewportOriginMax.x());
1566         }
1567     } else {
1568         bool rubberbandingAtLeft = allowRubberBanding && visualViewport.x() < stableLayoutViewportOriginMin.x();
1569         bool rubberbandingAtRight = allowRubberBanding && (visualViewport.maxX() - layoutViewport.width()) > stableLayoutViewportOriginMax.x();
1570
1571         if (visualViewport.x() < layoutViewport.x() || rubberbandingAtLeft)
1572             layoutViewportOrigin.setX(visualViewport.x());
1573
1574         if (visualViewport.maxX() > layoutViewport.maxX() || rubberbandingAtRight)
1575             layoutViewportOrigin.setX(visualViewport.maxX() - layoutViewport.width());
1576
1577         if (!rubberbandingAtLeft && layoutViewportOrigin.x() < stableLayoutViewportOriginMin.x())
1578             layoutViewportOrigin.setX(stableLayoutViewportOriginMin.x());
1579         
1580         if (!rubberbandingAtRight && layoutViewportOrigin.x() > stableLayoutViewportOriginMax.x())
1581             layoutViewportOrigin.setX(stableLayoutViewportOriginMax.x());
1582     }
1583
1584     if (visualViewport.height() > layoutViewport.height()) {
1585         layoutViewportOrigin.setY(visualViewport.y());
1586         if (!allowRubberBanding) {
1587             if (layoutViewportOrigin.y() < stableLayoutViewportOriginMin.y())
1588                 layoutViewportOrigin.setY(stableLayoutViewportOriginMin.y());
1589             else if (layoutViewportOrigin.y() > stableLayoutViewportOriginMax.y())
1590                 layoutViewportOrigin.setY(stableLayoutViewportOriginMax.y());
1591         }
1592     } else {
1593         bool rubberbandingAtTop = allowRubberBanding && visualViewport.y() < stableLayoutViewportOriginMin.y();
1594         bool rubberbandingAtBottom = allowRubberBanding && (visualViewport.maxY() - layoutViewport.height()) > stableLayoutViewportOriginMax.y();
1595
1596         if (visualViewport.y() < layoutViewport.y() || rubberbandingAtTop)
1597             layoutViewportOrigin.setY(visualViewport.y());
1598
1599         if (visualViewport.maxY() > layoutViewport.maxY() || rubberbandingAtBottom)
1600             layoutViewportOrigin.setY(visualViewport.maxY() - layoutViewport.height());
1601
1602         if (!rubberbandingAtTop && layoutViewportOrigin.y() < stableLayoutViewportOriginMin.y())
1603             layoutViewportOrigin.setY(stableLayoutViewportOriginMin.y());
1604
1605         if (!rubberbandingAtBottom && layoutViewportOrigin.y() > stableLayoutViewportOriginMax.y())
1606             layoutViewportOrigin.setY(stableLayoutViewportOriginMax.y());
1607     }
1608
1609     return layoutViewportOrigin;
1610 }
1611
1612 void FrameView::setBaseLayoutViewportOrigin(LayoutPoint origin, TriggerLayoutOrNot layoutTriggering)
1613 {
1614     ASSERT(frame().settings().visualViewportEnabled());
1615
1616     if (origin == m_layoutViewportOrigin)
1617         return;
1618
1619     m_layoutViewportOrigin = origin;
1620     if (layoutTriggering == TriggerLayoutOrNot::Yes)
1621         setViewportConstrainedObjectsNeedLayout();
1622     
1623     if (TiledBacking* tiledBacking = this->tiledBacking()) {
1624         FloatRect layoutViewport = layoutViewportRect();
1625         layoutViewport.moveBy(unscaledScrollOrigin()); // tiledBacking deals in top-left relative coordinates.
1626         tiledBacking->setLayoutViewportRect(layoutViewport);
1627     }
1628 }
1629
1630 void FrameView::setLayoutViewportOverrideRect(Optional<LayoutRect> rect, TriggerLayoutOrNot layoutTriggering)
1631 {
1632     if (rect == m_layoutViewportOverrideRect)
1633         return;
1634
1635     LayoutRect oldRect = layoutViewportRect();
1636     m_layoutViewportOverrideRect = rect;
1637
1638     // Triggering layout on height changes is necessary to make bottom-fixed elements behave correctly.
1639     if (oldRect.height() != layoutViewportRect().height())
1640         layoutTriggering = TriggerLayoutOrNot::Yes;
1641
1642     LOG_WITH_STREAM(Scrolling, stream << "\nFrameView " << this << " setLayoutViewportOverrideRect() - changing override layout viewport from " << oldRect << " to " << m_layoutViewportOverrideRect.valueOr(LayoutRect()) << " layoutTriggering " << (layoutTriggering == TriggerLayoutOrNot::Yes ? "yes" : "no"));
1643
1644     if (oldRect != layoutViewportRect() && layoutTriggering == TriggerLayoutOrNot::Yes)
1645         setViewportConstrainedObjectsNeedLayout();
1646 }
1647
1648 void FrameView::setVisualViewportOverrideRect(Optional<LayoutRect> rect)
1649 {
1650     m_visualViewportOverrideRect = rect;
1651 }
1652
1653 LayoutSize FrameView::baseLayoutViewportSize() const
1654 {
1655     return renderView() ? renderView()->size() : size();
1656 }
1657
1658 void FrameView::updateLayoutViewport()
1659 {
1660     if (!frame().settings().visualViewportEnabled())
1661         return;
1662     
1663     // Don't update the layout viewport if we're in the middle of adjusting scrollbars. We'll get another call
1664     // as a post-layout task.
1665     if (layoutContext().layoutPhase() == FrameViewLayoutContext::LayoutPhase::InViewSizeAdjust)
1666         return;
1667
1668     LayoutRect layoutViewport = layoutViewportRect();
1669
1670     LOG_WITH_STREAM(Scrolling, stream << "\nFrameView " << this << " updateLayoutViewport() totalContentSize " << totalContentsSize() << " unscaledDocumentRect " << (renderView() ? renderView()->unscaledDocumentRect() : IntRect()) << " header height " << headerHeight() << " footer height " << footerHeight() << " fixed behavior " << scrollBehaviorForFixedElements());
1671     LOG_WITH_STREAM(Scrolling, stream << "layoutViewport: " << layoutViewport);
1672     LOG_WITH_STREAM(Scrolling, stream << "visualViewport: " << visualViewportRect() << " (is override " << (bool)m_visualViewportOverrideRect << ")");
1673     LOG_WITH_STREAM(Scrolling, stream << "stable origins: min: " << minStableLayoutViewportOrigin() << " max: "<< maxStableLayoutViewportOrigin());
1674     
1675     if (m_layoutViewportOverrideRect) {
1676         if (currentScrollType() == ScrollType::Programmatic) {
1677             LOG_WITH_STREAM(Scrolling, stream << "computing new override layout viewport because of programmatic scrolling");
1678             LayoutPoint newOrigin = computeLayoutViewportOrigin(visualViewportRect(), minStableLayoutViewportOrigin(), maxStableLayoutViewportOrigin(), layoutViewport, StickToDocumentBounds);
1679             setLayoutViewportOverrideRect(LayoutRect(newOrigin, m_layoutViewportOverrideRect.value().size()));
1680         }
1681         if (frame().settings().visualViewportAPIEnabled()) {
1682             if (auto* window = frame().window())
1683                 window->visualViewport().update();
1684         }
1685         return;
1686     }
1687
1688     LayoutPoint newLayoutViewportOrigin = computeLayoutViewportOrigin(visualViewportRect(), minStableLayoutViewportOrigin(), maxStableLayoutViewportOrigin(), layoutViewport, scrollBehaviorForFixedElements());
1689     if (newLayoutViewportOrigin != m_layoutViewportOrigin) {
1690         setBaseLayoutViewportOrigin(newLayoutViewportOrigin);
1691         LOG_WITH_STREAM(Scrolling, stream << "layoutViewport changed to " << layoutViewportRect());
1692     }
1693     if (frame().settings().visualViewportAPIEnabled()) {
1694         if (auto* window = frame().window())
1695             window->visualViewport().update();
1696     }
1697 }
1698
1699 LayoutPoint FrameView::minStableLayoutViewportOrigin() const
1700 {
1701     return unscaledMinimumScrollPosition();
1702 }
1703
1704 LayoutPoint FrameView::maxStableLayoutViewportOrigin() const
1705 {
1706     LayoutPoint maxPosition = unscaledMaximumScrollPosition();
1707     maxPosition = (maxPosition - LayoutSize(0, headerHeight() + footerHeight())).expandedTo({ });
1708     return maxPosition;
1709 }
1710
1711 IntPoint FrameView::unscaledScrollOrigin() const
1712 {
1713     if (RenderView* renderView = this->renderView())
1714         return -renderView->unscaledDocumentRect().location(); // Akin to code in adjustViewSize().
1715
1716     return { };
1717 }
1718
1719 LayoutRect FrameView::layoutViewportRect() const
1720 {
1721     if (m_layoutViewportOverrideRect)
1722         return m_layoutViewportOverrideRect.value();
1723
1724     // Size of initial containing block, anchored at scroll position, in document coordinates (unchanged by scale factor).
1725     return LayoutRect(m_layoutViewportOrigin, baseLayoutViewportSize());
1726 }
1727
1728 // visibleContentRect is in the bounds of the scroll view content. That consists of an
1729 // optional header, the document, and an optional footer. Only the document is scaled,
1730 // so we have to compute the visible part of the document in unscaled document coordinates.
1731 // On iOS, pageScaleFactor is always 1 here, and we never have headers and footers.
1732 LayoutRect FrameView::visibleDocumentRect(const FloatRect& visibleContentRect, float headerHeight, float footerHeight, const FloatSize& totalContentsSize, float pageScaleFactor)
1733 {
1734     float contentsHeight = totalContentsSize.height() - headerHeight - footerHeight;
1735
1736     float rubberBandTop = std::min<float>(visibleContentRect.y(), 0);
1737     float visibleScaledDocumentTop = std::max<float>(visibleContentRect.y() - headerHeight, 0) + rubberBandTop;
1738     
1739     float rubberBandBottom = std::min<float>((totalContentsSize.height() - visibleContentRect.y()) - visibleContentRect.height(), 0);
1740     float visibleScaledDocumentBottom = std::min<float>(visibleContentRect.maxY() - headerHeight, contentsHeight) - rubberBandBottom;
1741
1742     FloatRect visibleDocumentRect = visibleContentRect;
1743     visibleDocumentRect.setY(visibleScaledDocumentTop);
1744     visibleDocumentRect.setHeight(std::max<float>(visibleScaledDocumentBottom - visibleScaledDocumentTop, 0));
1745     visibleDocumentRect.scale(1 / pageScaleFactor);
1746     
1747     return LayoutRect(visibleDocumentRect);
1748 }
1749
1750 LayoutRect FrameView::visualViewportRect() const
1751 {
1752     if (m_visualViewportOverrideRect)
1753         return m_visualViewportOverrideRect.value();
1754
1755     FloatRect visibleContentRect = this->visibleContentRect(LegacyIOSDocumentVisibleRect);
1756     return visibleDocumentRect(visibleContentRect, headerHeight(), footerHeight(), totalContentsSize(), frameScaleFactor());
1757 }
1758
1759 LayoutRect FrameView::viewportConstrainedVisibleContentRect() const
1760 {
1761     ASSERT(!frame().settings().visualViewportEnabled());
1762
1763 #if PLATFORM(IOS_FAMILY)
1764     if (useCustomFixedPositionLayoutRect())
1765         return customFixedPositionLayoutRect();
1766 #endif
1767     LayoutRect viewportRect = visibleContentRect();
1768
1769     viewportRect.setLocation(scrollPositionForFixedPosition());
1770     return viewportRect;
1771 }
1772
1773 LayoutRect FrameView::rectForFixedPositionLayout() const
1774 {
1775     if (frame().settings().visualViewportEnabled())
1776         return layoutViewportRect();
1777
1778     return viewportConstrainedVisibleContentRect();
1779 }
1780
1781 float FrameView::frameScaleFactor() const
1782 {
1783     return frame().frameScaleFactor();
1784 }
1785
1786 LayoutPoint FrameView::scrollPositionForFixedPosition() const
1787 {
1788     if (frame().settings().visualViewportEnabled())
1789         return layoutViewportRect().location();
1790
1791     return scrollPositionForFixedPosition(visibleContentRect(), totalContentsSize(), scrollPosition(), scrollOrigin(), frameScaleFactor(), fixedElementsLayoutRelativeToFrame(), scrollBehaviorForFixedElements(), headerHeight(), footerHeight());
1792 }
1793
1794 LayoutPoint FrameView::scrollPositionForFixedPosition(const LayoutRect& visibleContentRect, const LayoutSize& totalContentsSize, const LayoutPoint& scrollPosition, const LayoutPoint& scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements behaviorForFixed, int headerHeight, int footerHeight)
1795 {
1796     LayoutPoint position;
1797     if (behaviorForFixed == StickToDocumentBounds)
1798         position = ScrollableArea::constrainScrollPositionForOverhang(visibleContentRect, totalContentsSize, scrollPosition, scrollOrigin, headerHeight, footerHeight);
1799     else {
1800         position = scrollPosition;
1801         position.setY(position.y() - headerHeight);
1802     }
1803
1804     LayoutSize maxSize = totalContentsSize - visibleContentRect.size();
1805
1806     float dragFactorX = (fixedElementsLayoutRelativeToFrame || !maxSize.width()) ? 1 : (totalContentsSize.width() - visibleContentRect.width() * frameScaleFactor) / maxSize.width();
1807     float dragFactorY = (fixedElementsLayoutRelativeToFrame || !maxSize.height()) ? 1 : (totalContentsSize.height() - visibleContentRect.height() * frameScaleFactor) / maxSize.height();
1808
1809     return LayoutPoint(position.x() * dragFactorX / frameScaleFactor, position.y() * dragFactorY / frameScaleFactor);
1810 }
1811
1812 float FrameView::yPositionForInsetClipLayer(const FloatPoint& scrollPosition, float topContentInset)
1813 {
1814     if (!topContentInset)
1815         return 0;
1816
1817     // The insetClipLayer should not move for negative scroll values.
1818     float scrollY = std::max<float>(0, scrollPosition.y());
1819
1820     if (scrollY >= topContentInset)
1821         return 0;
1822
1823     return topContentInset - scrollY;
1824 }
1825
1826 float FrameView::yPositionForHeaderLayer(const FloatPoint& scrollPosition, float topContentInset)
1827 {
1828     if (!topContentInset)
1829         return 0;
1830
1831     float scrollY = std::max<float>(0, scrollPosition.y());
1832
1833     if (scrollY >= topContentInset)
1834         return topContentInset;
1835
1836     return scrollY;
1837 }
1838
1839 float FrameView::yPositionForFooterLayer(const FloatPoint& scrollPosition, float topContentInset, float totalContentsHeight, float footerHeight)
1840 {
1841     return yPositionForHeaderLayer(scrollPosition, topContentInset) + totalContentsHeight - footerHeight;
1842 }
1843
1844 FloatPoint FrameView::positionForRootContentLayer(const FloatPoint& scrollPosition, const FloatPoint& scrollOrigin, float topContentInset, float headerHeight)
1845 {
1846     return FloatPoint(0, yPositionForHeaderLayer(scrollPosition, topContentInset) + headerHeight) - toFloatSize(scrollOrigin);
1847 }
1848
1849 FloatPoint FrameView::positionForRootContentLayer() const
1850 {
1851     return positionForRootContentLayer(scrollPosition(), scrollOrigin(), topContentInset(), headerHeight());
1852 }
1853
1854 #if PLATFORM(IOS_FAMILY)
1855 LayoutRect FrameView::rectForViewportConstrainedObjects(const LayoutRect& visibleContentRect, const LayoutSize& totalContentsSize, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements scrollBehavior)
1856 {
1857     if (fixedElementsLayoutRelativeToFrame)
1858         return visibleContentRect;
1859     
1860     if (totalContentsSize.isEmpty())
1861         return visibleContentRect;
1862
1863     // We impose an lower limit on the size (so an upper limit on the scale) of
1864     // the rect used to position fixed objects so that they don't crowd into the
1865     // center of the screen at larger scales.
1866     const LayoutUnit maxContentWidthForZoomThreshold = 1024_lu;
1867     float zoomedOutScale = frameScaleFactor * visibleContentRect.width() / std::min(maxContentWidthForZoomThreshold, totalContentsSize.width());
1868     float constraintThresholdScale = 1.5 * zoomedOutScale;
1869     float maxPostionedObjectsRectScale = std::min(frameScaleFactor, constraintThresholdScale);
1870
1871     LayoutRect viewportConstrainedObjectsRect = visibleContentRect;
1872
1873     if (frameScaleFactor > constraintThresholdScale) {
1874         FloatRect contentRect(FloatPoint(), totalContentsSize);
1875         FloatRect viewportRect = visibleContentRect;
1876         
1877         // Scale the rect up from a point that is relative to its position in the viewport.
1878         FloatSize sizeDelta = contentRect.size() - viewportRect.size();
1879
1880         FloatPoint scaleOrigin;
1881         scaleOrigin.setX(contentRect.x() + sizeDelta.width() > 0 ? contentRect.width() * (viewportRect.x() - contentRect.x()) / sizeDelta.width() : 0);
1882         scaleOrigin.setY(contentRect.y() + sizeDelta.height() > 0 ? contentRect.height() * (viewportRect.y() - contentRect.y()) / sizeDelta.height() : 0);
1883         
1884         AffineTransform rescaleTransform = AffineTransform::translation(scaleOrigin.x(), scaleOrigin.y());
1885         rescaleTransform.scale(frameScaleFactor / maxPostionedObjectsRectScale, frameScaleFactor / maxPostionedObjectsRectScale);
1886         rescaleTransform = CGAffineTransformTranslate(rescaleTransform, -scaleOrigin.x(), -scaleOrigin.y());
1887
1888         viewportConstrainedObjectsRect = enclosingLayoutRect(rescaleTransform.mapRect(visibleContentRect));
1889     }
1890     
1891     if (scrollBehavior == StickToDocumentBounds) {
1892         LayoutRect documentBounds(LayoutPoint(), totalContentsSize);
1893         viewportConstrainedObjectsRect.intersect(documentBounds);
1894     }
1895
1896     return viewportConstrainedObjectsRect;
1897 }
1898     
1899 LayoutRect FrameView::viewportConstrainedObjectsRect() const
1900 {
1901     return rectForViewportConstrainedObjects(visibleContentRect(), totalContentsSize(), frame().frameScaleFactor(), fixedElementsLayoutRelativeToFrame(), scrollBehaviorForFixedElements());
1902 }
1903 #endif
1904     
1905 ScrollPosition FrameView::minimumScrollPosition() const
1906 {
1907     ScrollPosition minimumPosition = ScrollView::minimumScrollPosition();
1908
1909     if (frame().isMainFrame() && m_scrollPinningBehavior == PinToBottom)
1910         minimumPosition.setY(maximumScrollPosition().y());
1911     
1912     return minimumPosition;
1913 }
1914
1915 ScrollPosition FrameView::maximumScrollPosition() const
1916 {
1917     ScrollPosition maximumPosition = ScrollView::maximumScrollPosition();
1918
1919     if (frame().isMainFrame() && m_scrollPinningBehavior == PinToTop)
1920         maximumPosition.setY(minimumScrollPosition().y());
1921     
1922     return maximumPosition;
1923 }
1924
1925 ScrollPosition FrameView::unscaledMinimumScrollPosition() const
1926 {
1927     if (RenderView* renderView = this->renderView()) {
1928         IntRect unscaledDocumentRect = renderView->unscaledDocumentRect();
1929         ScrollPosition minimumPosition = unscaledDocumentRect.location();
1930
1931         if (frame().isMainFrame() && m_scrollPinningBehavior == PinToBottom)
1932             minimumPosition.setY(unscaledMaximumScrollPosition().y());
1933
1934         return minimumPosition;
1935     }
1936
1937     return minimumScrollPosition();
1938 }
1939
1940 ScrollPosition FrameView::unscaledMaximumScrollPosition() const
1941 {
1942     if (RenderView* renderView = this->renderView()) {
1943         IntRect unscaledDocumentRect = renderView->unscaledDocumentRect();
1944         unscaledDocumentRect.expand(0, headerHeight() + footerHeight());
1945         ScrollPosition maximumPosition = ScrollPosition(unscaledDocumentRect.maxXMaxYCorner() - visibleSize()).expandedTo({ 0, 0 });
1946         if (frame().isMainFrame() && m_scrollPinningBehavior == PinToTop)
1947             maximumPosition.setY(unscaledMinimumScrollPosition().y());
1948
1949         return maximumPosition;
1950     }
1951
1952     return maximumScrollPosition();
1953 }
1954
1955 void FrameView::viewportContentsChanged()
1956 {
1957     if (!frame().view()) {
1958         // The frame is being destroyed.
1959         return;
1960     }
1961
1962     if (auto* page = frame().page())
1963         page->updateValidationBubbleStateIfNeeded();
1964
1965     // When the viewport contents changes (scroll, resize, style recalc, layout, ...),
1966     // check if we should resume animated images or unthrottle DOM timers.
1967     applyRecursivelyWithVisibleRect([] (FrameView& frameView, const IntRect& visibleRect) {
1968         frameView.resumeVisibleImageAnimations(visibleRect);
1969         frameView.updateScriptedAnimationsAndTimersThrottlingState(visibleRect);
1970
1971         if (auto* renderView = frameView.frame().contentRenderer())
1972             renderView->updateVisibleViewportRect(visibleRect);
1973     });
1974 }
1975
1976 IntRect FrameView::visualViewportRectExpandedByContentInsets() const
1977 {
1978     FloatRect unobscuredContentRect = this->visualViewportRect();
1979     if (auto* page = frame().page())
1980         unobscuredContentRect.expand(page->contentInsets());
1981     return IntRect(unobscuredContentRect);
1982 }
1983
1984 bool FrameView::fixedElementsLayoutRelativeToFrame() const
1985 {
1986     return frame().settings().fixedElementsLayoutRelativeToFrame();
1987 }
1988
1989 IntPoint FrameView::lastKnownMousePosition() const
1990 {
1991     return frame().eventHandler().lastKnownMousePosition();
1992 }
1993
1994 bool FrameView::isHandlingWheelEvent() const
1995 {
1996     return frame().eventHandler().isHandlingWheelEvent();
1997 }
1998
1999 bool FrameView::shouldSetCursor() const
2000 {
2001     Page* page = frame().page();
2002     return page && page->isVisible() && page->focusController().isActive();
2003 }
2004
2005 #if ENABLE(DARK_MODE_CSS)
2006 RenderObject* FrameView::rendererForColorScheme() const
2007 {
2008     auto* document = frame().document();
2009     auto* documentElement = document ? document->documentElement() : nullptr;
2010     auto* documentElementRenderer = documentElement ? documentElement->renderer() : nullptr;
2011     if (documentElementRenderer && documentElementRenderer->style().hasExplicitlySetColorScheme())
2012         return documentElementRenderer;
2013     auto* bodyElement = document ? document->bodyOrFrameset() : nullptr;
2014     return bodyElement ? bodyElement->renderer() : nullptr;
2015 }
2016 #endif
2017
2018 bool FrameView::useDarkAppearance() const
2019 {
2020 #if ENABLE(DARK_MODE_CSS)
2021     if (auto* renderer = rendererForColorScheme())
2022         return renderer->useDarkAppearance();
2023 #endif
2024     if (auto* document = frame().document())
2025         return document->useDarkAppearance(nullptr);
2026     return false;
2027 }
2028
2029 OptionSet<StyleColor::Options> FrameView::styleColorOptions() const
2030 {
2031 #if ENABLE(DARK_MODE_CSS)
2032     if (auto* renderer = rendererForColorScheme())
2033         return renderer->styleColorOptions();
2034 #endif
2035     if (auto* document = frame().document())
2036         return document->styleColorOptions(nullptr);
2037     return { };
2038 }
2039
2040 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
2041 {
2042     if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty()) {
2043         frame().page()->chrome().scroll(scrollDelta, rectToScroll, clipRect);
2044         return true;
2045     }
2046
2047     bool isCompositedContentLayer = usesCompositedScrolling();
2048
2049     // Get the rects of the fixed objects visible in the rectToScroll
2050     Region regionToUpdate;
2051     for (auto& renderer : *m_viewportConstrainedObjects) {
2052         if (!renderer->style().hasViewportConstrainedPosition())
2053             continue;
2054         if (renderer->isComposited())
2055             continue;
2056
2057         // Fixed items should always have layers.
2058         ASSERT(renderer->hasLayer());
2059         RenderLayer* layer = downcast<RenderBoxModelObject>(*renderer).layer();
2060
2061         if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForBoundsOutOfView
2062             || layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForNoVisibleContent) {
2063             // Don't invalidate for invisible fixed layers.
2064             continue;
2065         }
2066
2067         if (layer->hasAncestorWithFilterOutsets()) {
2068             // If the fixed layer has a blur/drop-shadow filter applied on at least one of its parents, we cannot 
2069             // scroll using the fast path, otherwise the outsets of the filter will be moved around the page.
2070             return false;
2071         }
2072
2073         // FIXME: use pixel snapping instead of enclosing when ScrollView has finished transitioning from IntRect to Float/LayoutRect.
2074         IntRect updateRect = enclosingIntRect(layer->repaintRectIncludingNonCompositingDescendants());
2075         updateRect = contentsToRootView(updateRect);
2076         if (!isCompositedContentLayer)
2077             updateRect.intersect(rectToScroll);
2078         if (!updateRect.isEmpty())
2079             regionToUpdate.unite(updateRect);
2080     }
2081
2082     // 1) scroll
2083     frame().page()->chrome().scroll(scrollDelta, rectToScroll, clipRect);
2084
2085     // 2) update the area of fixed objects that has been invalidated
2086     for (auto& updateRect : regionToUpdate.rects()) {
2087         IntRect scrolledRect = updateRect;
2088         scrolledRect.move(scrollDelta);
2089         updateRect.unite(scrolledRect);
2090         if (isCompositedContentLayer) {
2091             updateRect = rootViewToContents(updateRect);
2092             ASSERT(renderView());
2093             renderView()->layer()->setBackingNeedsRepaintInRect(updateRect);
2094             continue;
2095         }
2096         updateRect.intersect(rectToScroll);
2097         frame().page()->chrome().invalidateContentsAndRootView(updateRect);
2098     }
2099
2100     return true;
2101 }
2102
2103 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
2104 {
2105     repaintSlowRepaintObjects();
2106
2107     if (!usesCompositedScrolling() && isEnclosedInCompositingLayer()) {
2108         if (RenderWidget* frameRenderer = frame().ownerRenderer()) {
2109             LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(), frameRenderer->borderTop() + frameRenderer->paddingTop(),
2110                 visibleWidth(), visibleHeight());
2111             frameRenderer->repaintRectangle(rect);
2112             return;
2113         }
2114     }
2115
2116     ScrollView::scrollContentsSlowPath(updateRect);
2117 }
2118
2119 void FrameView::repaintSlowRepaintObjects()
2120 {
2121     if (!m_slowRepaintObjects)
2122         return;
2123
2124     // Renderers with fixed backgrounds may be in compositing layers, so we need to explicitly
2125     // repaint them after scrolling.
2126     for (auto& renderer : *m_slowRepaintObjects)
2127         renderer->repaintSlowRepaintObject();
2128 }
2129
2130 // Note that this gets called at painting time.
2131 void FrameView::setIsOverlapped(bool isOverlapped)
2132 {
2133     if (isOverlapped == m_isOverlapped)
2134         return;
2135
2136     m_isOverlapped = isOverlapped;
2137     updateCanBlitOnScrollRecursively();
2138 }
2139
2140 void FrameView::setContentIsOpaque(bool contentIsOpaque)
2141 {
2142     if (contentIsOpaque == m_contentIsOpaque)
2143         return;
2144
2145     m_contentIsOpaque = contentIsOpaque;
2146     updateCanBlitOnScrollRecursively();
2147 }
2148
2149 void FrameView::restoreScrollbar()
2150 {
2151     setScrollbarsSuppressed(false);
2152 }
2153
2154 bool FrameView::scrollToFragment(const URL& url)
2155 {
2156     String fragmentIdentifier = url.fragmentIdentifier();
2157     if (scrollToAnchor(fragmentIdentifier))
2158         return true;
2159
2160     // Try again after decoding the ref, based on the document's encoding.
2161     if (TextResourceDecoder* decoder = frame().document()->decoder()) {
2162         if (scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding())))
2163             return true;
2164     }
2165
2166     resetScrollAnchor();
2167     return false;
2168 }
2169
2170 bool FrameView::scrollToAnchor(const String& fragmentIdentifier)
2171 {
2172     LOG(Scrolling, "FrameView::scrollToAnchor %s", fragmentIdentifier.utf8().data());
2173
2174     // If our URL has no ref, then we have no place we need to jump to.
2175     if (fragmentIdentifier.isNull())
2176         return false;
2177
2178     ASSERT(frame().document());
2179     auto& document = *frame().document();
2180
2181     if (!document.haveStylesheetsLoaded()) {
2182         document.setGotoAnchorNeededAfterStylesheetsLoad(true);
2183         return false;
2184     }
2185
2186     document.setGotoAnchorNeededAfterStylesheetsLoad(false);
2187
2188     Element* anchorElement = document.findAnchor(fragmentIdentifier);
2189
2190     LOG(Scrolling, " anchorElement is %p", anchorElement);
2191
2192     // Setting to null will clear the current target.
2193     document.setCSSTarget(anchorElement);
2194
2195     if (is<SVGDocument>(document)) {
2196         if (fragmentIdentifier.isEmpty())
2197             return false;
2198         if (auto rootElement = SVGDocument::rootElement(document)) {
2199             if (rootElement->scrollToFragment(fragmentIdentifier))
2200                 return true;
2201             // If SVG failed to scrollToAnchor() and anchorElement is null, no other scrolling will be possible.
2202             if (!anchorElement)
2203                 return false;
2204         }
2205     } else if (!anchorElement && !(fragmentIdentifier.isEmpty() || equalLettersIgnoringASCIICase(fragmentIdentifier, "top"))) {
2206         // Implement the rule that "" and "top" both mean top of page as in other browsers.
2207         return false;
2208     }
2209
2210     ContainerNode* scrollPositionAnchor = anchorElement;
2211     if (!scrollPositionAnchor)
2212         scrollPositionAnchor = frame().document();
2213     maintainScrollPositionAtAnchor(scrollPositionAnchor);
2214     
2215     // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
2216     if (anchorElement) {
2217         if (anchorElement->isFocusable())
2218             document.setFocusedElement(anchorElement);
2219         else {
2220             document.setFocusedElement(nullptr);
2221             document.setFocusNavigationStartingNode(anchorElement);
2222         }
2223     }
2224     
2225     return true;
2226 }
2227
2228 void FrameView::maintainScrollPositionAtAnchor(ContainerNode* anchorNode)
2229 {
2230     LOG(Scrolling, "FrameView::maintainScrollPositionAtAnchor at %p", anchorNode);
2231
2232     m_maintainScrollPositionAnchor = anchorNode;
2233     if (!m_maintainScrollPositionAnchor)
2234         return;
2235     m_shouldScrollToFocusedElement = false;
2236     m_delayedScrollToFocusedElementTimer.stop();
2237
2238     // We need to update the layout before scrolling, otherwise we could
2239     // really mess things up if an anchor scroll comes at a bad moment.
2240     frame().document()->updateStyleIfNeeded();
2241     // Only do a layout if changes have occurred that make it necessary.
2242     RenderView* renderView = this->renderView();
2243     if (renderView && renderView->needsLayout())
2244         layoutContext().layout();
2245     else
2246         scrollToAnchor();
2247 }
2248
2249 void FrameView::scrollElementToRect(const Element& element, const IntRect& rect)
2250 {
2251     frame().document()->updateLayoutIgnorePendingStylesheets();
2252
2253     LayoutRect bounds;
2254     if (RenderElement* renderer = element.renderer())
2255         bounds = renderer->absoluteAnchorRect();
2256     int centeringOffsetX = (rect.width() - bounds.width()) / 2;
2257     int centeringOffsetY = (rect.height() - bounds.height()) / 2;
2258     setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y()));
2259 }
2260
2261 void FrameView::setScrollPosition(const ScrollPosition& scrollPosition)
2262 {
2263     LOG_WITH_STREAM(Scrolling, stream << "FrameView::setScrollPosition " << scrollPosition << " , clearing anchor");
2264
2265     auto oldScrollType = currentScrollType();
2266     setCurrentScrollType(ScrollType::Programmatic);
2267
2268     m_maintainScrollPositionAnchor = nullptr;
2269     m_shouldScrollToFocusedElement = false;
2270     m_delayedScrollToFocusedElementTimer.stop();
2271     Page* page = frame().page();
2272     if (page && page->expectsWheelEventTriggers())
2273         scrollAnimator().setWheelEventTestTrigger(page->testTrigger());
2274     ScrollView::setScrollPosition(scrollPosition);
2275
2276     setCurrentScrollType(oldScrollType);
2277 }
2278
2279 void FrameView::resetScrollAnchor()
2280 {
2281     ASSERT(frame().document());
2282     auto& document = *frame().document();
2283
2284     // If CSS target was set previously, we want to set it to 0, recalc
2285     // and possibly repaint because :target pseudo class may have been
2286     // set (see bug 11321).
2287     document.setCSSTarget(nullptr);
2288
2289     if (is<SVGDocument>(document)) {
2290         if (auto rootElement = SVGDocument::rootElement(document)) {
2291             // We need to update the layout before resetScrollAnchor(), otherwise we
2292             // could really mess things up if resetting the anchor comes at a bad moment.
2293             document.updateStyleIfNeeded();
2294             rootElement->resetScrollAnchor();
2295         }
2296     }
2297 }
2298
2299 void FrameView::scheduleScrollToFocusedElement(SelectionRevealMode selectionRevealMode)
2300 {
2301     if (selectionRevealMode == SelectionRevealMode::DoNotReveal)
2302         return;
2303
2304     m_selectionRevealModeForFocusedElement = selectionRevealMode;
2305     if (m_shouldScrollToFocusedElement)
2306         return;
2307     m_shouldScrollToFocusedElement = true;
2308     m_delayedScrollToFocusedElementTimer.startOneShot(0_s);
2309 }
2310
2311 void FrameView::scrollToFocusedElementImmediatelyIfNeeded()
2312 {
2313     if (!m_shouldScrollToFocusedElement)
2314         return;
2315
2316     m_delayedScrollToFocusedElementTimer.stop();
2317     scrollToFocusedElementInternal();
2318 }
2319
2320 void FrameView::scrollToFocusedElementTimerFired()
2321 {
2322     auto protectedThis = makeRef(*this);
2323     scrollToFocusedElementInternal();
2324 }
2325
2326 void FrameView::scrollToFocusedElementInternal()
2327 {
2328     RELEASE_ASSERT(m_shouldScrollToFocusedElement);
2329     auto document = makeRefPtr(frame().document());
2330     if (!document)
2331         return;
2332
2333     document->updateLayoutIgnorePendingStylesheets();
2334     if (!m_shouldScrollToFocusedElement)
2335         return; // Updating the layout may have ran scripts.
2336     m_shouldScrollToFocusedElement = false;
2337
2338     auto focusedElement = makeRefPtr(document->focusedElement());
2339     if (!focusedElement)
2340         return;
2341     auto updateTarget = focusedElement->focusAppearanceUpdateTarget();
2342     if (!updateTarget)
2343         return;
2344
2345     auto* renderer = updateTarget->renderer();
2346     if (!renderer || renderer->isWidget())
2347         return;
2348
2349     bool insideFixed;
2350     LayoutRect absoluteBounds = renderer->absoluteAnchorRect(&insideFixed);
2351     renderer->scrollRectToVisible(absoluteBounds, insideFixed, { m_selectionRevealModeForFocusedElement, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded, ShouldAllowCrossOriginScrolling::No });
2352 }
2353
2354 void FrameView::contentsResized()
2355 {
2356     // For non-delegated scrolling, updateTiledBackingAdaptiveSizing() is called via addedOrRemovedScrollbar() which occurs less often.
2357     if (delegatesScrolling())
2358         updateTiledBackingAdaptiveSizing();
2359 }
2360
2361 void FrameView::delegatesScrollingDidChange()
2362 {
2363     RenderView* renderView = this->renderView();
2364     if (!renderView)
2365         return;
2366
2367     RenderLayerCompositor& compositor = renderView->compositor();
2368     // When we switch to delegatesScrolling mode, we should destroy the scrolling/clipping layers in RenderLayerCompositor.
2369     if (compositor.usesCompositing()) {
2370         ASSERT(compositor.usesCompositing());
2371         compositor.enableCompositingMode(false);
2372         compositor.clearBackingForAllLayers();
2373     }
2374 }
2375
2376 #if USE(COORDINATED_GRAPHICS)
2377 void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect)
2378 {
2379     bool visibleContentSizeDidChange = false;
2380     if (visibleContentRect.size() != this->fixedVisibleContentRect().size()) {
2381         // When the viewport size changes or the content is scaled, we need to
2382         // reposition the fixed and sticky positioned elements.
2383         setViewportConstrainedObjectsNeedLayout();
2384         visibleContentSizeDidChange = true;
2385     }
2386
2387     IntPoint oldPosition = scrollPosition();
2388     ScrollView::setFixedVisibleContentRect(visibleContentRect);
2389     IntPoint newPosition = scrollPosition();
2390     if (oldPosition != newPosition) {
2391         updateLayerPositionsAfterScrolling();
2392         if (frame().settings().acceleratedCompositingForFixedPositionEnabled())
2393             updateCompositingLayersAfterScrolling();
2394         scrollAnimator().setCurrentPosition(newPosition);
2395         scrollPositionChanged(oldPosition, newPosition);
2396     }
2397     if (visibleContentSizeDidChange) {
2398         // Update the scroll-bars to calculate new page-step size.
2399         updateScrollbars(scrollPosition());
2400     }
2401     didChangeScrollOffset();
2402 }
2403 #endif
2404
2405 void FrameView::setViewportConstrainedObjectsNeedLayout()
2406 {
2407     if (!hasViewportConstrainedObjects())
2408         return;
2409
2410     for (auto& renderer : *m_viewportConstrainedObjects) {
2411         renderer->setNeedsLayout();
2412         if (renderer->hasLayer()) {
2413             auto* layer = downcast<RenderBoxModelObject>(*renderer).layer();
2414             layer->setNeedsCompositingGeometryUpdate();
2415         }
2416     }
2417 }
2418
2419 void FrameView::didChangeScrollOffset()
2420 {
2421     if (auto* page = frame().page())
2422         page->pageOverlayController().didScrollFrame(frame());
2423     frame().loader().client().didChangeScrollOffset();
2424 }
2425
2426 void FrameView::scrollOffsetChangedViaPlatformWidgetImpl(const ScrollOffset& oldOffset, const ScrollOffset& newOffset)
2427 {
2428     updateLayerPositionsAfterScrolling();
2429     updateCompositingLayersAfterScrolling();
2430     repaintSlowRepaintObjects();
2431     scrollPositionChanged(scrollPositionFromOffset(oldOffset), scrollPositionFromOffset(newOffset));
2432     
2433     if (auto* renderView = this->renderView()) {
2434         if (renderView->usesCompositing())
2435             renderView->compositor().didChangeVisibleRect();
2436     }
2437 }
2438
2439 // These scroll positions are affected by zooming.
2440 void FrameView::scrollPositionChanged(const ScrollPosition& oldPosition, const ScrollPosition& newPosition)
2441 {
2442     UNUSED_PARAM(oldPosition);
2443     UNUSED_PARAM(newPosition);
2444
2445     Page* page = frame().page();
2446     Seconds throttlingDelay = page ? page->chrome().client().eventThrottlingDelay() : 0_s;
2447
2448     if (throttlingDelay == 0_s) {
2449         m_delayedScrollEventTimer.stop();
2450         sendScrollEvent();
2451     } else if (!m_delayedScrollEventTimer.isActive())
2452         m_delayedScrollEventTimer.startOneShot(throttlingDelay);
2453
2454     if (RenderView* renderView = this->renderView()) {
2455         if (renderView->usesCompositing())
2456             renderView->compositor().frameViewDidScroll();
2457     }
2458
2459     LOG_WITH_STREAM(Scrolling, stream << "FrameView " << this << " scrollPositionChanged from " << oldPosition << " to " << newPosition << " (scale " << frameScaleFactor() << " )");
2460     updateLayoutViewport();
2461     viewportContentsChanged();
2462 }
2463
2464 void FrameView::applyRecursivelyWithVisibleRect(const WTF::Function<void (FrameView& frameView, const IntRect& visibleRect)>& apply)
2465 {
2466     IntRect windowClipRect = this->windowClipRect();
2467     auto visibleRect = windowToContents(windowClipRect);
2468     apply(*this, visibleRect);
2469
2470     // Recursive call for subframes. We cache the current FrameView's windowClipRect to avoid recomputing it for every subframe.
2471     SetForScope<IntRect*> windowClipRectCache(m_cachedWindowClipRect, &windowClipRect);
2472     for (Frame* childFrame = frame().tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling()) {
2473         if (auto* childView = childFrame->view())
2474             childView->applyRecursivelyWithVisibleRect(apply);
2475     }
2476 }
2477
2478 void FrameView::resumeVisibleImageAnimations(const IntRect& visibleRect)
2479 {
2480     if (visibleRect.isEmpty())
2481         return;
2482
2483     if (auto* renderView = frame().contentRenderer())
2484         renderView->resumePausedImageAnimationsIfNeeded(visibleRect);
2485 }
2486
2487 void FrameView::updateScriptedAnimationsAndTimersThrottlingState(const IntRect& visibleRect)
2488 {
2489     if (frame().isMainFrame())
2490         return;
2491
2492     auto* document = frame().document();
2493     if (!document)
2494         return;
2495
2496     // We don't throttle zero-size or display:none frames because those are usually utility frames.
2497     bool shouldThrottle = visibleRect.isEmpty() && !m_size.isEmpty() && frame().ownerRenderer();
2498
2499     if (auto* scriptedAnimationController = document->scriptedAnimationController()) {
2500         if (shouldThrottle)
2501             scriptedAnimationController->addThrottlingReason(ScriptedAnimationController::ThrottlingReason::OutsideViewport);
2502         else
2503             scriptedAnimationController->removeThrottlingReason(ScriptedAnimationController::ThrottlingReason::OutsideViewport);
2504     }
2505
2506     document->setTimerThrottlingEnabled(shouldThrottle);
2507 }
2508
2509
2510 void FrameView::resumeVisibleImageAnimationsIncludingSubframes()
2511 {
2512     applyRecursivelyWithVisibleRect([] (FrameView& frameView, const IntRect& visibleRect) {
2513         frameView.resumeVisibleImageAnimations(visibleRect);
2514     });
2515 }
2516
2517 void FrameView::updateLayerPositionsAfterScrolling()
2518 {
2519     // If we're scrolling as a result of updating the view size after layout, we'll update widgets and layer positions soon anyway.
2520     if (layoutContext().layoutPhase() == FrameViewLayoutContext::LayoutPhase::InViewSizeAdjust)
2521         return;
2522
2523     if (!layoutContext().isLayoutNested() && hasViewportConstrainedObjects()) {
2524         if (RenderView* renderView = this->renderView()) {
2525             updateWidgetPositions();
2526             renderView->layer()->updateLayerPositionsAfterDocumentScroll();
2527         }
2528     }
2529 }
2530
2531 bool FrameView::shouldUpdateCompositingLayersAfterScrolling() const
2532 {
2533 #if ENABLE(ASYNC_SCROLLING)
2534     // If the scrolling thread is updating the fixed elements, then the FrameView should not update them as well.
2535
2536     Page* page = frame().page();
2537     if (!page)
2538         return true;
2539
2540     if (&page->mainFrame() != m_frame.ptr())
2541         return true;
2542
2543     ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
2544     if (!scrollingCoordinator)
2545         return true;
2546
2547     if (scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously(*this))
2548         return true;
2549
2550     if (currentScrollType() == ScrollType::Programmatic)
2551         return true;
2552
2553     return false;
2554 #endif
2555     return true;
2556 }
2557
2558 void FrameView::updateCompositingLayersAfterScrolling()
2559 {
2560     ASSERT(layoutContext().layoutPhase() >= FrameViewLayoutContext::LayoutPhase::InPostLayout || layoutContext().layoutPhase() == FrameViewLayoutContext::LayoutPhase::OutsideLayout);
2561
2562     if (!shouldUpdateCompositingLayersAfterScrolling())
2563         return;
2564
2565     if (!layoutContext().isLayoutNested() && hasViewportConstrainedObjects()) {
2566         if (RenderView* renderView = this->renderView())
2567             renderView->compositor().updateCompositingLayers(CompositingUpdateType::OnScroll);
2568     }
2569 }
2570
2571 bool FrameView::isRubberBandInProgress() const
2572 {
2573     if (scrollbarsSuppressed())
2574         return false;
2575
2576     // If the scrolling thread updates the scroll position for this FrameView, then we should return
2577     // ScrollingCoordinator::isRubberBandInProgress().
2578     if (Page* page = frame().page()) {
2579         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
2580             if (!scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously(*this))
2581                 return scrollingCoordinator->isRubberBandInProgress();
2582         }
2583     }
2584
2585     // If the main thread updates the scroll position for this FrameView, we should return
2586     // ScrollAnimator::isRubberBandInProgress().
2587     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
2588         return scrollAnimator->isRubberBandInProgress();
2589
2590     return false;
2591 }
2592
2593 bool FrameView::requestScrollPositionUpdate(const ScrollPosition& position)
2594 {
2595     LOG_WITH_STREAM(Scrolling, stream << "FrameView::requestScrollPositionUpdate " << position);
2596
2597 #if ENABLE(ASYNC_SCROLLING)
2598     if (TiledBacking* tiledBacking = this->tiledBacking())
2599         tiledBacking->prepopulateRect(FloatRect(position, visibleContentRect().size()));
2600 #endif
2601
2602 #if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
2603     if (Page* page = frame().page()) {
2604         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
2605             return scrollingCoordinator->requestScrollPositionUpdate(*this, position);
2606     }
2607 #else
2608     UNUSED_PARAM(position);
2609 #endif
2610
2611     return false;
2612 }
2613
2614 HostWindow* FrameView::hostWindow() const
2615 {
2616     auto* page = frame().page();
2617     if (!page)
2618         return nullptr;
2619     return &page->chrome();
2620 }
2621
2622 void FrameView::addTrackedRepaintRect(const FloatRect& r)
2623 {
2624     if (!m_isTrackingRepaints || r.isEmpty())
2625         return;
2626
2627     FloatRect repaintRect = r;
2628     repaintRect.moveBy(-scrollPosition());
2629     m_trackedRepaintRects.append(repaintRect);
2630 }
2631
2632 void FrameView::repaintContentRectangle(const IntRect& r)
2633 {
2634     ASSERT(!frame().ownerElement());
2635
2636     if (!shouldUpdate())
2637         return;
2638
2639     ScrollView::repaintContentRectangle(r);
2640 }
2641
2642 static unsigned countRenderedCharactersInRenderObjectWithThreshold(const RenderElement& renderer, unsigned threshold)
2643 {
2644     unsigned count = 0;
2645     for (const RenderObject* descendant = &renderer; descendant; descendant = descendant->nextInPreOrder()) {
2646         if (is<RenderText>(*descendant)) {
2647             count += downcast<RenderText>(*descendant).text().length();
2648             if (count >= threshold)
2649                 break;
2650         }
2651     }
2652     return count;
2653 }
2654
2655 bool FrameView::renderedCharactersExceed(unsigned threshold)
2656 {
2657     if (!frame().contentRenderer())
2658         return false;
2659     return countRenderedCharactersInRenderObjectWithThreshold(*frame().contentRenderer(), threshold) >= threshold;
2660 }
2661
2662 void FrameView::availableContentSizeChanged(AvailableSizeChangeReason reason)
2663 {
2664     if (Document* document = frame().document()) {
2665         // FIXME: Merge this logic with m_setNeedsLayoutWasDeferred and find a more appropriate
2666         // way of handling potential recursive layouts when the viewport is resized to accomodate
2667         // the content but the content always overflows the viewport. See webkit.org/b/165781.
2668         if (!(layoutContext().layoutPhase() == FrameViewLayoutContext::LayoutPhase::InViewSizeAdjust && useFixedLayout()))
2669             document->updateViewportUnitsOnResize();
2670     }
2671
2672     updateLayoutViewport();
2673     setNeedsLayoutAfterViewConfigurationChange();
2674     ScrollView::availableContentSizeChanged(reason);
2675 }
2676
2677 bool FrameView::shouldLayoutAfterContentsResized() const
2678 {
2679     return !useFixedLayout() || useCustomFixedPositionLayoutRect();
2680 }
2681
2682 void FrameView::updateContentsSize()
2683 {
2684     // We check to make sure the view is attached to a frame() as this method can
2685     // be triggered before the view is attached by Frame::createView(...) setting
2686     // various values such as setScrollBarModes(...) for example.  An ASSERT is
2687     // triggered when a view is layout before being attached to a frame().
2688     if (!frame().view())
2689         return;
2690
2691 #if PLATFORM(IOS_FAMILY)
2692     if (RenderView* root = m_frame->contentRenderer()) {
2693         if (useCustomFixedPositionLayoutRect() && hasViewportConstrainedObjects()) {
2694             setViewportConstrainedObjectsNeedLayout();
2695             // We must eagerly enter compositing mode because fixed position elements
2696             // will not have been made compositing via a preceding style change before
2697             // m_useCustomFixedPositionLayoutRect was true.
2698             root->compositor().enableCompositingMode();
2699         }
2700     }
2701 #endif
2702
2703     if (shouldLayoutAfterContentsResized() && needsLayout())
2704         layoutContext().layout();
2705
2706     if (RenderView* renderView = this->renderView()) {
2707         if (renderView->usesCompositing())
2708             renderView->compositor().frameViewDidChangeSize();
2709     }
2710 }
2711
2712 void FrameView::addedOrRemovedScrollbar()
2713 {
2714     if (RenderView* renderView = this->renderView()) {
2715         if (renderView->usesCompositing())
2716             renderView->compositor().frameViewDidAddOrRemoveScrollbars();
2717     }
2718
2719     updateTiledBackingAdaptiveSizing();
2720 }
2721
2722 TiledBacking::Scrollability FrameView::computeScrollability() const
2723 {
2724     auto* page = frame().page();
2725
2726     // Use smaller square tiles if the Window is not active to facilitate app napping.
2727     if (!page || !page->isWindowActive())
2728         return TiledBacking::HorizontallyScrollable | TiledBacking::VerticallyScrollable;
2729
2730     bool horizontallyScrollable;
2731     bool verticallyScrollable;
2732     bool clippedByAncestorView = static_cast<bool>(m_viewExposedRect);
2733
2734 #if PLATFORM(IOS_FAMILY)
2735     if (page)
2736         clippedByAncestorView |= page->enclosedInScrollableAncestorView();
2737 #endif
2738
2739     if (delegatesScrolling()) {
2740         IntSize documentSize = contentsSize();
2741         IntSize visibleSize = this->visibleSize();
2742
2743         horizontallyScrollable = clippedByAncestorView || documentSize.width() > visibleSize.width();
2744         verticallyScrollable = clippedByAncestorView || documentSize.height() > visibleSize.height();
2745     } else {
2746         horizontallyScrollable = clippedByAncestorView || horizontalScrollbar();
2747         verticallyScrollable = clippedByAncestorView || verticalScrollbar();
2748     }
2749
2750     TiledBacking::Scrollability scrollability = TiledBacking::NotScrollable;
2751     if (horizontallyScrollable)
2752         scrollability = TiledBacking::HorizontallyScrollable;
2753
2754     if (verticallyScrollable)
2755         scrollability |= TiledBacking::VerticallyScrollable;
2756
2757     return scrollability;
2758 }
2759
2760 void FrameView::updateTiledBackingAdaptiveSizing()
2761 {
2762     auto* tiledBacking = this->tiledBacking();
2763     if (!tiledBacking)
2764         return;
2765
2766     tiledBacking->setScrollability(computeScrollability());
2767 }
2768
2769 #if PLATFORM(IOS_FAMILY)
2770
2771 void FrameView::didUpdateViewportOverrideRects()
2772 {
2773     if (!frame().settings().visualViewportAPIEnabled())
2774         return;
2775
2776     if (auto* window = frame().window())
2777         window->visualViewport().update();
2778 }
2779
2780 void FrameView::unobscuredContentSizeChanged()
2781 {
2782     updateTiledBackingAdaptiveSizing();
2783 }
2784
2785 #endif
2786
2787 static LayerFlushThrottleState::Flags determineLayerFlushThrottleState(Page& page)
2788 {
2789     // We only throttle when constantly receiving new data during the inital page load.
2790     if (!page.progress().isMainLoadProgressing())
2791         return 0;
2792     // Scrolling during page loading disables throttling.
2793     if (page.mainFrame().view()->wasScrolledByUser())
2794         return 0;
2795     // Disable for image documents so large GIF animations don't get throttled during loading.
2796     auto* document = page.mainFrame().document();
2797     if (!document || is<ImageDocument>(*document))
2798         return 0;
2799     return LayerFlushThrottleState::Enabled;
2800 }
2801
2802 void FrameView::disableLayerFlushThrottlingTemporarilyForInteraction()
2803 {
2804     if (!frame().page())
2805         return;
2806     auto& page = *frame().page();
2807
2808     LayerFlushThrottleState::Flags flags = LayerFlushThrottleState::UserIsInteracting | determineLayerFlushThrottleState(page);
2809     if (page.chrome().client().adjustLayerFlushThrottling(flags))
2810         return;
2811
2812     if (RenderView* view = renderView())
2813         view->compositor().disableLayerFlushThrottlingTemporarilyForInteraction();
2814 }
2815
2816 void FrameView::loadProgressingStatusChanged()
2817 {
2818     if (!m_isVisuallyNonEmpty && frame().loader().isComplete())
2819         fireLayoutRelatedMilestonesIfNeeded();
2820     updateLayerFlushThrottling();
2821     adjustTiledBackingCoverage();
2822 }
2823
2824 void FrameView::updateLayerFlushThrottling()
2825 {
2826     Page* page = frame().page();
2827     if (!page)
2828         return;
2829
2830     ASSERT(frame().isMainFrame());
2831
2832     LayerFlushThrottleState::Flags flags = determineLayerFlushThrottleState(*page);
2833
2834     // See if the client is handling throttling.
2835     if (page->chrome().client().adjustLayerFlushThrottling(flags))
2836         return;
2837
2838     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
2839         if (RenderView* renderView = frame->contentRenderer())
2840             renderView->compositor().setLayerFlushThrottlingEnabled(flags & LayerFlushThrottleState::Enabled);
2841     }
2842 }
2843
2844 void FrameView::adjustTiledBackingCoverage()
2845 {
2846     if (!m_speculativeTilingEnabled)
2847         enableSpeculativeTilingIfNeeded();
2848
2849     RenderView* renderView = this->renderView();
2850     if (renderView && renderView->layer() && renderView->layer()->backing())
2851         renderView->layer()->backing()->adjustTiledBackingCoverage();
2852 #if PLATFORM(IOS_FAMILY)
2853     if (LegacyTileCache* tileCache = legacyTileCache())
2854         tileCache->setSpeculativeTileCreationEnabled(m_speculativeTilingEnabled);
2855 #endif
2856 }
2857
2858 static bool shouldEnableSpeculativeTilingDuringLoading(const FrameView& view)
2859 {
2860     Page* page = view.frame().page();
2861     return page && view.isVisuallyNonEmpty() && !page->progress().isMainLoadProgressing();
2862 }
2863
2864 void FrameView::enableSpeculativeTilingIfNeeded()
2865 {
2866     ASSERT(!m_speculativeTilingEnabled);
2867     if (m_wasScrolledByUser) {
2868         m_speculativeTilingEnabled = true;
2869         return;
2870     }
2871     if (!shouldEnableSpeculativeTilingDuringLoading(*this))
2872         return;
2873
2874     if (m_speculativeTilingDelayDisabledForTesting) {
2875         speculativeTilingEnableTimerFired();
2876         return;
2877     }
2878
2879     if (m_speculativeTilingEnableTimer.isActive())
2880         return;
2881     // Delay enabling a bit as load completion may trigger further loading from scripts.
2882     static const Seconds speculativeTilingEnableDelay { 500_ms };
2883     m_speculativeTilingEnableTimer.startOneShot(speculativeTilingEnableDelay);
2884 }
2885
2886 void FrameView::speculativeTilingEnableTimerFired()
2887 {
2888     if (m_speculativeTilingEnabled)
2889         return;
2890     m_speculativeTilingEnabled = shouldEnableSpeculativeTilingDuringLoading(*this);
2891     adjustTiledBackingCoverage();
2892 }
2893
2894 void FrameView::show()
2895 {
2896     ScrollView::show();
2897
2898     if (frame().isMainFrame()) {
2899         // Turn off speculative tiling for a brief moment after a FrameView appears on screen.
2900         // Note that adjustTiledBackingCoverage() kicks the (500ms) timer to re-enable it.
2901         m_speculativeTilingEnabled = false;
2902         m_wasScrolledByUser = false;
2903         adjustTiledBackingCoverage();
2904     }
2905 }
2906
2907 void FrameView::hide()
2908 {
2909     ScrollView::hide();
2910     adjustTiledBackingCoverage();
2911 }
2912
2913 bool FrameView::needsLayout() const
2914 {
2915     return layoutContext().needsLayout();
2916 }
2917
2918 void FrameView::setNeedsLayoutAfterViewConfigurationChange()
2919 {
2920     layoutContext().setNeedsLayoutAfterViewConfigurationChange();
2921 }
2922
2923 void FrameView::setNeedsCompositingConfigurationUpdate()
2924 {
2925     RenderView* renderView = this->renderView();
2926     if (renderView->usesCompositing()) {
2927         if (auto* rootLayer = renderView->layer())
2928             rootLayer->setNeedsCompositingConfigurationUpdate();
2929         renderView->compositor().scheduleCompositingLayerUpdate();
2930     }
2931 }
2932
2933 void FrameView::setNeedsCompositingGeometryUpdate()
2934 {
2935     RenderView* renderView = this->renderView();
2936     if (renderView->usesCompositing()) {
2937         if (auto* rootLayer = renderView->layer())
2938             rootLayer->setNeedsCompositingGeometryUpdate();
2939         renderView->compositor().scheduleCompositingLayerUpdate();
2940     }
2941 }
2942
2943 void FrameView::scheduleSelectionUpdate()
2944 {
2945     if (needsLayout())
2946         return;
2947     // FIXME: We should not need to go through the layout process since selection update does not change dimension/geometry.
2948     // However we can't tell at this point if the tree is stable yet, so let's just schedule a root only layout for now.
2949     setNeedsLayoutAfterViewConfigurationChange();
2950 }
2951
2952 bool FrameView::isTransparent() const
2953 {
2954     return m_isTransparent;
2955 }
2956
2957 void FrameView::setTransparent(bool isTransparent)
2958 {
2959     if (m_isTransparent == isTransparent)
2960         return;
2961
2962     m_isTransparent = isTransparent;
2963
2964     // setTransparent can be called in the window between FrameView initialization
2965     // and switching in the new Document; this means that the RenderView that we
2966     // retrieve is actually attached to the previous Document, which is going away,
2967     // and must not update compositing layers.
2968     if (!isViewForDocumentInFrame())
2969         return;
2970
2971     setNeedsLayoutAfterViewConfigurationChange();
2972     setNeedsCompositingConfigurationUpdate();
2973 }
2974
2975 bool FrameView::hasOpaqueBackground() const
2976 {
2977     return !m_isTransparent && m_baseBackgroundColor.isOpaque();
2978 }
2979
2980 Color FrameView::baseBackgroundColor() const
2981 {
2982     return m_baseBackgroundColor;
2983 }
2984
2985 void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
2986 {
2987     Color newBaseBackgroundColor = backgroundColor.isValid() ? backgroundColor : Color::white;
2988     if (m_baseBackgroundColor == newBaseBackgroundColor)
2989         return;
2990
2991     m_baseBackgroundColor = newBaseBackgroundColor;
2992
2993     if (!isViewForDocumentInFrame())
2994         return;
2995
2996     recalculateScrollbarOverlayStyle();
2997     setNeedsLayoutAfterViewConfigurationChange();
2998     setNeedsCompositingConfigurationUpdate();
2999 }
3000
3001 void FrameView::updateBackgroundRecursively(const Optional<Color>& backgroundColor)
3002 {
3003 #if HAVE(OS_DARK_MODE_SUPPORT) && ENABLE(DARK_MODE_CSS)
3004     Color baseBackgroundColor = backgroundColor.valueOr(RenderTheme::singleton().systemColor(CSSValueAppleSystemControlBackground, styleColorOptions()));
3005 #else
3006     Color baseBackgroundColor = backgroundColor.valueOr(Color::white);
3007 #endif
3008
3009     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
3010         if (FrameView* view = frame->view()) {
3011             view->setTransparent(!baseBackgroundColor.isVisible());
3012             view->setBaseBackgroundColor(baseBackgroundColor);
3013             if (view->needsLayout())
3014                 view->layoutContext().scheduleLayout();
3015         }
3016     }
3017 }
3018
3019 bool FrameView::hasExtendedBackgroundRectForPainting() const
3020 {
3021     TiledBacking* tiledBacking = this->tiledBacking();
3022     if (!tiledBacking)
3023         return false;
3024
3025     return tiledBacking->hasMargins();
3026 }
3027
3028 void FrameView::updateExtendBackgroundIfNecessary()
3029 {
3030     ExtendedBackgroundMode mode = calculateExtendedBackgroundMode();
3031     if (mode == ExtendedBackgroundModeNone)
3032         return;
3033
3034     updateTilesForExtendedBackgroundMode(mode);
3035 }
3036
3037 FrameView::ExtendedBackgroundMode FrameView::calculateExtendedBackgroundMode() const
3038 {
3039 #if PLATFORM(IOS_FAMILY)
3040     // <rdar://problem/16201373>
3041     return ExtendedBackgroundModeNone;
3042 #else
3043     if (!frame().settings().backgroundShouldExtendBeyondPage())
3044         return ExtendedBackgroundModeNone;
3045
3046     // Just because Settings::backgroundShouldExtendBeyondPage() is true does not necessarily mean
3047     // that the background rect needs to be extended for painting. Simple backgrounds can be extended
3048     // just with RenderLayerCompositor's rootExtendedBackgroundColor. More complicated backgrounds,
3049     // such as images, require extending the background rect to continue painting into the extended
3050     // region. This function finds out if it is necessary to extend the background rect for painting.
3051
3052     if (!frame().isMainFrame())
3053         return ExtendedBackgroundModeNone;
3054
3055     Document* document = frame().document();
3056     if (!document)
3057         return ExtendedBackgroundModeNone;
3058
3059     if (!renderView())
3060         return ExtendedBackgroundModeNone;
3061     
3062     auto* rootBackgroundRenderer = renderView()->rendererForRootBackground();
3063     if (!rootBackgroundRenderer)
3064         return ExtendedBackgroundModeNone;
3065
3066     if (!rootBackgroundRenderer->style().hasBackgroundImage())
3067         return ExtendedBackgroundModeNone;
3068
3069     ExtendedBackgroundMode mode = ExtendedBackgroundModeNone;
3070     if (rootBackgroundRenderer->style().backgroundRepeatX() == FillRepeat::Repeat)
3071         mode |= ExtendedBackgroundModeHorizontal;
3072     if (rootBackgroundRenderer->style().backgroundRepeatY() == FillRepeat::Repeat)
3073         mode |= ExtendedBackgroundModeVertical;
3074
3075     return mode;
3076 #endif
3077 }
3078
3079 void FrameView::updateTilesForExtendedBackgroundMode(ExtendedBackgroundMode mode)
3080 {
3081     RenderView* renderView = this->renderView();
3082     if (!renderView)
3083         return;
3084
3085     RenderLayerBacking* backing = renderView->layer()->backing();
3086     if (!backing)
3087         return;
3088
3089     TiledBacking* tiledBacking = backing->tiledBacking();
3090     if (!tiledBacking)
3091         return;
3092
3093     ExtendedBackgroundMode existingMode = ExtendedBackgroundModeNone;
3094     if (tiledBacking->hasVerticalMargins())
3095         existingMode |= ExtendedBackgroundModeVertical;
3096     if (tiledBacking->hasHorizontalMargins())
3097         existingMode |= ExtendedBackgroundModeHorizontal;
3098
3099     if (existingMode == mode)
3100         return;
3101
3102     backing->setTiledBackingHasMargins(mode & ExtendedBackgroundModeHorizontal, mode & ExtendedBackgroundModeVertical);
3103 }
3104
3105 IntRect FrameView::extendedBackgroundRectForPainting() const
3106 {
3107     TiledBacking* tiledBacking = this->tiledBacking();
3108     if (!tiledBacking)
3109         return IntRect();
3110     
3111     RenderView* renderView = this->renderView();
3112     if (!renderView)
3113         return IntRect();
3114     
3115     LayoutRect extendedRect = renderView->unextendedBackgroundRect();
3116     if (!tiledBacking->hasMargins())
3117         return snappedIntRect(extendedRect);
3118     
3119     extendedRect.moveBy(LayoutPoint(-tiledBacking->leftMarginWidth(), -tiledBacking->topMarginHeight()));
3120     extendedRect.expand(LayoutSize(tiledBacking->leftMarginWidth() + tiledBacking->rightMarginWidth(), tiledBacking->topMarginHeight() + tiledBacking->bottomMarginHeight()));
3121     return snappedIntRect(extendedRect);
3122 }
3123
3124 bool FrameView::shouldUpdateWhileOffscreen() const
3125 {
3126     return m_shouldUpdateWhileOffscreen;
3127 }
3128
3129 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
3130 {
3131     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
3132 }
3133
3134 bool FrameView::shouldUpdate() const
3135 {
3136     if (isOffscreen() && !shouldUpdateWhileOffscreen())
3137         return false;
3138     return true;
3139 }
3140
3141 bool FrameView::safeToPropagateScrollToParent() const
3142 {
3143     auto* document = frame().document();
3144     if (!document)
3145         return false;
3146
3147     auto* parentFrame = frame().tree().parent();
3148     if (!parentFrame)
3149         return false;
3150
3151     auto* parentDocument = parentFrame->document();
3152     if (!parentDocument)
3153         return false;
3154
3155     return document->securityOrigin().canAccess(parentDocument->securityOrigin());
3156 }
3157
3158 void FrameView::scrollToAnchor()
3159 {
3160     RefPtr<ContainerNode> anchorNode = m_maintainScrollPositionAnchor;
3161
3162     LOG_WITH_STREAM(Scrolling, stream << "FrameView::scrollToAnchor() " << anchorNode.get());
3163
3164     if (!anchorNode)
3165         return;
3166
3167     if (!anchorNode->renderer())
3168         return;
3169     m_shouldScrollToFocusedElement = false;
3170     m_delayedScrollToFocusedElementTimer.stop();
3171
3172     LayoutRect rect;
3173     bool insideFixed = false;
3174     if (anchorNode != frame().document() && anchorNode->renderer())
3175         rect = anchorNode->renderer()->absoluteAnchorRect(&insideFixed);
3176
3177     LOG_WITH_STREAM(Scrolling, stream << " anchor node rect " << rect);
3178
3179     // Scroll nested layers and frames to reveal the anchor.
3180     // Align to the top and to the closest side (this matches other browsers).
3181     if (anchorNode->renderer()->style().isHorizontalWritingMode())
3182         anchorNode->renderer()->scrollRectToVisible(rect, insideFixed, { SelectionRevealMode::Reveal, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways, ShouldAllowCrossOriginScrolling::No });
3183     else if (anchorNode->renderer()->style().isFlippedBlocksWritingMode())
3184         anchorNode->renderer()->scrollRectToVisible(rect, insideFixed, { SelectionRevealMode::Reveal, ScrollAlignment::alignRightAlways, ScrollAlignment::alignToEdgeIfNeeded, ShouldAllowCrossOriginScrolling::No });
3185     else
3186         anchorNode->renderer()->scrollRectToVisible(rect, insideFixed, { SelectionRevealMode::Reveal, ScrollAlignment::alignLeftAlways, ScrollAlignment::alignToEdgeIfNeeded, ShouldAllowCrossOriginScrolling::No });
3187
3188     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
3189         cache->handleScrolledToAnchor(anchorNode.get());
3190
3191     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
3192     LOG_WITH_STREAM(Scrolling, stream << " restoring anchor node to " << anchorNode.get());
3193     m_maintainScrollPositionAnchor = anchorNode;
3194     m_shouldScrollToFocusedElement = false;
3195     m_delayedScrollToFocusedElementTimer.stop();
3196 }
3197
3198 void FrameView::updateEmbeddedObject(RenderEmbeddedObject& embeddedObject)
3199 {
3200     // No need to update if it's already crashed or known to be missing.
3201     if (embeddedObject.isPluginUnavailable())
3202         return;
3203
3204     HTMLFrameOwnerElement& element = embeddedObject.frameOwnerElement();
3205
3206     if (embeddedObject.isSnapshottedPlugIn()) {
3207         if (is<HTMLObjectElement>(element) || is<HTMLEmbedElement>(element)) {
3208             HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
3209             pluginElement.checkSnapshotStatus();
3210         }
3211         return;
3212     }
3213
3214     auto weakRenderer = makeWeakPtr(embeddedObject);
3215
3216     // FIXME: This could turn into a real virtual dispatch if we defined
3217     // updateWidget(PluginCreationOption) on HTMLElement.
3218     if (is<HTMLPlugInImageElement>(element)) {
3219         HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
3220         if (pluginElement.needsCheckForSizeChange()) {
3221             pluginElement.checkSnapshotStatus();
3222             return;
3223         }
3224         if (pluginElement.needsWidgetUpdate())
3225             pluginElement.updateWidget(CreatePlugins::Yes);
3226     } else
3227         ASSERT_NOT_REACHED();
3228
3229     // It's possible the renderer was destroyed below updateWidget() since loading a plugin may execute arbitrary JavaScript.
3230     if (!weakRenderer)
3231         return;
3232
3233     auto ignoreWidgetState = embeddedObject.updateWidgetPosition();
3234     UNUSED_PARAM(ignoreWidgetState);
3235 }
3236
3237 bool FrameView::updateEmbeddedObjects()
3238 {
3239     if (layoutContext().isLayoutNested() || !m_embeddedObjectsToUpdate || m_embeddedObjectsToUpdate->isEmpty())
3240         return true;
3241
3242     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
3243
3244     // Insert a marker for where we should stop.
3245     ASSERT(!m_embeddedObjectsToUpdate->contains(nullptr));
3246     m_embeddedObjectsToUpdate->add(nullptr);
3247
3248     while (!m_embeddedObjectsToUpdate->isEmpty()) {
3249         RenderEmbeddedObject* embeddedObject = m_embeddedObjectsToUpdate->takeFirst();
3250         if (!embeddedObject)
3251             break;
3252         updateEmbeddedObject(*embeddedObject);
3253     }
3254
3255     return m_embeddedObjectsToUpdate->isEmpty();
3256 }
3257
3258 void FrameView::updateEmbeddedObjectsTimerFired()
3259 {
3260     RefPtr<FrameView> protectedThis(this);
3261     m_updateEmbeddedObjectsTimer.stop();
3262     for (unsigned i = 0; i < maxUpdateEmbeddedObjectsIterations; i++) {
3263         if (updateEmbeddedObjects())
3264             break;
3265     }
3266 }
3267
3268 void FrameView::flushAnyPendingPostLayoutTasks()
3269 {
3270     layoutContext().flushAsynchronousTasks();
3271     if (m_updateEmbeddedObjectsTimer.isActive())
3272         updateEmbeddedObjectsTimerFired();
3273 }
3274
3275 void FrameView::queuePostLayoutCallback(Function<void()>&& callback)
3276 {
3277     m_postLayoutCallbackQueue.append(WTFMove(callback));
3278 }
3279
3280 void FrameView::flushPostLayoutTasksQueue()
3281 {
3282     if (layoutContext().isLayoutNested())
3283         return;
3284
3285     if (!m_postLayoutCallbackQueue.size())
3286         return;
3287
3288     Vector<Function<void()>> queue = WTFMove(m_postLayoutCallbackQueue);
3289     for (auto& task : queue)
3290         task();
3291 }
3292
3293 void FrameView::performPostLayoutTasks()
3294 {
3295     // FIXME: We should not run any JavaScript code in this function.
3296     LOG(Layout, "FrameView %p performPostLayoutTasks", this);
3297     updateHasReachedSignificantRenderedTextThreshold();
3298     frame().selection().updateAppearanceAfterLayout();
3299
3300     flushPostLayoutTasksQueue();
3301
3302     if (!layoutContext().isLayoutNested() && frame().document()->documentElement())
3303         fireLayoutRelatedMilestonesIfNeeded();
3304
3305 #if PLATFORM(IOS_FAMILY)
3306     // Only send layout-related delegate callbacks synchronously for the main frame to
3307     // avoid re-entering layout for the main frame while delivering a layout-related delegate
3308     // callback for a subframe.
3309     if (frame().isMainFrame()) {
3310         if (Page* page = frame().page())
3311             page->chrome().client().didLayout();
3312     }
3313 #endif
3314     
3315     // FIXME: We should consider adding DidLayout as a LayoutMilestone. That would let us merge this
3316     // with didLayout(LayoutMilestones).
3317     frame().loader().client().dispatchDidLayout();
3318
3319     updateWidgetPositions();
3320
3321 #if ENABLE(CSS_SCROLL_SNAP)
3322     updateSnapOffsets();
3323 #endif
3324     m_updateEmbeddedObjectsTimer.startOneShot(0_s);
3325
3326     if (auto* page = frame().page()) {
3327         if (auto* scrollingCoordinator = page->scrollingCoordinator())
3328             scrollingCoordinator->frameViewLayoutUpdated(*this);
3329     }
3330
3331     if (RenderView* renderView = this->renderView()) {
3332         if (renderView->usesCompositing())
3333             renderView->compositor().frameViewDidLayout();
3334     }
3335
3336     scrollToAnchor();
3337
3338     sendResizeEventIfNeeded();
3339     
3340     updateLayoutViewport();
3341     viewportContentsChanged();
3342
3343     updateScrollSnapState();
3344
3345     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
3346         cache->performDeferredCacheUpdate();
3347 }
3348
3349 IntSize FrameView::sizeForResizeEvent() const
3350 {
3351 #if PLATFORM(IOS_FAMILY)
3352     if (m_useCustomSizeForResizeEvent)
3353         return m_customSizeForResizeEvent;
3354 #endif
3355     if (useFixedLayout() && !fixedLayoutSize().isEmpty() && delegatesScrolling())
3356         return fixedLayoutSize();
3357     return visibleContentRectIncludingScrollbars().size();
3358 }
3359
3360 void FrameView::sendResizeEventIfNeeded()
3361 {
3362     if (layoutContext().isInRenderTreeLayout() || needsLayout())
3363         return;
3364
3365     RenderView* renderView = this->renderView();
3366     if (!renderView || renderView->printing())
3367         return;
3368
3369     if (frame().page() && frame().page()->chrome().client().isSVGImageChromeClient())
3370         return;
3371
3372     IntSize currentSize = sizeForResizeEvent();
3373     float currentZoomFactor = renderView->style().zoom();
3374
3375     if (currentSize == m_lastViewportSize && currentZoomFactor == m_lastZoomFactor)
3376         return;
3377
3378     m_lastViewportSize = currentSize;
3379     m_lastZoomFactor = currentZoomFactor;
3380
3381     if (!layoutContext().didFirstLayout())
3382         return;
3383
3384 #if PLATFORM(IOS_FAMILY)
3385     // Don't send the resize event if the document is loading. Some pages automatically reload
3386     // when the window is resized; Safari on iOS often resizes the window while setting up its
3387     // viewport. This obviously can cause problems.
3388     if (DocumentLoader* documentLoader = frame().loader().documentLoader()) {
3389         if (documentLoader->isLoadingInAPISense())
3390             return;
3391     }
3392 #endif
3393
3394     bool isMainFrame = frame().isMainFrame();
3395     bool canSendResizeEventSynchronously = isMainFrame && !m_shouldAutoSize;
3396
3397     LOG(Events, "FrameView %p sendResizeEventIfNeeded sending resize event, size %dx%d (canSendResizeEventSynchronously %d)", this, currentSize.width(), currentSize.height(), canSendResizeEventSynchronously);
3398
3399     Ref<Event> resizeEvent = Event::create(eventNames().resizeEvent, Event::CanBubble::No, Event::IsCancelable::No);
3400     if (canSendResizeEventSynchronously)
3401         frame().document()->dispatchWindowEvent(resizeEvent);
3402     else {
3403         // FIXME: Queueing this event for an unpredictable time in the future seems
3404         // intrinsically racy. By the time this resize event fires, the frame might
3405         // be resized again, so we could end up with two resize events for the same size.
3406         frame().document()->enqueueWindowEvent(WTFMove(resizeEvent));
3407     }
3408
3409     if (InspectorInstrumentation::hasFrontends() && isMainFrame) {
3410         if (Page* page = frame().page()) {
3411             if (InspectorClient* inspectorClient = page->inspectorController().inspectorClient())
3412                 inspectorClient->didResizeMainFrame(&frame());
3413         }
3414     }
3415 }
3416
3417 void FrameView::willStartLiveResize()
3418 {
3419     ScrollView::willStartLiveResize();
3420     adjustTiledBackingCoverage();
3421 }
3422     
3423 void FrameView::willEndLiveResize()
3424 {
3425     ScrollView::willEndLiveResize();
3426     adjustTiledBackingCoverage();
3427 }
3428
3429 void FrameView::autoSizeIfEnabled()
3430 {
3431     if (!m_shouldAutoSize)
3432         return;
3433
3434     if (m_inAutoSize)
3435         return;
3436
3437     auto* document = frame().document();
3438     if (!document)
3439         return;
3440
3441     auto* renderView = document->renderView();
3442     if (!renderView)
3443         return;
3444
3445     auto* firstChild = renderView->firstChild();
3446     if (!firstChild)
3447         return;
3448
3449     LOG(Layout, "FrameView %p autoSizeIfEnabled", this);
3450     SetForScope<bool> changeInAutoSize(m_inAutoSize, true);
3451     if (layoutContext().subtreeLayoutRoot())
3452         layoutContext().convertSubtreeLayoutToFullLayout();
3453
3454     ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff;
3455     ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff;
3456     setVerticalScrollbarLock(false);
3457     setHorizontalScrollbarLock(false);
3458     setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true);
3459
3460     ASSERT(is<RenderElement>(*firstChild));
3461     auto& documentRenderer = downcast<RenderElement>(*firstChild);
3462     documentRenderer.mutableStyle().setMaxWidth(Length(m_autoSizeConstraint.width(), Fixed));
3463     resize(m_autoSizeConstraint.width(), m_autoSizeConstraint.height());
3464     document->updateStyleIfNeeded();
3465     document->updateLayoutIgnorePendingStylesheets();
3466     m_autoSizeContentSize = contentsSize();
3467
3468     auto finalWidth = std::max(m_autoSizeConstraint.width(), m_autoSizeContentSize.width());
3469     auto finalHeight = m_autoSizeFixedMinimumHeight ? std::max(m_autoSizeFixedMinimumHeight, m_autoSizeContentSize.height()) : m_autoSizeContentSize.height();
3470     resize(finalWidth, finalHeight);
3471     document->updateLayoutIgnorePendingStylesheets();
3472     m_didRunAutosize = true;
3473 }
3474
3475 void FrameView::setAutoSizeFixedMinimumHeight(int fixedMinimumHeight)
3476 {
3477     if (m_autoSizeFixedMinimumHeight == fixedMinimumHeight)
3478         return;
3479
3480     m_autoSizeFixedMinimumHeight = fixedMinimumHeight;
3481
3482     setNeedsLayoutAfterViewConfigurationChange();
3483 }
3484
3485 RenderElement* FrameView::viewportRenderer() const
3486 {
3487     if (m_viewportRendererType == ViewportRendererType::None)
3488         return nullptr;
3489
3490     auto* document = frame().document();
3491     if (!document)
3492         return nullptr;
3493
3494     if (m_viewportRendererType == ViewportRendererType::Document) {
3495         auto* documentElement = document->documentElement();
3496         if (!documentElement)
3497             return nullptr;
3498         return documentElement->renderer();
3499     }
3500
3501     if (m_viewportRendererType == ViewportRendererType::Body) {
3502         auto* body = document->body();
3503         if (!body)
3504             return nullptr;
3505         return body->renderer();
3506     }
3507
3508     ASSERT_NOT_REACHED();
3509     return nullptr;
3510 }
3511
3512 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
3513 {
3514     auto* viewportRenderer = this->viewportRenderer();
3515     if (!viewportRenderer)
3516         return;
3517     
3518     if (m_overflowStatusDirty) {
3519         m_horizontalOverflow = horizontalOverflow;
3520         m_verticalOverflow = verticalOverflow;
3521         m_overflowStatusDirty = false;
3522         return;
3523     }
3524     
3525     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
3526     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
3527     
3528     if (horizontalOverflowChanged || verticalOverflowChanged) {
3529         m_horizontalOverflow = horizontalOverflow;
3530         m_verticalOverflow = verticalOverflow;
3531
3532         Ref<OverflowEvent> overflowEvent = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
3533             verticalOverflowChanged, verticalOverflow);
3534         overflowEvent->setTarget(viewportRenderer->element());
3535
3536         frame().document()->enqueueOverflowEvent(WTFMove(overflowEvent));
3537     }
3538 }
3539
3540 const Pagination& FrameView::pagination() const
3541 {
3542     if (m_pagination != Pagination())
3543         return m_pagination;
3544
3545     if (frame().isMainFrame()) {
3546         if (Page* page = frame().page())
3547             return page->pagination();
3548     }
3549
3550     return m_pagination;
3551 }
3552
3553 void FrameView::setPagination(const Pagination& pagination)
3554 {
3555     if (m_pagination == pagination)
3556         return;
3557
3558     m_pagination = pagination;
3559
3560     frame().document()->styleScope().didChangeStyleSheetEnvironment();
3561 }
3562
3563 IntRect FrameView::windowClipRect() const
3564 {
3565     ASSERT(frame().view() == this);
3566
3567     if (m_cachedWindowClipRect)
3568         return *m_cachedWindowClipRect;
3569
3570     if (paintsEntireContents())
3571         return contentsToWindow(IntRect(IntPoint(), totalContentsSize()));
3572
3573     // Set our clip rect to be our contents.
3574     IntRect clipRect = contentsToWindow(visibleContentRect(LegacyIOSDocumentVisibleRect));
3575
3576     if (!frame().ownerElement())
3577         return clipRect;
3578
3579     // Take our owner element and get its clip rect.
3580     HTMLFrameOwnerElement* ownerElement = frame().ownerElement();
3581     if (FrameView* parentView = ownerElement->document().view())
3582         clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement, true));
3583     return clipRect;
3584 }
3585
3586 IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement, bool clipToLayerContents) const
3587 {
3588     // The renderer can sometimes be null when style="display:none" interacts
3589     // with external content and plugins.
3590     if (!ownerElement->renderer())
3591         return windowClipRect();
3592
3593     // If we have no layer, just return our window clip rect.
3594     const RenderLayer* enclosingLayer = ownerElement->renderer()->enclosingLayer();
3595     if (!enclosingLayer)
3596         return windowClipRect();
3597
3598     // Apply the clip from the layer.
3599     IntRect clipRect;
3600     if (clipToLayerContents)
3601         clipRect = snappedIntRect(enclosingLayer->childrenClipRect());
3602     else
3603         clipRect = snappedIntRect(enclosingLayer->selfClipRect());
3604     clipRect = contentsToWindow(clipRect); 
3605     return intersection(clipRect, windowClipRect());
3606 }
3607
3608 bool FrameView::isActive() const
3609 {
3610     Page* page = frame().page();
3611     return page && page->focusController().isActive();
3612 }
3613
3614 bool FrameView::forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const
3615 {
3616     Page* page = frame().page();
3617     return page && page->settings().forceUpdateScrollbarsOnMainThreadForPerformanceTesting();
3618 }
3619
3620 void FrameView::scrollTo(const ScrollPosition& newPosition)
3621 {
3622     IntPoint oldPosition = scrollPosition();
3623     ScrollView::scrollTo(newPosition);
3624     if (oldPosition != scrollPosition())
3625         scrollPositionChanged(oldPosition, scrollPosition());
3626
3627     didChangeScrollOffset();
3628 }
3629
3630 float FrameView::adjustScrollStepForFixedContent(float step, ScrollbarOrientation orientation, ScrollGranularity granularity)
3631 {
3632     if (granularity != ScrollByPage || orientation == HorizontalScrollbar)
3633         return step;
3634
3635     TrackedRendererListHashSet* positionedObjects = nullptr;
3636     if (RenderView* root = frame().contentRenderer()) {
3637         if (!root->hasPositionedObjects())
3638             return step;
3639         positionedObjects = root->positionedObjects();
3640     }
3641
3642     FloatRect unobscuredContentRect = this->unobscuredContentRect();
3643     float topObscuredArea = 0;
3644     float bottomObscuredArea = 0;
3645     for (const auto& positionedObject : *positionedObjects) {
3646         const RenderStyle& style = positionedObject->style();
3647         if (style.position() != PositionType::Fixed || style.visibility() == Visibility::Hidden || !style.opacity())
3648             continue;
3649
3650         FloatQuad contentQuad = positionedObject->absoluteContentQuad();
3651         if (!contentQuad.isRectilinear())
3652             continue;
3653
3654         FloatRect contentBoundingBox = contentQuad.boundingBox();
3655         FloatRect fixedRectInView = intersection(unobscuredContentRect, contentBoundingBox);
3656
3657         if (fixedRectInView.width() < unobscuredContentRect.width())
3658             continue;
3659
3660         if (fixedRectInView.y() == unobscuredContentRect.y())
3661             topObscuredArea = std::max(topObscuredArea, fixedRectInView.height());
3662         else if (fixedRectInView.maxY() == unobscuredContentRect.maxY())
3663             bottomObscuredArea = std::max(bottomObscuredArea, fixedRectInView.height());
3664     }
3665
3666     return Scrollbar::pageStep(unobscuredContentRect.height(), unobscuredContentRect.height() - topObscuredArea - bottomObscuredArea);
3667 }
3668
3669 void FrameView::invalidateScrollbarRect(Scrollbar& scrollbar, const IntRect& rect)
3670 {
3671     // Add in our offset within the FrameView.
3672     IntRect dirtyRect = rect;
3673     dirtyRect.moveBy(scrollbar.location());
3674     invalidateRect(dirtyRect);
3675 }
3676
3677 float FrameView::visibleContentScaleFactor() const
3678 {
3679     if (!frame().isMainFrame() || !frame().settings().delegatesPageScaling())
3680         return 1;
3681
3682     Page* page = frame().page();
3683     if (!page)
3684         return 1;
3685
3686     return page->pageScaleFactor();
3687 }
3688
3689 void FrameView::setVisibleScrollerThumbRect(const IntRect& scrollerThumb)
3690 {
3691     if (!frame().isMainFrame())
3692         return;
3693
3694     if (Page* page = frame().page())
3695         page->chrome().client().notifyScrollerThumbIsVisibleInRect(scrollerThumb);
3696 }
3697
3698 ScrollableArea* FrameView::enclosingScrollableArea() const
3699 {
3700     // FIXME: Walk up the frame tree and look for a scrollable parent frame or RenderLayer.
3701     return nullptr;
3702 }
3703
3704 IntRect FrameView::scrollableAreaBoundingBox(bool*) const
3705 {
3706     RenderWidget* ownerRenderer = frame().ownerRenderer();
3707     if (!ownerRenderer)
3708         return frameRect();
3709
3710     return ownerRenderer->absoluteContentQuad().enclosingBoundingBox();
3711 }
3712
3713 bool FrameView::isScrollable(Scrollability definitionOfScrollable)
3714 {
3715     // Check for:
3716     // 1) If there an actual overflow.
3717     // 2) display:none or visibility:hidden set to self or inherited.
3718     // 3) overflow{-x,-y}: hidden;
3719     // 4) scrolling: no;
3720     if (!didFirstLayout())
3721         return false;
3722
3723     bool requiresActualOverflowToBeConsideredScrollable = !frame().isMainFrame() || definitionOfScrollable != Scrollability::ScrollableOrRubberbandable;
3724 #if !ENABLE(RUBBER_BANDING)
3725     requiresActualOverflowToBeConsideredScrollable = true;
3726 #endif
3727
3728     // Covers #1
3729     if (requiresActualOverflowToBeConsideredScrollable) {
3730         IntSize totalContentsSize = this->totalContentsSize();
3731         IntSize visibleContentSize = visibleContentRect(LegacyIOSDocumentVisibleRect).size();
3732         if (totalContentsSize.height() <= visibleContentSize.height() && totalContentsSize.width() <= visibleContentSize.width())
3733             return false;
3734     }
3735
3736     // Covers #2.
3737     HTMLFrameOwnerElement* owner = frame().ownerElement();
3738     if (owner && (!owner->renderer() || !owner->renderer()->visibleToHitTesting()))
3739         return false;
3740
3741     // Cover #3 and #4.
3742     ScrollbarMode horizontalMode;
3743     ScrollbarMode verticalMode;
3744     calculateScrollbarModesForLayout(horizontalMode, verticalMode, RulesFromWebContentOnly);
3745     if (horizontalMode == ScrollbarAlwaysOff && verticalMode == ScrollbarAlwaysOff)
3746         return false;
3747
3748     return true;
3749 }
3750
3751 bool FrameView::isScrollableOrRubberbandable()
3752 {
3753     return isScrollable(Scrollability::ScrollableOrRubberbandable);
3754 }
3755
3756 bool FrameView::hasScrollableOrRubberbandableAncestor()
3757 {
3758     if (frame().isMainFrame())
3759         return isScrollableOrRubberbandable();
3760
3761     for (FrameView* parent = this->parentFrameView(); parent; parent = parent->parentFrameView()) {
3762         Scrollability frameScrollability = parent->frame().isMainFrame() ? Scrollability::ScrollableOrRubberbandable : Scrollability::Scrollable;
3763         if (parent->isScrollable(frameScrollability))
3764             return true;
3765     }
3766
3767     return false;
3768 }
3769
3770 void FrameView::updateScrollableAreaSet()
3771 {
3772     // That ensures that only inner frames are cached.
3773     FrameView* parentFrameView = this->parentFrameView();
3774     if (!parentFrameView)
3775         return;
3776
3777     if (!isScrollable()) {
3778         parentFrameView->removeScrollableArea(this);
3779         return;
3780     }
3781
3782     parentFrameView->addScrollableArea(this);
3783 }
3784
3785 bool FrameView::shouldSuspendScrollAnimations() const
3786 {
3787     return frame().loader().state() != FrameStateComplete;
3788 }
3789
3790 void FrameView::scrollbarStyleChanged(ScrollbarStyle newStyle, bool forceUpdate)
3791 {
3792     if (!frame().isMainFrame())
3793         return;
3794
3795     if (Page* page = frame().page())
3796         page->chrome().client().recommendedScrollbarStyleDidChange(newStyle);
3797
3798     ScrollView::scrollbarStyleChanged(newStyle, forceUpdate);
3799 }
3800
3801 void FrameView::notifyPageThatContentAreaWillPaint() const
3802 {
3803     Page* page = frame().page();
3804     if (!page)
3805         return;
3806
3807     contentAreaWillPaint();
3808
3809     if (!m_scrollableAreas)
3810         return;
3811
3812     for (auto& scrollableArea : *m_scrollableAreas)
3813         scrollableArea->contentAreaWillPaint();
3814 }
3815
3816 bool FrameView::scrollAnimatorEnabled() const
3817 {
3818 #if ENABLE(SMOOTH_SCROLLING)
3819     if (Page* page = frame().page())
3820         return page->settings().scrollAnimatorEnabled();
3821 #endif
3822
3823     return false;
3824 }
3825
3826 void FrameView::updateScrollCorner()
3827 {
3828     RenderElement* renderer = nullptr;
3829     std::unique_ptr<RenderStyle> cornerStyle;
3830     IntRect cornerRect = scrollCornerRect();
3831     
3832     if (!cornerRect.isEmpty()) {
3833         // Try the <body> element first as a scroll corner source.
3834         Document* doc = frame().document();
3835         Element* body = doc ? doc->bodyOrFrameset() : nullptr;
3836         if (body && body->renderer()) {
3837             renderer = body->renderer();
3838             cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(PseudoId::ScrollbarCorner), &renderer->style());
3839         }
3840         
3841         if (!cornerStyle) {
3842             // If the <body> didn't have a custom style, then the root element might.
3843             Element* docElement = doc ? doc->documentElement() : nullptr;
3844             if (docElement && docElement->renderer()) {
3845                 renderer = docElement->renderer();
3846                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(PseudoId::ScrollbarCorner), &renderer->style());
3847             }
3848         }
3849         
3850         if (!cornerStyle) {
3851             // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
3852             if (RenderWidget* renderer = frame().ownerRenderer())
3853                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(PseudoId::ScrollbarCorner), &renderer->style());
3854         }
3855     }
3856
3857     if (!cornerStyle)
3858         m_scrollCorner = nullptr;
3859     else {
3860         if (!m_scrollCorner) {
3861             m_scrollCorner = createRenderer<RenderScrollbarPart>(renderer->document(), WTFMove(*cornerStyle));
3862             m_scrollCorner->initializeStyle();
3863         } else
3864             m_scrollCorner->setStyle(WTFMove(*cornerStyle));
3865         invalidateScrollCorner(cornerRect);
3866     }
3867 }
3868
3869 void FrameView::paintScrollCorner(GraphicsContext& context, const IntRect& cornerRect)
3870 {
3871     if (context.invalidatingControlTints()) {
3872         updateScrollCorner();
3873         return;
3874     }
3875
3876     if (m_scrollCorner) {
3877         if (frame().isMainFrame())
3878             context.fillRect(cornerRect, baseBackgroundColor());
3879         m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect);
3880         return;
3881     }
3882
3883 #if PLATFORM(MAC)
3884     // Keep this in sync with ScrollAnimatorMac's effectiveAppearanceForScrollerImp:.
3885     LocalDefaultSystemAppearance localAppearance(useDarkAppearanceForScrollbars());
3886 #endif
3887
3888     ScrollView::paintScrollCorner(context, cornerRect);
3889 }
3890
3891 void FrameView::paintScrollbar(GraphicsContext& context, Scrollbar& bar, const IntRect& rect)
3892 {
3893     if (bar.isCustomScrollbar() && frame().isMainFrame()) {
3894         IntRect toFill = bar.frameRect();
3895         toFill.intersect(rect);
3896         context.fillRect(toFill, baseBackgroundColor());
3897     }
3898
3899     ScrollView::paintScrollbar(context, bar, rect);
3900 }
3901
3902 Color FrameView::documentBackgroundColor() const
3903 {
3904     // <https://bugs.webkit.org/show_bug.cgi?id=59540> We blend the background color of
3905     // the document and the body against the base background color of the frame view.
3906     // Background images are unfortunately impractical to include.
3907
3908     // Return invalid Color objects whenever there is insufficient information.
3909     if (!frame().document())
3910         return Color();
3911
3912     auto* htmlElement = frame().document()->documentElement();
3913     auto* bodyElement = frame().document()->bodyOrFrameset();
3914
3915     // Start with invalid colors.
3916     Color htmlBackgroundColor;
3917     Color bodyBackgroundColor;
3918     if (htmlElement && htmlElement->renderer())
3919         htmlBackgroundColor = htmlElement->renderer()->style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
3920     if (bodyElement && bodyElement->renderer())
3921         bodyBackgroundColor = bodyElement->renderer()->style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
3922
3923     if (!bodyBackgroundColor.isValid()) {
3924         if (!htmlBackgroundColor.isValid())
3925             return Color();
3926         return baseBackgroundColor().blend(htmlBackgroundColor);
3927     }
3928
3929     if (!htmlBackgroundColor.isValid())
3930         return baseBackgroundColor().blend(bodyBackgroundColor);
3931
3932     // We take the aggregate of the base background color
3933     // the <html> background color, and the <body>
3934     // background color to find the document color. The
3935     // addition of the base background color is not
3936     // technically part of the document background, but it
3937     // otherwise poses problems when the aggregate is not
3938     // fully opaque.
3939     return baseBackgroundColor().blend(htmlBackgroundColor).blend(bodyBackgroundColor);
3940 }
3941
3942 bool FrameView::hasCustomScrollbars() const
3943 {
3944     for (auto& widget : children()) {
3945         if (is<FrameView>(widget)) {
3946             if (downcast<FrameView>(widget.get()).hasCustomScrollbars())
3947                 return true;
3948         } else if (is<Scrollbar>(widget)) {
3949             if (downcast<Scrollbar>(widget.get()).isCustomScrollbar())
3950                 return true;
3951         }
3952     }
3953     return false;
3954 }
3955
3956 FrameView* FrameView::parentFrameView() const
3957 {
3958     if (!parent())
3959         return nullptr;
3960     auto* parentFrame = frame().tree().parent();
3961     if (!parentFrame)
3962         return nullptr;
3963     return parentFrame->view();
3964 }
3965
3966 bool FrameView::isInChildFrameWithFrameFlattening() const
3967 {
3968     if (!frameFlatteningEnabled())
3969         return false;
3970
3971     if (!parent())
3972         return false;
3973
3974     HTMLFrameOwnerElement* ownerElement = frame().ownerElement();
3975     if (!ownerElement)
3976         return false;
3977
3978     if (!ownerElement->renderWidget())
3979         return false;
3980
3981     // Frame flattening applies when the owner element is either in a frameset or
3982     // an iframe with flattening parameters.
3983     if (is<HTMLIFrameElement>(*ownerElement))
3984         return downcast<RenderIFrame>(*ownerElement->renderWidget()).flattenFrame();
3985
3986     if (is<HTMLFrameElement>(*ownerElement))
3987         return true;
3988
3989     return false;
3990 }
3991
3992 void FrameView::updateControlTints()
3993 {
3994     // This is called when control tints are changed from aqua/graphite to clear and vice versa.
3995     // We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
3996     // This is only done if the theme supports control tinting. It's up to the theme and platform
3997     // to define when controls get the tint and to call this function when that changes.
3998     
3999     // Optimize the common case where we bring a window to the front while it's still empty.
4000     if (frame().document()->url().isEmpty())
4001         return;
4002
4003     // As noted above, this is a "fake" paint, so we should pause counting relevant repainted objects.
4004     Page* page = frame().page();
4005     bool isCurrentlyCountingRelevantRepaintedObject = false;
4006     if (page) {
4007         isCurrentlyCountingRelevantRepaintedObject = page->isCountingRelevantRepaintedObjects();
4008         page->setIsCountingRelevantRepaintedObjects(false);
4009     }
4010
4011     RenderView* renderView = this->renderView();
4012     if ((renderView && renderView->theme().supportsControlTints()) || hasCustomScrollbars())
4013         invalidateControlTints();
4014
4015     if (page)
4016         page->setIsCountingRelevantRepaintedObjects(isCurrentlyCountingRelevantRepaintedObject);
4017 }
4018
4019 void FrameView::traverseForPaintInvalidation(GraphicsContext::PaintInvalidationReasons paintInvalidationReasons)
4020 {
4021     if (needsLayout())
4022         layoutContext().layout();
4023
4024     GraphicsContext context(paintInvalidationReasons);
4025     if (platformWidget()) {
4026         // FIXME: consult paintsEntireContents().
4027         paintContents(context, visibleContentRect(LegacyIOSDocumentVisibleRect));
4028     } else
4029         paint(context, frameRect());
4030 }
4031
4032 bool FrameView::wasScrolledByUser() const
4033 {
4034     return m_wasScrolledByUser;
4035 }
4036
4037 void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
4038 {
4039     LOG(Scrolling, "FrameView::setWasScrolledByUser at %d", wasScrolledByUser);
4040
4041     m_shouldScrollToFocusedElement = false;
4042     m_delayedScrollToFocusedElementTimer.stop();
4043     if (currentScrollType() == ScrollType::Programmatic)
4044         return;
4045     m_maintainScrollPositionAnchor = nullptr;
4046     if (m_wasScrolledByUser == wasScrolledByUser)
4047         return;
4048     m_wasScrolledByUser = wasScrolledByUser;
4049     if (frame().isMainFrame())
4050         updateLayerFlushThrottling();
4051     adjustTiledBackingCoverage();
4052 }
4053
4054 void FrameView::willPaintContents(GraphicsContext& context, const IntRect&, PaintingState& paintingState)
4055 {
4056     Document* document = frame().document();
4057
4058     if (!context.paintingDisabled())
4059         InspectorInstrumentation::willPaint(*renderView());
4060
4061     paintingState.isTopLevelPainter = !sCurrentPaintTimeStamp;
4062
4063     if (paintingState.isTopLevelPainter)
4064         sCurrentPaintTimeStamp = MonotonicTime::now();
4065
4066     paintingState.paintBehavior = m_paintBehavior;
4067     
4068     if (FrameView* parentView = parentFrameView()) {
4069         if (parentView->paintBehavior() & PaintBehavior::FlattenCompositingLayers)
4070             m_paintBehavior.add(PaintBehavior::FlattenCompositingLayers);
4071         
4072         if (parentView->paintBehavior() & PaintBehavior::Snapshotting)
4073             m_paintBehavior.add(PaintBehavior::Snapshotting);
4074         
4075         if (parentView->paintBehavior() & PaintBehavior::TileFirstPaint)
4076             m_paintBehavior.add(PaintBehavior::TileFirstPaint);
4077     }
4078
4079     if (document->printing()) {
4080         m_paintBehavior.add(PaintBehavior::FlattenCompositingLayers);
4081         m_paintBehavior.add(PaintBehavior::Snapshotting);
4082     }
4083
4084     paintingState.isFlatteningPaintOfRootFrame = (m_paintBehavior & PaintBehavior::FlattenCompositingLayers) && !frame().ownerElement();
4085     if (paintingState.isFlatteningPaintOfRootFrame)
4086         notifyWidgetsInAllFrames(WillPaintFlattened);
4087
4088     ASSERT(!m_isPainting);
4089     m_isPainting = true;
4090 }
4091
4092 void FrameView::didPaintContents(GraphicsContext& context, const IntRect& dirtyRect, PaintingState& paintingState)
4093 {
4094     m_isPainting = false;
4095
4096     if (paintingState.isFlatteningPaintOfRootFrame)
4097         notifyWidgetsInAllFrames(DidPaintFlattened);
4098
4099     m_paintBehavior = paintingState.paintBehavior;
4100     m_lastPaintTime = MonotonicTime::now();
4101
4102     // Regions may have changed as a result of the visibility/z-index of element changing.
4103     frame().document()->updateZOrderDependentRegions();
4104
4105     if (paintingState.isTopLevelPainter)
4106         sCurrentPaintTimeStamp = MonotonicTime();
4107
4108     if (!context.paintingDisabled()) {
4109         InspectorInstrumentation::didPaint(*renderView(), dirtyRect);
4110         // FIXME: should probably not fire milestones for snapshot painting. https://bugs.webkit.org/show_bug.cgi?id=117623
4111         firePaintRelatedMilestonesIfNeeded();
4112     }
4113 }
4114
4115 void FrameView::paintContents(GraphicsContext& context, const IntRect& dirtyRect, SecurityOriginPaintPolicy securityOriginPaintPolicy)
4116 {
4117 #ifndef NDEBUG
4118     bool fillWithWarningColor;
4119     if (frame().document()->printing())
4120         fillWithWarningColor = false; // Printing, don't fill with red (can't remember why).
4121     else if (frame().ownerElement())
4122         fillWithWarningColor = false; // Subframe, don't fill with red.
4123     else if (isTransparent())
4124         fillWithWarningColor = false; // Transparent, don't fill with red.
4125     else if (m_paintBehavior & PaintBehavior::SelectionOnly)
4126         fillWithWarningColor = false; // Selections are transparent, don't fill with red.
4127     else if (m_nodeToDraw)
4128         fillWithWarningColor = false; // Element images are transparent, don't fill with red.
4129     else
4130         fillWithWarningColor = true;
4131     
4132     if (fillWithWarningColor)
4133         context.fillRect(dirtyRect, Color(255, 64, 255));
4134 #endif
4135
4136     RenderView* renderView = this->renderView();
4137     if (!renderView) {
4138         LOG_ERROR("called FrameView::paint with nil renderer");
4139         return;
4140     }
4141
4142     if (!layoutContext().inPaintableState())
4143         return;
4144
4145     ASSERT(!needsLayout());
4146     if (needsLayout()) {
4147         RELEASE_LOG_IF_ALLOWED("FrameView::paintContents() - not painting because render tree needs layout (is main frame %d)", frame().isMainFrame());
4148         return;
4149     }
4150
4151     PaintingState paintingState;
4152     willPaintContents(context, dirtyRect, paintingState);
4153
4154     // m_nodeToDraw is used to draw only one element (and its descendants)
4155     RenderObject* renderer = m_nodeToDraw ? m_nodeToDraw->renderer() : nullptr;
4156     RenderLayer* rootLayer = renderView->layer();
4157
4158 #ifndef NDEBUG
4159     RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&rootLayer->renderer());
4160 #endif
4161
4162     // To work around http://webkit.org/b/135106, ensure that the paint root isn't an inline with culled line boxes.
4163     // FIXME: This can cause additional content to be included in the snapshot, so remove this once that bug is fixed.
4164     while (is<RenderInline>(renderer) && !downcast<RenderInline>(*renderer).firstLineBox())
4165         renderer = renderer->parent();
4166
4167     rootLayer->paint(context, dirtyRect, LayoutSize(), m_paintBehavior, renderer, { }, securityOriginPaintPolicy == SecurityOriginPaintPolicy::AnyOrigin ? RenderLayer::SecurityOriginPaintPolicy::AnyOrigin : RenderLayer::SecurityOriginPaintPolicy::AccessibleOriginOnly);
4168     if (rootLayer->containsDirtyOverlayScrollbars())
4169         rootLayer->paintOverlayScrollbars(context, dirtyRect, m_paintBehavior, renderer);
4170
4171     didPaintContents(context, dirtyRect, paintingState);
4172 }
4173
4174 void FrameView::setPaintBehavior(OptionSet<PaintBehavior> behavior)
4175 {
4176     m_paintBehavior = behavior;
4177 }
4178
4179 OptionSet<PaintBehavior> FrameView::paintBehavior() const
4180 {
4181     return m_paintBehavior;
4182 }
4183
4184 bool FrameView::isPainting() const
4185 {
4186     return m_isPainting;
4187 }
4188
4189 // FIXME: change this to use the subtreePaint terminology.
4190 void FrameView::setNodeToDraw(Node* node)
4191 {
4192     m_nodeToDraw = node;
4193 }
4194
4195 void FrameView::paintContentsForSnapshot(GraphicsContext& context, const IntRect& imageRect, SelectionInSnapshot shouldPaintSelection, CoordinateSpaceForSnapshot coordinateSpace)
4196 {
4197     updateLayoutAndStyleIfNeededRecursive();
4198
4199     // Cache paint behavior and set a new behavior appropriate for snapshots.
4200     auto oldBehavior = paintBehavior();
4201     setPaintBehavior(oldBehavior | PaintBehavior::FlattenCompositingLayers | PaintBehavior::Snapshotting);
4202
4203     // If the snapshot should exclude selection, then we'll clear the current selection
4204     // in the render tree only. This will allow us to restore the selection from the DOM
4205     // after we paint the snapshot.
4206     if (shouldPaintSelection == ExcludeSelection) {
4207         for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
4208             if (auto* renderView = frame->contentRenderer())
4209                 renderView->selection().clear();
4210         }
4211     }
4212
4213     if (coordinateSpace == DocumentCoordinates)
4214         paintContents(context, imageRect);
4215     else {
4216         // A snapshot in ViewCoordinates will include a scrollbar, and the snapshot will contain
4217         // whatever content the document is currently scrolled to.
4218         paint(context, imageRect);
4219     }
4220
4221     // Restore selection.
4222     if (shouldPaintSelection == ExcludeSelection) {
4223         for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr()))
4224             frame->selection().updateAppearance();
4225     }
4226
4227     // Restore cached paint behavior.
4228     setPaintBehavior(oldBehavior);
4229 }
4230
4231 void FrameView::paintOverhangAreas(GraphicsContext& context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
4232 {
4233     if (context.paintingDisabled())
4234         return;
4235
4236     if (frame().document()->printing())
4237         return;
4238
4239     ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
4240 }
4241
4242 void FrameView::updateLayoutAndStyleIfNeededRecursive()
4243 {
4244     // Style updating, render tree creation, and layout needs to be done multiple times
4245     // for more than one reason. But one reason is that when an <object> element determines
4246     // what it needs to load a subframe, a second pass is needed. That requires update
4247     // passes equal to the number of levels of DOM nesting. That is why this number is large.
4248     // There are test cases where we have roughly 10 levels of DOM nesting, so this needs to
4249     // be greater than that. We have a limit to avoid the possibility of an infinite loop.
4250     // Typical calls will run the loop 2 times (once to do work, once to detect no further work
4251     // is needed).
4252     // FIXME: We should find an approach that does not require a loop at all.
4253     const unsigned maxUpdatePasses = 25;
4254
4255     // Style updates can trigger script, which can cause this FrameView to be destroyed.
4256     Ref<FrameView> protectedThis(*this);
4257
4258     AnimationUpdateBlock animationUpdateBlock(&frame().animation());
4259
4260     using DescendantsDeque = Deque<Ref<FrameView>, 16>;
4261     auto nextRenderedDescendant = [this] (DescendantsDeque& descendantsDeque) -> RefPtr<FrameView> {
4262         if (descendantsDeque.isEmpty())
4263             descendantsDeque.append(*this);
4264         else {
4265             // Append renderered children after processing the parent, in case the processing
4266             // affects the set of rendered children.
4267             auto previousView = descendantsDeque.takeFirst();
4268             for (auto* frame = previousView->frame().tree().firstRenderedChild(); frame; frame = frame->tree().nextRenderedSibling()) {
4269