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