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