Web Automation: elements larger than the viewport have incorrect in-view center point
[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)
3004 #if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
3005     static const auto cssValueControlBackground = CSSValueAppleSystemControlBackground;
3006 #else
3007     static const auto cssValueControlBackground = CSSValueWindow;
3008 #endif
3009     Color baseBackgroundColor = backgroundColor.valueOr(RenderTheme::singleton().systemColor(cssValueControlBackground, styleColorOptions()));
3010 #else
3011     Color baseBackgroundColor = backgroundColor.valueOr(Color::white);
3012 #endif
3013
3014     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
3015         if (FrameView* view = frame->view()) {
3016             view->setTransparent(!baseBackgroundColor.isVisible());
3017             view->setBaseBackgroundColor(baseBackgroundColor);
3018             if (view->needsLayout())
3019                 view->layoutContext().scheduleLayout();
3020         }
3021     }
3022 }
3023
3024 bool FrameView::hasExtendedBackgroundRectForPainting() const
3025 {
3026     TiledBacking* tiledBacking = this->tiledBacking();
3027     if (!tiledBacking)
3028         return false;
3029
3030     return tiledBacking->hasMargins();
3031 }
3032
3033 void FrameView::updateExtendBackgroundIfNecessary()
3034 {
3035     ExtendedBackgroundMode mode = calculateExtendedBackgroundMode();
3036     if (mode == ExtendedBackgroundModeNone)
3037         return;
3038
3039     updateTilesForExtendedBackgroundMode(mode);
3040 }
3041
3042 FrameView::ExtendedBackgroundMode FrameView::calculateExtendedBackgroundMode() const
3043 {
3044 #if PLATFORM(IOS_FAMILY)
3045     // <rdar://problem/16201373>
3046     return ExtendedBackgroundModeNone;
3047 #else
3048     if (!frame().settings().backgroundShouldExtendBeyondPage())
3049         return ExtendedBackgroundModeNone;
3050
3051     // Just because Settings::backgroundShouldExtendBeyondPage() is true does not necessarily mean
3052     // that the background rect needs to be extended for painting. Simple backgrounds can be extended
3053     // just with RenderLayerCompositor's rootExtendedBackgroundColor. More complicated backgrounds,
3054     // such as images, require extending the background rect to continue painting into the extended
3055     // region. This function finds out if it is necessary to extend the background rect for painting.
3056
3057     if (!frame().isMainFrame())
3058         return ExtendedBackgroundModeNone;
3059
3060     Document* document = frame().document();
3061     if (!document)
3062         return ExtendedBackgroundModeNone;
3063
3064     if (!renderView())
3065         return ExtendedBackgroundModeNone;
3066     
3067     auto* rootBackgroundRenderer = renderView()->rendererForRootBackground();
3068     if (!rootBackgroundRenderer)
3069         return ExtendedBackgroundModeNone;
3070
3071     if (!rootBackgroundRenderer->style().hasBackgroundImage())
3072         return ExtendedBackgroundModeNone;
3073
3074     ExtendedBackgroundMode mode = ExtendedBackgroundModeNone;
3075     if (rootBackgroundRenderer->style().backgroundRepeatX() == FillRepeat::Repeat)
3076         mode |= ExtendedBackgroundModeHorizontal;
3077     if (rootBackgroundRenderer->style().backgroundRepeatY() == FillRepeat::Repeat)
3078         mode |= ExtendedBackgroundModeVertical;
3079
3080     return mode;
3081 #endif
3082 }
3083
3084 void FrameView::updateTilesForExtendedBackgroundMode(ExtendedBackgroundMode mode)
3085 {
3086     RenderView* renderView = this->renderView();
3087     if (!renderView)
3088         return;
3089
3090     RenderLayerBacking* backing = renderView->layer()->backing();
3091     if (!backing)
3092         return;
3093
3094     TiledBacking* tiledBacking = backing->tiledBacking();
3095     if (!tiledBacking)
3096         return;
3097
3098     ExtendedBackgroundMode existingMode = ExtendedBackgroundModeNone;
3099     if (tiledBacking->hasVerticalMargins())
3100         existingMode |= ExtendedBackgroundModeVertical;
3101     if (tiledBacking->hasHorizontalMargins())
3102         existingMode |= ExtendedBackgroundModeHorizontal;
3103
3104     if (existingMode == mode)
3105         return;
3106
3107     backing->setTiledBackingHasMargins(mode & ExtendedBackgroundModeHorizontal, mode & ExtendedBackgroundModeVertical);
3108 }
3109
3110 IntRect FrameView::extendedBackgroundRectForPainting() const
3111 {
3112     TiledBacking* tiledBacking = this->tiledBacking();
3113     if (!tiledBacking)
3114         return IntRect();
3115     
3116     RenderView* renderView = this->renderView();
3117     if (!renderView)
3118         return IntRect();
3119     
3120     LayoutRect extendedRect = renderView->unextendedBackgroundRect();
3121     if (!tiledBacking->hasMargins())
3122         return snappedIntRect(extendedRect);
3123     
3124     extendedRect.moveBy(LayoutPoint(-tiledBacking->leftMarginWidth(), -tiledBacking->topMarginHeight()));
3125     extendedRect.expand(LayoutSize(tiledBacking->leftMarginWidth() + tiledBacking->rightMarginWidth(), tiledBacking->topMarginHeight() + tiledBacking->bottomMarginHeight()));
3126     return snappedIntRect(extendedRect);
3127 }
3128
3129 bool FrameView::shouldUpdateWhileOffscreen() const
3130 {
3131     return m_shouldUpdateWhileOffscreen;
3132 }
3133
3134 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
3135 {
3136     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
3137 }
3138
3139 bool FrameView::shouldUpdate() const
3140 {
3141     if (isOffscreen() && !shouldUpdateWhileOffscreen())
3142         return false;
3143     return true;
3144 }
3145
3146 bool FrameView::safeToPropagateScrollToParent() const
3147 {
3148     auto* document = frame().document();
3149     if (!document)
3150         return false;
3151
3152     auto* parentFrame = frame().tree().parent();
3153     if (!parentFrame)
3154         return false;
3155
3156     auto* parentDocument = parentFrame->document();
3157     if (!parentDocument)
3158         return false;
3159
3160     return document->securityOrigin().canAccess(parentDocument->securityOrigin());
3161 }
3162
3163 void FrameView::scrollToAnchor()
3164 {
3165     RefPtr<ContainerNode> anchorNode = m_maintainScrollPositionAnchor;
3166
3167     LOG_WITH_STREAM(Scrolling, stream << "FrameView::scrollToAnchor() " << anchorNode.get());
3168
3169     if (!anchorNode)
3170         return;
3171
3172     if (!anchorNode->renderer())
3173         return;
3174     m_shouldScrollToFocusedElement = false;
3175     m_delayedScrollToFocusedElementTimer.stop();
3176
3177     LayoutRect rect;
3178     bool insideFixed = false;
3179     if (anchorNode != frame().document() && anchorNode->renderer())
3180         rect = anchorNode->renderer()->absoluteAnchorRect(&insideFixed);
3181
3182     LOG_WITH_STREAM(Scrolling, stream << " anchor node rect " << rect);
3183
3184     // Scroll nested layers and frames to reveal the anchor.
3185     // Align to the top and to the closest side (this matches other browsers).
3186     if (anchorNode->renderer()->style().isHorizontalWritingMode())
3187         anchorNode->renderer()->scrollRectToVisible(rect, insideFixed, { SelectionRevealMode::Reveal, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways, ShouldAllowCrossOriginScrolling::No });
3188     else if (anchorNode->renderer()->style().isFlippedBlocksWritingMode())
3189         anchorNode->renderer()->scrollRectToVisible(rect, insideFixed, { SelectionRevealMode::Reveal, ScrollAlignment::alignRightAlways, ScrollAlignment::alignToEdgeIfNeeded, ShouldAllowCrossOriginScrolling::No });
3190     else
3191         anchorNode->renderer()->scrollRectToVisible(rect, insideFixed, { SelectionRevealMode::Reveal, ScrollAlignment::alignLeftAlways, ScrollAlignment::alignToEdgeIfNeeded, ShouldAllowCrossOriginScrolling::No });
3192
3193     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
3194         cache->handleScrolledToAnchor(anchorNode.get());
3195
3196     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
3197     LOG_WITH_STREAM(Scrolling, stream << " restoring anchor node to " << anchorNode.get());
3198     m_maintainScrollPositionAnchor = anchorNode;
3199     m_shouldScrollToFocusedElement = false;
3200     m_delayedScrollToFocusedElementTimer.stop();
3201 }
3202
3203 void FrameView::updateEmbeddedObject(RenderEmbeddedObject& embeddedObject)
3204 {
3205     // No need to update if it's already crashed or known to be missing.
3206     if (embeddedObject.isPluginUnavailable())
3207         return;
3208
3209     HTMLFrameOwnerElement& element = embeddedObject.frameOwnerElement();
3210
3211     if (embeddedObject.isSnapshottedPlugIn()) {
3212         if (is<HTMLObjectElement>(element) || is<HTMLEmbedElement>(element)) {
3213             HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
3214             pluginElement.checkSnapshotStatus();
3215         }
3216         return;
3217     }
3218
3219     auto weakRenderer = makeWeakPtr(embeddedObject);
3220
3221     // FIXME: This could turn into a real virtual dispatch if we defined
3222     // updateWidget(PluginCreationOption) on HTMLElement.
3223     if (is<HTMLPlugInImageElement>(element)) {
3224         HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
3225         if (pluginElement.needsCheckForSizeChange()) {
3226             pluginElement.checkSnapshotStatus();
3227             return;
3228         }
3229         if (pluginElement.needsWidgetUpdate())
3230             pluginElement.updateWidget(CreatePlugins::Yes);
3231     } else
3232         ASSERT_NOT_REACHED();
3233
3234     // It's possible the renderer was destroyed below updateWidget() since loading a plugin may execute arbitrary JavaScript.
3235     if (!weakRenderer)
3236         return;
3237
3238     auto ignoreWidgetState = embeddedObject.updateWidgetPosition();
3239     UNUSED_PARAM(ignoreWidgetState);
3240 }
3241
3242 bool FrameView::updateEmbeddedObjects()
3243 {
3244     if (layoutContext().isLayoutNested() || !m_embeddedObjectsToUpdate || m_embeddedObjectsToUpdate->isEmpty())
3245         return true;
3246
3247     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
3248
3249     // Insert a marker for where we should stop.
3250     ASSERT(!m_embeddedObjectsToUpdate->contains(nullptr));
3251     m_embeddedObjectsToUpdate->add(nullptr);
3252
3253     while (!m_embeddedObjectsToUpdate->isEmpty()) {
3254         RenderEmbeddedObject* embeddedObject = m_embeddedObjectsToUpdate->takeFirst();
3255         if (!embeddedObject)
3256             break;
3257         updateEmbeddedObject(*embeddedObject);
3258     }
3259
3260     return m_embeddedObjectsToUpdate->isEmpty();
3261 }
3262
3263 void FrameView::updateEmbeddedObjectsTimerFired()
3264 {
3265     RefPtr<FrameView> protectedThis(this);
3266     m_updateEmbeddedObjectsTimer.stop();
3267     for (unsigned i = 0; i < maxUpdateEmbeddedObjectsIterations; i++) {
3268         if (updateEmbeddedObjects())
3269             break;
3270     }
3271 }
3272
3273 void FrameView::flushAnyPendingPostLayoutTasks()
3274 {
3275     layoutContext().flushAsynchronousTasks();
3276     if (m_updateEmbeddedObjectsTimer.isActive())
3277         updateEmbeddedObjectsTimerFired();
3278 }
3279
3280 void FrameView::queuePostLayoutCallback(Function<void()>&& callback)
3281 {
3282     m_postLayoutCallbackQueue.append(WTFMove(callback));
3283 }
3284
3285 void FrameView::flushPostLayoutTasksQueue()
3286 {
3287     if (layoutContext().isLayoutNested())
3288         return;
3289
3290     if (!m_postLayoutCallbackQueue.size())
3291         return;
3292
3293     Vector<Function<void()>> queue = WTFMove(m_postLayoutCallbackQueue);
3294     for (auto& task : queue)
3295         task();
3296 }
3297
3298 void FrameView::performPostLayoutTasks()
3299 {
3300     // FIXME: We should not run any JavaScript code in this function.
3301     LOG(Layout, "FrameView %p performPostLayoutTasks", this);
3302     updateHasReachedSignificantRenderedTextThreshold();
3303     frame().selection().updateAppearanceAfterLayout();
3304
3305     flushPostLayoutTasksQueue();
3306
3307     if (!layoutContext().isLayoutNested() && frame().document()->documentElement())
3308         fireLayoutRelatedMilestonesIfNeeded();
3309
3310 #if PLATFORM(IOS_FAMILY)
3311     // Only send layout-related delegate callbacks synchronously for the main frame to
3312     // avoid re-entering layout for the main frame while delivering a layout-related delegate
3313     // callback for a subframe.
3314     if (frame().isMainFrame()) {
3315         if (Page* page = frame().page())
3316             page->chrome().client().didLayout();
3317     }
3318 #endif
3319     
3320     // FIXME: We should consider adding DidLayout as a LayoutMilestone. That would let us merge this
3321     // with didLayout(LayoutMilestones).
3322     frame().loader().client().dispatchDidLayout();
3323
3324     updateWidgetPositions();
3325
3326 #if ENABLE(CSS_SCROLL_SNAP)
3327     updateSnapOffsets();
3328 #endif
3329     m_updateEmbeddedObjectsTimer.startOneShot(0_s);
3330
3331     if (auto* page = frame().page()) {
3332         if (auto* scrollingCoordinator = page->scrollingCoordinator())
3333             scrollingCoordinator->frameViewLayoutUpdated(*this);
3334     }
3335
3336     if (RenderView* renderView = this->renderView()) {
3337         if (renderView->usesCompositing())
3338             renderView->compositor().frameViewDidLayout();
3339     }
3340
3341     scrollToAnchor();
3342
3343     sendResizeEventIfNeeded();
3344     
3345     updateLayoutViewport();
3346     viewportContentsChanged();
3347
3348     updateScrollSnapState();
3349
3350     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
3351         cache->performDeferredCacheUpdate();
3352 }
3353
3354 IntSize FrameView::sizeForResizeEvent() const
3355 {
3356 #if PLATFORM(IOS_FAMILY)
3357     if (m_useCustomSizeForResizeEvent)
3358         return m_customSizeForResizeEvent;
3359 #endif
3360     if (useFixedLayout() && !fixedLayoutSize().isEmpty() && delegatesScrolling())
3361         return fixedLayoutSize();
3362     return visibleContentRectIncludingScrollbars().size();
3363 }
3364
3365 void FrameView::sendResizeEventIfNeeded()
3366 {
3367     if (layoutContext().isInRenderTreeLayout() || needsLayout())
3368         return;
3369
3370     RenderView* renderView = this->renderView();
3371     if (!renderView || renderView->printing())
3372         return;
3373
3374     if (frame().page() && frame().page()->chrome().client().isSVGImageChromeClient())
3375         return;
3376
3377     IntSize currentSize = sizeForResizeEvent();
3378     float currentZoomFactor = renderView->style().zoom();
3379
3380     if (currentSize == m_lastViewportSize && currentZoomFactor == m_lastZoomFactor)
3381         return;
3382
3383     m_lastViewportSize = currentSize;
3384     m_lastZoomFactor = currentZoomFactor;
3385
3386     if (!layoutContext().didFirstLayout())
3387         return;
3388
3389 #if PLATFORM(IOS_FAMILY)
3390     // Don't send the resize event if the document is loading. Some pages automatically reload
3391     // when the window is resized; Safari on iOS often resizes the window while setting up its
3392     // viewport. This obviously can cause problems.
3393     if (DocumentLoader* documentLoader = frame().loader().documentLoader()) {
3394         if (documentLoader->isLoadingInAPISense())
3395             return;
3396     }
3397 #endif
3398
3399     bool isMainFrame = frame().isMainFrame();
3400     bool canSendResizeEventSynchronously = isMainFrame && !m_shouldAutoSize;
3401
3402     LOG(Events, "FrameView %p sendResizeEventIfNeeded sending resize event, size %dx%d (canSendResizeEventSynchronously %d)", this, currentSize.width(), currentSize.height(), canSendResizeEventSynchronously);
3403
3404     Ref<Event> resizeEvent = Event::create(eventNames().resizeEvent, Event::CanBubble::No, Event::IsCancelable::No);
3405     if (canSendResizeEventSynchronously)
3406         frame().document()->dispatchWindowEvent(resizeEvent);
3407     else {
3408         // FIXME: Queueing this event for an unpredictable time in the future seems
3409         // intrinsically racy. By the time this resize event fires, the frame might
3410         // be resized again, so we could end up with two resize events for the same size.
3411         frame().document()->enqueueWindowEvent(WTFMove(resizeEvent));
3412     }
3413
3414     if (InspectorInstrumentation::hasFrontends() && isMainFrame) {
3415         if (Page* page = frame().page()) {
3416             if (InspectorClient* inspectorClient = page->inspectorController().inspectorClient())
3417                 inspectorClient->didResizeMainFrame(&frame());
3418         }
3419     }
3420 }
3421
3422 void FrameView::willStartLiveResize()
3423 {
3424     ScrollView::willStartLiveResize();
3425     adjustTiledBackingCoverage();
3426 }
3427     
3428 void FrameView::willEndLiveResize()
3429 {
3430     ScrollView::willEndLiveResize();
3431     adjustTiledBackingCoverage();
3432 }
3433
3434 void FrameView::autoSizeIfEnabled()
3435 {
3436     if (!m_shouldAutoSize)
3437         return;
3438
3439     if (m_inAutoSize)
3440         return;
3441
3442     auto* document = frame().document();
3443     if (!document)
3444         return;
3445
3446     auto* renderView = document->renderView();
3447     if (!renderView)
3448         return;
3449
3450     auto* firstChild = renderView->firstChild();
3451     if (!firstChild)
3452         return;
3453
3454     LOG(Layout, "FrameView %p autoSizeIfEnabled", this);
3455     SetForScope<bool> changeInAutoSize(m_inAutoSize, true);
3456     if (layoutContext().subtreeLayoutRoot())
3457         layoutContext().convertSubtreeLayoutToFullLayout();
3458
3459     ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff;
3460     ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff;
3461     setVerticalScrollbarLock(false);
3462     setHorizontalScrollbarLock(false);
3463     setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true);
3464
3465     ASSERT(is<RenderElement>(*firstChild));
3466     auto& documentRenderer = downcast<RenderElement>(*firstChild);
3467     documentRenderer.mutableStyle().setMaxWidth(Length(m_autoSizeConstraint.width(), Fixed));
3468     resize(m_autoSizeConstraint.width(), m_autoSizeConstraint.height());
3469     document->updateStyleIfNeeded();
3470     document->updateLayoutIgnorePendingStylesheets();
3471
3472     auto currentContentsSize = this->contentsSize();
3473     auto finalWidth = std::max(m_autoSizeConstraint.width(), currentContentsSize.width());
3474     auto finalHeight = m_autoSizeFixedMinimumHeight ? std::max(m_autoSizeFixedMinimumHeight, currentContentsSize.height()) : currentContentsSize.height();
3475     resize(finalWidth, finalHeight);
3476     document->updateLayoutIgnorePendingStylesheets();
3477     m_autoSizeContentSize = contentsSize(); 
3478     if (auto* page = frame().page())
3479         page->chrome().client().intrinsicContentsSizeChanged(m_autoSizeContentSize);
3480     m_didRunAutosize = true;
3481 }
3482
3483 void FrameView::setAutoSizeFixedMinimumHeight(int fixedMinimumHeight)
3484 {
3485     if (m_autoSizeFixedMinimumHeight == fixedMinimumHeight)
3486         return;
3487
3488     m_autoSizeFixedMinimumHeight = fixedMinimumHeight;
3489
3490     setNeedsLayoutAfterViewConfigurationChange();
3491 }
3492
3493 RenderElement* FrameView::viewportRenderer() const
3494 {
3495     if (m_viewportRendererType == ViewportRendererType::None)
3496         return nullptr;
3497
3498     auto* document = frame().document();
3499     if (!document)
3500         return nullptr;
3501
3502     if (m_viewportRendererType == ViewportRendererType::Document) {
3503         auto* documentElement = document->documentElement();
3504         if (!documentElement)
3505             return nullptr;
3506         return documentElement->renderer();
3507     }
3508
3509     if (m_viewportRendererType == ViewportRendererType::Body) {
3510         auto* body = document->body();
3511         if (!body)
3512             return nullptr;
3513         return body->renderer();
3514     }
3515
3516     ASSERT_NOT_REACHED();
3517     return nullptr;
3518 }
3519
3520 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
3521 {
3522     auto* viewportRenderer = this->viewportRenderer();
3523     if (!viewportRenderer)
3524         return;
3525     
3526     if (m_overflowStatusDirty) {
3527         m_horizontalOverflow = horizontalOverflow;
3528         m_verticalOverflow = verticalOverflow;
3529         m_overflowStatusDirty = false;
3530         return;
3531     }
3532     
3533     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
3534     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
3535     
3536     if (horizontalOverflowChanged || verticalOverflowChanged) {
3537         m_horizontalOverflow = horizontalOverflow;
3538         m_verticalOverflow = verticalOverflow;
3539
3540         Ref<OverflowEvent> overflowEvent = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
3541             verticalOverflowChanged, verticalOverflow);
3542         overflowEvent->setTarget(viewportRenderer->element());
3543
3544         frame().document()->enqueueOverflowEvent(WTFMove(overflowEvent));
3545     }
3546 }
3547
3548 const Pagination& FrameView::pagination() const
3549 {
3550     if (m_pagination != Pagination())
3551         return m_pagination;
3552
3553     if (frame().isMainFrame()) {
3554         if (Page* page = frame().page())
3555             return page->pagination();
3556     }
3557
3558     return m_pagination;
3559 }
3560
3561 void FrameView::setPagination(const Pagination& pagination)
3562 {
3563     if (m_pagination == pagination)
3564         return;
3565
3566     m_pagination = pagination;
3567
3568     frame().document()->styleScope().didChangeStyleSheetEnvironment();
3569 }
3570
3571 IntRect FrameView::windowClipRect() const
3572 {
3573     ASSERT(frame().view() == this);
3574
3575     if (m_cachedWindowClipRect)
3576         return *m_cachedWindowClipRect;
3577
3578     if (paintsEntireContents())
3579         return contentsToWindow(IntRect(IntPoint(), totalContentsSize()));
3580
3581     // Set our clip rect to be our contents.
3582     IntRect clipRect = contentsToWindow(visibleContentRect(LegacyIOSDocumentVisibleRect));
3583
3584     if (!frame().ownerElement())
3585         return clipRect;
3586
3587     // Take our owner element and get its clip rect.
3588     HTMLFrameOwnerElement* ownerElement = frame().ownerElement();
3589     if (FrameView* parentView = ownerElement->document().view())
3590         clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement, true));
3591     return clipRect;
3592 }
3593
3594 IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement, bool clipToLayerContents) const
3595 {
3596     // The renderer can sometimes be null when style="display:none" interacts
3597     // with external content and plugins.
3598     if (!ownerElement->renderer())
3599         return windowClipRect();
3600
3601     // If we have no layer, just return our window clip rect.
3602     const RenderLayer* enclosingLayer = ownerElement->renderer()->enclosingLayer();
3603     if (!enclosingLayer)
3604         return windowClipRect();
3605
3606     // Apply the clip from the layer.
3607     IntRect clipRect;
3608     if (clipToLayerContents)
3609         clipRect = snappedIntRect(enclosingLayer->childrenClipRect());
3610     else
3611         clipRect = snappedIntRect(enclosingLayer->selfClipRect());
3612     clipRect = contentsToWindow(clipRect); 
3613     return intersection(clipRect, windowClipRect());
3614 }
3615
3616 bool FrameView::isActive() const
3617 {
3618     Page* page = frame().page();
3619     return page && page->focusController().isActive();
3620 }
3621
3622 bool FrameView::forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const