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 "FrameView.h"
29
30#include "AXObjectCache.h"
31#include "CSSStyleSelector.h"
32#include "CachedResourceLoader.h"
33#include "Chrome.h"
34#include "ChromeClient.h"
35#include "DocumentMarkerController.h"
36#include "EventHandler.h"
37#include "FloatRect.h"
38#include "FocusController.h"
39#include "Frame.h"
40#include "FrameActionScheduler.h"
41#include "FrameLoader.h"
42#include "FrameLoaderClient.h"
43#include "FrameTree.h"
44#include "GraphicsContext.h"
45#include "HTMLDocument.h"
46#include "HTMLFrameElement.h"
47#include "HTMLFrameSetElement.h"
48#include "HTMLNames.h"
49#include "HTMLPlugInImageElement.h"
50#include "InspectorInstrumentation.h"
51#include "OverflowEvent.h"
52#include "RenderEmbeddedObject.h"
53#include "RenderFullScreen.h"
54#include "RenderLayer.h"
55#include "RenderPart.h"
56#include "RenderScrollbar.h"
57#include "RenderScrollbarPart.h"
58#include "RenderTheme.h"
59#include "RenderView.h"
60#include "ScrollAnimator.h"
61#include "Settings.h"
62#include "TextResourceDecoder.h"
63#include <wtf/CurrentTime.h>
64
65#if USE(ACCELERATED_COMPOSITING)
66#include "RenderLayerCompositor.h"
67#endif
68
69#if ENABLE(SVG)
70#include "SVGDocument.h"
71#include "SVGLocatable.h"
72#include "SVGNames.h"
73#include "SVGPreserveAspectRatio.h"
74#include "SVGSVGElement.h"
75#include "SVGViewElement.h"
76#include "SVGViewSpec.h"
77#endif
78
79#if ENABLE(TILED_BACKING_STORE)
80#include "TiledBackingStore.h"
81#endif
82
83#if PLATFORM(ANDROID)
84#include "WebCoreFrameBridge.h"
85#endif
86
87namespace WebCore {
88
89using namespace HTMLNames;
90
91double FrameView::sCurrentPaintTimeStamp = 0.0;
92
93// REPAINT_THROTTLING now chooses default values for throttling parameters.
94// Should be removed when applications start using runtime configuration.
95#if ENABLE(REPAINT_THROTTLING)
96// Normal delay
97double FrameView::s_deferredRepaintDelay = 0.025;
98// Negative value would mean that first few repaints happen without a delay
99double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
100// The delay grows on each repaint to this maximum value
101double FrameView::s_maxDeferredRepaintDelayDuringLoading = 2.5;
102// On each repaint the delay increses by this amount
103double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5;
104#else
105// FIXME: Repaint throttling could be good to have on all platform.
106// The balance between CPU use and repaint frequency will need some tuning for desktop.
107// More hooks may be needed to reset the delay on things like GIF and CSS animations.
108double FrameView::s_deferredRepaintDelay = 0;
109double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
110double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0;
111double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0;
112#endif
113
114// The maximum number of updateWidgets iterations that should be done before returning.
115static const unsigned maxUpdateWidgetsIterations = 2;
116
117FrameView::FrameView(Frame* frame)
118    : m_frame(frame)
119    , m_canHaveScrollbars(true)
120    , m_slowRepaintObjectCount(0)
121    , m_fixedObjectCount(0)
122    , m_layoutTimer(this, &FrameView::layoutTimerFired)
123    , m_layoutRoot(0)
124    , m_hasPendingPostLayoutTasks(false)
125    , m_inSynchronousPostLayout(false)
126    , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
127    , m_isTransparent(false)
128    , m_baseBackgroundColor(Color::white)
129    , m_mediaType("screen")
130    , m_actionScheduler(new FrameActionScheduler())
131    , m_overflowStatusDirty(true)
132    , m_viewportRenderer(0)
133    , m_wasScrolledByUser(false)
134    , m_inProgrammaticScroll(false)
135    , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired)
136    , m_shouldUpdateWhileOffscreen(true)
137    , m_deferSetNeedsLayouts(0)
138    , m_setNeedsLayoutWasDeferred(false)
139    , m_scrollCorner(0)
140#if ENABLE(ANDROID_OVERFLOW_SCROLL)
141    , m_hasOverflowScroll(false)
142#endif
143{
144    init();
145
146    if (m_frame) {
147        if (Page* page = m_frame->page()) {
148            m_page = page;
149            m_page->addScrollableArea(this);
150
151            if (m_frame == m_page->mainFrame()) {
152                ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
153                ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
154            }
155        }
156    }
157}
158
159PassRefPtr<FrameView> FrameView::create(Frame* frame)
160{
161    RefPtr<FrameView> view = adoptRef(new FrameView(frame));
162    view->show();
163    return view.release();
164}
165
166PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize)
167{
168    RefPtr<FrameView> view = adoptRef(new FrameView(frame));
169    view->Widget::setFrameRect(IntRect(view->pos(), initialSize));
170    view->setInitialBoundsSize(initialSize);
171    view->show();
172    return view.release();
173}
174
175FrameView::~FrameView()
176{
177    if (m_hasPendingPostLayoutTasks) {
178        m_postLayoutTasksTimer.stop();
179        m_actionScheduler->clear();
180    }
181
182    if (AXObjectCache::accessibilityEnabled() && axObjectCache())
183        axObjectCache()->remove(this);
184
185    resetScrollbars();
186
187    // Custom scrollbars should already be destroyed at this point
188    ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
189    ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
190
191    setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
192    setHasVerticalScrollbar(false);
193
194    ASSERT(!m_scrollCorner);
195    ASSERT(m_actionScheduler->isEmpty());
196
197    if (m_page)
198        m_page->removeScrollableArea(this);
199
200    if (m_frame) {
201        ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
202        RenderPart* renderer = m_frame->ownerRenderer();
203        if (renderer && renderer->widget() == this)
204            renderer->setWidget(0);
205    }
206}
207
208void FrameView::reset()
209{
210    m_useSlowRepaints = false;
211    m_isOverlapped = false;
212    m_contentIsOpaque = false;
213    m_borderX = 30;
214    m_borderY = 30;
215    m_layoutTimer.stop();
216    m_layoutRoot = 0;
217    m_delayedLayout = false;
218    m_doFullRepaint = true;
219    m_layoutSchedulingEnabled = true;
220    m_inLayout = false;
221    m_inSynchronousPostLayout = false;
222    m_hasPendingPostLayoutTasks = false;
223    m_layoutCount = 0;
224    m_nestedLayoutCount = 0;
225    m_postLayoutTasksTimer.stop();
226    m_firstLayout = true;
227    m_firstLayoutCallbackPending = false;
228    m_wasScrolledByUser = false;
229    m_lastLayoutSize = IntSize();
230    m_lastZoomFactor = 1.0f;
231    m_deferringRepaints = 0;
232    m_repaintCount = 0;
233    m_repaintRects.clear();
234    m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading;
235    m_deferredRepaintTimer.stop();
236    m_lastPaintTime = 0;
237    m_paintBehavior = PaintBehaviorNormal;
238    m_isPainting = false;
239    m_isVisuallyNonEmpty = false;
240    m_firstVisuallyNonEmptyLayoutCallbackPending = true;
241    m_maintainScrollPositionAnchor = 0;
242}
243
244bool FrameView::isFrameView() const
245{
246    return true;
247}
248
249void FrameView::clearFrame()
250{
251    m_frame = 0;
252}
253
254void FrameView::resetScrollbars()
255{
256    // Reset the document's scrollbars back to our defaults before we yield the floor.
257    m_firstLayout = true;
258    setScrollbarsSuppressed(true);
259    if (m_canHaveScrollbars)
260        setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
261    else
262        setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
263    setScrollbarsSuppressed(false);
264}
265
266void FrameView::resetScrollbarsAndClearContentsSize()
267{
268    // Since the contents size is being cleared, the scroll position will lost as a consequence.
269    // Cache the scroll position so it can be restored by the page cache if necessary.
270    cacheCurrentScrollPosition();
271
272    resetScrollbars();
273
274    setScrollbarsSuppressed(true);
275    setContentsSize(IntSize());
276    setScrollbarsSuppressed(false);
277}
278
279void FrameView::init()
280{
281    reset();
282
283    m_margins = IntSize(-1, -1); // undefined
284    m_size = IntSize();
285
286    // Propagate the marginwidth/height and scrolling modes to the view.
287    Element* ownerElement = m_frame ? m_frame->ownerElement() : 0;
288    if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
289        HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
290        if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
291            setCanHaveScrollbars(false);
292        int marginWidth = frameElt->marginWidth();
293        int marginHeight = frameElt->marginHeight();
294        if (marginWidth != -1)
295            setMarginWidth(marginWidth);
296        if (marginHeight != -1)
297            setMarginHeight(marginHeight);
298    }
299}
300
301void FrameView::detachCustomScrollbars()
302{
303    if (!m_frame)
304        return;
305
306    Scrollbar* horizontalBar = horizontalScrollbar();
307    if (horizontalBar && horizontalBar->isCustomScrollbar())
308        setHasHorizontalScrollbar(false);
309
310    Scrollbar* verticalBar = verticalScrollbar();
311    if (verticalBar && verticalBar->isCustomScrollbar())
312        setHasVerticalScrollbar(false);
313
314    if (m_scrollCorner) {
315        m_scrollCorner->destroy();
316        m_scrollCorner = 0;
317    }
318}
319
320void FrameView::clear()
321{
322    setCanBlitOnScroll(true);
323
324    reset();
325
326    if (m_frame) {
327        if (RenderPart* renderer = m_frame->ownerRenderer())
328            renderer->viewCleared();
329    }
330
331    setScrollbarsSuppressed(true);
332}
333
334bool FrameView::didFirstLayout() const
335{
336    return !m_firstLayout;
337}
338
339void FrameView::invalidateRect(const IntRect& rect)
340{
341    if (!parent()) {
342        if (hostWindow())
343            hostWindow()->invalidateContentsAndWindow(rect, false /*immediate*/);
344        return;
345    }
346
347    if (!m_frame)
348        return;
349
350    RenderPart* renderer = m_frame->ownerRenderer();
351    if (!renderer)
352        return;
353
354    IntRect repaintRect = rect;
355    repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
356                     renderer->borderTop() + renderer->paddingTop());
357    renderer->repaintRectangle(repaintRect);
358}
359
360void FrameView::setFrameRect(const IntRect& newRect)
361{
362    IntRect oldRect = frameRect();
363    if (newRect == oldRect)
364        return;
365
366    ScrollView::setFrameRect(newRect);
367
368#if USE(ACCELERATED_COMPOSITING)
369    if (RenderView* root = m_frame->contentRenderer()) {
370        if (root->usesCompositing())
371            root->compositor()->frameViewDidChangeSize();
372    }
373#endif
374}
375
376#if ENABLE(REQUEST_ANIMATION_FRAME)
377void FrameView::scheduleAnimation()
378{
379    if (hostWindow())
380        hostWindow()->scheduleAnimation();
381}
382#endif
383
384void FrameView::setMarginWidth(int w)
385{
386    // make it update the rendering area when set
387    m_margins.setWidth(w);
388}
389
390void FrameView::setMarginHeight(int h)
391{
392    // make it update the rendering area when set
393    m_margins.setHeight(h);
394}
395
396bool FrameView::avoidScrollbarCreation() const
397{
398    ASSERT(m_frame);
399
400    // with frame flattening no subframe can have scrollbars
401    // but we also cannot turn scrollbars of as we determine
402    // our flattening policy using that.
403
404    if (!m_frame->ownerElement())
405        return false;
406
407    if (!m_frame->settings() || m_frame->settings()->frameFlatteningEnabled())
408        return true;
409
410    return false;
411}
412
413void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
414{
415    m_canHaveScrollbars = canHaveScrollbars;
416    ScrollView::setCanHaveScrollbars(canHaveScrollbars);
417}
418
419void FrameView::updateCanHaveScrollbars()
420{
421    ScrollbarMode hMode;
422    ScrollbarMode vMode;
423    scrollbarModes(hMode, vMode);
424    if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
425        setCanHaveScrollbars(false);
426    else
427        setCanHaveScrollbars(true);
428}
429
430PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
431{
432    // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
433    Document* doc = m_frame->document();
434
435    // Try the <body> element first as a scrollbar source.
436    Element* body = doc ? doc->body() : 0;
437    if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR))
438        return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderer()->enclosingBox());
439
440    // If the <body> didn't have a custom style, then the root element might.
441    Element* docElement = doc ? doc->documentElement() : 0;
442    if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(SCROLLBAR))
443        return RenderScrollbar::createCustomScrollbar(this, orientation, docElement->renderBox());
444
445    // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
446    RenderPart* frameRenderer = m_frame->ownerRenderer();
447    if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR))
448        return RenderScrollbar::createCustomScrollbar(this, orientation, 0, m_frame.get());
449
450    // Nobody set a custom style, so we just use a native scrollbar.
451    return ScrollView::createScrollbar(orientation);
452}
453
454void FrameView::setContentsSize(const IntSize& size)
455{
456    if (size == contentsSize())
457        return;
458
459    m_deferSetNeedsLayouts++;
460
461    ScrollView::setContentsSize(size);
462    scrollAnimator()->contentsResized();
463
464    Page* page = frame() ? frame()->page() : 0;
465    if (!page)
466        return;
467
468    page->chrome()->contentsSizeChanged(frame(), size); //notify only
469
470    m_deferSetNeedsLayouts--;
471
472    if (!m_deferSetNeedsLayouts)
473        m_setNeedsLayoutWasDeferred = false; // FIXME: Find a way to make the deferred layout actually happen.
474}
475
476void FrameView::adjustViewSize()
477{
478    ASSERT(m_frame->view() == this);
479    RenderView* root = m_frame->contentRenderer();
480    if (!root)
481        return;
482
483    IntSize size = IntSize(root->docWidth(), root->docHeight());
484
485    ScrollView::setScrollOrigin(IntPoint(-root->docLeft(), -root->docTop()), !m_frame->document()->printing(), size == contentsSize());
486
487    setContentsSize(size);
488}
489
490void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
491{
492    // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
493    // overflow:hidden and overflow:scroll on <body> as applying to the document's
494    // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
495    // use the root element.
496    switch (o->style()->overflowX()) {
497        case OHIDDEN:
498            hMode = ScrollbarAlwaysOff;
499            break;
500        case OSCROLL:
501            hMode = ScrollbarAlwaysOn;
502            break;
503        case OAUTO:
504            hMode = ScrollbarAuto;
505            break;
506        default:
507            // Don't set it at all.
508            ;
509    }
510
511     switch (o->style()->overflowY()) {
512        case OHIDDEN:
513            vMode = ScrollbarAlwaysOff;
514            break;
515        case OSCROLL:
516            vMode = ScrollbarAlwaysOn;
517            break;
518        case OAUTO:
519            vMode = ScrollbarAuto;
520            break;
521        default:
522            // Don't set it at all.
523            ;
524    }
525
526    m_viewportRenderer = o;
527}
528
529void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode)
530{
531    m_viewportRenderer = 0;
532
533    const HTMLFrameOwnerElement* owner = m_frame->ownerElement();
534    if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
535        hMode = ScrollbarAlwaysOff;
536        vMode = ScrollbarAlwaysOff;
537        return;
538    }
539
540    if (m_canHaveScrollbars) {
541        hMode = ScrollbarAuto;
542        vMode = ScrollbarAuto;
543    } else {
544        hMode = ScrollbarAlwaysOff;
545        vMode = ScrollbarAlwaysOff;
546    }
547
548    if (!m_layoutRoot) {
549        Document* document = m_frame->document();
550        Node* documentElement = document->documentElement();
551        RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
552        Node* body = document->body();
553        if (body && body->renderer()) {
554            if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) {
555                vMode = ScrollbarAlwaysOff;
556                hMode = ScrollbarAlwaysOff;
557            } else if (body->hasTagName(bodyTag)) {
558                // It's sufficient to just check the X overflow,
559                // since it's illegal to have visible in only one direction.
560                RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
561                applyOverflowToViewport(o, hMode, vMode);
562            }
563        } else if (rootRenderer) {
564#if ENABLE(SVG)
565            if (!documentElement->isSVGElement())
566                applyOverflowToViewport(rootRenderer, hMode, vMode);
567#else
568            applyOverflowToViewport(rootRenderer, hMode, vMode);
569#endif
570        }
571    }
572}
573
574#if ENABLE(FULLSCREEN_API) && USE(ACCELERATED_COMPOSITING)
575static bool isDocumentRunningFullScreenAnimation(Document* document)
576{
577    return document->webkitIsFullScreen() && document->fullScreenRenderer() && document->fullScreenRenderer()->isAnimating();
578}
579#endif
580
581#if USE(ACCELERATED_COMPOSITING)
582void FrameView::updateCompositingLayers()
583{
584    RenderView* view = m_frame->contentRenderer();
585    if (!view)
586        return;
587
588    // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
589    view->compositor()->cacheAcceleratedCompositingFlags();
590    view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange);
591
592#if ENABLE(FULLSCREEN_API)
593    Document* document = m_frame->document();
594    if (isDocumentRunningFullScreenAnimation(document))
595        view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange, document->fullScreenRenderer()->layer());
596#endif
597}
598
599GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
600{
601    RenderView* view = m_frame->contentRenderer();
602    if (!view)
603        return 0;
604    return view->compositor()->layerForHorizontalScrollbar();
605}
606
607GraphicsLayer* FrameView::layerForVerticalScrollbar() const
608{
609    RenderView* view = m_frame->contentRenderer();
610    if (!view)
611        return 0;
612    return view->compositor()->layerForVerticalScrollbar();
613}
614
615GraphicsLayer* FrameView::layerForScrollCorner() const
616{
617    RenderView* view = m_frame->contentRenderer();
618    if (!view)
619        return 0;
620    return view->compositor()->layerForScrollCorner();
621}
622
623bool FrameView::syncCompositingStateForThisFrame()
624{
625    ASSERT(m_frame->view() == this);
626    RenderView* view = m_frame->contentRenderer();
627    if (!view)
628        return true; // We don't want to keep trying to update layers if we have no renderer.
629
630    // If we sync compositing layers when a layout is pending, we may cause painting of compositing
631    // layer content to occur before layout has happened, which will cause paintContents() to bail.
632    if (needsLayout())
633        return false;
634
635    if (GraphicsLayer* graphicsLayer = view->compositor()->layerForHorizontalScrollbar())
636        graphicsLayer->syncCompositingStateForThisLayerOnly();
637    if (GraphicsLayer* graphicsLayer = view->compositor()->layerForVerticalScrollbar())
638        graphicsLayer->syncCompositingStateForThisLayerOnly();
639    if (GraphicsLayer* graphicsLayer = view->compositor()->layerForScrollCorner())
640        graphicsLayer->syncCompositingStateForThisLayerOnly();
641
642    view->compositor()->flushPendingLayerChanges();
643
644#if ENABLE(FULLSCREEN_API)
645    // The fullScreenRenderer's graphicsLayer  has been re-parented, and the above recursive syncCompositingState
646    // call will not cause the subtree under it to repaint.  Explicitly call the syncCompositingState on
647    // the fullScreenRenderer's graphicsLayer here:
648    Document* document = m_frame->document();
649    if (isDocumentRunningFullScreenAnimation(document)) {
650#if PLATFORM(ANDROID)
651        // We don't create an extra layer for the full screen video.
652        if (!document->fullScreenRenderer()->layer()
653            || !document->fullScreenRenderer()->layer()->backing())
654            return true;
655#endif
656        RenderLayerBacking* backing = document->fullScreenRenderer()->layer()->backing();
657        if (GraphicsLayer* fullScreenLayer = backing->graphicsLayer())
658            fullScreenLayer->syncCompositingState();
659    }
660#endif
661    return true;
662}
663
664void FrameView::setNeedsOneShotDrawingSynchronization()
665{
666    Page* page = frame() ? frame()->page() : 0;
667    if (page)
668        page->chrome()->client()->setNeedsOneShotDrawingSynchronization();
669}
670
671#endif // USE(ACCELERATED_COMPOSITING)
672
673bool FrameView::hasCompositedContent() const
674{
675#if USE(ACCELERATED_COMPOSITING)
676    if (RenderView* view = m_frame->contentRenderer())
677        return view->compositor()->inCompositingMode();
678#endif
679    return false;
680}
681
682bool FrameView::hasCompositedContentIncludingDescendants() const
683{
684#if USE(ACCELERATED_COMPOSITING)
685    for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
686        RenderView* renderView = frame->contentRenderer();
687        RenderLayerCompositor* compositor = renderView ? renderView->compositor() : 0;
688        if (compositor) {
689            if (compositor->inCompositingMode())
690                return true;
691
692            if (!RenderLayerCompositor::allowsIndependentlyCompositedFrames(this))
693                break;
694        }
695    }
696#endif
697    return false;
698}
699
700bool FrameView::hasCompositingAncestor() const
701{
702#if USE(ACCELERATED_COMPOSITING)
703    for (Frame* frame = m_frame->tree()->parent(); frame; frame = frame->tree()->parent()) {
704        if (FrameView* view = frame->view()) {
705            if (view->hasCompositedContent())
706                return true;
707        }
708    }
709#endif
710    return false;
711}
712
713// Sometimes (for plug-ins) we need to eagerly go into compositing mode.
714void FrameView::enterCompositingMode()
715{
716#if USE(ACCELERATED_COMPOSITING)
717    if (RenderView* view = m_frame->contentRenderer()) {
718        view->compositor()->enableCompositingMode();
719        if (!needsLayout())
720            view->compositor()->scheduleCompositingLayerUpdate();
721    }
722#endif
723}
724
725bool FrameView::isEnclosedInCompositingLayer() const
726{
727#if USE(ACCELERATED_COMPOSITING)
728    RenderObject* frameOwnerRenderer = m_frame->ownerRenderer();
729    if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
730        return true;
731
732    if (FrameView* parentView = parentFrameView())
733        return parentView->isEnclosedInCompositingLayer();
734#endif
735    return false;
736}
737
738bool FrameView::syncCompositingStateIncludingSubframes()
739{
740#if USE(ACCELERATED_COMPOSITING)
741    bool allFramesSynced = syncCompositingStateForThisFrame();
742
743    for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->traverseNext(m_frame.get())) {
744        bool synced = child->view()->syncCompositingStateForThisFrame();
745        allFramesSynced &= synced;
746    }
747    return allFramesSynced;
748#else // USE(ACCELERATED_COMPOSITING)
749    return true;
750#endif
751}
752
753bool FrameView::isSoftwareRenderable() const
754{
755#if USE(ACCELERATED_COMPOSITING)
756    RenderView* view = m_frame->contentRenderer();
757    if (!view)
758        return true;
759
760    return !view->compositor()->has3DContent();
761#else
762    return true;
763#endif
764}
765
766void FrameView::didMoveOnscreen()
767{
768    RenderView* view = m_frame->contentRenderer();
769    if (view)
770        view->didMoveOnscreen();
771    scrollAnimator()->contentAreaDidShow();
772}
773
774void FrameView::willMoveOffscreen()
775{
776    RenderView* view = m_frame->contentRenderer();
777    if (view)
778        view->willMoveOffscreen();
779    scrollAnimator()->contentAreaDidHide();
780}
781
782RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
783{
784    return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
785}
786
787void FrameView::layout(bool allowSubtree)
788{
789    if (m_inLayout)
790        return;
791
792    bool inSubframeLayoutWithFrameFlattening = parent() && m_frame->settings() && m_frame->settings()->frameFlatteningEnabled();
793
794    if (inSubframeLayoutWithFrameFlattening) {
795        if (parent()->isFrameView()) {
796            FrameView* parentView =   static_cast<FrameView*>(parent());
797            if (!parentView->m_nestedLayoutCount) {
798                while (parentView->parent() && parentView->parent()->isFrameView())
799                    parentView = static_cast<FrameView*>(parentView->parent());
800                parentView->layout(allowSubtree);
801                return;
802            }
803        }
804    }
805
806    m_layoutTimer.stop();
807    m_delayedLayout = false;
808    m_setNeedsLayoutWasDeferred = false;
809
810    // Protect the view from being deleted during layout (in recalcStyle)
811    RefPtr<FrameView> protector(this);
812
813    if (!m_frame) {
814        // FIXME: Do we need to set m_size.width here?
815        // FIXME: Should we set m_size.height here too?
816        m_size.setWidth(layoutWidth());
817        return;
818    }
819
820    // we shouldn't enter layout() while painting
821    ASSERT(!isPainting());
822    if (isPainting())
823        return;
824
825    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(m_frame.get());
826
827    if (!allowSubtree && m_layoutRoot) {
828        m_layoutRoot->markContainingBlocksForLayout(false);
829        m_layoutRoot = 0;
830    }
831
832    ASSERT(m_frame->view() == this);
833
834    Document* document = m_frame->document();
835
836    m_layoutSchedulingEnabled = false;
837
838    if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_hasPendingPostLayoutTasks && !inSubframeLayoutWithFrameFlattening) {
839        // This is a new top-level layout. If there are any remaining tasks from the previous
840        // layout, finish them now.
841        m_inSynchronousPostLayout = true;
842        m_postLayoutTasksTimer.stop();
843        performPostLayoutTasks();
844        m_inSynchronousPostLayout = false;
845    }
846
847    // Viewport-dependent media queries may cause us to need completely different style information.
848    // Check that here.
849    if (document->styleSelector()->affectedByViewportChange())
850        document->styleSelectorChanged(RecalcStyleImmediately);
851
852    // Always ensure our style info is up-to-date.  This can happen in situations where
853    // the layout beats any sort of style recalc update that needs to occur.
854    document->updateStyleIfNeeded();
855
856    bool subtree = m_layoutRoot;
857
858    // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
859    // so there's no point to continuing to layout
860    if (protector->hasOneRef())
861        return;
862
863    RenderObject* root = subtree ? m_layoutRoot : document->renderer();
864    if (!root) {
865        // FIXME: Do we need to set m_size here?
866        m_layoutSchedulingEnabled = true;
867        return;
868    }
869
870    m_nestedLayoutCount++;
871
872    if (!m_layoutRoot) {
873        Document* document = m_frame->document();
874        Node* documentElement = document->documentElement();
875        RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
876        Node* body = document->body();
877        if (body && body->renderer()) {
878            if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) {
879                body->renderer()->setChildNeedsLayout(true);
880            } else if (body->hasTagName(bodyTag)) {
881                if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewport())
882                    body->renderer()->setChildNeedsLayout(true);
883            }
884        } else if (rootRenderer) {
885#if ENABLE(SVG)
886            if (documentElement->isSVGElement()) {
887                if (!m_firstLayout && (m_size.width() != layoutWidth() || m_size.height() != layoutHeight()))
888                    rootRenderer->setChildNeedsLayout(true);
889            }
890#endif
891        }
892
893#ifdef INSTRUMENT_LAYOUT_SCHEDULING
894        if (m_firstLayout && !m_frame->ownerElement())
895            printf("Elapsed time before first layout: %d\n", document->elapsedTime());
896#endif
897    }
898
899    ScrollbarMode hMode;
900    ScrollbarMode vMode;
901    calculateScrollbarModesForLayout(hMode, vMode);
902
903    m_doFullRepaint = !subtree && (m_firstLayout || toRenderView(root)->printing());
904
905    if (!subtree) {
906        // Now set our scrollbar state for the layout.
907        ScrollbarMode currentHMode = horizontalScrollbarMode();
908        ScrollbarMode currentVMode = verticalScrollbarMode();
909
910        if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
911            if (m_firstLayout) {
912                setScrollbarsSuppressed(true);
913
914                m_firstLayout = false;
915                m_firstLayoutCallbackPending = true;
916                m_lastLayoutSize = IntSize(width(), height());
917                m_lastZoomFactor = root->style()->zoom();
918
919                // Set the initial vMode to AlwaysOn if we're auto.
920                if (vMode == ScrollbarAuto)
921                    setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
922                // Set the initial hMode to AlwaysOff if we're auto.
923                if (hMode == ScrollbarAuto)
924                    setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
925
926                setScrollbarModes(hMode, vMode);
927                setScrollbarsSuppressed(false, true);
928            } else
929                setScrollbarModes(hMode, vMode);
930        }
931
932        IntSize oldSize = m_size;
933
934        m_size = IntSize(layoutWidth(), layoutHeight());
935
936        if (oldSize != m_size) {
937            m_doFullRepaint = true;
938            if (!m_firstLayout) {
939                RenderBox* rootRenderer = document->documentElement() ? document->documentElement()->renderBox() : 0;
940                RenderBox* bodyRenderer = rootRenderer && document->body() ? document->body()->renderBox() : 0;
941                if (bodyRenderer && bodyRenderer->stretchesToViewport())
942                    bodyRenderer->setChildNeedsLayout(true);
943                else if (rootRenderer && rootRenderer->stretchesToViewport())
944                    rootRenderer->setChildNeedsLayout(true);
945            }
946        }
947    }
948
949    RenderLayer* layer = root->enclosingLayer();
950
951    m_actionScheduler->pause();
952
953    bool disableLayoutState = false;
954    if (subtree) {
955        RenderView* view = root->view();
956        disableLayoutState = view->shouldDisableLayoutStateForSubtree(root);
957        view->pushLayoutState(root);
958        if (disableLayoutState)
959            view->disableLayoutState();
960    }
961
962    m_inLayout = true;
963    beginDeferredRepaints();
964    root->layout();
965    endDeferredRepaints();
966    m_inLayout = false;
967
968    if (subtree) {
969        RenderView* view = root->view();
970        view->popLayoutState(root);
971        if (disableLayoutState)
972            view->enableLayoutState();
973    }
974    m_layoutRoot = 0;
975
976    m_layoutSchedulingEnabled = true;
977
978    if (!subtree && !toRenderView(root)->printing())
979        adjustViewSize();
980
981    // Now update the positions of all layers.
982    beginDeferredRepaints();
983    IntPoint cachedOffset;
984    if (m_doFullRepaint)
985        root->view()->repaint(); // FIXME: This isn't really right, since the RenderView doesn't fully encompass the visibleContentRect(). It just happens
986                                 // to work out most of the time, since first layouts and printing don't have you scrolled anywhere.
987    layer->updateLayerPositions((m_doFullRepaint ? 0 : RenderLayer::CheckForRepaint)
988                                | RenderLayer::IsCompositingUpdateRoot
989                                | RenderLayer::UpdateCompositingLayers,
990                                subtree ? 0 : &cachedOffset);
991    endDeferredRepaints();
992
993#if USE(ACCELERATED_COMPOSITING)
994    updateCompositingLayers();
995#endif
996
997    m_layoutCount++;
998
999#if PLATFORM(MAC) || PLATFORM(CHROMIUM)
1000    if (AXObjectCache::accessibilityEnabled())
1001        root->document()->axObjectCache()->postNotification(root, AXObjectCache::AXLayoutComplete, true);
1002#endif
1003#if ENABLE(DASHBOARD_SUPPORT)
1004    updateDashboardRegions();
1005#endif
1006
1007    ASSERT(!root->needsLayout());
1008
1009    updateCanBlitOnScrollRecursively();
1010
1011    if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
1012        updateOverflowStatus(layoutWidth() < contentsWidth(),
1013                             layoutHeight() < contentsHeight());
1014
1015    if (!m_hasPendingPostLayoutTasks) {
1016        if (!m_inSynchronousPostLayout && !inSubframeLayoutWithFrameFlattening) {
1017            m_inSynchronousPostLayout = true;
1018            // Calls resumeScheduledEvents()
1019            performPostLayoutTasks();
1020            m_inSynchronousPostLayout = false;
1021        }
1022
1023        if (!m_hasPendingPostLayoutTasks && (needsLayout() || m_inSynchronousPostLayout || inSubframeLayoutWithFrameFlattening)) {
1024            // If we need layout or are already in a synchronous call to postLayoutTasks(),
1025            // defer widget updates and event dispatch until after we return. postLayoutTasks()
1026            // can make us need to update again, and we can get stuck in a nasty cycle unless
1027            // we call it through the timer here.
1028            m_hasPendingPostLayoutTasks = true;
1029            m_postLayoutTasksTimer.startOneShot(0);
1030            if (needsLayout()) {
1031                m_actionScheduler->pause();
1032                layout();
1033            }
1034        }
1035    } else {
1036        m_actionScheduler->resume();
1037    }
1038
1039    InspectorInstrumentation::didLayout(cookie);
1040
1041    m_nestedLayoutCount--;
1042#if ENABLE(ANDROID_OVERFLOW_SCROLL)
1043    // Reset to false each time we layout in case the overflow status changed.
1044    bool hasOverflowScroll = false;
1045    RenderObject* ownerRenderer = m_frame->ownerRenderer();
1046    if (ownerRenderer && ownerRenderer->isRenderIFrame()) {
1047        RenderLayer* layer = ownerRenderer->enclosingLayer();
1048        if (layer) {
1049            // Some sites use tiny iframes for loading so don't composite those.
1050            if (canHaveScrollbars() && layoutWidth() > 1 && layoutHeight() > 1)
1051                hasOverflowScroll = layoutWidth() < contentsWidth() || layoutHeight() < contentsHeight();
1052        }
1053    }
1054    if (RenderView* view = m_frame->contentRenderer()) {
1055        if (hasOverflowScroll != m_hasOverflowScroll) {
1056            if (hasOverflowScroll)
1057                enterCompositingMode();
1058            else
1059                // We are leaving overflow mode so we need to update the layer
1060                // tree in case that is the reason we were composited.
1061                view->compositor()->scheduleCompositingLayerUpdate();
1062        }
1063    }
1064    m_hasOverflowScroll = hasOverflowScroll;
1065#endif
1066}
1067
1068void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object)
1069{
1070    if (!m_widgetUpdateSet)
1071        m_widgetUpdateSet.set(new RenderEmbeddedObjectSet);
1072
1073    m_widgetUpdateSet->add(object);
1074}
1075
1076void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object)
1077{
1078    if (!m_widgetUpdateSet)
1079        return;
1080
1081    m_widgetUpdateSet->remove(object);
1082}
1083
1084void FrameView::setMediaType(const String& mediaType)
1085{
1086    m_mediaType = mediaType;
1087}
1088
1089String FrameView::mediaType() const
1090{
1091    // See if we have an override type.
1092    String overrideType = m_frame->loader()->client()->overrideMediaType();
1093    if (!overrideType.isNull())
1094        return overrideType;
1095    return m_mediaType;
1096}
1097
1098void FrameView::adjustMediaTypeForPrinting(bool printing)
1099{
1100    if (printing) {
1101        if (m_mediaTypeWhenNotPrinting.isNull())
1102            m_mediaTypeWhenNotPrinting = mediaType();
1103            setMediaType("print");
1104    } else {
1105        if (!m_mediaTypeWhenNotPrinting.isNull())
1106            setMediaType(m_mediaTypeWhenNotPrinting);
1107        m_mediaTypeWhenNotPrinting = String();
1108    }
1109}
1110
1111bool FrameView::useSlowRepaints() const
1112{
1113    if (m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque)
1114        return true;
1115
1116    if (FrameView* parentView = parentFrameView())
1117        return parentView->useSlowRepaints();
1118
1119    return false;
1120}
1121
1122bool FrameView::useSlowRepaintsIfNotOverlapped() const
1123{
1124    if (m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque)
1125        return true;
1126
1127    if (FrameView* parentView = parentFrameView())
1128        return parentView->useSlowRepaintsIfNotOverlapped();
1129
1130    return false;
1131}
1132
1133void FrameView::updateCanBlitOnScrollRecursively()
1134{
1135    for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
1136        if (FrameView* view = frame->view())
1137            view->setCanBlitOnScroll(!view->useSlowRepaints());
1138    }
1139}
1140
1141void FrameView::setUseSlowRepaints()
1142{
1143    m_useSlowRepaints = true;
1144    updateCanBlitOnScrollRecursively();
1145}
1146
1147void FrameView::addSlowRepaintObject()
1148{
1149    if (!m_slowRepaintObjectCount)
1150        updateCanBlitOnScrollRecursively();
1151    m_slowRepaintObjectCount++;
1152}
1153
1154void FrameView::removeSlowRepaintObject()
1155{
1156    ASSERT(m_slowRepaintObjectCount > 0);
1157    m_slowRepaintObjectCount--;
1158    if (!m_slowRepaintObjectCount)
1159        updateCanBlitOnScrollRecursively();
1160}
1161
1162void FrameView::addFixedObject()
1163{
1164    if (!m_fixedObjectCount && platformWidget())
1165        updateCanBlitOnScrollRecursively();
1166    ++m_fixedObjectCount;
1167}
1168
1169void FrameView::removeFixedObject()
1170{
1171    ASSERT(m_fixedObjectCount > 0);
1172    --m_fixedObjectCount;
1173    if (!m_fixedObjectCount)
1174        updateCanBlitOnScrollRecursively();
1175}
1176
1177#if PLATFORM(ANDROID)
1178// When the screen size change, fixed positioned element should be updated.
1179void FrameView::updatePositionedObjects()
1180{
1181    RenderBlock::PositionedObjectsListHashSet* positionedObjects = 0;
1182    if (RenderView* root = m_frame->contentRenderer())
1183        positionedObjects = root->positionedObjects();
1184
1185    if (!positionedObjects || positionedObjects->isEmpty())
1186        return;
1187
1188    RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
1189    for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
1190        RenderBox* renderBox = *it;
1191        if (renderBox->style()->position() != FixedPosition)
1192            continue;
1193
1194        renderBox->computeLogicalWidth();
1195        renderBox->computeLogicalHeight();
1196    }
1197}
1198#endif
1199
1200int FrameView::scrollXForFixedPosition() const
1201{
1202    int visibleContentWidth = visibleContentRect().width();
1203    int maxX = contentsWidth() - visibleContentWidth;
1204
1205    if (maxX == 0)
1206        return 0;
1207
1208    int x = scrollX();
1209
1210    if (x < 0)
1211        x = 0;
1212    else if (x > maxX)
1213        x = maxX;
1214
1215    if (!m_frame)
1216        return x;
1217
1218    float pageScaleFactor = m_frame->pageScaleFactor();
1219
1220    // When the page is scaled, the scaled "viewport" with respect to which fixed object are positioned
1221    // doesn't move as fast as the content view, so that when the content is scrolled all the way to the
1222    // end, the bottom of the scaled "viewport" touches the bottom of the real viewport.
1223    float dragFactor = (contentsWidth() - visibleContentWidth * pageScaleFactor) / maxX;
1224
1225    return x * dragFactor / pageScaleFactor;
1226}
1227
1228int FrameView::scrollYForFixedPosition() const
1229{
1230    int visibleContentHeight = visibleContentRect().height();
1231
1232    int maxY = contentsHeight() - visibleContentHeight;
1233    if (maxY == 0)
1234        return 0;
1235
1236    int y = scrollY();
1237
1238    if (y < 0)
1239        y = 0;
1240    else if (y > maxY)
1241        y = maxY;
1242
1243    if (!m_frame)
1244        return y;
1245
1246    float pageScaleFactor = m_frame->pageScaleFactor();
1247    float dragFactor = (contentsHeight() - visibleContentHeight * pageScaleFactor) / maxY;
1248
1249    return y * dragFactor / pageScaleFactor;
1250}
1251
1252IntSize FrameView::scrollOffsetForFixedPosition() const
1253{
1254    return IntSize(scrollXForFixedPosition(), scrollYForFixedPosition());
1255}
1256
1257IntPoint FrameView::currentMousePosition() const
1258{
1259    return m_frame ? m_frame->eventHandler()->currentMousePosition() : IntPoint();
1260}
1261
1262bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
1263{
1264    const size_t fixedObjectThreshold = 5;
1265
1266    RenderBlock::PositionedObjectsListHashSet* positionedObjects = 0;
1267    if (RenderView* root = m_frame->contentRenderer())
1268        positionedObjects = root->positionedObjects();
1269
1270    if (!positionedObjects || positionedObjects->isEmpty()) {
1271        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1272        return true;
1273    }
1274
1275    // Get the rects of the fixed objects visible in the rectToScroll
1276    Vector<IntRect, fixedObjectThreshold> subRectToUpdate;
1277    bool updateInvalidatedSubRect = true;
1278    RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
1279    for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
1280        RenderBox* renderBox = *it;
1281        if (renderBox->style()->position() != FixedPosition)
1282            continue;
1283        IntRect updateRect = renderBox->layer()->repaintRectIncludingDescendants();
1284        updateRect = contentsToWindow(updateRect);
1285        if (clipsRepaints())
1286            updateRect.intersect(rectToScroll);
1287        if (!updateRect.isEmpty()) {
1288            if (subRectToUpdate.size() >= fixedObjectThreshold) {
1289                updateInvalidatedSubRect = false;
1290                break;
1291            }
1292            subRectToUpdate.append(updateRect);
1293        }
1294    }
1295
1296    // Scroll the view
1297    if (updateInvalidatedSubRect) {
1298        // 1) scroll
1299        hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1300
1301        // 2) update the area of fixed objects that has been invalidated
1302        size_t fixObjectsCount = subRectToUpdate.size();
1303        for (size_t i = 0; i < fixObjectsCount; ++i) {
1304            IntRect updateRect = subRectToUpdate[i];
1305            IntRect scrolledRect = updateRect;
1306            scrolledRect.move(scrollDelta);
1307            updateRect.unite(scrolledRect);
1308            if (clipsRepaints())
1309                updateRect.intersect(rectToScroll);
1310            hostWindow()->invalidateContentsAndWindow(updateRect, false);
1311        }
1312        return true;
1313    }
1314
1315    // the number of fixed objects exceed the threshold, we cannot use the fast path
1316    return false;
1317}
1318
1319void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
1320{
1321#if USE(ACCELERATED_COMPOSITING)
1322    if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
1323        if (frameRenderer->containerForRepaint()) {
1324            IntRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
1325                         frameRenderer->borderTop() + frameRenderer->paddingTop(),
1326                         visibleWidth(), visibleHeight());
1327            frameRenderer->repaintRectangle(rect);
1328            return;
1329        }
1330    }
1331#endif
1332
1333    ScrollView::scrollContentsSlowPath(updateRect);
1334}
1335
1336// Note that this gets called at painting time.
1337void FrameView::setIsOverlapped(bool isOverlapped)
1338{
1339    if (isOverlapped == m_isOverlapped)
1340        return;
1341
1342    m_isOverlapped = isOverlapped;
1343    updateCanBlitOnScrollRecursively();
1344
1345#if USE(ACCELERATED_COMPOSITING)
1346    if (hasCompositedContentIncludingDescendants()) {
1347        // Overlap can affect compositing tests, so if it changes, we need to trigger
1348        // a layer update in the parent document.
1349        if (Frame* parentFrame = m_frame->tree()->parent()) {
1350            if (RenderView* parentView = parentFrame->contentRenderer()) {
1351                RenderLayerCompositor* compositor = parentView->compositor();
1352                compositor->setCompositingLayersNeedRebuild();
1353                compositor->scheduleCompositingLayerUpdate();
1354            }
1355        }
1356
1357        if (RenderLayerCompositor::allowsIndependentlyCompositedFrames(this)) {
1358            // We also need to trigger reevaluation for this and all descendant frames,
1359            // since a frame uses compositing if any ancestor is compositing.
1360            for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
1361                if (RenderView* view = frame->contentRenderer()) {
1362                    RenderLayerCompositor* compositor = view->compositor();
1363                    compositor->setCompositingLayersNeedRebuild();
1364                    compositor->scheduleCompositingLayerUpdate();
1365                }
1366            }
1367        }
1368    }
1369#endif
1370}
1371
1372bool FrameView::isOverlappedIncludingAncestors() const
1373{
1374    if (isOverlapped())
1375        return true;
1376
1377    if (FrameView* parentView = parentFrameView()) {
1378        if (parentView->isOverlapped())
1379            return true;
1380    }
1381
1382    return false;
1383}
1384
1385void FrameView::setContentIsOpaque(bool contentIsOpaque)
1386{
1387    if (contentIsOpaque == m_contentIsOpaque)
1388        return;
1389
1390    m_contentIsOpaque = contentIsOpaque;
1391    updateCanBlitOnScrollRecursively();
1392}
1393
1394void FrameView::restoreScrollbar()
1395{
1396    setScrollbarsSuppressed(false);
1397}
1398
1399bool FrameView::scrollToFragment(const KURL& url)
1400{
1401    // If our URL has no ref, then we have no place we need to jump to.
1402    // OTOH If CSS target was set previously, we want to set it to 0, recalc
1403    // and possibly repaint because :target pseudo class may have been
1404    // set (see bug 11321).
1405    if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget())
1406        return false;
1407
1408    String fragmentIdentifier = url.fragmentIdentifier();
1409    if (scrollToAnchor(fragmentIdentifier))
1410        return true;
1411
1412    // Try again after decoding the ref, based on the document's encoding.
1413    if (TextResourceDecoder* decoder = m_frame->document()->decoder())
1414        return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding()));
1415
1416    return false;
1417}
1418
1419bool FrameView::scrollToAnchor(const String& name)
1420{
1421    ASSERT(m_frame->document());
1422
1423    if (!m_frame->document()->haveStylesheetsLoaded()) {
1424        m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
1425        return false;
1426    }
1427
1428    m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false);
1429
1430    Element* anchorNode = m_frame->document()->findAnchor(name);
1431
1432#if ENABLE(SVG)
1433    if (m_frame->document()->isSVGDocument()) {
1434        if (name.startsWith("xpointer(")) {
1435            // We need to parse the xpointer reference here
1436        } else if (name.startsWith("svgView(")) {
1437            RefPtr<SVGSVGElement> svg = static_cast<SVGDocument*>(m_frame->document())->rootElement();
1438            if (!svg->currentView()->parseViewSpec(name))
1439                return false;
1440            svg->setUseCurrentView(true);
1441        } else {
1442            if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) {
1443                RefPtr<SVGViewElement> viewElement = anchorNode->hasTagName(SVGNames::viewTag) ? static_cast<SVGViewElement*>(anchorNode) : 0;
1444                if (viewElement.get()) {
1445                    SVGElement* element = SVGLocatable::nearestViewportElement(viewElement.get());
1446                    if (element->hasTagName(SVGNames::svgTag)) {
1447                        RefPtr<SVGSVGElement> svg = static_cast<SVGSVGElement*>(element);
1448                        svg->inheritViewAttributes(viewElement.get());
1449                    }
1450                }
1451            }
1452        }
1453        // FIXME: need to decide which <svg> to focus on, and zoom to that one
1454        // FIXME: need to actually "highlight" the viewTarget(s)
1455    }
1456#endif
1457
1458    m_frame->document()->setCSSTarget(anchorNode); // Setting to null will clear the current target.
1459
1460    // Implement the rule that "" and "top" both mean top of page as in other browsers.
1461    if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top")))
1462        return false;
1463
1464    maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document());
1465    return true;
1466}
1467
1468void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
1469{
1470    m_maintainScrollPositionAnchor = anchorNode;
1471    if (!m_maintainScrollPositionAnchor)
1472        return;
1473
1474    // We need to update the layout before scrolling, otherwise we could
1475    // really mess things up if an anchor scroll comes at a bad moment.
1476    m_frame->document()->updateStyleIfNeeded();
1477    // Only do a layout if changes have occurred that make it necessary.
1478    if (m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout())
1479        layout();
1480    else
1481        scrollToAnchor();
1482}
1483
1484void FrameView::setScrollPosition(const IntPoint& scrollPoint)
1485{
1486    bool wasInProgrammaticScroll = m_inProgrammaticScroll;
1487    m_inProgrammaticScroll = true;
1488    m_maintainScrollPositionAnchor = 0;
1489    ScrollView::setScrollPosition(scrollPoint);
1490    m_inProgrammaticScroll = wasInProgrammaticScroll;
1491}
1492
1493void FrameView::scrollPositionChangedViaPlatformWidget()
1494{
1495    repaintFixedElementsAfterScrolling();
1496    scrollPositionChanged();
1497}
1498
1499void FrameView::scrollPositionChanged()
1500{
1501    frame()->eventHandler()->sendScrollEvent();
1502
1503#if USE(ACCELERATED_COMPOSITING)
1504    if (RenderView* root = m_frame->contentRenderer()) {
1505        if (root->usesCompositing())
1506            root->compositor()->frameViewDidScroll(scrollPosition());
1507    }
1508#endif
1509}
1510
1511void FrameView::repaintFixedElementsAfterScrolling()
1512{
1513    // For fixed position elements, update widget positions and compositing layers after scrolling,
1514    // but only if we're not inside of layout.
1515    if (!m_nestedLayoutCount && hasFixedObjects()) {
1516        if (RenderView* root = m_frame->contentRenderer()) {
1517            root->updateWidgetPositions();
1518            root->layer()->updateRepaintRectsAfterScroll();
1519#if USE(ACCELERATED_COMPOSITING)
1520            root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
1521#endif
1522        }
1523    }
1524}
1525
1526HostWindow* FrameView::hostWindow() const
1527{
1528    Page* page = frame() ? frame()->page() : 0;
1529    if (!page)
1530        return 0;
1531    return page->chrome();
1532}
1533
1534const unsigned cRepaintRectUnionThreshold = 25;
1535
1536void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
1537{
1538    ASSERT(!m_frame->ownerElement());
1539
1540    double delay = m_deferringRepaints ? 0 : adjustedDeferredRepaintDelay();
1541    if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
1542        IntRect paintRect = r;
1543        if (clipsRepaints() && !paintsEntireContents())
1544            paintRect.intersect(visibleContentRect());
1545#ifdef ANDROID_CAPTURE_OFFSCREEN_PAINTS
1546        if (r != paintRect)
1547            ScrollView::platformOffscreenContentRectangle(visibleContentRect(), r);
1548#endif
1549        if (paintRect.isEmpty())
1550            return;
1551        if (m_repaintCount == cRepaintRectUnionThreshold) {
1552            IntRect unionedRect;
1553            for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i)
1554                unionedRect.unite(m_repaintRects[i]);
1555            m_repaintRects.clear();
1556            m_repaintRects.append(unionedRect);
1557        }
1558        if (m_repaintCount < cRepaintRectUnionThreshold)
1559            m_repaintRects.append(paintRect);
1560        else
1561            m_repaintRects[0].unite(paintRect);
1562        m_repaintCount++;
1563
1564        if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive())
1565             m_deferredRepaintTimer.startOneShot(delay);
1566        return;
1567    }
1568
1569    if (!shouldUpdate(immediate))
1570        return;
1571
1572#if ENABLE(TILED_BACKING_STORE)
1573    if (frame()->tiledBackingStore()) {
1574        frame()->tiledBackingStore()->invalidate(r);
1575        return;
1576    }
1577#endif
1578    ScrollView::repaintContentRectangle(r, immediate);
1579}
1580
1581void FrameView::contentsResized()
1582{
1583    scrollAnimator()->contentsResized();
1584    setNeedsLayout();
1585}
1586
1587void FrameView::visibleContentsResized()
1588{
1589    // We check to make sure the view is attached to a frame() as this method can
1590    // be triggered before the view is attached by Frame::createView(...) setting
1591    // various values such as setScrollBarModes(...) for example.  An ASSERT is
1592    // triggered when a view is layout before being attached to a frame().
1593    if (!frame()->view())
1594        return;
1595
1596    if (needsLayout())
1597        layout();
1598
1599#if USE(ACCELERATED_COMPOSITING)
1600    if (RenderView* root = m_frame->contentRenderer()) {
1601        if (root->usesCompositing())
1602            root->compositor()->frameViewDidChangeSize();
1603    }
1604#endif
1605}
1606
1607void FrameView::beginDeferredRepaints()
1608{
1609    Page* page = m_frame->page();
1610    if (page->mainFrame() != m_frame)
1611        return page->mainFrame()->view()->beginDeferredRepaints();
1612
1613    m_deferringRepaints++;
1614}
1615
1616
1617void FrameView::endDeferredRepaints()
1618{
1619    Page* page = m_frame->page();
1620    if (page->mainFrame() != m_frame)
1621        return page->mainFrame()->view()->endDeferredRepaints();
1622
1623    ASSERT(m_deferringRepaints > 0);
1624
1625    if (--m_deferringRepaints)
1626        return;
1627
1628    if (m_deferredRepaintTimer.isActive())
1629        return;
1630
1631    if (double delay = adjustedDeferredRepaintDelay()) {
1632        m_deferredRepaintTimer.startOneShot(delay);
1633        return;
1634    }
1635
1636    doDeferredRepaints();
1637}
1638
1639void FrameView::checkStopDelayingDeferredRepaints()
1640{
1641    if (!m_deferredRepaintTimer.isActive())
1642        return;
1643
1644    Document* document = m_frame->document();
1645    if (document && (document->parsing() || document->cachedResourceLoader()->requestCount()))
1646        return;
1647
1648    m_deferredRepaintTimer.stop();
1649
1650    doDeferredRepaints();
1651}
1652
1653void FrameView::doDeferredRepaints()
1654{
1655    ASSERT(!m_deferringRepaints);
1656    if (!shouldUpdate()) {
1657        m_repaintRects.clear();
1658        m_repaintCount = 0;
1659        return;
1660    }
1661    unsigned size = m_repaintRects.size();
1662    for (unsigned i = 0; i < size; i++) {
1663#if ENABLE(TILED_BACKING_STORE)
1664        if (frame()->tiledBackingStore()) {
1665            frame()->tiledBackingStore()->invalidate(m_repaintRects[i]);
1666            continue;
1667        }
1668#endif
1669        ScrollView::repaintContentRectangle(m_repaintRects[i], false);
1670    }
1671    m_repaintRects.clear();
1672    m_repaintCount = 0;
1673
1674    updateDeferredRepaintDelay();
1675}
1676
1677void FrameView::updateDeferredRepaintDelay()
1678{
1679    Document* document = m_frame->document();
1680    if (!document || (!document->parsing() && !document->cachedResourceLoader()->requestCount())) {
1681        m_deferredRepaintDelay = s_deferredRepaintDelay;
1682        return;
1683    }
1684    if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) {
1685        m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading;
1686        if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading)
1687            m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading;
1688    }
1689}
1690
1691void FrameView::resetDeferredRepaintDelay()
1692{
1693    m_deferredRepaintDelay = 0;
1694    if (m_deferredRepaintTimer.isActive()) {
1695        m_deferredRepaintTimer.stop();
1696        if (!m_deferringRepaints)
1697            doDeferredRepaints();
1698    }
1699}
1700
1701double FrameView::adjustedDeferredRepaintDelay() const
1702{
1703    ASSERT(!m_deferringRepaints);
1704    if (!m_deferredRepaintDelay)
1705        return 0;
1706    double timeSinceLastPaint = currentTime() - m_lastPaintTime;
1707    return max(0., m_deferredRepaintDelay - timeSinceLastPaint);
1708}
1709
1710void FrameView::deferredRepaintTimerFired(Timer<FrameView>*)
1711{
1712    doDeferredRepaints();
1713}
1714
1715void FrameView::layoutTimerFired(Timer<FrameView>*)
1716{
1717#ifdef INSTRUMENT_LAYOUT_SCHEDULING
1718    if (!m_frame->document()->ownerElement())
1719        printf("Layout timer fired at %d\n", m_frame->document()->elapsedTime());
1720#endif
1721    layout();
1722}
1723
1724void FrameView::scheduleRelayout()
1725{
1726    // FIXME: We should assert the page is not in the page cache, but that is causing
1727    // too many false assertions.  See <rdar://problem/7218118>.
1728    ASSERT(m_frame->view() == this);
1729
1730    if (m_layoutRoot) {
1731        m_layoutRoot->markContainingBlocksForLayout(false);
1732        m_layoutRoot = 0;
1733    }
1734    if (!m_layoutSchedulingEnabled)
1735        return;
1736    if (!needsLayout())
1737        return;
1738    if (!m_frame->document()->shouldScheduleLayout())
1739        return;
1740
1741    // When frame flattening is enabled, the contents of the frame affects layout of the parent frames.
1742    // Also invalidate parent frame starting from the owner element of this frame.
1743    if (m_frame->settings() && m_frame->settings()->frameFlatteningEnabled() && m_frame->ownerRenderer()) {
1744        if (m_frame->ownerElement()->hasTagName(iframeTag) || m_frame->ownerElement()->hasTagName(frameTag))
1745            m_frame->ownerRenderer()->setNeedsLayout(true, true);
1746    }
1747
1748#ifdef ANDROID_FLATTEN_FRAMESET
1749    if (m_frame->ownerRenderer() && m_frame->ownerElement()->hasTagName(frameTag))
1750        m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
1751#endif
1752
1753    int delay = m_frame->document()->minimumLayoutDelay();
1754    if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
1755        unscheduleRelayout();
1756    if (m_layoutTimer.isActive())
1757        return;
1758
1759    m_delayedLayout = delay != 0;
1760
1761#ifdef INSTRUMENT_LAYOUT_SCHEDULING
1762    if (!m_frame->document()->ownerElement())
1763        printf("Scheduling layout for %d\n", delay);
1764#endif
1765
1766    m_layoutTimer.startOneShot(delay * 0.001);
1767}
1768
1769static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
1770{
1771    for (RenderObject* r = descendant; r; r = r->container()) {
1772        if (r == ancestor)
1773            return true;
1774    }
1775    return false;
1776}
1777
1778void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
1779{
1780    ASSERT(m_frame->view() == this);
1781
1782    if (m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout()) {
1783        if (relayoutRoot)
1784            relayoutRoot->markContainingBlocksForLayout(false);
1785        return;
1786    }
1787
1788    if (layoutPending() || !m_layoutSchedulingEnabled) {
1789        if (m_layoutRoot != relayoutRoot) {
1790            if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) {
1791                // Keep the current root
1792                relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot);
1793                ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
1794            } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) {
1795                // Re-root at relayoutRoot
1796                m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
1797                m_layoutRoot = relayoutRoot;
1798                ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
1799            } else {
1800                // Just do a full relayout
1801                if (m_layoutRoot)
1802                    m_layoutRoot->markContainingBlocksForLayout(false);
1803                m_layoutRoot = 0;
1804                relayoutRoot->markContainingBlocksForLayout(false);
1805            }
1806        }
1807    } else if (m_layoutSchedulingEnabled) {
1808        int delay = m_frame->document()->minimumLayoutDelay();
1809        m_layoutRoot = relayoutRoot;
1810        ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
1811        m_delayedLayout = delay != 0;
1812        m_layoutTimer.startOneShot(delay * 0.001);
1813    }
1814}
1815
1816bool FrameView::layoutPending() const
1817{
1818    return m_layoutTimer.isActive();
1819}
1820
1821bool FrameView::needsLayout() const
1822{
1823    // This can return true in cases where the document does not have a body yet.
1824    // Document::shouldScheduleLayout takes care of preventing us from scheduling
1825    // layout in that case.
1826    if (!m_frame)
1827        return false;
1828    RenderView* root = m_frame->contentRenderer();
1829    return layoutPending()
1830        || (root && root->needsLayout())
1831        || m_layoutRoot
1832        || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred);
1833}
1834
1835void FrameView::setNeedsLayout()
1836{
1837    if (m_deferSetNeedsLayouts) {
1838        m_setNeedsLayoutWasDeferred = true;
1839        return;
1840    }
1841    RenderView* root = m_frame->contentRenderer();
1842    if (root)
1843        root->setNeedsLayout(true);
1844}
1845
1846void FrameView::unscheduleRelayout()
1847{
1848    m_postLayoutTasksTimer.stop();
1849
1850    if (!m_layoutTimer.isActive())
1851        return;
1852
1853#ifdef INSTRUMENT_LAYOUT_SCHEDULING
1854    if (!m_frame->document()->ownerElement())
1855        printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
1856#endif
1857
1858    m_layoutTimer.stop();
1859    m_delayedLayout = false;
1860}
1861
1862#if ENABLE(REQUEST_ANIMATION_FRAME)
1863void FrameView::serviceScriptedAnimations(DOMTimeStamp time)
1864{
1865    for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext())
1866        frame->document()->serviceScriptedAnimations(time);
1867}
1868#endif
1869
1870bool FrameView::isTransparent() const
1871{
1872    return m_isTransparent;
1873}
1874
1875void FrameView::setTransparent(bool isTransparent)
1876{
1877    m_isTransparent = isTransparent;
1878}
1879
1880Color FrameView::baseBackgroundColor() const
1881{
1882    return m_baseBackgroundColor;
1883}
1884
1885void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
1886{
1887    if (!backgroundColor.isValid())
1888        m_baseBackgroundColor = Color::white;
1889    else
1890        m_baseBackgroundColor = backgroundColor;
1891}
1892
1893void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
1894{
1895    for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
1896        if (FrameView* view = frame->view()) {
1897            view->setTransparent(transparent);
1898            view->setBaseBackgroundColor(backgroundColor);
1899        }
1900    }
1901}
1902
1903bool FrameView::shouldUpdateWhileOffscreen() const
1904{
1905    return m_shouldUpdateWhileOffscreen;
1906}
1907
1908void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
1909{
1910    m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
1911}
1912
1913bool FrameView::shouldUpdate(bool immediateRequested) const
1914{
1915    if (!immediateRequested && isOffscreen() && !shouldUpdateWhileOffscreen())
1916        return false;
1917    return true;
1918}
1919
1920void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget)
1921{
1922    m_actionScheduler->scheduleEvent(event, eventTarget);
1923}
1924
1925void FrameView::pauseScheduledEvents()
1926{
1927    m_actionScheduler->pause();
1928}
1929
1930void FrameView::resumeScheduledEvents()
1931{
1932    m_actionScheduler->resume();
1933}
1934
1935void FrameView::scrollToAnchor()
1936{
1937    RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
1938    if (!anchorNode)
1939        return;
1940
1941    if (!anchorNode->renderer())
1942        return;
1943
1944    IntRect rect;
1945    if (anchorNode != m_frame->document())
1946        rect = anchorNode->getRect();
1947
1948    // Scroll nested layers and frames to reveal the anchor.
1949    // Align to the top and to the closest side (this matches other browsers).
1950    anchorNode->renderer()->enclosingLayer()->scrollRectToVisible(rect, true, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
1951
1952    if (AXObjectCache::accessibilityEnabled())
1953        m_frame->document()->axObjectCache()->handleScrolledToAnchor(anchorNode.get());
1954
1955    // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
1956    m_maintainScrollPositionAnchor = anchorNode;
1957}
1958
1959void FrameView::updateWidget(RenderEmbeddedObject* object)
1960{
1961    ASSERT(!object->node() || object->node()->isElementNode());
1962    Element* ownerElement = static_cast<Element*>(object->node());
1963    // The object may have already been destroyed (thus node cleared),
1964    // but FrameView holds a manual ref, so it won't have been deleted.
1965    ASSERT(m_widgetUpdateSet->contains(object));
1966    if (!ownerElement)
1967        return;
1968
1969    // No need to update if it's already crashed or known to be missing.
1970    if (object->pluginCrashedOrWasMissing())
1971        return;
1972
1973    // FIXME: This could turn into a real virtual dispatch if we defined
1974    // updateWidget(bool) on HTMLElement.
1975    if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag))
1976        static_cast<HTMLPlugInImageElement*>(ownerElement)->updateWidget(CreateAnyWidgetType);
1977    // FIXME: It is not clear that Media elements need or want this updateWidget() call.
1978#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1979    else if (ownerElement->hasTagName(videoTag) || ownerElement->hasTagName(audioTag))
1980        static_cast<HTMLMediaElement*>(ownerElement)->updateWidget(CreateAnyWidgetType);
1981#endif
1982    else
1983        ASSERT_NOT_REACHED();
1984
1985    // Caution: it's possible the object was destroyed again, since loading a
1986    // plugin may run any arbitrary javascript.
1987    object->updateWidgetPosition();
1988}
1989
1990bool FrameView::updateWidgets()
1991{
1992    if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
1993        return true;
1994
1995    size_t size = m_widgetUpdateSet->size();
1996
1997    Vector<RenderEmbeddedObject*> objects;
1998    objects.reserveCapacity(size);
1999
2000    RenderEmbeddedObjectSet::const_iterator end = m_widgetUpdateSet->end();
2001    for (RenderEmbeddedObjectSet::const_iterator it = m_widgetUpdateSet->begin(); it != end; ++it) {
2002        objects.uncheckedAppend(*it);
2003        (*it)->ref();
2004    }
2005
2006    for (size_t i = 0; i < size; ++i) {
2007        RenderEmbeddedObject* object = objects[i];
2008        updateWidget(object);
2009        m_widgetUpdateSet->remove(object);
2010    }
2011
2012    RenderArena* arena = m_frame->document()->renderArena();
2013    for (size_t i = 0; i < size; ++i)
2014        objects[i]->deref(arena);
2015
2016    return m_widgetUpdateSet->isEmpty();
2017}
2018
2019void FrameView::flushAnyPendingPostLayoutTasks()
2020{
2021    if (!m_hasPendingPostLayoutTasks)
2022        return;
2023
2024    m_postLayoutTasksTimer.stop();
2025    performPostLayoutTasks();
2026}
2027
2028void FrameView::performPostLayoutTasks()
2029{
2030    m_hasPendingPostLayoutTasks = false;
2031
2032    m_frame->selection()->setCaretRectNeedsUpdate();
2033    m_frame->selection()->updateAppearance();
2034
2035    if (m_nestedLayoutCount <= 1) {
2036        if (m_firstLayoutCallbackPending) {
2037            m_firstLayoutCallbackPending = false;
2038            m_frame->loader()->didFirstLayout();
2039        }
2040
2041        if (m_isVisuallyNonEmpty && m_firstVisuallyNonEmptyLayoutCallbackPending) {
2042            m_firstVisuallyNonEmptyLayoutCallbackPending = false;
2043            m_frame->loader()->didFirstVisuallyNonEmptyLayout();
2044        }
2045    }
2046
2047    RenderView* root = m_frame->contentRenderer();
2048
2049    root->updateWidgetPositions();
2050
2051    for (unsigned i = 0; i < maxUpdateWidgetsIterations; i++) {
2052        if (updateWidgets())
2053            break;
2054    }
2055
2056    scrollToAnchor();
2057
2058    m_actionScheduler->resume();
2059
2060    if (!root->printing()) {
2061        IntSize currentSize = IntSize(width(), height());
2062        float currentZoomFactor = root->style()->zoom();
2063        bool resized = !m_firstLayout && (currentSize != m_lastLayoutSize || currentZoomFactor != m_lastZoomFactor);
2064        m_lastLayoutSize = currentSize;
2065        m_lastZoomFactor = currentZoomFactor;
2066        if (resized)
2067            m_frame->eventHandler()->sendResizeEvent();
2068    }
2069}
2070
2071void FrameView::postLayoutTimerFired(Timer<FrameView>*)
2072{
2073    performPostLayoutTasks();
2074}
2075
2076void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
2077{
2078    if (!m_viewportRenderer)
2079        return;
2080
2081    if (m_overflowStatusDirty) {
2082        m_horizontalOverflow = horizontalOverflow;
2083        m_verticalOverflow = verticalOverflow;
2084        m_overflowStatusDirty = false;
2085        return;
2086    }
2087
2088    bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
2089    bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
2090
2091    if (horizontalOverflowChanged || verticalOverflowChanged) {
2092        m_horizontalOverflow = horizontalOverflow;
2093        m_verticalOverflow = verticalOverflow;
2094
2095        m_actionScheduler->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
2096            verticalOverflowChanged, verticalOverflow),
2097            m_viewportRenderer->node());
2098    }
2099
2100}
2101
2102IntRect FrameView::windowClipRect(bool clipToContents) const
2103{
2104    ASSERT(m_frame->view() == this);
2105
2106    if (paintsEntireContents())
2107        return IntRect(IntPoint(0, 0), contentsSize());
2108
2109    // Set our clip rect to be our contents.
2110    IntRect clipRect = contentsToWindow(visibleContentRect(!clipToContents));
2111    if (!m_frame || !m_frame->ownerElement())
2112        return clipRect;
2113
2114    // Take our owner element and get the clip rect from the enclosing layer.
2115    Element* elt = m_frame->ownerElement();
2116    RenderLayer* layer = elt->renderer()->enclosingLayer();
2117    // FIXME: layer should never be null, but sometimes seems to be anyway.
2118    if (!layer)
2119        return clipRect;
2120    FrameView* parentView = elt->document()->view();
2121    clipRect.intersect(parentView->windowClipRectForLayer(layer, true));
2122    return clipRect;
2123}
2124
2125IntRect FrameView::windowClipRectForLayer(const RenderLayer* layer, bool clipToLayerContents) const
2126{
2127    // If we have no layer, just return our window clip rect.
2128    if (!layer)
2129        return windowClipRect();
2130
2131    // Apply the clip from the layer.
2132    IntRect clipRect;
2133    if (clipToLayerContents)
2134        clipRect = layer->childrenClipRect();
2135    else
2136        clipRect = layer->selfClipRect();
2137    clipRect = contentsToWindow(clipRect);
2138    return intersection(clipRect, windowClipRect());
2139}
2140
2141bool FrameView::isActive() const
2142{
2143    Page* page = frame()->page();
2144    return page && page->focusController()->isActive();
2145}
2146
2147void FrameView::scrollTo(const IntSize& newOffset)
2148{
2149    IntSize offset = scrollOffset();
2150    ScrollView::scrollTo(newOffset);
2151    if (offset != scrollOffset())
2152        scrollPositionChanged();
2153    frame()->loader()->client()->didChangeScrollOffset();
2154}
2155
2156void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
2157{
2158    // Add in our offset within the FrameView.
2159    IntRect dirtyRect = rect;
2160    dirtyRect.move(scrollbar->x(), scrollbar->y());
2161    invalidateRect(dirtyRect);
2162}
2163
2164void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
2165{
2166    tickmarks = frame()->document()->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch);
2167}
2168
2169IntRect FrameView::windowResizerRect() const
2170{
2171    Page* page = frame() ? frame()->page() : 0;
2172    if (!page)
2173        return IntRect();
2174    return page->chrome()->windowResizerRect();
2175}
2176
2177void FrameView::didCompleteRubberBand(const IntSize& initialOverhang) const
2178{
2179    Page* page = m_frame->page();
2180    if (page->mainFrame() != m_frame)
2181        return;
2182    return page->chrome()->client()->didCompleteRubberBandForMainFrame(initialOverhang);
2183}
2184
2185void FrameView::scrollbarStyleChanged()
2186{
2187    Page* page = m_frame->page();
2188    ASSERT(page);
2189    if (!page)
2190        return;
2191    page->setNeedsRecalcStyleInAllFrames();
2192}
2193
2194bool FrameView::shouldSuspendScrollAnimations() const
2195{
2196    return m_frame->loader()->state() != FrameStateComplete;
2197}
2198
2199void FrameView::notifyPageThatContentAreaWillPaint() const
2200{
2201    Page* page = m_frame->page();
2202    const HashSet<ScrollableArea*>* scrollableAreas = page->scrollableAreaSet();
2203    if (!scrollableAreas)
2204        return;
2205
2206    HashSet<ScrollableArea*>::const_iterator end = scrollableAreas->end();
2207    for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(); it != end; ++it)
2208        (*it)->scrollAnimator()->contentAreaWillPaint();
2209}
2210
2211#if ENABLE(DASHBOARD_SUPPORT)
2212void FrameView::updateDashboardRegions()
2213{
2214    Document* document = m_frame->document();
2215    if (!document->hasDashboardRegions())
2216        return;
2217    Vector<DashboardRegionValue> newRegions;
2218    document->renderBox()->collectDashboardRegions(newRegions);
2219    if (newRegions == document->dashboardRegions())
2220        return;
2221    document->setDashboardRegions(newRegions);
2222    Page* page = m_frame->page();
2223    if (!page)
2224        return;
2225    page->chrome()->client()->dashboardRegionsChanged();
2226}
2227#endif
2228
2229void FrameView::updateScrollCorner()
2230{
2231    RenderObject* renderer = 0;
2232    RefPtr<RenderStyle> cornerStyle;
2233
2234    if (!scrollCornerRect().isEmpty()) {
2235        // Try the <body> element first as a scroll corner source.
2236        Document* doc = m_frame->document();
2237        Element* body = doc ? doc->body() : 0;
2238        if (body && body->renderer()) {
2239            renderer = body->renderer();
2240            cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
2241        }
2242
2243        if (!cornerStyle) {
2244            // If the <body> didn't have a custom style, then the root element might.
2245            Element* docElement = doc ? doc->documentElement() : 0;
2246            if (docElement && docElement->renderer()) {
2247                renderer = docElement->renderer();
2248                cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
2249            }
2250        }
2251
2252        if (!cornerStyle) {
2253            // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
2254            if (RenderPart* renderer = m_frame->ownerRenderer())
2255                cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
2256        }
2257    }
2258
2259    if (cornerStyle) {
2260        if (!m_scrollCorner)
2261            m_scrollCorner = new (renderer->renderArena()) RenderScrollbarPart(renderer->document());
2262        m_scrollCorner->setStyle(cornerStyle.release());
2263        invalidateScrollCorner();
2264    } else if (m_scrollCorner) {
2265        m_scrollCorner->destroy();
2266        m_scrollCorner = 0;
2267    }
2268
2269    ScrollView::updateScrollCorner();
2270}
2271
2272void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
2273{
2274    if (context->updatingControlTints()) {
2275        updateScrollCorner();
2276        return;
2277    }
2278
2279    if (m_scrollCorner) {
2280        m_scrollCorner->paintIntoRect(context, cornerRect.x(), cornerRect.y(), cornerRect);
2281        return;
2282    }
2283
2284    ScrollView::paintScrollCorner(context, cornerRect);
2285}
2286
2287bool FrameView::hasCustomScrollbars() const
2288{
2289    const HashSet<RefPtr<Widget> >* viewChildren = children();
2290    HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
2291    for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
2292        Widget* widget = current->get();
2293        if (widget->isFrameView()) {
2294            if (static_cast<FrameView*>(widget)->hasCustomScrollbars())
2295                return true;
2296        } else if (widget->isScrollbar()) {
2297            Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
2298            if (scrollbar->isCustomScrollbar())
2299                return true;
2300        }
2301    }
2302
2303    return false;
2304}
2305
2306FrameView* FrameView::parentFrameView() const
2307{
2308    if (Widget* parentView = parent()) {
2309        if (parentView->isFrameView())
2310            return static_cast<FrameView*>(parentView);
2311    }
2312    return 0;
2313}
2314
2315void FrameView::updateControlTints()
2316{
2317    // This is called when control tints are changed from aqua/graphite to clear and vice versa.
2318    // We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
2319    // This is only done if the theme supports control tinting. It's up to the theme and platform
2320    // to define when controls get the tint and to call this function when that changes.
2321
2322    // Optimize the common case where we bring a window to the front while it's still empty.
2323    if (!m_frame || m_frame->document()->url().isEmpty())
2324        return;
2325
2326    if ((m_frame->contentRenderer() && m_frame->contentRenderer()->theme()->supportsControlTints()) || hasCustomScrollbars())  {
2327        if (needsLayout())
2328            layout();
2329        PlatformGraphicsContext* const noContext = 0;
2330        GraphicsContext context(noContext);
2331        context.setUpdatingControlTints(true);
2332        if (platformWidget())
2333            paintContents(&context, visibleContentRect());
2334        else
2335            paint(&context, frameRect());
2336    }
2337}
2338
2339bool FrameView::wasScrolledByUser() const
2340{
2341    return m_wasScrolledByUser;
2342}
2343
2344void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
2345{
2346    if (m_inProgrammaticScroll)
2347        return;
2348    m_maintainScrollPositionAnchor = 0;
2349    m_wasScrolledByUser = wasScrolledByUser;
2350}
2351
2352void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
2353{
2354    if (!frame())
2355        return;
2356
2357    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_frame.get(), rect);
2358
2359    Document* document = m_frame->document();
2360
2361#ifndef NDEBUG
2362    bool fillWithRed;
2363    if (document->printing())
2364        fillWithRed = false; // Printing, don't fill with red (can't remember why).
2365    else if (m_frame->ownerElement())
2366        fillWithRed = false; // Subframe, don't fill with red.
2367    else if (isTransparent())
2368        fillWithRed = false; // Transparent, don't fill with red.
2369    else if (m_paintBehavior & PaintBehaviorSelectionOnly)
2370        fillWithRed = false; // Selections are transparent, don't fill with red.
2371    else if (m_nodeToDraw)
2372        fillWithRed = false; // Element images are transparent, don't fill with red.
2373    else
2374        fillWithRed = true;
2375
2376    if (fillWithRed)
2377        p->fillRect(rect, Color(0xFF, 0, 0), ColorSpaceDeviceRGB);
2378#endif
2379
2380    bool isTopLevelPainter = !sCurrentPaintTimeStamp;
2381    if (isTopLevelPainter)
2382        sCurrentPaintTimeStamp = currentTime();
2383
2384    RenderView* contentRenderer = frame()->contentRenderer();
2385    if (!contentRenderer) {
2386        LOG_ERROR("called FrameView::paint with nil renderer");
2387        return;
2388    }
2389
2390    ASSERT(!needsLayout());
2391    if (needsLayout())
2392        return;
2393
2394#if USE(ACCELERATED_COMPOSITING)
2395    if (!p->paintingDisabled())
2396        syncCompositingStateForThisFrame();
2397#endif
2398
2399    PaintBehavior oldPaintBehavior = m_paintBehavior;
2400
2401    if (FrameView* parentView = parentFrameView()) {
2402        if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers)
2403            m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
2404    }
2405
2406    if (m_paintBehavior == PaintBehaviorNormal)
2407        document->markers()->invalidateRenderedRectsForMarkersInRect(rect);
2408
2409    if (document->printing())
2410        m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
2411
2412    bool flatteningPaint = m_paintBehavior & PaintBehaviorFlattenCompositingLayers;
2413    bool isRootFrame = !m_frame->ownerElement();
2414    if (flatteningPaint && isRootFrame)
2415        notifyWidgetsInAllFrames(WillPaintFlattened);
2416
2417    ASSERT(!m_isPainting);
2418    m_isPainting = true;
2419
2420    // m_nodeToDraw is used to draw only one element (and its descendants)
2421    RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
2422    RenderLayer* rootLayer = contentRenderer->layer();
2423
2424    rootLayer->paint(p, rect, m_paintBehavior, eltRenderer);
2425
2426    if (rootLayer->containsDirtyOverlayScrollbars())
2427        rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, eltRenderer);
2428
2429    m_isPainting = false;
2430
2431    if (flatteningPaint && isRootFrame)
2432        notifyWidgetsInAllFrames(DidPaintFlattened);
2433
2434    m_paintBehavior = oldPaintBehavior;
2435    m_lastPaintTime = currentTime();
2436
2437#if ENABLE(DASHBOARD_SUPPORT)
2438    // Regions may have changed as a result of the visibility/z-index of element changing.
2439    if (document->dashboardRegionsDirty())
2440        updateDashboardRegions();
2441#endif
2442
2443    if (isTopLevelPainter)
2444        sCurrentPaintTimeStamp = 0;
2445
2446    InspectorInstrumentation::didPaint(cookie);
2447}
2448
2449void FrameView::setPaintBehavior(PaintBehavior behavior)
2450{
2451    m_paintBehavior = behavior;
2452}
2453
2454PaintBehavior FrameView::paintBehavior() const
2455{
2456    return m_paintBehavior;
2457}
2458
2459bool FrameView::isPainting() const
2460{
2461    return m_isPainting;
2462}
2463
2464void FrameView::setNodeToDraw(Node* node)
2465{
2466    m_nodeToDraw = node;
2467}
2468
2469void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
2470{
2471    if (context->paintingDisabled())
2472        return;
2473
2474    if (m_frame->document()->printing())
2475        return;
2476
2477    Page* page = m_frame->page();
2478    if (page->mainFrame() == m_frame) {
2479        if (page->chrome()->client()->paintCustomOverhangArea(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect))
2480            return;
2481    }
2482
2483    return ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
2484}
2485
2486void FrameView::updateLayoutAndStyleIfNeededRecursive()
2487{
2488    // We have to crawl our entire tree looking for any FrameViews that need
2489    // layout and make sure they are up to date.
2490    // Mac actually tests for intersection with the dirty region and tries not to
2491    // update layout for frames that are outside the dirty region.  Not only does this seem
2492    // pointless (since those frames will have set a zero timer to layout anyway), but
2493    // it is also incorrect, since if two frames overlap, the first could be excluded from the dirty
2494    // region but then become included later by the second frame adding rects to the dirty region
2495    // when it lays out.
2496
2497    m_frame->document()->updateStyleIfNeeded();
2498
2499    if (needsLayout())
2500        layout();
2501
2502    const HashSet<RefPtr<Widget> >* viewChildren = children();
2503    HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
2504    for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
2505        Widget* widget = (*current).get();
2506        if (widget->isFrameView())
2507            static_cast<FrameView*>(widget)->updateLayoutAndStyleIfNeededRecursive();
2508    }
2509
2510    // updateLayoutAndStyleIfNeededRecursive is called when we need to make sure style and layout are up-to-date before
2511    // painting, so we need to flush out any deferred repaints too.
2512    flushDeferredRepaints();
2513}
2514
2515void FrameView::flushDeferredRepaints()
2516{
2517    if (!m_deferredRepaintTimer.isActive())
2518        return;
2519    m_deferredRepaintTimer.stop();
2520    doDeferredRepaints();
2521}
2522
2523void FrameView::forceLayout(bool allowSubtree)
2524{
2525    layout(allowSubtree);
2526}
2527
2528void FrameView::forceLayoutForPagination(const FloatSize& pageSize, float maximumShrinkFactor, Frame::AdjustViewSizeOrNot shouldAdjustViewSize)
2529{
2530    // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
2531    // the state of things before and after the layout
2532    RenderView *root = toRenderView(m_frame->document()->renderer());
2533    if (root) {
2534        float pageLogicalWidth = root->style()->isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
2535        float pageLogicalHeight = root->style()->isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
2536
2537        int flooredPageLogicalWidth = static_cast<int>(pageLogicalWidth);
2538        root->setLogicalWidth(flooredPageLogicalWidth);
2539        root->setPageLogicalHeight(pageLogicalHeight);
2540        root->setNeedsLayoutAndPrefWidthsRecalc();
2541        forceLayout();
2542
2543        // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
2544        // page width when shrunk, we will lay out at maximum shrink and clip extra content.
2545        // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
2546        // implementation should not do this!
2547        int docLogicalWidth = root->style()->isHorizontalWritingMode() ? root->docWidth() : root->docHeight();
2548        if (docLogicalWidth > pageLogicalWidth) {
2549            flooredPageLogicalWidth = std::min<int>(docLogicalWidth, pageLogicalWidth * maximumShrinkFactor);
2550            if (pageLogicalHeight)
2551                root->setPageLogicalHeight(flooredPageLogicalWidth / pageSize.width() * pageSize.height());
2552            root->setLogicalWidth(flooredPageLogicalWidth);
2553            root->setNeedsLayoutAndPrefWidthsRecalc();
2554            forceLayout();
2555            int docLogicalHeight = root->style()->isHorizontalWritingMode() ? root->docHeight() : root->docWidth();
2556            int docLogicalTop = root->style()->isHorizontalWritingMode() ? root->docTop() : root->docLeft();
2557            int docLogicalRight = root->style()->isHorizontalWritingMode() ? root->docRight() : root->docBottom();
2558            int clippedLogicalLeft = 0;
2559            if (!root->style()->isLeftToRightDirection())
2560                clippedLogicalLeft = docLogicalRight - flooredPageLogicalWidth;
2561            IntRect overflow(clippedLogicalLeft, docLogicalTop, flooredPageLogicalWidth, docLogicalHeight);
2562            if (!root->style()->isHorizontalWritingMode())
2563                overflow = overflow.transposedRect();
2564            root->clearLayoutOverflow();
2565            root->addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
2566        }
2567    }
2568
2569    if (shouldAdjustViewSize)
2570        adjustViewSize();
2571}
2572
2573void FrameView::adjustPageHeightDeprecated(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
2574{
2575    RenderView* root = m_frame->contentRenderer();
2576    if (root) {
2577        // Use a context with painting disabled.
2578        GraphicsContext context((PlatformGraphicsContext*)0);
2579        root->setTruncatedAt((int)floorf(oldBottom));
2580        IntRect dirtyRect(0, (int)floorf(oldTop), root->maxXLayoutOverflow(), (int)ceilf(oldBottom - oldTop));
2581        root->setPrintRect(dirtyRect);
2582        root->layer()->paint(&context, dirtyRect);
2583        *newBottom = root->bestTruncatedAt();
2584        if (*newBottom == 0)
2585            *newBottom = oldBottom;
2586        root->setPrintRect(IntRect());
2587    } else
2588        *newBottom = oldBottom;
2589}
2590
2591IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
2592{
2593    IntRect rect = renderer->localToAbsoluteQuad(FloatRect(rendererRect)).enclosingBoundingBox();
2594
2595    // Convert from page ("absolute") to FrameView coordinates.
2596    rect.move(-scrollX(), -scrollY());
2597
2598    return rect;
2599}
2600
2601IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect& viewRect) const
2602{
2603    IntRect rect = viewRect;
2604
2605    // Convert from FrameView coords into page ("absolute") coordinates.
2606    rect.move(scrollX(), scrollY());
2607
2608    // FIXME: we don't have a way to map an absolute rect down to a local quad, so just
2609    // move the rect for now.
2610    rect.setLocation(roundedIntPoint(renderer->absoluteToLocal(rect.location(), false, true /* use transforms */)));
2611    return rect;
2612}
2613
2614IntPoint FrameView::convertFromRenderer(const RenderObject* renderer, const IntPoint& rendererPoint) const
2615{
2616    IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, false, true /* use transforms */));
2617
2618    // Convert from page ("absolute") to FrameView coordinates.
2619    point.move(-scrollX(), -scrollY());
2620    return point;
2621}
2622
2623IntPoint FrameView::convertToRenderer(const RenderObject* renderer, const IntPoint& viewPoint) const
2624{
2625    IntPoint point = viewPoint;
2626
2627    // Convert from FrameView coords into page ("absolute") coordinates.
2628    point += IntSize(scrollX(), scrollY());
2629
2630    return roundedIntPoint(renderer->absoluteToLocal(point, false, true /* use transforms */));
2631}
2632
2633IntRect FrameView::convertToContainingView(const IntRect& localRect) const
2634{
2635    if (const ScrollView* parentScrollView = parent()) {
2636        if (parentScrollView->isFrameView()) {
2637            const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
2638            // Get our renderer in the parent view
2639            RenderPart* renderer = m_frame->ownerRenderer();
2640            if (!renderer)
2641                return localRect;
2642
2643            IntRect rect(localRect);
2644            // Add borders and padding??
2645            rect.move(renderer->borderLeft() + renderer->paddingLeft(),
2646                      renderer->borderTop() + renderer->paddingTop());
2647            return parentView->convertFromRenderer(renderer, rect);
2648        }
2649
2650        return Widget::convertToContainingView(localRect);
2651    }
2652
2653    return localRect;
2654}
2655
2656IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
2657{
2658    if (const ScrollView* parentScrollView = parent()) {
2659        if (parentScrollView->isFrameView()) {
2660            const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
2661
2662            // Get our renderer in the parent view
2663            RenderPart* renderer = m_frame->ownerRenderer();
2664            if (!renderer)
2665                return parentRect;
2666
2667            IntRect rect = parentView->convertToRenderer(renderer, parentRect);
2668            // Subtract borders and padding
2669            rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
2670                      -renderer->borderTop() - renderer->paddingTop());
2671            return rect;
2672        }
2673
2674        return Widget::convertFromContainingView(parentRect);
2675    }
2676
2677    return parentRect;
2678}
2679
2680IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
2681{
2682    if (const ScrollView* parentScrollView = parent()) {
2683        if (parentScrollView->isFrameView()) {
2684            const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
2685
2686            // Get our renderer in the parent view
2687            RenderPart* renderer = m_frame->ownerRenderer();
2688            if (!renderer)
2689                return localPoint;
2690
2691            IntPoint point(localPoint);
2692
2693            // Add borders and padding
2694            point.move(renderer->borderLeft() + renderer->paddingLeft(),
2695                       renderer->borderTop() + renderer->paddingTop());
2696            return parentView->convertFromRenderer(renderer, point);
2697        }
2698
2699        return Widget::convertToContainingView(localPoint);
2700    }
2701
2702    return localPoint;
2703}
2704
2705IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
2706{
2707    if (const ScrollView* parentScrollView = parent()) {
2708        if (parentScrollView->isFrameView()) {
2709            const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
2710
2711            // Get our renderer in the parent view
2712            RenderPart* renderer = m_frame->ownerRenderer();
2713            if (!renderer)
2714                return parentPoint;
2715
2716            IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
2717            // Subtract borders and padding
2718            point.move(-renderer->borderLeft() - renderer->paddingLeft(),
2719                       -renderer->borderTop() - renderer->paddingTop());
2720            return point;
2721        }
2722
2723        return Widget::convertFromContainingView(parentPoint);
2724    }
2725
2726    return parentPoint;
2727}
2728
2729// Normal delay
2730void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
2731{
2732    s_deferredRepaintDelay = p;
2733}
2734
2735// Negative value would mean that first few repaints happen without a delay
2736void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p)
2737{
2738    s_initialDeferredRepaintDelayDuringLoading = p;
2739}
2740
2741// The delay grows on each repaint to this maximum value
2742void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p)
2743{
2744    s_maxDeferredRepaintDelayDuringLoading = p;
2745}
2746
2747// On each repaint the delay increases by this amount
2748void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p)
2749{
2750    s_deferredRepaintDelayIncrementDuringLoading = p;
2751}
2752
2753bool FrameView::isVerticalDocument() const
2754{
2755    if (!m_frame)
2756        return true;
2757    Document* doc = m_frame->document();
2758    if (!doc)
2759        return true;
2760    RenderObject* renderView = doc->renderer();
2761    if (!renderView)
2762        return true;
2763    return renderView->style()->isHorizontalWritingMode();
2764}
2765
2766bool FrameView::isFlippedDocument() const
2767{
2768    if (!m_frame)
2769        return false;
2770    Document* doc = m_frame->document();
2771    if (!doc)
2772        return false;
2773    RenderObject* renderView = doc->renderer();
2774    if (!renderView)
2775        return false;
2776    return renderView->style()->isFlippedBlocksWritingMode();
2777}
2778
2779void FrameView::notifyWidgetsInAllFrames(WidgetNotification notification)
2780{
2781    for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
2782        if (RenderView* root = frame->contentRenderer())
2783            root->notifyWidgets(notification);
2784    }
2785}
2786
2787AXObjectCache* FrameView::axObjectCache() const
2788{
2789    if (frame() && frame()->document() && frame()->document()->axObjectCacheExists())
2790        return frame()->document()->axObjectCache();
2791    return 0;
2792}
2793
2794} // namespace WebCore
2795