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