From 2500818fde104e28501f6c02cfff930529b0e079 Mon Sep 17 00:00:00 2001 From: "troy%netscape.com" Date: Tue, 20 Jul 1999 02:48:18 +0000 Subject: [PATCH] Fix for bug #9611: now handles absolutely positioned replaced elements git-svn-id: svn://10.0.0.236/trunk@40211 18797224-902f-48f8-a5cc-f745e15eee43 --- .../generic/nsAbsoluteContainingBlock.cpp | 64 ++++++ mozilla/layout/generic/nsHTMLReflowState.cpp | 198 +++++++++++------- .../base/src/nsAbsoluteContainingBlock.cpp | 64 ++++++ .../html/base/src/nsHTMLReflowState.cpp | 198 +++++++++++------- mozilla/layout/html/base/src/nsIHTMLReflow.h | 8 +- 5 files changed, 376 insertions(+), 156 deletions(-) diff --git a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp index fe14ef27313..404db77f299 100644 --- a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp @@ -215,6 +215,70 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIPresContext& aPresCon rv = htmlReflow->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus); + // Because we don't know the size of a replaced element until after we reflow + // it 'auto' margins must be computed now + if (NS_FRAME_IS_REPLACED(kidReflowState.frameType)) { + // Get the containing block width/height + nscoord containingBlockWidth, containingBlockHeight; + kidReflowState.ComputeContainingBlockRectangle(&aReflowState, + containingBlockWidth, + containingBlockHeight); + + // XXX This code belongs in nsHTMLReflowState... + if ((NS_AUTOMARGIN == kidReflowState.computedMargin.left) || + (NS_AUTOMARGIN == kidReflowState.computedMargin.right)) { + // Calculate the amount of space for margins + nscoord availMarginSpace = containingBlockWidth - + kidReflowState.computedOffsets.left - kidReflowState.mComputedBorderPadding.left - + kidDesiredSize.width - kidReflowState.mComputedBorderPadding.right - + kidReflowState.computedOffsets.right; + + if (NS_AUTOMARGIN == kidReflowState.computedMargin.left) { + if (NS_AUTOMARGIN == kidReflowState.computedMargin.right) { + // Both 'margin-left' and 'margin-right' are 'auto', so they get + // equal values + kidReflowState.computedMargin.left = availMarginSpace / 2; + kidReflowState.computedMargin.right = availMarginSpace - + kidReflowState.computedMargin.left; + } else { + // Just 'margin-left' is 'auto' + kidReflowState.computedMargin.left = availMarginSpace - + kidReflowState.computedMargin.right; + } + } else { + // Just 'margin-right' is 'auto' + kidReflowState.computedMargin.right = availMarginSpace - + kidReflowState.computedMargin.left; + } + } + if ((NS_AUTOMARGIN == kidReflowState.computedMargin.top) || + (NS_AUTOMARGIN == kidReflowState.computedMargin.bottom)) { + // Calculate the amount of space for margins + nscoord availMarginSpace = containingBlockHeight - + kidReflowState.computedOffsets.top - kidReflowState.mComputedBorderPadding.top - + kidDesiredSize.height - kidReflowState.mComputedBorderPadding.bottom - + kidReflowState.computedOffsets.bottom; + + if (NS_AUTOMARGIN == kidReflowState.computedMargin.top) { + if (NS_AUTOMARGIN == kidReflowState.computedMargin.bottom) { + // Both 'margin-top' and 'margin-bottom' are 'auto', so they get + // equal values + kidReflowState.computedMargin.top = availMarginSpace / 2; + kidReflowState.computedMargin.bottom = availMarginSpace - + kidReflowState.computedMargin.top; + } else { + // Just 'margin-top' is 'auto' + kidReflowState.computedMargin.top = availMarginSpace - + kidReflowState.computedMargin.bottom; + } + } else { + // Just 'margin-bottom' is 'auto' + kidReflowState.computedMargin.bottom = availMarginSpace - + kidReflowState.computedMargin.top; + } + } + } + // XXX If the child had a fixed height, then make sure it respected it... if (NS_AUTOHEIGHT != kidReflowState.computedHeight) { if (kidDesiredSize.height < kidReflowState.computedHeight) { diff --git a/mozilla/layout/generic/nsHTMLReflowState.cpp b/mozilla/layout/generic/nsHTMLReflowState.cpp index 9007cc864cb..7dc86041d95 100644 --- a/mozilla/layout/generic/nsHTMLReflowState.cpp +++ b/mozilla/layout/generic/nsHTMLReflowState.cpp @@ -467,14 +467,30 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, } // Calculate the computed width - if (eStyleUnit_Auto == widthUnit) { - // Any remaining 'auto' values for 'left', 'right', 'margin-left', or - // 'margin-right' are replaced with 0 (their default value) - computedWidth = containingBlockWidth - computedOffsets.left - - computedMargin.left - mComputedBorderPadding.left - - mComputedBorderPadding.right - - computedMargin.right - computedOffsets.right; + PRBool marginLeftIsAuto = (eStyleUnit_Auto == mStyleSpacing->mMargin.GetLeftUnit()); + PRBool marginRightIsAuto = (eStyleUnit_Auto == mStyleSpacing->mMargin.GetRightUnit()); + if (eStyleUnit_Auto == widthUnit) { + // The element has a 'width' value of 'auto' + if (NS_FRAME_IS_REPLACED(frameType)) { + // Substitute the element's intrinsic width + computedWidth = NS_INTRINSICSIZE; + + } else { + // Any remaining 'auto' values for 'left', 'right', 'margin-left', or + // 'margin-right' are replaced with 0 (their default value) + leftIsAuto = PR_FALSE; + rightIsAuto = PR_FALSE; + marginLeftIsAuto = PR_FALSE; + marginRightIsAuto = PR_FALSE; + + computedWidth = containingBlockWidth - computedOffsets.left - + computedMargin.left - mComputedBorderPadding.left - + mComputedBorderPadding.right - + computedMargin.right - computedOffsets.right; + } + + // Factor in any minimum and maximum size information if (computedWidth > mComputedMaxWidth) { computedWidth = mComputedMaxWidth; } else if (computedWidth < mComputedMinWidth) { @@ -489,53 +505,63 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, ComputeHorizontalValue(containingBlockWidth, widthUnit, mStylePosition->mWidth, computedWidth); } + + // Factor in any minimum and maximum size information if (computedWidth > mComputedMaxWidth) { computedWidth = mComputedMaxWidth; } else if (computedWidth < mComputedMinWidth) { computedWidth = mComputedMinWidth; } + } - if (leftIsAuto) { - // Any 'auto' on 'margin-left' or 'margin-right' are replaced with 0 - // (their default value) - computedOffsets.left = containingBlockWidth - computedMargin.left - - mComputedBorderPadding.left - computedWidth - - mComputedBorderPadding.right - - computedMargin.right - computedOffsets.right; + // Calculate any remaining 'auto' values for the offsets and margins + if (leftIsAuto) { + // Any 'auto' on 'margin-left' or 'margin-right' are replaced with 0 + // (their default value) + computedOffsets.left = containingBlockWidth - computedMargin.left - + mComputedBorderPadding.left - computedWidth - + mComputedBorderPadding.right - + computedMargin.right - computedOffsets.right; - } else if (rightIsAuto) { - // Any 'auto' on 'margin-left' or 'margin-right' are replaced with 0 - // (their default value) - computedOffsets.right = containingBlockWidth - computedOffsets.left - - computedMargin.left - mComputedBorderPadding.left - computedWidth - - mComputedBorderPadding.right - computedMargin.right; + } else if (rightIsAuto) { + // Any 'auto' on 'margin-left' or 'margin-right' are replaced with 0 + // (their default value) + computedOffsets.right = containingBlockWidth - computedOffsets.left - + computedMargin.left - mComputedBorderPadding.left - computedWidth - + mComputedBorderPadding.right - computedMargin.right; + } else if (marginLeftIsAuto || marginRightIsAuto) { + // All that's left to solve for are 'auto' values for 'margin-left' and + // 'margin-right' + if (NS_FRAME_IS_REPLACED(frameType)) { + // We can't solve for 'auto' values for 'margin-left' and 'margin-right' + // until after we reflow the frame and it tells us its intrinsic width + if (marginLeftIsAuto) { + computedMargin.left = NS_AUTOMARGIN; + } + if (marginRightIsAuto) { + computedMargin.right = NS_AUTOMARGIN; + } } else { - // All that's left to solve for are 'auto' values for 'margin-left' and - // 'margin-right' - if ((eStyleUnit_Auto == mStyleSpacing->mMargin.GetLeftUnit()) || - (eStyleUnit_Auto == mStyleSpacing->mMargin.GetRightUnit())) { - - // Calculate the amount of space for margins - nscoord availMarginSpace = containingBlockWidth - - computedOffsets.left - mComputedBorderPadding.left - - computedWidth - mComputedBorderPadding.right - - computedOffsets.right; - - if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetLeftUnit()) { - if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetRightUnit()) { - // Both 'margin-left' and 'margin-right' are 'auto', so they get - // equal values - computedMargin.left = availMarginSpace / 2; - computedMargin.right = availMarginSpace - computedMargin.left; - } else { - // Just 'margin-left' is 'auto' - computedMargin.left = availMarginSpace - computedMargin.right; - } - } else { - // Just 'margin-right' is 'auto' + // Calculate the amount of space for margins + nscoord availMarginSpace = containingBlockWidth - + computedOffsets.left - mComputedBorderPadding.left - + computedWidth - mComputedBorderPadding.right - + computedOffsets.right; + + if (marginLeftIsAuto) { + if (marginRightIsAuto) { + // Both 'margin-left' and 'margin-right' are 'auto', so they get + // equal values + computedMargin.left = availMarginSpace / 2; computedMargin.right = availMarginSpace - computedMargin.left; + } else { + // Just 'margin-left' is 'auto' + computedMargin.left = availMarginSpace - computedMargin.right; } + } else { + // Just 'margin-right' is 'auto' + computedMargin.right = availMarginSpace - computedMargin.left; } } } @@ -584,15 +610,25 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, } // Calculate the computed height + PRBool marginTopIsAuto = (eStyleUnit_Auto == mStyleSpacing->mMargin.GetTopUnit()); + PRBool marginBottomIsAuto = (eStyleUnit_Auto == mStyleSpacing->mMargin.GetBottomUnit()); + if (eStyleUnit_Auto == heightUnit) { - // Any 'auto' on 'margin-top' or 'margin-bottom' are replaced with 0 - // (their default value) if (NS_FRAME_IS_REPLACED(frameType)) { computedHeight = NS_INTRINSICSIZE; } else { - // If the containing block's height was not explicitly specified (i.e., - // it depends on its content height), then so does our height + // Replace any 'auto' on 'margin-top' or 'margin-bottom' with 0 (their + // default values) + marginTopIsAuto = PR_FALSE; + marginBottomIsAuto = PR_FALSE; + + // If 'bottom' is 'auto', then replace it with '0' (its default value), too + bottomIsAuto = PR_FALSE; + + // Solve for the value of 'height' if (NS_AUTOHEIGHT == containingBlockHeight) { + // If the containing block's height was not explicitly specified (i.e., + // it depends on its content height), then so does our height computedHeight = NS_AUTOHEIGHT; } else { @@ -601,6 +637,7 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, mComputedBorderPadding.bottom - computedMargin.bottom - computedOffsets.bottom; + // Factor in any minimum and maximum size information if (computedHeight > mComputedMaxHeight) { computedHeight = mComputedMaxHeight; } else if (computedHeight < mComputedMinHeight) { @@ -617,45 +654,54 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, mStylePosition->mHeight, computedHeight); } + // Factor in any minimum and maximum size information if (computedHeight > mComputedMaxHeight) { computedHeight = mComputedMaxHeight; } if (computedHeight < mComputedMinHeight) { computedHeight = mComputedMinHeight; } + } - if (NS_AUTOHEIGHT != containingBlockHeight) { - if (bottomIsAuto) { - // Any 'auto' on 'margin-top' or 'margin-bottom' are replaced with 0 - computedOffsets.bottom = containingBlockHeight - computedOffsets.top - - computedMargin.top - mComputedBorderPadding.top - computedHeight - - mComputedBorderPadding.bottom - computedMargin.bottom; - + // Calculate any remaining 'auto' values for the offsets and margins + if (NS_AUTOHEIGHT != containingBlockHeight) { + if (bottomIsAuto) { + // Any 'auto' on 'margin-top' or 'margin-bottom' are replaced with 0 + computedOffsets.bottom = containingBlockHeight - computedOffsets.top - + computedMargin.top - mComputedBorderPadding.top - computedHeight - + mComputedBorderPadding.bottom - computedMargin.bottom; + + } else if (marginTopIsAuto || marginBottomIsAuto) { + // All that's left to solve for are 'auto' values for 'margin-top' and + // 'margin-bottom' + if (NS_FRAME_IS_REPLACED(frameType)) { + // We can't solve for 'auto' values for 'margin-top' and 'margin-bottom' + // until after we reflow the frame and it tells us its intrinsic height + if (marginTopIsAuto) { + computedMargin.top = NS_AUTOMARGIN; + } + if (marginBottomIsAuto) { + computedMargin.bottom = NS_AUTOMARGIN; + } } else { - // All that's left to solve for are 'auto' values for 'margin-top' and - // 'margin-bottom' - if ((eStyleUnit_Auto == mStyleSpacing->mMargin.GetTopUnit()) || - (eStyleUnit_Auto == mStyleSpacing->mMargin.GetBottomUnit())) { - - // Calculate the amount of space for margins - nscoord availMarginSpace = containingBlockHeight - computedOffsets.top - - mComputedBorderPadding.top - computedHeight - mComputedBorderPadding.bottom - - computedOffsets.bottom; - - if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetTopUnit()) { - if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetBottomUnit()) { - // Both 'margin-top' and 'margin-bottom' are 'auto', so they get - // equal values - computedMargin.top = availMarginSpace / 2; - computedMargin.bottom = availMarginSpace - computedMargin.top; - } else { - // Just 'margin-top' is 'auto' - computedMargin.top = availMarginSpace - computedMargin.bottom; - } - } else { - // Just 'margin-bottom' is 'auto' + // Calculate the amount of space for margins + nscoord availMarginSpace = containingBlockHeight - computedOffsets.top - + mComputedBorderPadding.top - computedHeight - mComputedBorderPadding.bottom - + computedOffsets.bottom; + + if (marginTopIsAuto) { + if (marginBottomIsAuto) { + // Both 'margin-top' and 'margin-bottom' are 'auto', so they get + // equal values + computedMargin.top = availMarginSpace / 2; computedMargin.bottom = availMarginSpace - computedMargin.top; + } else { + // Just 'margin-top' is 'auto' + computedMargin.top = availMarginSpace - computedMargin.bottom; } + } else { + // Just 'margin-bottom' is 'auto' + computedMargin.bottom = availMarginSpace - computedMargin.top; } } } diff --git a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp index fe14ef27313..404db77f299 100644 --- a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp +++ b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp @@ -215,6 +215,70 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIPresContext& aPresCon rv = htmlReflow->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus); + // Because we don't know the size of a replaced element until after we reflow + // it 'auto' margins must be computed now + if (NS_FRAME_IS_REPLACED(kidReflowState.frameType)) { + // Get the containing block width/height + nscoord containingBlockWidth, containingBlockHeight; + kidReflowState.ComputeContainingBlockRectangle(&aReflowState, + containingBlockWidth, + containingBlockHeight); + + // XXX This code belongs in nsHTMLReflowState... + if ((NS_AUTOMARGIN == kidReflowState.computedMargin.left) || + (NS_AUTOMARGIN == kidReflowState.computedMargin.right)) { + // Calculate the amount of space for margins + nscoord availMarginSpace = containingBlockWidth - + kidReflowState.computedOffsets.left - kidReflowState.mComputedBorderPadding.left - + kidDesiredSize.width - kidReflowState.mComputedBorderPadding.right - + kidReflowState.computedOffsets.right; + + if (NS_AUTOMARGIN == kidReflowState.computedMargin.left) { + if (NS_AUTOMARGIN == kidReflowState.computedMargin.right) { + // Both 'margin-left' and 'margin-right' are 'auto', so they get + // equal values + kidReflowState.computedMargin.left = availMarginSpace / 2; + kidReflowState.computedMargin.right = availMarginSpace - + kidReflowState.computedMargin.left; + } else { + // Just 'margin-left' is 'auto' + kidReflowState.computedMargin.left = availMarginSpace - + kidReflowState.computedMargin.right; + } + } else { + // Just 'margin-right' is 'auto' + kidReflowState.computedMargin.right = availMarginSpace - + kidReflowState.computedMargin.left; + } + } + if ((NS_AUTOMARGIN == kidReflowState.computedMargin.top) || + (NS_AUTOMARGIN == kidReflowState.computedMargin.bottom)) { + // Calculate the amount of space for margins + nscoord availMarginSpace = containingBlockHeight - + kidReflowState.computedOffsets.top - kidReflowState.mComputedBorderPadding.top - + kidDesiredSize.height - kidReflowState.mComputedBorderPadding.bottom - + kidReflowState.computedOffsets.bottom; + + if (NS_AUTOMARGIN == kidReflowState.computedMargin.top) { + if (NS_AUTOMARGIN == kidReflowState.computedMargin.bottom) { + // Both 'margin-top' and 'margin-bottom' are 'auto', so they get + // equal values + kidReflowState.computedMargin.top = availMarginSpace / 2; + kidReflowState.computedMargin.bottom = availMarginSpace - + kidReflowState.computedMargin.top; + } else { + // Just 'margin-top' is 'auto' + kidReflowState.computedMargin.top = availMarginSpace - + kidReflowState.computedMargin.bottom; + } + } else { + // Just 'margin-bottom' is 'auto' + kidReflowState.computedMargin.bottom = availMarginSpace - + kidReflowState.computedMargin.top; + } + } + } + // XXX If the child had a fixed height, then make sure it respected it... if (NS_AUTOHEIGHT != kidReflowState.computedHeight) { if (kidDesiredSize.height < kidReflowState.computedHeight) { diff --git a/mozilla/layout/html/base/src/nsHTMLReflowState.cpp b/mozilla/layout/html/base/src/nsHTMLReflowState.cpp index 9007cc864cb..7dc86041d95 100644 --- a/mozilla/layout/html/base/src/nsHTMLReflowState.cpp +++ b/mozilla/layout/html/base/src/nsHTMLReflowState.cpp @@ -467,14 +467,30 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, } // Calculate the computed width - if (eStyleUnit_Auto == widthUnit) { - // Any remaining 'auto' values for 'left', 'right', 'margin-left', or - // 'margin-right' are replaced with 0 (their default value) - computedWidth = containingBlockWidth - computedOffsets.left - - computedMargin.left - mComputedBorderPadding.left - - mComputedBorderPadding.right - - computedMargin.right - computedOffsets.right; + PRBool marginLeftIsAuto = (eStyleUnit_Auto == mStyleSpacing->mMargin.GetLeftUnit()); + PRBool marginRightIsAuto = (eStyleUnit_Auto == mStyleSpacing->mMargin.GetRightUnit()); + if (eStyleUnit_Auto == widthUnit) { + // The element has a 'width' value of 'auto' + if (NS_FRAME_IS_REPLACED(frameType)) { + // Substitute the element's intrinsic width + computedWidth = NS_INTRINSICSIZE; + + } else { + // Any remaining 'auto' values for 'left', 'right', 'margin-left', or + // 'margin-right' are replaced with 0 (their default value) + leftIsAuto = PR_FALSE; + rightIsAuto = PR_FALSE; + marginLeftIsAuto = PR_FALSE; + marginRightIsAuto = PR_FALSE; + + computedWidth = containingBlockWidth - computedOffsets.left - + computedMargin.left - mComputedBorderPadding.left - + mComputedBorderPadding.right - + computedMargin.right - computedOffsets.right; + } + + // Factor in any minimum and maximum size information if (computedWidth > mComputedMaxWidth) { computedWidth = mComputedMaxWidth; } else if (computedWidth < mComputedMinWidth) { @@ -489,53 +505,63 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, ComputeHorizontalValue(containingBlockWidth, widthUnit, mStylePosition->mWidth, computedWidth); } + + // Factor in any minimum and maximum size information if (computedWidth > mComputedMaxWidth) { computedWidth = mComputedMaxWidth; } else if (computedWidth < mComputedMinWidth) { computedWidth = mComputedMinWidth; } + } - if (leftIsAuto) { - // Any 'auto' on 'margin-left' or 'margin-right' are replaced with 0 - // (their default value) - computedOffsets.left = containingBlockWidth - computedMargin.left - - mComputedBorderPadding.left - computedWidth - - mComputedBorderPadding.right - - computedMargin.right - computedOffsets.right; + // Calculate any remaining 'auto' values for the offsets and margins + if (leftIsAuto) { + // Any 'auto' on 'margin-left' or 'margin-right' are replaced with 0 + // (their default value) + computedOffsets.left = containingBlockWidth - computedMargin.left - + mComputedBorderPadding.left - computedWidth - + mComputedBorderPadding.right - + computedMargin.right - computedOffsets.right; - } else if (rightIsAuto) { - // Any 'auto' on 'margin-left' or 'margin-right' are replaced with 0 - // (their default value) - computedOffsets.right = containingBlockWidth - computedOffsets.left - - computedMargin.left - mComputedBorderPadding.left - computedWidth - - mComputedBorderPadding.right - computedMargin.right; + } else if (rightIsAuto) { + // Any 'auto' on 'margin-left' or 'margin-right' are replaced with 0 + // (their default value) + computedOffsets.right = containingBlockWidth - computedOffsets.left - + computedMargin.left - mComputedBorderPadding.left - computedWidth - + mComputedBorderPadding.right - computedMargin.right; + } else if (marginLeftIsAuto || marginRightIsAuto) { + // All that's left to solve for are 'auto' values for 'margin-left' and + // 'margin-right' + if (NS_FRAME_IS_REPLACED(frameType)) { + // We can't solve for 'auto' values for 'margin-left' and 'margin-right' + // until after we reflow the frame and it tells us its intrinsic width + if (marginLeftIsAuto) { + computedMargin.left = NS_AUTOMARGIN; + } + if (marginRightIsAuto) { + computedMargin.right = NS_AUTOMARGIN; + } } else { - // All that's left to solve for are 'auto' values for 'margin-left' and - // 'margin-right' - if ((eStyleUnit_Auto == mStyleSpacing->mMargin.GetLeftUnit()) || - (eStyleUnit_Auto == mStyleSpacing->mMargin.GetRightUnit())) { - - // Calculate the amount of space for margins - nscoord availMarginSpace = containingBlockWidth - - computedOffsets.left - mComputedBorderPadding.left - - computedWidth - mComputedBorderPadding.right - - computedOffsets.right; - - if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetLeftUnit()) { - if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetRightUnit()) { - // Both 'margin-left' and 'margin-right' are 'auto', so they get - // equal values - computedMargin.left = availMarginSpace / 2; - computedMargin.right = availMarginSpace - computedMargin.left; - } else { - // Just 'margin-left' is 'auto' - computedMargin.left = availMarginSpace - computedMargin.right; - } - } else { - // Just 'margin-right' is 'auto' + // Calculate the amount of space for margins + nscoord availMarginSpace = containingBlockWidth - + computedOffsets.left - mComputedBorderPadding.left - + computedWidth - mComputedBorderPadding.right - + computedOffsets.right; + + if (marginLeftIsAuto) { + if (marginRightIsAuto) { + // Both 'margin-left' and 'margin-right' are 'auto', so they get + // equal values + computedMargin.left = availMarginSpace / 2; computedMargin.right = availMarginSpace - computedMargin.left; + } else { + // Just 'margin-left' is 'auto' + computedMargin.left = availMarginSpace - computedMargin.right; } + } else { + // Just 'margin-right' is 'auto' + computedMargin.right = availMarginSpace - computedMargin.left; } } } @@ -584,15 +610,25 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, } // Calculate the computed height + PRBool marginTopIsAuto = (eStyleUnit_Auto == mStyleSpacing->mMargin.GetTopUnit()); + PRBool marginBottomIsAuto = (eStyleUnit_Auto == mStyleSpacing->mMargin.GetBottomUnit()); + if (eStyleUnit_Auto == heightUnit) { - // Any 'auto' on 'margin-top' or 'margin-bottom' are replaced with 0 - // (their default value) if (NS_FRAME_IS_REPLACED(frameType)) { computedHeight = NS_INTRINSICSIZE; } else { - // If the containing block's height was not explicitly specified (i.e., - // it depends on its content height), then so does our height + // Replace any 'auto' on 'margin-top' or 'margin-bottom' with 0 (their + // default values) + marginTopIsAuto = PR_FALSE; + marginBottomIsAuto = PR_FALSE; + + // If 'bottom' is 'auto', then replace it with '0' (its default value), too + bottomIsAuto = PR_FALSE; + + // Solve for the value of 'height' if (NS_AUTOHEIGHT == containingBlockHeight) { + // If the containing block's height was not explicitly specified (i.e., + // it depends on its content height), then so does our height computedHeight = NS_AUTOHEIGHT; } else { @@ -601,6 +637,7 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, mComputedBorderPadding.bottom - computedMargin.bottom - computedOffsets.bottom; + // Factor in any minimum and maximum size information if (computedHeight > mComputedMaxHeight) { computedHeight = mComputedMaxHeight; } else if (computedHeight < mComputedMinHeight) { @@ -617,45 +654,54 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext, mStylePosition->mHeight, computedHeight); } + // Factor in any minimum and maximum size information if (computedHeight > mComputedMaxHeight) { computedHeight = mComputedMaxHeight; } if (computedHeight < mComputedMinHeight) { computedHeight = mComputedMinHeight; } + } - if (NS_AUTOHEIGHT != containingBlockHeight) { - if (bottomIsAuto) { - // Any 'auto' on 'margin-top' or 'margin-bottom' are replaced with 0 - computedOffsets.bottom = containingBlockHeight - computedOffsets.top - - computedMargin.top - mComputedBorderPadding.top - computedHeight - - mComputedBorderPadding.bottom - computedMargin.bottom; - + // Calculate any remaining 'auto' values for the offsets and margins + if (NS_AUTOHEIGHT != containingBlockHeight) { + if (bottomIsAuto) { + // Any 'auto' on 'margin-top' or 'margin-bottom' are replaced with 0 + computedOffsets.bottom = containingBlockHeight - computedOffsets.top - + computedMargin.top - mComputedBorderPadding.top - computedHeight - + mComputedBorderPadding.bottom - computedMargin.bottom; + + } else if (marginTopIsAuto || marginBottomIsAuto) { + // All that's left to solve for are 'auto' values for 'margin-top' and + // 'margin-bottom' + if (NS_FRAME_IS_REPLACED(frameType)) { + // We can't solve for 'auto' values for 'margin-top' and 'margin-bottom' + // until after we reflow the frame and it tells us its intrinsic height + if (marginTopIsAuto) { + computedMargin.top = NS_AUTOMARGIN; + } + if (marginBottomIsAuto) { + computedMargin.bottom = NS_AUTOMARGIN; + } } else { - // All that's left to solve for are 'auto' values for 'margin-top' and - // 'margin-bottom' - if ((eStyleUnit_Auto == mStyleSpacing->mMargin.GetTopUnit()) || - (eStyleUnit_Auto == mStyleSpacing->mMargin.GetBottomUnit())) { - - // Calculate the amount of space for margins - nscoord availMarginSpace = containingBlockHeight - computedOffsets.top - - mComputedBorderPadding.top - computedHeight - mComputedBorderPadding.bottom - - computedOffsets.bottom; - - if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetTopUnit()) { - if (eStyleUnit_Auto == mStyleSpacing->mMargin.GetBottomUnit()) { - // Both 'margin-top' and 'margin-bottom' are 'auto', so they get - // equal values - computedMargin.top = availMarginSpace / 2; - computedMargin.bottom = availMarginSpace - computedMargin.top; - } else { - // Just 'margin-top' is 'auto' - computedMargin.top = availMarginSpace - computedMargin.bottom; - } - } else { - // Just 'margin-bottom' is 'auto' + // Calculate the amount of space for margins + nscoord availMarginSpace = containingBlockHeight - computedOffsets.top - + mComputedBorderPadding.top - computedHeight - mComputedBorderPadding.bottom - + computedOffsets.bottom; + + if (marginTopIsAuto) { + if (marginBottomIsAuto) { + // Both 'margin-top' and 'margin-bottom' are 'auto', so they get + // equal values + computedMargin.top = availMarginSpace / 2; computedMargin.bottom = availMarginSpace - computedMargin.top; + } else { + // Just 'margin-top' is 'auto' + computedMargin.top = availMarginSpace - computedMargin.bottom; } + } else { + // Just 'margin-bottom' is 'auto' + computedMargin.bottom = availMarginSpace - computedMargin.top; } } } diff --git a/mozilla/layout/html/base/src/nsIHTMLReflow.h b/mozilla/layout/html/base/src/nsIHTMLReflow.h index 453a8b68165..6ea8441b1c5 100644 --- a/mozilla/layout/html/base/src/nsIHTMLReflow.h +++ b/mozilla/layout/html/base/src/nsIHTMLReflow.h @@ -280,6 +280,10 @@ struct nsHTMLReflowState : nsReflowState { static nsCSSFrameType DetermineFrameType(nsIFrame* aFrame); + void ComputeContainingBlockRectangle(const nsHTMLReflowState* aContainingBlockRS, + nscoord& aContainingBlockWidth, + nscoord& aContainingBlockHeight); + protected: // This method initializes various data members. It is automatically // called by the various constructors @@ -292,10 +296,6 @@ protected: nscoord aContainingBlockWidth, nscoord aContainingBlockHeight); - void ComputeContainingBlockRectangle(const nsHTMLReflowState* aContainingBlockRS, - nscoord& aContainingBlockWidth, - nscoord& aContainingBlockHeight); - void ComputeRelativeOffsets(const nsHTMLReflowState* cbrs, nscoord aContainingBlockWidth, nscoord aContainingBlockHeight);