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