summaryrefslogtreecommitdiffstats
path: root/WebCore
diff options
context:
space:
mode:
authorPatrick Scott <phanna@android.com>2009-09-29 14:11:16 -0400
committerPatrick Scott <phanna@android.com>2009-09-30 14:48:54 -0400
commit30027e43592c7246954056a89ce410c01d4dd86f (patch)
treebb8fa40a2f3bf31e04afadda893a098eb68e3947 /WebCore
parent418164343aa2437668796a013c1326c43ef318ac (diff)
downloadexternal_webkit-30027e43592c7246954056a89ce410c01d4dd86f.zip
external_webkit-30027e43592c7246954056a89ce410c01d4dd86f.tar.gz
external_webkit-30027e43592c7246954056a89ce410c01d4dd86f.tar.bz2
Fix the random crash around iframes.
The problem is that if updateWidgetPosition calls layout, the FrameView will layout with 0x0 dimensions. Then, we resize the view and try to relayout. This causes the body to be marked as needing a layout. But, the body does not get a chance to relayout. If updateWidgetPosition does not layout, the view size will match and the body will not be marked for layout. This makes everything sane after layout of the iframe. The root of the problem is that we are calling FrameView::layout() while in the midst of a layout. This is causing a child RenderObject to need a layout without the parent object needing a layout. We avoid this by not laying out until we set the FrameView dimensions. Bug: 2048855, 2134215
Diffstat (limited to 'WebCore')
-rw-r--r--WebCore/rendering/RenderPartObject.cpp26
-rw-r--r--WebCore/rendering/RenderWidget.cpp2
2 files changed, 24 insertions, 4 deletions
diff --git a/WebCore/rendering/RenderPartObject.cpp b/WebCore/rendering/RenderPartObject.cpp
index 5f6d903..72298c6 100644
--- a/WebCore/rendering/RenderPartObject.cpp
+++ b/WebCore/rendering/RenderPartObject.cpp
@@ -386,11 +386,13 @@ void RenderPartObject::layout()
h = 0;
if (w != view->width() || h != view->height()) {
view->resize(w, h);
- root->setNeedsLayout(true, false);
}
+
// Layout the view.
- if (view->needsLayout())
+ do {
view->layout();
+ } while (view->layoutPending() || root->needsLayout());
+
int contentHeight = view->contentsHeight();
int contentWidth = view->contentsWidth();
// Only change the width or height if scrollbars are visible or
@@ -403,6 +405,20 @@ void RenderPartObject::layout()
// Update one last time
updateWidgetPosition();
+
+#if !ASSERT_DISABLED
+ ASSERT(!view->layoutPending());
+ ASSERT(!root->needsLayout());
+ // Sanity check when assertions are enabled.
+ RenderObject* c = root->nextInPreOrder();
+ while (c) {
+ ASSERT(!c->needsLayout());
+ c = c->nextInPreOrder();
+ }
+ Node* body = document()->body();
+ if (body)
+ ASSERT(!body->renderer()->needsLayout());
+#endif
}
}
}
@@ -446,8 +462,9 @@ void RenderPartObject::calcWidth() {
updateWidgetPosition();
// Layout to get the content width
- while (view->needsLayout())
+ do {
view->layout();
+ } while (view->layoutPending() || root->needsLayout());
setWidth(max(width(), view->contentsWidth() + extraWidth));
@@ -471,8 +488,9 @@ void RenderPartObject::calcHeight() {
updateWidgetPosition();
// Layout to get the content height
- while (view->needsLayout())
+ do {
view->layout();
+ } while (view->layoutPending() || root->needsLayout());
int extraHeight = paddingTop() + paddingBottom() + borderTop() + borderBottom();
setHeight(max(width(), view->contentsHeight() + extraHeight));
diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp
index 16526ca..36f4fed 100644
--- a/WebCore/rendering/RenderWidget.cpp
+++ b/WebCore/rendering/RenderWidget.cpp
@@ -255,6 +255,7 @@ void RenderWidget::updateWidgetPosition()
deref(arena);
}
+#ifndef FLATTEN_IFRAME
// if the frame bounds got changed, or if view needs layout (possibly indicating
// content size is wrong) we have to do a layout to set the right widget size
if (m_widget->isFrameView()) {
@@ -262,6 +263,7 @@ void RenderWidget::updateWidgetPosition()
if (boundsChanged || frameView->needsLayout())
frameView->layout();
}
+#endif
}
void RenderWidget::setSelectionState(SelectionState state)