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