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