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