diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp
index 6370c7d76fcd..63c3f2a7db0f 100644
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -1129,16 +1129,51 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
} else {
// Only 'width' is 'auto' so just solve for 'width'
- mComputedWidth = containingBlockWidth - mComputedOffsets.left -
+ PRInt32 autoWidth = containingBlockWidth - mComputedOffsets.left -
mComputedMargin.left - mComputedBorderPadding.left -
mComputedBorderPadding.right -
mComputedMargin.right - mComputedOffsets.right;
- mComputedWidth = PR_MAX(mComputedWidth, 0);
+ if (autoWidth < 0) {
+ autoWidth = 0;
+ }
+ mComputedWidth = autoWidth;
AdjustComputedWidth(PR_FALSE);
- // XXX If the direction is rtl then we need to reevaluate left...
+ if (autoWidth != mComputedWidth) {
+ // Re-calculate any 'auto' margin values since the computed width
+ // was adjusted by a 'min-width' or 'max-width'.
+ PRInt32 availMarginSpace = autoWidth - mComputedWidth;
+
+ if (eStyleUnit_Auto == mStyleMargin->mMargin.GetLeftUnit()) {
+ if (eStyleUnit_Auto == mStyleMargin->mMargin.GetRightUnit()) {
+ // Both margins are 'auto' so their computed values are equal.
+ mComputedMargin.left = availMarginSpace / 2;
+ mComputedMargin.right = availMarginSpace - mComputedMargin.left;
+ } else {
+ mComputedMargin.left = availMarginSpace - mComputedMargin.right;
+ }
+ } else if (eStyleUnit_Auto == mStyleMargin->mMargin.GetRightUnit()) {
+ mComputedMargin.right = availMarginSpace - mComputedMargin.left;
+ } else {
+ // We're over-constrained - ignore the value for 'left' or 'right'
+ // and solve for that value.
+ if (NS_STYLE_DIRECTION_LTR == direction) {
+ // ignore 'right'
+ mComputedOffsets.right = containingBlockWidth - mComputedOffsets.left -
+ mComputedMargin.left - mComputedBorderPadding.left -
+ mComputedWidth - mComputedBorderPadding.right -
+ mComputedMargin.right;
+ } else {
+ // ignore 'left'
+ mComputedOffsets.left = containingBlockWidth -
+ mComputedMargin.left - mComputedBorderPadding.left -
+ mComputedWidth - mComputedBorderPadding.right -
+ mComputedMargin.right - mComputedOffsets.right;
+ }
+ }
+ }
}
} else {
@@ -1280,14 +1315,41 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
} else {
// Only 'height' is 'auto' so just solve for 'height'
- mComputedHeight = containingBlockHeight - mComputedOffsets.top -
+ PRInt32 autoHeight = containingBlockHeight - mComputedOffsets.top -
mComputedMargin.top - mComputedBorderPadding.top -
mComputedBorderPadding.bottom -
mComputedMargin.bottom - mComputedOffsets.bottom;
- mComputedHeight = PR_MAX(mComputedHeight, 0);
+ if (autoHeight < 0) {
+ autoHeight = 0;
+ }
+ mComputedHeight = autoHeight;
AdjustComputedHeight(PR_FALSE);
+
+ if (autoHeight != mComputedHeight) {
+ // Re-calculate any 'auto' margin values since the computed height
+ // was adjusted by a 'min-height' or 'max-height'.
+ PRInt32 availMarginSpace = autoHeight - mComputedHeight;
+
+ if (eStyleUnit_Auto == mStyleMargin->mMargin.GetTopUnit()) {
+ if (eStyleUnit_Auto == mStyleMargin->mMargin.GetBottomUnit()) {
+ // Both margins are 'auto' so their computed values are equal
+ mComputedMargin.top = availMarginSpace / 2;
+ mComputedMargin.bottom = availMarginSpace - mComputedMargin.top;
+ } else {
+ mComputedMargin.top = availMarginSpace - mComputedMargin.bottom;
+ }
+ } else if (eStyleUnit_Auto == mStyleMargin->mMargin.GetBottomUnit()) {
+ mComputedMargin.bottom = availMarginSpace - mComputedMargin.top;
+ } else {
+ // We're over-constrained - ignore 'bottom'.
+ mComputedOffsets.bottom = containingBlockHeight - mComputedOffsets.top -
+ mComputedMargin.top - mComputedBorderPadding.top -
+ mComputedHeight - mComputedBorderPadding.bottom -
+ mComputedMargin.bottom;
+ }
+ }
}
} else {