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