Bug 762902: Add a new ReflowChild flag within nsContainerState to disable deletion of next-in-flow children to prevent crash. [r=mats]

This commit is contained in:
Scott Johnson 2013-03-15 13:36:30 -05:00
parent 3703826d50
commit 134ecdfa4f
7 changed files with 58 additions and 3 deletions

View File

@ -0,0 +1,12 @@
<html><head>
</head><body>
<div style="-moz-column-count: 2;">
mmmmmmm
<div style="display: table;-moz-transform: translate(-50px);">
<div style="position: fixed;">b t</div>
</div>
</div>
</body></html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html style="-moz-columns: 2 auto;">
<head>
<style>
div { width:300px; background:yellow; height:50px; }
</style>
</head>
<body style="position: relative; display: table;"><div style="position: absolute;"></div></body>
</html>

View File

@ -432,6 +432,7 @@ load 734777.html
test-pref(layout.css.flexbox.enabled,true) load 737313-1.html
test-pref(layout.css.flexbox.enabled,true) load 737313-2.html
test-pref(layout.css.flexbox.enabled,true) load 737313-3.html
load 762902.html
load 762764-1.html
load 786740-1.html
asserts(12) test-pref(layout.css.flexbox.enabled,true) load 798020-1.html
@ -445,6 +446,7 @@ test-pref(layout.css.flexbox.enabled,true) load 812822-1.html
asserts(1) test-pref(layout.css.flexbox.enabled,true) load 824297-1.html # bug 399262
asserts(1) test-pref(layout.css.flexbox.enabled,true) load 826532-1.html # bug 399262
test-pref(layout.css.flexbox.enabled,true) load 827168-1.html
load 836895.html
load 842132-1.html
test-pref(layout.css.flexbox.enabled,true) load 844529-1.html
load 847130.xhtml

View File

@ -969,8 +969,9 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
aStatus);
// If the reflow was successful and the child frame is complete, delete any
// next-in-flows
if (NS_SUCCEEDED(result) && NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
// next-in-flows, but only if the NO_DELETE_NEXT_IN_FLOW flag isn't set.
if (NS_SUCCEEDED(result) && NS_FRAME_IS_FULLY_COMPLETE(aStatus) &&
!(aFlags & NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD)) {
nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow();
if (nullptr != kidNextInFlow) {
// Remove all of the childs next-in-flows. Make sure that we ask

View File

@ -23,6 +23,9 @@
// Only applies to ReflowChild: if true, invalidate the child if it's
// being moved
#define NS_FRAME_INVALIDATE_ON_MOVE 0x0010
// Only applies to ReflowChild; if true, don't delete the next-in-flow, even
// if the reflow is fully complete.
#define NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD 0x0020
class nsOverflowContinuationTracker;
namespace mozilla {

View File

@ -851,8 +851,19 @@ nsTableOuterFrame::OuterDoReflowChild(nsPresContext* aPresContext,
// use the current position as a best guess for placement
nsPoint childPt = aChildFrame->GetPosition();
uint32_t flags = NS_FRAME_NO_MOVE_FRAME;
// We don't want to delete our next-in-flow's child if it's an inner table
// frame, because outer table frames always assume that their inner table
// frames don't go away. If an outer table frame is removed because it is
// a next-in-flow of an already complete outer table frame, then it will
// take care of removing it's inner table frame.
if (aChildFrame == InnerTableFrame()) {
flags |= NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD;
}
return ReflowChild(aChildFrame, aPresContext, aMetrics, aChildRS,
childPt.x, childPt.y, NS_FRAME_NO_MOVE_FRAME, aStatus);
childPt.x, childPt.y, flags, aStatus);
}
void
@ -1047,6 +1058,13 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPresContext* aPresContext,
}
UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, captionMargin);
if (GetPrevInFlow()) {
ReflowOverflowContainerChildren(aPresContext, aOuterRS,
aDesiredSize.mOverflowAreas, 0,
aStatus);
}
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aOuterRS, aStatus);
// Return our desired rect

View File

@ -277,6 +277,12 @@ protected:
nscoord aAvailableWidth,
nsMargin& aMargin);
virtual bool IsFrameOfType(uint32_t aFlags) const
{
return nsContainerFrame::IsFrameOfType(aFlags &
(~eCanContainOverflowContainers));
}
nsTableFrame* InnerTableFrame() const {
return static_cast<nsTableFrame*>(mFrames.FirstChild());
}