Fixed elements bounce when rubber-banding at the bottom of the page
[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 "MemoryPressureHandler.h"
67 #include "OverflowEvent.h"
68 #include "Page.h"
69 #include "PageCache.h"
70 #include "PageOverlayController.h"
71 #include "ProgressTracker.h"
72 #include "RenderEmbeddedObject.h"
73 #include "RenderFullScreen.h"
74 #include "RenderIFrame.h"
75 #include "RenderInline.h"
76 #include "RenderLayer.h"
77 #include "RenderLayerBacking.h"
78 #include "RenderLayerCompositor.h"
79 #include "RenderSVGRoot.h"
80 #include "RenderScrollbar.h"
81 #include "RenderScrollbarPart.h"
82 #include "RenderStyle.h"
83 #include "RenderText.h"
84 #include "RenderTheme.h"
85 #include "RenderView.h"
86 #include "RenderWidget.h"
87 #include "SVGDocument.h"
88 #include "SVGSVGElement.h"
89 #include "ScriptedAnimationController.h"
90 #include "ScrollAnimator.h"
91 #include "ScrollingCoordinator.h"
92 #include "Settings.h"
93 #include "StyleResolver.h"
94 #include "StyleScope.h"
95 #include "TextResourceDecoder.h"
96 #include "TextStream.h"
97 #include "TiledBacking.h"
98 #include "WheelEventTestTrigger.h"
99
100 #include <wtf/CurrentTime.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     return true;
1062 }
1063
1064 void FrameView::setNeedsOneShotDrawingSynchronization()
1065 {
1066     if (Page* page = frame().page())
1067         page->chrome().client().setNeedsOneShotDrawingSynchronization();
1068 }
1069
1070 GraphicsLayer* FrameView::graphicsLayerForPlatformWidget(PlatformWidget platformWidget)
1071 {
1072     // To find the Widget that corresponds with platformWidget we have to do a linear
1073     // search of our child widgets.
1074     const Widget* foundWidget = nullptr;
1075     for (auto& widget : children()) {
1076         if (widget->platformWidget() != platformWidget)
1077             continue;
1078         foundWidget = widget.ptr();
1079         break;
1080     }
1081
1082     if (!foundWidget)
1083         return nullptr;
1084
1085     auto* renderWidget = RenderWidget::find(*foundWidget);
1086     if (!renderWidget)
1087         return nullptr;
1088
1089     auto* widgetLayer = renderWidget->layer();
1090     if (!widgetLayer || !widgetLayer->isComposited())
1091         return nullptr;
1092
1093     return widgetLayer->backing()->parentForSublayers();
1094 }
1095
1096 void FrameView::scheduleLayerFlushAllowingThrottling()
1097 {
1098     RenderView* view = this->renderView();
1099     if (!view)
1100         return;
1101     view->compositor().scheduleLayerFlush(true /* canThrottle */);
1102 }
1103
1104 LayoutRect FrameView::fixedScrollableAreaBoundsInflatedForScrolling(const LayoutRect& uninflatedBounds) const
1105 {
1106     LayoutPoint scrollPosition;
1107     LayoutSize topLeftExpansion;
1108     LayoutSize bottomRightExpansion;
1109
1110     if (frame().settings().visualViewportEnabled()) {
1111         // FIXME: this is wrong under zooming; uninflatedBounds is scaled but the scroll positions are not.
1112         scrollPosition = layoutViewportRect().location();
1113         topLeftExpansion = scrollPosition - unscaledMinimumScrollPosition();
1114         bottomRightExpansion = unscaledMaximumScrollPosition() - scrollPosition;
1115     } else {
1116         scrollPosition = scrollPositionRespectingCustomFixedPosition();
1117         topLeftExpansion = scrollPosition - minimumScrollPosition();
1118         bottomRightExpansion = maximumScrollPosition() - scrollPosition;
1119     }
1120
1121     return LayoutRect(uninflatedBounds.location() - topLeftExpansion, uninflatedBounds.size() + topLeftExpansion + bottomRightExpansion);
1122 }
1123
1124 LayoutPoint FrameView::scrollPositionRespectingCustomFixedPosition() const
1125 {
1126 #if PLATFORM(IOS)
1127     if (!frame().settings().visualViewportEnabled())
1128         return useCustomFixedPositionLayoutRect() ? customFixedPositionLayoutRect().location() : scrollPosition();
1129 #endif
1130
1131     return scrollPositionForFixedPosition();
1132 }
1133
1134 void FrameView::setHeaderHeight(int headerHeight)
1135 {
1136     if (frame().page())
1137         ASSERT(frame().isMainFrame());
1138     m_headerHeight = headerHeight;
1139
1140     if (RenderView* renderView = this->renderView())
1141         renderView->setNeedsLayout();
1142 }
1143
1144 void FrameView::setFooterHeight(int footerHeight)
1145 {
1146     if (frame().page())
1147         ASSERT(frame().isMainFrame());
1148     m_footerHeight = footerHeight;
1149
1150     if (RenderView* renderView = this->renderView())
1151         renderView->setNeedsLayout();
1152 }
1153
1154 float FrameView::topContentInset(TopContentInsetType contentInsetTypeToReturn) const
1155 {
1156     if (platformWidget() && contentInsetTypeToReturn == TopContentInsetType::WebCoreOrPlatformContentInset)
1157         return platformTopContentInset();
1158
1159     if (!frame().isMainFrame())
1160         return 0;
1161     
1162     Page* page = frame().page();
1163     return page ? page->topContentInset() : 0;
1164 }
1165     
1166 void FrameView::topContentInsetDidChange(float newTopContentInset)
1167 {
1168     RenderView* renderView = this->renderView();
1169     if (!renderView)
1170         return;
1171
1172     if (platformWidget())
1173         platformSetTopContentInset(newTopContentInset);
1174     
1175     layout();
1176
1177     updateScrollbars(scrollPosition());
1178     if (renderView->usesCompositing())
1179         renderView->compositor().frameViewDidChangeSize();
1180
1181     if (TiledBacking* tiledBacking = this->tiledBacking())
1182         tiledBacking->setTopContentInset(newTopContentInset);
1183 }
1184
1185 void FrameView::topContentDirectionDidChange()
1186 {
1187     m_needsDeferredScrollbarsUpdate = true;
1188 }
1189
1190 void FrameView::handleDeferredScrollbarsUpdateAfterDirectionChange()
1191 {
1192     if (!m_needsDeferredScrollbarsUpdate)
1193         return;
1194
1195     m_needsDeferredScrollbarsUpdate = false;
1196
1197     ASSERT(m_layoutPhase == InPostLayerPositionsUpdatedAfterLayout);
1198     updateScrollbars(scrollPosition());
1199     positionScrollbarLayers();
1200 }
1201     
1202 bool FrameView::hasCompositedContent() const
1203 {
1204     if (RenderView* renderView = this->renderView())
1205         return renderView->compositor().inCompositingMode();
1206     return false;
1207 }
1208
1209 // Sometimes (for plug-ins) we need to eagerly go into compositing mode.
1210 void FrameView::enterCompositingMode()
1211 {
1212     if (RenderView* renderView = this->renderView()) {
1213         renderView->compositor().enableCompositingMode();
1214         if (!needsLayout())
1215             renderView->compositor().scheduleCompositingLayerUpdate();
1216     }
1217 }
1218
1219 bool FrameView::isEnclosedInCompositingLayer() const
1220 {
1221     auto frameOwnerRenderer = frame().ownerRenderer();
1222     if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
1223         return true;
1224
1225     if (FrameView* parentView = parentFrameView())
1226         return parentView->isEnclosedInCompositingLayer();
1227     return false;
1228 }
1229
1230 bool FrameView::flushCompositingStateIncludingSubframes()
1231 {
1232     InspectorInstrumentation::willComposite(frame());
1233
1234     bool allFramesFlushed = flushCompositingStateForThisFrame(frame());
1235
1236     for (Frame* child = frame().tree().firstRenderedChild(); child; child = child->tree().traverseNextRendered(m_frame.ptr())) {
1237         if (!child->view())
1238             continue;
1239         bool flushed = child->view()->flushCompositingStateForThisFrame(frame());
1240         allFramesFlushed &= flushed;
1241     }
1242     return allFramesFlushed;
1243 }
1244
1245 bool FrameView::isSoftwareRenderable() const
1246 {
1247     RenderView* renderView = this->renderView();
1248     return !renderView || !renderView->compositor().has3DContent();
1249 }
1250
1251 void FrameView::setIsInWindow(bool isInWindow)
1252 {
1253     if (RenderView* renderView = this->renderView())
1254         renderView->setIsInWindow(isInWindow);
1255 }
1256
1257 inline void FrameView::forceLayoutParentViewIfNeeded()
1258 {
1259     RenderWidget* ownerRenderer = frame().ownerRenderer();
1260     if (!ownerRenderer)
1261         return;
1262
1263     RenderBox* contentBox = embeddedContentBox();
1264     if (!contentBox)
1265         return;
1266
1267     auto& svgRoot = downcast<RenderSVGRoot>(*contentBox);
1268     if (svgRoot.everHadLayout() && !svgRoot.needsLayout())
1269         return;
1270
1271     LOG(Layout, "FrameView %p forceLayoutParentViewIfNeeded scheduling layout on parent FrameView %p", this, &ownerRenderer->view().frameView());
1272
1273     // If the embedded SVG document appears the first time, the ownerRenderer has already finished
1274     // layout without knowing about the existence of the embedded SVG document, because RenderReplaced
1275     // embeddedContentBox() returns nullptr, as long as the embedded document isn't loaded yet. Before
1276     // bothering to lay out the SVG document, mark the ownerRenderer needing layout and ask its
1277     // FrameView for a layout. After that the RenderEmbeddedObject (ownerRenderer) carries the
1278     // correct size, which RenderSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying
1279     // out for the first time, or when the RenderSVGRoot size has changed dynamically (eg. via <script>).
1280
1281     ownerRenderer->setNeedsLayoutAndPrefWidthsRecalc();
1282     ownerRenderer->view().frameView().scheduleRelayout();
1283 }
1284
1285 void FrameView::layout(bool allowSubtree)
1286 {
1287     LOG(Layout, "FrameView %p (%dx%d) layout, main frameview %d, allowSubtree=%d", this, size().width(), size().height(), frame().isMainFrame(), allowSubtree);
1288     if (isInRenderTreeLayout()) {
1289         LOG(Layout, "  in layout, bailing");
1290         return;
1291     }
1292
1293     if (layoutDisallowed()) {
1294         LOG(Layout, "  layout is disallowed, bailing");
1295         return;
1296     }
1297
1298     // Protect the view from being deleted during layout (in recalcStyle).
1299     Ref<FrameView> protectedThis(*this);
1300
1301     // Many of the tasks performed during layout can cause this function to be re-entered,
1302     // so save the layout phase now and restore it on exit.
1303     SetForScope<LayoutPhase> layoutPhaseRestorer(m_layoutPhase, InPreLayout);
1304
1305     // Every scroll that happens during layout is programmatic.
1306     SetForScope<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
1307
1308     bool inChildFrameLayoutWithFrameFlattening = isInChildFrameWithFrameFlattening();
1309
1310     if (inChildFrameLayoutWithFrameFlattening) {
1311         startLayoutAtMainFrameViewIfNeeded(allowSubtree);
1312         RenderElement* root = m_layoutRoot ? m_layoutRoot : frame().document()->renderView();
1313         if (!root || !root->needsLayout())
1314             return;
1315     }
1316     
1317     TraceScope tracingScope(LayoutStart, LayoutEnd);
1318
1319 #if PLATFORM(IOS)
1320     if (updateFixedPositionLayoutRect())
1321         allowSubtree = false;
1322 #endif
1323
1324     m_layoutTimer.stop();
1325     m_delayedLayout = false;
1326     m_setNeedsLayoutWasDeferred = false;
1327     
1328     // we shouldn't enter layout() while painting
1329     ASSERT(!isPainting());
1330     if (isPainting())
1331         return;
1332
1333     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(frame());
1334     AnimationUpdateBlock animationUpdateBlock(&frame().animation());
1335     
1336     if (!allowSubtree && m_layoutRoot)
1337         convertSubtreeLayoutToFullLayout();
1338
1339     ASSERT(frame().view() == this);
1340     ASSERT(frame().document());
1341
1342     Document& document = *frame().document();
1343     ASSERT(document.pageCacheState() == Document::NotInPageCache);
1344
1345     {
1346         SetForScope<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
1347
1348         if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive() && !inChildFrameLayoutWithFrameFlattening) {
1349             // This is a new top-level layout. If there are any remaining tasks from the previous
1350             // layout, finish them now.
1351             SetForScope<bool> inSynchronousPostLayoutChange(m_inSynchronousPostLayout, true);
1352             performPostLayoutTasks();
1353         }
1354
1355         m_layoutPhase = InPreLayoutStyleUpdate;
1356
1357         // Viewport-dependent media queries may cause us to need completely different style information.
1358         auto* styleResolver = document.styleScope().resolverIfExists();
1359         if (!styleResolver || styleResolver->hasMediaQueriesAffectedByViewportChange()) {
1360             LOG(Layout, "  hasMediaQueriesAffectedByViewportChange, enqueueing style recalc");
1361             document.styleScope().didChangeStyleSheetEnvironment();
1362             // FIXME: This instrumentation event is not strictly accurate since cached media query results do not persist across StyleResolver rebuilds.
1363             InspectorInstrumentation::mediaQueryResultChanged(document);
1364         } else
1365             document.evaluateMediaQueryList();
1366
1367         // If there is any pagination to apply, it will affect the RenderView's style, so we should
1368         // take care of that now.
1369         applyPaginationToViewport();
1370
1371         // Always ensure our style info is up-to-date. This can happen in situations where
1372         // the layout beats any sort of style recalc update that needs to occur.
1373         document.updateStyleIfNeeded();
1374         // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
1375         // so there's no point to continuing to layout
1376         if (hasOneRef())
1377             return;
1378
1379         // Close block here so we can set up the font cache purge preventer, which we will still
1380         // want in scope even after we want m_layoutSchedulingEnabled to be restored again.
1381         // The next block sets m_layoutSchedulingEnabled back to false once again.
1382     }
1383
1384     m_layoutPhase = InPreLayout;
1385
1386     RenderLayer* layer = nullptr;
1387     bool subtree = false;
1388     RenderElement* root = nullptr;
1389
1390     ++m_nestedLayoutCount;
1391
1392     {
1393         SetForScope<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
1394
1395         autoSizeIfEnabled();
1396
1397         root = m_layoutRoot ? m_layoutRoot : document.renderView();
1398         if (!root)
1399             return;
1400         subtree = m_layoutRoot;
1401
1402         if (!m_layoutRoot) {
1403             auto* body = document.bodyOrFrameset();
1404             if (body && body->renderer()) {
1405                 if (is<HTMLFrameSetElement>(*body) && !frameFlatteningEnabled()) {
1406                     body->renderer()->setChildNeedsLayout();
1407                 } else if (is<HTMLBodyElement>(*body)) {
1408                     if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox().stretchesToViewport())
1409                         body->renderer()->setChildNeedsLayout();
1410                 }
1411             }
1412
1413 #if !LOG_DISABLED
1414             if (m_firstLayout && !frame().ownerElement())
1415                 LOG(Layout, "FrameView %p elapsed time before first layout: %.3fs\n", this, document.timeSinceDocumentCreation().value());
1416 #endif
1417         }
1418
1419         m_needsFullRepaint = !subtree && (m_firstLayout || downcast<RenderView>(*root).printing());
1420
1421         if (!subtree) {
1422             ScrollbarMode hMode;
1423             ScrollbarMode vMode;    
1424             calculateScrollbarModesForLayout(hMode, vMode);
1425
1426             if (m_firstLayout || (hMode != horizontalScrollbarMode() || vMode != verticalScrollbarMode())) {
1427                 if (m_firstLayout) {
1428                     setScrollbarsSuppressed(true);
1429
1430                     m_firstLayout = false;
1431                     m_firstLayoutCallbackPending = true;
1432                     m_lastViewportSize = sizeForResizeEvent();
1433                     m_lastZoomFactor = root->style().zoom();
1434
1435                     // Set the initial vMode to AlwaysOn if we're auto.
1436                     if (vMode == ScrollbarAuto)
1437                         setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
1438                     // Set the initial hMode to AlwaysOff if we're auto.
1439                     if (hMode == ScrollbarAuto)
1440                         setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
1441                     Page* page = frame().page();
1442                     if (page && page->expectsWheelEventTriggers())
1443                         scrollAnimator().setWheelEventTestTrigger(page->testTrigger());
1444                     setScrollbarModes(hMode, vMode);
1445                     setScrollbarsSuppressed(false, true);
1446                 } else
1447                     setScrollbarModes(hMode, vMode);
1448             }
1449
1450             LayoutSize oldSize = m_size;
1451             m_size = layoutSize();
1452
1453             if (oldSize != m_size) {
1454                 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());
1455                 m_needsFullRepaint = true;
1456                 if (!m_firstLayout) {
1457                     RenderBox* rootRenderer = document.documentElement() ? document.documentElement()->renderBox() : nullptr;
1458                     auto* body = document.bodyOrFrameset();
1459                     RenderBox* bodyRenderer = rootRenderer && body ? body->renderBox() : nullptr;
1460                     if (bodyRenderer && bodyRenderer->stretchesToViewport())
1461                         bodyRenderer->setChildNeedsLayout();
1462                     else if (rootRenderer && rootRenderer->stretchesToViewport())
1463                         rootRenderer->setChildNeedsLayout();
1464                 }
1465             }
1466
1467             m_layoutPhase = InPreLayout;
1468         }
1469
1470         layer = root->enclosingLayer();
1471         SubtreeLayoutStateMaintainer subtreeLayoutStateMaintainer(m_layoutRoot);
1472
1473         RenderView::RepaintRegionAccumulator repaintRegionAccumulator(&root->view());
1474
1475         ASSERT(m_layoutPhase == InPreLayout);
1476         m_layoutPhase = InRenderTreeLayout;
1477
1478         forceLayoutParentViewIfNeeded();
1479
1480         ASSERT(m_layoutPhase == InRenderTreeLayout);
1481 #ifndef NDEBUG
1482         RenderTreeNeedsLayoutChecker checker(*root);
1483 #endif
1484         root->layout();
1485         ASSERT(!root->view().renderTreeIsBeingMutatedInternally());
1486
1487 #if ENABLE(TEXT_AUTOSIZING)
1488         if (frame().settings().textAutosizingEnabled() && !root->view().printing()) {
1489             float minimumZoomFontSize = frame().settings().minimumZoomFontSize();
1490             float textAutosizingWidth = frame().page() ? frame().page()->textAutosizingWidth() : 0;
1491             if (int overrideWidth = frame().settings().textAutosizingWindowSizeOverride().width())
1492                 textAutosizingWidth = overrideWidth;
1493
1494             LOG(TextAutosizing, "Text Autosizing: minimumZoomFontSize=%.2f textAutosizingWidth=%.2f", minimumZoomFontSize, textAutosizingWidth);
1495             
1496             if (minimumZoomFontSize && textAutosizingWidth) {
1497                 root->adjustComputedFontSizesOnBlocks(minimumZoomFontSize, textAutosizingWidth);
1498                 if (root->needsLayout())
1499                     root->layout();
1500             }
1501         }
1502 #endif
1503
1504         ASSERT(m_layoutPhase == InRenderTreeLayout);
1505         m_layoutRoot = nullptr;
1506         // Close block here to end the scope of changeSchedulingEnabled and SubtreeLayoutStateMaintainer.
1507     }
1508
1509     m_layoutPhase = InViewSizeAdjust;
1510
1511     bool neededFullRepaint = m_needsFullRepaint;
1512
1513     if (!subtree && !downcast<RenderView>(*root).printing())
1514         adjustViewSize();
1515
1516     m_layoutPhase = InPostLayout;
1517
1518     m_needsFullRepaint = neededFullRepaint;
1519
1520     // Now update the positions of all layers.
1521     if (m_needsFullRepaint)
1522         root->view().repaintRootContents();
1523
1524     root->view().releaseProtectedRenderWidgets();
1525
1526     ASSERT(!root->needsLayout());
1527
1528     layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layer, subtree, m_needsFullRepaint));
1529
1530     updateCompositingLayersAfterLayout();
1531
1532     m_layoutPhase = InPostLayerPositionsUpdatedAfterLayout;
1533
1534     m_layoutCount++;
1535
1536 #if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK)
1537     if (AXObjectCache* cache = root->document().existingAXObjectCache())
1538         cache->postNotification(root, AXObjectCache::AXLayoutComplete);
1539 #endif
1540
1541 #if ENABLE(DASHBOARD_SUPPORT)
1542     updateAnnotatedRegions();
1543 #endif
1544
1545 #if ENABLE(IOS_TOUCH_EVENTS)
1546     document.dirtyTouchEventRects();
1547 #endif
1548
1549     updateCanBlitOnScrollRecursively();
1550
1551     handleDeferredScrollUpdateAfterContentSizeChange();
1552
1553     handleDeferredScrollbarsUpdateAfterDirectionChange();
1554
1555     if (document.hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
1556         updateOverflowStatus(layoutWidth() < contentsWidth(), layoutHeight() < contentsHeight());
1557
1558     frame().document()->markers().invalidateRectsForAllMarkers();
1559
1560     if (!m_postLayoutTasksTimer.isActive()) {
1561         if (!m_inSynchronousPostLayout) {
1562             if (inChildFrameLayoutWithFrameFlattening)
1563                 updateWidgetPositions();
1564             else {
1565                 SetForScope<bool> inSynchronousPostLayoutChange(m_inSynchronousPostLayout, true);
1566                 performPostLayoutTasks(); // Calls resumeScheduledEvents().
1567             }
1568         }
1569
1570         if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout || inChildFrameLayoutWithFrameFlattening)) {
1571             // If we need layout or are already in a synchronous call to postLayoutTasks(), 
1572             // defer widget updates and event dispatch until after we return. postLayoutTasks()
1573             // can make us need to update again, and we can get stuck in a nasty cycle unless
1574             // we call it through the timer here.
1575             m_postLayoutTasksTimer.startOneShot(0);
1576             if (needsLayout())
1577                 layout();
1578         }
1579     }
1580
1581     InspectorInstrumentation::didLayout(cookie, *root);
1582     DebugPageOverlays::didLayout(frame());
1583
1584     --m_nestedLayoutCount;
1585 }
1586
1587 bool FrameView::shouldDeferScrollUpdateAfterContentSizeChange()
1588 {
1589     return (m_layoutPhase < InPostLayout) && (m_layoutPhase != OutsideLayout);
1590 }
1591
1592 RenderBox* FrameView::embeddedContentBox() const
1593 {
1594     RenderView* renderView = this->renderView();
1595     if (!renderView)
1596         return nullptr;
1597
1598     RenderObject* firstChild = renderView->firstChild();
1599
1600     // Curently only embedded SVG documents participate in the size-negotiation logic.
1601     if (is<RenderSVGRoot>(firstChild))
1602         return downcast<RenderSVGRoot>(firstChild);
1603
1604     return nullptr;
1605 }
1606
1607 void FrameView::addEmbeddedObjectToUpdate(RenderEmbeddedObject& embeddedObject)
1608 {
1609     if (!m_embeddedObjectsToUpdate)
1610         m_embeddedObjectsToUpdate = std::make_unique<ListHashSet<RenderEmbeddedObject*>>();
1611
1612     HTMLFrameOwnerElement& element = embeddedObject.frameOwnerElement();
1613     if (is<HTMLObjectElement>(element) || is<HTMLEmbedElement>(element)) {
1614         // Tell the DOM element that it needs a widget update.
1615         HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
1616         if (!pluginElement.needsCheckForSizeChange())
1617             pluginElement.setNeedsWidgetUpdate(true);
1618     }
1619
1620     m_embeddedObjectsToUpdate->add(&embeddedObject);
1621 }
1622
1623 void FrameView::removeEmbeddedObjectToUpdate(RenderEmbeddedObject& embeddedObject)
1624 {
1625     if (!m_embeddedObjectsToUpdate)
1626         return;
1627
1628     m_embeddedObjectsToUpdate->remove(&embeddedObject);
1629 }
1630
1631 void FrameView::setMediaType(const String& mediaType)
1632 {
1633     m_mediaType = mediaType;
1634 }
1635
1636 String FrameView::mediaType() const
1637 {
1638     // See if we have an override type.
1639     String overrideType = frame().loader().client().overrideMediaType();
1640     InspectorInstrumentation::applyEmulatedMedia(frame(), overrideType);
1641     if (!overrideType.isNull())
1642         return overrideType;
1643     return m_mediaType;
1644 }
1645
1646 void FrameView::adjustMediaTypeForPrinting(bool printing)
1647 {
1648     if (printing) {
1649         if (m_mediaTypeWhenNotPrinting.isNull())
1650             m_mediaTypeWhenNotPrinting = mediaType();
1651         setMediaType("print");
1652     } else {
1653         if (!m_mediaTypeWhenNotPrinting.isNull())
1654             setMediaType(m_mediaTypeWhenNotPrinting);
1655         m_mediaTypeWhenNotPrinting = String();
1656     }
1657 }
1658
1659 bool FrameView::useSlowRepaints(bool considerOverlap) const
1660 {
1661     bool mustBeSlow = hasSlowRepaintObjects() || (platformWidget() && hasViewportConstrainedObjects());
1662
1663     // FIXME: WidgetMac.mm makes the assumption that useSlowRepaints ==
1664     // m_contentIsOpaque, so don't take the fast path for composited layers
1665     // if they are a platform widget in order to get painting correctness
1666     // for transparent layers. See the comment in WidgetMac::paint.
1667     if (usesCompositedScrolling() && !platformWidget())
1668         return mustBeSlow;
1669
1670     bool isOverlapped = m_isOverlapped && considerOverlap;
1671
1672     if (mustBeSlow || m_cannotBlitToWindow || isOverlapped || !m_contentIsOpaque)
1673         return true;
1674
1675     if (FrameView* parentView = parentFrameView())
1676         return parentView->useSlowRepaints(considerOverlap);
1677
1678     return false;
1679 }
1680
1681 bool FrameView::useSlowRepaintsIfNotOverlapped() const
1682 {
1683     return useSlowRepaints(false);
1684 }
1685
1686 void FrameView::updateCanBlitOnScrollRecursively()
1687 {
1688     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
1689         if (FrameView* view = frame->view())
1690             view->setCanBlitOnScroll(!view->useSlowRepaints());
1691     }
1692 }
1693
1694 bool FrameView::usesCompositedScrolling() const
1695 {
1696     RenderView* renderView = this->renderView();
1697     if (renderView && renderView->isComposited()) {
1698         GraphicsLayer* layer = renderView->layer()->backing()->graphicsLayer();
1699         if (layer && layer->drawsContent())
1700             return true;
1701     }
1702
1703     return false;
1704 }
1705
1706 bool FrameView::usesAsyncScrolling() const
1707 {
1708 #if ENABLE(ASYNC_SCROLLING)
1709     if (Page* page = frame().page()) {
1710         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1711             return scrollingCoordinator->coordinatesScrollingForFrameView(*this);
1712     }
1713 #endif
1714     return false;
1715 }
1716
1717 bool FrameView::usesMockScrollAnimator() const
1718 {
1719     return Settings::usesMockScrollAnimator();
1720 }
1721
1722 void FrameView::logMockScrollAnimatorMessage(const String& message) const
1723 {
1724     Document* document = frame().document();
1725     if (!document)
1726         return;
1727     StringBuilder builder;
1728     if (frame().isMainFrame())
1729         builder.appendLiteral("Main");
1730     builder.appendLiteral("FrameView: ");
1731     builder.append(message);
1732     document->addConsoleMessage(MessageSource::Other, MessageLevel::Debug, builder.toString());
1733 }
1734
1735 void FrameView::setCannotBlitToWindow()
1736 {
1737     m_cannotBlitToWindow = true;
1738     updateCanBlitOnScrollRecursively();
1739 }
1740
1741 void FrameView::addSlowRepaintObject(RenderElement* o)
1742 {
1743     bool hadSlowRepaintObjects = hasSlowRepaintObjects();
1744
1745     if (!m_slowRepaintObjects)
1746         m_slowRepaintObjects = std::make_unique<HashSet<const RenderElement*>>();
1747
1748     m_slowRepaintObjects->add(o);
1749
1750     if (!hadSlowRepaintObjects) {
1751         updateCanBlitOnScrollRecursively();
1752
1753         if (Page* page = frame().page()) {
1754             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1755                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(*this);
1756         }
1757     }
1758 }
1759
1760 void FrameView::removeSlowRepaintObject(RenderElement* o)
1761 {
1762     if (!m_slowRepaintObjects)
1763         return;
1764
1765     m_slowRepaintObjects->remove(o);
1766     if (m_slowRepaintObjects->isEmpty()) {
1767         m_slowRepaintObjects = nullptr;
1768         updateCanBlitOnScrollRecursively();
1769
1770         if (Page* page = frame().page()) {
1771             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1772                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(*this);
1773         }
1774     }
1775 }
1776
1777 void FrameView::addViewportConstrainedObject(RenderElement* object)
1778 {
1779     if (!m_viewportConstrainedObjects)
1780         m_viewportConstrainedObjects = std::make_unique<ViewportConstrainedObjectSet>();
1781
1782     if (!m_viewportConstrainedObjects->contains(object)) {
1783         m_viewportConstrainedObjects->add(object);
1784         if (platformWidget())
1785             updateCanBlitOnScrollRecursively();
1786
1787         if (Page* page = frame().page()) {
1788             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1789                 scrollingCoordinator->frameViewFixedObjectsDidChange(*this);
1790         }
1791     }
1792 }
1793
1794 void FrameView::removeViewportConstrainedObject(RenderElement* object)
1795 {
1796     if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->remove(object)) {
1797         if (Page* page = frame().page()) {
1798             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1799                 scrollingCoordinator->frameViewFixedObjectsDidChange(*this);
1800         }
1801
1802         // FIXME: In addFixedObject() we only call this if there's a platform widget,
1803         // why isn't the same check being made here?
1804         updateCanBlitOnScrollRecursively();
1805     }
1806 }
1807
1808 // visualViewport and layoutViewport are both in content coordinates (unzoomed).
1809 LayoutPoint FrameView::computeLayoutViewportOrigin(const LayoutRect& visualViewport, const LayoutPoint& stableLayoutViewportOriginMin, const LayoutPoint& stableLayoutViewportOriginMax, const LayoutRect& layoutViewport, ScrollBehaviorForFixedElements fixedBehavior)
1810 {
1811     LayoutPoint layoutViewportOrigin = layoutViewport.location();
1812     bool allowRubberBanding = fixedBehavior == StickToViewportBounds;
1813
1814     if (visualViewport.width() > layoutViewport.width())
1815         layoutViewportOrigin.setX(visualViewport.x());
1816     else {
1817         bool rubberbandingAtLeft = allowRubberBanding && visualViewport.x() < stableLayoutViewportOriginMin.x();
1818         bool rubberbandingAtRight = allowRubberBanding && (visualViewport.maxX() - layoutViewport.width()) > stableLayoutViewportOriginMax.x();
1819
1820         if (visualViewport.x() < layoutViewport.x() || rubberbandingAtLeft)
1821             layoutViewportOrigin.setX(visualViewport.x());
1822
1823         if (visualViewport.maxX() > layoutViewport.maxX() || rubberbandingAtRight)
1824             layoutViewportOrigin.setX(visualViewport.maxX() - layoutViewport.width());
1825         
1826         if (!rubberbandingAtLeft && layoutViewportOrigin.x() < stableLayoutViewportOriginMin.x())
1827             layoutViewportOrigin.setX(stableLayoutViewportOriginMin.x());
1828         
1829         if (!rubberbandingAtRight && layoutViewportOrigin.x() > stableLayoutViewportOriginMax.x())
1830             layoutViewportOrigin.setX(stableLayoutViewportOriginMax.x());
1831     }
1832
1833     if (visualViewport.height() > layoutViewport.height())
1834         layoutViewportOrigin.setY(visualViewport.y());
1835     else {
1836         bool rubberbandingAtTop = allowRubberBanding && visualViewport.y() < stableLayoutViewportOriginMin.y();
1837         bool rubberbandingAtBottom = allowRubberBanding && (visualViewport.maxY() - layoutViewport.height()) > stableLayoutViewportOriginMax.y();
1838
1839         if (visualViewport.y() < layoutViewport.y() || rubberbandingAtTop)
1840             layoutViewportOrigin.setY(visualViewport.y());
1841
1842         if (visualViewport.maxY() > layoutViewport.maxY() || rubberbandingAtBottom)
1843             layoutViewportOrigin.setY(visualViewport.maxY() - layoutViewport.height());
1844         
1845         if (!rubberbandingAtTop && layoutViewportOrigin.y() < stableLayoutViewportOriginMin.y())
1846             layoutViewportOrigin.setY(stableLayoutViewportOriginMin.y());
1847         
1848         if (!rubberbandingAtBottom && layoutViewportOrigin.y() > stableLayoutViewportOriginMax.y())
1849             layoutViewportOrigin.setY(stableLayoutViewportOriginMax.y());
1850     }
1851
1852     return layoutViewportOrigin;
1853 }
1854
1855 void FrameView::setBaseLayoutViewportOrigin(LayoutPoint origin, TriggerLayoutOrNot layoutTriggering)
1856 {
1857     ASSERT(frame().settings().visualViewportEnabled());
1858
1859     if (origin == m_layoutViewportOrigin)
1860         return;
1861
1862     m_layoutViewportOrigin = origin;
1863     if (layoutTriggering == TriggerLayoutOrNot::Yes)
1864         setViewportConstrainedObjectsNeedLayout();
1865     
1866     if (TiledBacking* tiledBacking = this->tiledBacking()) {
1867         FloatRect layoutViewport = layoutViewportRect();
1868         layoutViewport.moveBy(unscaledScrollOrigin()); // tiledBacking deals in top-left relative coordinates.
1869         tiledBacking->setLayoutViewportRect(layoutViewport);
1870     }
1871 }
1872
1873 void FrameView::setLayoutViewportOverrideRect(std::optional<LayoutRect> rect)
1874 {
1875     if (rect == m_layoutViewportOverrideRect)
1876         return;
1877
1878     LayoutRect oldRect = layoutViewportRect();
1879     m_layoutViewportOverrideRect = rect;
1880
1881     LOG_WITH_STREAM(Scrolling, stream << "\nFrameView " << this << " setLayoutViewportOverrideRect() - changing layout viewport from " << oldRect << " to " << m_layoutViewportOverrideRect.value());
1882
1883     if (oldRect != layoutViewportRect())
1884         setViewportConstrainedObjectsNeedLayout();
1885 }
1886
1887 LayoutSize FrameView::baseLayoutViewportSize() const
1888 {
1889     return renderView() ? renderView()->size() : size();
1890 }
1891
1892 void FrameView::updateLayoutViewport()
1893 {
1894     if (!frame().settings().visualViewportEnabled())
1895         return;
1896     
1897     // Don't update the layout viewport if we're in the middle of adjusting scrollbars. We'll get another call
1898     // as a post-layout task.
1899     if (m_layoutPhase == InViewSizeAdjust)
1900         return;
1901     
1902     if (m_layoutViewportOverrideRect) {
1903         LOG_WITH_STREAM(Scrolling, stream << "\nFrameView " << this << " updateLayoutViewport() - has layoutViewportOverrideRect" << m_layoutViewportOverrideRect.value());
1904         return;
1905     }
1906
1907     LayoutRect layoutViewport = layoutViewportRect();
1908
1909     LOG_WITH_STREAM(Scrolling, stream << "\nFrameView " << this << " updateLayoutViewport() totalContentSize " << totalContentsSize() << " unscaledDocumentRect " << (renderView() ? renderView()->unscaledDocumentRect() : IntRect()) << " header height " << headerHeight() << " footer height " << footerHeight() << " fixed behavior " << scrollBehaviorForFixedElements());
1910     LOG_WITH_STREAM(Scrolling, stream << "layoutViewport: " << layoutViewport);
1911     LOG_WITH_STREAM(Scrolling, stream << "visualViewport: " << visualViewportRect());
1912     LOG_WITH_STREAM(Scrolling, stream << "scroll positions: min: " << unscaledMinimumScrollPosition() << " max: "<< unscaledMaximumScrollPosition());
1913
1914     LayoutPoint newLayoutViewportOrigin = computeLayoutViewportOrigin(visualViewportRect(), minStableLayoutViewportOrigin(), maxStableLayoutViewportOrigin(), layoutViewport, scrollBehaviorForFixedElements());
1915     if (newLayoutViewportOrigin != m_layoutViewportOrigin) {
1916         setBaseLayoutViewportOrigin(newLayoutViewportOrigin);
1917         LOG_WITH_STREAM(Scrolling, stream << "layoutViewport changed to " << layoutViewportRect());
1918     }
1919 }
1920
1921 LayoutPoint FrameView::minStableLayoutViewportOrigin() const
1922 {
1923     return unscaledMinimumScrollPosition();
1924 }
1925
1926 LayoutPoint FrameView::maxStableLayoutViewportOrigin() const
1927 {
1928     LayoutPoint maxPosition = unscaledMaximumScrollPosition();
1929     maxPosition = (maxPosition - LayoutSize(0, headerHeight() + footerHeight())).expandedTo({ });
1930     return maxPosition;
1931 }
1932
1933 IntPoint FrameView::unscaledScrollOrigin() const
1934 {
1935     if (RenderView* renderView = this->renderView())
1936         return -renderView->unscaledDocumentRect().location(); // Akin to code in adjustViewSize().
1937
1938     return { };
1939 }
1940
1941 LayoutRect FrameView::layoutViewportRect() const
1942 {
1943     if (m_layoutViewportOverrideRect)
1944         return m_layoutViewportOverrideRect.value();
1945
1946     // Size of initial containing block, anchored at scroll position, in document coordinates (unchanged by scale factor).
1947     return LayoutRect(m_layoutViewportOrigin, renderView() ? renderView()->size() : size());
1948 }
1949
1950 // visibleContentRect is in the bounds of the scroll view content. That consists of an
1951 // optional header, the document, and an optional footer. Only the document is scaled,
1952 // so we have to compute the visible part of the document in unscaled document coordinates.
1953 // On iOS, pageScaleFactor is always 1 here, and we never have headers and footers.
1954 LayoutRect FrameView::visibleDocumentRect(const FloatRect& visibleContentRect, float headerHeight, float footerHeight, const FloatSize& totalContentsSize, float pageScaleFactor)
1955 {
1956     float contentsHeight = totalContentsSize.height() - headerHeight - footerHeight;
1957
1958     float rubberBandTop = std::min<float>(visibleContentRect.y(), 0);
1959     float visibleScaledDocumentTop = std::max<float>(visibleContentRect.y() - headerHeight, 0) + rubberBandTop;
1960     
1961     float rubberBandBottom = std::min<float>((totalContentsSize.height() - visibleContentRect.y()) - visibleContentRect.height(), 0);
1962     float visibleScaledDocumentBottom = std::min<float>(visibleContentRect.maxY() - headerHeight, contentsHeight) - rubberBandBottom;
1963
1964     FloatRect visibleDocumentRect = visibleContentRect;
1965     visibleDocumentRect.setY(visibleScaledDocumentTop);
1966     visibleDocumentRect.setHeight(std::max<float>(visibleScaledDocumentBottom - visibleScaledDocumentTop, 0));
1967     visibleDocumentRect.scale(1 / pageScaleFactor);
1968     
1969     return LayoutRect(visibleDocumentRect);
1970 }
1971
1972 LayoutRect FrameView::visualViewportRect() const
1973 {
1974     FloatRect visibleContentRect = this->visibleContentRect(LegacyIOSDocumentVisibleRect);
1975     return visibleDocumentRect(visibleContentRect, headerHeight(), footerHeight(), totalContentsSize(), frameScaleFactor());
1976 }
1977
1978 LayoutRect FrameView::viewportConstrainedVisibleContentRect() const
1979 {
1980     ASSERT(!frame().settings().visualViewportEnabled());
1981
1982 #if PLATFORM(IOS)
1983     if (useCustomFixedPositionLayoutRect())
1984         return customFixedPositionLayoutRect();
1985 #endif
1986     LayoutRect viewportRect = visibleContentRect();
1987
1988     viewportRect.setLocation(scrollPositionForFixedPosition());
1989     return viewportRect;
1990 }
1991
1992 LayoutRect FrameView::rectForFixedPositionLayout() const
1993 {
1994     if (frame().settings().visualViewportEnabled())
1995         return layoutViewportRect();
1996
1997     return viewportConstrainedVisibleContentRect();
1998 }
1999
2000 float FrameView::frameScaleFactor() const
2001 {
2002     return frame().frameScaleFactor();
2003 }
2004
2005 LayoutPoint FrameView::scrollPositionForFixedPosition() const
2006 {
2007     if (frame().settings().visualViewportEnabled())
2008         return layoutViewportRect().location();
2009
2010     return scrollPositionForFixedPosition(visibleContentRect(), totalContentsSize(), scrollPosition(), scrollOrigin(), frameScaleFactor(), fixedElementsLayoutRelativeToFrame(), scrollBehaviorForFixedElements(), headerHeight(), footerHeight());
2011 }
2012
2013 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)
2014 {
2015     LayoutPoint position;
2016     if (behaviorForFixed == StickToDocumentBounds)
2017         position = ScrollableArea::constrainScrollPositionForOverhang(visibleContentRect, totalContentsSize, scrollPosition, scrollOrigin, headerHeight, footerHeight);
2018     else {
2019         position = scrollPosition;
2020         position.setY(position.y() - headerHeight);
2021     }
2022
2023     LayoutSize maxSize = totalContentsSize - visibleContentRect.size();
2024
2025     float dragFactorX = (fixedElementsLayoutRelativeToFrame || !maxSize.width()) ? 1 : (totalContentsSize.width() - visibleContentRect.width() * frameScaleFactor) / maxSize.width();
2026     float dragFactorY = (fixedElementsLayoutRelativeToFrame || !maxSize.height()) ? 1 : (totalContentsSize.height() - visibleContentRect.height() * frameScaleFactor) / maxSize.height();
2027
2028     return LayoutPoint(position.x() * dragFactorX / frameScaleFactor, position.y() * dragFactorY / frameScaleFactor);
2029 }
2030
2031 float FrameView::yPositionForInsetClipLayer(const FloatPoint& scrollPosition, float topContentInset)
2032 {
2033     if (!topContentInset)
2034         return 0;
2035
2036     // The insetClipLayer should not move for negative scroll values.
2037     float scrollY = std::max<float>(0, scrollPosition.y());
2038
2039     if (scrollY >= topContentInset)
2040         return 0;
2041
2042     return topContentInset - scrollY;
2043 }
2044
2045 float FrameView::yPositionForHeaderLayer(const FloatPoint& scrollPosition, float topContentInset)
2046 {
2047     if (!topContentInset)
2048         return 0;
2049
2050     float scrollY = std::max<float>(0, scrollPosition.y());
2051
2052     if (scrollY >= topContentInset)
2053         return topContentInset;
2054
2055     return scrollY;
2056 }
2057
2058 float FrameView::yPositionForFooterLayer(const FloatPoint& scrollPosition, float topContentInset, float totalContentsHeight, float footerHeight)
2059 {
2060     return yPositionForHeaderLayer(scrollPosition, topContentInset) + totalContentsHeight - footerHeight;
2061 }
2062
2063 FloatPoint FrameView::positionForRootContentLayer(const FloatPoint& scrollPosition, const FloatPoint& scrollOrigin, float topContentInset, float headerHeight)
2064 {
2065     return FloatPoint(0, yPositionForHeaderLayer(scrollPosition, topContentInset) + headerHeight) - toFloatSize(scrollOrigin);
2066 }
2067
2068 FloatPoint FrameView::positionForRootContentLayer() const
2069 {
2070     return positionForRootContentLayer(scrollPosition(), scrollOrigin(), topContentInset(), headerHeight());
2071 }
2072
2073 #if PLATFORM(IOS)
2074 LayoutRect FrameView::rectForViewportConstrainedObjects(const LayoutRect& visibleContentRect, const LayoutSize& totalContentsSize, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame, ScrollBehaviorForFixedElements scrollBehavior)
2075 {
2076     if (fixedElementsLayoutRelativeToFrame)
2077         return visibleContentRect;
2078     
2079     if (totalContentsSize.isEmpty())
2080         return visibleContentRect;
2081
2082     // We impose an lower limit on the size (so an upper limit on the scale) of
2083     // the rect used to position fixed objects so that they don't crowd into the
2084     // center of the screen at larger scales.
2085     const LayoutUnit maxContentWidthForZoomThreshold = LayoutUnit::fromPixel(1024);
2086     float zoomedOutScale = frameScaleFactor * visibleContentRect.width() / std::min(maxContentWidthForZoomThreshold, totalContentsSize.width());
2087     float constraintThresholdScale = 1.5 * zoomedOutScale;
2088     float maxPostionedObjectsRectScale = std::min(frameScaleFactor, constraintThresholdScale);
2089
2090     LayoutRect viewportConstrainedObjectsRect = visibleContentRect;
2091
2092     if (frameScaleFactor > constraintThresholdScale) {
2093         FloatRect contentRect(FloatPoint(), totalContentsSize);
2094         FloatRect viewportRect = visibleContentRect;
2095         
2096         // Scale the rect up from a point that is relative to its position in the viewport.
2097         FloatSize sizeDelta = contentRect.size() - viewportRect.size();
2098
2099         FloatPoint scaleOrigin;
2100         scaleOrigin.setX(contentRect.x() + sizeDelta.width() > 0 ? contentRect.width() * (viewportRect.x() - contentRect.x()) / sizeDelta.width() : 0);
2101         scaleOrigin.setY(contentRect.y() + sizeDelta.height() > 0 ? contentRect.height() * (viewportRect.y() - contentRect.y()) / sizeDelta.height() : 0);
2102         
2103         AffineTransform rescaleTransform = AffineTransform::translation(scaleOrigin.x(), scaleOrigin.y());
2104         rescaleTransform.scale(frameScaleFactor / maxPostionedObjectsRectScale, frameScaleFactor / maxPostionedObjectsRectScale);
2105         rescaleTransform = CGAffineTransformTranslate(rescaleTransform, -scaleOrigin.x(), -scaleOrigin.y());
2106
2107         viewportConstrainedObjectsRect = enclosingLayoutRect(rescaleTransform.mapRect(visibleContentRect));
2108     }
2109     
2110     if (scrollBehavior == StickToDocumentBounds) {
2111         LayoutRect documentBounds(LayoutPoint(), totalContentsSize);
2112         viewportConstrainedObjectsRect.intersect(documentBounds);
2113     }
2114
2115     return viewportConstrainedObjectsRect;
2116 }
2117     
2118 LayoutRect FrameView::viewportConstrainedObjectsRect() const
2119 {
2120     return rectForViewportConstrainedObjects(visibleContentRect(), totalContentsSize(), frame().frameScaleFactor(), fixedElementsLayoutRelativeToFrame(), scrollBehaviorForFixedElements());
2121 }
2122 #endif
2123     
2124 ScrollPosition FrameView::minimumScrollPosition() const
2125 {
2126     ScrollPosition minimumPosition = ScrollView::minimumScrollPosition();
2127
2128     if (frame().isMainFrame() && m_scrollPinningBehavior == PinToBottom)
2129         minimumPosition.setY(maximumScrollPosition().y());
2130     
2131     return minimumPosition;
2132 }
2133
2134 ScrollPosition FrameView::maximumScrollPosition() const
2135 {
2136     ScrollPosition maximumPosition = ScrollView::maximumScrollPosition();
2137
2138     if (frame().isMainFrame() && m_scrollPinningBehavior == PinToTop)
2139         maximumPosition.setY(minimumScrollPosition().y());
2140     
2141     return maximumPosition;
2142 }
2143
2144 ScrollPosition FrameView::unscaledMinimumScrollPosition() const
2145 {
2146     if (RenderView* renderView = this->renderView()) {
2147         IntRect unscaledDocumentRect = renderView->unscaledDocumentRect();
2148         ScrollPosition minimumPosition = unscaledDocumentRect.location();
2149
2150         if (frame().isMainFrame() && m_scrollPinningBehavior == PinToBottom)
2151             minimumPosition.setY(unscaledMaximumScrollPosition().y());
2152
2153         return minimumPosition;
2154     }
2155
2156     return minimumScrollPosition();
2157 }
2158
2159 ScrollPosition FrameView::unscaledMaximumScrollPosition() const
2160 {
2161     if (RenderView* renderView = this->renderView()) {
2162         IntRect unscaledDocumentRect = renderView->unscaledDocumentRect();
2163         unscaledDocumentRect.expand(0, headerHeight() + footerHeight());
2164         ScrollPosition maximumPosition = ScrollPosition(unscaledDocumentRect.maxXMaxYCorner() - visibleSize()).expandedTo({ 0, 0 });
2165
2166         if (frame().isMainFrame() && m_scrollPinningBehavior == PinToTop)
2167             maximumPosition.setY(unscaledMinimumScrollPosition().y());
2168
2169         return maximumPosition;
2170     }
2171
2172     return maximumScrollPosition();
2173 }
2174
2175 void FrameView::viewportContentsChanged()
2176 {
2177     if (!frame().view()) {
2178         // The frame is being destroyed.
2179         return;
2180     }
2181
2182     if (auto* page = frame().page())
2183         page->updateValidationBubbleStateIfNeeded();
2184
2185     // When the viewport contents changes (scroll, resize, style recalc, layout, ...),
2186     // check if we should resume animated images or unthrottle DOM timers.
2187     applyRecursivelyWithVisibleRect([] (FrameView& frameView, const IntRect& visibleRect) {
2188         frameView.resumeVisibleImageAnimations(visibleRect);
2189         frameView.updateScriptedAnimationsAndTimersThrottlingState(visibleRect);
2190
2191         if (auto* renderView = frameView.frame().contentRenderer())
2192             renderView->updateVisibleViewportRect(visibleRect);
2193     });
2194 }
2195
2196 bool FrameView::fixedElementsLayoutRelativeToFrame() const
2197 {
2198     return frame().settings().fixedElementsLayoutRelativeToFrame();
2199 }
2200
2201 IntPoint FrameView::lastKnownMousePosition() const
2202 {
2203     return frame().eventHandler().lastKnownMousePosition();
2204 }
2205
2206 bool FrameView::isHandlingWheelEvent() const
2207 {
2208     return frame().eventHandler().isHandlingWheelEvent();
2209 }
2210
2211 bool FrameView::shouldSetCursor() const
2212 {
2213     Page* page = frame().page();
2214     return page && page->isVisible() && page->focusController().isActive();
2215 }
2216
2217 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
2218 {
2219     if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty()) {
2220         frame().page()->chrome().scroll(scrollDelta, rectToScroll, clipRect);
2221         return true;
2222     }
2223
2224     bool isCompositedContentLayer = usesCompositedScrolling();
2225
2226     // Get the rects of the fixed objects visible in the rectToScroll
2227     Region regionToUpdate;
2228     for (auto& renderer : *m_viewportConstrainedObjects) {
2229         if (!renderer->style().hasViewportConstrainedPosition())
2230             continue;
2231         if (renderer->isComposited())
2232             continue;
2233
2234         // Fixed items should always have layers.
2235         ASSERT(renderer->hasLayer());
2236         RenderLayer* layer = downcast<RenderBoxModelObject>(*renderer).layer();
2237
2238         if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForBoundsOutOfView
2239             || layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForNoVisibleContent) {
2240             // Don't invalidate for invisible fixed layers.
2241             continue;
2242         }
2243
2244         if (layer->hasAncestorWithFilterOutsets()) {
2245             // If the fixed layer has a blur/drop-shadow filter applied on at least one of its parents, we cannot 
2246             // scroll using the fast path, otherwise the outsets of the filter will be moved around the page.
2247             return false;
2248         }
2249
2250         // FIXME: use pixel snapping instead of enclosing when ScrollView has finished transitioning from IntRect to Float/LayoutRect.
2251         IntRect updateRect = enclosingIntRect(layer->repaintRectIncludingNonCompositingDescendants());
2252         updateRect = contentsToRootView(updateRect);
2253         if (!isCompositedContentLayer && clipsRepaints())
2254             updateRect.intersect(rectToScroll);
2255         if (!updateRect.isEmpty())
2256             regionToUpdate.unite(updateRect);
2257     }
2258
2259     // 1) scroll
2260     frame().page()->chrome().scroll(scrollDelta, rectToScroll, clipRect);
2261
2262     // 2) update the area of fixed objects that has been invalidated
2263     for (auto& updateRect : regionToUpdate.rects()) {
2264         IntRect scrolledRect = updateRect;
2265         scrolledRect.move(scrollDelta);
2266         updateRect.unite(scrolledRect);
2267         if (isCompositedContentLayer) {
2268             updateRect = rootViewToContents(updateRect);
2269             ASSERT(renderView());
2270             renderView()->layer()->setBackingNeedsRepaintInRect(updateRect);
2271             continue;
2272         }
2273         if (clipsRepaints())
2274             updateRect.intersect(rectToScroll);
2275         frame().page()->chrome().invalidateContentsAndRootView(updateRect);
2276     }
2277
2278     return true;
2279 }
2280
2281 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
2282 {
2283     repaintSlowRepaintObjects();
2284
2285     if (!usesCompositedScrolling() && isEnclosedInCompositingLayer()) {
2286         if (RenderWidget* frameRenderer = frame().ownerRenderer()) {
2287             LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(), frameRenderer->borderTop() + frameRenderer->paddingTop(),
2288                 visibleWidth(), visibleHeight());
2289             frameRenderer->repaintRectangle(rect);
2290             return;
2291         }
2292     }
2293
2294     ScrollView::scrollContentsSlowPath(updateRect);
2295 }
2296
2297 void FrameView::repaintSlowRepaintObjects()
2298 {
2299     if (!m_slowRepaintObjects)
2300         return;
2301
2302     // Renderers with fixed backgrounds may be in compositing layers, so we need to explicitly
2303     // repaint them after scrolling.
2304     for (auto& renderer : *m_slowRepaintObjects)
2305         renderer->repaintSlowRepaintObject();
2306 }
2307
2308 // Note that this gets called at painting time.
2309 void FrameView::setIsOverlapped(bool isOverlapped)
2310 {
2311     if (isOverlapped == m_isOverlapped)
2312         return;
2313
2314     m_isOverlapped = isOverlapped;
2315     updateCanBlitOnScrollRecursively();
2316 }
2317
2318 void FrameView::setContentIsOpaque(bool contentIsOpaque)
2319 {
2320     if (contentIsOpaque == m_contentIsOpaque)
2321         return;
2322
2323     m_contentIsOpaque = contentIsOpaque;
2324     updateCanBlitOnScrollRecursively();
2325 }
2326
2327 void FrameView::restoreScrollbar()
2328 {
2329     setScrollbarsSuppressed(false);
2330 }
2331
2332 bool FrameView::scrollToFragment(const URL& url)
2333 {
2334     // If our URL has no ref, then we have no place we need to jump to.
2335     // OTOH If CSS target was set previously, we want to set it to 0, recalc
2336     // and possibly repaint because :target pseudo class may have been
2337     // set (see bug 11321).
2338     if (!url.hasFragmentIdentifier()) {
2339         frame().document()->setCSSTarget(nullptr);
2340         return false;
2341     }
2342
2343     String fragmentIdentifier = url.fragmentIdentifier();
2344     if (scrollToAnchor(fragmentIdentifier))
2345         return true;
2346
2347     // Try again after decoding the ref, based on the document's encoding.
2348     if (TextResourceDecoder* decoder = frame().document()->decoder())
2349         return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding()));
2350
2351     return false;
2352 }
2353
2354 bool FrameView::scrollToAnchor(const String& name)
2355 {
2356     ASSERT(frame().document());
2357     auto& document = *frame().document();
2358
2359     if (!document.haveStylesheetsLoaded()) {
2360         document.setGotoAnchorNeededAfterStylesheetsLoad(true);
2361         return false;
2362     }
2363
2364     document.setGotoAnchorNeededAfterStylesheetsLoad(false);
2365
2366     Element* anchorElement = document.findAnchor(name);
2367
2368     // Setting to null will clear the current target.
2369     document.setCSSTarget(anchorElement);
2370
2371     if (is<SVGDocument>(document)) {
2372         if (auto* rootElement = SVGDocument::rootElement(document)) {
2373             rootElement->scrollToAnchor(name, anchorElement);
2374             if (!anchorElement)
2375                 return true;
2376         }
2377     }
2378
2379     // Implement the rule that "" and "top" both mean top of page as in other browsers.
2380     if (!anchorElement && !(name.isEmpty() || equalLettersIgnoringASCIICase(name, "top")))
2381         return false;
2382
2383     ContainerNode* scrollPositionAnchor = anchorElement;
2384     if (!scrollPositionAnchor)
2385         scrollPositionAnchor = frame().document();
2386     maintainScrollPositionAtAnchor(scrollPositionAnchor);
2387     
2388     // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
2389     if (anchorElement) {
2390         if (anchorElement->isFocusable())
2391             document.setFocusedElement(anchorElement);
2392         else {
2393             document.setFocusedElement(nullptr);
2394             document.setFocusNavigationStartingNode(anchorElement);
2395         }
2396     }
2397     
2398     return true;
2399 }
2400
2401 void FrameView::maintainScrollPositionAtAnchor(ContainerNode* anchorNode)
2402 {
2403     m_maintainScrollPositionAnchor = anchorNode;
2404     if (!m_maintainScrollPositionAnchor)
2405         return;
2406
2407     // We need to update the layout before scrolling, otherwise we could
2408     // really mess things up if an anchor scroll comes at a bad moment.
2409     frame().document()->updateStyleIfNeeded();
2410     // Only do a layout if changes have occurred that make it necessary.
2411     RenderView* renderView = this->renderView();
2412     if (renderView && renderView->needsLayout())
2413         layout();
2414     else
2415         scrollToAnchor();
2416 }
2417
2418 void FrameView::scrollElementToRect(const Element& element, const IntRect& rect)
2419 {
2420     frame().document()->updateLayoutIgnorePendingStylesheets();
2421
2422     LayoutRect bounds;
2423     if (RenderElement* renderer = element.renderer())
2424         bounds = renderer->absoluteAnchorRect();
2425     int centeringOffsetX = (rect.width() - bounds.width()) / 2;
2426     int centeringOffsetY = (rect.height() - bounds.height()) / 2;
2427     setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y()));
2428 }
2429
2430 void FrameView::setScrollPosition(const ScrollPosition& scrollPosition)
2431 {
2432     SetForScope<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
2433     m_maintainScrollPositionAnchor = nullptr;
2434     Page* page = frame().page();
2435     if (page && page->expectsWheelEventTriggers())
2436         scrollAnimator().setWheelEventTestTrigger(page->testTrigger());
2437     ScrollView::setScrollPosition(scrollPosition);
2438 }
2439
2440 void FrameView::contentsResized()
2441 {
2442     // For non-delegated scrolling, updateTiledBackingAdaptiveSizing() is called via addedOrRemovedScrollbar() which occurs less often.
2443     if (delegatesScrolling())
2444         updateTiledBackingAdaptiveSizing();
2445 }
2446
2447 void FrameView::delegatesScrollingDidChange()
2448 {
2449     // When we switch to delgatesScrolling mode, we should destroy the scrolling/clipping layers in RenderLayerCompositor.
2450     if (hasCompositedContent())
2451         clearBackingStores();
2452 }
2453
2454 #if USE(COORDINATED_GRAPHICS)
2455 void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect)
2456 {
2457     bool visibleContentSizeDidChange = false;
2458     if (visibleContentRect.size() != this->fixedVisibleContentRect().size()) {
2459         // When the viewport size changes or the content is scaled, we need to
2460         // reposition the fixed and sticky positioned elements.
2461         setViewportConstrainedObjectsNeedLayout();
2462         visibleContentSizeDidChange = true;
2463     }
2464
2465     IntPoint oldPosition = scrollPosition();
2466     ScrollView::setFixedVisibleContentRect(visibleContentRect);
2467     IntPoint newPosition = scrollPosition();
2468     if (oldPosition != newPosition) {
2469         updateLayerPositionsAfterScrolling();
2470         if (frame().settings().acceleratedCompositingForFixedPositionEnabled())
2471             updateCompositingLayersAfterScrolling();
2472         scrollAnimator().setCurrentPosition(newPosition);
2473         scrollPositionChanged(oldPosition, newPosition);
2474     }
2475     if (visibleContentSizeDidChange) {
2476         // Update the scroll-bars to calculate new page-step size.
2477         updateScrollbars(scrollPosition());
2478     }
2479     didChangeScrollOffset();
2480 }
2481 #endif
2482
2483 void FrameView::setViewportConstrainedObjectsNeedLayout()
2484 {
2485     if (!hasViewportConstrainedObjects())
2486         return;
2487
2488     for (auto& renderer : *m_viewportConstrainedObjects)
2489         renderer->setNeedsLayout();
2490 }
2491
2492 void FrameView::didChangeScrollOffset()
2493 {
2494     frame().mainFrame().pageOverlayController().didScrollFrame(frame());
2495     frame().loader().client().didChangeScrollOffset();
2496 }
2497
2498 void FrameView::scrollOffsetChangedViaPlatformWidgetImpl(const ScrollOffset& oldOffset, const ScrollOffset& newOffset)
2499 {
2500     updateLayerPositionsAfterScrolling();
2501     updateCompositingLayersAfterScrolling();
2502     repaintSlowRepaintObjects();
2503     scrollPositionChanged(scrollPositionFromOffset(oldOffset), scrollPositionFromOffset(newOffset));
2504 }
2505
2506 // These scroll positions are affected by zooming.
2507 void FrameView::scrollPositionChanged(const ScrollPosition& oldPosition, const ScrollPosition& newPosition)
2508 {
2509     Page* page = frame().page();
2510     Seconds throttlingDelay = page ? page->chrome().client().eventThrottlingDelay() : 0_s;
2511
2512     if (throttlingDelay == 0_s) {
2513         m_delayedScrollEventTimer.stop();
2514         sendScrollEvent();
2515     } else if (!m_delayedScrollEventTimer.isActive())
2516         m_delayedScrollEventTimer.startOneShot(throttlingDelay.value());
2517
2518     if (Document* document = frame().document())
2519         document->sendWillRevealEdgeEventsIfNeeded(oldPosition, newPosition, visibleContentRect(), contentsSize());
2520
2521     if (RenderView* renderView = this->renderView()) {
2522         if (renderView->usesCompositing())
2523             renderView->compositor().frameViewDidScroll();
2524     }
2525
2526     LOG_WITH_STREAM(Scrolling, stream << "FrameView " << this << " scrollPositionChanged from " << oldPosition << " to " << newPosition << " (scale " << frameScaleFactor() << " )");
2527     updateLayoutViewport();
2528     viewportContentsChanged();
2529 }
2530
2531 void FrameView::applyRecursivelyWithVisibleRect(const std::function<void (FrameView& frameView, const IntRect& visibleRect)>& apply)
2532 {
2533     IntRect windowClipRect = this->windowClipRect();
2534     auto visibleRect = windowToContents(windowClipRect);
2535     apply(*this, visibleRect);
2536
2537     // Recursive call for subframes. We cache the current FrameView's windowClipRect to avoid recomputing it for every subframe.
2538     SetForScope<IntRect*> windowClipRectCache(m_cachedWindowClipRect, &windowClipRect);
2539     for (Frame* childFrame = frame().tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling()) {
2540         if (auto* childView = childFrame->view())
2541             childView->applyRecursivelyWithVisibleRect(apply);
2542     }
2543 }
2544
2545 void FrameView::resumeVisibleImageAnimations(const IntRect& visibleRect)
2546 {
2547     if (visibleRect.isEmpty())
2548         return;
2549
2550     if (auto* renderView = frame().contentRenderer())
2551         renderView->resumePausedImageAnimationsIfNeeded(visibleRect);
2552 }
2553
2554 void FrameView::updateScriptedAnimationsAndTimersThrottlingState(const IntRect& visibleRect)
2555 {
2556     if (frame().isMainFrame())
2557         return;
2558
2559     auto* document = frame().document();
2560     if (!document)
2561         return;
2562
2563     // We don't throttle zero-size or display:none frames because those are usually utility frames.
2564     bool shouldThrottle = visibleRect.isEmpty() && !m_size.isEmpty() && frame().ownerRenderer();
2565
2566     if (auto* scriptedAnimationController = document->scriptedAnimationController())
2567         scriptedAnimationController->setThrottled(shouldThrottle);
2568
2569     document->setTimerThrottlingEnabled(shouldThrottle);
2570 }
2571
2572
2573 void FrameView::resumeVisibleImageAnimationsIncludingSubframes()
2574 {
2575     applyRecursivelyWithVisibleRect([] (FrameView& frameView, const IntRect& visibleRect) {
2576         frameView.resumeVisibleImageAnimations(visibleRect);
2577     });
2578 }
2579
2580 void FrameView::updateLayerPositionsAfterScrolling()
2581 {
2582     // If we're scrolling as a result of updating the view size after layout, we'll update widgets and layer positions soon anyway.
2583     if (m_layoutPhase == InViewSizeAdjust)
2584         return;
2585
2586     if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) {
2587         if (RenderView* renderView = this->renderView()) {
2588             updateWidgetPositions();
2589             renderView->layer()->updateLayerPositionsAfterDocumentScroll();
2590         }
2591     }
2592 }
2593
2594 bool FrameView::shouldUpdateCompositingLayersAfterScrolling() const
2595 {
2596 #if ENABLE(ASYNC_SCROLLING)
2597     // If the scrolling thread is updating the fixed elements, then the FrameView should not update them as well.
2598
2599     Page* page = frame().page();
2600     if (!page)
2601         return true;
2602
2603     if (&page->mainFrame() != m_frame.ptr())
2604         return true;
2605
2606     ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
2607     if (!scrollingCoordinator)
2608         return true;
2609
2610     if (!scrollingCoordinator->supportsFixedPositionLayers())
2611         return true;
2612
2613     if (scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously(*this))
2614         return true;
2615
2616     if (inProgrammaticScroll())
2617         return true;
2618
2619     return false;
2620 #endif
2621     return true;
2622 }
2623
2624 void FrameView::updateCompositingLayersAfterScrolling()
2625 {
2626     ASSERT(m_layoutPhase >= InPostLayout || m_layoutPhase == OutsideLayout);
2627
2628     if (!shouldUpdateCompositingLayersAfterScrolling())
2629         return;
2630
2631     if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) {
2632         if (RenderView* renderView = this->renderView())
2633             renderView->compositor().updateCompositingLayers(CompositingUpdateOnScroll);
2634     }
2635 }
2636
2637 bool FrameView::isRubberBandInProgress() const
2638 {
2639     if (scrollbarsSuppressed())
2640         return false;
2641
2642     // If the scrolling thread updates the scroll position for this FrameView, then we should return
2643     // ScrollingCoordinator::isRubberBandInProgress().
2644     if (Page* page = frame().page()) {
2645         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
2646             if (!scrollingCoordinator->shouldUpdateScrollLayerPositionSynchronously(*this))
2647                 return scrollingCoordinator->isRubberBandInProgress();
2648         }
2649     }
2650
2651     // If the main thread updates the scroll position for this FrameView, we should return
2652     // ScrollAnimator::isRubberBandInProgress().
2653     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
2654         return scrollAnimator->isRubberBandInProgress();
2655
2656     return false;
2657 }
2658
2659 bool FrameView::requestScrollPositionUpdate(const ScrollPosition& position)
2660 {
2661     LOG_WITH_STREAM(Scrolling, stream << "FrameView::requestScrollPositionUpdate " << position);
2662
2663 #if ENABLE(ASYNC_SCROLLING)
2664     if (TiledBacking* tiledBacking = this->tiledBacking())
2665         tiledBacking->prepopulateRect(FloatRect(position, visibleContentRect().size()));
2666 #endif
2667
2668 #if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
2669     if (Page* page = frame().page()) {
2670         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
2671             return scrollingCoordinator->requestScrollPositionUpdate(*this, position);
2672     }
2673 #else
2674     UNUSED_PARAM(position);
2675 #endif
2676
2677     return false;
2678 }
2679
2680 HostWindow* FrameView::hostWindow() const
2681 {
2682     auto* page = frame().page();
2683     if (!page)
2684         return nullptr;
2685     return &page->chrome();
2686 }
2687
2688 void FrameView::addTrackedRepaintRect(const FloatRect& r)
2689 {
2690     if (!m_isTrackingRepaints || r.isEmpty())
2691         return;
2692
2693     FloatRect repaintRect = r;
2694     repaintRect.moveBy(-scrollPosition());
2695     m_trackedRepaintRects.append(repaintRect);
2696 }
2697
2698 void FrameView::repaintContentRectangle(const IntRect& r)
2699 {
2700     ASSERT(!frame().ownerElement());
2701
2702     if (!shouldUpdate())
2703         return;
2704
2705     ScrollView::repaintContentRectangle(r);
2706 }
2707
2708 static unsigned countRenderedCharactersInRenderObjectWithThreshold(const RenderElement& renderer, unsigned threshold)
2709 {
2710     unsigned count = 0;
2711     for (const RenderObject* descendant = &renderer; descendant; descendant = descendant->nextInPreOrder()) {
2712         if (is<RenderText>(*descendant)) {
2713             count += downcast<RenderText>(*descendant).text()->length();
2714             if (count >= threshold)
2715                 break;
2716         }
2717     }
2718     return count;
2719 }
2720
2721 bool FrameView::renderedCharactersExceed(unsigned threshold)
2722 {
2723     if (!frame().contentRenderer())
2724         return false;
2725     return countRenderedCharactersInRenderObjectWithThreshold(*frame().contentRenderer(), threshold) >= threshold;
2726 }
2727
2728 void FrameView::availableContentSizeChanged(AvailableSizeChangeReason reason)
2729 {
2730     if (Document* document = frame().document()) {
2731         // FIXME: Merge this logic with m_setNeedsLayoutWasDeferred and find a more appropriate
2732         // way of handling potential recursive layouts when the viewport is resized to accomodate
2733         // the content but the content always overflows the viewport. See webkit.org/b/165781.
2734         if (!(layoutPhase() == InViewSizeAdjust && useFixedLayout()))
2735             document->updateViewportUnitsOnResize();
2736     }
2737
2738     updateLayoutViewport();
2739     setNeedsLayout();
2740     ScrollView::availableContentSizeChanged(reason);
2741 }
2742
2743 bool FrameView::shouldLayoutAfterContentsResized() const
2744 {
2745     return !useFixedLayout() || useCustomFixedPositionLayoutRect();
2746 }
2747
2748 void FrameView::updateContentsSize()
2749 {
2750     // We check to make sure the view is attached to a frame() as this method can
2751     // be triggered before the view is attached by Frame::createView(...) setting
2752     // various values such as setScrollBarModes(...) for example.  An ASSERT is
2753     // triggered when a view is layout before being attached to a frame().
2754     if (!frame().view())
2755         return;
2756
2757 #if PLATFORM(IOS)
2758     if (RenderView* root = m_frame->contentRenderer()) {
2759         if (useCustomFixedPositionLayoutRect() && hasViewportConstrainedObjects()) {
2760             setViewportConstrainedObjectsNeedLayout();
2761             // We must eagerly enter compositing mode because fixed position elements
2762             // will not have been made compositing via a preceding style change before
2763             // m_useCustomFixedPositionLayoutRect was true.
2764             root->compositor().enableCompositingMode();
2765         }
2766     }
2767 #endif
2768
2769     if (shouldLayoutAfterContentsResized() && needsLayout())
2770         layout();
2771
2772     if (RenderView* renderView = this->renderView()) {
2773         if (renderView->usesCompositing())
2774             renderView->compositor().frameViewDidChangeSize();
2775     }
2776 }
2777
2778 void FrameView::addedOrRemovedScrollbar()
2779 {
2780     if (RenderView* renderView = this->renderView()) {
2781         if (renderView->usesCompositing())
2782             renderView->compositor().frameViewDidAddOrRemoveScrollbars();
2783     }
2784
2785     updateTiledBackingAdaptiveSizing();
2786 }
2787
2788 TiledBacking::Scrollability FrameView::computeScrollability() const
2789 {
2790     auto* page = frame().page();
2791
2792     // Use smaller square tiles if the Window is not active to facilitate app napping.
2793     if (!page || !page->isWindowActive())
2794         return TiledBacking::HorizontallyScrollable | TiledBacking::VerticallyScrollable;
2795
2796     bool horizontallyScrollable;
2797     bool verticallyScrollable;
2798     bool clippedByAncestorView = static_cast<bool>(m_viewExposedRect);
2799
2800 #if PLATFORM(IOS)
2801     if (page)
2802         clippedByAncestorView |= page->enclosedInScrollableAncestorView();
2803 #endif
2804
2805     if (delegatesScrolling()) {
2806         IntSize documentSize = contentsSize();
2807         IntSize visibleSize = this->visibleSize();
2808
2809         horizontallyScrollable = clippedByAncestorView || documentSize.width() > visibleSize.width();
2810         verticallyScrollable = clippedByAncestorView || documentSize.height() > visibleSize.height();
2811     } else {
2812         horizontallyScrollable = clippedByAncestorView || horizontalScrollbar();
2813         verticallyScrollable = clippedByAncestorView || verticalScrollbar();
2814     }
2815
2816     TiledBacking::Scrollability scrollability = TiledBacking::NotScrollable;
2817     if (horizontallyScrollable)
2818         scrollability = TiledBacking::HorizontallyScrollable;
2819
2820     if (verticallyScrollable)
2821         scrollability |= TiledBacking::VerticallyScrollable;
2822
2823     return scrollability;
2824 }
2825
2826 void FrameView::updateTiledBackingAdaptiveSizing()
2827 {
2828     auto* tiledBacking = this->tiledBacking();
2829     if (!tiledBacking)
2830         return;
2831
2832     tiledBacking->setScrollability(computeScrollability());
2833 }
2834
2835 #if PLATFORM(IOS)
2836
2837 void FrameView::unobscuredContentSizeChanged()
2838 {
2839     updateTiledBackingAdaptiveSizing();
2840 }
2841
2842 #endif
2843
2844 static LayerFlushThrottleState::Flags determineLayerFlushThrottleState(Page& page)
2845 {
2846     // We only throttle when constantly receiving new data during the inital page load.
2847     if (!page.progress().isMainLoadProgressing())
2848         return 0;
2849     // Scrolling during page loading disables throttling.
2850     if (page.mainFrame().view()->wasScrolledByUser())
2851         return 0;
2852     // Disable for image documents so large GIF animations don't get throttled during loading.
2853     auto* document = page.mainFrame().document();
2854     if (!document || is<ImageDocument>(*document))
2855         return 0;
2856     return LayerFlushThrottleState::Enabled;
2857 }
2858
2859 void FrameView::disableLayerFlushThrottlingTemporarilyForInteraction()
2860 {
2861     if (!frame().page())
2862         return;
2863     auto& page = *frame().page();
2864
2865     LayerFlushThrottleState::Flags flags = LayerFlushThrottleState::UserIsInteracting | determineLayerFlushThrottleState(page);
2866     if (page.chrome().client().adjustLayerFlushThrottling(flags))
2867         return;
2868
2869     if (RenderView* view = renderView())
2870         view->compositor().disableLayerFlushThrottlingTemporarilyForInteraction();
2871 }
2872
2873 void FrameView::loadProgressingStatusChanged()
2874 {
2875     updateLayerFlushThrottling();
2876     adjustTiledBackingCoverage();
2877 }
2878
2879 void FrameView::updateLayerFlushThrottling()
2880 {
2881     Page* page = frame().page();
2882     if (!page)
2883         return;
2884
2885     ASSERT(frame().isMainFrame());
2886
2887     LayerFlushThrottleState::Flags flags = determineLayerFlushThrottleState(*page);
2888
2889     // See if the client is handling throttling.
2890     if (page->chrome().client().adjustLayerFlushThrottling(flags))
2891         return;
2892
2893     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
2894         if (RenderView* renderView = frame->contentRenderer())
2895             renderView->compositor().setLayerFlushThrottlingEnabled(flags & LayerFlushThrottleState::Enabled);
2896     }
2897 }
2898
2899 void FrameView::adjustTiledBackingCoverage()
2900 {
2901     if (!m_speculativeTilingEnabled)
2902         enableSpeculativeTilingIfNeeded();
2903
2904     RenderView* renderView = this->renderView();
2905     if (renderView && renderView->layer()->backing())
2906         renderView->layer()->backing()->adjustTiledBackingCoverage();
2907 #if PLATFORM(IOS)
2908     if (LegacyTileCache* tileCache = legacyTileCache())
2909         tileCache->setSpeculativeTileCreationEnabled(m_speculativeTilingEnabled);
2910 #endif
2911 }
2912
2913 static bool shouldEnableSpeculativeTilingDuringLoading(const FrameView& view)
2914 {
2915     Page* page = view.frame().page();
2916     return page && view.isVisuallyNonEmpty() && !page->progress().isMainLoadProgressing();
2917 }
2918
2919 void FrameView::enableSpeculativeTilingIfNeeded()
2920 {
2921     ASSERT(!m_speculativeTilingEnabled);
2922     if (m_wasScrolledByUser) {
2923         m_speculativeTilingEnabled = true;
2924         return;
2925     }
2926     if (!shouldEnableSpeculativeTilingDuringLoading(*this))
2927         return;
2928     if (m_speculativeTilingEnableTimer.isActive())
2929         return;
2930     // Delay enabling a bit as load completion may trigger further loading from scripts.
2931     static const double speculativeTilingEnableDelay = 0.5;
2932     m_speculativeTilingEnableTimer.startOneShot(speculativeTilingEnableDelay);
2933 }
2934
2935 void FrameView::speculativeTilingEnableTimerFired()
2936 {
2937     if (m_speculativeTilingEnabled)
2938         return;
2939     m_speculativeTilingEnabled = shouldEnableSpeculativeTilingDuringLoading(*this);
2940     adjustTiledBackingCoverage();
2941 }
2942
2943 void FrameView::show()
2944 {
2945     ScrollView::show();
2946
2947     if (frame().isMainFrame()) {
2948         // Turn off speculative tiling for a brief moment after a FrameView appears on screen.
2949         // Note that adjustTiledBackingCoverage() kicks the (500ms) timer to re-enable it.
2950         m_speculativeTilingEnabled = false;
2951         m_wasScrolledByUser = false;
2952         adjustTiledBackingCoverage();
2953     }
2954 }
2955 void FrameView::convertSubtreeLayoutToFullLayout()
2956 {
2957     ASSERT(m_layoutRoot);
2958     m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No);
2959     m_layoutRoot = nullptr;
2960 }
2961
2962 void FrameView::layoutTimerFired()
2963 {
2964 #if !LOG_DISABLED
2965     if (!frame().document()->ownerElement())
2966         LOG(Layout, "FrameView %p layout timer fired at %.3fs", this, frame().document()->timeSinceDocumentCreation().value());
2967 #endif
2968     layout();
2969 }
2970
2971 void FrameView::scheduleRelayout()
2972 {
2973     // FIXME: We should assert the page is not in the page cache, but that is causing
2974     // too many false assertions.  See <rdar://problem/7218118>.
2975     ASSERT(frame().view() == this);
2976
2977     if (m_layoutRoot)
2978         convertSubtreeLayoutToFullLayout();
2979     if (!m_layoutSchedulingEnabled)
2980         return;
2981     if (!needsLayout())
2982         return;
2983     if (!frame().document()->shouldScheduleLayout())
2984         return;
2985     InspectorInstrumentation::didInvalidateLayout(frame());
2986     // When frame flattening is enabled, the contents of the frame could affect the layout of the parent frames.
2987     // Also invalidate parent frame starting from the owner element of this frame.
2988     if (frame().ownerRenderer() && isInChildFrameWithFrameFlattening())
2989         frame().ownerRenderer()->setNeedsLayout(MarkContainingBlockChain);
2990
2991     Seconds delay = frame().document()->minimumLayoutDelay();
2992     if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
2993         unscheduleRelayout();
2994
2995     if (m_layoutTimer.isActive())
2996         return;
2997
2998     m_delayedLayout = delay.value();
2999
3000 #if !LOG_DISABLED
3001     if (!frame().document()->ownerElement())
3002         LOG(Layout, "FrameView %p scheduling layout for %.3fs", this, delay.value());
3003 #endif
3004
3005     m_layoutTimer.startOneShot(delay);
3006 }
3007
3008 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
3009 {
3010     for (RenderObject* r = descendant; r; r = r->container()) {
3011         if (r == ancestor)
3012             return true;
3013     }
3014     return false;
3015 }
3016
3017 void FrameView::scheduleRelayoutOfSubtree(RenderElement& newRelayoutRoot)
3018 {
3019     ASSERT(renderView());
3020     const RenderView& renderView = *this->renderView();
3021
3022     // Try to catch unnecessary work during render tree teardown.
3023     ASSERT(!renderView.documentBeingDestroyed());
3024     ASSERT(frame().view() == this);
3025
3026     // When m_layoutRoot is already set, ignore the renderView's needsLayout bit
3027     // since we need to resolve the conflict between the m_layoutRoot and newRelayoutRoot layouts.
3028     if (renderView.needsLayout() && !m_layoutRoot) {
3029         m_layoutRoot = &newRelayoutRoot;
3030         convertSubtreeLayoutToFullLayout();
3031         return;
3032     }
3033
3034     if (!layoutPending() && m_layoutSchedulingEnabled) {
3035         Seconds delay = renderView.document().minimumLayoutDelay();
3036         ASSERT(!newRelayoutRoot.container() || is<RenderView>(newRelayoutRoot.container()) || !newRelayoutRoot.container()->needsLayout());
3037         m_layoutRoot = &newRelayoutRoot;
3038         InspectorInstrumentation::didInvalidateLayout(frame());
3039         m_delayedLayout = delay.value();
3040         m_layoutTimer.startOneShot(delay);
3041         return;
3042     }
3043
3044     if (m_layoutRoot == &newRelayoutRoot)
3045         return;
3046
3047     if (!m_layoutRoot) {
3048         // We already have a pending (full) layout. Just mark the subtree for layout.
3049         newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No);
3050         InspectorInstrumentation::didInvalidateLayout(frame());
3051         return;
3052     }
3053
3054     if (isObjectAncestorContainerOf(m_layoutRoot, &newRelayoutRoot)) {
3055         // Keep the current root.
3056         newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No, m_layoutRoot);
3057         ASSERT(!m_layoutRoot->container() || is<RenderView>(m_layoutRoot->container()) || !m_layoutRoot->container()->needsLayout());
3058         return;
3059     }
3060
3061     if (isObjectAncestorContainerOf(&newRelayoutRoot, m_layoutRoot)) {
3062         // Re-root at newRelayoutRoot.
3063         m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No, &newRelayoutRoot);
3064         m_layoutRoot = &newRelayoutRoot;
3065         ASSERT(!m_layoutRoot->container() || is<RenderView>(m_layoutRoot->container()) || !m_layoutRoot->container()->needsLayout());
3066         InspectorInstrumentation::didInvalidateLayout(frame());
3067         return;
3068     }
3069     // Two disjoint subtrees need layout. Mark both of them and issue a full layout instead.
3070     convertSubtreeLayoutToFullLayout();
3071     newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No);
3072     InspectorInstrumentation::didInvalidateLayout(frame());
3073 }
3074
3075 bool FrameView::layoutPending() const
3076 {
3077     return m_layoutTimer.isActive();
3078 }
3079
3080 bool FrameView::needsStyleRecalcOrLayout(bool includeSubframes) const
3081 {
3082     if (frame().document() && frame().document()->childNeedsStyleRecalc())
3083         return true;
3084     
3085     if (needsLayout())
3086         return true;
3087
3088     if (!includeSubframes)
3089         return false;
3090
3091     for (auto& frameView : renderedChildFrameViews()) {
3092         if (frameView->needsStyleRecalcOrLayout())
3093             return true;
3094     }
3095
3096     return false;
3097 }
3098
3099 bool FrameView::needsLayout() const
3100 {
3101     // This can return true in cases where the document does not have a body yet.
3102     // Document::shouldScheduleLayout takes care of preventing us from scheduling
3103     // layout in that case.
3104     RenderView* renderView = this->renderView();
3105     return layoutPending()
3106         || (renderView && renderView->needsLayout())
3107         || m_layoutRoot
3108         || (m_deferSetNeedsLayoutCount && m_setNeedsLayoutWasDeferred);
3109 }
3110
3111 void FrameView::setNeedsLayout()
3112 {
3113     if (m_deferSetNeedsLayoutCount) {
3114         m_setNeedsLayoutWasDeferred = true;
3115         return;
3116     }
3117
3118     if (auto* renderView = this->renderView()) {
3119         ASSERT(!renderView->inHitTesting());
3120         renderView->setNeedsLayout();
3121     }
3122 }
3123
3124 void FrameView::unscheduleRelayout()
3125 {
3126     if (m_postLayoutTasksTimer.isActive())
3127         m_postLayoutTasksTimer.stop();
3128
3129     if (!m_layoutTimer.isActive())
3130         return;
3131
3132 #if !LOG_DISABLED
3133     if (!frame().document()->ownerElement())
3134         LOG(Layout, "FrameView %p layout timer unscheduled at %.3fs", this, frame().document()->timeSinceDocumentCreation().value());
3135 #endif
3136     
3137     m_layoutTimer.stop();
3138     m_delayedLayout = false;
3139 }
3140
3141 void FrameView::serviceScriptedAnimations()
3142 {
3143     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext()) {
3144         frame->view()->serviceScrollAnimations();
3145         frame->animation().serviceAnimations();
3146     }
3147
3148     if (!frame().document() || !frame().document()->domWindow())
3149         return;
3150
3151     Vector<RefPtr<Document>> documents;
3152     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext())
3153         documents.append(frame->document());
3154
3155     double timestamp = frame().document()->domWindow()->nowTimestamp();
3156     for (auto& document : documents)
3157         document->serviceScriptedAnimations(timestamp);
3158 }
3159
3160 bool FrameView::isTransparent() const
3161 {
3162     return m_isTransparent;
3163 }
3164
3165 void FrameView::setTransparent(bool isTransparent)
3166 {
3167     if (m_isTransparent == isTransparent)
3168         return;
3169
3170     m_isTransparent = isTransparent;
3171
3172     // setTransparent can be called in the window between FrameView initialization
3173     // and switching in the new Document; this means that the RenderView that we
3174     // retrieve is actually attached to the previous Document, which is going away,
3175     // and must not update compositing layers.
3176     if (!isViewForDocumentInFrame())
3177         return;
3178
3179     renderView()->compositor().rootBackgroundTransparencyChanged();
3180 }
3181
3182 bool FrameView::hasOpaqueBackground() const
3183 {
3184     return !m_isTransparent && m_baseBackgroundColor.isOpaque();
3185 }
3186
3187 Color FrameView::baseBackgroundColor() const
3188 {
3189     return m_baseBackgroundColor;
3190 }
3191
3192 void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
3193 {
3194     bool wasOpaque = m_baseBackgroundColor.isOpaque();
3195     
3196     if (!backgroundColor.isValid())
3197         m_baseBackgroundColor = Color::white;
3198     else
3199         m_baseBackgroundColor = backgroundColor;
3200
3201     if (!isViewForDocumentInFrame())
3202         return;
3203
3204     recalculateScrollbarOverlayStyle();
3205
3206     if (m_baseBackgroundColor.isOpaque() != wasOpaque)
3207         renderView()->compositor().rootBackgroundTransparencyChanged();
3208 }
3209
3210 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
3211 {
3212     for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
3213         if (FrameView* view = frame->view()) {
3214             view->setTransparent(transparent);
3215             view->setBaseBackgroundColor(backgroundColor);
3216         }
3217     }
3218 }
3219
3220 bool FrameView::hasExtendedBackgroundRectForPainting() const
3221 {
3222     if (!frame().settings().backgroundShouldExtendBeyondPage())
3223         return false;
3224
3225     TiledBacking* tiledBacking = this->tiledBacking();
3226     if (!tiledBacking)
3227         return false;
3228
3229     return tiledBacking->hasMargins();
3230 }
3231
3232 void FrameView::updateExtendBackgroundIfNecessary()
3233 {
3234     ExtendedBackgroundMode mode = calculateExtendedBackgroundMode();
3235     if (mode == ExtendedBackgroundModeNone)
3236         return;
3237
3238     updateTilesForExtendedBackgroundMode(mode);
3239 }
3240
3241 FrameView::ExtendedBackgroundMode FrameView::calculateExtendedBackgroundMode() const
3242 {
3243     // Just because Settings::backgroundShouldExtendBeyondPage() is true does not necessarily mean
3244     // that the background rect needs to be extended for painting. Simple backgrounds can be extended
3245     // just with RenderLayerCompositor::setRootExtendedBackgroundColor(). More complicated backgrounds,
3246     // such as images, require extending the background rect to continue painting into the extended
3247     // region. This function finds out if it is necessary to extend the background rect for painting.
3248
3249 #if PLATFORM(IOS)
3250     // <rdar://problem/16201373>
3251     return ExtendedBackgroundModeNone;
3252 #else
3253     if (!frame().settings().backgroundShouldExtendBeyondPage())
3254         return ExtendedBackgroundModeNone;
3255
3256     if (!frame().isMainFrame())
3257         return ExtendedBackgroundModeNone;
3258
3259     Document* document = frame().document();
3260     if (!document)
3261         return ExtendedBackgroundModeNone;
3262
3263     if (!renderView())
3264         return ExtendedBackgroundModeNone;
3265     
3266     auto* rootBackgroundRenderer = renderView()->rendererForRootBackground();
3267     if (!rootBackgroundRenderer)
3268         return ExtendedBackgroundModeNone;
3269
3270     if (!rootBackgroundRenderer->style().hasBackgroundImage())
3271         return ExtendedBackgroundModeNone;
3272
3273     ExtendedBackgroundMode mode = ExtendedBackgroundModeNone;
3274     if (rootBackgroundRenderer->style().backgroundRepeatX() == RepeatFill)
3275         mode |= ExtendedBackgroundModeHorizontal;
3276     if (rootBackgroundRenderer->style().backgroundRepeatY() == RepeatFill)
3277         mode |= ExtendedBackgroundModeVertical;
3278
3279     return mode;
3280 #endif
3281 }
3282
3283 void FrameView::updateTilesForExtendedBackgroundMode(ExtendedBackgroundMode mode)
3284 {
3285     if (!frame().settings().backgroundShouldExtendBeyondPage())
3286         return;
3287
3288     RenderView* renderView = this->renderView();
3289     if (!renderView)
3290         return;
3291
3292     RenderLayerBacking* backing = renderView->layer()->backing();
3293     if (!backing)
3294         return;
3295
3296     TiledBacking* tiledBacking = backing->graphicsLayer()->tiledBacking();
3297     if (!tiledBacking)
3298         return;
3299
3300     ExtendedBackgroundMode existingMode = ExtendedBackgroundModeNone;
3301     if (tiledBacking->hasVerticalMargins())
3302         existingMode |= ExtendedBackgroundModeVertical;
3303     if (tiledBacking->hasHorizontalMargins())
3304         existingMode |= ExtendedBackgroundModeHorizontal;
3305
3306     if (existingMode == mode)
3307         return;
3308
3309     renderView->compositor().setRootExtendedBackgroundColor(mode == ExtendedBackgroundModeAll ? Color() : documentBackgroundColor());
3310     backing->setTiledBackingHasMargins(mode & ExtendedBackgroundModeHorizontal, mode & ExtendedBackgroundModeVertical);
3311 }
3312
3313 IntRect FrameView::extendedBackgroundRectForPainting() const
3314 {
3315     TiledBacking* tiledBacking = this->tiledBacking();
3316     if (!tiledBacking)
3317         return IntRect();
3318     
3319     RenderView* renderView = this->renderView();
3320     if (!renderView)
3321         return IntRect();
3322     
3323     LayoutRect extendedRect = renderView->unextendedBackgroundRect();
3324     if (!tiledBacking->hasMargins())
3325         return snappedIntRect(extendedRect);
3326     
3327     extendedRect.moveBy(LayoutPoint(-tiledBacking->leftMarginWidth(), -tiledBacking->topMarginHeight()));
3328     extendedRect.expand(LayoutSize(tiledBacking->leftMarginWidth() + tiledBacking->rightMarginWidth(), tiledBacking->topMarginHeight() + tiledBacking->bottomMarginHeight()));
3329     return snappedIntRect(extendedRect);
3330 }
3331
3332 bool FrameView::shouldUpdateWhileOffscreen() const
3333 {
3334     return m_shouldUpdateWhileOffscreen;
3335 }
3336
3337 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
3338 {
3339     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
3340 }
3341
3342 bool FrameView::shouldUpdate() const
3343 {
3344     if (isOffscreen() && !shouldUpdateWhileOffscreen())
3345         return false;
3346     return true;
3347 }
3348
3349 void FrameView::scrollToAnchor()
3350 {
3351     RefPtr<ContainerNode> anchorNode = m_maintainScrollPositionAnchor;
3352     if (!anchorNode)
3353         return;
3354
3355     if (!anchorNode->renderer())
3356         return;
3357
3358     LayoutRect rect;
3359     bool insideFixed = false;
3360     if (anchorNode != frame().document() && anchorNode->renderer())
3361         rect = anchorNode->renderer()->absoluteAnchorRect(&insideFixed);
3362
3363     // Scroll nested layers and frames to reveal the anchor.
3364     // Align to the top and to the closest side (this matches other browsers).
3365     if (anchorNode->renderer()->style().isHorizontalWritingMode())
3366         anchorNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, rect, insideFixed, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
3367     else if (anchorNode->renderer()->style().isFlippedBlocksWritingMode())
3368         anchorNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, rect, insideFixed, ScrollAlignment::alignRightAlways, ScrollAlignment::alignToEdgeIfNeeded);
3369     else
3370         anchorNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, rect, insideFixed, ScrollAlignment::alignLeftAlways, ScrollAlignment::alignToEdgeIfNeeded);
3371
3372     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
3373         cache->handleScrolledToAnchor(anchorNode.get());
3374
3375     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
3376     m_maintainScrollPositionAnchor = anchorNode;
3377 }
3378
3379 void FrameView::updateEmbeddedObject(RenderEmbeddedObject& embeddedObject)
3380 {
3381     // No need to update if it's already crashed or known to be missing.
3382     if (embeddedObject.isPluginUnavailable())
3383         return;
3384
3385     HTMLFrameOwnerElement& element = embeddedObject.frameOwnerElement();
3386
3387     if (embeddedObject.isSnapshottedPlugIn()) {
3388         if (is<HTMLObjectElement>(element) || is<HTMLEmbedElement>(element)) {
3389             HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
3390             pluginElement.checkSnapshotStatus();
3391         }
3392         return;
3393     }
3394
3395     auto weakRenderer = embeddedObject.createWeakPtr();
3396
3397     // FIXME: This could turn into a real virtual dispatch if we defined
3398     // updateWidget(PluginCreationOption) on HTMLElement.
3399     if (is<HTMLPlugInImageElement>(element)) {
3400         HTMLPlugInImageElement& pluginElement = downcast<HTMLPlugInImageElement>(element);
3401         if (pluginElement.needsCheckForSizeChange()) {
3402             pluginElement.checkSnapshotStatus();
3403             return;
3404         }
3405         if (pluginElement.needsWidgetUpdate())
3406             pluginElement.updateWidget(CreatePlugins::Yes);
3407     } else
3408         ASSERT_NOT_REACHED();
3409
3410     // It's possible the renderer was destroyed below updateWidget() since loading a plugin may execute arbitrary JavaScript.
3411     if (!weakRenderer)
3412         return;
3413
3414     auto ignoreWidgetState = embeddedObject.updateWidgetPosition();
3415     UNUSED_PARAM(ignoreWidgetState);
3416 }
3417
3418 bool FrameView::updateEmbeddedObjects()
3419 {
3420     if (m_nestedLayoutCount > 1 || !m_embeddedObjectsToUpdate || m_embeddedObjectsToUpdate->isEmpty())
3421         return true;
3422
3423     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
3424
3425     // Insert a marker for where we should stop.
3426     ASSERT(!m_embeddedObjectsToUpdate->contains(nullptr));
3427     m_embeddedObjectsToUpdate->add(nullptr);
3428
3429     while (!m_embeddedObjectsToUpdate->isEmpty()) {
3430         RenderEmbeddedObject* embeddedObject = m_embeddedObjectsToUpdate->takeFirst();
3431         if (!embeddedObject)
3432             break;
3433         updateEmbeddedObject(*embeddedObject);
3434     }
3435
3436     return m_embeddedObjectsToUpdate->isEmpty();
3437 }
3438
3439 void FrameView::updateEmbeddedObjectsTimerFired()
3440 {
3441     RefPtr<FrameView> protectedThis(this);
3442     m_updateEmbeddedObjectsTimer.stop();
3443     for (unsigned i = 0; i < maxUpdateEmbeddedObjectsIterations; i++) {
3444         if (updateEmbeddedObjects())
3445             break;
3446     }
3447 }
3448
3449 void FrameView::flushAnyPendingPostLayoutTasks()
3450 {
3451     if (m_postLayoutTasksTimer.isActive())
3452         performPostLayoutTasks();
3453     if (m_updateEmbeddedObjectsTimer.isActive())
3454         updateEmbeddedObjectsTimerFired();
3455 }
3456
3457 void FrameView::queuePostLayoutCallback(Function<void()>&& callback)
3458 {
3459     m_postLayoutCallbackQueue.append(WTFMove(callback));
3460 }
3461
3462 void FrameView::flushPostLayoutTasksQueue()
3463 {
3464     if (m_nestedLayoutCount > 1)
3465         return;
3466
3467     if (!m_postLayoutCallbackQueue.size())
3468         return;
3469
3470     Vector<Function<void()>> queue = WTFMove(m_postLayoutCallbackQueue);
3471     for (auto& task : queue)
3472         task();
3473 }
3474
3475 void FrameView::performPostLayoutTasks()
3476 {
3477     LOG(Layout, "FrameView %p performPostLayoutTasks", this);
3478
3479     // FIXME: We should not run any JavaScript code in this function.
3480
3481     m_postLayoutTasksTimer.stop();
3482
3483     frame().selection().updateAppearanceAfterLayout();
3484
3485     flushPostLayoutTasksQueue();
3486
3487     if (m_nestedLayoutCount <= 1 && frame().document()->documentElement())
3488         fireLayoutRelatedMilestonesIfNeeded();
3489
3490 #if PLATFORM(IOS)
3491     // Only send layout-related delegate callbacks synchronously for the main frame to
3492     // avoid re-entering layout for the main frame while delivering a layout-related delegate
3493     // callback for a subframe.
3494     if (frame().isMainFrame()) {
3495         if (Page* page = frame().page())
3496             page->chrome().client().didLayout();
3497     }
3498 #endif
3499
3500 #if ENABLE(FONT_LOAD_EVENTS)
3501     if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
3502         frame().document()->fonts()->didLayout();
3503 #endif
3504     
3505     // FIXME: We should consider adding DidLayout as a LayoutMilestone. That would let us merge this
3506     // with didLayout(LayoutMilestones).
3507     frame().loader().client().dispatchDidLayout();
3508
3509     updateWidgetPositions();
3510
3511 #if ENABLE(CSS_SCROLL_SNAP)
3512     updateSnapOffsets();
3513 #endif
3514
3515     // layout() protects FrameView, but it still can get destroyed when updateEmbeddedObjects()
3516     // is called through the post layout timer.
3517     Ref<FrameView> protectedThis(*this);
3518
3519     m_updateEmbeddedObjectsTimer.startOneShot(0);
3520
3521     if (auto* page = frame().page()) {
3522         if (auto* scrollingCoordinator = page->scrollingCoordinator())
3523             scrollingCoordinator->frameViewLayoutUpdated(*this);
3524     }
3525
3526     if (RenderView* renderView = this->renderView()) {
3527         if (renderView->usesCompositing())
3528             renderView->compositor().frameViewDidLayout();
3529     }
3530
3531     scrollToAnchor();
3532
3533     sendResizeEventIfNeeded();
3534     
3535     updateLayoutViewport();
3536     viewportContentsChanged();
3537
3538     updateScrollSnapState();
3539
3540     if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
3541         cache->performDeferredIsIgnoredChange();
3542 }
3543
3544 IntSize FrameView::sizeForResizeEvent() const
3545 {
3546 #if PLATFORM(IOS)
3547     if (m_useCustomSizeForResizeEvent)
3548         return m_customSizeForResizeEvent;
3549 #endif
3550     if (useFixedLayout() && !fixedLayoutSize().isEmpty() && delegatesScrolling())
3551         return fixedLayoutSize();
3552     return visibleContentRectIncludingScrollbars().size();
3553 }
3554
3555 void FrameView::sendResizeEventIfNeeded()
3556 {
3557     if (isInRenderTreeLayout() || needsLayout())
3558         return;
3559
3560     RenderView* renderView = this->renderView();
3561     if (!renderView || renderView->printing())
3562         return;
3563
3564     if (frame().page() && frame().page()->chrome().client().isSVGImageChromeClient())
3565         return;
3566
3567     IntSize currentSize = sizeForResizeEvent();
3568     float currentZoomFactor = renderView->style().zoom();
3569
3570     if (currentSize == m_lastViewportSize && currentZoomFactor == m_lastZoomFactor)
3571         return;
3572
3573     m_lastViewportSize = currentSize;
3574     m_lastZoomFactor = currentZoomFactor;
3575
3576     if (m_firstLayout)
3577         return;
3578
3579 #if PLATFORM(IOS)
3580     // Don't send the resize event if the document is loading. Some pages automatically reload
3581     // when the window is resized; Safari on iOS often resizes the window while setting up its
3582     // viewport. This obviously can cause problems.
3583     if (DocumentLoader* documentLoader = frame().loader().documentLoader()) {
3584         if (documentLoader->isLoadingInAPISense())
3585             return;
3586     }
3587 #endif
3588
3589     bool isMainFrame = frame().isMainFrame();
3590     bool canSendResizeEventSynchronously = isMainFrame && !m_shouldAutoSize;
3591
3592     Ref<Event> resizeEvent = Event::create(eventNames().resizeEvent, false, false);
3593     if (canSendResizeEventSynchronously)
3594         frame().document()->dispatchWindowEvent(resizeEvent);
3595     else {
3596         // FIXME: Queueing this event for an unpredictable time in the future seems
3597         // intrinsically racy. By the time this resize event fires, the frame might
3598         // be resized again, so we could end up with two resize events for the same size.
3599         frame().document()->enqueueWindowEvent(WTFMove(resizeEvent));
3600     }
3601
3602     if (InspectorInstrumentation::hasFrontends() && isMainFrame) {
3603         if (Page* page = frame().page()) {
3604             if (InspectorClient* inspectorClient = page->inspectorController().inspectorClient())
3605                 inspectorClient->didResizeMainFrame(&frame());
3606         }
3607     }
3608 }
3609