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