e070f53585ab3b2b9dbfc39d34937d3cfd3e7d29
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / frame / 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 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 "core/frame/FrameView.h"
29
30 #include "HTMLNames.h"
31 #include "RuntimeEnabledFeatures.h"
32 #include "core/accessibility/AXObjectCache.h"
33 #include "core/css/FontFaceSet.h"
34 #include "core/css/resolver/StyleResolver.h"
35 #include "core/dom/DocumentMarkerController.h"
36 #include "core/editing/FrameSelection.h"
37 #include "core/events/OverflowEvent.h"
38 #include "core/fetch/ResourceFetcher.h"
39 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
40 #include "core/frame/LocalFrame.h"
41 #include "core/frame/Settings.h"
42 #include "core/html/HTMLFrameElement.h"
43 #include "core/html/HTMLPlugInElement.h"
44 #include "core/html/parser/TextResourceDecoder.h"
45 #include "core/inspector/InspectorInstrumentation.h"
46 #include "core/loader/FrameLoader.h"
47 #include "core/loader/FrameLoaderClient.h"
48 #include "core/page/Chrome.h"
49 #include "core/page/ChromeClient.h"
50 #include "core/page/EventHandler.h"
51 #include "core/page/FocusController.h"
52 #include "core/page/FrameTree.h"
53 #include "core/page/scrolling/ScrollingCoordinator.h"
54 #include "core/rendering/FastTextAutosizer.h"
55 #include "core/rendering/RenderCounter.h"
56 #include "core/rendering/RenderEmbeddedObject.h"
57 #include "core/rendering/RenderLayer.h"
58 #include "core/rendering/RenderListBox.h"
59 #include "core/rendering/RenderPart.h"
60 #include "core/rendering/RenderScrollbar.h"
61 #include "core/rendering/RenderScrollbarPart.h"
62 #include "core/rendering/RenderTheme.h"
63 #include "core/rendering/RenderView.h"
64 #include "core/rendering/RenderWidget.h"
65 #include "core/rendering/TextAutosizer.h"
66 #include "core/rendering/compositing/CompositedLayerMapping.h"
67 #include "core/rendering/compositing/RenderLayerCompositor.h"
68 #include "core/rendering/style/RenderStyle.h"
69 #include "core/rendering/svg/RenderSVGRoot.h"
70 #include "core/svg/SVGDocument.h"
71 #include "core/svg/SVGSVGElement.h"
72 #include "platform/TraceEvent.h"
73 #include "platform/fonts/FontCache.h"
74 #include "platform/geometry/FloatRect.h"
75 #include "platform/graphics/GraphicsContext.h"
76 #include "platform/graphics/GraphicsLayerDebugInfo.h"
77 #include "platform/scroll/ScrollAnimator.h"
78 #include "platform/scroll/ScrollbarTheme.h"
79 #include "platform/text/TextStream.h"
80 #include "wtf/CurrentTime.h"
81 #include "wtf/TemporaryChange.h"
82
83 namespace WebCore {
84
85 using namespace HTMLNames;
86
87 double FrameView::s_currentFrameTimeStamp = 0.0;
88 bool FrameView::s_inPaintContents = false;
89
90 // The maximum number of updateWidgets iterations that should be done before returning.
91 static const unsigned maxUpdateWidgetsIterations = 2;
92 static const double resourcePriorityUpdateDelayAfterScroll = 0.250;
93
94 static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLayer* layer, bool isRelayoutingSubtree, bool didFullRepaint)
95 {
96     RenderLayer::UpdateLayerPositionsFlags flags = RenderLayer::defaultFlags;
97
98     if (didFullRepaint) {
99         flags &= ~RenderLayer::CheckForRepaint;
100         flags |= RenderLayer::NeedsFullRepaintInBacking;
101     }
102     if (isRelayoutingSubtree && layer->isPaginated())
103         flags |= RenderLayer::UpdatePagination;
104     return flags;
105 }
106
107 class FrameViewLayoutStateMaintainer {
108     WTF_MAKE_NONCOPYABLE(FrameViewLayoutStateMaintainer);
109 public:
110     FrameViewLayoutStateMaintainer(RenderObject& root, bool inSubtreeLayout)
111         : m_view(*root.view())
112         , m_inSubtreeLayout(inSubtreeLayout)
113         , m_disabled(inSubtreeLayout && m_view.shouldDisableLayoutStateForSubtree(root))
114     {
115         if (m_inSubtreeLayout)
116             m_view.pushLayoutState(root);
117         if (m_disabled)
118             m_view.disableLayoutState();
119     }
120
121     ~FrameViewLayoutStateMaintainer()
122     {
123         if (m_disabled)
124             m_view.enableLayoutState();
125         if (m_inSubtreeLayout)
126             m_view.popLayoutState();
127     }
128 private:
129     RenderView& m_view;
130     bool m_inSubtreeLayout;
131     bool m_disabled;
132 };
133
134 FrameView::FrameView(LocalFrame* frame)
135     : m_frame(frame)
136     , m_canHaveScrollbars(true)
137     , m_slowRepaintObjectCount(0)
138     , m_hasPendingLayout(false)
139     , m_layoutSubtreeRoot(0)
140     , m_inSynchronousPostLayout(false)
141     , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
142     , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired)
143     , m_isTransparent(false)
144     , m_baseBackgroundColor(Color::white)
145     , m_mediaType("screen")
146     , m_overflowStatusDirty(true)
147     , m_viewportRenderer(0)
148     , m_wasScrolledByUser(false)
149     , m_inProgrammaticScroll(false)
150     , m_safeToPropagateScrollToParent(true)
151     , m_isTrackingRepaints(false)
152     , m_scrollCorner(0)
153     , m_shouldAutoSize(false)
154     , m_inAutoSize(false)
155     , m_didRunAutosize(false)
156     , m_hasSoftwareFilters(false)
157     , m_visibleContentScaleFactor(1)
158     , m_inputEventsScaleFactorForEmulation(1)
159     , m_layoutSizeFixedToFrameSize(true)
160     , m_didScrollTimer(this, &FrameView::didScrollTimerFired)
161 {
162     ASSERT(m_frame);
163     init();
164
165     if (!isMainFrame())
166         return;
167
168     ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
169     ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
170 }
171
172 PassRefPtr<FrameView> FrameView::create(LocalFrame* frame)
173 {
174     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
175     view->show();
176     return view.release();
177 }
178
179 PassRefPtr<FrameView> FrameView::create(LocalFrame* frame, const IntSize& initialSize)
180 {
181     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
182     view->Widget::setFrameRect(IntRect(view->location(), initialSize));
183     view->setLayoutSizeInternal(initialSize);
184
185     view->show();
186     return view.release();
187 }
188
189 FrameView::~FrameView()
190 {
191     if (m_postLayoutTasksTimer.isActive())
192         m_postLayoutTasksTimer.stop();
193
194     if (m_didScrollTimer.isActive())
195         m_didScrollTimer.stop();
196
197     removeFromAXObjectCache();
198     resetScrollbars();
199
200     // Custom scrollbars should already be destroyed at this point
201     ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
202     ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
203
204     setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
205     setHasVerticalScrollbar(false);
206
207     ASSERT(!m_scrollCorner);
208
209     ASSERT(m_frame);
210     ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
211     RenderPart* renderer = m_frame->ownerRenderer();
212     if (renderer && renderer->widget() == this)
213         renderer->setWidget(nullptr);
214 }
215
216 void FrameView::reset()
217 {
218     m_cannotBlitToWindow = false;
219     m_isOverlapped = false;
220     m_contentIsOpaque = false;
221     m_hasPendingLayout = false;
222     m_layoutSubtreeRoot = 0;
223     m_doFullRepaint = false;
224     m_layoutSchedulingEnabled = true;
225     m_inPerformLayout = false;
226     m_canRepaintDuringPerformLayout = false;
227     m_doingPreLayoutStyleUpdate = false;
228     m_inSynchronousPostLayout = false;
229     m_layoutCount = 0;
230     m_nestedLayoutCount = 0;
231     m_postLayoutTasksTimer.stop();
232     m_updateWidgetsTimer.stop();
233     m_firstLayout = true;
234     m_firstLayoutCallbackPending = false;
235     m_wasScrolledByUser = false;
236     m_safeToPropagateScrollToParent = true;
237     m_lastViewportSize = IntSize();
238     m_lastZoomFactor = 1.0f;
239     m_isTrackingRepaints = false;
240     m_trackedRepaintRects.clear();
241     m_lastPaintTime = 0;
242     m_paintBehavior = PaintBehaviorNormal;
243     m_isPainting = false;
244     m_visuallyNonEmptyCharacterCount = 0;
245     m_visuallyNonEmptyPixelCount = 0;
246     m_isVisuallyNonEmpty = false;
247     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
248     m_maintainScrollPositionAnchor = nullptr;
249     m_viewportConstrainedObjects.clear();
250 }
251
252 void FrameView::removeFromAXObjectCache()
253 {
254     if (AXObjectCache* cache = axObjectCache())
255         cache->remove(this);
256 }
257
258 void FrameView::resetScrollbars()
259 {
260     // Reset the document's scrollbars back to our defaults before we yield the floor.
261     m_firstLayout = true;
262     setScrollbarsSuppressed(true);
263     if (m_canHaveScrollbars)
264         setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
265     else
266         setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
267     setScrollbarsSuppressed(false);
268 }
269
270 void FrameView::init()
271 {
272     reset();
273
274     m_size = LayoutSize();
275
276     // Propagate the marginwidth/height and scrolling modes to the view.
277     Element* ownerElement = m_frame->ownerElement();
278     if (ownerElement && (isHTMLFrameElement(*ownerElement) || isHTMLIFrameElement(*ownerElement))) {
279         HTMLFrameElementBase* frameElt = toHTMLFrameElementBase(ownerElement);
280         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
281             setCanHaveScrollbars(false);
282     }
283 }
284
285 void FrameView::prepareForDetach()
286 {
287     RELEASE_ASSERT(!isInPerformLayout());
288
289     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
290         scrollAnimator->cancelAnimations();
291
292     detachCustomScrollbars();
293     // When the view is no longer associated with a frame, it needs to be removed from the ax object cache
294     // right now, otherwise it won't be able to reach the topDocument()'s axObject cache later.
295     removeFromAXObjectCache();
296
297     if (m_frame->page()) {
298         if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator())
299             scrollingCoordinator->willDestroyScrollableArea(this);
300     }
301 }
302
303 void FrameView::detachCustomScrollbars()
304 {
305     Scrollbar* horizontalBar = horizontalScrollbar();
306     if (horizontalBar && horizontalBar->isCustomScrollbar())
307         setHasHorizontalScrollbar(false);
308
309     Scrollbar* verticalBar = verticalScrollbar();
310     if (verticalBar && verticalBar->isCustomScrollbar())
311         setHasVerticalScrollbar(false);
312
313     if (m_scrollCorner) {
314         m_scrollCorner->destroy();
315         m_scrollCorner = 0;
316     }
317 }
318
319 void FrameView::recalculateScrollbarOverlayStyle()
320 {
321     ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
322     ScrollbarOverlayStyle overlayStyle = ScrollbarOverlayStyleDefault;
323
324     Color backgroundColor = documentBackgroundColor();
325     // Reduce the background color from RGB to a lightness value
326     // and determine which scrollbar style to use based on a lightness
327     // heuristic.
328     double hue, saturation, lightness;
329     backgroundColor.getHSL(hue, saturation, lightness);
330     if (lightness <= .5)
331         overlayStyle = ScrollbarOverlayStyleLight;
332
333     if (oldOverlayStyle != overlayStyle)
334         setScrollbarOverlayStyle(overlayStyle);
335 }
336
337 void FrameView::clear()
338 {
339     reset();
340     setScrollbarsSuppressed(true);
341 }
342
343 bool FrameView::didFirstLayout() const
344 {
345     return !m_firstLayout;
346 }
347
348 void FrameView::invalidateRect(const IntRect& rect)
349 {
350     if (!parent()) {
351         if (HostWindow* window = hostWindow())
352             window->invalidateContentsAndRootView(rect);
353         return;
354     }
355
356     RenderPart* renderer = m_frame->ownerRenderer();
357     if (!renderer)
358         return;
359
360     IntRect repaintRect = rect;
361     repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
362                      renderer->borderTop() + renderer->paddingTop());
363     renderer->repaintRectangle(repaintRect);
364 }
365
366 void FrameView::setFrameRect(const IntRect& newRect)
367 {
368     IntRect oldRect = frameRect();
369     if (newRect == oldRect)
370         return;
371
372     // Autosized font sizes depend on the width of the viewing area.
373     if (newRect.width() != oldRect.width()) {
374         if (isMainFrame() && m_frame->settings()->textAutosizingEnabled()) {
375             for (LocalFrame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext()) {
376                 if (TextAutosizer* textAutosizer = frame->document()->textAutosizer())
377                     textAutosizer->recalculateMultipliers();
378             }
379         }
380     }
381
382     ScrollView::setFrameRect(newRect);
383
384     updateScrollableAreaSet();
385
386     if (RenderView* renderView = this->renderView()) {
387         if (renderView->usesCompositing())
388             renderView->compositor()->frameViewDidChangeSize();
389     }
390
391     viewportConstrainedVisibleContentSizeChanged(newRect.width() != oldRect.width(), newRect.height() != oldRect.height());
392 }
393
394 bool FrameView::scheduleAnimation()
395 {
396     if (HostWindow* window = hostWindow()) {
397         window->scheduleAnimation();
398         return true;
399     }
400     return false;
401 }
402
403 Page* FrameView::page() const
404 {
405     return frame().page();
406 }
407
408 RenderView* FrameView::renderView() const
409 {
410     return frame().contentRenderer();
411 }
412
413 void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
414 {
415     m_canHaveScrollbars = canHaveScrollbars;
416     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
417 }
418
419 bool FrameView::shouldUseCustomScrollbars(Element*& customScrollbarElement, LocalFrame*& customScrollbarFrame)
420 {
421     customScrollbarElement = 0;
422     customScrollbarFrame = 0;
423
424     if (Settings* settings = m_frame->settings()) {
425         if (!settings->allowCustomScrollbarInMainFrame() && isMainFrame())
426             return false;
427     }
428
429     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
430     Document* doc = m_frame->document();
431
432     // Try the <body> element first as a scrollbar source.
433     Element* body = doc ? doc->body() : 0;
434     if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR)) {
435         customScrollbarElement = body;
436         return true;
437     }
438
439     // If the <body> didn't have a custom style, then the root element might.
440     Element* docElement = doc ? doc->documentElement() : 0;
441     if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(SCROLLBAR)) {
442         customScrollbarElement = docElement;
443         return true;
444     }
445
446     // If we have an owning ipage/LocalFrame element, then it can set the custom scrollbar also.
447     RenderPart* frameRenderer = m_frame->ownerRenderer();
448     if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR)) {
449         customScrollbarFrame = m_frame.get();
450         return true;
451     }
452
453     return false;
454 }
455
456 PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
457 {
458     Element* customScrollbarElement = 0;
459     LocalFrame* customScrollbarFrame = 0;
460     if (shouldUseCustomScrollbars(customScrollbarElement, customScrollbarFrame))
461         return RenderScrollbar::createCustomScrollbar(this, orientation, customScrollbarElement, customScrollbarFrame);
462
463     // Nobody set a custom style, so we just use a native scrollbar.
464     return ScrollView::createScrollbar(orientation);
465 }
466
467 void FrameView::setContentsSize(const IntSize& size)
468 {
469     if (size == contentsSize())
470         return;
471
472     ScrollView::setContentsSize(size);
473     ScrollView::contentsResized();
474
475     Page* page = frame().page();
476     if (!page)
477         return;
478
479     updateScrollableAreaSet();
480
481     page->chrome().contentsSizeChanged(m_frame.get(), size);
482 }
483
484 IntPoint FrameView::clampOffsetAtScale(const IntPoint& offset, float scale) const
485 {
486     IntPoint maxScrollExtent(contentsSize().width() - scrollOrigin().x(), contentsSize().height() - scrollOrigin().y());
487     FloatSize scaledSize = unscaledVisibleContentSize();
488     if (scale)
489         scaledSize.scale(1 / scale);
490
491     IntPoint clampedOffset = offset;
492     clampedOffset = clampedOffset.shrunkTo(maxScrollExtent - expandedIntSize(scaledSize));
493     clampedOffset = clampedOffset.expandedTo(-scrollOrigin());
494
495     return clampedOffset;
496 }
497
498 void FrameView::adjustViewSize()
499 {
500     RenderView* renderView = this->renderView();
501     if (!renderView)
502         return;
503
504     ASSERT(m_frame->view() == this);
505
506     const IntRect rect = renderView->documentRect();
507     const IntSize& size = rect.size();
508     ScrollView::setScrollOrigin(IntPoint(-rect.x(), -rect.y()), !m_frame->document()->printing(), size == contentsSize());
509
510     setContentsSize(size);
511 }
512
513 void FrameView::applyOverflowToViewportAndSetRenderer(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
514 {
515     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
516     // overflow:hidden and overflow:scroll on <body> as applying to the document's
517     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
518     // use the root element.
519
520     EOverflow overflowX = o->style()->overflowX();
521     EOverflow overflowY = o->style()->overflowY();
522
523     if (o->isSVGRoot()) {
524         // overflow is ignored in stand-alone SVG documents.
525         if (!toRenderSVGRoot(o)->isEmbeddedThroughFrameContainingSVGDocument())
526             return;
527         overflowX = OHIDDEN;
528         overflowY = OHIDDEN;
529     }
530
531     bool ignoreOverflowHidden = false;
532     if (m_frame->settings()->ignoreMainFrameOverflowHiddenQuirk() && m_frame->isMainFrame())
533         ignoreOverflowHidden = true;
534
535     switch (overflowX) {
536         case OHIDDEN:
537             if (!ignoreOverflowHidden)
538                 hMode = ScrollbarAlwaysOff;
539             break;
540         case OSCROLL:
541             hMode = ScrollbarAlwaysOn;
542             break;
543         case OAUTO:
544             hMode = ScrollbarAuto;
545             break;
546         default:
547             // Don't set it at all.
548             ;
549     }
550
551      switch (overflowY) {
552         case OHIDDEN:
553             if (!ignoreOverflowHidden)
554                 vMode = ScrollbarAlwaysOff;
555             break;
556         case OSCROLL:
557             vMode = ScrollbarAlwaysOn;
558             break;
559         case OAUTO:
560             vMode = ScrollbarAuto;
561             break;
562         default:
563             // Don't set it at all.
564             ;
565     }
566
567     m_viewportRenderer = o;
568 }
569
570 void FrameView::calculateScrollbarModesForLayoutAndSetViewportRenderer(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
571 {
572     m_viewportRenderer = 0;
573
574     const HTMLFrameOwnerElement* owner = m_frame->ownerElement();
575     if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
576         hMode = ScrollbarAlwaysOff;
577         vMode = ScrollbarAlwaysOff;
578         return;
579     }
580
581     if (m_canHaveScrollbars || strategy == RulesFromWebContentOnly) {
582         hMode = ScrollbarAuto;
583         vMode = ScrollbarAuto;
584     } else {
585         hMode = ScrollbarAlwaysOff;
586         vMode = ScrollbarAlwaysOff;
587     }
588
589     if (!isSubtreeLayout()) {
590         Document* document = m_frame->document();
591         Node* body = document->body();
592         if (isHTMLFrameSetElement(body) && body->renderer()) {
593             vMode = ScrollbarAlwaysOff;
594             hMode = ScrollbarAlwaysOff;
595         } else if (Element* viewportElement = document->viewportDefiningElement()) {
596             if (RenderObject* viewportRenderer = viewportElement->renderer()) {
597                 if (viewportRenderer->style())
598                     applyOverflowToViewportAndSetRenderer(viewportRenderer, hMode, vMode);
599             }
600         }
601     }
602 }
603
604 void FrameView::updateCompositingLayersAfterStyleChange()
605 {
606     TRACE_EVENT0("webkit", "FrameView::updateCompositingLayersAfterStyleChange");
607     RenderView* renderView = this->renderView();
608     if (!renderView)
609         return;
610
611     // If we expect to update compositing after an incipient layout, don't do so here.
612     if (m_doingPreLayoutStyleUpdate || layoutPending() || renderView->needsLayout())
613         return;
614
615     // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
616     // https://code.google.com/p/chromium/issues/detail?id=343756
617     DisableCompositingQueryAsserts disabler;
618
619     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
620     renderView->compositor()->cacheAcceleratedCompositingFlags();
621
622     // Sometimes we will change a property (for example, z-index) that will not
623     // cause a layout, but will require us to update compositing state. We only
624     // need to do this if a layout is not already scheduled.
625     if (!needsLayout())
626         renderView->compositor()->updateCompositingRequirementsState();
627
628     renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterStyleChange);
629 }
630
631 void FrameView::updateCompositingLayersAfterLayout()
632 {
633     TRACE_EVENT0("webkit", "FrameView::updateCompositingLayersAfterLayout");
634     RenderView* renderView = this->renderView();
635     if (!renderView)
636         return;
637
638     // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
639     // https://code.google.com/p/chromium/issues/detail?id=343756
640     DisableCompositingQueryAsserts disabler;
641
642     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
643     renderView->compositor()->cacheAcceleratedCompositingFlags();
644     renderView->compositor()->updateCompositingRequirementsState();
645     renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterLayout);
646 }
647
648 bool FrameView::usesCompositedScrolling() const
649 {
650     RenderView* renderView = this->renderView();
651     if (!renderView)
652         return false;
653     if (m_frame->settings() && m_frame->settings()->compositedScrollingForFramesEnabled())
654         return renderView->compositor()->inForcedCompositingMode();
655     return false;
656 }
657
658 GraphicsLayer* FrameView::layerForScrolling() const
659 {
660     RenderView* renderView = this->renderView();
661     if (!renderView)
662         return 0;
663     return renderView->compositor()->scrollLayer();
664 }
665
666 GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
667 {
668     RenderView* renderView = this->renderView();
669     if (!renderView)
670         return 0;
671     return renderView->compositor()->layerForHorizontalScrollbar();
672 }
673
674 GraphicsLayer* FrameView::layerForVerticalScrollbar() const
675 {
676     RenderView* renderView = this->renderView();
677     if (!renderView)
678         return 0;
679     return renderView->compositor()->layerForVerticalScrollbar();
680 }
681
682 GraphicsLayer* FrameView::layerForScrollCorner() const
683 {
684     RenderView* renderView = this->renderView();
685     if (!renderView)
686         return 0;
687     return renderView->compositor()->layerForScrollCorner();
688 }
689
690 bool FrameView::hasCompositedContent() const
691 {
692     if (RenderView* renderView = this->renderView())
693         return renderView->compositor()->inCompositingMode();
694     return false;
695 }
696
697 bool FrameView::isEnclosedInCompositingLayer() const
698 {
699     RenderObject* frameOwnerRenderer = m_frame->ownerRenderer();
700     if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
701         return true;
702
703     if (FrameView* parentView = parentFrameView())
704         return parentView->isEnclosedInCompositingLayer();
705
706     return false;
707 }
708
709 RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
710 {
711     return onlyDuringLayout && layoutPending() ? 0 : m_layoutSubtreeRoot;
712 }
713
714 inline void FrameView::forceLayoutParentViewIfNeeded()
715 {
716     RenderPart* ownerRenderer = m_frame->ownerRenderer();
717     if (!ownerRenderer || !ownerRenderer->frame())
718         return;
719
720     RenderBox* contentBox = embeddedContentBox();
721     if (!contentBox)
722         return;
723
724     RenderSVGRoot* svgRoot = toRenderSVGRoot(contentBox);
725     if (svgRoot->everHadLayout() && !svgRoot->needsLayout())
726         return;
727
728     // If the embedded SVG document appears the first time, the ownerRenderer has already finished
729     // layout without knowing about the existence of the embedded SVG document, because RenderReplaced
730     // embeddedContentBox() returns 0, as long as the embedded document isn't loaded yet. Before
731     // bothering to lay out the SVG document, mark the ownerRenderer needing layout and ask its
732     // FrameView for a layout. After that the RenderEmbeddedObject (ownerRenderer) carries the
733     // correct size, which RenderSVGRoot::computeReplacedLogicalWidth/Height rely on, when laying
734     // out for the first time, or when the RenderSVGRoot size has changed dynamically (eg. via <script>).
735     RefPtr<FrameView> frameView = ownerRenderer->frame()->view();
736
737     // Mark the owner renderer as needing layout.
738     ownerRenderer->setNeedsLayoutAndPrefWidthsRecalc();
739
740     // Synchronously enter layout, to layout the view containing the host object/embed/iframe.
741     ASSERT(frameView);
742     frameView->layout();
743 }
744
745 void FrameView::performPreLayoutTasks()
746 {
747     TRACE_EVENT0("webkit", "FrameView::performPreLayoutTasks");
748     lifecycle().advanceTo(DocumentLifecycle::InPreLayout);
749
750     // Don't schedule more layouts, we're in one.
751     TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
752
753     if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive()) {
754         // This is a new top-level layout. If there are any remaining tasks from the previous layout, finish them now.
755         m_inSynchronousPostLayout = true;
756         performPostLayoutTasks();
757         m_inSynchronousPostLayout = false;
758     }
759
760     Document* document = m_frame->document();
761     document->notifyResizeForViewportUnits();
762
763     // Viewport-dependent media queries may cause us to need completely different style information.
764     if (!document->styleResolver() || document->styleResolver()->mediaQueryAffectedByViewportChange()) {
765         document->styleResolverChanged(RecalcStyleDeferred);
766         document->mediaQueryAffectingValueChanged();
767
768         // FIXME: This instrumentation event is not strictly accurate since cached media query results
769         //        do not persist across StyleResolver rebuilds.
770         InspectorInstrumentation::mediaQueryResultChanged(document);
771     } else {
772         document->evaluateMediaQueryList();
773     }
774
775     // Always ensure our style info is up-to-date. This can happen in situations where
776     // the layout beats any sort of style recalc update that needs to occur.
777     TemporaryChange<bool> changeDoingPreLayoutStyleUpdate(m_doingPreLayoutStyleUpdate, true);
778     document->updateRenderTreeIfNeeded();
779     lifecycle().advanceTo(DocumentLifecycle::StyleClean);
780 }
781
782 void FrameView::performLayout(RenderObject* rootForThisLayout, bool inSubtreeLayout)
783 {
784     TRACE_EVENT0("webkit", "FrameView::performLayout");
785
786     ASSERT(!isInPerformLayout());
787     lifecycle().advanceTo(DocumentLifecycle::InPerformLayout);
788
789     TemporaryChange<bool> changeInPerformLayout(m_inPerformLayout, true);
790
791     // performLayout is the actual guts of layout().
792     // FIXME: The 300 other lines in layout() probably belong in other helper functions
793     // so that a single human could understand what layout() is actually doing.
794
795     FrameViewLayoutStateMaintainer statePusher(*rootForThisLayout, inSubtreeLayout);
796     forceLayoutParentViewIfNeeded();
797
798     // FIXME (crbug.com/256657): Do not do two layouts for text autosizing.
799     rootForThisLayout->layout();
800     gatherDebugLayoutRects(rootForThisLayout);
801
802     ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllImageResourcePriorities();
803
804     TextAutosizer* textAutosizer = frame().document()->textAutosizer();
805     bool autosized = textAutosizer && textAutosizer->processSubtree(rootForThisLayout);
806     if (autosized && rootForThisLayout->needsLayout()) {
807         TRACE_EVENT0("webkit", "2nd layout due to Text Autosizing");
808         UseCounter::count(*frame().document(), UseCounter::TextAutosizingLayout);
809         rootForThisLayout->layout();
810         gatherDebugLayoutRects(rootForThisLayout);
811     }
812
813     lifecycle().advanceTo(DocumentLifecycle::AfterPerformLayout);
814 }
815
816 void FrameView::scheduleOrPerformPostLayoutTasks()
817 {
818     if (m_postLayoutTasksTimer.isActive())
819         return;
820
821     if (!m_inSynchronousPostLayout) {
822         m_inSynchronousPostLayout = true;
823         // Calls resumeScheduledEvents()
824         performPostLayoutTasks();
825         m_inSynchronousPostLayout = false;
826     }
827
828     if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout)) {
829         // If we need layout or are already in a synchronous call to postLayoutTasks(),
830         // defer widget updates and event dispatch until after we return. postLayoutTasks()
831         // can make us need to update again, and we can get stuck in a nasty cycle unless
832         // we call it through the timer here.
833         m_postLayoutTasksTimer.startOneShot(0, FROM_HERE);
834         if (needsLayout())
835             layout();
836     }
837 }
838
839 void FrameView::layout(bool allowSubtree)
840 {
841     // We should never layout a Document which is not in a LocalFrame.
842     ASSERT(m_frame);
843     ASSERT(m_frame->view() == this);
844     ASSERT(m_frame->page());
845
846     if (isInPerformLayout() || !m_frame->document()->isActive())
847         return;
848
849     TRACE_EVENT0("webkit", "FrameView::layout");
850     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "Layout");
851
852     // Protect the view from being deleted during layout (in recalcStyle)
853     RefPtr<FrameView> protector(this);
854
855     // Every scroll that happens during layout is programmatic.
856     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
857
858     m_hasPendingLayout = false;
859     DocumentLifecycle::Scope lifecycleScope(lifecycle(), DocumentLifecycle::LayoutClean);
860
861     RELEASE_ASSERT(!isPainting());
862
863     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(m_frame.get());
864
865     if (!allowSubtree && isSubtreeLayout()) {
866         m_layoutSubtreeRoot->markContainingBlocksForLayout(false);
867         m_layoutSubtreeRoot = 0;
868     }
869
870     performPreLayoutTasks();
871
872     // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
873     // so there's no point to continuing to layout
874     if (protector->hasOneRef())
875         return;
876
877     Document* document = m_frame->document();
878     bool inSubtreeLayout = isSubtreeLayout();
879     RenderObject* rootForThisLayout = inSubtreeLayout ? m_layoutSubtreeRoot : document->renderer();
880     if (!rootForThisLayout) {
881         // FIXME: Do we need to set m_size here?
882         ASSERT_NOT_REACHED();
883         return;
884     }
885
886     bool shouldDoFullLayout = false;
887     FontCachePurgePreventer fontCachePurgePreventer;
888     RenderLayer* layer;
889     {
890         TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
891
892         m_nestedLayoutCount++;
893         if (!inSubtreeLayout) {
894             Document* document = m_frame->document();
895             Node* body = document->body();
896             if (body && body->renderer()) {
897                 if (isHTMLFrameSetElement(*body)) {
898                     body->renderer()->setChildNeedsLayout();
899                 } else if (isHTMLBodyElement(*body)) {
900                     if (!m_firstLayout && m_size.height() != layoutSize().height() && body->renderer()->enclosingBox()->stretchesToViewport())
901                         body->renderer()->setChildNeedsLayout();
902                 }
903             }
904         }
905         updateCounters();
906         autoSizeIfEnabled();
907
908         ScrollbarMode hMode;
909         ScrollbarMode vMode;
910         calculateScrollbarModesForLayoutAndSetViewportRenderer(hMode, vMode);
911
912         shouldDoFullLayout = !inSubtreeLayout && (m_firstLayout || toRenderView(rootForThisLayout)->document().printing());
913
914         if (!inSubtreeLayout) {
915             // Now set our scrollbar state for the layout.
916             ScrollbarMode currentHMode = horizontalScrollbarMode();
917             ScrollbarMode currentVMode = verticalScrollbarMode();
918
919             if (m_firstLayout) {
920                 setScrollbarsSuppressed(true);
921
922                 m_firstLayout = false;
923                 m_firstLayoutCallbackPending = true;
924                 m_lastViewportSize = layoutSize(IncludeScrollbars);
925                 m_lastZoomFactor = rootForThisLayout->style()->zoom();
926
927                 // Set the initial vMode to AlwaysOn if we're auto.
928                 if (vMode == ScrollbarAuto)
929                     setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
930                 // Set the initial hMode to AlwaysOff if we're auto.
931                 if (hMode == ScrollbarAuto)
932                     setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
933
934                 setScrollbarModes(hMode, vMode);
935                 setScrollbarsSuppressed(false, true);
936             } else if (hMode != currentHMode || vMode != currentVMode) {
937                 setScrollbarModes(hMode, vMode);
938             }
939
940             LayoutSize oldSize = m_size;
941
942             m_size = LayoutSize(layoutSize().width(), layoutSize().height());
943
944             if (oldSize != m_size) {
945                 shouldDoFullLayout = true;
946                 if (!m_firstLayout) {
947                     RenderBox* rootRenderer = document->documentElement() ? document->documentElement()->renderBox() : 0;
948                     RenderBox* bodyRenderer = rootRenderer && document->body() ? document->body()->renderBox() : 0;
949                     if (bodyRenderer && bodyRenderer->stretchesToViewport())
950                         bodyRenderer->setChildNeedsLayout();
951                     else if (rootRenderer && rootRenderer->stretchesToViewport())
952                         rootRenderer->setChildNeedsLayout();
953                 }
954             }
955         }
956
957         layer = rootForThisLayout->enclosingLayer();
958
959         // We need to set m_doFullRepaint before triggering layout as RenderObject::checkForRepaint
960         // checks the boolean to disable local repaints.
961         m_doFullRepaint |= shouldDoFullLayout;
962
963         performLayout(rootForThisLayout, inSubtreeLayout);
964
965         m_layoutSubtreeRoot = 0;
966     } // Reset m_layoutSchedulingEnabled to its previous value.
967
968     if (!inSubtreeLayout && !toRenderView(rootForThisLayout)->document().printing())
969         adjustViewSize();
970
971     layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layer, inSubtreeLayout, m_doFullRepaint));
972
973     updateCompositingLayersAfterLayout();
974
975     m_layoutCount++;
976
977     if (AXObjectCache* cache = rootForThisLayout->document().existingAXObjectCache())
978         cache->postNotification(rootForThisLayout, AXObjectCache::AXLayoutComplete, true);
979     updateAnnotatedRegions();
980
981     ASSERT(!rootForThisLayout->needsLayout());
982
983     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
984         updateOverflowStatus(layoutSize().width() < contentsWidth(), layoutSize().height() < contentsHeight());
985
986     scheduleOrPerformPostLayoutTasks();
987
988     InspectorInstrumentation::didLayout(cookie, rootForThisLayout);
989
990     m_nestedLayoutCount--;
991     if (m_nestedLayoutCount)
992         return;
993
994     if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
995         if (m_doFullRepaint)
996             renderView()->setShouldDoFullRepaintAfterLayout(true);
997
998         repaintTree(rootForThisLayout);
999
1000     } else if (m_doFullRepaint) {
1001         // FIXME: This isn't really right, since the RenderView doesn't fully encompass
1002         // the visibleContentRect(). It just happens to work out most of the time,
1003         // since first layouts and printing don't have you scrolled anywhere.
1004         renderView()->repaint();
1005     }
1006
1007     m_doFullRepaint = false;
1008
1009 #ifndef NDEBUG
1010     // Post-layout assert that nobody was re-marked as needing layout during layout.
1011     document->renderer()->assertSubtreeIsLaidOut();
1012 #endif
1013
1014     // FIXME: It should be not possible to remove the FrameView from the frame/page during layout
1015     // however m_inPerformLayout is not set for most of this function, so none of our RELEASE_ASSERTS
1016     // in LocalFrame/Page will fire. One of the post-layout tasks is disconnecting the LocalFrame from
1017     // the page in fast/frames/crash-remove-iframe-during-object-beforeload-2.html
1018     // necessitating this check here.
1019     // ASSERT(frame()->page());
1020     if (frame().page())
1021         frame().page()->chrome().client().layoutUpdated(m_frame.get());
1022 }
1023
1024 // The plan is to move to compositor-queried repainting, in which case this
1025 // method would setNeedsRedraw on the GraphicsLayers with invalidations and
1026 // let the compositor pick which to actually draw.
1027 // See http://crbug.com/306706
1028 void FrameView::repaintTree(RenderObject* root)
1029 {
1030     ASSERT(RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
1031     ASSERT(!root->needsLayout());
1032     // We should only repaint for the outer most layout. This works as
1033     // we continue to track repaint rects until this function is called.
1034     ASSERT(!m_nestedLayoutCount);
1035
1036     // FIXME: really, we're in the repaint phase here, and the compositing queries are legal.
1037     // Until those states are fully fledged, I'll just disable the ASSERTS.
1038     DisableCompositingQueryAsserts disabler;
1039
1040     for (RenderObject* renderer = root; renderer; renderer = renderer->nextInPreOrder()) {
1041         const LayoutRect& oldRepaintRect = renderer->oldRepaintRect();
1042         const LayoutRect& newRepaintRect = renderer->newRepaintRect();
1043
1044         if ((renderer->onlyNeededPositionedMovementLayout() && renderer->compositingState() != PaintsIntoOwnBacking)
1045             || (renderer->shouldDoFullRepaintIfSelfPaintingLayer()
1046                 && renderer->hasLayer()
1047                 && toRenderLayerModelObject(renderer)->layer()->isSelfPaintingLayer())) {
1048             renderer->setShouldDoFullRepaintAfterLayout(true);
1049         }
1050
1051         // FIXME: Currently renderers with layers will get repainted when we call updateLayerPositionsAfterLayout.
1052         // That call should be broken apart to position the layers be done before
1053         // the repaintTree call so this will repaint everything.
1054         bool didFullRepaint = false;
1055         if (!renderer->layoutDidGetCalled()) {
1056             if (renderer->shouldDoFullRepaintAfterLayout()) {
1057                 renderer->repaint();
1058                 didFullRepaint = true;
1059             }
1060
1061         } else {
1062             didFullRepaint = renderer->repaintAfterLayoutIfNeeded(renderer->containerForRepaint(),
1063                 renderer->shouldDoFullRepaintAfterLayout(), oldRepaintRect, &newRepaintRect);
1064         }
1065
1066         if (!didFullRepaint)
1067             renderer->repaintOverflowIfNeeded();
1068
1069         // Repaint any scrollbars if there is a scrollable area for this renderer.
1070         if (RenderLayerScrollableArea* area = renderer->enclosingLayer()->scrollableArea()) {
1071             if (area->hasVerticalBarDamage())
1072                 renderer->repaintRectangle(area->verticalBarDamage());
1073             if (area->hasHorizontalBarDamage())
1074                 renderer->repaintRectangle(area->horizontalBarDamage());
1075             area->resetScrollbarDamage();
1076         }
1077
1078         // The list box has a verticalScrollbar we may need to repaint.
1079         if (renderer->isListBox()) {
1080             RenderListBox* listBox = static_cast<RenderListBox*>(renderer);
1081             listBox->repaintScrollbarIfNeeded();
1082         }
1083
1084         renderer->clearRepaintState();
1085     }
1086
1087     // Repaint the frameviews scrollbars if needed
1088     if (hasVerticalBarDamage())
1089         invalidateRect(verticalBarDamage());
1090     if (hasHorizontalBarDamage())
1091         invalidateRect(horizontalBarDamage());
1092     resetScrollbarDamage();
1093 }
1094
1095 DocumentLifecycle& FrameView::lifecycle() const
1096 {
1097     return m_frame->document()->lifecycle();
1098 }
1099
1100 void FrameView::gatherDebugLayoutRects(RenderObject* layoutRoot)
1101 {
1102     bool isTracing;
1103     TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("blink.debug.layout"), &isTracing);
1104     if (!isTracing)
1105         return;
1106     if (!layoutRoot->enclosingLayer()->hasCompositedLayerMapping())
1107         return;
1108     GraphicsLayer* graphicsLayer = layoutRoot->enclosingLayer()->compositedLayerMapping()->mainGraphicsLayer();
1109     if (!graphicsLayer)
1110         return;
1111
1112     GraphicsLayerDebugInfo& debugInfo = graphicsLayer->debugInfo();
1113
1114     debugInfo.currentLayoutRects().clear();
1115     for (RenderObject* renderer = layoutRoot; renderer; renderer = renderer->nextInPreOrder()) {
1116         if (renderer->layoutDidGetCalled()) {
1117             FloatQuad quad = renderer->localToAbsoluteQuad(FloatQuad(renderer->newRepaintRect()));
1118             LayoutRect rect = quad.enclosingBoundingBox();
1119             debugInfo.currentLayoutRects().append(rect);
1120             renderer->setLayoutDidGetCalled(false);
1121         }
1122     }
1123 }
1124
1125 RenderBox* FrameView::embeddedContentBox() const
1126 {
1127     RenderView* renderView = this->renderView();
1128     if (!renderView)
1129         return 0;
1130
1131     RenderObject* firstChild = renderView->firstChild();
1132     if (!firstChild || !firstChild->isBox())
1133         return 0;
1134
1135     // Curently only embedded SVG documents participate in the size-negotiation logic.
1136     if (firstChild->isSVGRoot())
1137         return toRenderBox(firstChild);
1138
1139     return 0;
1140 }
1141
1142
1143 void FrameView::addWidget(RenderWidget* object)
1144 {
1145     m_widgets.add(object);
1146 }
1147
1148 void FrameView::removeWidget(RenderWidget* object)
1149 {
1150     m_widgets.remove(object);
1151 }
1152
1153 void FrameView::updateWidgetPositions()
1154 {
1155     Vector<RefPtr<RenderWidget> > widgets;
1156     copyToVector(m_widgets, widgets);
1157
1158     // Script or plugins could detach the frame so abort processing if that happens.
1159
1160     for (size_t i = 0; i < widgets.size() && renderView(); ++i)
1161         widgets[i]->updateWidgetPosition();
1162
1163     for (size_t i = 0; i < widgets.size() && renderView(); ++i)
1164         widgets[i]->widgetPositionsUpdated();
1165 }
1166
1167 void FrameView::addWidgetToUpdate(RenderEmbeddedObject& object)
1168 {
1169     ASSERT(isInPerformLayout());
1170     // Tell the DOM element that it needs a widget update.
1171     Node* node = object.node();
1172     ASSERT(node);
1173     if (isHTMLObjectElement(*node) || isHTMLEmbedElement(*node))
1174         toHTMLPlugInElement(node)->setNeedsWidgetUpdate(true);
1175
1176     m_widgetUpdateSet.add(&object);
1177 }
1178
1179 void FrameView::setMediaType(const AtomicString& mediaType)
1180 {
1181     ASSERT(m_frame->document());
1182     m_frame->document()->mediaQueryAffectingValueChanged();
1183     m_mediaType = mediaType;
1184 }
1185
1186 AtomicString FrameView::mediaType() const
1187 {
1188     // See if we have an override type.
1189     String overrideType;
1190     InspectorInstrumentation::applyEmulatedMedia(m_frame.get(), &overrideType);
1191     if (!overrideType.isNull())
1192         return AtomicString(overrideType);
1193     return m_mediaType;
1194 }
1195
1196 void FrameView::adjustMediaTypeForPrinting(bool printing)
1197 {
1198     if (printing) {
1199         if (m_mediaTypeWhenNotPrinting.isNull())
1200             m_mediaTypeWhenNotPrinting = mediaType();
1201             setMediaType("print");
1202     } else {
1203         if (!m_mediaTypeWhenNotPrinting.isNull())
1204             setMediaType(m_mediaTypeWhenNotPrinting);
1205         m_mediaTypeWhenNotPrinting = nullAtom;
1206     }
1207 }
1208
1209 bool FrameView::useSlowRepaints(bool considerOverlap) const
1210 {
1211     if (m_slowRepaintObjectCount > 0)
1212         return true;
1213
1214     if (contentsInCompositedLayer())
1215         return false;
1216
1217     // The chromium compositor does not support scrolling a non-composited frame within a composited page through
1218     // the fast scrolling path, so force slow scrolling in that case.
1219     if (m_frame->ownerElement() && !hasCompositedContent() && m_frame->page() && m_frame->page()->mainFrame()->view()->hasCompositedContent())
1220         return true;
1221
1222     if (m_isOverlapped && considerOverlap)
1223         return true;
1224
1225     if (m_cannotBlitToWindow)
1226         return true;
1227
1228     if (!m_contentIsOpaque)
1229         return true;
1230
1231     if (FrameView* parentView = parentFrameView())
1232         return parentView->useSlowRepaints(considerOverlap);
1233
1234     return false;
1235 }
1236
1237 bool FrameView::useSlowRepaintsIfNotOverlapped() const
1238 {
1239     return useSlowRepaints(false);
1240 }
1241
1242 bool FrameView::shouldAttemptToScrollUsingFastPath() const
1243 {
1244     return !useSlowRepaints();
1245 }
1246
1247 bool FrameView::contentsInCompositedLayer() const
1248 {
1249     RenderView* renderView = this->renderView();
1250     if (renderView && renderView->compositingState() == PaintsIntoOwnBacking) {
1251         GraphicsLayer* layer = renderView->layer()->compositedLayerMapping()->mainGraphicsLayer();
1252         if (layer && layer->drawsContent())
1253             return true;
1254     }
1255
1256     return false;
1257 }
1258
1259 void FrameView::setCannotBlitToWindow()
1260 {
1261     m_cannotBlitToWindow = true;
1262 }
1263
1264 void FrameView::addSlowRepaintObject()
1265 {
1266     if (!m_slowRepaintObjectCount++) {
1267         if (Page* page = m_frame->page()) {
1268             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1269                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
1270         }
1271     }
1272 }
1273
1274 void FrameView::removeSlowRepaintObject()
1275 {
1276     ASSERT(m_slowRepaintObjectCount > 0);
1277     m_slowRepaintObjectCount--;
1278     if (!m_slowRepaintObjectCount) {
1279         if (Page* page = m_frame->page()) {
1280             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1281                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
1282         }
1283     }
1284 }
1285
1286 void FrameView::addViewportConstrainedObject(RenderObject* object)
1287 {
1288     if (!m_viewportConstrainedObjects)
1289         m_viewportConstrainedObjects = adoptPtr(new ViewportConstrainedObjectSet);
1290
1291     if (!m_viewportConstrainedObjects->contains(object)) {
1292         m_viewportConstrainedObjects->add(object);
1293
1294         if (Page* page = m_frame->page()) {
1295             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1296                 scrollingCoordinator->frameViewFixedObjectsDidChange(this);
1297         }
1298     }
1299 }
1300
1301 void FrameView::removeViewportConstrainedObject(RenderObject* object)
1302 {
1303     if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->contains(object)) {
1304         m_viewportConstrainedObjects->remove(object);
1305
1306         if (Page* page = m_frame->page()) {
1307             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
1308                 scrollingCoordinator->frameViewFixedObjectsDidChange(this);
1309         }
1310     }
1311 }
1312
1313 LayoutRect FrameView::viewportConstrainedVisibleContentRect() const
1314 {
1315     LayoutRect viewportRect = visibleContentRect();
1316     // Ignore overhang. No-op when not using rubber banding.
1317     viewportRect.setLocation(clampScrollPosition(scrollPosition()));
1318     return viewportRect;
1319 }
1320
1321 void FrameView::viewportConstrainedVisibleContentSizeChanged(bool widthChanged, bool heightChanged)
1322 {
1323     // If viewport is not enabled, frameRect change will cause layout size change and then layout.
1324     // Otherwise, viewport constrained objects need their layout flags set separately to ensure
1325     // they are positioned correctly.
1326     if ((m_frame->settings() && !m_frame->settings()->viewportEnabled()) || !hasViewportConstrainedObjects())
1327         return;
1328
1329     ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
1330     for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
1331         RenderObject* renderer = *it;
1332         RenderStyle* style = renderer->style();
1333         if (widthChanged) {
1334             if (style->width().isFixed() && (style->left().isAuto() || style->right().isAuto()))
1335                 renderer->setNeedsPositionedMovementLayout();
1336             else
1337                 renderer->setNeedsLayout();
1338         }
1339         if (heightChanged) {
1340             if (style->height().isFixed() && (style->top().isAuto() || style->bottom().isAuto()))
1341                 renderer->setNeedsPositionedMovementLayout();
1342             else
1343                 renderer->setNeedsLayout();
1344         }
1345     }
1346 }
1347
1348 bool FrameView::shouldPlaceVerticalScrollbarOnLeft() const
1349 {
1350     // FIXME: Mainframe scrollbar placement should respect the embedding application RTL UI policy.
1351     // See crbug.com/249860.
1352     if (isMainFrame())
1353         return false;
1354
1355     Document* document = m_frame->document();
1356     if (!document)
1357         return false;
1358
1359     // <body> inherits 'direction' from <html>, so it can safaly be used
1360     // to dictate the frame vertical scrollbar placement.
1361     if (!document->body() || !document->body()->renderer())
1362         return false;
1363
1364     return document->body()->renderer()->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft();
1365 }
1366
1367 IntSize FrameView::scrollOffsetForFixedPosition() const
1368 {
1369     return toIntSize(clampScrollPosition(scrollPosition()));
1370 }
1371
1372 IntPoint FrameView::lastKnownMousePosition() const
1373 {
1374     return m_frame->eventHandler().lastKnownMousePosition();
1375 }
1376
1377 bool FrameView::shouldSetCursor() const
1378 {
1379     Page* page = frame().page();
1380     return page && page->visibilityState() != PageVisibilityStateHidden && page->focusController().isActive();
1381 }
1382
1383 void FrameView::scrollContentsIfNeededRecursive()
1384 {
1385     scrollContentsIfNeeded();
1386
1387     for (LocalFrame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
1388         if (FrameView* view = child->view())
1389             view->scrollContentsIfNeededRecursive();
1390     }
1391 }
1392
1393 void FrameView::scrollContentsIfNeeded()
1394 {
1395     bool didScroll = !pendingScrollDelta().isZero();
1396     ScrollView::scrollContentsIfNeeded();
1397     if (didScroll)
1398         updateFixedElementRepaintRectsAfterScroll();
1399 }
1400
1401 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
1402 {
1403     if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty()) {
1404         hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1405         return true;
1406     }
1407
1408     const bool isCompositedContentLayer = contentsInCompositedLayer();
1409
1410     // Get the rects of the fixed objects visible in the rectToScroll
1411     Region regionToUpdate;
1412     ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
1413     for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
1414         RenderObject* renderer = *it;
1415         // m_viewportConstrainedObjects should not contain non-viewport constrained objects.
1416         ASSERT(renderer->style()->hasViewportConstrainedPosition());
1417
1418         // Fixed items should always have layers.
1419         ASSERT(renderer->hasLayer());
1420         RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1421
1422         // Layers that paint into their ancestor or into a grouped backing will still need
1423         // to apply a repaint invalidation. If the layer paints into its own backing, then
1424         // it does not need repainting just to scroll.
1425         if (layer->compositingState() == PaintsIntoOwnBacking)
1426             continue;
1427
1428         if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForBoundsOutOfView
1429             || layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForNoVisibleContent) {
1430             // Don't invalidate for invisible fixed layers.
1431             continue;
1432         }
1433
1434         if (layer->hasAncestorWithFilterOutsets()) {
1435             // If the fixed layer has a blur/drop-shadow filter applied on at least one of its parents, we cannot
1436             // scroll using the fast path, otherwise the outsets of the filter will be moved around the page.
1437             return false;
1438         }
1439
1440         IntRect updateRect = pixelSnappedIntRect(layer->repainter().repaintRectIncludingNonCompositingDescendants());
1441
1442         RenderLayer* enclosingCompositingLayer = layer->enclosingCompositingLayer(ExcludeSelf);
1443         if (enclosingCompositingLayer && !enclosingCompositingLayer->renderer()->isRenderView()) {
1444             // If the fixed-position layer is contained by a composited layer that is not its containing block,
1445             // then we have to invlidate that enclosing layer, not the RenderView.
1446             updateRect.moveBy(scrollPosition());
1447             IntRect previousRect = updateRect;
1448             previousRect.move(scrollDelta);
1449             updateRect.unite(previousRect);
1450             enclosingCompositingLayer->repainter().setBackingNeedsRepaintInRect(updateRect);
1451         } else {
1452             // Coalesce the repaints that will be issued to the renderView.
1453             updateRect = contentsToRootView(updateRect);
1454             if (!isCompositedContentLayer && clipsRepaints())
1455                 updateRect.intersect(rectToScroll);
1456             if (!updateRect.isEmpty())
1457                 regionToUpdate.unite(updateRect);
1458         }
1459     }
1460
1461     // 1) scroll
1462     hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1463
1464     // 2) update the area of fixed objects that has been invalidated
1465     Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
1466     size_t viewportConstrainedObjectsCount = subRectsToUpdate.size();
1467     for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) {
1468         IntRect updateRect = subRectsToUpdate[i];
1469         IntRect scrolledRect = updateRect;
1470         scrolledRect.move(-scrollDelta);
1471         updateRect.unite(scrolledRect);
1472         if (isCompositedContentLayer) {
1473             updateRect = rootViewToContents(updateRect);
1474             ASSERT(renderView());
1475             renderView()->layer()->repainter().setBackingNeedsRepaintInRect(updateRect);
1476             continue;
1477         }
1478         if (clipsRepaints())
1479             updateRect.intersect(rectToScroll);
1480         hostWindow()->invalidateContentsAndRootView(updateRect);
1481     }
1482
1483     return true;
1484 }
1485
1486 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
1487 {
1488     if (contentsInCompositedLayer()) {
1489         IntRect updateRect = visibleContentRect();
1490         ASSERT(renderView());
1491         renderView()->layer()->repainter().setBackingNeedsRepaintInRect(updateRect);
1492     }
1493     if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
1494         if (isEnclosedInCompositingLayer()) {
1495             LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
1496                             frameRenderer->borderTop() + frameRenderer->paddingTop(),
1497                             visibleWidth(), visibleHeight());
1498             frameRenderer->repaintRectangle(rect);
1499             return;
1500         }
1501     }
1502
1503     ScrollView::scrollContentsSlowPath(updateRect);
1504 }
1505
1506 // Note that this gets called at painting time.
1507 void FrameView::setIsOverlapped(bool isOverlapped)
1508 {
1509     m_isOverlapped = isOverlapped;
1510 }
1511
1512 void FrameView::setContentIsOpaque(bool contentIsOpaque)
1513 {
1514     m_contentIsOpaque = contentIsOpaque;
1515 }
1516
1517 void FrameView::restoreScrollbar()
1518 {
1519     setScrollbarsSuppressed(false);
1520 }
1521
1522 bool FrameView::scrollToFragment(const KURL& url)
1523 {
1524     // If our URL has no ref, then we have no place we need to jump to.
1525     // OTOH If CSS target was set previously, we want to set it to 0, recalc
1526     // and possibly repaint because :target pseudo class may have been
1527     // set (see bug 11321).
1528     if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget())
1529         return false;
1530
1531     String fragmentIdentifier = url.fragmentIdentifier();
1532     if (scrollToAnchor(fragmentIdentifier))
1533         return true;
1534
1535     // Try again after decoding the ref, based on the document's encoding.
1536     if (m_frame->document()->encoding().isValid())
1537         return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, m_frame->document()->encoding()));
1538
1539     return false;
1540 }
1541
1542 bool FrameView::scrollToAnchor(const String& name)
1543 {
1544     ASSERT(m_frame->document());
1545
1546     if (!m_frame->document()->haveStylesheetsLoaded()) {
1547         m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
1548         return false;
1549     }
1550
1551     m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false);
1552
1553     Element* anchorNode = m_frame->document()->findAnchor(name);
1554
1555     // Setting to null will clear the current target.
1556     m_frame->document()->setCSSTarget(anchorNode);
1557
1558     if (m_frame->document()->isSVGDocument()) {
1559         if (SVGSVGElement* svg = toSVGDocument(m_frame->document())->rootElement()) {
1560             svg->setupInitialView(name, anchorNode);
1561             if (!anchorNode)
1562                 return true;
1563         }
1564     }
1565
1566     // Implement the rule that "" and "top" both mean top of page as in other browsers.
1567     if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top")))
1568         return false;
1569
1570     maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document());
1571
1572     // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
1573     if (anchorNode && anchorNode->isFocusable())
1574         m_frame->document()->setFocusedElement(anchorNode);
1575
1576     return true;
1577 }
1578
1579 void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
1580 {
1581     m_maintainScrollPositionAnchor = anchorNode;
1582     if (!m_maintainScrollPositionAnchor)
1583         return;
1584
1585     // We need to update the layout before scrolling, otherwise we could
1586     // really mess things up if an anchor scroll comes at a bad moment.
1587     m_frame->document()->updateRenderTreeIfNeeded();
1588     // Only do a layout if changes have occurred that make it necessary.
1589     RenderView* renderView = this->renderView();
1590     if (renderView && renderView->needsLayout())
1591         layout();
1592     else
1593         scrollToAnchor();
1594 }
1595
1596 void FrameView::scrollElementToRect(Element* element, const IntRect& rect)
1597 {
1598     m_frame->document()->updateLayoutIgnorePendingStylesheets();
1599
1600     LayoutRect bounds = element->boundingBox();
1601     int centeringOffsetX = (rect.width() - bounds.width()) / 2;
1602     int centeringOffsetY = (rect.height() - bounds.height()) / 2;
1603     setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y()));
1604 }
1605
1606 void FrameView::setScrollPosition(const IntPoint& scrollPoint)
1607 {
1608     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
1609     m_maintainScrollPositionAnchor = nullptr;
1610
1611     IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
1612
1613     if (newScrollPosition == scrollPosition())
1614         return;
1615
1616     ScrollView::setScrollPosition(newScrollPosition);
1617 }
1618
1619 void FrameView::setScrollPositionNonProgrammatically(const IntPoint& scrollPoint)
1620 {
1621     IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
1622
1623     if (newScrollPosition == scrollPosition())
1624         return;
1625
1626     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, false);
1627     notifyScrollPositionChanged(newScrollPosition);
1628 }
1629
1630 IntSize FrameView::layoutSize(IncludeScrollbarsInRect scrollbarInclusion) const
1631 {
1632     return scrollbarInclusion == ExcludeScrollbars ? excludeScrollbars(m_layoutSize) : m_layoutSize;
1633 }
1634
1635 void FrameView::setLayoutSize(const IntSize& size)
1636 {
1637     ASSERT(!layoutSizeFixedToFrameSize());
1638
1639     setLayoutSizeInternal(size);
1640 }
1641
1642 void FrameView::scrollPositionChanged()
1643 {
1644     setWasScrolledByUser(true);
1645
1646     Document* document = m_frame->document();
1647     document->enqueueScrollEventForNode(document);
1648
1649     m_frame->eventHandler().dispatchFakeMouseMoveEventSoon();
1650
1651     if (RenderView* renderView = document->renderView()) {
1652         if (renderView->usesCompositing()) {
1653             // https://code.google.com/p/chromium/issues/detail?id=343767
1654             DisableCompositingQueryAsserts disabler;
1655             renderView->compositor()->frameViewDidScroll();
1656         }
1657     }
1658
1659     if (m_didScrollTimer.isActive())
1660         m_didScrollTimer.stop();
1661     m_didScrollTimer.startOneShot(resourcePriorityUpdateDelayAfterScroll, FROM_HERE);
1662
1663     if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
1664         cache->handleScrollPositionChanged(this);
1665
1666     frame().loader().saveScrollState();
1667 }
1668
1669 void FrameView::didScrollTimerFired(Timer<FrameView>*)
1670 {
1671     if (m_frame->document() && m_frame->document()->renderer()) {
1672         ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllImageResourcePriorities();
1673     }
1674 }
1675
1676 void FrameView::updateLayersAndCompositingAfterScrollIfNeeded()
1677 {
1678     // Nothing to do after scrolling if there are no fixed position elements.
1679     if (!hasViewportConstrainedObjects())
1680         return;
1681
1682     RefPtr<FrameView> protect(this);
1683
1684     // If there fixed position elements, scrolling may cause compositing layers to change.
1685     // Update widget and layer positions after scrolling, but only if we're not inside of
1686     // layout.
1687     if (!m_nestedLayoutCount) {
1688         updateWidgetPositions();
1689         if (RenderView* renderView = this->renderView())
1690             renderView->layer()->updateLayerPositionsAfterDocumentScroll();
1691     }
1692
1693     // Compositing layers may change after scrolling.
1694     // FIXME: Maybe no longer needed after we land squashing and kill overlap testing?
1695     if (RenderView* renderView = this->renderView())
1696         renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdateOnScroll);
1697 }
1698
1699 void FrameView::updateFixedElementRepaintRectsAfterScroll()
1700 {
1701     if (!hasViewportConstrainedObjects())
1702         return;
1703
1704     // Update the repaint rects for fixed elements after scrolling and invalidation to reflect
1705     // the new scroll position.
1706     ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
1707     for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
1708         RenderObject* renderer = *it;
1709         // m_viewportConstrainedObjects should not contain non-viewport constrained objects.
1710         ASSERT(renderer->style()->hasViewportConstrainedPosition());
1711
1712         // Fixed items should always have layers.
1713         ASSERT(renderer->hasLayer());
1714
1715         RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1716
1717         // Don't need to do this for composited fixed items.
1718         if (layer->compositingState() == PaintsIntoOwnBacking)
1719             continue;
1720
1721         // Also don't need to do this for invisible items.
1722         if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForBoundsOutOfView
1723             || layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForNoVisibleContent)
1724             continue;
1725
1726         layer->repainter().computeRepaintRectsIncludingDescendants();
1727     }
1728 }
1729
1730 bool FrameView::shouldRubberBandInDirection(ScrollDirection direction) const
1731 {
1732     Page* page = frame().page();
1733     if (!page)
1734         return ScrollView::shouldRubberBandInDirection(direction);
1735     return page->chrome().client().shouldRubberBandInDirection(direction);
1736 }
1737
1738 bool FrameView::isRubberBandInProgress() const
1739 {
1740     if (scrollbarsSuppressed())
1741         return false;
1742
1743     // If the main thread updates the scroll position for this FrameView, we should return
1744     // ScrollAnimator::isRubberBandInProgress().
1745     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
1746         return scrollAnimator->isRubberBandInProgress();
1747
1748     return false;
1749 }
1750
1751 HostWindow* FrameView::hostWindow() const
1752 {
1753     Page* page = frame().page();
1754     if (!page)
1755         return 0;
1756     return &page->chrome();
1757 }
1758
1759 void FrameView::repaintContentRectangle(const IntRect& r)
1760 {
1761     ASSERT(repaintAllowed());
1762     ASSERT(!m_frame->ownerElement());
1763
1764     if (m_isTrackingRepaints) {
1765         IntRect repaintRect = r;
1766         repaintRect.move(-scrollOffset());
1767         m_trackedRepaintRects.append(repaintRect);
1768     }
1769
1770     ScrollView::repaintContentRectangle(r);
1771 }
1772
1773 void FrameView::contentsResized()
1774 {
1775     ScrollView::contentsResized();
1776     setNeedsLayout();
1777 }
1778
1779 void FrameView::scrollbarExistenceDidChange()
1780 {
1781     // We check to make sure the view is attached to a frame() as this method can
1782     // be triggered before the view is attached by LocalFrame::createView(...) setting
1783     // various values such as setScrollBarModes(...) for example.  An ASSERT is
1784     // triggered when a view is layout before being attached to a frame().
1785     if (!frame().view())
1786         return;
1787
1788     // Note that simply having overlay scrollbars is not sufficient to be
1789     // certain that scrollbars' presence does not impact layout. This should
1790     // also check if custom scrollbars (as reported by shouldUseCustomScrollbars)
1791     // are in use as well.
1792     // http://crbug.com/269692
1793     bool useOverlayScrollbars = ScrollbarTheme::theme()->usesOverlayScrollbars();
1794
1795     if (!useOverlayScrollbars && needsLayout())
1796         layout();
1797
1798     if (renderView() && renderView()->usesCompositing()) {
1799         renderView()->compositor()->frameViewScrollbarsExistenceDidChange();
1800
1801         if (!useOverlayScrollbars)
1802             renderView()->compositor()->frameViewDidChangeSize();
1803     }
1804 }
1805
1806 void FrameView::handleLoadCompleted()
1807 {
1808     // Once loading has completed, allow autoSize one last opportunity to
1809     // reduce the size of the frame.
1810     autoSizeIfEnabled();
1811 }
1812
1813 void FrameView::scheduleRelayout()
1814 {
1815     ASSERT(m_frame->view() == this);
1816
1817     if (isSubtreeLayout()) {
1818         m_layoutSubtreeRoot->markContainingBlocksForLayout(false);
1819         m_layoutSubtreeRoot = 0;
1820     }
1821     if (!m_layoutSchedulingEnabled)
1822         return;
1823     if (!needsLayout())
1824         return;
1825     if (!m_frame->document()->shouldScheduleLayout())
1826         return;
1827     InspectorInstrumentation::didInvalidateLayout(m_frame.get());
1828
1829     if (m_hasPendingLayout)
1830         return;
1831     m_hasPendingLayout = true;
1832     page()->animator().scheduleVisualUpdate();
1833 }
1834
1835 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
1836 {
1837     for (RenderObject* r = descendant; r; r = r->container()) {
1838         if (r == ancestor)
1839             return true;
1840     }
1841     return false;
1842 }
1843
1844 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
1845 {
1846     ASSERT(m_frame->view() == this);
1847
1848     RenderView* renderView = this->renderView();
1849     if (renderView && renderView->needsLayout()) {
1850         if (relayoutRoot)
1851             relayoutRoot->markContainingBlocksForLayout(false);
1852         return;
1853     }
1854
1855     if (layoutPending() || !m_layoutSchedulingEnabled) {
1856         if (m_layoutSubtreeRoot != relayoutRoot) {
1857             if (isObjectAncestorContainerOf(m_layoutSubtreeRoot, relayoutRoot)) {
1858                 // Keep the current root
1859                 relayoutRoot->markContainingBlocksForLayout(false, m_layoutSubtreeRoot);
1860                 ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
1861             } else if (isSubtreeLayout() && isObjectAncestorContainerOf(relayoutRoot, m_layoutSubtreeRoot)) {
1862                 // Re-root at relayoutRoot
1863                 m_layoutSubtreeRoot->markContainingBlocksForLayout(false, relayoutRoot);
1864                 m_layoutSubtreeRoot = relayoutRoot;
1865                 ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
1866                 InspectorInstrumentation::didInvalidateLayout(m_frame.get());
1867             } else {
1868                 // Just do a full relayout
1869                 if (isSubtreeLayout())
1870                     m_layoutSubtreeRoot->markContainingBlocksForLayout(false);
1871                 m_layoutSubtreeRoot = 0;
1872                 relayoutRoot->markContainingBlocksForLayout(false);
1873                 InspectorInstrumentation::didInvalidateLayout(m_frame.get());
1874             }
1875         }
1876     } else if (m_layoutSchedulingEnabled) {
1877         m_layoutSubtreeRoot = relayoutRoot;
1878         ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
1879         InspectorInstrumentation::didInvalidateLayout(m_frame.get());
1880         m_hasPendingLayout = true;
1881         page()->animator().scheduleVisualUpdate();
1882     }
1883 }
1884
1885 bool FrameView::layoutPending() const
1886 {
1887     return m_hasPendingLayout;
1888 }
1889
1890 bool FrameView::isInPerformLayout() const
1891 {
1892     ASSERT(m_inPerformLayout == (lifecycle().state() == DocumentLifecycle::InPerformLayout));
1893     return m_inPerformLayout;
1894 }
1895
1896 bool FrameView::needsLayout() const
1897 {
1898     // This can return true in cases where the document does not have a body yet.
1899     // Document::shouldScheduleLayout takes care of preventing us from scheduling
1900     // layout in that case.
1901
1902     RenderView* renderView = this->renderView();
1903     return layoutPending()
1904         || (renderView && renderView->needsLayout())
1905         || isSubtreeLayout();
1906 }
1907
1908 void FrameView::setNeedsLayout()
1909 {
1910     if (RenderView* renderView = this->renderView())
1911         renderView->setNeedsLayout();
1912 }
1913
1914 bool FrameView::isTransparent() const
1915 {
1916     return m_isTransparent;
1917 }
1918
1919 void FrameView::setTransparent(bool isTransparent)
1920 {
1921     m_isTransparent = isTransparent;
1922     DisableCompositingQueryAsserts disabler;
1923     if (renderView() && renderView()->layer()->hasCompositedLayerMapping())
1924         renderView()->layer()->compositedLayerMapping()->updateContentsOpaque();
1925 }
1926
1927 bool FrameView::hasOpaqueBackground() const
1928 {
1929     return !m_isTransparent && !m_baseBackgroundColor.hasAlpha();
1930 }
1931
1932 Color FrameView::baseBackgroundColor() const
1933 {
1934     return m_baseBackgroundColor;
1935 }
1936
1937 void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
1938 {
1939     m_baseBackgroundColor = backgroundColor;
1940
1941     if (renderView() && renderView()->layer()->hasCompositedLayerMapping()) {
1942         CompositedLayerMappingPtr compositedLayerMapping = renderView()->layer()->compositedLayerMapping();
1943         compositedLayerMapping->updateContentsOpaque();
1944         if (compositedLayerMapping->mainGraphicsLayer())
1945             compositedLayerMapping->mainGraphicsLayer()->setNeedsDisplay();
1946     }
1947     recalculateScrollbarOverlayStyle();
1948 }
1949
1950 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
1951 {
1952     for (LocalFrame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
1953         if (FrameView* view = frame->view()) {
1954             view->setTransparent(transparent);
1955             view->setBaseBackgroundColor(backgroundColor);
1956         }
1957     }
1958 }
1959
1960 void FrameView::scrollToAnchor()
1961 {
1962     RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
1963     if (!anchorNode)
1964         return;
1965
1966     if (!anchorNode->renderer())
1967         return;
1968
1969     LayoutRect rect;
1970     if (anchorNode != m_frame->document())
1971         rect = anchorNode->boundingBox();
1972
1973     // Scroll nested layers and frames to reveal the anchor.
1974     // Align to the top and to the closest side (this matches other browsers).
1975     anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
1976
1977     if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
1978         cache->handleScrolledToAnchor(anchorNode.get());
1979
1980     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
1981     m_maintainScrollPositionAnchor = anchorNode;
1982 }
1983
1984 bool FrameView::updateWidgets()
1985 {
1986     // This is always called from updateWidgetsTimerFired.
1987     // m_updateWidgetsTimer should only be scheduled if we have widgets to update.
1988     // Thus I believe we can stop checking isEmpty here, and just ASSERT isEmpty:
1989     ASSERT(!m_widgetUpdateSet.isEmpty());
1990     if (m_nestedLayoutCount > 1 || m_widgetUpdateSet.isEmpty())
1991         return true;
1992
1993     // Need to swap because script will run inside the below loop and invalidate the iterator.
1994     EmbeddedObjectSet objects;
1995     objects.swap(m_widgetUpdateSet);
1996
1997     for (EmbeddedObjectSet::iterator it = objects.begin(); it != objects.end(); ++it) {
1998         RenderEmbeddedObject& object = **it;
1999         HTMLPlugInElement* element = toHTMLPlugInElement(object.node());
2000
2001         // The object may have already been destroyed (thus node cleared),
2002         // but FrameView holds a manual ref, so it won't have been deleted.
2003         if (!element)
2004             continue;
2005
2006         // No need to update if it's already crashed or known to be missing.
2007         if (object.showsUnavailablePluginIndicator())
2008             continue;
2009
2010         if (element->needsWidgetUpdate())
2011             element->updateWidget();
2012         object.updateWidgetPosition();
2013
2014         // Prevent plugins from causing infinite updates of themselves.
2015         // FIXME: Do we really need to prevent this?
2016         m_widgetUpdateSet.remove(&object);
2017     }
2018
2019     return m_widgetUpdateSet.isEmpty();
2020 }
2021
2022 void FrameView::updateWidgetsTimerFired(Timer<FrameView>*)
2023 {
2024     ASSERT(!isInPerformLayout());
2025     RefPtr<FrameView> protect(this);
2026     m_updateWidgetsTimer.stop();
2027     for (unsigned i = 0; i < maxUpdateWidgetsIterations; ++i) {
2028         if (updateWidgets())
2029             return;
2030     }
2031 }
2032
2033 void FrameView::flushAnyPendingPostLayoutTasks()
2034 {
2035     ASSERT(!isInPerformLayout());
2036     if (m_postLayoutTasksTimer.isActive())
2037         performPostLayoutTasks();
2038     if (m_updateWidgetsTimer.isActive())
2039         updateWidgetsTimerFired(0);
2040 }
2041
2042 void FrameView::scheduleUpdateWidgetsIfNecessary()
2043 {
2044     ASSERT(!isInPerformLayout());
2045     if (m_updateWidgetsTimer.isActive() || m_widgetUpdateSet.isEmpty())
2046         return;
2047     m_updateWidgetsTimer.startOneShot(0, FROM_HERE);
2048 }
2049
2050 void FrameView::performPostLayoutTasks()
2051 {
2052     // FIXME: We can reach here, even when the page is not active!
2053     // http/tests/inspector/elements/html-link-import.html and many other
2054     // tests hit that case.
2055     // We should ASSERT(isActive()); or at least return early if we can!
2056     ASSERT(!isInPerformLayout()); // Always before or after performLayout(), part of the highest-level layout() call.
2057     TRACE_EVENT0("webkit", "FrameView::performPostLayoutTasks");
2058     RefPtr<FrameView> protect(this);
2059
2060     m_postLayoutTasksTimer.stop();
2061
2062     m_frame->selection().setCaretRectNeedsUpdate();
2063
2064     {
2065         // Hits in compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html
2066         DisableCompositingQueryAsserts disabler;
2067         m_frame->selection().updateAppearance();
2068     }
2069
2070     ASSERT(m_frame->document());
2071     if (m_nestedLayoutCount <= 1) {
2072         if (m_firstLayoutCallbackPending)
2073             m_firstLayoutCallbackPending = false;
2074
2075         // Ensure that we always send this eventually.
2076         if (!m_frame->document()->parsing() && m_frame->loader().stateMachine()->committedFirstRealDocumentLoad())
2077             m_isVisuallyNonEmpty = true;
2078
2079         // If the layout was done with pending sheets, we are not in fact visually non-empty yet.
2080         if (m_isVisuallyNonEmpty && !m_frame->document()->didLayoutWithPendingStylesheets() && m_firstVisuallyNonEmptyLayoutCallbackPending) {
2081             m_firstVisuallyNonEmptyLayoutCallbackPending = false;
2082             // FIXME: This callback is probably not needed, but is currently used
2083             // by android for setting the background color.
2084             m_frame->loader().client()->dispatchDidFirstVisuallyNonEmptyLayout();
2085         }
2086     }
2087
2088     FontFaceSet::didLayout(*m_frame->document());
2089
2090     updateWidgetPositions();
2091
2092     // Plugins could have torn down the page inside updateWidgetPositions().
2093     if (!renderView())
2094         return;
2095
2096     scheduleUpdateWidgetsIfNecessary();
2097
2098     if (Page* page = m_frame->page()) {
2099         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
2100             scrollingCoordinator->notifyLayoutUpdated();
2101     }
2102
2103     scrollToAnchor();
2104
2105     sendResizeEventIfNeeded();
2106 }
2107
2108 void FrameView::sendResizeEventIfNeeded()
2109 {
2110     ASSERT(m_frame);
2111
2112     RenderView* renderView = this->renderView();
2113     if (!renderView || renderView->document().printing())
2114         return;
2115
2116     IntSize currentSize = layoutSize(IncludeScrollbars);
2117     float currentZoomFactor = renderView->style()->zoom();
2118
2119     bool shouldSendResizeEvent = currentSize != m_lastViewportSize || currentZoomFactor != m_lastZoomFactor;
2120
2121     m_lastViewportSize = currentSize;
2122     m_lastZoomFactor = currentZoomFactor;
2123
2124     if (!shouldSendResizeEvent)
2125         return;
2126
2127     m_frame->document()->enqueueResizeEvent();
2128
2129     if (isMainFrame())
2130         InspectorInstrumentation::didResizeMainFrame(m_frame->page());
2131 }
2132
2133 void FrameView::postLayoutTimerFired(Timer<FrameView>*)
2134 {
2135     performPostLayoutTasks();
2136 }
2137
2138 void FrameView::updateCounters()
2139 {
2140     RenderView* view = renderView();
2141     if (!view->hasRenderCounters())
2142         return;
2143
2144     for (RenderObject* renderer = view; renderer; renderer = renderer->nextInPreOrder()) {
2145         if (!renderer->isCounter())
2146             continue;
2147
2148         toRenderCounter(renderer)->updateCounter();
2149     }
2150 }
2151
2152 void FrameView::autoSizeIfEnabled()
2153 {
2154     if (!m_shouldAutoSize)
2155         return;
2156
2157     if (m_inAutoSize)
2158         return;
2159
2160     TemporaryChange<bool> changeInAutoSize(m_inAutoSize, true);
2161
2162     Document* document = frame().document();
2163     if (!document || !document->isActive())
2164         return;
2165
2166     Element* documentElement = document->documentElement();
2167     if (!documentElement)
2168         return;
2169
2170     // If this is the first time we run autosize, start from small height and
2171     // allow it to grow.
2172     if (!m_didRunAutosize)
2173         resize(frameRect().width(), m_minAutoSize.height());
2174
2175     IntSize size = frameRect().size();
2176
2177     // Do the resizing twice. The first time is basically a rough calculation using the preferred width
2178     // which may result in a height change during the second iteration.
2179     for (int i = 0; i < 2; i++) {
2180         // Update various sizes including contentsSize, scrollHeight, etc.
2181         document->updateLayoutIgnorePendingStylesheets();
2182
2183         RenderView* renderView = document->renderView();
2184         if (!renderView)
2185             return;
2186
2187         int width = renderView->minPreferredLogicalWidth();
2188
2189         RenderBox* documentRenderBox = documentElement->renderBox();
2190         if (!documentRenderBox)
2191             return;
2192
2193         int height = documentRenderBox->scrollHeight();
2194         IntSize newSize(width, height);
2195
2196         // Check to see if a scrollbar is needed for a given dimension and
2197         // if so, increase the other dimension to account for the scrollbar.
2198         // Since the dimensions are only for the view rectangle, once a
2199         // dimension exceeds the maximum, there is no need to increase it further.
2200         if (newSize.width() > m_maxAutoSize.width()) {
2201             RefPtr<Scrollbar> localHorizontalScrollbar = horizontalScrollbar();
2202             if (!localHorizontalScrollbar)
2203                 localHorizontalScrollbar = createScrollbar(HorizontalScrollbar);
2204             if (!localHorizontalScrollbar->isOverlayScrollbar())
2205                 newSize.setHeight(newSize.height() + localHorizontalScrollbar->height());
2206
2207             // Don't bother checking for a vertical scrollbar because the width is at
2208             // already greater the maximum.
2209         } else if (newSize.height() > m_maxAutoSize.height()) {
2210             RefPtr<Scrollbar> localVerticalScrollbar = verticalScrollbar();
2211             if (!localVerticalScrollbar)
2212                 localVerticalScrollbar = createScrollbar(VerticalScrollbar);
2213             if (!localVerticalScrollbar->isOverlayScrollbar())
2214                 newSize.setWidth(newSize.width() + localVerticalScrollbar->width());
2215
2216             // Don't bother checking for a horizontal scrollbar because the height is
2217             // already greater the maximum.
2218         }
2219
2220         // Ensure the size is at least the min bounds.
2221         newSize = newSize.expandedTo(m_minAutoSize);
2222
2223         // Bound the dimensions by the max bounds and determine what scrollbars to show.
2224         ScrollbarMode horizonalScrollbarMode = ScrollbarAlwaysOff;
2225         if (newSize.width() > m_maxAutoSize.width()) {
2226             newSize.setWidth(m_maxAutoSize.width());
2227             horizonalScrollbarMode = ScrollbarAlwaysOn;
2228         }
2229         ScrollbarMode verticalScrollbarMode = ScrollbarAlwaysOff;
2230         if (newSize.height() > m_maxAutoSize.height()) {
2231             newSize.setHeight(m_maxAutoSize.height());
2232             verticalScrollbarMode = ScrollbarAlwaysOn;
2233         }
2234
2235         if (newSize == size)
2236             continue;
2237
2238         // While loading only allow the size to increase (to avoid twitching during intermediate smaller states)
2239         // unless autoresize has just been turned on or the maximum size is smaller than the current size.
2240         if (m_didRunAutosize && size.height() <= m_maxAutoSize.height() && size.width() <= m_maxAutoSize.width()
2241             && !m_frame->document()->loadEventFinished() && (newSize.height() < size.height() || newSize.width() < size.width()))
2242             break;
2243
2244         resize(newSize.width(), newSize.height());
2245         // Force the scrollbar state to avoid the scrollbar code adding them and causing them to be needed. For example,
2246         // a vertical scrollbar may cause text to wrap and thus increase the height (which is the only reason the scollbar is needed).
2247         setVerticalScrollbarLock(false);
2248         setHorizontalScrollbarLock(false);
2249         setScrollbarModes(horizonalScrollbarMode, verticalScrollbarMode, true, true);
2250     }
2251     m_didRunAutosize = true;
2252 }
2253
2254 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
2255 {
2256     if (!m_viewportRenderer)
2257         return;
2258
2259     if (m_overflowStatusDirty) {
2260         m_horizontalOverflow = horizontalOverflow;
2261         m_verticalOverflow = verticalOverflow;
2262         m_overflowStatusDirty = false;
2263         return;
2264     }
2265
2266     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
2267     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
2268
2269     if (horizontalOverflowChanged || verticalOverflowChanged) {
2270         m_horizontalOverflow = horizontalOverflow;
2271         m_verticalOverflow = verticalOverflow;
2272
2273         RefPtr<OverflowEvent> event = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow);
2274         event->setTarget(m_viewportRenderer->node());
2275         m_frame->document()->enqueueAnimationFrameEvent(event.release());
2276     }
2277
2278 }
2279
2280 IntRect FrameView::windowClipRect(IncludeScrollbarsInRect scrollbarInclusion) const
2281 {
2282     ASSERT(m_frame->view() == this);
2283
2284     if (paintsEntireContents())
2285         return IntRect(IntPoint(), contentsSize());
2286
2287     // Set our clip rect to be our contents.
2288     IntRect clipRect = contentsToWindow(visibleContentRect(scrollbarInclusion));
2289     if (!m_frame->ownerElement())
2290         return clipRect;
2291
2292     // Take our owner element and get its clip rect.
2293     HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement();
2294     FrameView* parentView = ownerElement->document().view();
2295     if (parentView)
2296         clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement));
2297     return clipRect;
2298 }
2299
2300 IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement) const
2301 {
2302     // The renderer can sometimes be null when style="display:none" interacts
2303     // with external content and plugins.
2304     if (!ownerElement->renderer())
2305         return windowClipRect();
2306
2307     // If we have no layer, just return our window clip rect.
2308     const RenderLayer* enclosingLayer = ownerElement->renderer()->enclosingLayer();
2309     if (!enclosingLayer)
2310         return windowClipRect();
2311
2312     // FIXME: childrenClipRect relies on compositingState, which is not necessarily up to date.
2313     // https://code.google.com/p/chromium/issues/detail?id=343769
2314     DisableCompositingQueryAsserts disabler;
2315
2316     // Apply the clip from the layer.
2317     IntRect clipRect = contentsToWindow(pixelSnappedIntRect(enclosingLayer->clipper().childrenClipRect()));
2318     return intersection(clipRect, windowClipRect());
2319 }
2320
2321 bool FrameView::isActive() const
2322 {
2323     Page* page = frame().page();
2324     return page && page->focusController().isActive();
2325 }
2326
2327 void FrameView::scrollTo(const IntSize& newOffset)
2328 {
2329     LayoutSize offset = scrollOffset();
2330     ScrollView::scrollTo(newOffset);
2331     if (offset != scrollOffset()) {
2332         updateLayersAndCompositingAfterScrollIfNeeded();
2333         scrollPositionChanged();
2334     }
2335     frame().loader().client()->didChangeScrollOffset();
2336 }
2337
2338 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
2339 {
2340     // Add in our offset within the FrameView.
2341     IntRect dirtyRect = rect;
2342     dirtyRect.moveBy(scrollbar->location());
2343
2344     if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && isInPerformLayout()) {
2345         if (scrollbar == verticalScrollbar()) {
2346             m_verticalBarDamage = dirtyRect;
2347             m_hasVerticalBarDamage = true;
2348         } else {
2349             m_horizontalBarDamage = dirtyRect;
2350             m_hasHorizontalBarDamage = true;
2351         }
2352     } else {
2353         invalidateRect(dirtyRect);
2354     }
2355 }
2356
2357 void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
2358 {
2359     if (!m_tickmarks.isEmpty())
2360         tickmarks = m_tickmarks;
2361     else
2362         tickmarks = frame().document()->markers().renderedRectsForMarkers(DocumentMarker::TextMatch);
2363 }
2364
2365 IntRect FrameView::windowResizerRect() const
2366 {
2367     Page* page = frame().page();
2368     if (!page)
2369         return IntRect();
2370     return page->chrome().windowResizerRect();
2371 }
2372
2373 void FrameView::setVisibleContentScaleFactor(float visibleContentScaleFactor)
2374 {
2375     if (m_visibleContentScaleFactor == visibleContentScaleFactor)
2376         return;
2377
2378     m_visibleContentScaleFactor = visibleContentScaleFactor;
2379     updateScrollbars(scrollOffset());
2380 }
2381
2382 void FrameView::setInputEventsTransformForEmulation(const IntSize& offset, float contentScaleFactor)
2383 {
2384     m_inputEventsOffsetForEmulation = offset;
2385     m_inputEventsScaleFactorForEmulation = contentScaleFactor;
2386 }
2387
2388 IntSize FrameView::inputEventsOffsetForEmulation() const
2389 {
2390     return m_inputEventsOffsetForEmulation;
2391 }
2392
2393 float FrameView::inputEventsScaleFactor() const
2394 {
2395     return visibleContentScaleFactor() * m_inputEventsScaleFactorForEmulation;
2396 }
2397
2398 bool FrameView::scrollbarsCanBeActive() const
2399 {
2400     if (m_frame->view() != this)
2401         return false;
2402
2403     return !!m_frame->document();
2404 }
2405
2406 IntRect FrameView::scrollableAreaBoundingBox() const
2407 {
2408     RenderPart* ownerRenderer = frame().ownerRenderer();
2409     if (!ownerRenderer)
2410         return frameRect();
2411
2412     return ownerRenderer->absoluteContentQuad().enclosingBoundingBox();
2413 }
2414
2415 bool FrameView::isScrollable()
2416 {
2417     // Check for:
2418     // 1) If there an actual overflow.
2419     // 2) display:none or visibility:hidden set to self or inherited.
2420     // 3) overflow{-x,-y}: hidden;
2421     // 4) scrolling: no;
2422
2423     // Covers #1
2424     IntSize contentsSize = this->contentsSize();
2425     IntSize visibleContentSize = visibleContentRect().size();
2426     if ((contentsSize.height() <= visibleContentSize.height() && contentsSize.width() <= visibleContentSize.width()))
2427         return false;
2428
2429     // Covers #2.
2430     HTMLFrameOwnerElement* owner = m_frame->ownerElement();
2431     if (owner && (!owner->renderer() || !owner->renderer()->visibleToHitTesting()))
2432         return false;
2433
2434     // Cover #3 and #4.
2435     ScrollbarMode horizontalMode;
2436     ScrollbarMode verticalMode;
2437     calculateScrollbarModesForLayoutAndSetViewportRenderer(horizontalMode, verticalMode, RulesFromWebContentOnly);
2438     if (horizontalMode == ScrollbarAlwaysOff && verticalMode == ScrollbarAlwaysOff)
2439         return false;
2440
2441     return true;
2442 }
2443
2444 void FrameView::updateScrollableAreaSet()
2445 {
2446     // That ensures that only inner frames are cached.
2447     FrameView* parentFrameView = this->parentFrameView();
2448     if (!parentFrameView)
2449         return;
2450
2451     if (!isScrollable()) {
2452         parentFrameView->removeScrollableArea(this);
2453         return;
2454     }
2455
2456     parentFrameView->addScrollableArea(this);
2457 }
2458
2459 bool FrameView::shouldSuspendScrollAnimations() const
2460 {
2461     return m_frame->loader().state() != FrameStateComplete;
2462 }
2463
2464 void FrameView::scrollbarStyleChanged(int newStyle, bool forceUpdate)
2465 {
2466     if (!isMainFrame())
2467         return;
2468
2469     if (forceUpdate)
2470         ScrollView::scrollbarStyleChanged(newStyle, forceUpdate);
2471 }
2472
2473 void FrameView::notifyPageThatContentAreaWillPaint() const
2474 {
2475     Page* page = m_frame->page();
2476     if (!page)
2477         return;
2478
2479     contentAreaWillPaint();
2480
2481     if (!m_scrollableAreas)
2482         return;
2483
2484     for (HashSet<ScrollableArea*>::const_iterator it = m_scrollableAreas->begin(), end = m_scrollableAreas->end(); it != end; ++it) {
2485         ScrollableArea* scrollableArea = *it;
2486
2487         if (!scrollableArea->scrollbarsCanBeActive())
2488             continue;
2489
2490         scrollableArea->contentAreaWillPaint();
2491     }
2492 }
2493
2494 bool FrameView::scrollAnimatorEnabled() const
2495 {
2496     return m_frame->settings() && m_frame->settings()->scrollAnimatorEnabled();
2497 }
2498
2499 void FrameView::updateAnnotatedRegions()
2500 {
2501     Document* document = m_frame->document();
2502     if (!document->hasAnnotatedRegions())
2503         return;
2504     Vector<AnnotatedRegionValue> newRegions;
2505     document->renderBox()->collectAnnotatedRegions(newRegions);
2506     if (newRegions == document->annotatedRegions())
2507         return;
2508     document->setAnnotatedRegions(newRegions);
2509     if (Page* page = m_frame->page())
2510         page->chrome().client().annotatedRegionsChanged();
2511 }
2512
2513 void FrameView::updateScrollCorner()
2514 {
2515     RefPtr<RenderStyle> cornerStyle;
2516     IntRect cornerRect = scrollCornerRect();
2517     Document* doc = m_frame->document();
2518
2519     if (doc && !cornerRect.isEmpty()) {
2520         // Try the <body> element first as a scroll corner source.
2521         if (Element* body = doc->body()) {
2522             if (RenderObject* renderer = body->renderer())
2523                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
2524         }
2525
2526         if (!cornerStyle) {
2527             // If the <body> didn't have a custom style, then the root element might.
2528             if (Element* docElement = doc->documentElement()) {
2529                 if (RenderObject* renderer = docElement->renderer())
2530                     cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
2531             }
2532         }
2533
2534         if (!cornerStyle) {
2535             // If we have an owning ipage/LocalFrame element, then it can set the custom scrollbar also.
2536             if (RenderPart* renderer = m_frame->ownerRenderer())
2537                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
2538         }
2539     }
2540
2541     if (cornerStyle) {
2542         if (!m_scrollCorner)
2543             m_scrollCorner = RenderScrollbarPart::createAnonymous(doc);
2544         m_scrollCorner->setStyle(cornerStyle.release());
2545         invalidateScrollCorner(cornerRect);
2546     } else if (m_scrollCorner) {
2547         m_scrollCorner->destroy();
2548         m_scrollCorner = 0;
2549     }
2550
2551     ScrollView::updateScrollCorner();
2552 }
2553
2554 void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
2555 {
2556     if (context->updatingControlTints()) {
2557         updateScrollCorner();
2558         return;
2559     }
2560
2561     if (m_scrollCorner) {
2562         bool needsBackgorund = isMainFrame();
2563         if (needsBackgorund)
2564             context->fillRect(cornerRect, baseBackgroundColor());
2565         m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect);
2566         return;
2567     }
2568
2569     ScrollView::paintScrollCorner(context, cornerRect);
2570 }
2571
2572 void FrameView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
2573 {
2574     bool needsBackgorund = bar->isCustomScrollbar() && isMainFrame();
2575     if (needsBackgorund) {
2576         IntRect toFill = bar->frameRect();
2577         toFill.intersect(rect);
2578         context->fillRect(toFill, baseBackgroundColor());
2579     }
2580
2581     ScrollView::paintScrollbar(context, bar, rect);
2582 }
2583
2584 Color FrameView::documentBackgroundColor() const
2585 {
2586     // <https://bugs.webkit.org/show_bug.cgi?id=59540> We blend the background color of
2587     // the document and the body against the base background color of the frame view.
2588     // Background images are unfortunately impractical to include.
2589
2590     Color result = baseBackgroundColor();
2591     if (!frame().document())
2592         return result;
2593
2594     Element* htmlElement = frame().document()->documentElement();
2595     Element* bodyElement = frame().document()->body();
2596
2597     // We take the aggregate of the base background color
2598     // the <html> background color, and the <body>
2599     // background color to find the document color. The
2600     // addition of the base background color is not
2601     // technically part of the document background, but it
2602     // otherwise poses problems when the aggregate is not
2603     // fully opaque.
2604     if (htmlElement && htmlElement->renderer())
2605         result = result.blend(htmlElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor));
2606     if (bodyElement && bodyElement->renderer())
2607         result = result.blend(bodyElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor));
2608
2609     return result;
2610 }
2611
2612 bool FrameView::hasCustomScrollbars() const
2613 {
2614     const HashSet<RefPtr<Widget> >* viewChildren = children();
2615     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
2616     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
2617         Widget* widget = current->get();
2618         if (widget->isFrameView()) {
2619             if (toFrameView(widget)->hasCustomScrollbars())
2620                 return true;
2621         } else if (widget->isScrollbar()) {
2622             Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
2623             if (scrollbar->isCustomScrollbar())
2624                 return true;
2625         }
2626     }
2627
2628     return false;
2629 }
2630
2631 FrameView* FrameView::parentFrameView() const
2632 {
2633     if (!parent())
2634         return 0;
2635
2636     if (LocalFrame* parentFrame = m_frame->tree().parent())
2637         return parentFrame->view();
2638
2639     return 0;
2640 }
2641
2642 void FrameView::updateControlTints()
2643 {
2644     // This is called when control tints are changed from aqua/graphite to clear and vice versa.
2645     // We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
2646     // This is only done if the theme supports control tinting. It's up to the theme and platform
2647     // to define when controls get the tint and to call this function when that changes.
2648
2649     // Optimize the common case where we bring a window to the front while it's still empty.
2650     if (m_frame->document()->url().isEmpty())
2651         return;
2652
2653     // FIXME: We shouldn't rely on the paint code to implement :window-inactive on custom scrollbars.
2654     if (!RenderTheme::theme().supportsControlTints() && !hasCustomScrollbars())
2655         return;
2656
2657     // Updating layout can run script, which can tear down the FrameView.
2658     RefPtr<FrameView> protector(this);
2659     updateLayoutAndStyleForPainting();
2660
2661     // FIXME: The use of paint seems like overkill: crbug.com/236892
2662     GraphicsContext context(0); // NULL canvas to get a non-painting context.
2663     context.setUpdatingControlTints(true);
2664     paint(&context, frameRect());
2665 }
2666
2667 bool FrameView::wasScrolledByUser() const
2668 {
2669     return m_wasScrolledByUser;
2670 }
2671
2672 void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
2673 {
2674     if (m_inProgrammaticScroll)
2675         return;
2676     m_maintainScrollPositionAnchor = nullptr;
2677     m_wasScrolledByUser = wasScrolledByUser;
2678 }
2679
2680 void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
2681 {
2682     Document* document = m_frame->document();
2683
2684 #ifndef NDEBUG
2685     bool fillWithRed;
2686     if (document->printing())
2687         fillWithRed = false; // Printing, don't fill with red (can't remember why).
2688     else if (m_frame->ownerElement())
2689         fillWithRed = false; // Subframe, don't fill with red.
2690     else if (isTransparent())
2691         fillWithRed = false; // Transparent, don't fill with red.
2692     else if (m_paintBehavior & PaintBehaviorSelectionOnly)
2693         fillWithRed = false; // Selections are transparent, don't fill with red.
2694     else if (m_nodeToDraw)
2695         fillWithRed = false; // Element images are transparent, don't fill with red.
2696     else
2697         fillWithRed = true;
2698
2699     if (fillWithRed)
2700         p->fillRect(rect, Color(0xFF, 0, 0));
2701 #endif
2702
2703     RenderView* renderView = this->renderView();
2704     if (!renderView) {
2705         WTF_LOG_ERROR("called FrameView::paint with nil renderer");
2706         return;
2707     }
2708
2709     ASSERT(!needsLayout());
2710     if (needsLayout())
2711         return;
2712
2713     InspectorInstrumentation::willPaint(renderView, 0);
2714
2715     bool isTopLevelPainter = !s_inPaintContents;
2716     s_inPaintContents = true;
2717
2718     FontCachePurgePreventer fontCachePurgePreventer;
2719
2720     PaintBehavior oldPaintBehavior = m_paintBehavior;
2721
2722     if (FrameView* parentView = parentFrameView()) {
2723         if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers)
2724             m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
2725     }
2726
2727     if (m_paintBehavior == PaintBehaviorNormal)
2728         document->markers().invalidateRenderedRectsForMarkersInRect(rect);
2729
2730     if (document->printing())
2731         m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
2732
2733     ASSERT(!m_isPainting);
2734     m_isPainting = true;
2735
2736     // m_nodeToDraw is used to draw only one element (and its descendants)
2737     RenderObject* renderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
2738     RenderLayer* rootLayer = renderView->layer();
2739
2740 #ifndef NDEBUG
2741     renderView->assertSubtreeIsLaidOut();
2742     RenderObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(rootLayer->renderer());
2743 #endif
2744
2745     RenderObject* enclosingLayerRenderer = renderer ? renderer->enclosingLayer()->renderer() : 0;
2746     rootLayer->paint(p, rect, m_paintBehavior, enclosingLayerRenderer);
2747
2748     if (rootLayer->containsDirtyOverlayScrollbars())
2749         rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, renderer);
2750
2751     m_isPainting = false;
2752
2753     m_paintBehavior = oldPaintBehavior;
2754     m_lastPaintTime = currentTime();
2755
2756     // Regions may have changed as a result of the visibility/z-index of element changing.
2757     if (document->annotatedRegionsDirty())
2758         updateAnnotatedRegions();
2759
2760     if (isTopLevelPainter) {
2761         // Everythin that happens after paintContents completions is considered
2762         // to be part of the next frame.
2763         s_currentFrameTimeStamp = currentTime();
2764         s_inPaintContents = false;
2765     }
2766
2767     InspectorInstrumentation::didPaint(renderView, 0, p, rect);
2768 }
2769
2770 void FrameView::setPaintBehavior(PaintBehavior behavior)
2771 {
2772     m_paintBehavior = behavior;
2773 }
2774
2775 PaintBehavior FrameView::paintBehavior() const
2776 {
2777     return m_paintBehavior;
2778 }
2779
2780 bool FrameView::isPainting() const
2781 {
2782     return m_isPainting;
2783 }
2784
2785 void FrameView::setNodeToDraw(Node* node)
2786 {
2787     m_nodeToDraw = node;
2788 }
2789
2790 void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
2791 {
2792     if (context->paintingDisabled())
2793         return;
2794
2795     if (m_frame->document()->printing())
2796         return;
2797
2798     if (isMainFrame()) {
2799         if (m_frame->page()->chrome().client().paintCustomOverhangArea(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect))
2800             return;
2801     }
2802
2803     ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
2804 }
2805
2806 void FrameView::updateLayoutAndStyleForPainting()
2807 {
2808     // Updating layout can run script, which can tear down the FrameView.
2809     RefPtr<FrameView> protector(this);
2810
2811     updateLayoutAndStyleIfNeededRecursive();
2812     if (RenderView* view = renderView()) {
2813         ASSERT(!view->needsLayout());
2814         view->compositor()->updateCompositingLayers();
2815
2816         // FIXME: we should not have any dirty bits left at this point. Unfortunately, this is not yet the case because
2817         // the code in updateCompositingLayers sometimes creates new dirty bits when updating direct compositing reasons.
2818         // See crbug.com/354100.
2819         view->compositor()->scheduleAnimationIfNeeded();
2820     }
2821
2822     scrollContentsIfNeededRecursive();
2823 }
2824
2825 void FrameView::updateLayoutAndStyleIfNeededRecursive()
2826 {
2827     // We have to crawl our entire tree looking for any FrameViews that need
2828     // layout and make sure they are up to date.
2829     // Mac actually tests for intersection with the dirty region and tries not to
2830     // update layout for frames that are outside the dirty region.  Not only does this seem
2831     // pointless (since those frames will have set a zero timer to layout anyway), but
2832     // it is also incorrect, since if two frames overlap, the first could be excluded from the dirty
2833     // region but then become included later by the second frame adding rects to the dirty region
2834     // when it lays out.
2835
2836     m_frame->document()->updateRenderTreeIfNeeded();
2837
2838     if (needsLayout())
2839         layout();
2840
2841     // FIXME: Calling layout() shouldn't trigger scripe execution or have any
2842     // observable effects on the frame tree but we're not quite there yet.
2843     Vector<RefPtr<FrameView> > frameViews;
2844     for (LocalFrame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
2845         if (FrameView* view = child->view())
2846             frameViews.append(view);
2847     }
2848
2849     const Vector<RefPtr<FrameView> >::iterator end = frameViews.end();
2850     for (Vector<RefPtr<FrameView> >::iterator it = frameViews.begin(); it != end; ++it)
2851         (*it)->updateLayoutAndStyleIfNeededRecursive();
2852
2853     // This assert ensures that parent frames are clean, when child frames finished updating layout and style.
2854     ASSERT(!needsLayout());
2855 }
2856
2857 void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize)
2858 {
2859     ASSERT(!enable || !minSize.isEmpty());
2860     ASSERT(minSize.width() <= maxSize.width());
2861     ASSERT(minSize.height() <= maxSize.height());
2862
2863     if (m_shouldAutoSize == enable && m_minAutoSize == minSize && m_maxAutoSize == maxSize)
2864         return;
2865
2866
2867     m_shouldAutoSize = enable;
2868     m_minAutoSize = minSize;
2869     m_maxAutoSize = maxSize;
2870     m_didRunAutosize = false;
2871
2872     setLayoutSizeFixedToFrameSize(enable);
2873     setNeedsLayout();
2874     scheduleRelayout();
2875     if (m_shouldAutoSize)
2876         return;
2877
2878     // Since autosize mode forces the scrollbar mode, change them to being auto.
2879     setVerticalScrollbarLock(false);
2880     setHorizontalScrollbarLock(false);
2881     setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
2882 }
2883
2884 void FrameView::forceLayout(bool allowSubtree)
2885 {
2886     layout(allowSubtree);
2887 }
2888
2889 void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor)
2890 {
2891     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
2892     // the state of things before and after the layout
2893     if (RenderView* renderView = this->renderView()) {
2894         float pageLogicalWidth = renderView->style()->isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
2895         float pageLogicalHeight = renderView->style()->isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
2896
2897         LayoutUnit flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
2898         LayoutUnit flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
2899         renderView->setLogicalWidth(flooredPageLogicalWidth);
2900         renderView->setPageLogicalHeight(flooredPageLogicalHeight);
2901         renderView->setNeedsLayoutAndPrefWidthsRecalc();
2902         forceLayout();
2903
2904         // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
2905         // page width when shrunk, we will lay out at maximum shrink and clip extra content.
2906         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
2907         // implementation should not do this!
2908         bool horizontalWritingMode = renderView->style()->isHorizontalWritingMode();
2909         const LayoutRect& documentRect = renderView->documentRect();
2910         LayoutUnit docLogicalWidth = horizontalWritingMode ? documentRect.width() : documentRect.height();
2911         if (docLogicalWidth > pageLogicalWidth) {
2912             FloatSize expectedPageSize(std::min<float>(documentRect.width().toFloat(), pageSize.width() * maximumShrinkFactor), std::min<float>(documentRect.height().toFloat(), pageSize.height() * maximumShrinkFactor));
2913             FloatSize maxPageSize = m_frame->resizePageRectsKeepingRatio(FloatSize(originalPageSize.width(), originalPageSize.height()), expectedPageSize);
2914             pageLogicalWidth = horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
2915             pageLogicalHeight = horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();
2916
2917             flooredPageLogicalWidth = static_cast<LayoutUnit>(pageLogicalWidth);
2918             flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
2919             renderView->setLogicalWidth(flooredPageLogicalWidth);
2920             renderView->setPageLogicalHeight(flooredPageLogicalHeight);
2921             renderView->setNeedsLayoutAndPrefWidthsRecalc();
2922             forceLayout();
2923
2924             const LayoutRect& updatedDocumentRect = renderView->documentRect();
2925             LayoutUnit docLogicalHeight = horizontalWritingMode ? updatedDocumentRect.height() : updatedDocumentRect.width();
2926             LayoutUnit docLogicalTop = horizontalWritingMode ? updatedDocumentRect.y() : updatedDocumentRect.x();
2927             LayoutUnit docLogicalRight = horizontalWritingMode ? updatedDocumentRect.maxX() : updatedDocumentRect.maxY();
2928             LayoutUnit clippedLogicalLeft = 0;
2929             if (!renderView->style()->isLeftToRightDirection())
2930                 clippedLogicalLeft = docLogicalRight - pageLogicalWidth;
2931             LayoutRect overflow(clippedLogicalLeft, docLogicalTop, pageLogicalWidth, docLogicalHeight);
2932
2933             if (!horizontalWritingMode)
2934                 overflow = overflow.transposedRect();
2935             renderView->clearLayoutOverflow();
2936             renderView->addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
2937         }
2938     }
2939
2940     adjustViewSize();
2941 }
2942
2943 IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
2944 {
2945     IntRect rect = pixelSnappedIntRect(enclosingLayoutRect(renderer->localToAbsoluteQuad(FloatRect(rendererRect)).boundingBox()));
2946
2947     // Convert from page ("absolute") to FrameView coordinates.
2948     rect.moveBy(-scrollPosition());
2949
2950     return rect;
2951 }
2952
2953 IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect& viewRect) const
2954 {
2955     IntRect rect = viewRect;
2956
2957     // Convert from FrameView coords into page ("absolute") coordinates.
2958     rect.moveBy(scrollPosition());
2959
2960     // FIXME: we don't have a way to map an absolute rect down to a local quad, so just
2961     // move the rect for now.
2962     rect.setLocation(roundedIntPoint(renderer->absoluteToLocal(rect.location(), UseTransforms)));
2963     return rect;
2964 }
2965
2966 IntPoint FrameView::convertFromRenderer(const RenderObject* renderer, const IntPoint& rendererPoint) const
2967 {
2968     IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, UseTransforms));
2969
2970     // Convert from page ("absolute") to FrameView coordinates.
2971     point.moveBy(-scrollPosition());
2972     return point;
2973 }
2974
2975 IntPoint FrameView::convertToRenderer(const RenderObject* renderer, const IntPoint& viewPoint) const
2976 {
2977     IntPoint point = viewPoint;
2978
2979     // Convert from FrameView coords into page ("absolute") coordinates.
2980     point += IntSize(scrollX(), scrollY());
2981
2982     return roundedIntPoint(renderer->absoluteToLocal(point, UseTransforms));
2983 }
2984
2985 IntRect FrameView::convertToContainingView(const IntRect& localRect) const
2986 {
2987     if (const ScrollView* parentScrollView = toScrollView(parent())) {
2988         if (parentScrollView->isFrameView()) {
2989             const FrameView* parentView = toFrameView(parentScrollView);
2990             // Get our renderer in the parent view
2991             RenderPart* renderer = m_frame->ownerRenderer();
2992             if (!renderer)
2993                 return localRect;
2994
2995             IntRect rect(localRect);
2996             // Add borders and padding??
2997             rect.move(renderer->borderLeft() + renderer->paddingLeft(),
2998                 renderer->borderTop() + renderer->paddingTop());
2999             return parentView->convertFromRenderer(renderer, rect);
3000         }
3001
3002         return Widget::convertToContainingView(localRect);
3003     }
3004
3005     return localRect;
3006 }
3007
3008 IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
3009 {
3010     if (const ScrollView* parentScrollView = toScrollView(parent())) {
3011         if (parentScrollView->isFrameView()) {
3012             const FrameView* parentView = toFrameView(parentScrollView);
3013
3014             // Get our renderer in the parent view
3015             RenderPart* renderer = m_frame->ownerRenderer();
3016             if (!renderer)
3017                 return parentRect;
3018
3019             IntRect rect = parentView->convertToRenderer(renderer, parentRect);
3020             // Subtract borders and padding
3021             rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
3022                       -renderer->borderTop() - renderer->paddingTop());
3023             return rect;
3024         }
3025
3026         return Widget::convertFromContainingView(parentRect);
3027     }
3028
3029     return parentRect;
3030 }
3031
3032 IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
3033 {
3034     if (const ScrollView* parentScrollView = toScrollView(parent())) {
3035         if (parentScrollView->isFrameView()) {
3036             const FrameView* parentView = toFrameView(parentScrollView);
3037
3038             // Get our renderer in the parent view
3039             RenderPart* renderer = m_frame->ownerRenderer();
3040             if (!renderer)
3041                 return localPoint;
3042
3043             IntPoint point(localPoint);
3044
3045             // Add borders and padding
3046             point.move(renderer->borderLeft() + renderer->paddingLeft(),
3047                        renderer->borderTop() + renderer->paddingTop());
3048             return parentView->convertFromRenderer(renderer, point);
3049         }
3050
3051         return Widget::convertToContainingView(localPoint);
3052     }
3053
3054     return localPoint;
3055 }
3056
3057 IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
3058 {
3059     if (const ScrollView* parentScrollView = toScrollView(parent())) {
3060         if (parentScrollView->isFrameView()) {
3061             const FrameView* parentView = toFrameView(parentScrollView);
3062
3063             // Get our renderer in the parent view
3064             RenderPart* renderer = m_frame->ownerRenderer();
3065             if (!renderer)
3066                 return parentPoint;
3067
3068             IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
3069             // Subtract borders and padding
3070             point.move(-renderer->borderLeft() - renderer->paddingLeft(),
3071                        -renderer->borderTop() - renderer->paddingTop());
3072             return point;
3073         }
3074
3075         return Widget::convertFromContainingView(parentPoint);
3076     }
3077
3078     return parentPoint;
3079 }
3080
3081 void FrameView::setTracksRepaints(bool trackRepaints)
3082 {
3083     if (trackRepaints == m_isTrackingRepaints)
3084         return;
3085
3086     for (LocalFrame* frame = m_frame->tree().top(); frame; frame = frame->tree().traverseNext()) {
3087         if (RenderView* renderView = frame->contentRenderer())
3088             renderView->compositor()->setTracksRepaints(trackRepaints);
3089     }
3090
3091     resetTrackedRepaints();
3092     m_isTrackingRepaints = trackRepaints;
3093 }
3094
3095 void FrameView::resetTrackedRepaints()
3096 {
3097     m_trackedRepaintRects.clear();
3098     if (RenderView* renderView = this->renderView())
3099         renderView->compositor()->resetTrackedRepaintRects();
3100 }
3101
3102 String FrameView::trackedRepaintRectsAsText() const
3103 {
3104     TextStream ts;
3105     if (!m_trackedRepaintRects.isEmpty()) {
3106         ts << "(repaint rects\n";
3107         for (size_t i = 0; i < m_trackedRepaintRects.size(); ++i)
3108             ts << "  (rect " << m_trackedRepaintRects[i].x() << " " << m_trackedRepaintRects[i].y() << " " << m_trackedRepaintRects[i].width() << " " << m_trackedRepaintRects[i].height() << ")\n";
3109         ts << ")\n";
3110     }
3111     return ts.release();
3112 }
3113
3114 void FrameView::addResizerArea(RenderBox* resizerBox)
3115 {
3116     if (!m_resizerAreas)
3117         m_resizerAreas = adoptPtr(new ResizerAreaSet);
3118     m_resizerAreas->add(resizerBox);
3119 }
3120
3121 void FrameView::removeResizerArea(RenderBox* resizerBox)
3122 {
3123     if (!m_resizerAreas)
3124         return;
3125
3126     ResizerAreaSet::iterator it = m_resizerAreas->find(resizerBox);
3127     if (it != m_resizerAreas->end())
3128         m_resizerAreas->remove(it);
3129 }
3130
3131 bool FrameView::addScrollableArea(ScrollableArea* scrollableArea)
3132 {
3133     ASSERT(scrollableArea);
3134     if (!m_scrollableAreas)
3135         m_scrollableAreas = adoptPtr(new ScrollableAreaSet);
3136     return m_scrollableAreas->add(scrollableArea).isNewEntry;
3137 }
3138
3139 bool FrameView::removeScrollableArea(ScrollableArea* scrollableArea)
3140 {
3141     if (!m_scrollableAreas)
3142         return false;
3143
3144     ScrollableAreaSet::iterator it = m_scrollableAreas->find(scrollableArea);
3145     if (it == m_scrollableAreas->end())
3146         return false;
3147
3148     m_scrollableAreas->remove(it);
3149     return true;
3150 }
3151
3152 bool FrameView::containsScrollableArea(const ScrollableArea* scrollableArea) const
3153 {
3154     ASSERT(scrollableArea);
3155     if (!m_scrollableAreas || !scrollableArea)
3156         return false;
3157     return m_scrollableAreas->contains(const_cast<ScrollableArea*>(scrollableArea));
3158 }
3159
3160 void FrameView::removeChild(Widget* widget)
3161 {
3162     if (widget->isFrameView())
3163         removeScrollableArea(toFrameView(widget));
3164
3165     ScrollView::removeChild(widget);
3166 }
3167
3168 bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent)
3169 {
3170     // Note that to allow for rubber-band over-scroll behavior, even non-scrollable views
3171     // should handle wheel events.
3172 #if !USE(RUBBER_BANDING)
3173     if (!isScrollable())
3174         return false;
3175 #endif
3176
3177     // We don't allow mouse wheeling to happen in a ScrollView that has had its scrollbars explicitly disabled.
3178     if (!canHaveScrollbars())
3179         return false;
3180
3181     return ScrollableArea::handleWheelEvent(wheelEvent);
3182 }
3183
3184 bool FrameView::isVerticalDocument() const
3185 {
3186     RenderView* renderView = this->renderView();
3187     if (!renderView)
3188         return true;
3189
3190     return renderView->style()->isHorizontalWritingMode();
3191 }
3192
3193 bool FrameView::isFlippedDocument() const
3194 {
3195     RenderView* renderView = this->renderView();
3196     if (!renderView)
3197         return false;
3198
3199     return renderView->style()->isFlippedBlocksWritingMode();
3200 }
3201
3202 AXObjectCache* FrameView::axObjectCache() const
3203 {
3204     if (frame().document())
3205         return frame().document()->existingAXObjectCache();
3206     return 0;
3207 }
3208
3209 void FrameView::setCursor(const Cursor& cursor)
3210 {
3211     Page* page = frame().page();
3212     if (!page)
3213         return;
3214     page->chrome().setCursor(cursor);
3215 }
3216
3217 bool FrameView::isMainFrame() const
3218 {
3219     return m_frame->isMainFrame();
3220 }
3221
3222 void FrameView::frameRectsChanged()
3223 {
3224     if (layoutSizeFixedToFrameSize())
3225         setLayoutSizeInternal(frameRect().size());
3226
3227     ScrollView::frameRectsChanged();
3228 }
3229
3230 void FrameView::setLayoutSizeInternal(const IntSize& size)
3231 {
3232     if (m_layoutSize == size)
3233         return;
3234
3235     m_layoutSize = size;
3236     contentsResized();
3237 }
3238
3239 void FrameView::didAddScrollbar(Scrollbar* scrollbar, ScrollbarOrientation orientation)
3240 {
3241     ScrollableArea::didAddScrollbar(scrollbar, orientation);
3242     if (AXObjectCache* cache = axObjectCache())
3243         cache->handleScrollbarUpdate(this);
3244 }
3245
3246 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation orientation)
3247 {
3248     ScrollableArea::willRemoveScrollbar(scrollbar, orientation);
3249     if (AXObjectCache* cache = axObjectCache()) {
3250         cache->remove(scrollbar);
3251         cache->handleScrollbarUpdate(this);
3252     }
3253 }
3254
3255 } // namespace WebCore