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