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