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