Introduce two different definitions of the placeholder's containing block in InitAbsoluteConstraints, since we want to use a different one for the hypothetical box and for the direction. (Bug 462844) r+sr=bzbarsky a=blocking1.9.1+

This commit is contained in:
L. David Baron 2008-11-25 13:27:54 -08:00
parent b2d5d794fb
commit 50244a3fdd
8 changed files with 90 additions and 18 deletions

View File

@ -698,15 +698,25 @@ nsHTMLReflowState::ComputeRelativeOffsets(const nsHTMLReflowState* cbrs,
}
}
nsIFrame*
nsHTMLReflowState::GetNearestContainingBlock(nsIFrame* aFrame, nscoord& aCBLeftEdge,
nscoord& aCBWidth)
inline PRBool
IsAnonBlockPseudo(nsIAtom *aPseudo)
{
for (aFrame = aFrame->GetParent(); aFrame && !aFrame->IsContainingBlock();
aFrame = aFrame->GetParent())
/* do nothing */;
return aPseudo == nsCSSAnonBoxes::mozAnonymousBlock ||
aPseudo == nsCSSAnonBoxes::mozAnonymousPositionedBlock;
}
nsIFrame*
nsHTMLReflowState::GetHypotheticalBoxContainer(nsIFrame* aFrame,
nscoord& aCBLeftEdge,
nscoord& aCBWidth)
{
do {
aFrame = aFrame->GetParent();
NS_ASSERTION(aFrame, "Must find containing block somewhere");
} while (!(aFrame->IsContainingBlock() ||
(aFrame->IsFrameOfType(nsIFrame::eBlockFrame) &&
IsAnonBlockPseudo(aFrame->GetStyleContext()->GetPseudoType()))));
NS_ASSERTION(aFrame, "Must find containing block somewhere");
NS_ASSERTION(aFrame != frame, "How did that happen?");
/* Now aFrame is the containing block we want */
@ -740,6 +750,16 @@ nsHTMLReflowState::GetNearestContainingBlock(nsIFrame* aFrame, nscoord& aCBLeftE
return aFrame;
}
static nsIFrame*
GetNearestContainingBlock(nsIFrame *aFrame)
{
nsIFrame *cb = aFrame;
do {
cb = cb->GetParent();
} while (!cb->IsContainingBlock());
return cb;
}
// When determining the hypothetical box that would have been if the element
// had been in the flow we may not be able to exactly determine both the left
// and right edges. For example, if the element is a non-replaced inline-level
@ -1111,12 +1131,6 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
aPresContext->PresShell()->GetPlaceholderFrameFor(frame, &placeholderFrame);
NS_ASSERTION(nsnull != placeholderFrame, "no placeholder frame");
// Find the nearest containing block frame to the placeholder frame,
// and return its left edge and width.
nscoord cbLeftEdge, cbWidth;
nsIFrame* cbFrame = GetNearestContainingBlock(placeholderFrame, cbLeftEdge,
cbWidth);
// If both 'left' and 'right' are 'auto' or both 'top' and 'bottom' are
// 'auto', then compute the hypothetical box of where the element would
// have been if it had been in the flow
@ -1125,6 +1139,12 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
(eStyleUnit_Auto == mStylePosition->mOffset.GetRightUnit())) ||
((eStyleUnit_Auto == mStylePosition->mOffset.GetTopUnit()) &&
(eStyleUnit_Auto == mStylePosition->mOffset.GetBottomUnit()))) {
// Find the nearest containing block frame to the placeholder frame,
// and return its left edge and width.
nscoord cbLeftEdge, cbWidth;
nsIFrame* cbFrame = GetHypotheticalBoxContainer(placeholderFrame,
cbLeftEdge,
cbWidth);
CalculateHypotheticalBox(aPresContext, placeholderFrame, cbFrame,
cbLeftEdge, cbWidth, cbrs, hypotheticalBox);
@ -1155,7 +1175,8 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
if (leftIsAuto && rightIsAuto) {
// Use the direction of the original ("static-position") containing block
// to dictate whether 'left' or 'right' is treated like 'static-position'.
if (NS_STYLE_DIRECTION_LTR == cbFrame->GetStyleVisibility()->mDirection) {
if (NS_STYLE_DIRECTION_LTR == GetNearestContainingBlock(placeholderFrame)
->GetStyleVisibility()->mDirection) {
NS_ASSERTION(hypotheticalBox.mLeftIsExact, "should always have "
"exact value on containing block's start side");
mComputedOffsets.left = hypotheticalBox.mLeft;

View File

@ -462,11 +462,13 @@ protected:
const nsMargin* aBorder,
const nsMargin* aPadding);
// Returns the nearest containing block frame for the specified frame. Also
// returns the left edge and width of the containing block's content area.
// Returns the nearest containing block or block frame (whether or not
// it is a containing block) for the specified frame. Also returns
// the left edge and width of the containing block's content area.
// These are returned in the coordinate space of the containing block.
nsIFrame* GetNearestContainingBlock(nsIFrame* aFrame, nscoord& aCBLeftEdge,
nscoord& aCBWidth);
nsIFrame* GetHypotheticalBoxContainer(nsIFrame* aFrame,
nscoord& aCBLeftEdge,
nscoord& aCBWidth);
void CalculateHypotheticalBox(nsPresContext* aPresContext,
nsIFrame* aPlaceholderFrame,

View File

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<title>Testcase, bug 462844</title>
<div style="position: relative">
<div style="display:inline">
<div style="height: 100px"></div>
<div style="background: aqua; height: 20px;"></div>
<div style="display:block; position: absolute; top: auto; left: 0; background: yellow;">Should be just below aqua block</div>
<div style="height: 100px"></div>
</div>
</div>

View File

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<title>Testcase, bug 462844</title>
<div style="position: relative">
<div style="display:inline">
<div style="height: 100px"></div>
<div style="background: aqua; height: 20px;"></div>
<div style="display:inline; position: absolute; top: auto; left: 0; background: yellow;">Should be just below aqua block</div>
<div style="height: 100px"></div>
</div>
</div>

View File

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<title>Testcase, bug 462844</title>
<div style="position: relative">
<div>
<div style="height: 100px"></div>
<div style="background: aqua; height: 20px;"></div>
<div style="display:block; position: absolute; top: auto; left: 0; background: yellow;">Should be just below aqua block</div>
<div style="height: 100px"></div>
</div>
</div>

View File

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<title>Testcase, bug 462844</title>
<div style="position: relative">
<div>
<div style="height: 100px"></div>
<div style="background: aqua; height: 20px;"></div>
<div style="display:block; position: absolute; top: auto; left: 0; background: yellow;">Should be just below aqua block</div>
<div style="height: 100px"></div>
</div>
</div>

View File

@ -0,0 +1,5 @@
<!DOCTYPE HTML>
<title>Testcase, bug 462844</title>
<div style="height: 100px"></div>
<div style="background: aqua; height: 20px;"></div>
<div style="display:block; background: yellow; width: -moz-fit-content">Should be just below aqua block</div>

View File

@ -959,6 +959,10 @@ fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 456147.xul 456147-ref.html # bug 456147
== 458487-5b.html 458487-5-ref.html
== 461266-1.html 461266-1-ref.html
fails == 461512-1.html 461512-1-ref.html # Bug 461512
== 462844-1.html 462844-ref.html
== 462844-2.html 462844-ref.html
== 462844-3.html 462844-ref.html
== 462844-4.html 462844-ref.html
== 463204-1.html 463204-1-ref.html
== 463217-1.xul 463217-1-ref.xul
== 464811-1.html 464811-1-ref.html