WebCore/page/FrameView.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 "Chrome.h"
       
    33 #include "ChromeClient.h"
       
    34 #include "DocLoader.h"
       
    35 #include "EventHandler.h"
       
    36 #include "FloatRect.h"
       
    37 #include "FocusController.h"
       
    38 #include "Frame.h"
       
    39 #include "FrameLoader.h"
       
    40 #include "FrameLoaderClient.h"
       
    41 #include "FrameTree.h"
       
    42 #include "GraphicsContext.h"
       
    43 #include "HTMLDocument.h"
       
    44 #include "HTMLFrameElement.h"
       
    45 #include "HTMLFrameSetElement.h"
       
    46 #include "HTMLNames.h"
       
    47 #include "InspectorTimelineAgent.h"
       
    48 #include "OverflowEvent.h"
       
    49 #include "RenderEmbeddedObject.h"
       
    50 #include "RenderLayer.h"
       
    51 #include "RenderPart.h"
       
    52 #include "RenderScrollbar.h"
       
    53 #include "RenderScrollbarPart.h"
       
    54 #include "RenderTheme.h"
       
    55 #include "RenderView.h"
       
    56 #include "Settings.h"
       
    57 #include "TextResourceDecoder.h"
       
    58 #include <wtf/CurrentTime.h>
       
    59 
       
    60 #if USE(ACCELERATED_COMPOSITING)
       
    61 #include "RenderLayerCompositor.h"
       
    62 #endif
       
    63 
       
    64 #if ENABLE(SVG)
       
    65 #include "SVGDocument.h"
       
    66 #include "SVGLocatable.h"
       
    67 #include "SVGNames.h"
       
    68 #include "SVGPreserveAspectRatio.h"
       
    69 #include "SVGSVGElement.h"
       
    70 #include "SVGViewElement.h"
       
    71 #include "SVGViewSpec.h"
       
    72 #endif
       
    73 
       
    74 #if ENABLE(TILED_BACKING_STORE)
       
    75 #include "TiledBackingStore.h"
       
    76 #endif
       
    77 
       
    78 namespace WebCore {
       
    79 
       
    80 using namespace HTMLNames;
       
    81 
       
    82 double FrameView::sCurrentPaintTimeStamp = 0.0;
       
    83 
       
    84 // REPAINT_THROTTLING now chooses default values for throttling parameters.
       
    85 // Should be removed when applications start using runtime configuration.
       
    86 #if ENABLE(REPAINT_THROTTLING)
       
    87 // Normal delay
       
    88 double FrameView::s_deferredRepaintDelay = 0.025;
       
    89 // Negative value would mean that first few repaints happen without a delay
       
    90 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
       
    91 // The delay grows on each repaint to this maximum value
       
    92 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 2.5;
       
    93 // On each repaint the delay increses by this amount
       
    94 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5;
       
    95 #else
       
    96 // FIXME: Repaint throttling could be good to have on all platform.
       
    97 // The balance between CPU use and repaint frequency will need some tuning for desktop.
       
    98 // More hooks may be needed to reset the delay on things like GIF and CSS animations.
       
    99 double FrameView::s_deferredRepaintDelay = 0;
       
   100 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
       
   101 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0;
       
   102 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0;
       
   103 #endif
       
   104 
       
   105 // The maximum number of updateWidgets iterations that should be done before returning.
       
   106 static const unsigned maxUpdateWidgetsIterations = 2;
       
   107 
       
   108 struct ScheduledEvent : Noncopyable {
       
   109     RefPtr<Event> m_event;
       
   110     RefPtr<Node> m_eventTarget;
       
   111 };
       
   112 
       
   113 static inline float parentZoomFactor(Frame* frame)
       
   114 {
       
   115     Frame* parent = frame->tree()->parent();
       
   116     if (!parent)
       
   117         return 1;
       
   118     FrameView* parentView = parent->view();
       
   119     if (!parentView)
       
   120         return 1;
       
   121     return parentView->zoomFactor();
       
   122 }
       
   123 
       
   124 FrameView::FrameView(Frame* frame)
       
   125     : m_frame(frame)
       
   126     , m_canHaveScrollbars(true)
       
   127     , m_slowRepaintObjectCount(0)
       
   128     , m_fixedObjectCount(0)
       
   129     , m_layoutTimer(this, &FrameView::layoutTimerFired)
       
   130     , m_layoutRoot(0)
       
   131     , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
       
   132     , m_isTransparent(false)
       
   133     , m_baseBackgroundColor(Color::white)
       
   134     , m_mediaType("screen")
       
   135     , m_enqueueEvents(0)
       
   136     , m_overflowStatusDirty(true)
       
   137     , m_viewportRenderer(0)
       
   138     , m_wasScrolledByUser(false)
       
   139     , m_inProgrammaticScroll(false)
       
   140     , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired)
       
   141     , m_shouldUpdateWhileOffscreen(true)
       
   142     , m_deferSetNeedsLayouts(0)
       
   143     , m_setNeedsLayoutWasDeferred(false)
       
   144     , m_scrollCorner(0)
       
   145     , m_zoomFactor(parentZoomFactor(frame))
       
   146 {
       
   147     init();
       
   148 }
       
   149 
       
   150 PassRefPtr<FrameView> FrameView::create(Frame* frame)
       
   151 {
       
   152     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
       
   153     view->show();
       
   154     return view.release();
       
   155 }
       
   156 
       
   157 PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize)
       
   158 {
       
   159     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
       
   160     view->Widget::setFrameRect(IntRect(view->pos(), initialSize));
       
   161     view->show();
       
   162     return view.release();
       
   163 }
       
   164 
       
   165 FrameView::~FrameView()
       
   166 {
       
   167     if (m_postLayoutTasksTimer.isActive()) {
       
   168         m_postLayoutTasksTimer.stop();
       
   169         m_scheduledEvents.clear();
       
   170         m_enqueueEvents = 0;
       
   171     }
       
   172 
       
   173     resetScrollbars();
       
   174 
       
   175     // Custom scrollbars should already be destroyed at this point
       
   176     ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
       
   177     ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
       
   178 
       
   179     setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
       
   180     setHasVerticalScrollbar(false);
       
   181     
       
   182     ASSERT(!m_scrollCorner);
       
   183     ASSERT(m_scheduledEvents.isEmpty());
       
   184     ASSERT(!m_enqueueEvents);
       
   185 
       
   186     if (m_frame) {
       
   187         ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
       
   188         RenderPart* renderer = m_frame->ownerRenderer();
       
   189         if (renderer && renderer->widget() == this)
       
   190             renderer->setWidget(0);
       
   191     }
       
   192 }
       
   193 
       
   194 void FrameView::reset()
       
   195 {
       
   196     m_useSlowRepaints = false;
       
   197     m_isOverlapped = false;
       
   198     m_contentIsOpaque = false;
       
   199     m_borderX = 30;
       
   200     m_borderY = 30;
       
   201     m_layoutTimer.stop();
       
   202     m_layoutRoot = 0;
       
   203     m_delayedLayout = false;
       
   204     m_doFullRepaint = true;
       
   205     m_layoutSchedulingEnabled = true;
       
   206     m_midLayout = false;
       
   207     m_layoutCount = 0;
       
   208     m_nestedLayoutCount = 0;
       
   209     m_postLayoutTasksTimer.stop();
       
   210     m_firstLayout = true;
       
   211     m_firstLayoutCallbackPending = false;
       
   212     m_wasScrolledByUser = false;
       
   213     m_lastLayoutSize = IntSize();
       
   214     m_lastZoomFactor = 1.0f;
       
   215     m_deferringRepaints = 0;
       
   216     m_repaintCount = 0;
       
   217     m_repaintRects.clear();
       
   218     m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading;
       
   219     m_deferredRepaintTimer.stop();
       
   220     m_lastPaintTime = 0;
       
   221     m_paintBehavior = PaintBehaviorNormal;
       
   222     m_isPainting = false;
       
   223     m_isVisuallyNonEmpty = false;
       
   224     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
       
   225     m_maintainScrollPositionAnchor = 0;
       
   226 }
       
   227 
       
   228 bool FrameView::isFrameView() const 
       
   229 { 
       
   230     return true; 
       
   231 }
       
   232 
       
   233 void FrameView::clearFrame()
       
   234 {
       
   235     m_frame = 0;
       
   236 }
       
   237 
       
   238 void FrameView::resetScrollbars()
       
   239 {
       
   240     // Reset the document's scrollbars back to our defaults before we yield the floor.
       
   241     m_firstLayout = true;
       
   242     setScrollbarsSuppressed(true);
       
   243     if (m_canHaveScrollbars)
       
   244         setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
       
   245     else
       
   246         setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
       
   247     setScrollbarsSuppressed(false);
       
   248 }
       
   249 
       
   250 void FrameView::init()
       
   251 {
       
   252     reset();
       
   253 
       
   254     m_margins = IntSize(-1, -1); // undefined
       
   255     m_size = IntSize();
       
   256 
       
   257     // Propagate the marginwidth/height and scrolling modes to the view.
       
   258     Element* ownerElement = m_frame && m_frame->document() ? m_frame->document()->ownerElement() : 0;
       
   259     if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
       
   260         HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
       
   261         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
       
   262             setCanHaveScrollbars(false);
       
   263         int marginWidth = frameElt->getMarginWidth();
       
   264         int marginHeight = frameElt->getMarginHeight();
       
   265         if (marginWidth != -1)
       
   266             setMarginWidth(marginWidth);
       
   267         if (marginHeight != -1)
       
   268             setMarginHeight(marginHeight);
       
   269     }
       
   270 }
       
   271 
       
   272 void FrameView::detachCustomScrollbars()
       
   273 {
       
   274     if (!m_frame)
       
   275         return;
       
   276 
       
   277     Scrollbar* horizontalBar = horizontalScrollbar();
       
   278     if (horizontalBar && horizontalBar->isCustomScrollbar())
       
   279         setHasHorizontalScrollbar(false);
       
   280 
       
   281     Scrollbar* verticalBar = verticalScrollbar();
       
   282     if (verticalBar && verticalBar->isCustomScrollbar())
       
   283         setHasVerticalScrollbar(false);
       
   284 
       
   285     if (m_scrollCorner) {
       
   286         m_scrollCorner->destroy();
       
   287         m_scrollCorner = 0;
       
   288     }
       
   289 }
       
   290 
       
   291 void FrameView::clear()
       
   292 {
       
   293     setCanBlitOnScroll(true);
       
   294     
       
   295     reset();
       
   296 
       
   297     if (m_frame) {
       
   298         if (RenderPart* renderer = m_frame->ownerRenderer())
       
   299             renderer->viewCleared();
       
   300     }
       
   301 
       
   302     setScrollbarsSuppressed(true);
       
   303 }
       
   304 
       
   305 bool FrameView::didFirstLayout() const
       
   306 {
       
   307     return !m_firstLayout;
       
   308 }
       
   309 
       
   310 void FrameView::invalidateRect(const IntRect& rect)
       
   311 {
       
   312     if (!parent()) {
       
   313         if (hostWindow())
       
   314             hostWindow()->invalidateContentsAndWindow(rect, false /*immediate*/);
       
   315         return;
       
   316     }
       
   317 
       
   318     if (!m_frame)
       
   319         return;
       
   320 
       
   321     RenderPart* renderer = m_frame->ownerRenderer();
       
   322     if (!renderer)
       
   323         return;
       
   324 
       
   325     IntRect repaintRect = rect;
       
   326     repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
       
   327                      renderer->borderTop() + renderer->paddingTop());
       
   328     renderer->repaintRectangle(repaintRect);
       
   329 }
       
   330 
       
   331 void FrameView::setMarginWidth(int w)
       
   332 {
       
   333     // make it update the rendering area when set
       
   334     m_margins.setWidth(w);
       
   335 }
       
   336 
       
   337 void FrameView::setMarginHeight(int h)
       
   338 {
       
   339     // make it update the rendering area when set
       
   340     m_margins.setHeight(h);
       
   341 }
       
   342 
       
   343 bool FrameView::avoidScrollbarCreation()
       
   344 {
       
   345     ASSERT(m_frame);
       
   346 
       
   347     // with frame flattening no subframe can have scrollbars
       
   348     // but we also cannot turn scrollbars of as we determine
       
   349     // our flattening policy using that.
       
   350 
       
   351     if (!m_frame->ownerElement())
       
   352         return false;
       
   353 
       
   354     if (!m_frame->settings() || m_frame->settings()->frameFlatteningEnabled())
       
   355         return true;
       
   356 
       
   357     return false;
       
   358 }
       
   359 
       
   360 void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
       
   361 {
       
   362     m_canHaveScrollbars = canHaveScrollbars;
       
   363     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
       
   364 }
       
   365 
       
   366 void FrameView::updateCanHaveScrollbars()
       
   367 {
       
   368     ScrollbarMode hMode;
       
   369     ScrollbarMode vMode;
       
   370     scrollbarModes(hMode, vMode);
       
   371     if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
       
   372         m_canHaveScrollbars = false;
       
   373     else
       
   374         m_canHaveScrollbars = true;
       
   375 }
       
   376 
       
   377 PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
       
   378 {
       
   379     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
       
   380     Document* doc = m_frame->document();
       
   381 
       
   382     // Try the <body> element first as a scrollbar source.
       
   383     Element* body = doc ? doc->body() : 0;
       
   384     if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR))
       
   385         return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderer()->enclosingBox());
       
   386     
       
   387     // If the <body> didn't have a custom style, then the root element might.
       
   388     Element* docElement = doc ? doc->documentElement() : 0;
       
   389     if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(SCROLLBAR))
       
   390         return RenderScrollbar::createCustomScrollbar(this, orientation, docElement->renderBox());
       
   391         
       
   392     // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
       
   393     RenderPart* frameRenderer = m_frame->ownerRenderer();
       
   394     if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR))
       
   395         return RenderScrollbar::createCustomScrollbar(this, orientation, frameRenderer);
       
   396     
       
   397     // Nobody set a custom style, so we just use a native scrollbar.
       
   398     return ScrollView::createScrollbar(orientation);
       
   399 }
       
   400 
       
   401 void FrameView::setContentsSize(const IntSize& size)
       
   402 {
       
   403     if (size == contentsSize())
       
   404         return;
       
   405 
       
   406     m_deferSetNeedsLayouts++;
       
   407 
       
   408     ScrollView::setContentsSize(size);
       
   409 
       
   410     Page* page = frame() ? frame()->page() : 0;
       
   411     if (!page)
       
   412         return;
       
   413 
       
   414     page->chrome()->contentsSizeChanged(frame(), size); //notify only
       
   415 
       
   416     m_deferSetNeedsLayouts--;
       
   417     
       
   418     if (!m_deferSetNeedsLayouts)
       
   419         m_setNeedsLayoutWasDeferred = false; // FIXME: Find a way to make the deferred layout actually happen.
       
   420 }
       
   421 
       
   422 void FrameView::adjustViewSize()
       
   423 {
       
   424     ASSERT(m_frame->view() == this);
       
   425     RenderView* root = m_frame->contentRenderer();
       
   426     if (!root)
       
   427         return;
       
   428 
       
   429     setContentsSize(IntSize(root->rightLayoutOverflow(), root->bottomLayoutOverflow()));
       
   430 }
       
   431 
       
   432 void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
       
   433 {
       
   434     // Handle the overflow:hidden/scroll case for the body/html elements.  WinIE treats
       
   435     // overflow:hidden and overflow:scroll on <body> as applying to the document's
       
   436     // scrollbars.  The CSS2.1 draft states that HTML UAs should use the <html> or <body> element and XML/XHTML UAs should
       
   437     // use the root element.
       
   438     switch (o->style()->overflowX()) {
       
   439         case OHIDDEN:
       
   440             hMode = ScrollbarAlwaysOff;
       
   441             break;
       
   442         case OSCROLL:
       
   443             hMode = ScrollbarAlwaysOn;
       
   444             break;
       
   445         case OAUTO:
       
   446             hMode = ScrollbarAuto;
       
   447             break;
       
   448         default:
       
   449             // Don't set it at all.
       
   450             ;
       
   451     }
       
   452     
       
   453      switch (o->style()->overflowY()) {
       
   454         case OHIDDEN:
       
   455             vMode = ScrollbarAlwaysOff;
       
   456             break;
       
   457         case OSCROLL:
       
   458             vMode = ScrollbarAlwaysOn;
       
   459             break;
       
   460         case OAUTO:
       
   461             vMode = ScrollbarAuto;
       
   462             break;
       
   463         default:
       
   464             // Don't set it at all.
       
   465             ;
       
   466     }
       
   467 
       
   468     m_viewportRenderer = o;
       
   469 }
       
   470 
       
   471 #if USE(ACCELERATED_COMPOSITING)
       
   472 void FrameView::updateCompositingLayers()
       
   473 {
       
   474     RenderView* view = m_frame->contentRenderer();
       
   475     if (!view)
       
   476         return;
       
   477 
       
   478     // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
       
   479     view->compositor()->cacheAcceleratedCompositingFlags();
       
   480     view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange);
       
   481 }
       
   482 
       
   483 void FrameView::setNeedsOneShotDrawingSynchronization()
       
   484 {
       
   485     Page* page = frame() ? frame()->page() : 0;
       
   486     if (page)
       
   487         page->chrome()->client()->setNeedsOneShotDrawingSynchronization();
       
   488 }
       
   489 
       
   490 #endif // USE(ACCELERATED_COMPOSITING)
       
   491 
       
   492 bool FrameView::hasCompositedContent() const
       
   493 {
       
   494 #if USE(ACCELERATED_COMPOSITING)
       
   495     if (RenderView* view = m_frame->contentRenderer())
       
   496         return view->compositor()->inCompositingMode();
       
   497 #endif
       
   498     return false;
       
   499 }
       
   500 
       
   501 // Sometimes (for plug-ins) we need to eagerly go into compositing mode.
       
   502 void FrameView::enterCompositingMode()
       
   503 {
       
   504 #if USE(ACCELERATED_COMPOSITING)
       
   505     if (RenderView* view = m_frame->contentRenderer())
       
   506         view->compositor()->enableCompositingMode();
       
   507 #endif
       
   508 }
       
   509 
       
   510 bool FrameView::isEnclosedInCompositingLayer() const
       
   511 {
       
   512 #if USE(ACCELERATED_COMPOSITING)
       
   513     RenderObject* frameOwnerRenderer = m_frame->ownerRenderer();
       
   514     return frameOwnerRenderer && frameOwnerRenderer->containerForRepaint();
       
   515 #else
       
   516     return false;
       
   517 #endif
       
   518 }
       
   519 
       
   520 bool FrameView::syncCompositingStateRecursive()
       
   521 {
       
   522 #if USE(ACCELERATED_COMPOSITING)
       
   523     ASSERT(m_frame->view() == this);
       
   524     RenderView* contentRenderer = m_frame->contentRenderer();
       
   525     if (!contentRenderer)
       
   526         return true;    // We don't want to keep trying to update layers if we have no renderer.
       
   527 
       
   528     if (m_layoutTimer.isActive()) {
       
   529         // Don't sync layers if there's a layout pending.
       
   530         return false;
       
   531     }
       
   532     
       
   533     if (GraphicsLayer* rootLayer = contentRenderer->compositor()->rootPlatformLayer())
       
   534         rootLayer->syncCompositingState();
       
   535 
       
   536     bool allSubframesSynced = true;
       
   537     const HashSet<RefPtr<Widget> >* viewChildren = children();
       
   538     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
       
   539     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
       
   540         Widget* widget = (*current).get();
       
   541         if (widget->isFrameView()) {
       
   542             bool synced = static_cast<FrameView*>(widget)->syncCompositingStateRecursive();
       
   543             allSubframesSynced &= synced;
       
   544         }
       
   545     }
       
   546     return allSubframesSynced;
       
   547 #else // USE(ACCELERATED_COMPOSITING)
       
   548     return true;
       
   549 #endif
       
   550 }
       
   551 
       
   552 bool FrameView::isSoftwareRenderable() const
       
   553 {
       
   554 #if USE(ACCELERATED_COMPOSITING)
       
   555     RenderView* view = m_frame->contentRenderer();
       
   556     if (!view)
       
   557         return true;
       
   558 
       
   559     return !view->compositor()->has3DContent();
       
   560 #else
       
   561     return true;
       
   562 #endif
       
   563 }
       
   564 
       
   565 void FrameView::didMoveOnscreen()
       
   566 {
       
   567     RenderView* view = m_frame->contentRenderer();
       
   568     if (view)
       
   569         view->didMoveOnscreen();
       
   570 }
       
   571 
       
   572 void FrameView::willMoveOffscreen()
       
   573 {
       
   574     RenderView* view = m_frame->contentRenderer();
       
   575     if (view)
       
   576         view->willMoveOffscreen();
       
   577 }
       
   578 
       
   579 RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
       
   580 {
       
   581     return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
       
   582 }
       
   583 
       
   584 void FrameView::layout(bool allowSubtree)
       
   585 {
       
   586     if (m_midLayout)
       
   587         return;
       
   588 
       
   589     m_layoutTimer.stop();
       
   590     m_delayedLayout = false;
       
   591     m_setNeedsLayoutWasDeferred = false;
       
   592 
       
   593     // Protect the view from being deleted during layout (in recalcStyle)
       
   594     RefPtr<FrameView> protector(this);
       
   595 
       
   596     if (!m_frame) {
       
   597         // FIXME: Do we need to set m_size.width here?
       
   598         // FIXME: Should we set m_size.height here too?
       
   599         m_size.setWidth(layoutWidth());
       
   600         return;
       
   601     }
       
   602     
       
   603     // we shouldn't enter layout() while painting
       
   604     ASSERT(!isPainting());
       
   605     if (isPainting())
       
   606         return;
       
   607 
       
   608 #if ENABLE(INSPECTOR)    
       
   609     if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
       
   610         timelineAgent->willLayout();
       
   611 #endif
       
   612 
       
   613     if (!allowSubtree && m_layoutRoot) {
       
   614         m_layoutRoot->markContainingBlocksForLayout(false);
       
   615         m_layoutRoot = 0;
       
   616     }
       
   617 
       
   618     ASSERT(m_frame->view() == this);
       
   619     // This early return should be removed when rdar://5598072 is resolved. In the meantime, there is a
       
   620     // gigantic CrashTracer because of this issue, and the early return will hopefully cause graceful 
       
   621     // failure instead.  
       
   622     if (m_frame->view() != this)
       
   623         return;
       
   624 
       
   625     Document* document = m_frame->document();
       
   626 
       
   627     m_layoutSchedulingEnabled = false;
       
   628 
       
   629     if (!m_nestedLayoutCount && m_postLayoutTasksTimer.isActive()) {
       
   630         // This is a new top-level layout. If there are any remaining tasks from the previous
       
   631         // layout, finish them now.
       
   632         m_postLayoutTasksTimer.stop();
       
   633         performPostLayoutTasks();
       
   634     }
       
   635 
       
   636     // Viewport-dependent media queries may cause us to need completely different style information.
       
   637     // Check that here.
       
   638     if (document->styleSelector()->affectedByViewportChange())
       
   639         document->updateStyleSelector();
       
   640 
       
   641     // Always ensure our style info is up-to-date.  This can happen in situations where
       
   642     // the layout beats any sort of style recalc update that needs to occur.
       
   643     if (m_frame->needsReapplyStyles())
       
   644         m_frame->reapplyStyles();
       
   645     else if (document->childNeedsStyleRecalc())
       
   646         document->recalcStyle();
       
   647     
       
   648     bool subtree = m_layoutRoot;
       
   649 
       
   650     // If there is only one ref to this view left, then its going to be destroyed as soon as we exit, 
       
   651     // so there's no point to continuing to layout
       
   652     if (protector->hasOneRef())
       
   653         return;
       
   654 
       
   655     RenderObject* root = subtree ? m_layoutRoot : document->renderer();
       
   656     if (!root) {
       
   657         // FIXME: Do we need to set m_size here?
       
   658         m_layoutSchedulingEnabled = true;
       
   659         return;
       
   660     }
       
   661 
       
   662     m_nestedLayoutCount++;
       
   663 
       
   664     ScrollbarMode hMode;
       
   665     ScrollbarMode vMode;
       
   666     if (m_canHaveScrollbars) {
       
   667         hMode = ScrollbarAuto;
       
   668         vMode = ScrollbarAuto;
       
   669     } else {
       
   670         hMode = ScrollbarAlwaysOff;
       
   671         vMode = ScrollbarAlwaysOff;
       
   672     }
       
   673 
       
   674     if (!subtree) {
       
   675         Node* documentElement = document->documentElement();
       
   676         RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
       
   677         Node* body = document->body();
       
   678         if (body && body->renderer()) {
       
   679             if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) {
       
   680                 body->renderer()->setChildNeedsLayout(true);
       
   681                 vMode = ScrollbarAlwaysOff;
       
   682                 hMode = ScrollbarAlwaysOff;
       
   683             } else if (body->hasTagName(bodyTag)) {
       
   684                 if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewHeight())
       
   685                     body->renderer()->setChildNeedsLayout(true);
       
   686                 // It's sufficient to just check the X overflow,
       
   687                 // since it's illegal to have visible in only one direction.
       
   688                 RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
       
   689                 applyOverflowToViewport(o, hMode, vMode);
       
   690             }
       
   691         } else if (rootRenderer) {
       
   692 #if ENABLE(SVG)
       
   693             if (documentElement->isSVGElement()) {
       
   694                 if (!m_firstLayout && (m_size.width() != layoutWidth() || m_size.height() != layoutHeight()))
       
   695                     rootRenderer->setChildNeedsLayout(true);
       
   696             } else
       
   697                 applyOverflowToViewport(rootRenderer, hMode, vMode);
       
   698 #else
       
   699             applyOverflowToViewport(rootRenderer, hMode, vMode);
       
   700 #endif
       
   701         }
       
   702 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
       
   703         if (m_firstLayout && !document->ownerElement())
       
   704             printf("Elapsed time before first layout: %d\n", document->elapsedTime());
       
   705 #endif
       
   706     }
       
   707 
       
   708     m_doFullRepaint = !subtree && (m_firstLayout || toRenderView(root)->printing());
       
   709 
       
   710     if (!subtree) {
       
   711         // Now set our scrollbar state for the layout.
       
   712         ScrollbarMode currentHMode = horizontalScrollbarMode();
       
   713         ScrollbarMode currentVMode = verticalScrollbarMode();
       
   714 
       
   715         if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
       
   716             if (m_firstLayout) {
       
   717                 setScrollbarsSuppressed(true);
       
   718 
       
   719                 m_firstLayout = false;
       
   720                 m_firstLayoutCallbackPending = true;
       
   721                 m_lastLayoutSize = IntSize(width(), height());
       
   722                 m_lastZoomFactor = root->style()->zoom();
       
   723 
       
   724                 // Set the initial vMode to AlwaysOn if we're auto.
       
   725                 if (vMode == ScrollbarAuto)
       
   726                     setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
       
   727                 // Set the initial hMode to AlwaysOff if we're auto.
       
   728                 if (hMode == ScrollbarAuto)
       
   729                     setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
       
   730 
       
   731                 setScrollbarModes(hMode, vMode);
       
   732                 setScrollbarsSuppressed(false, true);
       
   733             } else
       
   734                 setScrollbarModes(hMode, vMode);
       
   735         }
       
   736 
       
   737         IntSize oldSize = m_size;
       
   738 
       
   739         m_size = IntSize(layoutWidth(), layoutHeight());
       
   740 
       
   741         if (oldSize != m_size)
       
   742             m_doFullRepaint = true;
       
   743     }
       
   744 
       
   745     RenderLayer* layer = root->enclosingLayer();
       
   746 
       
   747     pauseScheduledEvents();
       
   748 
       
   749     bool disableLayoutState = false;
       
   750     if (subtree) {
       
   751         RenderView* view = root->view();
       
   752         disableLayoutState = view->shouldDisableLayoutStateForSubtree(root);
       
   753         view->pushLayoutState(root);
       
   754         if (disableLayoutState)
       
   755             view->disableLayoutState();
       
   756     }
       
   757         
       
   758     m_midLayout = true;
       
   759     beginDeferredRepaints();
       
   760     root->layout();
       
   761     endDeferredRepaints();
       
   762     m_midLayout = false;
       
   763 
       
   764     if (subtree) {
       
   765         RenderView* view = root->view();
       
   766         view->popLayoutState();
       
   767         if (disableLayoutState)
       
   768             view->enableLayoutState();
       
   769     }
       
   770     m_layoutRoot = 0;
       
   771 
       
   772     m_frame->selection()->setNeedsLayout();
       
   773     m_frame->selection()->updateAppearance();
       
   774    
       
   775     m_layoutSchedulingEnabled = true;
       
   776 
       
   777     if (!subtree && !toRenderView(root)->printing())
       
   778         adjustViewSize();
       
   779 
       
   780     // Now update the positions of all layers.
       
   781     beginDeferredRepaints();
       
   782     IntPoint cachedOffset;
       
   783     layer->updateLayerPositions((m_doFullRepaint ? RenderLayer::DoFullRepaint : 0)
       
   784                                 | RenderLayer::CheckForRepaint
       
   785                                 | RenderLayer::IsCompositingUpdateRoot
       
   786                                 | RenderLayer::UpdateCompositingLayers,
       
   787                                 subtree ? 0 : &cachedOffset);
       
   788     endDeferredRepaints();
       
   789 
       
   790 #if USE(ACCELERATED_COMPOSITING)
       
   791     updateCompositingLayers();
       
   792 #endif
       
   793     
       
   794     m_layoutCount++;
       
   795 
       
   796 #if PLATFORM(MAC)
       
   797     if (AXObjectCache::accessibilityEnabled())
       
   798         root->document()->axObjectCache()->postNotification(root, AXObjectCache::AXLayoutComplete, true);
       
   799 #endif
       
   800 #if ENABLE(DASHBOARD_SUPPORT)
       
   801     updateDashboardRegions();
       
   802 #endif
       
   803 
       
   804     ASSERT(!root->needsLayout());
       
   805 
       
   806     setCanBlitOnScroll(!useSlowRepaints());
       
   807 
       
   808     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
       
   809         updateOverflowStatus(layoutWidth() < contentsWidth(),
       
   810                              layoutHeight() < contentsHeight());
       
   811 
       
   812     if (!m_postLayoutTasksTimer.isActive()) {
       
   813         // Calls resumeScheduledEvents()
       
   814         performPostLayoutTasks();
       
   815 
       
   816         if (!m_postLayoutTasksTimer.isActive() && needsLayout()) {
       
   817             // Post-layout widget updates or an event handler made us need layout again.
       
   818             // Lay out again, but this time defer widget updates and event dispatch until after
       
   819             // we return.
       
   820             m_postLayoutTasksTimer.startOneShot(0);
       
   821             pauseScheduledEvents();
       
   822             layout();
       
   823         }
       
   824     } else {
       
   825         resumeScheduledEvents();
       
   826         ASSERT(m_enqueueEvents);
       
   827     }
       
   828 
       
   829 #if ENABLE(INSPECTOR)
       
   830     if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
       
   831         timelineAgent->didLayout();
       
   832 #endif
       
   833 
       
   834     m_nestedLayoutCount--;
       
   835 }
       
   836 
       
   837 void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object)
       
   838 {
       
   839     if (!m_widgetUpdateSet)
       
   840         m_widgetUpdateSet.set(new RenderEmbeddedObjectSet);
       
   841 
       
   842     m_widgetUpdateSet->add(object);
       
   843 }
       
   844 
       
   845 void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object)
       
   846 {
       
   847     if (!m_widgetUpdateSet)
       
   848         return;
       
   849 
       
   850     m_widgetUpdateSet->remove(object);
       
   851 }
       
   852 
       
   853 void FrameView::setMediaType(const String& mediaType)
       
   854 {
       
   855     m_mediaType = mediaType;
       
   856 }
       
   857 
       
   858 String FrameView::mediaType() const
       
   859 {
       
   860     // See if we have an override type.
       
   861     String overrideType = m_frame->loader()->client()->overrideMediaType();
       
   862     if (!overrideType.isNull())
       
   863         return overrideType;
       
   864     return m_mediaType;
       
   865 }
       
   866 
       
   867 void FrameView::adjustMediaTypeForPrinting(bool printing)
       
   868 {
       
   869     if (printing) {
       
   870         if (m_mediaTypeWhenNotPrinting.isNull())
       
   871             m_mediaTypeWhenNotPrinting = mediaType();
       
   872             setMediaType("print");
       
   873     } else {
       
   874         if (!m_mediaTypeWhenNotPrinting.isNull())
       
   875             setMediaType(m_mediaTypeWhenNotPrinting);
       
   876         m_mediaTypeWhenNotPrinting = String();
       
   877     }
       
   878 }
       
   879 
       
   880 bool FrameView::useSlowRepaints() const
       
   881 {
       
   882     return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque;
       
   883 }
       
   884 
       
   885 bool FrameView::useSlowRepaintsIfNotOverlapped() const
       
   886 {
       
   887     return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque;
       
   888 }
       
   889 
       
   890 void FrameView::setUseSlowRepaints()
       
   891 {
       
   892     m_useSlowRepaints = true;
       
   893     setCanBlitOnScroll(false);
       
   894 }
       
   895 
       
   896 void FrameView::addSlowRepaintObject()
       
   897 {
       
   898     if (!m_slowRepaintObjectCount)
       
   899         setCanBlitOnScroll(false);
       
   900     m_slowRepaintObjectCount++;
       
   901 }
       
   902 
       
   903 void FrameView::removeSlowRepaintObject()
       
   904 {
       
   905     ASSERT(m_slowRepaintObjectCount > 0);
       
   906     m_slowRepaintObjectCount--;
       
   907     if (!m_slowRepaintObjectCount)
       
   908         setCanBlitOnScroll(!useSlowRepaints());
       
   909 }
       
   910 
       
   911 void FrameView::addFixedObject()
       
   912 {
       
   913     if (!m_fixedObjectCount && platformWidget())
       
   914         setCanBlitOnScroll(false);
       
   915     ++m_fixedObjectCount;
       
   916 }
       
   917 
       
   918 void FrameView::removeFixedObject()
       
   919 {
       
   920     ASSERT(m_fixedObjectCount > 0);
       
   921     --m_fixedObjectCount;
       
   922     if (!m_fixedObjectCount)
       
   923         setCanBlitOnScroll(!useSlowRepaints());
       
   924 }
       
   925 
       
   926 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
       
   927 {
       
   928     const size_t fixedObjectThreshold = 5;
       
   929 
       
   930     RenderBlock::PositionedObjectsListHashSet* positionedObjects = 0;
       
   931     if (RenderView* root = m_frame->contentRenderer())
       
   932         positionedObjects = root->positionedObjects();
       
   933 
       
   934     if (!positionedObjects || positionedObjects->isEmpty()) {
       
   935         hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
       
   936         return true;
       
   937     }
       
   938 
       
   939     // Get the rects of the fixed objects visible in the rectToScroll
       
   940     Vector<IntRect, fixedObjectThreshold> subRectToUpdate;
       
   941     bool updateInvalidatedSubRect = true;
       
   942     RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
       
   943     for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
       
   944         RenderBox* renderBox = *it;
       
   945         if (renderBox->style()->position() != FixedPosition)
       
   946             continue;
       
   947         IntRect updateRect = renderBox->layer()->repaintRectIncludingDescendants();
       
   948         updateRect = contentsToWindow(updateRect);
       
   949 
       
   950         updateRect.intersect(rectToScroll);
       
   951         if (!updateRect.isEmpty()) {
       
   952             if (subRectToUpdate.size() >= fixedObjectThreshold) {
       
   953                 updateInvalidatedSubRect = false;
       
   954                 break;
       
   955             }
       
   956             subRectToUpdate.append(updateRect);
       
   957         }
       
   958     }
       
   959 
       
   960     // Scroll the view
       
   961     if (updateInvalidatedSubRect) {
       
   962         // 1) scroll
       
   963         hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
       
   964 
       
   965         // 2) update the area of fixed objects that has been invalidated
       
   966         size_t fixObjectsCount = subRectToUpdate.size();
       
   967         for (size_t i = 0; i < fixObjectsCount; ++i) {
       
   968             IntRect updateRect = subRectToUpdate[i];
       
   969             IntRect scrolledRect = updateRect;
       
   970             scrolledRect.move(scrollDelta);
       
   971             updateRect.unite(scrolledRect);
       
   972             updateRect.intersect(rectToScroll);
       
   973             hostWindow()->invalidateContentsAndWindow(updateRect, false);
       
   974         }
       
   975         return true;
       
   976     }
       
   977 
       
   978     // the number of fixed objects exceed the threshold, we cannot use the fast path
       
   979     return false;
       
   980 }
       
   981 
       
   982 void FrameView::setIsOverlapped(bool isOverlapped)
       
   983 {
       
   984     if (isOverlapped == m_isOverlapped)
       
   985         return;
       
   986 
       
   987     m_isOverlapped = isOverlapped;
       
   988     setCanBlitOnScroll(!useSlowRepaints());
       
   989     
       
   990 #if USE(ACCELERATED_COMPOSITING)
       
   991     // Overlap can affect compositing tests, so if it changes, we need to trigger
       
   992     // a recalcStyle in the parent document.
       
   993     if (hasCompositedContent()) {
       
   994         if (Element* ownerElement = m_frame->document()->ownerElement())
       
   995             ownerElement->setNeedsStyleRecalc(SyntheticStyleChange);
       
   996     }
       
   997 #endif    
       
   998 }
       
   999 
       
  1000 void FrameView::setContentIsOpaque(bool contentIsOpaque)
       
  1001 {
       
  1002     if (contentIsOpaque == m_contentIsOpaque)
       
  1003         return;
       
  1004 
       
  1005     m_contentIsOpaque = contentIsOpaque;
       
  1006     setCanBlitOnScroll(!useSlowRepaints());
       
  1007 }
       
  1008 
       
  1009 void FrameView::restoreScrollbar()
       
  1010 {
       
  1011     setScrollbarsSuppressed(false);
       
  1012 }
       
  1013 
       
  1014 bool FrameView::scrollToFragment(const KURL& url)
       
  1015 {
       
  1016     // If our URL has no ref, then we have no place we need to jump to.
       
  1017     // OTOH If CSS target was set previously, we want to set it to 0, recalc
       
  1018     // and possibly repaint because :target pseudo class may have been
       
  1019     // set (see bug 11321).
       
  1020     if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget())
       
  1021         return false;
       
  1022 
       
  1023     String fragmentIdentifier = url.fragmentIdentifier();
       
  1024     if (scrollToAnchor(fragmentIdentifier))
       
  1025         return true;
       
  1026 
       
  1027     // Try again after decoding the ref, based on the document's encoding.
       
  1028     if (TextResourceDecoder* decoder = m_frame->document()->decoder())
       
  1029         return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding()));
       
  1030 
       
  1031     return false;
       
  1032 }
       
  1033 
       
  1034 bool FrameView::scrollToAnchor(const String& name)
       
  1035 {
       
  1036     ASSERT(m_frame->document());
       
  1037 
       
  1038     if (!m_frame->document()->haveStylesheetsLoaded()) {
       
  1039         m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
       
  1040         return false;
       
  1041     }
       
  1042 
       
  1043     m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false);
       
  1044 
       
  1045     Element* anchorNode = m_frame->document()->findAnchor(name);
       
  1046 
       
  1047 #if ENABLE(SVG)
       
  1048     if (m_frame->document()->isSVGDocument()) {
       
  1049         if (name.startsWith("xpointer(")) {
       
  1050             // We need to parse the xpointer reference here
       
  1051         } else if (name.startsWith("svgView(")) {
       
  1052             RefPtr<SVGSVGElement> svg = static_cast<SVGDocument*>(m_frame->document())->rootElement();
       
  1053             if (!svg->currentView()->parseViewSpec(name))
       
  1054                 return false;
       
  1055             svg->setUseCurrentView(true);
       
  1056         } else {
       
  1057             if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) {
       
  1058                 RefPtr<SVGViewElement> viewElement = anchorNode->hasTagName(SVGNames::viewTag) ? static_cast<SVGViewElement*>(anchorNode) : 0;
       
  1059                 if (viewElement.get()) {
       
  1060                     RefPtr<SVGSVGElement> svg = static_cast<SVGSVGElement*>(SVGLocatable::nearestViewportElement(viewElement.get()));
       
  1061                     svg->inheritViewAttributes(viewElement.get());
       
  1062                 }
       
  1063             }
       
  1064         }
       
  1065         // FIXME: need to decide which <svg> to focus on, and zoom to that one
       
  1066         // FIXME: need to actually "highlight" the viewTarget(s)
       
  1067     }
       
  1068 #endif
       
  1069 
       
  1070     m_frame->document()->setCSSTarget(anchorNode); // Setting to null will clear the current target.
       
  1071   
       
  1072     // Implement the rule that "" and "top" both mean top of page as in other browsers.
       
  1073     if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top")))
       
  1074         return false;
       
  1075 
       
  1076     maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document());
       
  1077     return true;
       
  1078 }
       
  1079 
       
  1080 void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
       
  1081 {
       
  1082     m_maintainScrollPositionAnchor = anchorNode;
       
  1083     if (!m_maintainScrollPositionAnchor)
       
  1084         return;
       
  1085 
       
  1086     // We need to update the layout before scrolling, otherwise we could
       
  1087     // really mess things up if an anchor scroll comes at a bad moment.
       
  1088     m_frame->document()->updateStyleIfNeeded();
       
  1089     // Only do a layout if changes have occurred that make it necessary.
       
  1090     if (m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout())
       
  1091         layout();
       
  1092     else
       
  1093         scrollToAnchor();
       
  1094 }
       
  1095 
       
  1096 void FrameView::setScrollPosition(const IntPoint& scrollPoint)
       
  1097 {
       
  1098     bool wasInProgrammaticScroll = m_inProgrammaticScroll;
       
  1099     m_inProgrammaticScroll = true;
       
  1100     m_maintainScrollPositionAnchor = 0;
       
  1101     ScrollView::setScrollPosition(scrollPoint);
       
  1102     m_inProgrammaticScroll = wasInProgrammaticScroll;
       
  1103 }
       
  1104 
       
  1105 void FrameView::scrollPositionChangedViaPlatformWidget()
       
  1106 {
       
  1107     frame()->eventHandler()->sendScrollEvent();
       
  1108     repaintFixedElementsAfterScrolling();
       
  1109 }
       
  1110 
       
  1111 void FrameView::repaintFixedElementsAfterScrolling()
       
  1112 {
       
  1113     // For fixed position elements, update widget positions and compositing layers after scrolling,
       
  1114     // but only if we're not inside of layout.
       
  1115     if (!m_nestedLayoutCount && hasFixedObjects()) {
       
  1116         if (RenderView* root = m_frame->contentRenderer()) {
       
  1117             root->updateWidgetPositions();
       
  1118             root->layer()->updateRepaintRectsAfterScroll();
       
  1119 #if USE(ACCELERATED_COMPOSITING)
       
  1120             root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
       
  1121 #endif
       
  1122         }
       
  1123     }
       
  1124 
       
  1125 #if USE(ACCELERATED_COMPOSITING)
       
  1126     if (RenderView* root = m_frame->contentRenderer()) {
       
  1127         if (root->usesCompositing())
       
  1128             root->compositor()->updateContentLayerScrollPosition(scrollPosition());
       
  1129     }
       
  1130 #endif
       
  1131 }
       
  1132 
       
  1133 HostWindow* FrameView::hostWindow() const
       
  1134 {
       
  1135     Page* page = frame() ? frame()->page() : 0;
       
  1136     if (!page)
       
  1137         return 0;
       
  1138     return page->chrome();
       
  1139 }
       
  1140 
       
  1141 const unsigned cRepaintRectUnionThreshold = 25;
       
  1142 
       
  1143 void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
       
  1144 {
       
  1145     ASSERT(!m_frame->document()->ownerElement());
       
  1146 
       
  1147     double delay = adjustedDeferredRepaintDelay();
       
  1148     if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
       
  1149         IntRect paintRect = r;
       
  1150         if (!paintsEntireContents())
       
  1151             paintRect.intersect(visibleContentRect());
       
  1152         if (paintRect.isEmpty())
       
  1153             return;
       
  1154         if (m_repaintCount == cRepaintRectUnionThreshold) {
       
  1155             IntRect unionedRect;
       
  1156             for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i)
       
  1157                 unionedRect.unite(m_repaintRects[i]);
       
  1158             m_repaintRects.clear();
       
  1159             m_repaintRects.append(unionedRect);
       
  1160         }
       
  1161         if (m_repaintCount < cRepaintRectUnionThreshold)
       
  1162             m_repaintRects.append(paintRect);
       
  1163         else
       
  1164             m_repaintRects[0].unite(paintRect);
       
  1165         m_repaintCount++;
       
  1166     
       
  1167         if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive())
       
  1168              m_deferredRepaintTimer.startOneShot(delay);
       
  1169         return;
       
  1170     }
       
  1171     
       
  1172     if (!immediate && isOffscreen() && !shouldUpdateWhileOffscreen())
       
  1173         return;
       
  1174 
       
  1175 #if ENABLE(TILED_BACKING_STORE)
       
  1176     if (frame()->tiledBackingStore()) {
       
  1177         frame()->tiledBackingStore()->invalidate(r);
       
  1178         return;
       
  1179     }
       
  1180 #endif
       
  1181     ScrollView::repaintContentRectangle(r, immediate);
       
  1182 }
       
  1183 
       
  1184 void FrameView::visibleContentsResized()
       
  1185 {
       
  1186     // We check to make sure the view is attached to a frame() as this method can
       
  1187     // be triggered before the view is attached by Frame::createView(...) setting
       
  1188     // various values such as setScrollBarModes(...) for example.  An ASSERT is
       
  1189     // triggered when a view is layout before being attached to a frame().
       
  1190     if (!frame()->view())
       
  1191         return;
       
  1192 
       
  1193     if (needsLayout())
       
  1194         layout();
       
  1195 }
       
  1196 
       
  1197 void FrameView::beginDeferredRepaints()
       
  1198 {
       
  1199     Page* page = m_frame->page();
       
  1200     if (page->mainFrame() != m_frame)
       
  1201         return page->mainFrame()->view()->beginDeferredRepaints();
       
  1202 
       
  1203     m_deferringRepaints++;
       
  1204 }
       
  1205 
       
  1206 
       
  1207 void FrameView::endDeferredRepaints()
       
  1208 {
       
  1209     Page* page = m_frame->page();
       
  1210     if (page->mainFrame() != m_frame)
       
  1211         return page->mainFrame()->view()->endDeferredRepaints();
       
  1212 
       
  1213     ASSERT(m_deferringRepaints > 0);
       
  1214 
       
  1215     if (--m_deferringRepaints)
       
  1216         return;
       
  1217     
       
  1218     if (m_deferredRepaintTimer.isActive())
       
  1219         return;
       
  1220 
       
  1221     if (double delay = adjustedDeferredRepaintDelay()) {
       
  1222         m_deferredRepaintTimer.startOneShot(delay);
       
  1223         return;
       
  1224     }
       
  1225     
       
  1226     doDeferredRepaints();
       
  1227 }
       
  1228 
       
  1229 void FrameView::checkStopDelayingDeferredRepaints()
       
  1230 {
       
  1231     if (!m_deferredRepaintTimer.isActive())
       
  1232         return;
       
  1233 
       
  1234     Document* document = m_frame->document();
       
  1235     if (document && (document->parsing() || document->docLoader()->requestCount()))
       
  1236         return;
       
  1237     
       
  1238     m_deferredRepaintTimer.stop();
       
  1239 
       
  1240     doDeferredRepaints();
       
  1241 }
       
  1242     
       
  1243 void FrameView::doDeferredRepaints()
       
  1244 {
       
  1245     ASSERT(!m_deferringRepaints);
       
  1246     if (isOffscreen() && !shouldUpdateWhileOffscreen()) {
       
  1247         m_repaintRects.clear();
       
  1248         m_repaintCount = 0;
       
  1249         return;
       
  1250     }
       
  1251     unsigned size = m_repaintRects.size();
       
  1252     for (unsigned i = 0; i < size; i++) {
       
  1253 #if ENABLE(TILED_BACKING_STORE)
       
  1254         if (frame()->tiledBackingStore()) {
       
  1255             frame()->tiledBackingStore()->invalidate(m_repaintRects[i]);
       
  1256             continue;
       
  1257         }
       
  1258 #endif
       
  1259         ScrollView::repaintContentRectangle(m_repaintRects[i], false);
       
  1260     }
       
  1261     m_repaintRects.clear();
       
  1262     m_repaintCount = 0;
       
  1263     
       
  1264     updateDeferredRepaintDelay();
       
  1265 }
       
  1266 
       
  1267 void FrameView::updateDeferredRepaintDelay()
       
  1268 {
       
  1269     Document* document = m_frame->document();
       
  1270     if (!document || (!document->parsing() && !document->docLoader()->requestCount())) {
       
  1271         m_deferredRepaintDelay = s_deferredRepaintDelay;
       
  1272         return;
       
  1273     }
       
  1274     if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) {
       
  1275         m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading;
       
  1276         if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading)
       
  1277             m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading;
       
  1278     }
       
  1279 }
       
  1280 
       
  1281 void FrameView::resetDeferredRepaintDelay()
       
  1282 {
       
  1283     m_deferredRepaintDelay = 0;
       
  1284     if (m_deferredRepaintTimer.isActive()) {
       
  1285         m_deferredRepaintTimer.stop();
       
  1286         if (!m_deferringRepaints)
       
  1287             doDeferredRepaints();
       
  1288     }
       
  1289 }
       
  1290 
       
  1291 double FrameView::adjustedDeferredRepaintDelay() const
       
  1292 {
       
  1293     if (!m_deferredRepaintDelay)
       
  1294         return 0;
       
  1295     double timeSinceLastPaint = currentTime() - m_lastPaintTime;
       
  1296     return max(0., m_deferredRepaintDelay - timeSinceLastPaint);
       
  1297 }
       
  1298     
       
  1299 void FrameView::deferredRepaintTimerFired(Timer<FrameView>*)
       
  1300 {
       
  1301     doDeferredRepaints();
       
  1302 }    
       
  1303 
       
  1304 void FrameView::layoutTimerFired(Timer<FrameView>*)
       
  1305 {
       
  1306 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
       
  1307     if (!m_frame->document()->ownerElement())
       
  1308         printf("Layout timer fired at %d\n", m_frame->document()->elapsedTime());
       
  1309 #endif
       
  1310     layout();
       
  1311 }
       
  1312 
       
  1313 void FrameView::scheduleRelayout()
       
  1314 {
       
  1315     // FIXME: We should assert the page is not in the page cache, but that is causing
       
  1316     // too many false assertions.  See <rdar://problem/7218118>.
       
  1317     ASSERT(m_frame->view() == this);
       
  1318 
       
  1319     if (m_layoutRoot) {
       
  1320         m_layoutRoot->markContainingBlocksForLayout(false);
       
  1321         m_layoutRoot = 0;
       
  1322     }
       
  1323     if (!m_layoutSchedulingEnabled)
       
  1324         return;
       
  1325     if (!needsLayout())
       
  1326         return;
       
  1327     if (!m_frame->document()->shouldScheduleLayout())
       
  1328         return;
       
  1329 
       
  1330     // When frame flattening is enabled, the contents of the frame affects layout of the parent frames.
       
  1331     // Also invalidate parent frame starting from the owner element of this frame.
       
  1332     if (m_frame->settings() && m_frame->settings()->frameFlatteningEnabled() && m_frame->ownerRenderer()) {
       
  1333         if (m_frame->ownerElement()->hasTagName(iframeTag) || m_frame->ownerElement()->hasTagName(frameTag))
       
  1334             m_frame->ownerRenderer()->setNeedsLayout(true, true);
       
  1335     }
       
  1336 
       
  1337     int delay = m_frame->document()->minimumLayoutDelay();
       
  1338     if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
       
  1339         unscheduleRelayout();
       
  1340     if (m_layoutTimer.isActive())
       
  1341         return;
       
  1342 
       
  1343     m_delayedLayout = delay != 0;
       
  1344 
       
  1345 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
       
  1346     if (!m_frame->document()->ownerElement())
       
  1347         printf("Scheduling layout for %d\n", delay);
       
  1348 #endif
       
  1349 
       
  1350     m_layoutTimer.startOneShot(delay * 0.001);
       
  1351 }
       
  1352 
       
  1353 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
       
  1354 {
       
  1355     for (RenderObject* r = descendant; r; r = r->container()) {
       
  1356         if (r == ancestor)
       
  1357             return true;
       
  1358     }
       
  1359     return false;
       
  1360 }
       
  1361 
       
  1362 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
       
  1363 {
       
  1364     ASSERT(m_frame->view() == this);
       
  1365 
       
  1366     if (m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout()) {
       
  1367         if (relayoutRoot)
       
  1368             relayoutRoot->markContainingBlocksForLayout(false);
       
  1369         return;
       
  1370     }
       
  1371 
       
  1372     if (layoutPending() || !m_layoutSchedulingEnabled) {
       
  1373         if (m_layoutRoot != relayoutRoot) {
       
  1374             if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) {
       
  1375                 // Keep the current root
       
  1376                 relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot);
       
  1377             } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) {
       
  1378                 // Re-root at relayoutRoot
       
  1379                 m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
       
  1380                 m_layoutRoot = relayoutRoot;
       
  1381             } else {
       
  1382                 // Just do a full relayout
       
  1383                 if (m_layoutRoot)
       
  1384                     m_layoutRoot->markContainingBlocksForLayout(false);
       
  1385                 m_layoutRoot = 0;
       
  1386                 relayoutRoot->markContainingBlocksForLayout(false);
       
  1387             }
       
  1388         }
       
  1389     } else if (m_layoutSchedulingEnabled) {
       
  1390         int delay = m_frame->document()->minimumLayoutDelay();
       
  1391         m_layoutRoot = relayoutRoot;
       
  1392         m_delayedLayout = delay != 0;
       
  1393         m_layoutTimer.startOneShot(delay * 0.001);
       
  1394     }
       
  1395 }
       
  1396 
       
  1397 bool FrameView::layoutPending() const
       
  1398 {
       
  1399     return m_layoutTimer.isActive();
       
  1400 }
       
  1401 
       
  1402 bool FrameView::needsLayout() const
       
  1403 {
       
  1404     // This can return true in cases where the document does not have a body yet.
       
  1405     // Document::shouldScheduleLayout takes care of preventing us from scheduling
       
  1406     // layout in that case.
       
  1407     if (!m_frame)
       
  1408         return false;
       
  1409     RenderView* root = m_frame->contentRenderer();
       
  1410     Document* document = m_frame->document();
       
  1411     return layoutPending()
       
  1412         || (root && root->needsLayout())
       
  1413         || m_layoutRoot
       
  1414         || (document && document->childNeedsStyleRecalc()) // can occur when using WebKit ObjC interface
       
  1415         || m_frame->needsReapplyStyles()
       
  1416         || (m_deferSetNeedsLayouts && m_setNeedsLayoutWasDeferred);
       
  1417 }
       
  1418 
       
  1419 void FrameView::setNeedsLayout()
       
  1420 {
       
  1421     if (m_deferSetNeedsLayouts) {
       
  1422         m_setNeedsLayoutWasDeferred = true;
       
  1423         return;
       
  1424     }
       
  1425     RenderView* root = m_frame->contentRenderer();
       
  1426     if (root)
       
  1427         root->setNeedsLayout(true);
       
  1428 }
       
  1429 
       
  1430 void FrameView::unscheduleRelayout()
       
  1431 {
       
  1432     if (!m_layoutTimer.isActive())
       
  1433         return;
       
  1434 
       
  1435 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
       
  1436     if (!m_frame->document()->ownerElement())
       
  1437         printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
       
  1438 #endif
       
  1439     
       
  1440     m_layoutTimer.stop();
       
  1441     m_delayedLayout = false;
       
  1442 }
       
  1443 
       
  1444 bool FrameView::isTransparent() const
       
  1445 {
       
  1446     return m_isTransparent;
       
  1447 }
       
  1448 
       
  1449 void FrameView::setTransparent(bool isTransparent)
       
  1450 {
       
  1451     m_isTransparent = isTransparent;
       
  1452 }
       
  1453 
       
  1454 Color FrameView::baseBackgroundColor() const
       
  1455 {
       
  1456     return m_baseBackgroundColor;
       
  1457 }
       
  1458 
       
  1459 void FrameView::setBaseBackgroundColor(Color bc)
       
  1460 {
       
  1461     if (!bc.isValid())
       
  1462         bc = Color::white;
       
  1463     m_baseBackgroundColor = bc;
       
  1464 }
       
  1465 
       
  1466 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
       
  1467 {
       
  1468     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext(m_frame.get())) {
       
  1469         FrameView* view = frame->view();
       
  1470         if (!view)
       
  1471             continue;
       
  1472 
       
  1473         view->setTransparent(transparent);
       
  1474         view->setBaseBackgroundColor(backgroundColor);
       
  1475     }
       
  1476 }
       
  1477 
       
  1478 bool FrameView::shouldUpdateWhileOffscreen() const
       
  1479 {
       
  1480     return m_shouldUpdateWhileOffscreen;
       
  1481 }
       
  1482 
       
  1483 void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
       
  1484 {
       
  1485     m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
       
  1486 }
       
  1487 
       
  1488 void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget)
       
  1489 {
       
  1490     if (!m_enqueueEvents) {
       
  1491         ExceptionCode ec = 0;
       
  1492         eventTarget->dispatchEvent(event, ec);
       
  1493         return;
       
  1494     }
       
  1495 
       
  1496     ScheduledEvent* scheduledEvent = new ScheduledEvent;
       
  1497     scheduledEvent->m_event = event;
       
  1498     scheduledEvent->m_eventTarget = eventTarget;
       
  1499     m_scheduledEvents.append(scheduledEvent);
       
  1500 }
       
  1501 
       
  1502 void FrameView::pauseScheduledEvents()
       
  1503 {
       
  1504     ASSERT(m_scheduledEvents.isEmpty() || m_enqueueEvents);
       
  1505     m_enqueueEvents++;
       
  1506 }
       
  1507 
       
  1508 void FrameView::resumeScheduledEvents()
       
  1509 {
       
  1510     m_enqueueEvents--;
       
  1511     if (!m_enqueueEvents)
       
  1512         dispatchScheduledEvents();
       
  1513     ASSERT(m_scheduledEvents.isEmpty() || m_enqueueEvents);
       
  1514 }
       
  1515 
       
  1516 void FrameView::scrollToAnchor()
       
  1517 {
       
  1518     RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
       
  1519     if (!anchorNode)
       
  1520         return;
       
  1521 
       
  1522     if (!anchorNode->renderer())
       
  1523         return;
       
  1524 
       
  1525     IntRect rect;
       
  1526     if (anchorNode != m_frame->document())
       
  1527         rect = anchorNode->getRect();
       
  1528 
       
  1529     // Scroll nested layers and frames to reveal the anchor.
       
  1530     // Align to the top and to the closest side (this matches other browsers).
       
  1531     anchorNode->renderer()->enclosingLayer()->scrollRectToVisible(rect, true, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
       
  1532 
       
  1533     if (AXObjectCache::accessibilityEnabled())
       
  1534         m_frame->document()->axObjectCache()->handleScrolledToAnchor(anchorNode.get());
       
  1535 
       
  1536     // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor.
       
  1537     m_maintainScrollPositionAnchor = anchorNode;
       
  1538 }
       
  1539 
       
  1540 bool FrameView::updateWidgets()
       
  1541 {
       
  1542     if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
       
  1543         return true;
       
  1544     
       
  1545     size_t size = m_widgetUpdateSet->size();
       
  1546 
       
  1547     Vector<RenderEmbeddedObject*> objects;
       
  1548     objects.reserveCapacity(size);
       
  1549 
       
  1550     RenderEmbeddedObjectSet::const_iterator end = m_widgetUpdateSet->end();
       
  1551     for (RenderEmbeddedObjectSet::const_iterator it = m_widgetUpdateSet->begin(); it != end; ++it) {
       
  1552         objects.uncheckedAppend(*it);
       
  1553         (*it)->ref();
       
  1554     }
       
  1555 
       
  1556     for (size_t i = 0; i < size; ++i) {
       
  1557         RenderEmbeddedObject* object = objects[i];
       
  1558 
       
  1559         // The object may have been destroyed, but our manual ref() keeps the object from being deleted.
       
  1560         object->updateWidget(false);
       
  1561         object->updateWidgetPosition();
       
  1562 
       
  1563         m_widgetUpdateSet->remove(object);
       
  1564     }
       
  1565 
       
  1566     RenderArena* arena = m_frame->document()->renderArena();
       
  1567     for (size_t i = 0; i < size; ++i)
       
  1568         objects[i]->deref(arena);
       
  1569     
       
  1570     return m_widgetUpdateSet->isEmpty();
       
  1571 }
       
  1572     
       
  1573 void FrameView::performPostLayoutTasks()
       
  1574 {
       
  1575     if (m_firstLayoutCallbackPending) {
       
  1576         m_firstLayoutCallbackPending = false;
       
  1577         m_frame->loader()->didFirstLayout();
       
  1578     }
       
  1579 
       
  1580     if (m_isVisuallyNonEmpty && m_firstVisuallyNonEmptyLayoutCallbackPending) {
       
  1581         m_firstVisuallyNonEmptyLayoutCallbackPending = false;
       
  1582         m_frame->loader()->didFirstVisuallyNonEmptyLayout();
       
  1583     }
       
  1584 
       
  1585     RenderView* root = m_frame->contentRenderer();
       
  1586 
       
  1587     root->updateWidgetPositions();
       
  1588     
       
  1589     for (unsigned i = 0; i < maxUpdateWidgetsIterations; i++) {
       
  1590         if (updateWidgets())
       
  1591             break;
       
  1592     }
       
  1593 
       
  1594     scrollToAnchor();
       
  1595 
       
  1596     resumeScheduledEvents();
       
  1597 
       
  1598     if (!root->printing()) {
       
  1599         IntSize currentSize = IntSize(width(), height());
       
  1600         float currentZoomFactor = root->style()->zoom();
       
  1601         bool resized = !m_firstLayout && (currentSize != m_lastLayoutSize || currentZoomFactor != m_lastZoomFactor);
       
  1602         m_lastLayoutSize = currentSize;
       
  1603         m_lastZoomFactor = currentZoomFactor;
       
  1604         if (resized)
       
  1605             m_frame->eventHandler()->sendResizeEvent();
       
  1606     }
       
  1607 }
       
  1608 
       
  1609 void FrameView::postLayoutTimerFired(Timer<FrameView>*)
       
  1610 {
       
  1611     performPostLayoutTasks();
       
  1612 }
       
  1613 
       
  1614 void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
       
  1615 {
       
  1616     if (!m_viewportRenderer)
       
  1617         return;
       
  1618     
       
  1619     if (m_overflowStatusDirty) {
       
  1620         m_horizontalOverflow = horizontalOverflow;
       
  1621         m_verticalOverflow = verticalOverflow;
       
  1622         m_overflowStatusDirty = false;
       
  1623         return;
       
  1624     }
       
  1625     
       
  1626     bool horizontalOverflowChanged = (m_horizontalOverflow != horizontalOverflow);
       
  1627     bool verticalOverflowChanged = (m_verticalOverflow != verticalOverflow);
       
  1628     
       
  1629     if (horizontalOverflowChanged || verticalOverflowChanged) {
       
  1630         m_horizontalOverflow = horizontalOverflow;
       
  1631         m_verticalOverflow = verticalOverflow;
       
  1632         
       
  1633         scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
       
  1634             verticalOverflowChanged, verticalOverflow),
       
  1635             m_viewportRenderer->node());
       
  1636     }
       
  1637     
       
  1638 }
       
  1639 
       
  1640 void FrameView::dispatchScheduledEvents()
       
  1641 {
       
  1642     if (m_scheduledEvents.isEmpty())
       
  1643         return;
       
  1644 
       
  1645     Vector<ScheduledEvent*> scheduledEventsCopy = m_scheduledEvents;
       
  1646     m_scheduledEvents.clear();
       
  1647     
       
  1648     Vector<ScheduledEvent*>::iterator end = scheduledEventsCopy.end();
       
  1649     for (Vector<ScheduledEvent*>::iterator it = scheduledEventsCopy.begin(); it != end; ++it) {
       
  1650         ScheduledEvent* scheduledEvent = *it;
       
  1651         
       
  1652         ExceptionCode ec = 0;
       
  1653         
       
  1654         // Only dispatch events to nodes that are in the document
       
  1655         if (scheduledEvent->m_eventTarget->inDocument())
       
  1656             scheduledEvent->m_eventTarget->dispatchEvent(scheduledEvent->m_event, ec);
       
  1657         
       
  1658         delete scheduledEvent;
       
  1659     }
       
  1660 }
       
  1661 
       
  1662 IntRect FrameView::windowClipRect(bool clipToContents) const
       
  1663 {
       
  1664     ASSERT(m_frame->view() == this);
       
  1665 
       
  1666     // Set our clip rect to be our contents.
       
  1667     IntRect clipRect = contentsToWindow(visibleContentRect(!clipToContents));
       
  1668     if (!m_frame || !m_frame->document() || !m_frame->document()->ownerElement())
       
  1669         return clipRect;
       
  1670 
       
  1671     // Take our owner element and get the clip rect from the enclosing layer.
       
  1672     Element* elt = m_frame->document()->ownerElement();
       
  1673     RenderLayer* layer = elt->renderer()->enclosingLayer();
       
  1674     // FIXME: layer should never be null, but sometimes seems to be anyway.
       
  1675     if (!layer)
       
  1676         return clipRect;
       
  1677     FrameView* parentView = elt->document()->view();
       
  1678     clipRect.intersect(parentView->windowClipRectForLayer(layer, true));
       
  1679     return clipRect;
       
  1680 }
       
  1681 
       
  1682 IntRect FrameView::windowClipRectForLayer(const RenderLayer* layer, bool clipToLayerContents) const
       
  1683 {
       
  1684     // If we have no layer, just return our window clip rect.
       
  1685     if (!layer)
       
  1686         return windowClipRect();
       
  1687 
       
  1688     // Apply the clip from the layer.
       
  1689     IntRect clipRect;
       
  1690     if (clipToLayerContents)
       
  1691         clipRect = layer->childrenClipRect();
       
  1692     else
       
  1693         clipRect = layer->selfClipRect();
       
  1694     clipRect = contentsToWindow(clipRect); 
       
  1695     return intersection(clipRect, windowClipRect());
       
  1696 }
       
  1697 
       
  1698 bool FrameView::isActive() const
       
  1699 {
       
  1700     Page* page = frame()->page();
       
  1701     return page && page->focusController()->isActive();
       
  1702 }
       
  1703 
       
  1704 void FrameView::valueChanged(Scrollbar* bar)
       
  1705 {
       
  1706     // Figure out if we really moved.
       
  1707     IntSize offset = scrollOffset();
       
  1708     ScrollView::valueChanged(bar);
       
  1709     if (offset != scrollOffset())
       
  1710         frame()->eventHandler()->sendScrollEvent();
       
  1711     frame()->loader()->client()->didChangeScrollOffset();
       
  1712 }
       
  1713 
       
  1714 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
       
  1715 {
       
  1716     // Add in our offset within the FrameView.
       
  1717     IntRect dirtyRect = rect;
       
  1718     dirtyRect.move(scrollbar->x(), scrollbar->y());
       
  1719     invalidateRect(dirtyRect);
       
  1720 }
       
  1721 
       
  1722 void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
       
  1723 {
       
  1724     tickmarks = frame()->document()->renderedRectsForMarkers(DocumentMarker::TextMatch);
       
  1725 }
       
  1726 
       
  1727 IntRect FrameView::windowResizerRect() const
       
  1728 {
       
  1729     Page* page = frame() ? frame()->page() : 0;
       
  1730     if (!page)
       
  1731         return IntRect();
       
  1732     return page->chrome()->windowResizerRect();
       
  1733 }
       
  1734 
       
  1735 #if ENABLE(DASHBOARD_SUPPORT)
       
  1736 void FrameView::updateDashboardRegions()
       
  1737 {
       
  1738     Document* document = m_frame->document();
       
  1739     if (!document->hasDashboardRegions())
       
  1740         return;
       
  1741     Vector<DashboardRegionValue> newRegions;
       
  1742     document->renderBox()->collectDashboardRegions(newRegions);
       
  1743     if (newRegions == document->dashboardRegions())
       
  1744         return;
       
  1745     document->setDashboardRegions(newRegions);
       
  1746     Page* page = m_frame->page();
       
  1747     if (!page)
       
  1748         return;
       
  1749     page->chrome()->client()->dashboardRegionsChanged();
       
  1750 }
       
  1751 #endif
       
  1752 
       
  1753 void FrameView::invalidateScrollCorner()
       
  1754 {
       
  1755     invalidateRect(scrollCornerRect());
       
  1756 }
       
  1757 
       
  1758 void FrameView::updateScrollCorner()
       
  1759 {
       
  1760     RenderObject* renderer = 0;
       
  1761     RefPtr<RenderStyle> cornerStyle;
       
  1762     
       
  1763     if (!scrollCornerRect().isEmpty()) {
       
  1764         // Try the <body> element first as a scroll corner source.
       
  1765         Document* doc = m_frame->document();
       
  1766         Element* body = doc ? doc->body() : 0;
       
  1767         if (body && body->renderer()) {
       
  1768             renderer = body->renderer();
       
  1769             cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
       
  1770         }
       
  1771         
       
  1772         if (!cornerStyle) {
       
  1773             // If the <body> didn't have a custom style, then the root element might.
       
  1774             Element* docElement = doc ? doc->documentElement() : 0;
       
  1775             if (docElement && docElement->renderer()) {
       
  1776                 renderer = docElement->renderer();
       
  1777                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
       
  1778             }
       
  1779         }
       
  1780         
       
  1781         if (!cornerStyle) {
       
  1782             // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
       
  1783             if (RenderPart* renderer = m_frame->ownerRenderer())
       
  1784                 cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
       
  1785         }
       
  1786     }
       
  1787 
       
  1788     if (cornerStyle) {
       
  1789         if (!m_scrollCorner)
       
  1790             m_scrollCorner = new (renderer->renderArena()) RenderScrollbarPart(renderer->document());
       
  1791         m_scrollCorner->setStyle(cornerStyle.release());
       
  1792         invalidateRect(scrollCornerRect());
       
  1793     } else if (m_scrollCorner) {
       
  1794         m_scrollCorner->destroy();
       
  1795         m_scrollCorner = 0;
       
  1796     }
       
  1797 }
       
  1798 
       
  1799 void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
       
  1800 {
       
  1801     if (context->updatingControlTints()) {
       
  1802         updateScrollCorner();
       
  1803         return;
       
  1804     }
       
  1805 
       
  1806     if (m_scrollCorner) {
       
  1807         m_scrollCorner->paintIntoRect(context, cornerRect.x(), cornerRect.y(), cornerRect);
       
  1808         return;
       
  1809     }
       
  1810 
       
  1811     ScrollView::paintScrollCorner(context, cornerRect);
       
  1812 }
       
  1813 
       
  1814 bool FrameView::hasCustomScrollbars() const
       
  1815 {
       
  1816     const HashSet<RefPtr<Widget> >* viewChildren = children();
       
  1817     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
       
  1818     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
       
  1819         Widget* widget = current->get();
       
  1820         if (widget->isFrameView()) {
       
  1821             if (static_cast<FrameView*>(widget)->hasCustomScrollbars())
       
  1822                 return true;
       
  1823         } else if (widget->isScrollbar()) {
       
  1824             Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
       
  1825             if (scrollbar->isCustomScrollbar())
       
  1826                 return true;
       
  1827         }
       
  1828     }
       
  1829 
       
  1830     return false;
       
  1831 }
       
  1832 
       
  1833 void FrameView::updateControlTints()
       
  1834 {
       
  1835     // This is called when control tints are changed from aqua/graphite to clear and vice versa.
       
  1836     // We do a "fake" paint, and when the theme gets a paint call, it can then do an invalidate.
       
  1837     // This is only done if the theme supports control tinting. It's up to the theme and platform
       
  1838     // to define when controls get the tint and to call this function when that changes.
       
  1839     
       
  1840     // Optimize the common case where we bring a window to the front while it's still empty.
       
  1841     if (!m_frame || m_frame->loader()->url().isEmpty())
       
  1842         return;
       
  1843 
       
  1844     if ((m_frame->contentRenderer() && m_frame->contentRenderer()->theme()->supportsControlTints()) || hasCustomScrollbars())  {
       
  1845         if (needsLayout())
       
  1846             layout();
       
  1847         PlatformGraphicsContext* const noContext = 0;
       
  1848         GraphicsContext context(noContext);
       
  1849         context.setUpdatingControlTints(true);
       
  1850         if (platformWidget())
       
  1851             paintContents(&context, visibleContentRect());
       
  1852         else
       
  1853             paint(&context, frameRect());
       
  1854     }
       
  1855 }
       
  1856 
       
  1857 bool FrameView::wasScrolledByUser() const
       
  1858 {
       
  1859     return m_wasScrolledByUser;
       
  1860 }
       
  1861 
       
  1862 void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
       
  1863 {
       
  1864     if (m_inProgrammaticScroll)
       
  1865         return;
       
  1866     m_maintainScrollPositionAnchor = 0;
       
  1867     m_wasScrolledByUser = wasScrolledByUser;
       
  1868 }
       
  1869 
       
  1870 void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
       
  1871 {
       
  1872     if (!frame())
       
  1873         return;
       
  1874 
       
  1875 #if ENABLE(INSPECTOR)
       
  1876     if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
       
  1877         timelineAgent->willPaint(rect);
       
  1878 #endif
       
  1879 
       
  1880     Document* document = frame()->document();
       
  1881 
       
  1882 #ifndef NDEBUG
       
  1883     bool fillWithRed;
       
  1884     if (document->printing())
       
  1885         fillWithRed = false; // Printing, don't fill with red (can't remember why).
       
  1886     else if (document->ownerElement())
       
  1887         fillWithRed = false; // Subframe, don't fill with red.
       
  1888     else if (isTransparent())
       
  1889         fillWithRed = false; // Transparent, don't fill with red.
       
  1890     else if (m_paintBehavior & PaintBehaviorSelectionOnly)
       
  1891         fillWithRed = false; // Selections are transparent, don't fill with red.
       
  1892     else if (m_nodeToDraw)
       
  1893         fillWithRed = false; // Element images are transparent, don't fill with red.
       
  1894     else
       
  1895         fillWithRed = true;
       
  1896     
       
  1897     if (fillWithRed)
       
  1898         p->fillRect(rect, Color(0xFF, 0, 0), DeviceColorSpace);
       
  1899 #endif
       
  1900 
       
  1901     bool isTopLevelPainter = !sCurrentPaintTimeStamp;
       
  1902     if (isTopLevelPainter)
       
  1903         sCurrentPaintTimeStamp = currentTime();
       
  1904     
       
  1905     RenderView* contentRenderer = frame()->contentRenderer();
       
  1906     if (!contentRenderer) {
       
  1907         LOG_ERROR("called Frame::paint with nil renderer");
       
  1908         return;
       
  1909     }
       
  1910 
       
  1911     ASSERT(!needsLayout());
       
  1912     if (needsLayout())
       
  1913         return;
       
  1914 
       
  1915 #if USE(ACCELERATED_COMPOSITING)
       
  1916     if (!p->paintingDisabled()) {
       
  1917         if (GraphicsLayer* rootLayer = contentRenderer->compositor()->rootPlatformLayer())
       
  1918             rootLayer->syncCompositingState();
       
  1919     }
       
  1920 #endif
       
  1921 
       
  1922     ASSERT(!m_isPainting);
       
  1923         
       
  1924     m_isPainting = true;
       
  1925         
       
  1926     // m_nodeToDraw is used to draw only one element (and its descendants)
       
  1927     RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
       
  1928 
       
  1929     PaintBehavior oldPaintBehavior = m_paintBehavior;
       
  1930     if (m_paintBehavior == PaintBehaviorNormal)
       
  1931         document->invalidateRenderedRectsForMarkersInRect(rect);
       
  1932 
       
  1933     if (document->printing())
       
  1934         m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
       
  1935 
       
  1936     contentRenderer->layer()->paint(p, rect, m_paintBehavior, eltRenderer);
       
  1937     
       
  1938     m_paintBehavior = oldPaintBehavior;
       
  1939     
       
  1940     m_isPainting = false;
       
  1941     m_lastPaintTime = currentTime();
       
  1942 
       
  1943 #if ENABLE(DASHBOARD_SUPPORT)
       
  1944     // Regions may have changed as a result of the visibility/z-index of element changing.
       
  1945     if (document->dashboardRegionsDirty())
       
  1946         updateDashboardRegions();
       
  1947 #endif
       
  1948 
       
  1949     if (isTopLevelPainter)
       
  1950         sCurrentPaintTimeStamp = 0;
       
  1951 
       
  1952 #if ENABLE(INSPECTOR)
       
  1953     if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
       
  1954         timelineAgent->didPaint();
       
  1955 #endif
       
  1956 }
       
  1957 
       
  1958 void FrameView::setPaintBehavior(PaintBehavior behavior)
       
  1959 {
       
  1960     m_paintBehavior = behavior;
       
  1961 }
       
  1962 
       
  1963 PaintBehavior FrameView::paintBehavior() const
       
  1964 {
       
  1965     return m_paintBehavior;
       
  1966 }
       
  1967 
       
  1968 bool FrameView::isPainting() const
       
  1969 {
       
  1970     return m_isPainting;
       
  1971 }
       
  1972 
       
  1973 void FrameView::setNodeToDraw(Node* node)
       
  1974 {
       
  1975     m_nodeToDraw = node;
       
  1976 }
       
  1977 
       
  1978 void FrameView::layoutIfNeededRecursive()
       
  1979 {
       
  1980     // We have to crawl our entire tree looking for any FrameViews that need
       
  1981     // layout and make sure they are up to date.
       
  1982     // Mac actually tests for intersection with the dirty region and tries not to
       
  1983     // update layout for frames that are outside the dirty region.  Not only does this seem
       
  1984     // pointless (since those frames will have set a zero timer to layout anyway), but
       
  1985     // it is also incorrect, since if two frames overlap, the first could be excluded from the dirty
       
  1986     // region but then become included later by the second frame adding rects to the dirty region
       
  1987     // when it lays out.
       
  1988 
       
  1989     if (needsLayout())
       
  1990         layout();
       
  1991 
       
  1992     const HashSet<RefPtr<Widget> >* viewChildren = children();
       
  1993     HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
       
  1994     for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
       
  1995         Widget* widget = (*current).get();
       
  1996         if (widget->isFrameView())
       
  1997             static_cast<FrameView*>(widget)->layoutIfNeededRecursive();
       
  1998     }
       
  1999 
       
  2000     // layoutIfNeededRecursive is called when we need to make sure layout is up-to-date before
       
  2001     // painting, so we need to flush out any deferred repaints too.
       
  2002     flushDeferredRepaints();
       
  2003 }
       
  2004     
       
  2005 void FrameView::flushDeferredRepaints()
       
  2006 {
       
  2007     if (!m_deferredRepaintTimer.isActive())
       
  2008         return;
       
  2009     m_deferredRepaintTimer.stop();
       
  2010     doDeferredRepaints();
       
  2011 }
       
  2012 
       
  2013 void FrameView::forceLayout(bool allowSubtree)
       
  2014 {
       
  2015     layout(allowSubtree);
       
  2016     // We cannot unschedule a pending relayout, since the force can be called with
       
  2017     // a tiny rectangle from a drawRect update.  By unscheduling we in effect
       
  2018     // "validate" and stop the necessary full repaint from occurring.  Basically any basic
       
  2019     // append/remove DHTML is broken by this call.  For now, I have removed the optimization
       
  2020     // until we have a better invalidation stategy. -dwh
       
  2021     //unscheduleRelayout();
       
  2022 }
       
  2023 
       
  2024 void FrameView::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth, bool _adjustViewSize)
       
  2025 {
       
  2026     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
       
  2027     // the state of things before and after the layout
       
  2028     RenderView *root = toRenderView(m_frame->document()->renderer());
       
  2029     if (root) {
       
  2030         // This magic is basically copied from khtmlview::print
       
  2031         int pageW = (int)ceilf(minPageWidth);
       
  2032         root->setWidth(pageW);
       
  2033         root->setNeedsLayoutAndPrefWidthsRecalc();
       
  2034         forceLayout();
       
  2035 
       
  2036         // If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the
       
  2037         // maximum page width, we will lay out to the maximum page width and clip extra content.
       
  2038         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
       
  2039         // implementation should not do this!
       
  2040         int rightmostPos = root->rightmostPosition();
       
  2041         if (rightmostPos > minPageWidth) {
       
  2042             pageW = std::min(rightmostPos, (int)ceilf(maxPageWidth));
       
  2043             root->setWidth(pageW);
       
  2044             root->setNeedsLayoutAndPrefWidthsRecalc();
       
  2045             forceLayout();
       
  2046         }
       
  2047     }
       
  2048 
       
  2049     if (_adjustViewSize)
       
  2050         adjustViewSize();
       
  2051 }
       
  2052 
       
  2053 void FrameView::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
       
  2054 {
       
  2055     RenderView* root = m_frame->contentRenderer();
       
  2056     if (root) {
       
  2057         // Use a context with painting disabled.
       
  2058         GraphicsContext context((PlatformGraphicsContext*)0);
       
  2059         root->setTruncatedAt((int)floorf(oldBottom));
       
  2060         IntRect dirtyRect(0, (int)floorf(oldTop), root->rightLayoutOverflow(), (int)ceilf(oldBottom - oldTop));
       
  2061         root->layer()->paint(&context, dirtyRect);
       
  2062         *newBottom = root->bestTruncatedAt();
       
  2063         if (*newBottom == 0)
       
  2064             *newBottom = oldBottom;
       
  2065     } else
       
  2066         *newBottom = oldBottom;
       
  2067 }
       
  2068 
       
  2069 IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
       
  2070 {
       
  2071     IntRect rect = renderer->localToAbsoluteQuad(FloatRect(rendererRect)).enclosingBoundingBox();
       
  2072 
       
  2073     // Convert from page ("absolute") to FrameView coordinates.
       
  2074     rect.move(-scrollX(), -scrollY());
       
  2075 
       
  2076     return rect;
       
  2077 }
       
  2078 
       
  2079 IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect& viewRect) const
       
  2080 {
       
  2081     IntRect rect = viewRect;
       
  2082     
       
  2083     // Convert from FrameView coords into page ("absolute") coordinates.
       
  2084     rect.move(scrollX(), scrollY());
       
  2085 
       
  2086     // FIXME: we don't have a way to map an absolute rect down to a local quad, so just
       
  2087     // move the rect for now.
       
  2088     rect.setLocation(roundedIntPoint(renderer->absoluteToLocal(rect.location(), false, true /* use transforms */)));
       
  2089     return rect;
       
  2090 }
       
  2091 
       
  2092 IntPoint FrameView::convertFromRenderer(const RenderObject* renderer, const IntPoint& rendererPoint) const
       
  2093 {
       
  2094     IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, false, true /* use transforms */));
       
  2095 
       
  2096     // Convert from page ("absolute") to FrameView coordinates.
       
  2097     point.move(-scrollX(), -scrollY());
       
  2098     return point;
       
  2099 }
       
  2100 
       
  2101 IntPoint FrameView::convertToRenderer(const RenderObject* renderer, const IntPoint& viewPoint) const
       
  2102 {
       
  2103     IntPoint point = viewPoint;
       
  2104     
       
  2105     // Convert from FrameView coords into page ("absolute") coordinates.
       
  2106     point += IntSize(scrollX(), scrollY());
       
  2107 
       
  2108     return roundedIntPoint(renderer->absoluteToLocal(point, false, true /* use transforms */));
       
  2109 }
       
  2110 
       
  2111 IntRect FrameView::convertToContainingView(const IntRect& localRect) const
       
  2112 {
       
  2113     if (const ScrollView* parentScrollView = parent()) {
       
  2114         if (parentScrollView->isFrameView()) {
       
  2115             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
       
  2116             // Get our renderer in the parent view
       
  2117             RenderPart* renderer = m_frame->ownerRenderer();
       
  2118             if (!renderer)
       
  2119                 return localRect;
       
  2120                 
       
  2121             IntRect rect(localRect);
       
  2122             // Add borders and padding??
       
  2123             rect.move(renderer->borderLeft() + renderer->paddingLeft(),
       
  2124                       renderer->borderTop() + renderer->paddingTop());
       
  2125             return parentView->convertFromRenderer(renderer, rect);
       
  2126         }
       
  2127         
       
  2128         return Widget::convertToContainingView(localRect);
       
  2129     }
       
  2130     
       
  2131     return localRect;
       
  2132 }
       
  2133 
       
  2134 IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
       
  2135 {
       
  2136     if (const ScrollView* parentScrollView = parent()) {
       
  2137         if (parentScrollView->isFrameView()) {
       
  2138             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
       
  2139 
       
  2140             // Get our renderer in the parent view
       
  2141             RenderPart* renderer = m_frame->ownerRenderer();
       
  2142             if (!renderer)
       
  2143                 return parentRect;
       
  2144 
       
  2145             IntRect rect = parentView->convertToRenderer(renderer, parentRect);
       
  2146             // Subtract borders and padding
       
  2147             rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
       
  2148                       -renderer->borderTop() - renderer->paddingTop());
       
  2149             return rect;
       
  2150         }
       
  2151         
       
  2152         return Widget::convertFromContainingView(parentRect);
       
  2153     }
       
  2154     
       
  2155     return parentRect;
       
  2156 }
       
  2157 
       
  2158 IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
       
  2159 {
       
  2160     if (const ScrollView* parentScrollView = parent()) {
       
  2161         if (parentScrollView->isFrameView()) {
       
  2162             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
       
  2163 
       
  2164             // Get our renderer in the parent view
       
  2165             RenderPart* renderer = m_frame->ownerRenderer();
       
  2166             if (!renderer)
       
  2167                 return localPoint;
       
  2168                 
       
  2169             IntPoint point(localPoint);
       
  2170 
       
  2171             // Add borders and padding
       
  2172             point.move(renderer->borderLeft() + renderer->paddingLeft(),
       
  2173                        renderer->borderTop() + renderer->paddingTop());
       
  2174             return parentView->convertFromRenderer(renderer, point);
       
  2175         }
       
  2176         
       
  2177         return Widget::convertToContainingView(localPoint);
       
  2178     }
       
  2179     
       
  2180     return localPoint;
       
  2181 }
       
  2182 
       
  2183 IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
       
  2184 {
       
  2185     if (const ScrollView* parentScrollView = parent()) {
       
  2186         if (parentScrollView->isFrameView()) {
       
  2187             const FrameView* parentView = static_cast<const FrameView*>(parentScrollView);
       
  2188 
       
  2189             // Get our renderer in the parent view
       
  2190             RenderPart* renderer = m_frame->ownerRenderer();
       
  2191             if (!renderer)
       
  2192                 return parentPoint;
       
  2193 
       
  2194             IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
       
  2195             // Subtract borders and padding
       
  2196             point.move(-renderer->borderLeft() - renderer->paddingLeft(),
       
  2197                        -renderer->borderTop() - renderer->paddingTop());
       
  2198             return point;
       
  2199         }
       
  2200         
       
  2201         return Widget::convertFromContainingView(parentPoint);
       
  2202     }
       
  2203     
       
  2204     return parentPoint;
       
  2205 }
       
  2206 
       
  2207 bool FrameView::shouldApplyTextZoom() const
       
  2208 {
       
  2209     if (m_zoomFactor == 1)
       
  2210         return false;
       
  2211     if (!m_frame)
       
  2212         return false;
       
  2213     Page* page = m_frame->page();
       
  2214     return page && page->settings()->zoomMode() == ZoomTextOnly;
       
  2215 }
       
  2216 
       
  2217 bool FrameView::shouldApplyPageZoom() const
       
  2218 {
       
  2219     if (m_zoomFactor == 1)
       
  2220         return false;
       
  2221     if (!m_frame)
       
  2222         return false;
       
  2223     Page* page = m_frame->page();
       
  2224     return page && page->settings()->zoomMode() == ZoomPage;
       
  2225 }
       
  2226 
       
  2227 void FrameView::setZoomFactor(float percent, ZoomMode mode)
       
  2228 {
       
  2229     if (!m_frame)
       
  2230         return;
       
  2231 
       
  2232     Page* page = m_frame->page();
       
  2233     if (!page)
       
  2234         return;
       
  2235 
       
  2236     if (m_zoomFactor == percent && page->settings()->zoomMode() == mode)
       
  2237         return;
       
  2238 
       
  2239     Document* document = m_frame->document();
       
  2240     if (!document)
       
  2241         return;
       
  2242 
       
  2243 #if ENABLE(SVG)
       
  2244     // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
       
  2245     // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
       
  2246     if (document->isSVGDocument()) {
       
  2247         if (!static_cast<SVGDocument*>(document)->zoomAndPanEnabled())
       
  2248             return;
       
  2249         if (document->renderer())
       
  2250             document->renderer()->setNeedsLayout(true);
       
  2251     }
       
  2252 #endif
       
  2253 
       
  2254     if (mode == ZoomPage) {
       
  2255         // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
       
  2256         IntPoint scrollPosition = this->scrollPosition();
       
  2257         float percentDifference = (percent / m_zoomFactor);
       
  2258         setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference));
       
  2259     }
       
  2260 
       
  2261     m_zoomFactor = percent;
       
  2262     page->settings()->setZoomMode(mode);
       
  2263 
       
  2264     document->recalcStyle(Node::Force);
       
  2265 
       
  2266     for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
       
  2267         if (FrameView* childView = child->view())
       
  2268             childView->setZoomFactor(m_zoomFactor, mode);
       
  2269     }
       
  2270 
       
  2271     if (document->renderer() && document->renderer()->needsLayout() && didFirstLayout())
       
  2272         layout();
       
  2273 }
       
  2274 
       
  2275 
       
  2276 // Normal delay
       
  2277 void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
       
  2278 {
       
  2279     s_deferredRepaintDelay = p;
       
  2280 }
       
  2281 
       
  2282 // Negative value would mean that first few repaints happen without a delay
       
  2283 void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p)
       
  2284 {
       
  2285     s_initialDeferredRepaintDelayDuringLoading = p;
       
  2286 }
       
  2287 
       
  2288 // The delay grows on each repaint to this maximum value
       
  2289 void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p)
       
  2290 {
       
  2291     s_maxDeferredRepaintDelayDuringLoading = p;
       
  2292 }
       
  2293 
       
  2294 // On each repaint the delay increases by this amount
       
  2295 void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p)
       
  2296 {
       
  2297     s_deferredRepaintDelayIncrementDuringLoading = p;
       
  2298 }
       
  2299 
       
  2300 } // namespace WebCore