[Settings] Remove all custom code from Settings.h/cpp
[WebKit.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 "DocumentMarkerController.h"
40 #include "EventHandler.h"
41 #include "EventNames.h"
42 #include "FloatRect.h"
43 #include "FocusController.h"
44 #include "FrameLoader.h"
45 #include "FrameLoaderClient.h"
46 #include "FrameSelection.h"
47 #include "FrameTree.h"
48 #include "GraphicsContext.h"
49 #include "HTMLBodyElement.h"
50 #include "HTMLDocument.h"
51 #include "HTMLEmbedElement.h"
52 #include "HTMLFrameElement.h"
53 #include "HTMLFrameSetElement.h"
54 #include "HTMLHtmlElement.h"
55 #include "HTMLIFrameElement.h"
56 #include "HTMLNames.h"
57 #include "HTMLObjectElement.h"
58 #include "HTMLPlugInImageElement.h"
59 #include "ImageDocument.h"
60 #include "InspectorClient.h"
61 #include "InspectorController.h"
62 #include "InspectorInstrumentation.h"
63 #include "Logging.h"
64 #include "MainFrame.h"
65 #include "MemoryCache.h"
66 #include "OverflowEvent.h"
67 #include "Page.h"
68 #include "PageCache.h"
69 #include "PageOverlayController.h"
70 #include "ProgressTracker.h"
71 #include "RenderEmbeddedObject.h"
72 #include "RenderFullScreen.h"
73 #include "RenderIFrame.h"
74 #include "RenderInline.h"
75 #include "RenderLayer.h"
76 #include "RenderLayerBacking.h"
77 #include "RenderLayerCompositor.h"
78 #include "RenderSVGRoot.h"
79 #include "RenderScrollbar.h"
80 #include "RenderScrollbarPart.h"
81 #include "RenderStyle.h"
82 #include "RenderText.h"
83 #include "RenderTheme.h"
84 #include "RenderView.h"
85 #include "RenderWidget.h"
86 #include "SVGDocument.h"
87 #include "SVGSVGElement.h"
88 #include "ScriptedAnimationController.h"
89 #include "ScrollAnimator.h"
90 #include "ScrollingCoordinator.h"
91 #include "Settings.h"
92 #include "StyleResolver.h"
93 #include "StyleScope.h"
94 #include "TextResourceDecoder.h"
95 #include "TiledBacking.h"
96 #include "WheelEventTestTrigger.h"
97 #include <wtf/text/TextStream.h>
98
99 #include <wtf/CurrentTime.h>
100 #include <wtf/MemoryPressureHandler.h>
101 #include <wtf/Ref.h>
102 #include <wtf/SetForScope.h>
103 #include <wtf/SystemTracing.h>
104
105 #if USE(COORDINATED_GRAPHICS)
106 #include "TiledBackingStore.h"
107 #endif
108
109 #if ENABLE(CSS_SCROLL_SNAP)
110 #include "AxisScrollSnapOffsets.h"
111 #endif
112
113 #if PLATFORM(IOS)
114 #include "DocumentLoader.h"
115 #include "LegacyTileCache.h"
116 #endif
117
118 namespace WebCore {
119
120 using namespace HTMLNames;
121
122 double FrameView::sCurrentPaintTimeStamp = 0.0;
123
124 // The maximum number of updateEmbeddedObjects iterations that should be done before returning.
125 static const unsigned maxUpdateEmbeddedObjectsIterations = 2;
126
127 static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLayer* layer, bool isRelayoutingSubtree, bool didFullRepaint)
128 {
129     RenderLayer::UpdateLayerPositionsFlags flags = RenderLayer::defaultFlags;
130     if (didFullRepaint) {
131         flags &= ~RenderLayer::CheckForRepaint;
132         flags |= RenderLayer::NeedsFullRepaintInBacking;
133     }
134     if (isRelayoutingSubtree && layer->enclosingPaginationLayer(RenderLayer::IncludeCompositedPaginatedLayers))
135         flags |= RenderLayer::UpdatePagination;
136     return flags;
137 }
138
139 Pagination::Mode paginationModeForRenderStyle(const RenderStyle& style)
140 {
141     EOverflow overflow = style.overflowY();
142     if (overflow != OPAGEDX && overflow != OPAGEDY)
143         return Pagination::Unpaginated;
144
145     bool isHorizontalWritingMode = style.isHorizontalWritingMode();
146     TextDirection textDirection = style.direction();
147     WritingMode writingMode = style.writingMode();
148
149     // paged-x always corresponds to LeftToRightPaginated or RightToLeftPaginated. If the WritingMode
150     // is horizontal, then we use TextDirection to choose between those options. If the WritingMode
151     // is vertical, then the direction of the verticality dictates the choice.
152     if (overflow == OPAGEDX) {
153         if ((isHorizontalWritingMode && textDirection == LTR) || writingMode == LeftToRightWritingMode)
154             return Pagination::LeftToRightPaginated;
155         return Pagination::RightToLeftPaginated;
156     }
157
158     // paged-y always corresponds to TopToBottomPaginated or BottomToTopPaginated. If the WritingMode
159     // is horizontal, then the direction of the horizontality dictates the choice. If the WritingMode
160     // is vertical, then we use TextDirection to choose between those options. 
161     if (writingMode == TopToBottomWritingMode || (!isHorizontalWritingMode && textDirection == RTL))
162         return Pagination::TopToBottomPaginated;
163     return Pagination::BottomToTopPaginated;
164 }
165
166 class SubtreeLayoutStateMaintainer {
167 public:
168     SubtreeLayoutStateMaintainer(RenderElement* subtreeLayoutRoot)
169         : m_layoutRoot(subtreeLayoutRoot)
170     {
171         if (m_layoutRoot) {
172             RenderView& view = m_layoutRoot->view();
173             view.pushLayoutState(*m_layoutRoot);
174             if (shouldDisableLayoutStateForSubtree()) {
175                 view.disableLayoutState();
176                 m_didDisableLayoutState = true;
177             }
178         }
179     }
180
181     ~SubtreeLayoutStateMaintainer()
182     {
183         if (m_layoutRoot) {
184             RenderView& view = m_layoutRoot->view();
185             view.popLayoutState(*m_layoutRoot);
186             if (m_didDisableLayoutState)
187                 view.enableLayoutState();
188         }
189     }
190
191     bool shouldDisableLayoutStateForSubtree()
192     {
193         for (auto* renderer = m_layoutRoot; renderer; renderer = renderer->container()) {
194             if (renderer->hasTransform() || renderer->hasReflection())
195                 return true;
196         }
197         return false;
198     }
199     
200 private:
201     RenderElement* m_layoutRoot { nullptr };
202     bool m_didDisableLayoutState { false };
203 };
204
205 #ifndef NDEBUG
206 class RenderTreeNeedsLayoutChecker {
207 public :
208     RenderTreeNeedsLayoutChecker(const RenderElement& layoutRoot)
209         : m_layoutRoot(layoutRoot)
210     {
211     }
212
213     ~RenderTreeNeedsLayoutChecker()
214     {
215         auto reportNeedsLayoutError = [] (const RenderObject& renderer) {
216             WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, "post-layout: dirty renderer(s)");
217             renderer.showRenderTreeForThis();
218             ASSERT_NOT_REACHED();
219         };
220
221         if (m_layoutRoot.needsLayout()) {
222             reportNeedsLayoutError(m_layoutRoot);
223             return;
224         }
225
226         for (auto* descendant = m_layoutRoot.firstChild(); descendant; descendant = descendant->nextInPreOrder(&m_layoutRoot)) {
227             if (!descendant->needsLayout())
228                 continue;
229             
230             reportNeedsLayoutError(*descendant);
231             return;
232         }
233     }
234
235 private:
236     const RenderElement& m_layoutRoot;
237 };
238 #endif
239
240 FrameView::FrameView(Frame& frame)
241     : m_frame(frame)
242     , m_canHaveScrollbars(true)
243     , m_layoutTimer(*this, &FrameView::layoutTimerFired)
244     , m_layoutPhase(OutsideLayout)
245     , m_inSynchronousPostLayout(false)
246     , m_postLayoutTasksTimer(*this, &FrameView::performPostLayoutTasks)
247     , m_updateEmbeddedObjectsTimer(*this, &FrameView::updateEmbeddedObjectsTimerFired)
248     , m_isTransparent(false)
249     , m_baseBackgroundColor(Color::white)
250     , m_mediaType("screen")
251     , m_overflowStatusDirty(true)
252     , m_wasScrolledByUser(false)
253     , m_inProgrammaticScroll(false)
254     , m_safeToPropagateScrollToParent(true)
255     , m_delayedScrollEventTimer(*this, &FrameView::sendScrollEvent)
256     , m_isTrackingRepaints(false)
257     , m_shouldUpdateWhileOffscreen(true)
258     , m_deferSetNeedsLayoutCount(0)
259     , m_setNeedsLayoutWasDeferred(false)
260     , m_speculativeTilingEnabled(false)
261     , m_speculativeTilingEnableTimer(*this, &FrameView::speculativeTilingEnableTimerFired)
262 #if PLATFORM(IOS)
263     , m_useCustomFixedPositionLayoutRect(false)
264     , m_useCustomSizeForResizeEvent(false)
265 #endif
266     , m_hasOverrideViewportSize(false)
267     , m_shouldAutoSize(false)
268     , m_inAutoSize(false)
269     , m_didRunAutosize(false)
270     , m_autoSizeFixedMinimumHeight(0)
271     , m_headerHeight(0)
272     , m_footerHeight(0)
273     , m_milestonesPendingPaint(0)
274     , m_visualUpdatesAllowedByClient(true)
275     , m_hasFlippedBlockRenderers(false)
276     , m_scrollPinningBehavior(DoNotPin)
277 {
278     init();
279
280 #if ENABLE(RUBBER_BANDING)
281     ScrollElasticity verticalElasticity = ScrollElasticityNone;
282     ScrollElasticity horizontalElasticity = ScrollElasticityNone;
283     if (m_frame->isMainFrame()) {
284         verticalElasticity = m_frame->page() ? m_frame->page()->verticalScrollElasticity() : ScrollElasticityAllowed;
285         horizontalElasticity = m_frame->page() ? m_frame->page()->horizontalScrollElasticity() : ScrollElasticityAllowed;
286     } else if (m_frame->settings().rubberBandingForSubScrollableRegionsEnabled()) {
287         verticalElasticity = ScrollElasticityAutomatic;
288         horizontalElasticity = ScrollElasticityAutomatic;
289     }
290
291     ScrollableArea::setVerticalScrollElasticity(verticalElasticity);
292     ScrollableArea::setHorizontalScrollElasticity(horizontalElasticity);
293 #endif
294 }
295
296 Ref<FrameView> FrameView::create(Frame& frame)
297 {
298     Ref<FrameView> view = adoptRef(*new FrameView(frame));
299     if (frame.page() && frame.page()->isVisible())
300         view->show();
301     return view;
302 }
303
304 Ref<FrameView> FrameView::create(Frame& frame, const IntSize& initialSize)
305 {
306     Ref<FrameView> view = adoptRef(*new FrameView(frame));
307     view->Widget::setFrameRect(IntRect(view->location(), initialSize));
308     if (frame.page() && frame.page()->isVisible())
309         view->show();
310     return view;
311 }
312
313 FrameView::~FrameView()
314 {
315     if (m_postLayoutTasksTimer.isActive())
316         m_postLayoutTasksTimer.stop();
317     
318     removeFromAXObjectCache();
319     resetScrollbars();
320
321     // Custom scrollbars should already be destroyed at this point
322     ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
323     ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
324
325     setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
326     setHasVerticalScrollbar(false);
327     
328     ASSERT(!m_scrollCorner);
329
330     ASSERT(frame().view() != this || !frame().contentRenderer());
331 }
332
333 void FrameView::reset()
334 {
335     m_cannotBlitToWindow = false;
336     m_isOverlapped = false;
337     m_contentIsOpaque = false;
338     m_layoutTimer.stop();
339     m_layoutRoot = nullptr;
340     m_delayedLayout = false;
341     m_needsFullRepaint = true;
342     m_layoutSchedulingEnabled = true;
343     m_layoutPhase = OutsideLayout;
344     m_inSynchronousPostLayout = false;
345     m_layoutCount = 0;
346     m_nestedLayoutCount = 0;
347     m_postLayoutTasksTimer.stop();
348     m_updateEmbeddedObjectsTimer.stop();
349     m_firstLayout = true;
350     m_firstLayoutCallbackPending = false;
351     m_wasScrolledByUser = false;
352     m_safeToPropagateScrollToParent = true;
353     m_delayedScrollEventTimer.stop();
354     m_lastViewportSize = IntSize();
355     m_lastZoomFactor = 1.0f;
356     m_isTrackingRepaints = false;
357     m_trackedRepaintRects.clear();
358     m_lastPaintTime = 0;
359     m_paintBehavior = PaintBehaviorNormal;
360     m_isPainting = false;
361     m_visuallyNonEmptyCharacterCount = 0;
362     m_visuallyNonEmptyPixelCount = 0;
363     m_isVisuallyNonEmpty = false;
364     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
365     m_needsDeferredScrollbarsUpdate = false;
366     m_maintainScrollPositionAnchor = nullptr;
367 }
368
369 void FrameView::removeFromAXObjectCache()
370 {
371     if (AXObjectCache* cache = axObjectCache()) {
372         if (HTMLFrameOwnerElement* owner = frame().ownerElement())
373             cache->childrenChanged(owner->renderer());
374         cache->remove(this);
375     }
376 }
377
378 void FrameView::resetScrollbars()
379 {
380     // Reset the document's scrollbars back to our defaults before we yield the floor.
381     m_firstLayout = true;
382     setScrollbarsSuppressed(true);
383     if (m_canHaveScrollbars)
384         setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
385     else
386         setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
387     setScrollbarsSuppressed(false);
388 }
389
390 void FrameView::resetScrollbarsAndClearContentsSize()
391 {
392     resetScrollbars();
393
394     setScrollbarsSuppressed(true);
395     setContentsSize(IntSize());
396     setScrollbarsSuppressed(false);
397 }
398
399 void FrameView::init()
400 {
401     reset();
402
403     m_margins = LayoutSize(-1, -1); // undefined
404     m_size = LayoutSize();
405
406     // Propagate the marginwidth/height and scrolling modes to the view.
407     Element* ownerElement = frame().ownerElement();
408     if (is<HTMLFrameElementBase>(ownerElement)) {
409         HTMLFrameElementBase& frameElement = downcast<HTMLFrameElementBase>(*ownerElement);
410         if (frameElement.scrollingMode() == ScrollbarAlwaysOff)
411             setCanHaveScrollbars(false);
412         LayoutUnit marginWidth = frameElement.marginWidth();
413         LayoutUnit marginHeight = frameElement.marginHeight();
414         if (marginWidth != -1)
415             setMarginWidth(marginWidth);
416         if (marginHeight != -1)
417             setMarginHeight(marginHeight);
418     }
419
420     Page* page = frame().page();
421     if (page && page->chrome().client().shouldPaintEntireContents())
422         setPaintsEntireContents(true);
423 }
424     
425 void FrameView::prepareForDetach()
426 {
427     detachCustomScrollbars();
428     // When the view is no longer associated with a frame, it needs to be removed from the ax object cache
429     // right now, otherwise it won't be able to reach the topDocument()'s axObject cache later.
430     removeFromAXObjectCache();
431
432     if (frame().page()) {
433         if (ScrollingCoordinator* scrollingCoordinator = frame().page()->scrollingCoordinator())
434             scrollingCoordinator->willDestroyScrollableArea(*this);
435     }
436 }
437
438 void FrameView::detachCustomScrollbars()
439 {
440     Scrollbar* horizontalBar = horizontalScrollbar();
441     if (horizontalBar && horizontalBar->isCustomScrollbar())
442         setHasHorizontalScrollbar(false);
443
444     Scrollbar* verticalBar = verticalScrollbar();
445     if (verticalBar && verticalBar->isCustomScrollbar())
446         setHasVerticalScrollbar(false);
447
448     m_scrollCorner = nullptr;
449 }
450
451 void FrameView::recalculateScrollbarOverlayStyle()
452 {
453     ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
454     std::optional<ScrollbarOverlayStyle> clientOverlayStyle = frame().page() ? frame().page()->chrome().client().preferredScrollbarOverlayStyle() : ScrollbarOverlayStyleDefault;
455     if (clientOverlayStyle) {
456         if (clientOverlayStyle.value() != oldOverlayStyle)
457             setScrollbarOverlayStyle(clientOverlayStyle.value());
458         return;
459     }
460
461     ScrollbarOverlayStyle computedOverlayStyle = ScrollbarOverlayStyleDefault;
462
463     Color backgroundColor = documentBackgroundColor();
464     if (backgroundColor.isValid()) {
465         // Reduce the background color from RGB to a lightness value
466         // and determine which scrollbar style to use based on a lightness
467         // heuristic.
468         double hue, saturation, lightness;
469         backgroundColor.getHSL(hue, saturation, lightness);
470         if (lightness <= .5 && backgroundColor.isVisible())
471             computedOverlayStyle = ScrollbarOverlayStyleLight;
472     }
473
474     if (oldOverlayStyle != computedOverlayStyle)
475         setScrollbarOverlayStyle(computedOverlayStyle);
476 }
477
478 void FrameView::clear()
479 {
480     setCanBlitOnScroll(true);
481     
482     reset();
483
484     setScrollbarsSuppressed(true);
485
486 #if PLATFORM(IOS)
487     // To avoid flashes of white, disable tile updates immediately when view is cleared at the beginning of a page load.
488     // Tiling will be re-enabled from UIKit via [WAKWindow setTilingMode:] when we have content to draw.
489     if (LegacyTileCache* tileCache = legacyTileCache())
490         tileCache->setTilingMode(LegacyTileCache::Disabled);
491 #endif
492 }
493
494 #if PLATFORM(IOS)
495 void FrameView::didReplaceMultipartContent()
496 {
497     // Re-enable tile updates that were disabled in clear().
498     if (LegacyTileCache* tileCache = legacyTileCache())
499         tileCache->setTilingMode(LegacyTileCache::Normal);
500 }
501 #endif
502
503 bool FrameView::didFirstLayout() const
504 {
505     return !m_firstLayout;
506 }
507
508 void FrameView::invalidateRect(const IntRect& rect)
509 {
510     if (!parent()) {
511         if (auto* page = frame().page())
512             page->chrome().invalidateContentsAndRootView(rect);
513         return;
514     }
515
516     auto* renderer = frame().ownerRenderer();
517     if (!renderer)
518         return;
519
520     IntRect repaintRect = rect;
521     repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(), renderer->borderTop() + renderer->paddingTop());
522     renderer->repaintRectangle(repaintRect);
523 }
524
525 void FrameView::setFrameRect(const IntRect& newRect)
526 {
527     Ref<FrameView> protectedThis(*this);
528     IntRect oldRect = frameRect();
529     if (newRect == oldRect)
530         return;
531     // Every scroll that happens as the result of frame size change is programmatic.
532     SetForScope<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
533     ScrollView::setFrameRect(newRect);
534
535     updateScrollableAreaSet();
536
537     if (RenderView* renderView = this->renderView()) {
538         if (renderView->usesCompositing())
539             renderView->compositor().frameViewDidChangeSize();
540     }
541
542     if (frame().isMainFrame())
543         frame().mainFrame().pageOverlayController().didChangeViewSize();
544
545     viewportContentsChanged();
546 }
547
548 bool FrameView::scheduleAnimation()
549 {
550     auto* page = frame().page();
551     if (!page)
552         return false;
553     page->chrome().scheduleAnimation();
554     return true;
555 }
556
557 void FrameView::setMarginWidth(LayoutUnit w)
558 {
559     // make it update the rendering area when set
560     m_margins.setWidth(w);
561 }
562
563 void FrameView::setMarginHeight(LayoutUnit h)
564 {
565     // make it update the rendering area when set
566     m_margins.setHeight(h);
567 }
568
569 FrameFlattening FrameView::effectiveFrameFlattening() const
570 {
571 #if PLATFORM(IOS)
572     // On iOS when async frame scrolling is enabled, it does not make sense to use full frame flattening.
573     // In that case, we just consider that frame flattening is disabled. This allows people to test
574     // frame scrolling on iOS by enabling "Async Frame Scrolling" via the Safari menu.
575     if (frame().settings().asyncFrameScrollingEnabled() && frame().settings().frameFlattening() == FrameFlattening::FullyEnabled)
576         return FrameFlattening::Disabled;
577 #endif
578     return frame().settings().frameFlattening();
579 }
580
581 bool FrameView::frameFlatteningEnabled() const
582 {
583     return effectiveFrameFlattening() != FrameFlattening::Disabled;
584 }
585
586 bool FrameView::isFrameFlatteningValidForThisFrame() const
587 {
588     if (!frameFlatteningEnabled())
589         return false;
590
591     HTMLFrameOwnerElement* owner = frame().ownerElement();
592     if (!owner)
593         return false;
594
595     // Frame flattening is valid only for <frame> and <iframe>.
596     return owner->hasTagName(frameTag) || owner->hasTagName(iframeTag);
597 }
598
599 bool FrameView::avoidScrollbarCreation() const
600 {
601     // with frame flattening no subframe can have scrollbars
602     // but we also cannot turn scrollbars off as we determine
603     // our flattening policy using that.
604     return isFrameFlatteningValidForThisFrame();
605 }
606
607 void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
608 {
609     m_canHaveScrollbars = canHaveScrollbars;
610     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
611 }
612
613 void FrameView::updateCanHaveScrollbars()
614 {
615     ScrollbarMode hMode;
616     ScrollbarMode vMode;
617     scrollbarModes(hMode, vMode);
618     if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
619         setCanHaveScrollbars(false);
620     else
621         setCanHaveScrollbars(true);
622 }
623
624 Ref<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
625 {
626     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
627     Document* doc = frame().document();
628
629     // Try the <body> element first as a scrollbar source.
630     HTMLElement* body = doc ? doc->bodyOrFrameset() : nullptr;
631     if (body && body->renderer() && body->renderer()->style().hasPseudoStyle(SCROLLBAR))
632         return RenderScrollbar::createCustomScrollbar(*this, orientation, body);
633     
634     // If the <body> didn't have a custom style, then the root element might.
635     Element* docElement = doc ? doc->documentElement() : nullptr;
636     if (docElement && docElement->renderer() && docElement->renderer()->style().hasPseudoStyle(SCROLLBAR))
637         return RenderScrollbar::createCustomScrollbar(*this, orientation, docElement);
638         
639     // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
640     RenderWidget* frameRenderer = frame().ownerRenderer();
641     if (frameRenderer && frameRenderer->style().hasPseudoStyle(SCROLLBAR))
642         return RenderScrollbar::createCustomScrollbar(*this, orientation, nullptr, &frame());
643     
644     // Nobody set a custom style, so we just use a native scrollbar.
645     return ScrollView::createScrollbar(orientation);
646 }
647
648 void FrameView::didRestoreFromPageCache()
649 {
650     // When restoring from page cache, the main frame stays in place while subframes get swapped in.
651     // We update the scrollable area set to ensure that scrolling data structures get invalidated.
652     updateScrollableAreaSet();
653 }
654
655 void FrameView::willDestroyRenderTree()
656 {
657     detachCustomScrollbars();
658     m_layoutRoot = nullptr;
659 }
660
661 void FrameView::didDestroyRenderTree()
662 {
663     ASSERT(!m_layoutRoot);
664     ASSERT(m_widgetsInRenderTree.isEmpty());
665
666     // If the render tree is destroyed below FrameView::updateEmbeddedObjects(), there will still be a null sentinel in the set.
667     // Everything else should have removed itself as the tree was felled.
668     ASSERT(!m_embeddedObjectsToUpdate || m_embeddedObjectsToUpdate->isEmpty() || (m_embeddedObjectsToUpdate->size() == 1 && m_embeddedObjectsToUpdate->first() == nullptr));
669
670     ASSERT(!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty());
671     ASSERT(!m_slowRepaintObjects || m_slowRepaintObjects->isEmpty());
672
673     ASSERT(!frame().animation().hasAnimations());
674 }
675
676 void FrameView::setContentsSize(const IntSize& size)
677 {
678     if (size == contentsSize())
679         return;
680
681     m_deferSetNeedsLayoutCount++;
682
683     ScrollView::setContentsSize(size);
684     contentsResized();
685     
686     Page* page = frame().page();
687     if (!page)
688         return;
689
690     updateScrollableAreaSet();
691
692     page->chrome().contentsSizeChanged(frame(), size); // Notify only.
693
694     if (frame().isMainFrame()) {
695         frame().mainFrame().pageOverlayController().didChangeDocumentSize();
696         PageCache::singleton().markPagesForContentsSizeChanged(*page);
697     }
698
699     ASSERT(m_deferSetNeedsLayoutCount);
700     m_deferSetNeedsLayoutCount--;
701     
702     if (!m_deferSetNeedsLayoutCount)
703         m_setNeedsLayoutWasDeferred = false; // FIXME: Find a way to make the deferred layout actually happen.
704 }
705
706 void FrameView::adjustViewSize()
707 {
708     RenderView* renderView = this->renderView();
709     if (!renderView)
710         return;
711
712     ASSERT(frame().view() == this);
713
714     const IntRect rect = renderView->documentRect();
715     const IntSize& size = rect.size();
716     ScrollView::setScrollOrigin(IntPoint(-rect.x(), -rect.y()), !frame().document()->printing(), size == contentsSize());
717
718     LOG_WITH_STREAM(Layout, stream << "FrameView " << this << " adjustViewSize: unscaled document rect changed to " << renderView->unscaledDocumentRect() << " (scaled to " << size << ")");
719
720     setContentsSize(size);
721 }
722
723 void FrameView::applyOverflowToViewport(const RenderElement& renderer, ScrollbarMode& hMode, ScrollbarMode& vMode)
724 {
725     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
726     // overflow:hidden and overflow:scroll on <body> as applying to the document's
727     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
728     // use the root element.
729
730     // To combat the inability to scroll on a page with overflow:hidden on the root when scaled, disregard hidden when
731     // there is a frameScaleFactor that is greater than one on the main frame. Also disregard hidden if there is a
732     // header or footer.
733
734     bool overrideHidden = frame().isMainFrame() && ((frame().frameScaleFactor() > 1) || headerHeight() || footerHeight());
735
736     EOverflow overflowX = renderer.style().overflowX();
737     EOverflow overflowY = renderer.style().overflowY();
738
739     if (is<RenderSVGRoot>(renderer)) {
740         // FIXME: evaluate if we can allow overflow for these cases too.
741         // Overflow is always hidden when stand-alone SVG documents are embedded.
742         if (downcast<RenderSVGRoot>(renderer).isEmbeddedThroughFrameContainingSVGDocument()) {
743             overflowX = OHIDDEN;
744             overflowY = OHIDDEN;
745         }
746     }
747
748     switch (overflowX) {
749         case OHIDDEN:
750             if (overrideHidden)
751                 hMode = ScrollbarAuto;
752             else
753                 hMode = ScrollbarAlwaysOff;
754             break;
755         case OSCROLL:
756             hMode = ScrollbarAlwaysOn;
757             break;
758         case OAUTO:
759             hMode = ScrollbarAuto;
760             break;
761         default:
762             // Don't set it at all.
763             ;
764     }
765     
766      switch (overflowY) {
767         case OHIDDEN:
768             if (overrideHidden)
769                 vMode = ScrollbarAuto;
770             else
771                 vMode = ScrollbarAlwaysOff;
772             break;
773         case OSCROLL:
774             vMode = ScrollbarAlwaysOn;
775             break;
776         case OAUTO:
777             vMode = ScrollbarAuto;
778             break;
779         default:
780             // Don't set it at all. Values of OPAGEDX and OPAGEDY are handled by applyPaginationToViewPort().
781             ;
782     }
783 }
784
785 void FrameView::applyPaginationToViewport()
786 {
787     auto* document = frame().document();
788     auto* documentElement = document ? document->documentElement() : nullptr;
789     if (!documentElement || !documentElement->renderer()) {
790         setPagination(Pagination());
791         return;
792     }
793
794     auto& documentRenderer = *documentElement->renderer();
795     auto* documentOrBodyRenderer = &documentRenderer;
796
797     auto* body = document->body();
798     if (body && body->renderer()) {
799         documentOrBodyRenderer = documentRenderer.style().overflowX() == OVISIBLE && is<HTMLHtmlElement>(*documentElement) ?
800             body->renderer() : &documentRenderer;
801     }
802
803     Pagination pagination;
804     EOverflow overflowY = documentOrBodyRenderer->style().overflowY();
805     if (overflowY == OPAGEDX || overflowY == OPAGEDY) {
806         pagination.mode = WebCore::paginationModeForRenderStyle(documentOrBodyRenderer->style());
807         pagination.gap = static_cast<unsigned>(documentOrBodyRenderer->style().columnGap());
808     }
809     setPagination(pagination);
810 }
811
812 void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
813 {
814     m_viewportRendererType = ViewportRendererType::None;
815
816     const HTMLFrameOwnerElement* owner = frame().ownerElement();
817     if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
818         hMode = ScrollbarAlwaysOff;
819         vMode = ScrollbarAlwaysOff;
820         return;
821     }  
822     
823     if (m_canHaveScrollbars || strategy == RulesFromWebContentOnly) {
824         hMode = ScrollbarAuto;
825         vMode = ScrollbarAuto;
826     } else {
827         hMode = ScrollbarAlwaysOff;
828         vMode = ScrollbarAlwaysOff;
829     }
830     
831     if (m_layoutRoot)
832         return;
833     
834     auto* document = frame().document();
835     if (!document)
836         return;
837
838     auto* documentElement = document->documentElement();
839     if (!documentElement)
840         return;
841
842     auto* bodyOrFrameset = document->bodyOrFrameset();
843     auto* rootRenderer = documentElement->renderer();
844     if (!bodyOrFrameset || !bodyOrFrameset->renderer()) {
845         if (rootRenderer) {
846             applyOverflowToViewport(*rootRenderer, hMode, vMode);
847             m_viewportRendererType = ViewportRendererType::Document;
848         }
849         return;
850     }
851     
852     if (is<HTMLFrameSetElement>(*bodyOrFrameset) && !frameFlatteningEnabled()) {
853         vMode = ScrollbarAlwaysOff;
854         hMode = ScrollbarAlwaysOff;
855         return;
856     }
857
858     if (is<HTMLBodyElement>(*bodyOrFrameset) && rootRenderer) {
859         // It's sufficient to just check the X overflow,
860         // since it's illegal to have visible in only one direction.
861         if (rootRenderer->style().overflowX() == OVISIBLE && is<HTMLHtmlElement>(documentElement)) {
862             auto* bodyRenderer = bodyOrFrameset->renderer();
863             if (bodyRenderer) {
864                 applyOverflowToViewport(*bodyRenderer, hMode, vMode);
865                 m_viewportRendererType = ViewportRendererType::Body;
866             }
867         } else {
868             applyOverflowToViewport(*rootRenderer, hMode, vMode);
869             m_viewportRendererType = ViewportRendererType::Document;
870         }
871     }
872 }
873
874 void FrameView::willRecalcStyle()
875 {
876     RenderView* renderView = this->renderView();
877     if (!renderView)
878         return;
879
880     renderView->compositor().willRecalcStyle();
881 }
882
883 bool FrameView::updateCompositingLayersAfterStyleChange()
884 {
885     RenderView* renderView = this->renderView();
886     if (!renderView)
887         return false;
888
889     // If we expect to update compositing after an incipient layout, don't do so here.
890     if (inPreLayoutStyleUpdate() || layoutPending() || renderView->needsLayout())
891         return false;
892
893     return renderView->compositor().didRecalcStyleWithNoPendingLayout();
894 }
895
896 void FrameView::updateCompositingLayersAfterLayout()
897 {
898     RenderView* renderView = this->renderView();
899     if (!renderView)
900         return;
901
902     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
903     renderView->compositor().cacheAcceleratedCompositingFlags();
904     renderView->compositor().updateCompositingLayers(CompositingUpdateType::AfterLayout);
905 }
906
907 void FrameView::clearBackingStores()
908 {
909     RenderView* renderView = this->renderView();
910     if (!renderView)
911         return;
912
913     RenderLayerCompositor& compositor = renderView->compositor();
914     ASSERT(compositor.inCompositingMode());
915     compositor.enableCompositingMode(false);
916     compositor.clearBackingForAllLayers();
917 }
918
919 GraphicsLayer* FrameView::layerForScrolling() const
920 {
921     RenderView* renderView = this->renderView();
922     if (!renderView)
923         return nullptr;
924     return renderView->compositor().scrollLayer();
925 }
926
927 GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
928 {
929     RenderView* renderView = this->renderView();
930     if (!renderView)
931         return nullptr;
932     return renderView->compositor().layerForHorizontalScrollbar();
933 }
934
935 GraphicsLayer* FrameView::layerForVerticalScrollbar() const
936 {
937     RenderView* renderView = this->renderView();
938     if (!renderView)
939         return nullptr;
940     return renderView->compositor().layerForVerticalScrollbar();
941 }
942
943 GraphicsLayer* FrameView::layerForScrollCorner() const
944 {
945     RenderView* renderView = this->renderView();
946     if (!renderView)
947         return nullptr;
948     return renderView->compositor().layerForScrollCorner();
949 }
950
951 TiledBacking* FrameView::tiledBacking() const
952 {
953     RenderView* renderView = this->renderView();
954     if (!renderView)
955         return nullptr;
956
957     RenderLayerBacking* backing = renderView->layer()->backing();
958     if (!backing)
959         return nullptr;
960
961     return backing->tiledBacking();
962 }
963
964 uint64_t FrameView::scrollLayerID() const
965 {
966     RenderView* renderView = this->renderView();
967     if (!renderView)
968         return 0;
969
970     RenderLayerBacking* backing = renderView->layer()->backing();
971     if (!backing)
972         return 0;
973
974     return backing->scrollingNodeIDForRole(Scrolling);
975 }
976
977 ScrollableArea* FrameView::scrollableAreaForScrollLayerID(uint64_t nodeID) const
978 {
979     RenderView* renderView = this->renderView();
980     if (!renderView)
981         return nullptr;
982
983     return renderView->compositor().scrollableAreaForScrollLayerID(nodeID);
984 }
985
986 #if ENABLE(RUBBER_BANDING)
987 GraphicsLayer* FrameView::layerForOverhangAreas() const
988 {
989     RenderView* renderView = this->renderView();
990     if (!renderView)
991         return nullptr;
992     return renderView->compositor().layerForOverhangAreas();
993 }
994
995 GraphicsLayer* FrameView::setWantsLayerForTopOverHangArea(bool wantsLayer) const
996 {
997     RenderView* renderView = this->renderView();
998     if (!renderView)
999         return nullptr;
1000
1001     return renderView->compositor().updateLayerForTopOverhangArea(wantsLayer);
1002 }
1003
1004 GraphicsLayer* FrameView::setWantsLayerForBottomOverHangArea(bool wantsLayer) const
1005 {
1006     RenderView* renderView = this->renderView();
1007     if (!renderView)
1008         return nullptr;
1009
1010     return renderView->compositor().updateLayerForBottomOverhangArea(wantsLayer);
1011 }
1012
1013 #endif // ENABLE(RUBBER_BANDING)
1014
1015 #if ENABLE(CSS_SCROLL_SNAP)
1016 void FrameView::updateSnapOffsets()
1017 {
1018     if (!frame().document())
1019         return;
1020
1021     // FIXME: Should we allow specifying snap points through <html> tags too?
1022     HTMLElement* body = frame().document()->bodyOrFrameset();
1023     if (!renderView() || !body || !body->renderer())
1024         return;
1025     
1026     updateSnapOffsetsForScrollableArea(*this, *body, *renderView(), body->renderer()->style());
1027 }
1028
1029 bool FrameView::isScrollSnapInProgress() const
1030 {
1031     if (scrollbarsSuppressed())
1032         return false;
1033     
1034     // If the scrolling thread updates the scroll position for this FrameView, then we should return
1035     // ScrollingCoordinator::isScrollSnapInProgress().
1036     if (Page* page = frame().page()) {
1037         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
1038             if (!scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously(*this))
1039                 return scrollingCoordinator->isScrollSnapInProgress();
1040         }
1041     }
1042     
1043     // If the main thread updates the scroll position for this FrameView, we should return
1044     // ScrollAnimator::isScrollSnapInProgress().
1045     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
1046         return scrollAnimator->isScrollSnapInProgress();
1047     
1048     return false;
1049 }
1050
1051 void FrameView::updateScrollingCoordinatorScrollSnapProperties() const
1052 {
1053     renderView()->compositor().updateScrollSnapPropertiesWithFrameView(*this);
1054 }
1055 #endif
1056
1057 bool FrameView::flushCompositingStateForThisFrame(const Frame& rootFrameForFlush)
1058 {
1059     RenderView* renderView = this->renderView();
1060     if (!renderView)
1061         return true; // We don't want to keep trying to update layers if we have no renderer.
1062
1063     ASSERT(frame().view() == this);
1064
1065     // If we sync compositing layers when a layout is pending, we may cause painting of compositing
1066     // layer content to occur before layout has happened, which will cause paintContents() to bail.
1067     if (needsLayout())
1068         return false;
1069
1070 #if PLATFORM(IOS)
1071     if (LegacyTileCache* tileCache = legacyTileCache())
1072         tileCache->doPendingRepaints();
1073 #endif
1074
1075     renderView->compositor().flushPendingLayerChanges(&rootFrameForFlush == m_frame.ptr());
1076     return true;
1077 }
1078
1079 void FrameView::setNeedsOneShotDrawingSynchronization()
1080 {
1081     if (Page* page = frame().page())
1082         page->chrome().client().setNeedsOneShotDrawingSynchronization();
1083 }
1084
1085 GraphicsLayer* FrameView::graphicsLayerForPlatformWidget(PlatformWidget platformWidget)
1086 {
1087     // To find the Widget that corresponds with platformWidget we have to do a linear
1088     // search of our child widgets.
1089     const Widget* foundWidget = nullptr;
1090     for (auto& widget : children()) {
1091         if (widget->platformWidget() != platformWidget)
1092             continue;
1093         foundWidget = widget.ptr();
1094         break;
1095     }
1096
1097     if (!foundWidget)
1098         return nullptr;
1099
1100     auto* renderWidget = RenderWidget::find(*foundWidget);
1101     if (!renderWidget)
1102         return nullptr;
1103
1104     auto* widgetLayer = renderWidget->layer();
1105     if (!widgetLayer || !widgetLayer->isComposited())
1106         return nullptr;
1107
1108     return widgetLayer->backing()->parentForSublayers();
1109 }
1110
1111 void FrameView::scheduleLayerFlushAllowingThrottling()
1112 {
1113     RenderView* view = this->renderView();
1114     if (!view)
1115         return;
1116     view->compositor().scheduleLayerFlush(true /* canThrottle */);
1117 }
1118
1119 LayoutRect FrameView::fixedScrollableAreaBoundsInflatedForScrolling(const LayoutRect& uninflatedBounds) const
1120 {
1121     LayoutPoint scrollPosition;
1122     LayoutSize topLeftExpansion;
1123     LayoutSize bottomRightExpansion;
1124
1125     if (frame().settings().visualViewportEnabled()) {
1126         // FIXME: this is wrong under zooming; uninflatedBounds is scaled but the scroll positions are not.
1127         scrollPosition = layoutViewportRect().location();
1128         topLeftExpansion = scrollPosition - unscaledMinimumScrollPosition();
1129         bottomRightExpansion = unscaledMaximumScrollPosition() - scrollPosition;
1130     } else {
1131         scrollPosition = scrollPositionRespectingCustomFixedPosition();
1132         topLeftExpansion = scrollPosition - minimumScrollPosition();
1133         bottomRightExpansion = maximumScrollPosition() - scrollPosition;
1134     }
1135
1136     return LayoutRect(uninflatedBounds.location() - topLeftExpansion, uninflatedBounds.size() + topLeftExpansion + bottomRightExpansion);
1137 }
1138
1139 LayoutPoint FrameView::scrollPositionRespectingCustomFixedPosition() const
1140 {
1141 #if PLATFORM(IOS)
1142     if (!frame().settings().visualViewportEnabled())
1143         return useCustomFixedPositionLayoutRect() ? customFixedPositionLayoutRect().location() : scrollPosition();
1144 #endif
1145
1146     return scrollPositionForFixedPosition();
1147 }
1148
1149 void FrameView::setHeaderHeight(int headerHeight)
1150 {
1151     if (frame().page())
1152         ASSERT(frame().isMainFrame());
1153     m_headerHeight = headerHeight;
1154
1155     if (RenderView* renderView = this->renderView())
1156         renderView->setNeedsLayout();
1157 }
1158
1159 void FrameView::setFooterHeight(int footerHeight)
1160 {
1161     if (frame().page())
1162         ASSERT(frame().isMainFrame());
1163     m_footerHeight = footerHeight;
1164
1165     if (RenderView* renderView = this->renderView())
1166         renderView->setNeedsLayout();
1167 }
1168
1169 float FrameView::topContentInset(TopContentInsetType contentInsetTypeToReturn) const
1170 {
1171     if (platformWidget() && contentInsetTypeToReturn == TopContentInsetType::WebCoreOrPlatformContentInset)
1172         return platformTopContentInset();
1173
1174     if (!frame().isMainFrame())
1175         return 0;
1176     
1177     Page* page = frame().page();
1178     return page ? page->topContentInset() : 0;
1179 }
1180     
1181 void FrameView::topContentInsetDidChange(float newTopContentInset)
1182 {
1183     RenderView* renderView = this->renderView();
1184     if (!renderView)
1185         return;
1186
1187     if (platformWidget())
1188         platformSetTopContentInset(newTopContentInset);
1189     
1190     layout();
1191     // Every scroll that happens as the result of content inset change is programmatic.
1192     SetForScope<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
1193     updateScrollbars(scrollPosition());
1194     if (renderView->usesCompositing())
1195         renderView->compositor().frameViewDidChangeSize();
1196
1197     if (TiledBacking* tiledBacking = this->tiledBacking())
1198         tiledBacking->setTopContentInset(newTopContentInset);
1199 }
1200
1201 void FrameView::topContentDirectionDidChange()
1202 {
1203     m_needsDeferredScrollbarsUpdate = true;
1204 }
1205
1206 void FrameView::handleDeferredScrollbarsUpdateAfterDirectionChange()
1207 {
1208     if (!m_needsDeferredScrollbarsUpdate)
1209         return;
1210
1211     m_needsDeferredScrollbarsUpdate = false;
1212
1213     ASSERT(m_layoutPhase == InPostLayerPositionsUpdatedAfterLayout);
1214     updateScrollbars(scrollPosition());
1215     positionScrollbarLayers();
1216 }
1217     
1218 bool FrameView::hasCompositedContent() const
1219 {
1220     if (RenderView* renderView = this->renderView())
1221         return renderView->compositor().inCompositingMode();
1222     return false;
1223 }
1224
1225 // Sometimes (for plug-ins) we need to eagerly go into compositing mode.
1226 void FrameView::enterCompositingMode()
1227 {
1228     if (RenderView* renderView = this->renderView()) {
1229         renderView->compositor().enableCompositingMode();
1230         if (!needsLayout())
1231             renderView->compositor().scheduleCompositingLayerUpdate();
1232     }
1233 }
1234
1235 bool FrameView::isEnclosedInCompositingLayer() const
1236 {
1237     auto frameOwnerRenderer = frame().ownerRenderer();
1238     if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
1239         return true;
1240
1241     if (FrameView* parentView = parentFrameView())
1242         return parentView->isEnclosedInCompositingLayer();
1243     return false;
1244 }
1245
1246 bool FrameView::flushCompositingStateIncludingSubframes()
1247 {
1248 #if PLATFORM(COCOA)
1249     InspectorInstrumentation::willComposite(frame());
1250 #endif
1251
1252     bool allFramesFlushed = flushCompositingStateForThisFrame(frame());
1253
1254     for (Frame* child = frame().tree().firstRenderedChild(); child; child = child->tree().traverseNextRendered(m_frame.ptr())) {
1255         if (!child->view())
1256             continue;
1257         bool flushed = child->view()->flushCompositingStateForThisFrame(frame());
1258         allFramesFlushed &= flushed;
1259     }
1260     return allFramesFlushed;
1261 }
1262
1263 bool FrameView::isSoftwareRenderable() const
1264 {
1265     RenderView* renderView = this->renderView();
1266     return !renderView || !renderView->compositor().has3DContent();
1267 }
1268
1269 void FrameView::setIsInWindow(bool isInWindow)
1270 {
1271     if (RenderView* renderView = this->renderView())
1272         renderView->setIsInWindow(isInWindow);
1273 }
1274
1275 inline void FrameView::forceLayoutParentViewIfNeeded()
1276 {
1277     RenderWidget* ownerRenderer = frame().ownerRenderer();
1278     if (!ownerRenderer)
1279         return;
1280
1281     RenderBox* contentBox = embeddedContentBox();
1282     if (!contentBox)
1283         return;
1284
1285     auto& svgRoot = downcast<RenderSVGRoot>(*contentBox);
1286     if (svgRoot.everHadLayout() && !svgRoot.needsLayout())
1287         return;
1288
1289     LOG(Layout, "FrameView %p forceLayoutParentViewIfNeeded scheduling layout on parent FrameView %p", this, &ownerRenderer->view().frameView());
1290
1291     // If the embedded SVG document appears the first time, the ownerRenderer has already finished
1292     // layout without knowing about the existence of the embedded SVG document, because RenderReplaced
1293     // embeddedContentBox() returns nullptr, as long as the embedded document isn't loaded yet. Before
1294     // bothering to lay out the SVG document, mark the ownerRenderer needing layout and ask its
1295     // FrameView for a layout. After that the RenderEmbeddedObject (ownerRenderer) carries the
1296     // correct size, which RenderSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying
1297     // out for the first time, or when the RenderSVGRoot size has changed dynamically (eg. via <script>).
1298
1299     ownerRenderer->setNeedsLayoutAndPrefWidthsRecalc();
1300     ownerRenderer->view().frameView().scheduleRelayout();
1301 }
1302
1303 void FrameView::layout(bool allowSubtree)
1304 {
1305     ASSERT_WITH_SECURITY_IMPLICATION(!frame().document()->inRenderTreeUpdate());
1306
1307     LOG(Layout, "FrameView %p (%dx%d) layout, main frameview %d, allowSubtree=%d", this, size().width(), size().height(), frame().isMainFrame(), allowSubtree);
1308     if (isInRenderTreeLayout()) {
1309         LOG(Layout, "  in layout, bailing");
1310         return;
1311     }
1312
1313     if (layoutDisallowed()) {
1314         LOG(Layout, "  layout is disallowed, bailing");
1315         return;
1316     }
1317
1318     // Protect the view from being deleted during layout (in recalcStyle).
1319     Ref<FrameView> protectedThis(*this);
1320
1321     // Many of the tasks performed during layout can cause this function to be re-entered,
1322     // so save the layout phase now and restore it on exit.
1323     SetForScope<LayoutPhase> layoutPhaseRestorer(m_layoutPhase, InPreLayout);
1324
1325     // Every scroll that happens during layout is programmatic.
1326     SetForScope<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
1327
1328     bool inChildFrameLayoutWithFrameFlattening = isInChildFrameWithFrameFlattening();
1329
1330     if (inChildFrameLayoutWithFrameFlattening) {
1331         if (!m_frameFlatteningViewSizeForMediaQuery) {
1332             LOG_WITH_STREAM(MediaQueries, stream << "FrameView " << this << " snapshotting size " <<  ScrollView::layoutSize() << " for media queries");
1333             m_frameFlatteningViewSizeForMediaQuery = ScrollView::layoutSize();
1334         }
1335         startLayoutAtMainFrameViewIfNeeded(allowSubtree);
1336         RenderElement* root = m_layoutRoot ? m_layoutRoot : frame().document()->renderView();
1337         if (!root || !root->needsLayout())
1338             return;
1339     }
1340     
1341     TraceScope tracingScope(LayoutStart, LayoutEnd);
1342
1343 #if PLATFORM(IOS)
1344     if (updateFixedPositionLayoutRect())
1345         allowSubtree = false;
1346 #endif
1347
1348     m_layoutTimer.stop();
1349     m_delayedLayout = false;
1350     m_setNeedsLayoutWasDeferred = false;
1351     
1352     // we shouldn't enter layout() while painting
1353     ASSERT(!isPainting());
1354     if (isPainting())
1355         return;
1356
1357     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(frame());
1358     AnimationUpdateBlock animationUpdateBlock(&frame().animation());
1359     
1360     if (!allowSubtree && m_layoutRoot)
1361         convertSubtreeLayoutToFullLayout();
1362
1363     ASSERT(frame().view() == this);
1364     ASSERT(frame().document());
1365
1366     Document& document = *frame().document();
1367     ASSERT(document.pageCacheState() == Document::NotInPageCache);
1368
1369     {
1370         SetForScope<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
1371
1372         if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive() && !inChildFrameLayoutWithFrameFlattening) {
1373             // This is a new top-level layout. If there are any remaining tasks from the previous
1374             // layout, finish them now.
1375             SetForScope<bool> inSynchronousPostLayoutChange(m_inSynchronousPostLayout, true);
1376             performPostLayoutTasks();
1377         }
1378
1379         m_layoutPhase = InPreLayoutStyleUpdate;
1380
1381         // Viewport-dependent media queries may cause us to need completely different style information.
1382         auto* styleResolver = document.styleScope().resolverIfExists();
1383         if (!styleResolver || styleResolver->hasMediaQueriesAffectedByViewportChange()) {
1384             LOG(Layout, "  hasMediaQueriesAffectedByViewportChange, enqueueing style recalc");
1385             document.styleScope().didChangeStyleSheetEnvironment();
1386             // FIXME: This instrumentation event is not strictly accurate since cached media query results do not persist across StyleResolver rebuilds.
1387             InspectorInstrumentation::mediaQueryResultChanged(document);
1388         }
1389         document.evaluateMediaQueryList();
1390         // If there is any pagination to apply, it will affect the RenderView's style, so we should
1391         // take care of that now.
1392         applyPaginationToViewport();
1393         // Always ensure our style info is up-to-date. This can happen in situations where
1394         // the layout beats any sort of style recalc update that needs to occur.
1395         document.updateStyleIfNeeded();
1396         // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
1397         // so there's no point to continuing to layout
1398         if (hasOneRef())
1399             return;
1400
1401         // Close block here so we can set up the font cache purge preventer, which we will still
1402         // want in scope even after we want m_layoutSchedulingEnabled to be restored again.
1403         // The next block sets m_layoutSchedulingEnabled back to false once again.
1404     }
1405
1406     m_layoutPhase = InPreLayout;
1407
1408     RenderLayer* layer = nullptr;
1409     bool subtree = false;
1410     RenderElement* root = nullptr;
1411
1412     ++m_nestedLayoutCount;
1413
1414     {
1415         SetForScope<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
1416
1417         autoSizeIfEnabled();
1418
1419         root = m_layoutRoot ? m_layoutRoot : document.renderView();
1420         if (!root)
1421             return;
1422         subtree = m_layoutRoot;
1423
1424         if (!m_layoutRoot) {
1425             auto* body = document.bodyOrFrameset();
1426             if (body && body->renderer()) {
1427                 if (is<HTMLFrameSetElement>(*body) && !frameFlatteningEnabled()) {
1428                     body->renderer()->setChildNeedsLayout();
1429                 } else if (is<HTMLBodyElement>(*body)) {
1430                     if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox().stretchesToViewport())
1431                         body->renderer()->setChildNeedsLayout();
1432                 }
1433             }
1434
1435 #if !LOG_DISABLED
1436             if (m_firstLayout && !frame().ownerElement())
1437                 LOG(Layout, "FrameView %p elapsed time before first layout: %.3fs\n", this, document.timeSinceDocumentCreation().value());
1438 #endif
1439         }
1440
1441         m_needsFullRepaint = !subtree && (m_firstLayout || downcast<RenderView>(*root).printing());
1442
1443         if (!subtree) {
1444             ScrollbarMode hMode;
1445             ScrollbarMode vMode;    
1446             calculateScrollbarModesForLayout(hMode, vMode);
1447
1448             if (m_firstLayout || (hMode != horizontalScrollbarMode() || vMode != verticalScrollbarMode())) {
1449                 if (m_firstLayout) {
1450                     setScrollbarsSuppressed(true);
1451
1452                     m_firstLayout = false;
1453                     m_firstLayoutCallbackPending = true;
1454                     m_lastViewportSize = sizeForResizeEvent();
1455                     m_lastZoomFactor = root->style().zoom();
1456
1457                     // Set the initial vMode to AlwaysOn if we're auto.
1458                     if (vMode == ScrollbarAuto)
1459                         setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
1460                     // Set the initial hMode to AlwaysOff if we're auto.
1461                     if (hMode == ScrollbarAuto)
1462                         setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
1463                     Page* page = frame().page();
1464                     if (page && page->expectsWheelEventTriggers())
1465                         scrollAnimator().setWheelEventTestTrigger(page->testTrigger());
1466                     setScrollbarModes(hMode, vMode);
1467                     setScrollbarsSuppressed(false, true);
1468                 } else
1469                     setScrollbarModes(hMode, vMode);
1470             }
1471
1472             LayoutSize oldSize = m_size;
1473             m_size = layoutSize();
1474
1475             if (oldSize != m_size) {
1476                 LOG(Layout, "  layout size changed from %.3fx%.3f to %.3fx%.3f", oldSize.width().toFloat(), oldSize.height().toFloat(), m_size.width().toFloat(), m_size.height().toFloat());
1477                 m_needsFullRepaint = true;
1478                 if (!m_firstLayout) {
1479                     RenderBox* rootRenderer = document.documentElement() ? document.documentElement()->renderBox() : nullptr;
1480                     auto* body = document.bodyOrFrameset();
1481                     RenderBox* bodyRenderer = rootRenderer && body ? body->renderBox() : nullptr;
1482                     if (bodyRenderer && bodyRenderer->stretchesToViewport())
1483                         bodyRenderer->setChildNeedsLayout();
1484                     else if (rootRenderer && rootRenderer->stretchesToViewport())
1485                         rootRenderer->setChildNeedsLayout();
1486                 }
1487             }
1488
1489             m_layoutPhase = InPreLayout;
1490         }
1491
1492         layer = root->enclosingLayer();
1493         SubtreeLayoutStateMaintainer subtreeLayoutStateMaintainer(m_layoutRoot);
1494
1495         RenderView::RepaintRegionAccumulator repaintRegionAccumulator(&root->view());
1496
1497         ASSERT(m_layoutPhase == InPreLayout);
1498         m_layoutPhase = InRenderTreeLayout;
1499
1500         forceLayoutParentViewIfNeeded();
1501
1502         ASSERT(m_layoutPhase == InRenderTreeLayout);
1503 #ifndef NDEBUG
1504         RenderTreeNeedsLayoutChecker checker(*root);
1505 #endif
1506         root->layout();
1507
1508 #if ENABLE(TEXT_AUTOSIZING)
1509         if (frame().settings().textAutosizingEnabled() && !root->view().printing()) {
1510             float minimumZoomFontSize = frame().settings().minimumZoomFontSize();
1511             float textAutosizingWidth = frame().page() ? frame().page()->textAutosizingWidth() : 0;
1512             if (int overrideWidth = frame().settings().textAutosizingWindowSizeOverride().width())
1513                 textAutosizingWidth = overrideWidth;
1514
1515             LOG(TextAutosizing, "Text Autosizing: minimumZoomFontSize=%.2f textAutosizingWidth=%.2f", minimumZoomFontSize, textAutosizingWidth);
1516             
1517             if (minimumZoomFontSize && textAutosizingWidth) {
1518                 root->adjustComputedFontSizesOnBlocks(minimumZoomFontSize, textAutosizingWidth);
1519                 if (root->needsLayout())
1520                     root->layout();
1521             }
1522         }
1523 #endif
1524
1525         ASSERT(m_layoutPhase == InRenderTreeLayout);
1526         m_layoutRoot = nullptr;
1527         // Close block here to end the scope of changeSchedulingEnabled and SubtreeLayoutStateMaintainer.
1528     }
1529
1530     m_layoutPhase = InViewSizeAdjust;
1531
1532     bool neededFullRepaint = m_needsFullRepaint;
1533
1534     if (!subtree && !downcast<RenderView>(*root).printing()) {
1535         adjustViewSize();
1536         // FIXME: Firing media query callbacks synchronously on nested frames could produced a detached FrameView here by
1537         // navigating away from the current document (see webkit.org/b/173329).
1538         if (hasOneRef())
1539             return;
1540     }
1541
1542     m_layoutPhase = InPostLayout;
1543
1544     m_needsFullRepaint = neededFullRepaint;
1545
1546     // Now update the positions of all layers.
1547     if (m_needsFullRepaint)
1548         root->view().repaintRootContents();
1549
1550     root->view().releaseProtectedRenderWidgets();
1551
1552     ASSERT(!root->needsLayout());
1553
1554     layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layer, subtree, m_needsFullRepaint));
1555
1556     updateCompositingLayersAfterLayout();
1557
1558     m_layoutPhase = InPostLayerPositionsUpdatedAfterLayout;
1559
1560     m_layoutCount++;
1561
1562 #if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK)
1563     if (AXObjectCache* cache = root->document().existingAXObjectCache())
1564         cache->postNotification(root, AXObjectCache::AXLayoutComplete);
1565 #endif
1566
1567 #if ENABLE(DASHBOARD_SUPPORT)
1568     updateAnnotatedRegions();
1569 #endif
1570
1571 #if ENABLE(IOS_TOUCH_EVENTS)
1572     document.setTouchEventRegionsNeedUpdate();
1573 #endif
1574
1575     updateCanBlitOnScrollRecursively();
1576
1577     handleDeferredScrollUpdateAfterContentSizeChange();
1578
1579     handleDeferredScrollbarsUpdateAfterDirectionChange();
1580
1581     if (document.hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
1582         updateOverflowStatus(layoutWidth() < contentsWidth(), layoutHeight() < contentsHeight());
1583
1584     frame().document()->markers().invalidateRectsForAllMarkers();
1585
1586     if (!m_postLayoutTasksTimer.isActive()) {
1587         if (!m_inSynchronousPostLayout) {
1588             if (inChildFrameLayoutWithFrameFlattening)
1589                 updateWidgetPositions();
1590             else {
1591                 SetForScope<bool> inSynchronousPostLayoutChange(m_inSynchronousPostLayout, true);
1592                 performPostLayoutTasks(); // Calls resumeScheduledEvents().
1593             }
1594         }
1595
1596         if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout || inChildFrameLayoutWithFrameFlattening)) {
1597             // If we need layout or are already in a synchronous call to postLayoutTasks(), 
1598             // defer widget updates and event dispatch until after we return. postLayoutTasks()
1599             // can make us need to update again, and we can get stuck in a nasty cycle unless
1600             // we call it through the timer here.
1601             m_postLayoutTasksTimer.startOneShot(0_s);
1602         }
1603         if (needsLayout())
1604             layout();
1605     }
1606
1607     InspectorInstrumentation::didLayout(cookie, *root);
1608     DebugPageOverlays::didLayout(frame());
1609
1610     --m_nestedLayoutCount;
1611 }
1612
1613 bool FrameView::shouldDeferScrollUpdateAfterContentSizeChange()
1614 {
1615     return (m_layoutPhase < InPostLayout) && (m_layoutPhase != OutsideLayout);
1616 }
1617
1618 RenderBox* FrameView::embeddedContentBox() const
1619 {
1620     RenderView* renderView = this->renderView();
1621     if (!renderView)
1622         return nullptr;
1623
1624     RenderObject* firstChild = renderView->firstChild();
1625
1626     // Curently only embedded SVG documents participate in the size-negotiation logic.
1627     if (is<RenderSVGRoot>(firstChild))
1628         return downcast<RenderSVGRoot>(firstChild);
1629
1630     return nullptr;
1631 }
1632
1633 void FrameView::addEmbeddedObjectToUpdate(RenderEmbeddedObject& embeddedObject)
1634 {
1635     if (!m_embeddedObjectsToUpdate)
1636         m_embeddedObjectsToUpdate = std::make_unique<ListHashSet<RenderEmbeddedObject*>>();
1637
1638     HTMLFrameOwnerElement& element = embeddedObject.frameOwnerElement();
1639     if (is<HTMLObjectElement>(element) || is<HTMLEmbedElement>(element)) {
1640         // Tell the DOM element that it needs a widget update.
1641         HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
1642         if (!pluginElement.needsCheckForSizeChange())
1643             pluginElement.setNeedsWidgetUpdate(true);
1644     }
1645
1646     m_embeddedObjectsToUpdate->add(&embeddedObject);
1647 }
1648
1649 void FrameView::removeEmbeddedObjectToUpdate(RenderEmbeddedObject& embeddedObject)
1650 {
1651     if (!m_embeddedObjectsToUpdate)
1652         return;
1653
1654     m_embeddedObjectsToUpdate->remove(&embeddedObject);
1655 }
1656
1657 void FrameView::setMediaType(const String& mediaType)
1658 {
1659     m_mediaType = mediaType;
1660 }
1661
1662 String FrameView::mediaType() const
1663 {
1664     // See if we have an override type.
1665     String overrideType = frame().loader().client().overrideMediaType();
1666     InspectorInstrumentation::applyEmulatedMedia(frame(), overrideType);
1667     if (!overrideType.isNull())
1668         return overrideType;
1669     return m_mediaType;
1670 }
1671
1672 void FrameView::adjustMediaTypeForPrinting(bool printing)
1673 {
1674     if (printing) {
1675         if (m_mediaTypeWhenNotPrinting.isNull())
1676             m_mediaTypeWhenNotPrinting = mediaType();
1677         setMediaType("print");
1678     } else {
1679         if (!m_mediaTypeWhenNotPrinting.isNull())
1680             setMediaType(m_mediaTypeWhenNotPrinting);
1681         m_mediaTypeWhenNotPrinting = String();
1682     }
1683 }
1684
1685 bool FrameView::useSlowRepaints(bool considerOverlap) const
1686 {
1687     bool mustBeSlow = hasSlowRepaintObjects() || (platformWidget() && hasViewportConstrainedObjects());
1688
1689     // FIXME: WidgetMac.mm makes the assumption that useSlowRepaints ==
1690     // m_contentIsOpaque, so don't take the fast path for composited layers
1691     // if they are a platform widget in order to get painting correctness
1692     // for transparent layers. See the comment in WidgetMac::paint.
1693     if (usesCompositedScrolling() && !platformWidget())
1694         return mustBeSlow;
1695
1696     bool isOverlapped = m_isOverlapped && considerOverlap;
1697
1698     if (mustBeSlow || m_cannotBlitToWindow || isOverlapped || !m_contentIsOpaque)
1699         return true;
1700
1701     if (FrameView* parentView = parentFrameView())
1702         return parentView->useSlowRepaints(considerOverlap);
1703
1704     return false;
1705 }
1706
1707 bool FrameView::useSlowRepaintsIfNotOverlapped() const
1708 {
1709     return useSlowRepaints(false);
1710 }
1711
1712 void FrameView::updateCanBlitOnScrollRecursively()
1713 {
1714     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
1715         if (FrameView* view = frame->view())
1716             view->setCanBlitOnScroll(!view->useSlowRepaints());
1717     }
1718 }
1719
1720 bool FrameView::usesCompositedScrolling() const
1721 {
1722     RenderView* renderView = this->renderView();
1723     if (renderView && renderView->isComposited()) {
1724         GraphicsLayer* layer = renderView->layer()->backing()->graphicsLayer();
1725         if (layer && layer->drawsContent())
1726             return true;
1727     }
1728
1729     return false;
1730 }
1731
1732 bool FrameView::usesAsyncScrolling() const
1733 {
1734 #if ENABLE(ASYNC_SCROLLING)
1735     if (Page* page = frame().page()) {
1736         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1737             return scrollingCoordinator->coordinatesScrollingForFrameView(*this);
1738     }
1739 #endif
1740     return false;
1741 }
1742
1743 bool FrameView::usesMockScrollAnimator() const
1744 {
1745     return Settings::usesMockScrollAnimator();
1746 }
1747
1748 void FrameView::logMockScrollAnimatorMessage(const String& message) const
1749 {
1750     Document* document = frame().document();
1751     if (!document)
1752         return;
1753     StringBuilder builder;
1754     if (frame().isMainFrame())
1755         builder.appendLiteral("Main");
1756     builder.appendLiteral("FrameView: ");
1757     builder.append(message);
1758     document->addConsoleMessage(MessageSource::Other, MessageLevel::Debug, builder.toString());
1759 }
1760
1761 void FrameView::setCannotBlitToWindow()
1762 {
1763     m_cannotBlitToWindow = true;
1764     updateCanBlitOnScrollRecursively();
1765 }
1766
1767 void FrameView::addSlowRepaintObject(RenderElement* o)
1768 {
1769     bool hadSlowRepaintObjects = hasSlowRepaintObjects();
1770
1771     if (!m_slowRepaintObjects)
1772         m_slowRepaintObjects = std::make_unique<HashSet<const RenderElement*>>();
1773
1774     m_slowRepaintObjects->add(o);
1775
1776     if (!hadSlowRepaintObjects) {
1777         updateCanBlitOnScrollRecursively();
1778
1779         if (Page* page = frame().page()) {
1780             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1781                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(*this);
1782         }
1783     }
1784 }
1785
1786 void FrameView::removeSlowRepaintObject(RenderElement* o)
1787 {
1788     if (!m_slowRepaintObjects)
1789         return;
1790
1791     m_slowRepaintObjects->remove(o);
1792     if (m_slowRepaintObjects->isEmpty()) {
1793         m_slowRepaintObjects = nullptr;
1794         updateCanBlitOnScrollRecursively();
1795
1796         if (Page* page = frame().page()) {
1797             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1798                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(*this);
1799         }
1800     }
1801 }
1802
1803 void FrameView::addViewportConstrainedObject(RenderElement* object)
1804 {
1805     if (!m_viewportConstrainedObjects)
1806         m_viewportConstrainedObjects = std::make_unique<ViewportConstrainedObjectSet>();
1807
1808     if (!m_viewportConstrainedObjects->contains(object)) {
1809         m_viewportConstrainedObjects->add(object);
1810         if (platformWidget())
1811             updateCanBlitOnScrollRecursively();
1812
1813         if (Page* page = frame().page()) {
1814             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1815                 scrollingCoordinator->frameViewFixedObjectsDidChange(*this);
1816         }
1817     }
1818 }
1819
1820 void FrameView::removeViewportConstrainedObject(RenderElement* object)
1821 {
1822     if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->remove(object)) {
1823         if (Page* page = frame().page()) {
1824             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1825                 scrollingCoordinator->frameViewFixedObjectsDidChange(*this);
1826         }
1827
1828         // FIXME: In addFixedObject() we only call this if there's a platform widget,
1829         // why isn't the same check being made here?
1830         updateCanBlitOnScrollRecursively();
1831     }
1832 }
1833
1834 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)
1835 {
1836     LayoutRect layoutViewportRect = layoutViewport;
1837     
1838     // The layout viewport is never smaller than baseLayoutViewportSize, and never be smaller than the unobscuredContentRect.
1839     LayoutSize constrainedSize = baseLayoutViewportSize;
1840     layoutViewportRect.setSize(constrainedSize.expandedTo(unobscuredContentSize));
1841         
1842     LayoutPoint layoutViewportOrigin = computeLayoutViewportOrigin(unobscuredContentRect, stableLayoutViewportOriginMin, stableLayoutViewportOriginMax, layoutViewportRect, StickToViewportBounds);
1843
1844     // FIXME: Is this equivalent to calling computeLayoutViewportOrigin() with StickToDocumentBounds?
1845     if (constraint == LayoutViewportConstraint::ConstrainedToDocumentRect) {
1846         // 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.
1847         // 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
1848         // back in until the user scrolls back in the other direction.
1849         layoutViewportOrigin.setX(clampTo<float>(layoutViewportOrigin.x(), 0, documentRect.width() - layoutViewportRect.width()));
1850         layoutViewportOrigin.setY(clampTo<float>(layoutViewportOrigin.y(), 0, documentRect.height() - layoutViewportRect.height()));
1851     }
1852     layoutViewportRect.setLocation(layoutViewportOrigin);
1853     
1854     return layoutViewportRect;
1855 }
1856
1857 // visualViewport and layoutViewport are both in content coordinates (unzoomed).
1858 LayoutPoint FrameView::computeLayoutViewportOrigin(const LayoutRect& visualViewport, const LayoutPoint& stableLayoutViewportOriginMin, const LayoutPoint& stableLayoutViewportOriginMax, const LayoutRect& layoutViewport, ScrollBehaviorForFixedElements fixedBehavior)
1859 {
1860     LayoutPoint layoutViewportOrigin = layoutViewport.location();
1861     bool allowRubberBanding = fixedBehavior == StickToViewportBounds;
1862
1863     if (visualViewport.width() > layoutViewport.width()) {
1864         layoutViewportOrigin.setX(visualViewport.x());
1865         if (!allowRubberBanding) {
1866             if (layoutViewportOrigin.x() < stableLayoutViewportOriginMin.x())
1867                 layoutViewportOrigin.setX(stableLayoutViewportOriginMin.x());
1868             else if (layoutViewportOrigin.x() > stableLayoutViewportOriginMax.x())
1869                 layoutViewportOrigin.setX(stableLayoutViewportOriginMax.x());
1870         }
1871     } else {
1872         bool rubberbandingAtLeft = allowRubberBanding && visualViewport.x() < stableLayoutViewportOriginMin.x();
1873         bool rubberbandingAtRight = allowRubberBanding && (visualViewport.maxX() - layoutViewport.width()) > stableLayoutViewportOriginMax.x();
1874
1875         if (visualViewport.x() < layoutViewport.x() || rubberbandingAtLeft)
1876             layoutViewportOrigin.setX(visualViewport.x());
1877
1878         if (visualViewport.maxX() > layoutViewport.maxX() || rubberbandingAtRight)
1879             layoutViewportOrigin.setX(visualViewport.maxX() - layoutViewport.width());
1880
1881         if (!rubberbandingAtLeft && layoutViewportOrigin.x() < stableLayoutViewportOriginMin.x())
1882             layoutViewportOrigin.setX(stableLayoutViewportOriginMin.x());
1883         
1884         if (!rubberbandingAtRight && layoutViewportOrigin.x() > stableLayoutViewportOriginMax.x())
1885             layoutViewportOrigin.setX(stableLayoutViewportOriginMax.x());
1886     }
1887
1888     if (visualViewport.height() > layoutViewport.height()) {
1889         layoutViewportOrigin.setY(visualViewport.y());
1890         if (!allowRubberBanding) {
1891             if (layoutViewportOrigin.y() < stableLayoutViewportOriginMin.y())
1892                 layoutViewportOrigin.setY(stableLayoutViewportOriginMin.y());
1893             else if (layoutViewportOrigin.y() > stableLayoutViewportOriginMax.y())
1894                 layoutViewportOrigin.setY(stableLayoutViewportOriginMax.y());
1895         }
1896     } else {
1897         bool rubberbandingAtTop = allowRubberBanding && visualViewport.y() < stableLayoutViewportOriginMin.y();
1898         bool rubberbandingAtBottom = allowRubberBanding && (visualViewport.maxY() - layoutViewport.height()) > stableLayoutViewportOriginMax.y();
1899
1900         if (visualViewport.y() < layoutViewport.y() || rubberbandingAtTop)
1901             layoutViewportOrigin.setY(visualViewport.y());
1902
1903         if (visualViewport.maxY() > layoutViewport.maxY() || rubberbandingAtBottom)
1904             layoutViewportOrigin.setY(visualViewport.maxY() - layoutViewport.height());
1905
1906         if (!rubberbandingAtTop && layoutViewportOrigin.y() < stableLayoutViewportOriginMin.y())
1907             layoutViewportOrigin.setY(stableLayoutViewportOriginMin.y());
1908
1909         if (!rubberbandingAtBottom && layoutViewportOrigin.y() > stableLayoutViewportOriginMax.y())
1910             layoutViewportOrigin.setY(stableLayoutViewportOriginMax.y());
1911     }
1912
1913     return layoutViewportOrigin;
1914 }
1915
1916 void FrameView::setBaseLayoutViewportOrigin(LayoutPoint origin, TriggerLayoutOrNot layoutTriggering)
1917 {
1918     ASSERT(frame().settings().visualViewportEnabled());
1919
1920     if (origin == m_layoutViewportOrigin)
1921         return;
1922
1923     m_layoutViewportOrigin = origin;
1924     if (layoutTriggering == TriggerLayoutOrNot::Yes)
1925         setViewportConstrainedObjectsNeedLayout();
1926     
1927     if (TiledBacking* tiledBacking = this->tiledBacking()) {
1928         FloatRect layoutViewport = layoutViewportRect();
1929         layoutViewport.moveBy(unscaledScrollOrigin()); // tiledBacking deals in top-left relative coordinates.
1930         tiledBacking->setLayoutViewportRect(layoutViewport);
1931     }
1932 }
1933
1934 void FrameView::setLayoutViewportOverrideRect(std::optional<LayoutRect> rect, TriggerLayoutOrNot layoutTriggering)
1935 {
1936     if (rect == m_layoutViewportOverrideRect)
1937         return;
1938
1939     LayoutRect oldRect = layoutViewportRect();
1940     m_layoutViewportOverrideRect = rect;
1941
1942     // Triggering layout on height changes is necessary to make bottom-fixed elements behave correctly.
1943     if (oldRect.height() != layoutViewportRect().height())
1944         layoutTriggering = TriggerLayoutOrNot::Yes;
1945
1946     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"));
1947
1948     if (oldRect != layoutViewportRect() && layoutTriggering == TriggerLayoutOrNot::Yes)
1949         setViewportConstrainedObjectsNeedLayout();
1950 }
1951
1952 LayoutSize FrameView::baseLayoutViewportSize() const
1953 {
1954     return renderView() ? renderView()->size() : size();
1955 }
1956
1957 void FrameView::updateLayoutViewport()
1958 {
1959     if (!frame().settings().visualViewportEnabled())
1960         return;
1961     
1962     // Don't update the layout viewport if we're in the middle of adjusting scrollbars. We'll get another call
1963     // as a post-layout task.
1964     if (m_layoutPhase == InViewSizeAdjust)
1965         return;
1966
1967     LayoutRect layoutViewport = layoutViewportRect();
1968
1969     LOG_WITH_STREAM(Scrolling, stream << "\nFrameView " << this << " updateLayoutViewport() totalContentSize " << totalContentsSize() << " unscaledDocumentRect " << (renderView() ? renderView()->unscaledDocumentRect() : IntRect()) << " header height " << headerHeight() << " footer height " << footerHeight() << " fixed behavior " << scrollBehaviorForFixedElements());
1970     LOG_WITH_STREAM(Scrolling, stream << "layoutViewport: " << layoutViewport);
1971     LOG_WITH_STREAM(Scrolling, stream << "visualViewport: " << visualViewportRect());
1972     LOG_WITH_STREAM(Scrolling, stream << "stable origins: min: " << minStableLayoutViewportOrigin() << " max: "<< maxStableLayoutViewportOrigin());
1973     
1974     if (m_layoutViewportOverrideRect) {
1975         if (m_inProgrammaticScroll) {
1976             LayoutPoint newOrigin = computeLayoutViewportOrigin(visualViewportRect(), minStableLayoutViewportOrigin(), maxStableLayoutViewportOrigin(), layoutViewport, StickToDocumentBounds);
1977             setLayoutViewportOverrideRect(LayoutRect(newOrigin, m_layoutViewportOverrideRect.value().size()));
1978         }
1979         return;
1980     }
1981
1982     LayoutPoint newLayoutViewportOrigin = computeLayoutViewportOrigin(visualViewportRect(), minStableLayoutViewportOrigin(), maxStableLayoutViewportOrigin(), layoutViewport, scrollBehaviorForFixedElements());
1983     if (newLayoutViewportOrigin != m_layoutViewportOrigin) {
1984         setBaseLayoutViewportOrigin(newLayoutViewportOrigin);
1985         LOG_WITH_STREAM(Scrolling, stream << "layoutViewport changed to " << layoutViewportRect());
1986     }
1987 }
1988
1989 LayoutPoint FrameView::minStableLayoutViewportOrigin() const
1990 {
1991     return unscaledMinimumScrollPosition();
1992 }
1993
1994 LayoutPoint FrameView::maxStableLayoutViewportOrigin() const
1995 {
1996     LayoutPoint maxPosition = unscaledMaximumScrollPosition();
1997     maxPosition = (maxPosition - LayoutSize(0, headerHeight() + footerHeight())).expandedTo({ });
1998     return maxPosition;
1999 }
2000
2001 IntPoint FrameView::unscaledScrollOrigin() const
2002 {
2003     if (RenderView* renderView = this->renderView())
2004         return -renderView->unscaledDocumentRect().location(); // Akin to code in adjustViewSize().
2005
2006     return { };
2007 }
2008
2009 LayoutRect FrameView::layoutViewportRect() const
2010 {
2011     if (m_layoutViewportOverrideRect)
2012         return m_layoutViewportOverrideRect.value();
2013
2014     // Size of initial containing block, anchored at scroll position, in document coordinates (unchanged by scale factor).
2015     return LayoutRect(m_layoutViewportOrigin, baseLayoutViewportSize());
2016 }
2017
2018 // visibleContentRect is in the bounds of the scroll view content. That consists of an
2019 // optional header, the document, and an optional footer. Only the document is scaled,
2020 // so we have to compute the visible part of the document in unscaled document coordinates.
2021 // On iOS, pageScaleFactor is always 1 here, and we never have headers and footers.
2022 LayoutRect FrameView::visibleDocumentRect(const FloatRect& visibleContentRect, float headerHeight, float footerHeight, const FloatSize& totalContentsSize, float pageScaleFactor)
2023 {
2024     float contentsHeight = totalContentsSize.height() - headerHeight - footerHeight;
2025
2026     float rubberBandTop = std::min<float>(visibleContentRect.y(), 0);
2027     float visibleScaledDocumentTop = std::max<float>(visibleContentRect.y() - headerHeight, 0) + rubberBandTop;
2028     
2029     float rubberBandBottom = std::min<float>((totalContentsSize.height() - visibleContentRect.y()) - visibleContentRect.height(), 0);
2030     float visibleScaledDocumentBottom = std::min<float>(visibleContentRect.maxY() - headerHeight, contentsHeight) - rubberBandBottom;
2031
2032     FloatRect visibleDocumentRect = visibleContentRect;
2033     visibleDocumentRect.setY(visibleScaledDocumentTop);
2034     visibleDocumentRect.setHeight(std::max<float>(visibleScaledDocumentBottom - visibleScaledDocumentTop, 0));
2035     visibleDocumentRect.scale(1 / pageScaleFactor);
2036     
2037     return LayoutRect(visibleDocumentRect);
2038 }
2039
2040 LayoutRect FrameView::visualViewportRect() const
2041 {
2042     FloatRect visibleContentRect = this->visibleContentRect(LegacyIOSDocumentVisibleRect);
2043     return visibleDocumentRect(visibleContentRect, headerHeight(), footerHeight(), totalContentsSize(), frameScaleFactor());
2044 }
2045
2046 LayoutRect FrameView::viewportConstrainedVisibleContentRect() const
2047 {
2048     ASSERT(!frame().settings().visualViewportEnabled());
2049
2050 #if PLATFORM(IOS)
2051     if (useCustomFixedPositionLayoutRect())
2052         return customFixedPositionLayoutRect();
2053 #endif
2054     LayoutRect viewportRect = visibleContentRect();
2055
2056     viewportRect.setLocation(scrollPositionForFixedPosition());
2057     return viewportRect;
2058 }
2059
2060 LayoutRect FrameView::rectForFixedPositionLayout() const
2061 {
2062     if (frame().settings().visualViewportEnabled())
2063         return layoutViewportRect();
2064
2065     return viewportConstrainedVisibleContentRect();
2066 }
2067
2068 float FrameView::frameScaleFactor() const
2069 {
2070     return frame().frameScaleFactor();
2071 }
2072
2073 LayoutPoint FrameView::scrollPositionForFixedPosition() const
2074 {
2075     if (frame().settings().visualViewportEnabled())
2076         return layoutViewportRect().location();
2077
2078     return scrollPositionForFixedPosition(visibleContentRect(), totalContentsSize(), scrollPosition(), scrollOrigin(), frameScaleFactor(), fixedElementsLayoutRelativeToFrame(), scrollBehaviorForFixedElements(), headerHeight(), footerHeight());
2079 }
2080
2081 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)
2082 {
2083     LayoutPoint position;
2084     if (behaviorForFixed == StickToDocumentBounds)
2085         position = ScrollableArea::constrainScrollPositionForOverhang(visibleContentRect, totalContentsSize, scrollPosition, scrollOrigin, headerHeight, footerHeight);
2086     else {
2087         position = scrollPosition;
2088         position.setY(position.y() - headerHeight);
2089     }
2090
2091     LayoutSize maxSize = totalContentsSize - visibleContentRect.size();
2092
2093     float dragFactorX = (fixedElementsLayoutRelativeToFrame || !maxSize.width()) ? 1 : (totalContentsSize.width() - visibleContentRect.width() * frameScaleFactor) / maxSize.width();
2094     float dragFactorY = (fixedElementsLayoutRelativeToFrame || !maxSize.height()) ? 1 : (totalContentsSize.height() - visibleContentRect.height() * frameScaleFactor) / maxSize.height();
2095
2096     return LayoutPoint(position.x() * dragFactorX / frameScaleFactor, position.y() * dragFactorY / frameScaleFactor);
2097 }
2098
2099 float FrameView::yPositionForInsetClipLayer(const FloatPoint& scrollPosition, float topContentInset)
2100 {
2101     if (!topContentInset)
2102         return 0;
2103
2104     // The insetClipLayer should not move for negative scroll values.
2105     float scrollY = std::max<float>(0, scrollPosition.y());
2106
2107     if (scrollY >= topContentInset)
2108         return 0;
2109
2110     return topContentInset - scrollY;
2111 }
2112
2113 float FrameView::yPositionForHeaderLayer(const FloatPoint& scrollPosition, float topContentInset)
2114 {
2115     if (!topContentInset)
2116         return 0;
2117
2118     float scrollY = std::max<float>(0, scrollPosition.y());
2119
2120     if (scrollY >= topContentInset)
2121         return topContentInset;
2122
2123     return scrollY;
2124 }
2125
2126 float FrameView::yPositionForFooterLayer(const FloatPoint& scrollPosition, float topContentInset, float totalContentsHeight, float footerHeight)
2127 {
2128     return yPositionForHeaderLayer(scrollPosition, topContentInset) + totalContentsHeight - footerHeight;
2129 }
2130
2131 FloatPoint FrameView::positionForRootContentLayer(const FloatPoint& scrollPosition, const FloatPoint& scrollOrigin, float topContentInset, float headerHeight)
2132 {
2133     return FloatPoint(0, yPositionForHeaderLayer(scrollPosition, topContentInset) + headerHeight) - toFloatSize(scrollOrigin);
2134 }
2135
2136 FloatPoint FrameView::positionForRootContentLayer() const
2137 {
2138     return positionForRootContentLayer(scrollPosition(), scrollOrigin(), topContentInset(), headerHeight());
2139 }
2140
2141 #if PLATFORM(IOS)
2142 LayoutRect FrameView::rectForViewportConstrainedObjects(const LayoutRect& visibleContentRect, const LayoutSize& totalContentsSize, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements scrollBehavior)
2143 {
2144     if (fixedElementsLayoutRelativeToFrame)
2145         return visibleContentRect;
2146     
2147     if (totalContentsSize.isEmpty())
2148         return visibleContentRect;
2149
2150     // We impose an lower limit on the size (so an upper limit on the scale) of
2151     // the rect used to position fixed objects so that they don't crowd into the
2152     // center of the screen at larger scales.
2153     const LayoutUnit maxContentWidthForZoomThreshold = LayoutUnit::fromPixel(1024);
2154     float zoomedOutScale = frameScaleFactor * visibleContentRect.width() / std::min(maxContentWidthForZoomThreshold, totalContentsSize.width());
2155     float constraintThresholdScale = 1.5 * zoomedOutScale;
2156     float maxPostionedObjectsRectScale = std::min(frameScaleFactor, constraintThresholdScale);
2157
2158     LayoutRect viewportConstrainedObjectsRect = visibleContentRect;
2159
2160     if (frameScaleFactor > constraintThresholdScale) {
2161         FloatRect contentRect(FloatPoint(), totalContentsSize);
2162         FloatRect viewportRect = visibleContentRect;
2163         
2164         // Scale the rect up from a point that is relative to its position in the viewport.
2165         FloatSize sizeDelta = contentRect.size() - viewportRect.size();
2166
2167         FloatPoint scaleOrigin;
2168         scaleOrigin.setX(contentRect.x() + sizeDelta.width() > 0 ? contentRect.width() * (viewportRect.x() - contentRect.x()) / sizeDelta.width() : 0);
2169         scaleOrigin.setY(contentRect.y() + sizeDelta.height() > 0 ? contentRect.height() * (viewportRect.y() - contentRect.y()) / sizeDelta.height() : 0);
2170         
2171         AffineTransform rescaleTransform = AffineTransform::translation(scaleOrigin.x(), scaleOrigin.y());
2172         rescaleTransform.scale(frameScaleFactor / maxPostionedObjectsRectScale, frameScaleFactor / maxPostionedObjectsRectScale);
2173         rescaleTransform = CGAffineTransformTranslate(rescaleTransform, -scaleOrigin.x(), -scaleOrigin.y());
2174
2175         viewportConstrainedObjectsRect = enclosingLayoutRect(rescaleTransform.mapRect(visibleContentRect));
2176     }
2177     
2178     if (scrollBehavior == StickToDocumentBounds) {
2179         LayoutRect documentBounds(LayoutPoint(), totalContentsSize);
2180         viewportConstrainedObjectsRect.intersect(documentBounds);
2181     }
2182
2183     return viewportConstrainedObjectsRect;
2184 }
2185     
2186 LayoutRect FrameView::viewportConstrainedObjectsRect() const
2187 {
2188     return rectForViewportConstrainedObjects(visibleContentRect(), totalContentsSize(), frame().frameScaleFactor(), fixedElementsLayoutRelativeToFrame(), scrollBehaviorForFixedElements());
2189 }
2190 #endif
2191     
2192 ScrollPosition FrameView::minimumScrollPosition() const
2193 {
2194     ScrollPosition minimumPosition = ScrollView::minimumScrollPosition();
2195
2196     if (frame().isMainFrame() && m_scrollPinningBehavior == PinToBottom)
2197         minimumPosition.setY(maximumScrollPosition().y());
2198     
2199     return minimumPosition;
2200 }
2201
2202 ScrollPosition FrameView::maximumScrollPosition() const
2203 {
2204     ScrollPosition maximumPosition = ScrollView::maximumScrollPosition();
2205
2206     if (frame().isMainFrame() && m_scrollPinningBehavior == PinToTop)
2207         maximumPosition.setY(minimumScrollPosition().y());
2208     
2209     return maximumPosition;
2210 }
2211
2212 ScrollPosition FrameView::unscaledMinimumScrollPosition() const
2213 {
2214     if (RenderView* renderView = this->renderView()) {
2215         IntRect unscaledDocumentRect = renderView->unscaledDocumentRect();
2216         ScrollPosition minimumPosition = unscaledDocumentRect.location();
2217
2218         if (frame().isMainFrame() && m_scrollPinningBehavior == PinToBottom)
2219             minimumPosition.setY(unscaledMaximumScrollPosition().y());
2220
2221         return minimumPosition;
2222     }
2223
2224     return minimumScrollPosition();
2225 }
2226
2227 ScrollPosition FrameView::unscaledMaximumScrollPosition() const
2228 {
2229     if (RenderView* renderView = this->renderView()) {
2230         IntRect unscaledDocumentRect = renderView->unscaledDocumentRect();
2231         unscaledDocumentRect.expand(0, headerHeight() + footerHeight());
2232         IntSize visibleSize = this->visibleSize();
2233 #if PLATFORM(IOS)
2234         // FIXME: visibleSize() is the unscaled size on macOS, but the scaled size on iOS. This should be consistent. webkit.org/b/174648.
2235         visibleSize.scale(visibleContentScaleFactor());
2236 #endif        
2237         ScrollPosition maximumPosition = ScrollPosition(unscaledDocumentRect.maxXMaxYCorner() - visibleSize).expandedTo({ 0, 0 });
2238         if (frame().isMainFrame() && m_scrollPinningBehavior == PinToTop)
2239             maximumPosition.setY(unscaledMinimumScrollPosition().y());
2240
2241         return maximumPosition;
2242     }
2243
2244     return maximumScrollPosition();
2245 }
2246
2247 void FrameView::viewportContentsChanged()
2248 {
2249     if (!frame().view()) {
2250         // The frame is being destroyed.
2251         return;
2252     }
2253
2254     if (auto* page = frame().page())
2255         page->updateValidationBubbleStateIfNeeded();
2256
2257     // When the viewport contents changes (scroll, resize, style recalc, layout, ...),
2258     // check if we should resume animated images or unthrottle DOM timers.
2259     applyRecursivelyWithVisibleRect([] (FrameView& frameView, const IntRect& visibleRect) {
2260         frameView.resumeVisibleImageAnimations(visibleRect);
2261         frameView.updateScriptedAnimationsAndTimersThrottlingState(visibleRect);
2262
2263         if (auto* renderView = frameView.frame().contentRenderer())
2264             renderView->updateVisibleViewportRect(visibleRect);
2265     });
2266 }
2267
2268 bool FrameView::fixedElementsLayoutRelativeToFrame() const
2269 {
2270     return frame().settings().fixedElementsLayoutRelativeToFrame();
2271 }
2272
2273 IntPoint FrameView::lastKnownMousePosition() const
2274 {
2275     return frame().eventHandler().lastKnownMousePosition();
2276 }
2277
2278 bool FrameView::isHandlingWheelEvent() const
2279 {
2280     return frame().eventHandler().isHandlingWheelEvent();
2281 }
2282
2283 bool FrameView::shouldSetCursor() const
2284 {
2285     Page* page = frame().page();
2286     return page && page->isVisible() && page->focusController().isActive();
2287 }
2288
2289 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
2290 {
2291     if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty()) {
2292         frame().page()->chrome().scroll(scrollDelta, rectToScroll, clipRect);
2293         return true;
2294     }
2295
2296     bool isCompositedContentLayer = usesCompositedScrolling();
2297
2298     // Get the rects of the fixed objects visible in the rectToScroll
2299     Region regionToUpdate;
2300     for (auto& renderer : *m_viewportConstrainedObjects) {
2301         if (!renderer->style().hasViewportConstrainedPosition())
2302             continue;
2303         if (renderer->isComposited())
2304             continue;
2305
2306         // Fixed items should always have layers.
2307         ASSERT(renderer->hasLayer());
2308         RenderLayer* layer = downcast<RenderBoxModelObject>(*renderer).layer();
2309
2310         if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForBoundsOutOfView
2311             || layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForNoVisibleContent) {
2312             // Don't invalidate for invisible fixed layers.
2313             continue;
2314         }
2315
2316         if (layer->hasAncestorWithFilterOutsets()) {
2317             // If the fixed layer has a blur/drop-shadow filter applied on at least one of its parents, we cannot 
2318             // scroll using the fast path, otherwise the outsets of the filter will be moved around the page.
2319             return false;
2320         }
2321
2322         // FIXME: use pixel snapping instead of enclosing when ScrollView has finished transitioning from IntRect to Float/LayoutRect.
2323         IntRect updateRect = enclosingIntRect(layer->repaintRectIncludingNonCompositingDescendants());
2324         updateRect = contentsToRootView(updateRect);
2325         if (!isCompositedContentLayer)
2326             updateRect.intersect(rectToScroll);
2327         if (!updateRect.isEmpty())
2328             regionToUpdate.unite(updateRect);
2329     }
2330
2331     // 1) scroll
2332     frame().page()->chrome().scroll(scrollDelta, rectToScroll, clipRect);
2333
2334     // 2) update the area of fixed objects that has been invalidated
2335     for (auto& updateRect : regionToUpdate.rects()) {
2336         IntRect scrolledRect = updateRect;
2337         scrolledRect.move(scrollDelta);
2338         updateRect.unite(scrolledRect);
2339         if (isCompositedContentLayer) {
2340             updateRect = rootViewToContents(updateRect);
2341             ASSERT(renderView());
2342             renderView()->layer()->setBackingNeedsRepaintInRect(updateRect);
2343             continue;
2344         }
2345         updateRect.intersect(rectToScroll);
2346         frame().page()->chrome().invalidateContentsAndRootView(updateRect);
2347     }
2348
2349     return true;
2350 }
2351
2352 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
2353 {
2354     repaintSlowRepaintObjects();
2355
2356     if (!usesCompositedScrolling() && isEnclosedInCompositingLayer()) {
2357         if (RenderWidget* frameRenderer = frame().ownerRenderer()) {
2358             LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(), frameRenderer->borderTop() + frameRenderer->paddingTop(),
2359                 visibleWidth(), visibleHeight());
2360             frameRenderer->repaintRectangle(rect);
2361             return;
2362         }
2363     }
2364
2365     ScrollView::scrollContentsSlowPath(updateRect);
2366 }
2367
2368 void FrameView::repaintSlowRepaintObjects()
2369 {
2370     if (!m_slowRepaintObjects)
2371         return;
2372
2373     // Renderers with fixed backgrounds may be in compositing layers, so we need to explicitly
2374     // repaint them after scrolling.
2375     for (auto& renderer : *m_slowRepaintObjects)
2376         renderer->repaintSlowRepaintObject();
2377 }
2378
2379 // Note that this gets called at painting time.
2380 void FrameView::setIsOverlapped(bool isOverlapped)
2381 {
2382     if (isOverlapped == m_isOverlapped)
2383         return;
2384
2385     m_isOverlapped = isOverlapped;
2386     updateCanBlitOnScrollRecursively();
2387 }
2388
2389 void FrameView::setContentIsOpaque(bool contentIsOpaque)
2390 {
2391     if (contentIsOpaque == m_contentIsOpaque)
2392         return;
2393
2394     m_contentIsOpaque = contentIsOpaque;
2395     updateCanBlitOnScrollRecursively();
2396 }
2397
2398 void FrameView::restoreScrollbar()
2399 {
2400     setScrollbarsSuppressed(false);
2401 }
2402
2403 bool FrameView::scrollToFragment(const URL& url)
2404 {
2405     // If our URL has no ref, then we have no place we need to jump to.
2406     // OTOH If CSS target was set previously, we want to set it to 0, recalc
2407     // and possibly repaint because :target pseudo class may have been
2408     // set (see bug 11321).
2409     if (!url.hasFragmentIdentifier()) {
2410         frame().document()->setCSSTarget(nullptr);
2411         return false;
2412     }
2413
2414     String fragmentIdentifier = url.fragmentIdentifier();
2415     if (scrollToAnchor(fragmentIdentifier))
2416         return true;
2417
2418     // Try again after decoding the ref, based on the document's encoding.
2419     if (TextResourceDecoder* decoder = frame().document()->decoder())
2420         return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding()));
2421
2422     return false;
2423 }
2424
2425 bool FrameView::scrollToAnchor(const String& name)
2426 {
2427     ASSERT(frame().document());
2428     auto& document = *frame().document();
2429
2430     if (!document.haveStylesheetsLoaded()) {
2431         document.setGotoAnchorNeededAfterStylesheetsLoad(true);
2432         return false;
2433     }
2434
2435     document.setGotoAnchorNeededAfterStylesheetsLoad(false);
2436
2437     Element* anchorElement = document.findAnchor(name);
2438
2439     // Setting to null will clear the current target.
2440     document.setCSSTarget(anchorElement);
2441
2442     if (is<SVGDocument>(document)) {
2443         if (auto* rootElement = SVGDocument::rootElement(document)) {
2444             rootElement->scrollToAnchor(name, anchorElement);
2445             if (!anchorElement)
2446                 return true;
2447         }
2448     }
2449
2450     // Implement the rule that "" and "top" both mean top of page as in other browsers.
2451     if (!anchorElement && !(name.isEmpty() || equalLettersIgnoringASCIICase(name, "top")))
2452         return false;
2453
2454     ContainerNode* scrollPositionAnchor = anchorElement;
2455     if (!scrollPositionAnchor)
2456         scrollPositionAnchor = frame().document();
2457     maintainScrollPositionAtAnchor(scrollPositionAnchor);
2458     
2459     // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
2460     if (anchorElement) {
2461         if (anchorElement->isFocusable())
2462             document.setFocusedElement(anchorElement);
2463         else {
2464             document.setFocusedElement(nullptr);
2465             document.setFocusNavigationStartingNode(anchorElement);
2466         }
2467     }
2468     
2469     return true;
2470 }
2471
2472 void FrameView::maintainScrollPositionAtAnchor(ContainerNode* anchorNode)
2473 {
2474     m_maintainScrollPositionAnchor = anchorNode;
2475     if (!m_maintainScrollPositionAnchor)
2476         return;
2477
2478     // We need to update the layout before scrolling, otherwise we could
2479     // really mess things up if an anchor scroll comes at a bad moment.
2480     frame().document()->updateStyleIfNeeded();
2481     // Only do a layout if changes have occurred that make it necessary.
2482     RenderView* renderView = this->renderView();
2483     if (renderView && renderView->needsLayout())
2484         layout();
2485     else
2486         scrollToAnchor();
2487 }
2488
2489 void FrameView::scrollElementToRect(const Element& element, const IntRect& rect)
2490 {
2491     frame().document()->updateLayoutIgnorePendingStylesheets();
2492
2493     LayoutRect bounds;
2494     if (RenderElement* renderer = element.renderer())
2495         bounds = renderer->absoluteAnchorRect();
2496     int centeringOffsetX = (rect.width() - bounds.width()) / 2;
2497     int centeringOffsetY = (rect.height() - bounds.height()) / 2;
2498     setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y()));
2499 }
2500
2501 void FrameView::setScrollPosition(const ScrollPosition& scrollPosition)
2502 {
2503     SetForScope<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
2504     m_maintainScrollPositionAnchor = nullptr;
2505     Page* page = frame().page();
2506     if (page && page->expectsWheelEventTriggers())
2507         scrollAnimator().setWheelEventTestTrigger(page->testTrigger());
2508     ScrollView::setScrollPosition(scrollPosition);
2509 }
2510
2511 void FrameView::contentsResized()
2512 {
2513     // For non-delegated scrolling, updateTiledBackingAdaptiveSizing() is called via addedOrRemovedScrollbar() which occurs less often.
2514     if (delegatesScrolling())
2515         updateTiledBackingAdaptiveSizing();
2516 }
2517
2518 void FrameView::delegatesScrollingDidChange()
2519 {
2520     // When we switch to delgatesScrolling mode, we should destroy the scrolling/clipping layers in RenderLayerCompositor.
2521     if (hasCompositedContent())
2522         clearBackingStores();
2523 }
2524
2525 #if USE(COORDINATED_GRAPHICS)
2526 void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect)
2527 {
2528     bool visibleContentSizeDidChange = false;
2529     if (visibleContentRect.size() != this->fixedVisibleContentRect().size()) {
2530         // When the viewport size changes or the content is scaled, we need to
2531         // reposition the fixed and sticky positioned elements.
2532         setViewportConstrainedObjectsNeedLayout();
2533         visibleContentSizeDidChange = true;
2534     }
2535
2536     IntPoint oldPosition = scrollPosition();
2537     ScrollView::setFixedVisibleContentRect(visibleContentRect);
2538     IntPoint newPosition = scrollPosition();
2539     if (oldPosition != newPosition) {
2540         updateLayerPositionsAfterScrolling();
2541         if (frame().settings().acceleratedCompositingForFixedPositionEnabled())
2542             updateCompositingLayersAfterScrolling();
2543         scrollAnimator().setCurrentPosition(newPosition);
2544         scrollPositionChanged(oldPosition, newPosition);
2545     }
2546     if (visibleContentSizeDidChange) {
2547         // Update the scroll-bars to calculate new page-step size.
2548         updateScrollbars(scrollPosition());
2549     }
2550     didChangeScrollOffset();
2551 }
2552 #endif
2553
2554 void FrameView::setViewportConstrainedObjectsNeedLayout()
2555 {
2556     if (!hasViewportConstrainedObjects())
2557         return;
2558
2559     for (auto& renderer : *m_viewportConstrainedObjects)
2560         renderer->setNeedsLayout();
2561 }
2562
2563 void FrameView::didChangeScrollOffset()
2564 {
2565     frame().mainFrame().pageOverlayController().didScrollFrame(frame());
2566     frame().loader().client().didChangeScrollOffset();
2567 }
2568
2569 void FrameView::scrollOffsetChangedViaPlatformWidgetImpl(const ScrollOffset& oldOffset, const ScrollOffset& newOffset)
2570 {
2571     updateLayerPositionsAfterScrolling();
2572     updateCompositingLayersAfterScrolling();
2573     repaintSlowRepaintObjects();
2574     scrollPositionChanged(scrollPositionFromOffset(oldOffset), scrollPositionFromOffset(newOffset));
2575 }
2576
2577 // These scroll positions are affected by zooming.
2578 void FrameView::scrollPositionChanged(const ScrollPosition& oldPosition, const ScrollPosition& newPosition)
2579 {
2580     UNUSED_PARAM(oldPosition);
2581     UNUSED_PARAM(newPosition);
2582
2583     Page* page = frame().page();
2584     Seconds throttlingDelay = page ? page->chrome().client().eventThrottlingDelay() : 0_s;
2585
2586     if (throttlingDelay == 0_s) {
2587         m_delayedScrollEventTimer.stop();
2588         sendScrollEvent();
2589     } else if (!m_delayedScrollEventTimer.isActive())
2590         m_delayedScrollEventTimer.startOneShot(throttlingDelay);
2591
2592     if (RenderView* renderView = this->renderView()) {
2593         if (renderView->usesCompositing())
2594             renderView->compositor().frameViewDidScroll();
2595     }
2596
2597     LOG_WITH_STREAM(Scrolling, stream << "FrameView " << this << " scrollPositionChanged from " << oldPosition << " to " << newPosition << " (scale " << frameScaleFactor() << " )");
2598     updateLayoutViewport();
2599     viewportContentsChanged();
2600 }
2601
2602 void FrameView::applyRecursivelyWithVisibleRect(const WTF::Function<void (FrameView& frameView, const IntRect& visibleRect)>& apply)
2603 {
2604     IntRect windowClipRect = this->windowClipRect();
2605     auto visibleRect = windowToContents(windowClipRect);
2606     apply(*this, visibleRect);
2607
2608     // Recursive call for subframes. We cache the current FrameView's windowClipRect to avoid recomputing it for every subframe.
2609     SetForScope<IntRect*> windowClipRectCache(m_cachedWindowClipRect, &windowClipRect);
2610     for (Frame* childFrame = frame().tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling()) {
2611         if (auto* childView = childFrame->view())
2612             childView->applyRecursivelyWithVisibleRect(apply);
2613     }
2614 }
2615
2616 void FrameView::resumeVisibleImageAnimations(const IntRect& visibleRect)
2617 {
2618     if (visibleRect.isEmpty())
2619         return;
2620
2621     if (auto* renderView = frame().contentRenderer())
2622         renderView->resumePausedImageAnimationsIfNeeded(visibleRect);
2623 }
2624
2625 void FrameView::updateScriptedAnimationsAndTimersThrottlingState(const IntRect& visibleRect)
2626 {
2627     if (frame().isMainFrame())
2628         return;
2629
2630     auto* document = frame().document();
2631     if (!document)
2632         return;
2633
2634     // We don't throttle zero-size or display:none frames because those are usually utility frames.
2635     bool shouldThrottle = visibleRect.isEmpty() && !m_size.isEmpty() && frame().ownerRenderer();
2636
2637     if (auto* scriptedAnimationController = document->scriptedAnimationController()) {
2638         if (shouldThrottle)
2639             scriptedAnimationController->addThrottlingReason(ScriptedAnimationController::ThrottlingReason::OutsideViewport);
2640         else
2641             scriptedAnimationController->removeThrottlingReason(ScriptedAnimationController::ThrottlingReason::OutsideViewport);
2642     }
2643
2644     document->setTimerThrottlingEnabled(shouldThrottle);
2645 }
2646
2647
2648 void FrameView::resumeVisibleImageAnimationsIncludingSubframes()
2649 {
2650     applyRecursivelyWithVisibleRect([] (FrameView& frameView, const IntRect& visibleRect) {
2651         frameView.resumeVisibleImageAnimations(visibleRect);
2652     });
2653 }
2654
2655 void FrameView::updateLayerPositionsAfterScrolling()
2656 {
2657     // If we're scrolling as a result of updating the view size after layout, we'll update widgets and layer positions soon anyway.
2658     if (m_layoutPhase == InViewSizeAdjust)
2659         return;
2660
2661     if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) {
2662         if (RenderView* renderView = this->renderView()) {
2663             updateWidgetPositions();
2664             renderView->layer()->updateLayerPositionsAfterDocumentScroll();
2665         }
2666     }
2667 }
2668
2669 bool FrameView::shouldUpdateCompositingLayersAfterScrolling() const
2670 {
2671 #if ENABLE(ASYNC_SCROLLING)
2672     // If the scrolling thread is updating the fixed elements, then the FrameView should not update them as well.
2673
2674     Page* page = frame().page();
2675     if (!page)
2676         return true;
2677
2678     if (&page->mainFrame() != m_frame.ptr())
2679         return true;
2680
2681     ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
2682     if (!scrollingCoordinator)
2683         return true;
2684
2685     if (scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously(*this))
2686         return true;
2687
2688     if (inProgrammaticScroll())
2689         return true;
2690
2691     return false;
2692 #endif
2693     return true;
2694 }
2695
2696 void FrameView::updateCompositingLayersAfterScrolling()
2697 {
2698     ASSERT(m_layoutPhase >= InPostLayout || m_layoutPhase == OutsideLayout);
2699
2700     if (!shouldUpdateCompositingLayersAfterScrolling())
2701         return;
2702
2703     if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) {
2704         if (RenderView* renderView = this->renderView())
2705             renderView->compositor().updateCompositingLayers(CompositingUpdateType::OnScroll);
2706     }
2707 }
2708
2709 bool FrameView::isRubberBandInProgress() const
2710 {
2711     if (scrollbarsSuppressed())
2712         return false;
2713
2714     // If the scrolling thread updates the scroll position for this FrameView, then we should return
2715     // ScrollingCoordinator::isRubberBandInProgress().
2716     if (Page* page = frame().page()) {
2717         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
2718             if (!scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously(*this))
2719                 return scrollingCoordinator->isRubberBandInProgress();
2720         }
2721     }
2722
2723     // If the main thread updates the scroll position for this FrameView, we should return
2724     // ScrollAnimator::isRubberBandInProgress().
2725     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
2726         return scrollAnimator->isRubberBandInProgress();
2727
2728     return false;
2729 }
2730
2731 bool FrameView::requestScrollPositionUpdate(const ScrollPosition& position)
2732 {
2733     LOG_WITH_STREAM(Scrolling, stream << "FrameView::requestScrollPositionUpdate " << position);
2734
2735 #if ENABLE(ASYNC_SCROLLING)
2736     if (TiledBacking* tiledBacking = this->tiledBacking())
2737         tiledBacking->prepopulateRect(FloatRect(position, visibleContentRect().size()));
2738 #endif
2739
2740 #if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
2741     if (Page* page = frame().page()) {
2742         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
2743             return scrollingCoordinator->requestScrollPositionUpdate(*this, position);
2744     }
2745 #else
2746     UNUSED_PARAM(position);
2747 #endif
2748
2749     return false;
2750 }
2751
2752 HostWindow* FrameView::hostWindow() const
2753 {
2754     auto* page = frame().page();
2755     if (!page)
2756         return nullptr;
2757     return &page->chrome();
2758 }
2759
2760 void FrameView::addTrackedRepaintRect(const FloatRect& r)
2761 {
2762     if (!m_isTrackingRepaints || r.isEmpty())
2763         return;
2764
2765     FloatRect repaintRect = r;
2766     repaintRect.moveBy(-scrollPosition());
2767     m_trackedRepaintRects.append(repaintRect);
2768 }
2769
2770 void FrameView::repaintContentRectangle(const IntRect& r)
2771 {
2772     ASSERT(!frame().ownerElement());
2773
2774     if (!shouldUpdate())
2775         return;
2776
2777     ScrollView::repaintContentRectangle(r);
2778 }
2779
2780 static unsigned countRenderedCharactersInRenderObjectWithThreshold(const RenderElement& renderer, unsigned threshold)
2781 {
2782     unsigned count = 0;
2783     for (const RenderObject* descendant = &renderer; descendant; descendant = descendant->nextInPreOrder()) {
2784         if (is<RenderText>(*descendant)) {
2785             count += downcast<RenderText>(*descendant).text()->length();
2786             if (count >= threshold)
2787                 break;
2788         }
2789     }
2790     return count;
2791 }
2792
2793 bool FrameView::renderedCharactersExceed(unsigned threshold)
2794 {
2795     if (!frame().contentRenderer())
2796         return false;
2797     return countRenderedCharactersInRenderObjectWithThreshold(*frame().contentRenderer(), threshold) >= threshold;
2798 }
2799
2800 void FrameView::availableContentSizeChanged(AvailableSizeChangeReason reason)
2801 {
2802     if (Document* document = frame().document()) {
2803         // FIXME: Merge this logic with m_setNeedsLayoutWasDeferred and find a more appropriate
2804         // way of handling potential recursive layouts when the viewport is resized to accomodate
2805         // the content but the content always overflows the viewport. See webkit.org/b/165781.
2806         if (!(layoutPhase() == InViewSizeAdjust && useFixedLayout()))
2807             document->updateViewportUnitsOnResize();
2808     }
2809
2810     updateLayoutViewport();
2811     setNeedsLayout();
2812     ScrollView::availableContentSizeChanged(reason);
2813 }
2814
2815 bool FrameView::shouldLayoutAfterContentsResized() const
2816 {
2817     return !useFixedLayout() || useCustomFixedPositionLayoutRect();
2818 }
2819
2820 void FrameView::updateContentsSize()
2821 {
2822     // We check to make sure the view is attached to a frame() as this method can
2823     // be triggered before the view is attached by Frame::createView(...) setting
2824     // various values such as setScrollBarModes(...) for example.  An ASSERT is
2825     // triggered when a view is layout before being attached to a frame().
2826     if (!frame().view())
2827         return;
2828
2829 #if PLATFORM(IOS)
2830     if (RenderView* root = m_frame->contentRenderer()) {
2831         if (useCustomFixedPositionLayoutRect() && hasViewportConstrainedObjects()) {
2832             setViewportConstrainedObjectsNeedLayout();
2833             // We must eagerly enter compositing mode because fixed position elements
2834             // will not have been made compositing via a preceding style change before
2835             // m_useCustomFixedPositionLayoutRect was true.
2836             root->compositor().enableCompositingMode();
2837         }
2838     }
2839 #endif
2840
2841     if (shouldLayoutAfterContentsResized() && needsLayout())
2842         layout();
2843
2844     if (RenderView* renderView = this->renderView()) {
2845         if (renderView->usesCompositing())
2846             renderView->compositor().frameViewDidChangeSize();
2847     }
2848 }
2849
2850 void FrameView::addedOrRemovedScrollbar()
2851 {
2852     if (RenderView* renderView = this->renderView()) {
2853         if (renderView->usesCompositing())
2854             renderView->compositor().frameViewDidAddOrRemoveScrollbars();
2855     }
2856
2857     updateTiledBackingAdaptiveSizing();
2858 }
2859
2860 TiledBacking::Scrollability FrameView::computeScrollability() const
2861 {
2862     auto* page = frame().page();
2863
2864     // Use smaller square tiles if the Window is not active to facilitate app napping.
2865     if (!page || !page->isWindowActive())
2866         return TiledBacking::HorizontallyScrollable | TiledBacking::VerticallyScrollable;
2867
2868     bool horizontallyScrollable;
2869     bool verticallyScrollable;
2870     bool clippedByAncestorView = static_cast<bool>(m_viewExposedRect);
2871
2872 #if PLATFORM(IOS)
2873     if (page)
2874         clippedByAncestorView |= page->enclosedInScrollableAncestorView();
2875 #endif
2876
2877     if (delegatesScrolling()) {
2878         IntSize documentSize = contentsSize();
2879         IntSize visibleSize = this->visibleSize();
2880
2881         horizontallyScrollable = clippedByAncestorView || documentSize.width() > visibleSize.width();
2882         verticallyScrollable = clippedByAncestorView || documentSize.height() > visibleSize.height();
2883     } else {
2884         horizontallyScrollable = clippedByAncestorView || horizontalScrollbar();
2885         verticallyScrollable = clippedByAncestorView || verticalScrollbar();
2886     }
2887
2888     TiledBacking::Scrollability scrollability = TiledBacking::NotScrollable;
2889     if (horizontallyScrollable)
2890         scrollability = TiledBacking::HorizontallyScrollable;
2891
2892     if (verticallyScrollable)
2893         scrollability |= TiledBacking::VerticallyScrollable;
2894
2895     return scrollability;
2896 }
2897
2898 void FrameView::updateTiledBackingAdaptiveSizing()
2899 {
2900     auto* tiledBacking = this->tiledBacking();
2901     if (!tiledBacking)
2902         return;
2903
2904     tiledBacking->setScrollability(computeScrollability());
2905 }
2906
2907 #if PLATFORM(IOS)
2908
2909 void FrameView::unobscuredContentSizeChanged()
2910 {
2911     updateTiledBackingAdaptiveSizing();
2912 }
2913
2914 #endif
2915
2916 static LayerFlushThrottleState::Flags determineLayerFlushThrottleState(Page& page)
2917 {
2918     // We only throttle when constantly receiving new data during the inital page load.
2919     if (!page.progress().isMainLoadProgressing())
2920         return 0;
2921     // Scrolling during page loading disables throttling.
2922     if (page.mainFrame().view()->wasScrolledByUser())
2923         return 0;
2924     // Disable for image documents so large GIF animations don't get throttled during loading.
2925     auto* document = page.mainFrame().document();
2926     if (!document || is<ImageDocument>(*document))
2927         return 0;
2928     return LayerFlushThrottleState::Enabled;
2929 }
2930
2931 void FrameView::disableLayerFlushThrottlingTemporarilyForInteraction()
2932 {
2933     if (!frame().page())
2934         return;
2935     auto& page = *frame().page();
2936
2937     LayerFlushThrottleState::Flags flags = LayerFlushThrottleState::UserIsInteracting | determineLayerFlushThrottleState(page);
2938     if (page.chrome().client().adjustLayerFlushThrottling(flags))
2939         return;
2940
2941     if (RenderView* view = renderView())
2942         view->compositor().disableLayerFlushThrottlingTemporarilyForInteraction();
2943 }
2944
2945 void FrameView::loadProgressingStatusChanged()
2946 {
2947     updateLayerFlushThrottling();
2948     adjustTiledBackingCoverage();
2949 }
2950
2951 void FrameView::updateLayerFlushThrottling()
2952 {
2953     Page* page = frame().page();
2954     if (!page)
2955         return;
2956
2957     ASSERT(frame().isMainFrame());
2958
2959     LayerFlushThrottleState::Flags flags = determineLayerFlushThrottleState(*page);
2960
2961     // See if the client is handling throttling.
2962     if (page->chrome().client().adjustLayerFlushThrottling(flags))
2963         return;
2964
2965     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
2966         if (RenderView* renderView = frame->contentRenderer())
2967             renderView->compositor().setLayerFlushThrottlingEnabled(flags & LayerFlushThrottleState::Enabled);
2968     }
2969 }
2970
2971 void FrameView::adjustTiledBackingCoverage()
2972 {
2973     if (!m_speculativeTilingEnabled)
2974         enableSpeculativeTilingIfNeeded();
2975
2976     RenderView* renderView = this->renderView();
2977     if (renderView && renderView->layer() && renderView->layer()->backing())
2978         renderView->layer()->backing()->adjustTiledBackingCoverage();
2979 #if PLATFORM(IOS)
2980     if (LegacyTileCache* tileCache = legacyTileCache())
2981         tileCache->setSpeculativeTileCreationEnabled(m_speculativeTilingEnabled);
2982 #endif
2983 }
2984
2985 static bool shouldEnableSpeculativeTilingDuringLoading(const FrameView& view)
2986 {
2987     Page* page = view.frame().page();
2988     return page && view.isVisuallyNonEmpty() && !page->progress().isMainLoadProgressing();
2989 }
2990
2991 void FrameView::enableSpeculativeTilingIfNeeded()
2992 {
2993     ASSERT(!m_speculativeTilingEnabled);
2994     if (m_wasScrolledByUser) {
2995         m_speculativeTilingEnabled = true;
2996         return;
2997     }
2998     if (!shouldEnableSpeculativeTilingDuringLoading(*this))
2999         return;
3000
3001     if (m_speculativeTilingDelayDisabledForTesting) {
3002         speculativeTilingEnableTimerFired();
3003         return;
3004     }
3005
3006     if (m_speculativeTilingEnableTimer.isActive())
3007         return;
3008     // Delay enabling a bit as load completion may trigger further loading from scripts.
3009     static const Seconds speculativeTilingEnableDelay { 500_ms };
3010     m_speculativeTilingEnableTimer.startOneShot(speculativeTilingEnableDelay);
3011 }
3012
3013 void FrameView::speculativeTilingEnableTimerFired()
3014 {
3015     if (m_speculativeTilingEnabled)
3016         return;
3017     m_speculativeTilingEnabled = shouldEnableSpeculativeTilingDuringLoading(*this);
3018     adjustTiledBackingCoverage();
3019 }
3020
3021 void FrameView::show()
3022 {
3023     ScrollView::show();
3024
3025     if (frame().isMainFrame()) {
3026         // Turn off speculative tiling for a brief moment after a FrameView appears on screen.
3027         // Note that adjustTiledBackingCoverage() kicks the (500ms) timer to re-enable it.
3028         m_speculativeTilingEnabled = false;
3029         m_wasScrolledByUser = false;
3030         adjustTiledBackingCoverage();
3031     }
3032 }
3033
3034 void FrameView::hide()
3035 {
3036     ScrollView::hide();
3037     adjustTiledBackingCoverage();
3038 }
3039
3040 void FrameView::convertSubtreeLayoutToFullLayout()
3041 {
3042     ASSERT(m_layoutRoot);
3043     m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No);
3044     m_layoutRoot = nullptr;
3045 }
3046
3047 void FrameView::layoutTimerFired()
3048 {
3049 #if !LOG_DISABLED
3050     if (!frame().document()->ownerElement())
3051         LOG(Layout, "FrameView %p layout timer fired at %.3fs", this, frame().document()->timeSinceDocumentCreation().value());
3052 #endif
3053     layout();
3054 }
3055
3056 void FrameView::scheduleRelayout()
3057 {
3058     // FIXME: We should assert the page is not in the page cache, but that is causing
3059     // too many false assertions.  See <rdar://problem/7218118>.
3060     ASSERT(frame().view() == this);
3061
3062     if (m_layoutRoot)
3063         convertSubtreeLayoutToFullLayout();
3064     if (!m_layoutSchedulingEnabled)
3065         return;
3066     if (!needsLayout())
3067         return;
3068     if (!frame().document()->shouldScheduleLayout())
3069         return;
3070     InspectorInstrumentation::didInvalidateLayout(frame());
3071     // When frame flattening is enabled, the contents of the frame could affect the layout of the parent frames.
3072     // Also invalidate parent frame starting from the owner element of this frame.
3073     if (frame().ownerRenderer() && isInChildFrameWithFrameFlattening())
3074         frame().ownerRenderer()->setNeedsLayout(MarkContainingBlockChain);
3075
3076     Seconds delay = frame().document()->minimumLayoutDelay();
3077     if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
3078         unscheduleRelayout();
3079
3080     if (m_layoutTimer.isActive())
3081         return;
3082
3083     m_delayedLayout = delay.value();
3084
3085 #if !LOG_DISABLED
3086     if (!frame().document()->ownerElement())
3087         LOG(Layout, "FrameView %p scheduling layout for %.3fs", this, delay.value());
3088 #endif
3089
3090     m_layoutTimer.startOneShot(delay);
3091 }
3092
3093 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
3094 {
3095     for (RenderObject* r = descendant; r; r = r->container()) {
3096         if (r == ancestor)
3097             return true;
3098     }
3099     return false;
3100 }
3101
3102 void FrameView::scheduleRelayoutOfSubtree(RenderElement& newRelayoutRoot)
3103 {
3104     ASSERT(renderView());
3105     const RenderView& renderView = *this->renderView();
3106
3107     // Try to catch unnecessary work during render tree teardown.
3108     ASSERT(!renderView.renderTreeBeingDestroyed());
3109     ASSERT(frame().view() == this);
3110
3111     // When m_layoutRoot is already set, ignore the renderView's needsLayout bit
3112     // since we need to resolve the conflict between the m_layoutRoot and newRelayoutRoot layouts.
3113     if (renderView.needsLayout() && !m_layoutRoot) {
3114         m_layoutRoot = &newRelayoutRoot;
3115         convertSubtreeLayoutToFullLayout();
3116         return;
3117     }
3118
3119     if (!layoutPending() && m_layoutSchedulingEnabled) {
3120         Seconds delay = renderView.document().minimumLayoutDelay();
3121         ASSERT(!newRelayoutRoot.container() || is<RenderView>(newRelayoutRoot.container()) || !newRelayoutRoot.container()->needsLayout());
3122         m_layoutRoot = &newRelayoutRoot;
3123         InspectorInstrumentation::didInvalidateLayout(frame());
3124         m_delayedLayout = delay.value();
3125         m_layoutTimer.startOneShot(delay);
3126         return;
3127     }
3128
3129     if (m_layoutRoot == &newRelayoutRoot)
3130         return;
3131
3132     if (!m_layoutRoot) {
3133         // We already have a pending (full) layout. Just mark the subtree for layout.
3134         newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No);
3135         InspectorInstrumentation::didInvalidateLayout(frame());
3136         return;
3137     }
3138
3139     if (isObjectAncestorContainerOf(m_layoutRoot, &newRelayoutRoot)) {
3140         // Keep the current root.
3141         newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No, m_layoutRoot);
3142         ASSERT(!m_layoutRoot->container() || is<RenderView>(m_layoutRoot->container()) || !m_layoutRoot->container()->needsLayout());
3143         return;
3144     }
3145
3146     if (isObjectAncestorContainerOf(&newRelayoutRoot, m_layoutRoot)) {
3147         // Re-root at newRelayoutRoot.
3148         m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No, &newRelayoutRoot);
3149         m_layoutRoot = &newRelayoutRoot;
3150         ASSERT(!m_layoutRoot->container() || is<RenderView>(m_layoutRoot->container()) || !m_layoutRoot->container()->needsLayout());
3151         InspectorInstrumentation::didInvalidateLayout(frame());
3152         return;
3153     }
3154     // Two disjoint subtrees need layout. Mark both of them and issue a full layout instead.
3155     convertSubtreeLayoutToFullLayout();
3156     newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No);
3157     InspectorInstrumentation::didInvalidateLayout(frame());
3158 }
3159
3160 bool FrameView::layoutPending() const
3161 {
3162     return m_layoutTimer.isActive();
3163 }
3164
3165 bool FrameView::needsLayout() const
3166 {
3167     // This can return true in cases where the document does not have a body yet.
3168     // Document::shouldScheduleLayout takes care of preventing us from scheduling
3169     // layout in that case.
3170     RenderView* renderView = this->renderView();
3171     return layoutPending()
3172         || (renderView && renderView->needsLayout())
3173         || m_layoutRoot
3174         || (m_deferSetNeedsLayoutCount && m_setNeedsLayoutWasDeferred);
3175 }
3176
3177 void FrameView::setNeedsLayout()
3178 {
3179     if (m_deferSetNeedsLayoutCount) {
3180         m_setNeedsLayoutWasDeferred = true;
3181         return;
3182     }
3183
3184     if (auto* renderView = this->renderView()) {
3185         ASSERT(!renderView->inHitTesting());
3186         renderView->setNeedsLayout();
3187     }
3188 }
3189
3190 void FrameView::unscheduleRelayout()
3191 {
3192     if (m_postLayoutTasksTimer.isActive())
3193         m_postLayoutTasksTimer.stop();
3194
3195     if (!m_layoutTimer.isActive())
3196         return;
3197
3198 #if !LOG_DISABLED
3199     if (!frame().document()->ownerElement())
3200         LOG(Layout, "FrameView %p layout timer unscheduled at %.3fs", this, frame().document()->timeSinceDocumentCreation().value());
3201 #endif
3202     
3203     m_layoutTimer.stop();
3204     m_delayedLayout = false;
3205 }
3206
3207 void FrameView::serviceScriptedAnimations()
3208 {
3209     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext()) {
3210         frame->view()->serviceScrollAnimations();
3211         frame->animation().serviceAnimations();
3212     }
3213
3214     if (!frame().document() || !frame().document()->domWindow())
3215         return;
3216
3217     Vector<RefPtr<Document>> documents;
3218     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext())
3219         documents.append(frame->document());
3220
3221     double timestamp = frame().document()->domWindow()->nowTimestamp();
3222     for (auto& document : documents)
3223         document->serviceScriptedAnimations(timestamp);
3224 }
3225
3226 bool FrameView::isTransparent() const
3227 {
3228     return m_isTransparent;
3229 }
3230
3231 void FrameView::setTransparent(bool isTransparent)
3232 {
3233     if (m_isTransparent == isTransparent)
3234         return;
3235
3236     m_isTransparent = isTransparent;
3237
3238     // setTransparent can be called in the window between FrameView initialization
3239     // and switching in the new Document; this means that the RenderView that we
3240     // retrieve is actually attached to the previous Document, which is going away,
3241     // and must not update compositing layers.
3242     if (!isViewForDocumentInFrame())
3243         return;
3244
3245     renderView()->compositor().rootBackgroundTransparencyChanged();
3246 }
3247
3248 bool FrameView::hasOpaqueBackground() const
3249 {
3250     return !m_isTransparent && m_baseBackgroundColor.isOpaque();
3251 }
3252
3253 Color FrameView::baseBackgroundColor() const
3254 {
3255     return m_baseBackgroundColor;
3256 }
3257
3258 void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
3259 {
3260     bool wasOpaque = m_baseBackgroundColor.isOpaque();
3261     
3262     if (!backgroundColor.isValid())
3263         m_baseBackgroundColor = Color::white;
3264     else
3265         m_baseBackgroundColor = backgroundColor;
3266
3267     if (!isViewForDocumentInFrame())
3268         return;
3269
3270     recalculateScrollbarOverlayStyle();
3271
3272     if (m_baseBackgroundColor.isOpaque() != wasOpaque)
3273         renderView()->compositor().rootBackgroundTransparencyChanged();
3274 }
3275
3276 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
3277 {
3278     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
3279         if (FrameView* view = frame->view()) {
3280             view->setTransparent(transparent);
3281             view->setBaseBackgroundColor(backgroundColor);
3282         }
3283     }
3284 }
3285
3286 bool FrameView::hasExtendedBackgroundRectForPainting() const
3287 {
3288     TiledBacking* tiledBacking = this->tiledBacking();
3289     if (!tiledBacking)
3290         return false;
3291
3292     return tiledBacking->hasMargins();
3293 }
3294
3295 void FrameView::updateExtendBackgroundIfNecessary()
3296 {
3297     ExtendedBackgroundMode mode = calculateExtendedBackgroundMode();
3298     if (mode == ExtendedBackgroundModeNone)
3299         return;
3300
3301     updateTilesForExtendedBackgroundMode(mode);
3302 }
3303
3304 FrameView::ExtendedBackgroundMode FrameView::calculateExtendedBackgroundMode() const
3305 {
3306 #if PLATFORM(IOS)
3307     // <rdar://problem/16201373>
3308     return ExtendedBackgroundModeNone;
3309 #else
3310     if (!frame().settings().backgroundShouldExtendBeyondPage())
3311         return ExtendedBackgroundModeNone;
3312
3313     // Just because Settings::backgroundShouldExtendBeyondPage() is true does not necessarily mean
3314     // that the background rect needs to be extended for painting. Simple backgrounds can be extended
3315     // just with RenderLayerCompositor::setRootExtendedBackgroundColor(). More complicated backgrounds,
3316     // such as images, require extending the background rect to continue painting into the extended
3317     // region. This function finds out if it is necessary to extend the background rect for painting.
3318
3319     if (!frame().isMainFrame())
3320         return ExtendedBackgroundModeNone;
3321
3322     Document* document = frame().document();
3323     if (!document)
3324         return ExtendedBackgroundModeNone;
3325
3326     if (!renderView())
3327         return ExtendedBackgroundModeNone;
3328     
3329     auto* rootBackgroundRenderer = renderView()->rendererForRootBackground();
3330     if (!rootBackgroundRenderer)
3331         return ExtendedBackgroundModeNone;
3332
3333     if (!rootBackgroundRenderer->style().hasBackgroundImage())
3334         return ExtendedBackgroundModeNone;
3335
3336     ExtendedBackgroundMode mode = ExtendedBackgroundModeNone;
3337     if (rootBackgroundRenderer->style().backgroundRepeatX() == RepeatFill)
3338         mode |= ExtendedBackgroundModeHorizontal;
3339     if (rootBackgroundRenderer->style().backgroundRepeatY() == RepeatFill)
3340         mode |= ExtendedBackgroundModeVertical;
3341
3342     return mode;
3343 #endif
3344 }
3345
3346 void FrameView::updateTilesForExtendedBackgroundMode(ExtendedBackgroundMode mode)
3347 {
3348     RenderView* renderView = this->renderView();
3349     if (!renderView)
3350         return;
3351
3352     RenderLayerBacking* backing = renderView->layer()->backing();
3353     if (!backing)
3354         return;
3355
3356     TiledBacking* tiledBacking = backing->tiledBacking();
3357     if (!tiledBacking)
3358         return;
3359
3360     ExtendedBackgroundMode existingMode = ExtendedBackgroundModeNone;
3361     if (tiledBacking->hasVerticalMargins())
3362         existingMode |= ExtendedBackgroundModeVertical;
3363     if (tiledBacking->hasHorizontalMargins())
3364         existingMode |= ExtendedBackgroundModeHorizontal;
3365
3366     if (existingMode == mode)
3367         return;
3368
3369     renderView->compositor().setRootExtendedBackgroundColor(mode == ExtendedBackgroundModeAll ? Color() : documentBackgroundColor());
3370     backing->setTiledBackingHasMargins(mode & ExtendedBackgroundModeHorizontal, mode & ExtendedBackgroundModeVertical);
3371 }
3372
3373 IntRect FrameView::extendedBackgroundRectForPainting() const
3374 {
3375     TiledBacking* tiledBacking = this->tiledBacking();
3376     if (!tiledBacking)
3377         return IntRect();
3378     
3379     RenderView* renderView = this->renderView();
3380     if (!renderView)
3381         return IntRect();
3382     
3383     LayoutRect extendedRect = renderView->unextendedBackgroundRect();
3384     if (!tiledBacking->hasMargins())
3385         return snappedIntRect(extendedRect);
3386     
3387     extendedRect.moveBy(LayoutPoint(-tiledBacking->leftMarginWidth(), -tiledBacking->topMarginHeight()));
3388     extendedRect.expand(LayoutSize(tiledBacking->leftMarginWidth() + tiledBacking->rightMarginWidth(), tiledBacking->topMarginHeight() + tiledBacking->bottomMarginHeight()));
3389     return snappedIntRect(extendedRect);
3390 }
3391
3392 bool FrameView::shouldUpdateWhileOffscreen() const
3393 {
3394     return m_shouldUpdateWhileOffscreen;
3395 }
3396
3397 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
3398 {
3399     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
3400 }
3401
3402 bool FrameView::shouldUpdate() const
3403 {
3404     if (isOffscreen() && !shouldUpdateWhileOffscreen())
3405         return false;
3406     return true;
3407 }
3408
3409 void FrameView::scrollToAnchor()
3410 {
3411     RefPtr<ContainerNode> anchorNode = m_maintainScrollPositionAnchor;
3412     if (!anchorNode)
3413         return;
3414
3415     if (!anchorNode->renderer())
3416         return;
3417
3418     LayoutRect rect;
3419     bool insideFixed = false;
3420     if (anchorNode != frame().document() && anchorNode->renderer())
3421         rect = anchorNode->renderer()->absoluteAnchorRect(&insideFixed);
3422
3423     // Scroll nested layers and frames to reveal the anchor.
3424     // Align to the top and to the closest side (this matches other browsers).
3425     if (anchorNode->renderer()->style().isHorizontalWritingMode())
3426         anchorNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, rect, insideFixed, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
3427     else if (anchorNode->renderer()->style().isFlippedBlocksWritingMode())
3428         anchorNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, rect, insideFixed, ScrollAlignment::alignRightAlways, ScrollAlignment::alignToEdgeIfNeeded);
3429     else
3430         anchorNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, rect, insideFixed, ScrollAlignment::alignLeftAlways, ScrollAlignment::alignToEdgeIfNeeded);
3431
3432     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
3433         cache->handleScrolledToAnchor(anchorNode.get());
3434
3435     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
3436     m_maintainScrollPositionAnchor = anchorNode;
3437 }
3438
3439 void FrameView::updateEmbeddedObject(RenderEmbeddedObject& embeddedObject)
3440 {
3441     // No need to update if it's already crashed or known to be missing.
3442     if (embeddedObject.isPluginUnavailable())
3443         return;
3444
3445     HTMLFrameOwnerElement& element = embeddedObject.frameOwnerElement();
3446
3447     if (embeddedObject.isSnapshottedPlugIn()) {
3448         if (is<HTMLObjectElement>(element) || is<HTMLEmbedElement>(element)) {
3449             HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
3450             pluginElement.checkSnapshotStatus();
3451         }
3452         return;
3453     }
3454
3455     auto weakRenderer = makeWeakPtr(embeddedObject);
3456
3457     // FIXME: This could turn into a real virtual dispatch if we defined
3458     // updateWidget(PluginCreationOption) on HTMLElement.
3459     if (is<HTMLPlugInImageElement>(element)) {
3460         HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
3461         if (pluginElement.needsCheckForSizeChange()) {
3462             pluginElement.checkSnapshotStatus();
3463             return;
3464         }
3465         if (pluginElement.needsWidgetUpdate())
3466             pluginElement.updateWidget(CreatePlugins::Yes);
3467     } else
3468         ASSERT_NOT_REACHED();
3469
3470     // It's possible the renderer was destroyed below updateWidget() since loading a plugin may execute arbitrary JavaScript.
3471     if (!weakRenderer)
3472         return;
3473
3474     auto ignoreWidgetState = embeddedObject.updateWidgetPosition();
3475     UNUSED_PARAM(ignoreWidgetState);
3476 }
3477
3478 bool FrameView::updateEmbeddedObjects()
3479 {
3480     if (m_nestedLayoutCount > 1 || !m_embeddedObjectsToUpdate || m_embeddedObjectsToUpdate->isEmpty())
3481         return true;
3482
3483     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
3484
3485     // Insert a marker for where we should stop.
3486     ASSERT(!m_embeddedObjectsToUpdate->contains(nullptr));
3487     m_embeddedObjectsToUpdate->add(nullptr);
3488
3489     while (!m_embeddedObjectsToUpdate->isEmpty()) {
3490         RenderEmbeddedObject* embeddedObject = m_embeddedObjectsToUpdate->takeFirst();
3491         if (!embeddedObject)
3492             break;
3493         updateEmbeddedObject(*embeddedObject);
3494     }
3495
3496     return m_embeddedObjectsToUpdate->isEmpty();
3497 }
3498
3499 void FrameView::updateEmbeddedObjectsTimerFired()
3500 {
3501     RefPtr<FrameView> protectedThis(this);
3502     m_updateEmbeddedObjectsTimer.stop();
3503     for (unsigned i = 0; i < maxUpdateEmbeddedObjectsIterations; i++) {
3504         if (updateEmbeddedObjects())
3505             break;
3506     }
3507 }
3508
3509 void FrameView::flushAnyPendingPostLayoutTasks()
3510 {
3511     if (m_postLayoutTasksTimer.isActive())
3512         performPostLayoutTasks();
3513     if (m_updateEmbeddedObjectsTimer.isActive())
3514         updateEmbeddedObjectsTimerFired();
3515 }
3516
3517 void FrameView::queuePostLayoutCallback(Function<void()>&& callback)
3518 {
3519     m_postLayoutCallbackQueue.append(WTFMove(callback));
3520 }
3521
3522 void FrameView::flushPostLayoutTasksQueue()
3523 {
3524     if (m_nestedLayoutCount > 1)
3525         return;
3526
3527     if (!m_postLayoutCallbackQueue.size())
3528         return;
3529
3530     Vector<Function<void()>> queue = WTFMove(m_postLayoutCallbackQueue);
3531     for (auto& task : queue)
3532         task();
3533 }
3534
3535 void FrameView::performPostLayoutTasks()
3536 {
3537     // FIXME: We should not run any JavaScript code in this function.
3538     LOG(Layout, "FrameView %p performPostLayoutTasks", this);
3539
3540     m_postLayoutTasksTimer.stop();
3541
3542     frame().selection().updateAppearanceAfterLayout();
3543
3544     flushPostLayoutTasksQueue();
3545
3546     if (m_nestedLayoutCount <= 1 && frame().document()->documentElement())
3547         fireLayoutRelatedMilestonesIfNeeded();
3548
3549 #if PLATFORM(IOS)
3550     // Only send layout-related delegate callbacks synchronously for the main frame to
3551     // avoid re-entering layout for the main frame while delivering a layout-related delegate
3552     // callback for a subframe.
3553     if (frame().isMainFrame()) {
3554         if (Page* page = frame().page())
3555             page->chrome().client().didLayout();
3556     }
3557 #endif
3558     
3559     // FIXME: We should consider adding DidLayout as a LayoutMilestone. That would let us merge this
3560     // with didLayout(LayoutMilestones).
3561     frame().loader().client().dispatchDidLayout();
3562
3563     updateWidgetPositions();
3564
3565 #if ENABLE(CSS_SCROLL_SNAP)
3566     updateSnapOffsets();
3567 #endif
3568     m_updateEmbeddedObjectsTimer.startOneShot(0_s);
3569
3570     if (auto* page = frame().page()) {
3571         if (auto* scrollingCoordinator = page->scrollingCoordinator())
3572             scrollingCoordinator->frameViewLayoutUpdated(*this);
3573     }
3574
3575     if (RenderView* renderView = this->renderView()) {
3576         if (renderView->usesCompositing())
3577             renderView->compositor().frameViewDidLayout();
3578     }
3579
3580     scrollToAnchor();
3581
3582     sendResizeEventIfNeeded();
3583     
3584     updateLayoutViewport();
3585     viewportContentsChanged();
3586
3587     updateScrollSnapState();
3588
3589     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
3590         cache->performDeferredCacheUpdate();
3591 }
3592
3593 IntSize FrameView::sizeForResizeEvent() const
3594 {
3595 #if PLATFORM(IOS)
3596     if (m_useCustomSizeForResizeEvent)
3597         return m_customSizeForResizeEvent;
3598 #endif
3599     if (useFixedLayout() && !fixedLayoutSize().isEmpty() && delegatesScrolling())
3600         return fixedLayoutSize();
3601     return visibleContentRectIncludingScrollbars().size();
3602 }
3603
3604 void FrameView::sendResizeEventIfNeeded()
3605 {
3606     if (isInRenderTreeLayout() || needsLayout())
3607         return;
3608
3609     RenderView* renderView = this->renderView();
3610     if (!renderView || renderView->printing())
3611         return;
3612
3613     if (frame().page() && frame().page()->chrome().client().isSVGImageChromeClient())
3614         return;
3615
3616     IntSize currentSize = sizeForResizeEvent();
3617     float currentZoomFactor = renderView->style().zoom();
3618
3619     if (currentSize == m_lastViewportSize && currentZoomFactor == m_lastZoomFactor)
3620         return;
3621
3622     m_lastViewportSize = currentSize;
3623     m_lastZoomFactor = currentZoomFactor;
3624
3625     if (m_firstLayout)
3626         return;
3627
3628 #if PLATFORM(IOS)
3629     // Don't send the resize event if the document is loading. Some pages automatically reload
3630     // when the window is resized; Safari on iOS often resizes the window while setting up its
3631     // viewport. This obviously can cause problems.
3632     if (DocumentLoader* documentLoader = frame().loader().documentLoader()) {
3633         if (documentLoader->isLoadingInAPISense())
3634             return;
3635     }
3636 #endif
3637
3638     bool isMainFrame = frame().isMainFrame();
3639     bool canSendResizeEventSynchronously = isMainFrame && !m_shouldAutoSize;
3640
3641     LOG(Events, "FrameView %p sendResizeEventIfNeeded sending resize event, size %dx%d (canSendResizeEventSynchronously %d)", this, currentSize.width(), currentSize.height(), canSendResizeEventSynchronously);
3642
3643     Ref<Event> resizeEvent = Event::create(eventNames().resizeEvent, false, false);
3644     if (canSendResizeEventSynchronously)
3645         frame().document()->dispatchWindowEvent(resizeEvent);
3646     else {
3647         // FIXME: Queueing this event for an unpredictable time in the future seems
3648         // intrinsically racy. By the time this resize event fires, the frame might
3649         // be resized again, so we could end up with two resize events for the same size.
3650         frame().document()->enqueueWindowEvent(WTFMove(resizeEvent));
3651     }
3652
3653     if (InspectorInstrumentation::hasFrontends() && isMainFrame) {
3654         if (Page* page = frame().page()) {
3655             if (InspectorClient* inspectorClient = page->inspectorController().inspectorClient())
3656                 inspectorClient->didResizeMainFrame(&frame());
3657         }
3658     }
3659 }
3660
3661 void FrameView::willStartLiveResize()
3662 {
3663     ScrollView::willStartLiveResize();
3664     adjustTiledBackingCoverage();
3665 }
3666     
3667 void FrameView::willEndLiveResize()
3668 {
3669     ScrollView::willEndLiveResize();
3670     adjustTiledBackingCoverage();