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