Reviewed by Darin Adler.
- fix <rdar://problem/
5619240> REGRESSION (Leopard-r28069): Reproducible crash with a Mootools-based calendar picker (jump to null in FrameView::layout)
Test: fast/dynamic/subtree-common-root.html
* page/FrameView.cpp:
(WebCore::FrameView::layoutRoot): Added a parameter to let this method
return the layout root for a pending layout as well.
(WebCore::FrameView::scheduleRelayoutOfSubtree): Pass the new root
to markContainingBlocksForLayout(). Otherwise,
markContainingBlocksForLayout() could mark past the new root, if it had
previously been marked as having a normal child needing layout and then
was reached via a positioned child.
* page/FrameView.h:
* rendering/RenderBox.cpp:
(WebCore::RenderBox::calcWidth):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::~RenderObject): Fixed the ASSERT so that
it would really catch deletion of the layout root.
(WebCore::RenderObject::markContainingBlocksForLayout): Added the
newRoot parameter, which tells this method where to stop marking.
* rendering/RenderObject.h:
LayoutTests:
Reviewed by Darin Adler.
- test for <rdar://problem/
5619240> REGRESSION (Leopard-r28069): Reproducible crash with a Mootools-based calendar picker (jump to null in FrameView::layout)
* fast/dynamic/subtree-common-root-expected.txt: Added.
* fast/dynamic/subtree-common-root.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28299
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2007-12-01 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ - test for <rdar://problem/5619240> REGRESSION (Leopard-r28069): Reproducible crash with a Mootools-based calendar picker (jump to null in FrameView::layout)
+
+ * fast/dynamic/subtree-common-root-expected.txt: Added.
+ * fast/dynamic/subtree-common-root.html: Added.
+
2007-11-30 Eric Seidel <eric@webkit.org>
Reviewed by darin.
--- /dev/null
+Test for rdar://problem/5619240 REGRESSION (Leopard-r28069): Reproducible crash with a Mootools-based calendar picker (jump to null in FrameView::layout).
--- /dev/null
+<p>
+ Test for <i><a href="rdar://problem/5619240">rdar://problem/5619240</a> REGRESSION (Leopard-r28069): Reproducible crash with a Mootools-based calendar picker (jump to null in FrameView::layout)</i>.
+</p>
+<div id="target">
+ <div style="overflow: hidden; width: 400px; height: 400px; position: relative;">
+ <div></div>
+ <div style="position: absolute; overflow: hidden; top: 0; width: 50px; height: 50px;"><div></div></div>
+ </div>
+</div>
+<script>
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+ document.body.offsetTop;
+ document.getElementById("target").style.display = "none";
+</script>
+2007-12-01 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ - fix <rdar://problem/5619240> REGRESSION (Leopard-r28069): Reproducible crash with a Mootools-based calendar picker (jump to null in FrameView::layout)
+
+ Test: fast/dynamic/subtree-common-root.html
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::layoutRoot): Added a parameter to let this method
+ return the layout root for a pending layout as well.
+ (WebCore::FrameView::scheduleRelayoutOfSubtree): Pass the new root
+ to markContainingBlocksForLayout(). Otherwise,
+ markContainingBlocksForLayout() could mark past the new root, if it had
+ previously been marked as having a normal child needing layout and then
+ was reached via a positioned child.
+ * page/FrameView.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::calcWidth):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::~RenderObject): Fixed the ASSERT so that
+ it would really catch deletion of the layout root.
+ (WebCore::RenderObject::markContainingBlocksForLayout): Added the
+ newRoot parameter, which tells this method where to stop marking.
+ * rendering/RenderObject.h:
+
2007-12-01 Dan Bernstein <mitz@apple.com>
Reviewed by Darin Adler.
d->repaintRects.append(RenderObject::RepaintInfo(o, r));
}
-RenderObject* FrameView::layoutRoot() const
+RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
{
- return layoutPending() ? 0 : d->layoutRoot;
+ return onlyDuringLayout && layoutPending() ? 0 : d->layoutRoot;
}
void FrameView::layout(bool allowSubtree)
if (d->layoutRoot != o) {
if (isObjectAncestorContainerOf(d->layoutRoot, o)) {
// Keep the current root
- o->markContainingBlocksForLayout(false);
+ o->markContainingBlocksForLayout(false, d->layoutRoot);
} else if (d->layoutRoot && isObjectAncestorContainerOf(o, d->layoutRoot)) {
// Re-root at o
- d->layoutRoot->markContainingBlocksForLayout(false);
+ d->layoutRoot->markContainingBlocksForLayout(false, o);
d->layoutRoot = o;
} else {
// Just do a full relayout
void unscheduleRelayout();
bool layoutPending() const;
- RenderObject* layoutRoot() const;
+ RenderObject* layoutRoot(bool onlyDuringLayout = false) const;
int layoutCount() const;
// These two helper functions just pass through to the RenderView.
}
// If layout is limited to a subtree, the subtree root's width does not change.
- if (node() && view()->frameView() && view()->frameView()->layoutRoot() == this)
+ if (node() && view()->frameView() && view()->frameView()->layoutRoot(true) == this)
return;
// The parent box is flexing us, so it has increased or decreased our
RenderObject::~RenderObject()
{
- ASSERT(!node() || !document()->frame()->view() || document()->frame()->view()->layoutRoot() != this);
+ ASSERT(!node() || documentBeingDestroyed() || !document()->frame()->view() || document()->frame()->view()->layoutRoot() != this);
#ifndef NDEBUG
--RenderObjectCounter::count;
#endif
;
}
-void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout)
+void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, RenderObject* newRoot)
{
+ ASSERT(!scheduleRelayout || !newRoot);
+
RenderObject* o = container();
RenderObject* last = this;
o->m_normalChildNeedsLayout = true;
}
+ if (o == newRoot)
+ return;
+
last = o;
if (scheduleRelayout && objectIsRelayoutBoundary(last))
break;
RenderObject* hoverAncestor() const;
virtual void markAllDescendantsWithFloatsForLayout(RenderObject* floatToRemove = 0);
- void markContainingBlocksForLayout(bool scheduleRelayout = true);
+ void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderObject* newRoot = 0);
void setNeedsLayout(bool b, bool markParents = true);
void setChildNeedsLayout(bool b, bool markParents = true);