diff --git a/layout/generic/crashtests/25888-1.html b/layout/generic/crashtests/25888-1.html
new file mode 100644
index 00000000000..bfe0f79e510
--- /dev/null
+++ b/layout/generic/crashtests/25888-1.html
@@ -0,0 +1,6 @@
+
Hang while developing patch for bug 25888
+
+
diff --git a/layout/generic/crashtests/25888-2.html b/layout/generic/crashtests/25888-2.html
new file mode 100644
index 00000000000..065218f31dc
--- /dev/null
+++ b/layout/generic/crashtests/25888-2.html
@@ -0,0 +1,8 @@
+
+Testcase for hang while developing bug 25888 (hit on www.flightaware.com)
+
+
diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list
index 8432fc90603..1b446d9f89c 100644
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -1,3 +1,5 @@
+load 25888-1.html
+load 25888-2.html
load 37757-1.html
load 225868-1.html
load 264937-1.html
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index 3212088f9d1..a02c9f14aa1 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -783,6 +783,20 @@ nsBlockFrame::ComputeTightBounds(gfxContext* aContext) const
return ComputeSimpleTightBounds(aContext);
}
+static PRBool
+AvailableSpaceShrunk(const nsRect& aOldAvailableSpace,
+ const nsRect& aNewAvailableSpace)
+{
+ if (aNewAvailableSpace.width == 0) {
+ // Positions are not significant if the width is zero.
+ return aOldAvailableSpace.width != 0;
+ }
+ NS_ASSERTION(aOldAvailableSpace.x <= aNewAvailableSpace.x &&
+ aOldAvailableSpace.XMost() >= aNewAvailableSpace.XMost(),
+ "available space should never grow");
+ return aOldAvailableSpace.width != aNewAvailableSpace.width;
+}
+
static nsSize
CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
nsSize aFrameSize)
@@ -1663,11 +1677,11 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
// decide what it needs to reflow.
aLine->MarkDirty();
} else {
- // Note that this check will become incorrect once bug 25888 is fixed
- // because we are only checking the top of the line
PRBool wasImpactedByFloat = aLine->IsImpactedByFloat();
nsFlowAreaRect floatAvailableSpace =
- aState.GetFloatAvailableSpace(aLine->mBounds.y + aDeltaY, PR_FALSE);
+ aState.GetFloatAvailableSpaceForHeight(aLine->mBounds.y + aDeltaY,
+ aLine->mBounds.height,
+ nsnull);
#ifdef REALLY_NOISY_REFLOW
printf("nsBlockFrame::PropagateFloatDamage %p was = %d, is=%d\n",
@@ -3320,11 +3334,19 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
nsresult rv = NS_OK;
*aKeepReflowGoing = PR_TRUE;
+ aLine->SetLineIsImpactedByFloat(PR_FALSE);
+
+ // Setup initial coordinate system for reflowing the inline frames
+ // into. Apply a previous block frame's bottom margin first.
+ if (ShouldApplyTopMargin(aState, aLine)) {
+ aState.mY += aState.mPrevBottomMargin.get();
+ }
+ nsFlowAreaRect floatAvailableSpace = aState.GetFloatAvailableSpace();
+
#ifdef DEBUG
PRInt32 spins = 0;
#endif
LineReflowStatus lineReflowStatus = LINE_REFLOW_REDO_NEXT_BAND;
- PRBool movedPastFloat = PR_FALSE;
do {
PRBool allowPullUp = PR_TRUE;
nsIContent* forceBreakInContent = nsnull;
@@ -3349,11 +3371,13 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
lineLayout.ForceBreakAtPosition(forceBreakInContent, forceBreakOffset);
}
rv = DoReflowInlineFrames(aState, lineLayout, aLine,
+ floatAvailableSpace, &floatManagerState,
aKeepReflowGoing, &lineReflowStatus,
allowPullUp);
lineLayout.EndLineReflow();
if (LINE_REFLOW_REDO_NO_PULL == lineReflowStatus ||
+ LINE_REFLOW_REDO_MORE_FLOATS == lineReflowStatus ||
LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus) {
if (lineLayout.NeedsBackup()) {
NS_ASSERTION(!forceBreakInContent, "Backing up twice; this should never be necessary");
@@ -3383,17 +3407,9 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
// Don't allow pullup on a subsequent LINE_REFLOW_REDO_NO_PULL pass
allowPullUp = PR_FALSE;
} while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO_NO_PULL == lineReflowStatus);
-
- if (LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus) {
- movedPastFloat = PR_TRUE;
- }
- } while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus);
-
- // If we did at least one REDO_FOR_FLOAT, then the line did not fit next to some float.
- // Mark it as impacted by a float, even if it no longer is next to a float.
- if (movedPastFloat) {
- aLine->SetLineIsImpactedByFloat(PR_TRUE);
- }
+ } while (NS_SUCCEEDED(rv) &&
+ (LINE_REFLOW_REDO_MORE_FLOATS == lineReflowStatus ||
+ LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus));
return rv;
}
@@ -3417,6 +3433,7 @@ nsBlockFrame::PushTruncatedPlaceholderLine(nsBlockReflowState& aState,
#ifdef DEBUG
static const char* LineReflowStatusNames[] = {
"LINE_REFLOW_OK", "LINE_REFLOW_STOP", "LINE_REFLOW_REDO_NO_PULL",
+ "LINE_REFLOW_REDO_MORE_FLOATS",
"LINE_REFLOW_REDO_NEXT_BAND", "LINE_REFLOW_TRUNCATED"
};
#endif
@@ -3425,6 +3442,9 @@ nsresult
nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
line_iterator aLine,
+ nsFlowAreaRect& aFloatAvailableSpace,
+ nsFloatManager::SavedState*
+ aFloatStateBeforeLine,
PRBool* aKeepReflowGoing,
LineReflowStatus* aLineReflowStatus,
PRBool aAllowPullUp)
@@ -3433,28 +3453,25 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
aLine->FreeFloats(aState.mFloatCacheFreeList);
aState.mFloatCombinedArea.SetRect(0, 0, 0, 0);
- // Setup initial coordinate system for reflowing the inline frames
- // into. Apply a previous block frame's bottom margin first.
- if (ShouldApplyTopMargin(aState, aLine)) {
- aState.mY += aState.mPrevBottomMargin.get();
- }
- nsFlowAreaRect floatAvailableSpace = aState.GetFloatAvailableSpace();
- aLine->SetLineIsImpactedByFloat(floatAvailableSpace.mHasFloats);
+ // We need to set this flag on the line if any of our reflow passes
+ // are impacted by floats.
+ if (aFloatAvailableSpace.mHasFloats)
+ aLine->SetLineIsImpactedByFloat(PR_TRUE);
#ifdef REALLY_NOISY_REFLOW
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
- this, floatAvailableSpace.mHasFloats);
+ this, aFloatAvailableSpace.mHasFloats);
#endif
const nsMargin& borderPadding = aState.BorderPadding();
- nscoord x = floatAvailableSpace.mRect.x + borderPadding.left;
- nscoord availWidth = floatAvailableSpace.mRect.width;
+ nscoord x = aFloatAvailableSpace.mRect.x + borderPadding.left;
+ nscoord availWidth = aFloatAvailableSpace.mRect.width;
nscoord availHeight;
if (aState.GetFlag(BRS_UNCONSTRAINEDHEIGHT)) {
availHeight = NS_UNCONSTRAINEDSIZE;
}
else {
/* XXX get the height right! */
- availHeight = floatAvailableSpace.mRect.height;
+ availHeight = aFloatAvailableSpace.mRect.height;
}
// Make sure to enable resize optimization before we call BeginLineReflow
@@ -3463,7 +3480,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
- floatAvailableSpace.mHasFloats,
+ aFloatAvailableSpace.mHasFloats,
PR_FALSE /*XXX isTopOfPage*/);
aState.SetFlag(BRS_LINE_LAYOUT_EMPTY, PR_FALSE);
@@ -3486,7 +3503,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
// continuations
PRBool isContinuingPlaceholders = PR_FALSE;
- if (floatAvailableSpace.mHasFloats) {
+ if (aFloatAvailableSpace.mHasFloats) {
// There is a soft break opportunity at the start of the line, because
// we can always move this line down below float(s).
if (aLineLayout.NotifyOptionalBreakPosition(frame->GetContent(), 0, PR_TRUE, eNormalBreak)) {
@@ -3591,20 +3608,32 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
//
// What we do is to advance past the first float we find and
// then reflow the line all over again.
- NS_ASSERTION(NS_UNCONSTRAINEDSIZE != floatAvailableSpace.mRect.height,
+ NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aFloatAvailableSpace.mRect.height,
"unconstrained height on totally empty line");
// See the analogous code for blocks in nsBlockReflowState::ClearFloats.
- if (floatAvailableSpace.mRect.height > 0) {
- NS_ASSERTION(floatAvailableSpace.mHasFloats,
+ if (aFloatAvailableSpace.mRect.height > 0) {
+ NS_ASSERTION(aFloatAvailableSpace.mHasFloats,
"redo line on totally empty line with non-empty band...");
- aState.mY += floatAvailableSpace.mRect.height;
+ // We should never hit this case if we've placed floats on the
+ // line; if we have, then the GetFloatAvailableSpace call is wrong
+ // and needs to happen after the caller pops the space manager
+ // state.
+ aState.mFloatManager->AssertStateMatches(aFloatStateBeforeLine);
+ aState.mY += aFloatAvailableSpace.mRect.height;
+ aFloatAvailableSpace = aState.GetFloatAvailableSpace();
} else {
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aState.mReflowState.availableHeight,
"We shouldn't be running out of height here");
if (NS_UNCONSTRAINEDSIZE == aState.mReflowState.availableHeight) {
// just move it down a bit to try to get out of this mess
aState.mY += 1;
+ // We should never hit this case if we've placed floats on the
+ // line; if we have, then the GetFloatAvailableSpace call is wrong
+ // and needs to happen after the caller pops the space manager
+ // state.
+ aState.mFloatManager->AssertStateMatches(aFloatStateBeforeLine);
+ aFloatAvailableSpace = aState.GetFloatAvailableSpace();
} else {
// There's nowhere to retry placing the line. Just treat it as if
// we placed the float but it was truncated so we need this line
@@ -3614,30 +3643,22 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
PushTruncatedPlaceholderLine(aState, aLine, *aKeepReflowGoing);
}
}
-
- // We don't want to advance by the bottom margin anymore (we did it
- // once at the beginning of this function, which will just be called
- // again), and we certainly don't want to go back if it's negative
- // (infinite loop, bug 153429).
- aState.mPrevBottomMargin.Zero();
// XXX: a small optimization can be done here when paginating:
// if the new Y coordinate is past the end of the block then
// push the line and return now instead of later on after we are
// past the float.
}
- else if (LINE_REFLOW_REDO_NO_PULL == lineReflowStatus) {
- // We don't want to advance by the bottom margin anymore (we did it
- // once at the beginning of this function, which will just be called
- // again), and we certainly don't want to go back if it's negative
- // (infinite loop, bug 153429).
- aState.mPrevBottomMargin.Zero();
- }
- else if (LINE_REFLOW_TRUNCATED != lineReflowStatus) {
+ else if (LINE_REFLOW_TRUNCATED != lineReflowStatus &&
+ LINE_REFLOW_REDO_NO_PULL != lineReflowStatus) {
// If we are propagating out a break-before status then there is
// no point in placing the line.
if (!NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus)) {
- PlaceLine(aState, aLineLayout, aLine, aKeepReflowGoing);
+ if (!PlaceLine(aState, aLineLayout, aLine, aFloatStateBeforeLine,
+ aFloatAvailableSpace.mRect, aKeepReflowGoing)) {
+ lineReflowStatus = LINE_REFLOW_REDO_MORE_FLOATS;
+ // PlaceLine already called GetAvailableSpaceForHeight for us.
+ }
}
}
#ifdef DEBUG
@@ -4017,10 +4038,12 @@ nsBlockFrame::ShouldJustifyLine(nsBlockReflowState& aState,
return PR_FALSE;
}
-void
+PRBool
nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
line_iterator aLine,
+ nsFloatManager::SavedState *aFloatStateBeforeLine,
+ nsRect& aFloatAvailableSpace,
PRBool* aKeepReflowGoing)
{
// Trim extra white-space from the line before placing the frames
@@ -4049,6 +4072,26 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
}
aLineLayout.VerticalAlignLine();
+ // We want to compare to the available space that we would have had in
+ // the line's height *before* we placed any floats in the line itself.
+ // Floats that are in the line are handled during line reflow (and may
+ // result in floats being pushed to below the line or (I HOPE???) in a
+ // reflow with a forced break position).
+ nsRect oldFloatAvailableSpace(aFloatAvailableSpace);
+ aFloatAvailableSpace =
+ aState.GetFloatAvailableSpaceForHeight(aLine->mBounds.y,
+ aLine->mBounds.height,
+ aFloatStateBeforeLine).mRect;
+ NS_ASSERTION(aFloatAvailableSpace.y == oldFloatAvailableSpace.y, "yikes");
+ // Restore the height to the position of the next band.
+ aFloatAvailableSpace.height = oldFloatAvailableSpace.height;
+ // If the available space between the floats is smaller now that we
+ // know the height, return false (and cause another pass with
+ // LINE_REFLOW_REDO_MORE_FLOATS).
+ if (AvailableSpaceShrunk(oldFloatAvailableSpace, aFloatAvailableSpace)) {
+ return PR_FALSE;
+ }
+
#ifdef DEBUG
{
static nscoord lastHeight = 0;
@@ -4143,7 +4186,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
*aKeepReflowGoing = PR_FALSE;
}
- return;
+ return PR_TRUE;
}
// May be needed below
@@ -4200,6 +4243,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
if (aLine->HasFloatBreakAfter()) {
aState.mY = aState.ClearFloats(aState.mY, aLine->GetBreakTypeAfter());
}
+ return PR_TRUE;
}
void
diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h
index af7e667ee26..1277c17b3cf 100644
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -50,6 +50,7 @@
#include "nsLineBox.h"
#include "nsCSSPseudoElements.h"
#include "nsStyleSet.h"
+#include "nsFloatManager.h"
enum LineReflowStatus {
// The line was completely reflowed and fit in available width, and we should
@@ -61,6 +62,10 @@ enum LineReflowStatus {
// We need to reflow the line again at its current vertical position. The
// new reflow should not try to pull up any frames from the next line.
LINE_REFLOW_REDO_NO_PULL,
+ // We need to reflow the line again using the floats from its height
+ // this reflow, since its height made it hit floats that were not
+ // adjacent to its top.
+ LINE_REFLOW_REDO_MORE_FLOATS,
// We need to reflow the line again at a lower vertical postion where there
// may be more horizontal space due to different float configuration.
LINE_REFLOW_REDO_NEXT_BAND,
@@ -479,11 +484,15 @@ protected:
line_iterator aLine,
PRBool* aKeepReflowGoing);
- // Return PR_TRUE if aLine gets pushed.
- void PlaceLine(nsBlockReflowState& aState,
- nsLineLayout& aLineLayout,
- line_iterator aLine,
- PRBool* aKeepReflowGoing);
+ // Return false if it needs another reflow because of reduced space
+ // between floats that are next to it (but not next to its top), and
+ // return true otherwise.
+ PRBool PlaceLine(nsBlockReflowState& aState,
+ nsLineLayout& aLineLayout,
+ line_iterator aLine,
+ nsFloatManager::SavedState* aFloatStateBeforeLine,
+ nsRect& aFloatAvailableSpace, /* in-out */
+ PRBool* aKeepReflowGoing);
/**
* Mark |aLine| dirty, and, if necessary because of possible
@@ -522,6 +531,9 @@ protected:
nsresult DoReflowInlineFrames(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
line_iterator aLine,
+ nsFlowAreaRect& aFloatAvailableSpace,
+ nsFloatManager::SavedState*
+ aFloatStateBeforeLine,
PRBool* aKeepReflowGoing,
LineReflowStatus* aLineReflowStatus,
PRBool aAllowPullUp);
diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp
index a6d463788f7..947d68fc257 100644
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -366,6 +366,38 @@ nsBlockReflowState::GetFloatAvailableSpaceWithState(
return result;
}
+nsFlowAreaRect
+nsBlockReflowState::GetFloatAvailableSpaceForHeight(
+ nscoord aY, nscoord aHeight,
+ nsFloatManager::SavedState *aState) const
+{
+#ifdef DEBUG
+ // Verify that the caller setup the coordinate system properly
+ nscoord wx, wy;
+ mFloatManager->GetTranslation(wx, wy);
+ NS_ASSERTION((wx == mFloatManagerX) && (wy == mFloatManagerY),
+ "bad coord system");
+#endif
+
+ nsFlowAreaRect result =
+ mFloatManager->GetFlowArea(aY - BorderPadding().top,
+ nsFloatManager::WIDTH_WITHIN_HEIGHT,
+ aHeight, mContentArea.width, aState);
+ // Keep the width >= 0 for compatibility with nsSpaceManager.
+ if (result.mRect.width < 0)
+ result.mRect.width = 0;
+
+#ifdef DEBUG
+ if (nsBlockFrame::gNoisyReflow) {
+ nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
+ printf("GetAvailableSpaceForHeight: space=%d,%d,%d,%d hasfloats=%d\n",
+ result.mRect.x, result.mRect.y, result.mRect.width,
+ result.mRect.height, result.mHasFloats);
+ }
+#endif
+ return result;
+}
+
/*
* Reconstruct the vertical margin before the line |aLine| in order to
* do an incremental reflow that begins with |aLine| without reflowing
diff --git a/layout/generic/nsBlockReflowState.h b/layout/generic/nsBlockReflowState.h
index 9a4bf9bc347..c9ed874d080 100644
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -100,6 +100,9 @@ public:
nsFlowAreaRect
GetFloatAvailableSpaceWithState(nscoord aY, PRBool aRelaxHeightConstraint,
nsFloatManager::SavedState *aState) const;
+ nsFlowAreaRect
+ GetFloatAvailableSpaceForHeight(nscoord aY, nscoord aHeight,
+ nsFloatManager::SavedState *aState) const;
/*
* The following functions all return PR_TRUE if they were able to
diff --git a/layout/generic/nsFloatManager.h b/layout/generic/nsFloatManager.h
index 84dd48a20d3..0d74bca16d6 100644
--- a/layout/generic/nsFloatManager.h
+++ b/layout/generic/nsFloatManager.h
@@ -227,6 +227,13 @@ public:
*/
nscoord ClearFloats(nscoord aY, PRUint8 aBreakType) const;
+ void AssertStateMatches(SavedState *aState) const
+ {
+ NS_ASSERTION(aState->mX == mX && aState->mY == mY &&
+ aState->mFloatInfoCount == mFloats.Length(),
+ "float manager state should match saved state");
+ }
+
#ifdef DEBUG
/**
* Dump the state of the float manager out to a file.
diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list
index acf3571e08d..380d407e20c 100644
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -36,14 +36,14 @@
== 23604-1.html 23604-1-ref.html
== 23604-2.html 23604-2-ref.html
!= 24998-1.html 24998-1-ref.html
-fails == 25888-1l.html 25888-1l-ref.html # bug 25888
-fails != 25888-1l.html 25888-1l-notref.html # bug 25888
-fails == 25888-1r.html 25888-1r-ref.html # bug 25888
-fails != 25888-1r.html 25888-1r-notref.html # bug 25888
-fails == 25888-2l.html 25888-2l-ref.html # bug 25888
-fails == 25888-2r.html 25888-2r-ref.html # bug 25888
-fails == 25888-3l.html 25888-3l-ref.html # bug 25888
-fails == 25888-3r.html 25888-3r-ref.html # bug 25888
+== 25888-1l.html 25888-1l-ref.html
+!= 25888-1l.html 25888-1l-notref.html
+== 25888-1r.html 25888-1r-ref.html
+!= 25888-1r.html 25888-1r-notref.html
+== 25888-2l.html 25888-2l-ref.html
+== 25888-2r.html 25888-2r-ref.html
+== 25888-3l.html 25888-3l-ref.html
+== 25888-3r.html 25888-3r-ref.html
== 28811-1a.html 28811-1-ref.html
== 28811-1b.html 28811-1-ref.html
== 28811-2a.html 28811-2-ref.html
diff --git a/layout/reftests/floats/345369-1-ref.html b/layout/reftests/floats/345369-1-ref.html
new file mode 100644
index 00000000000..9febdf382b2
--- /dev/null
+++ b/layout/reftests/floats/345369-1-ref.html
@@ -0,0 +1,9 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/345369-1.html b/layout/reftests/floats/345369-1.html
new file mode 100644
index 00000000000..714899a47d2
--- /dev/null
+++ b/layout/reftests/floats/345369-1.html
@@ -0,0 +1,9 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/345369-2-ref.html b/layout/reftests/floats/345369-2-ref.html
new file mode 100644
index 00000000000..76d999dcfa3
--- /dev/null
+++ b/layout/reftests/floats/345369-2-ref.html
@@ -0,0 +1,10 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/345369-2.html b/layout/reftests/floats/345369-2.html
new file mode 100644
index 00000000000..ccd4696a04f
--- /dev/null
+++ b/layout/reftests/floats/345369-2.html
@@ -0,0 +1,12 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/345369-3-ref.html b/layout/reftests/floats/345369-3-ref.html
new file mode 100644
index 00000000000..166f5e475fa
--- /dev/null
+++ b/layout/reftests/floats/345369-3-ref.html
@@ -0,0 +1,10 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/345369-3.html b/layout/reftests/floats/345369-3.html
new file mode 100644
index 00000000000..f758302d9ab
--- /dev/null
+++ b/layout/reftests/floats/345369-3.html
@@ -0,0 +1,10 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/345369-4-ref.html b/layout/reftests/floats/345369-4-ref.html
new file mode 100644
index 00000000000..79d32213e24
--- /dev/null
+++ b/layout/reftests/floats/345369-4-ref.html
@@ -0,0 +1,10 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/345369-4.html b/layout/reftests/floats/345369-4.html
new file mode 100644
index 00000000000..a5c53e25464
--- /dev/null
+++ b/layout/reftests/floats/345369-4.html
@@ -0,0 +1,10 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/345369-5-ref.html b/layout/reftests/floats/345369-5-ref.html
new file mode 100644
index 00000000000..a38cc580ad1
--- /dev/null
+++ b/layout/reftests/floats/345369-5-ref.html
@@ -0,0 +1,10 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/345369-5.html b/layout/reftests/floats/345369-5.html
new file mode 100644
index 00000000000..0ed4014c1b6
--- /dev/null
+++ b/layout/reftests/floats/345369-5.html
@@ -0,0 +1,10 @@
+Ambiguous line width
+
+
diff --git a/layout/reftests/floats/reftest.list b/layout/reftests/floats/reftest.list
index ebae5752936..ebc240fdfe2 100644
--- a/layout/reftests/floats/reftest.list
+++ b/layout/reftests/floats/reftest.list
@@ -7,5 +7,10 @@ fails == other-float-outside-rule-3-right-2.html other-float-outside-rule-3-righ
fails == other-float-outside-rule-7-left.html other-float-outside-rule-7-left-ref.html
fails == other-float-outside-rule-7-right.html other-float-outside-rule-7-right-ref.html
== float-outside-block-push.html float-outside-block-push-ref.html
-fails == zero-height-float-base.html zero-height-float-ref.html
+== zero-height-float-base.html zero-height-float-ref.html
fails == zero-height-float.html zero-height-float-ref.html
+fails == 345369-1.html 345369-1-ref.html
+fails == 345369-2.html 345369-2-ref.html
+== 345369-3.html 345369-3-ref.html
+== 345369-4.html 345369-4-ref.html
+== 345369-5.html 345369-5-ref.html