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