summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/page/FrameView.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/page/FrameView.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameView.cpp266
1 files changed, 201 insertions, 65 deletions
diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp
index 4c3a0ab..45764de 100644
--- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp
+++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp
@@ -29,6 +29,7 @@
#include "AXObjectCache.h"
#include "CSSStyleSelector.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "DocLoader.h"
#include "EventHandler.h"
@@ -45,8 +46,8 @@
#include "HTMLNames.h"
#include "InspectorTimelineAgent.h"
#include "OverflowEvent.h"
+#include "RenderEmbeddedObject.h"
#include "RenderPart.h"
-#include "RenderPartObject.h"
#include "RenderScrollbar.h"
#include "RenderScrollbarPart.h"
#include "RenderTheme.h"
@@ -69,6 +70,9 @@
#include "SVGViewSpec.h"
#endif
+#if ENABLE(TILED_BACKING_STORE)
+#include "TiledBackingStore.h"
+#endif
namespace WebCore {
@@ -98,13 +102,14 @@ static const double deferredRepaintDelayIncrementDuringLoading = 0;
// The maximum number of updateWidgets iterations that should be done before returning.
static const unsigned maxUpdateWidgetsIterations = 2;
-struct ScheduledEvent {
+struct ScheduledEvent : Noncopyable {
RefPtr<Event> m_event;
RefPtr<Node> m_eventTarget;
};
FrameView::FrameView(Frame* frame)
: m_frame(frame)
+ , m_canHaveScrollbars(true)
, m_slowRepaintObjectCount(0)
, m_fixedObjectCount(0)
, m_layoutTimer(this, &FrameView::layoutTimerFired)
@@ -198,7 +203,7 @@ void FrameView::reset()
m_deferredRepaintDelay = initialDeferredRepaintDelayDuringLoading;
m_deferredRepaintTimer.stop();
m_lastPaintTime = 0;
- m_paintRestriction = PaintRestrictionNone;
+ m_paintBehavior = PaintBehaviorNormal;
m_isPainting = false;
m_isVisuallyNonEmpty = false;
m_firstVisuallyNonEmptyLayoutCallbackPending = true;
@@ -220,7 +225,10 @@ void FrameView::resetScrollbars()
// Reset the document's scrollbars back to our defaults before we yield the floor.
m_firstLayout = true;
setScrollbarsSuppressed(true);
- setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
+ if (m_canHaveScrollbars)
+ setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
+ else
+ setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
setScrollbarsSuppressed(false);
}
@@ -288,7 +296,7 @@ void FrameView::invalidateRect(const IntRect& rect)
{
if (!parent()) {
if (hostWindow())
- hostWindow()->repaint(rect, true);
+ hostWindow()->invalidateContentsAndWindow(rect, false /*immediate*/);
return;
}
@@ -317,6 +325,40 @@ void FrameView::setMarginHeight(int h)
m_margins.setHeight(h);
}
+bool FrameView::avoidScrollbarCreation()
+{
+ ASSERT(m_frame);
+
+ // with frame flattening no subframe can have scrollbars
+ // but we also cannot turn scrollbars of as we determine
+ // our flattening policy using that.
+
+ if (!m_frame->ownerElement())
+ return false;
+
+ if (!m_frame->settings() || m_frame->settings()->frameFlatteningEnabled())
+ return true;
+
+ return false;
+}
+
+void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
+{
+ m_canHaveScrollbars = canHaveScrollbars;
+ ScrollView::setCanHaveScrollbars(canHaveScrollbars);
+}
+
+void FrameView::updateCanHaveScrollbars()
+{
+ ScrollbarMode hMode;
+ ScrollbarMode vMode;
+ scrollbarModes(hMode, vMode);
+ if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
+ m_canHaveScrollbars = false;
+ else
+ m_canHaveScrollbars = true;
+}
+
PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
{
// FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
@@ -325,7 +367,7 @@ PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientatio
// Try the <body> element first as a scrollbar source.
Element* body = doc ? doc->body() : 0;
if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR))
- return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderBox());
+ return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderer()->enclosingBox());
// If the <body> didn't have a custom style, then the root element might.
Element* docElement = doc ? doc->documentElement() : 0;
@@ -343,6 +385,9 @@ PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientatio
void FrameView::setContentsSize(const IntSize& size)
{
+ if (size == contentsSize())
+ return;
+
m_deferSetNeedsLayouts++;
ScrollView::setContentsSize(size);
@@ -352,7 +397,7 @@ void FrameView::setContentsSize(const IntSize& size)
return;
page->chrome()->contentsSizeChanged(frame(), size); //notify only
-
+
m_deferSetNeedsLayouts--;
if (!m_deferSetNeedsLayouts)
@@ -365,6 +410,7 @@ void FrameView::adjustViewSize()
RenderView* root = m_frame->contentRenderer();
if (!root)
return;
+
setContentsSize(IntSize(root->rightLayoutOverflow(), root->bottomLayoutOverflow()));
}
@@ -415,12 +461,12 @@ void FrameView::updateCompositingLayers()
return;
// This call will make sure the cached hasAcceleratedCompositing is updated from the pref
- view->compositor()->cacheAcceleratedCompositingEnabledFlag();
+ view->compositor()->cacheAcceleratedCompositingFlags();
if (!view->usesCompositing())
return;
- view->compositor()->updateCompositingLayers();
+ view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange);
}
void FrameView::setNeedsOneShotDrawingSynchronization()
@@ -458,8 +504,22 @@ bool FrameView::syncCompositingStateRecursive()
}
}
return allSubframesSynced;
-#endif // USE(ACCELERATED_COMPOSITING)
+#else // USE(ACCELERATED_COMPOSITING)
+ return true;
+#endif
+}
+
+bool FrameView::isSoftwareRenderable() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ RenderView* view = m_frame->contentRenderer();
+ if (!view)
+ return true;
+
+ return !view->compositor()->has3DContent();
+#else
return true;
+#endif
}
void FrameView::didMoveOnscreen()
@@ -505,9 +565,8 @@ void FrameView::layout(bool allowSubtree)
if (isPainting())
return;
-#if ENABLE(INSPECTOR)
- InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
- if (timelineAgent)
+#if ENABLE(INSPECTOR)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
timelineAgent->willLayout();
#endif
@@ -564,27 +623,42 @@ void FrameView::layout(bool allowSubtree)
ScrollbarMode hMode;
ScrollbarMode vMode;
- scrollbarModes(hMode, vMode);
+ if (m_canHaveScrollbars) {
+ hMode = ScrollbarAuto;
+ vMode = ScrollbarAuto;
+ } else {
+ hMode = ScrollbarAlwaysOff;
+ vMode = ScrollbarAlwaysOff;
+ }
if (!subtree) {
- RenderObject* rootRenderer = document->documentElement() ? document->documentElement()->renderer() : 0;
+ Node* documentElement = document->documentElement();
+ RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
Node* body = document->body();
if (body && body->renderer()) {
- if (body->hasTagName(framesetTag)) {
+ if (body->hasTagName(framesetTag) && !m_frame->settings()->frameFlatteningEnabled()) {
body->renderer()->setChildNeedsLayout(true);
vMode = ScrollbarAlwaysOff;
hMode = ScrollbarAlwaysOff;
} else if (body->hasTagName(bodyTag)) {
- if (!m_firstLayout && m_size.height() != layoutHeight()
- && toRenderBox(body->renderer())->stretchesToViewHeight())
+ if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewHeight())
body->renderer()->setChildNeedsLayout(true);
// It's sufficient to just check the X overflow,
// since it's illegal to have visible in only one direction.
RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
applyOverflowToViewport(o, hMode, vMode);
}
- } else if (rootRenderer)
+ } else if (rootRenderer) {
+#if ENABLE(SVG)
+ if (documentElement->isSVGElement()) {
+ if (!m_firstLayout && (m_size.width() != layoutWidth() || m_size.height() != layoutHeight()))
+ rootRenderer->setChildNeedsLayout(true);
+ } else
+ applyOverflowToViewport(rootRenderer, hMode, vMode);
+#else
applyOverflowToViewport(rootRenderer, hMode, vMode);
+#endif
+ }
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (m_firstLayout && !document->ownerElement())
printf("Elapsed time before first layout: %d\n", document->elapsedTime());
@@ -629,8 +703,14 @@ void FrameView::layout(bool allowSubtree)
pauseScheduledEvents();
- if (subtree)
- root->view()->pushLayoutState(root);
+ bool disableLayoutState = false;
+ if (subtree) {
+ RenderView* view = root->view();
+ disableLayoutState = view->shouldDisableLayoutStateForSubtree(root);
+ view->pushLayoutState(root);
+ if (disableLayoutState)
+ view->disableLayoutState();
+ }
m_midLayout = true;
beginDeferredRepaints();
@@ -638,11 +718,16 @@ void FrameView::layout(bool allowSubtree)
endDeferredRepaints();
m_midLayout = false;
- if (subtree)
- root->view()->popLayoutState();
+ if (subtree) {
+ RenderView* view = root->view();
+ view->popLayoutState();
+ if (disableLayoutState)
+ view->enableLayoutState();
+ }
m_layoutRoot = 0;
- m_frame->invalidateSelection();
+ m_frame->selection()->setNeedsLayout();
+ m_frame->selection()->updateAppearance();
m_layoutSchedulingEnabled = true;
@@ -697,22 +782,22 @@ void FrameView::layout(bool allowSubtree)
}
#if ENABLE(INSPECTOR)
- if (timelineAgent)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
timelineAgent->didLayout();
#endif
m_nestedLayoutCount--;
}
-void FrameView::addWidgetToUpdate(RenderPartObject* object)
+void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object)
{
if (!m_widgetUpdateSet)
- m_widgetUpdateSet.set(new HashSet<RenderPartObject*>);
+ m_widgetUpdateSet.set(new RenderEmbeddedObjectSet);
m_widgetUpdateSet->add(object);
}
-void FrameView::removeWidgetToUpdate(RenderPartObject* object)
+void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object)
{
if (!m_widgetUpdateSet)
return;
@@ -734,11 +819,29 @@ String FrameView::mediaType() const
return m_mediaType;
}
+void FrameView::adjustMediaTypeForPrinting(bool printing)
+{
+ if (printing) {
+ if (m_mediaTypeWhenNotPrinting.isNull())
+ m_mediaTypeWhenNotPrinting = mediaType();
+ setMediaType("print");
+ } else {
+ if (!m_mediaTypeWhenNotPrinting.isNull())
+ setMediaType(m_mediaTypeWhenNotPrinting);
+ m_mediaTypeWhenNotPrinting = String();
+ }
+}
+
bool FrameView::useSlowRepaints() const
{
return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque;
}
+bool FrameView::useSlowRepaintsIfNotOverlapped() const
+{
+ return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque;
+}
+
void FrameView::setUseSlowRepaints()
{
m_useSlowRepaints = true;
@@ -770,12 +873,12 @@ void FrameView::addFixedObject()
void FrameView::removeFixedObject()
{
ASSERT(m_fixedObjectCount > 0);
- m_fixedObjectCount--;
+ --m_fixedObjectCount;
if (!m_fixedObjectCount)
setCanBlitOnScroll(!useSlowRepaints());
}
-void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
{
const size_t fixedObjectThreshold = 5;
@@ -785,7 +888,7 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
if (!positionedObjects || positionedObjects->isEmpty()) {
hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
- return;
+ return true;
}
// Get the rects of the fixed objects visible in the rectToScroll
@@ -814,7 +917,7 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
// 1) scroll
hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
- // 2) update the area of fixed objets that has been invalidated
+ // 2) update the area of fixed objects that has been invalidated
size_t fixObjectsCount = subRectToUpdate.size();
for (size_t i = 0; i < fixObjectsCount; ++i) {
IntRect updateRect = subRectToUpdate[i];
@@ -822,14 +925,13 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
scrolledRect.move(scrollDelta);
updateRect.unite(scrolledRect);
updateRect.intersect(rectToScroll);
- hostWindow()->repaint(updateRect, true, false, true);
+ hostWindow()->invalidateContentsAndWindow(updateRect, false);
}
- } else {
- // the number of fixed objects exceed the threshold, so we repaint everything.
- IntRect updateRect = clipRect;
- updateRect.intersect(rectToScroll);
- hostWindow()->repaint(updateRect, true, false, true);
+ return true;
}
+
+ // the number of fixed objects exceed the threshold, we cannot use the fast path
+ return false;
}
void FrameView::setIsOverlapped(bool isOverlapped)
@@ -959,16 +1061,18 @@ void FrameView::scrollPositionChanged()
{
frame()->eventHandler()->sendScrollEvent();
+ // For fixed position elements, update widget positions and compositing layers after scrolling,
+ // but only if we're not inside of layout.
+ // FIXME: we could skip this if we knew the page had no fixed position elements.
+ if (!m_nestedLayoutCount) {
+ if (RenderView* root = m_frame->contentRenderer()) {
+ root->updateWidgetPositions();
#if USE(ACCELERATED_COMPOSITING)
- // We need to update layer positions after scrolling to account for position:fixed layers.
- Document* document = m_frame->document();
- if (!document)
- return;
-
- RenderLayer* layer = document->renderer() ? document->renderer()->enclosingLayer() : 0;
- if (layer)
- layer->updateLayerPositions(RenderLayer::UpdateCompositingLayers);
+ if (root->usesCompositing())
+ root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
#endif
+ }
+ }
}
HostWindow* FrameView::hostWindow() const
@@ -987,9 +1091,10 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
double delay = adjustedDeferredRepaintDelay();
if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
- IntRect visibleContent = visibleContentRect();
- visibleContent.intersect(r);
- if (visibleContent.isEmpty())
+ IntRect paintRect = r;
+ if (!paintsEntireContents())
+ paintRect.intersect(visibleContentRect());
+ if (paintRect.isEmpty())
return;
if (m_repaintCount == cRepaintRectUnionThreshold) {
IntRect unionedRect;
@@ -999,9 +1104,9 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
m_repaintRects.append(unionedRect);
}
if (m_repaintCount < cRepaintRectUnionThreshold)
- m_repaintRects.append(visibleContent);
+ m_repaintRects.append(paintRect);
else
- m_repaintRects[0].unite(visibleContent);
+ m_repaintRects[0].unite(paintRect);
m_repaintCount++;
if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive())
@@ -1012,6 +1117,12 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
if (!immediate && isOffscreen() && !shouldUpdateWhileOffscreen())
return;
+#if ENABLE(TILED_BACKING_STORE)
+ if (frame()->tiledBackingStore()) {
+ frame()->tiledBackingStore()->invalidate(r);
+ return;
+ }
+#endif
ScrollView::repaintContentRectangle(r, immediate);
}
@@ -1083,8 +1194,15 @@ void FrameView::doDeferredRepaints()
return;
}
unsigned size = m_repaintRects.size();
- for (unsigned i = 0; i < size; i++)
+ for (unsigned i = 0; i < size; i++) {
+#if ENABLE(TILED_BACKING_STORE)
+ if (frame()->tiledBackingStore()) {
+ frame()->tiledBackingStore()->invalidate(m_repaintRects[i]);
+ continue;
+ }
+#endif
ScrollView::repaintContentRectangle(m_repaintRects[i], false);
+ }
m_repaintRects.clear();
m_repaintCount = 0;
@@ -1154,6 +1272,13 @@ void FrameView::scheduleRelayout()
if (!m_frame->document()->shouldScheduleLayout())
return;
+ // When frame flattening is enabled, the contents of the frame affects layout of the parent frames.
+ // Also invalidate parent frame starting from the owner element of this frame.
+ if (m_frame->settings()->frameFlatteningEnabled() && m_frame->ownerRenderer()) {
+ if (m_frame->ownerElement()->hasTagName(iframeTag) || m_frame->ownerElement()->hasTagName(frameTag))
+ m_frame->ownerRenderer()->setNeedsLayout(true, true);
+ }
+
int delay = m_frame->document()->minimumLayoutDelay();
if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
unscheduleRelayout();
@@ -1363,11 +1488,11 @@ bool FrameView::updateWidgets()
if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
return true;
- Vector<RenderPartObject*> objectVector;
+ Vector<RenderEmbeddedObject*> objectVector;
copyToVector(*m_widgetUpdateSet, objectVector);
size_t size = objectVector.size();
for (size_t i = 0; i < size; ++i) {
- RenderPartObject* object = objectVector[i];
+ RenderEmbeddedObject* object = objectVector[i];
object->updateWidget(false);
// updateWidget() can destroy the RenderPartObject, so we need to make sure it's
@@ -1519,6 +1644,7 @@ void FrameView::valueChanged(Scrollbar* bar)
ScrollView::valueChanged(bar);
if (offset != scrollOffset())
frame()->eventHandler()->sendScrollEvent();
+ frame()->loader()->client()->didChangeScrollOffset();
}
void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
@@ -1683,9 +1809,8 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
return;
#if ENABLE(INSPECTOR)
- InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
- if (timelineAgent)
- timelineAgent->willPaint();
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
+ timelineAgent->willPaint(rect);
#endif
Document* document = frame()->document();
@@ -1698,7 +1823,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
fillWithRed = false; // Subframe, don't fill with red.
else if (isTransparent())
fillWithRed = false; // Transparent, don't fill with red.
- else if (m_paintRestriction == PaintRestrictionSelectionOnly || m_paintRestriction == PaintRestrictionSelectionOnlyBlackText)
+ else if (m_paintBehavior & PaintBehaviorSelectionOnly)
fillWithRed = false; // Selections are transparent, don't fill with red.
else if (m_nodeToDraw)
fillWithRed = false; // Element images are transparent, don't fill with red.
@@ -1706,7 +1831,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
fillWithRed = true;
if (fillWithRed)
- p->fillRect(rect, Color(0xFF, 0, 0));
+ p->fillRect(rect, Color(0xFF, 0, 0), DeviceColorSpace);
#endif
bool isTopLevelPainter = !sCurrentPaintTimeStamp;
@@ -1736,9 +1861,15 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
// m_nodeToDraw is used to draw only one element (and its descendants)
RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
- if (m_paintRestriction == PaintRestrictionNone)
+
+ PaintBehavior paintBehavior = m_paintBehavior;
+ if (paintBehavior == PaintBehaviorNormal)
document->invalidateRenderedRectsForMarkersInRect(rect);
- contentRenderer->layer()->paint(p, rect, m_paintRestriction, eltRenderer);
+
+ if (document->printing())
+ paintBehavior |= PaintBehaviorFlattenCompositingLayers;
+
+ contentRenderer->layer()->paint(p, rect, paintBehavior, eltRenderer);
m_isPainting = false;
m_lastPaintTime = currentTime();
@@ -1753,16 +1884,21 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
sCurrentPaintTimeStamp = 0;
#if ENABLE(INSPECTOR)
- if (timelineAgent)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
timelineAgent->didPaint();
#endif
}
-void FrameView::setPaintRestriction(PaintRestriction pr)
+void FrameView::setPaintBehavior(PaintBehavior behavior)
{
- m_paintRestriction = pr;
+ m_paintBehavior = behavior;
}
-
+
+PaintBehavior FrameView::paintBehavior() const
+{
+ return m_paintBehavior;
+}
+
bool FrameView::isPainting() const
{
return m_isPainting;