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