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