From 275b85f68e79f01e994ffdeaa77b7eb79150aaca Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Thu, 3 Mar 2011 13:18:42 -0800 Subject: [PATCH] Fix implementation of rules for auto margins on absolutely positioned elements; honor auto margins when only one margin is auto, even when the auto margin gets a negative value. (Bug 419100) r=roc Needed to help CSS 2.1 meet Proposed Recommendation entrance criteria. --- layout/generic/nsHTMLReflowState.cpp | 89 ++++++++++++------- ...-non-replaced-width-offset-margin-ref.html | 28 ++---- ...spos-replaced-width-offset-margin-ref.html | 46 ++++------ 3 files changed, 81 insertions(+), 82 deletions(-) diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index b16ef3f64a94..5a01849eace0 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -1313,32 +1313,50 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext, PRBool marginRightIsAuto = eStyleUnit_Auto == mStyleMargin->mMargin.GetRightUnit(); - if (availMarginSpace < 0 || - (!marginLeftIsAuto && !marginRightIsAuto)) { - // We're over-constrained so use the direction of the containing block - // to dictate which value to ignore. (And note that the spec says to ignore - // 'left' or 'right' rather than 'margin-left' or 'margin-right'.) - if (cbrs && - NS_STYLE_DIRECTION_RTL == cbrs->mStyleVisibility->mDirection) { - // Ignore the specified value for 'left'. - mComputedOffsets.left += availMarginSpace; - } else { - // Ignore the specified value for 'right'. - mComputedOffsets.right += availMarginSpace; - } - } else if (marginLeftIsAuto) { + if (marginLeftIsAuto) { if (marginRightIsAuto) { - // Both 'margin-left' and 'margin-right' are 'auto', so they get - // equal values - mComputedMargin.left = availMarginSpace / 2; - mComputedMargin.right = availMarginSpace - mComputedMargin.left; + if (availMarginSpace < 0) { + // Note that this case is different from the neither-'auto' + // case below, where the spec says to ignore 'left'/'right'. + if (cbrs && + NS_STYLE_DIRECTION_RTL == cbrs->mStyleVisibility->mDirection) { + // Ignore the specified value for 'margin-left'. + mComputedMargin.left = availMarginSpace; + } else { + // Ignore the specified value for 'margin-right'. + mComputedMargin.right = availMarginSpace; + } + } else { + // Both 'margin-left' and 'margin-right' are 'auto', so they get + // equal values + mComputedMargin.left = availMarginSpace / 2; + mComputedMargin.right = availMarginSpace - mComputedMargin.left; + } } else { // Just 'margin-left' is 'auto' mComputedMargin.left = availMarginSpace; } } else { - // Just 'margin-right' is 'auto' - mComputedMargin.right = availMarginSpace; + if (marginRightIsAuto) { + // Just 'margin-right' is 'auto' + mComputedMargin.right = availMarginSpace; + } else { + // We're over-constrained so use the direction of the containing + // block to dictate which value to ignore. (And note that the + // spec says to ignore 'left' or 'right' rather than + // 'margin-left' or 'margin-right'.) + // Note that this case is different from the both-'auto' case + // above, where the spec says to ignore + // 'margin-left'/'margin-right'. + if (cbrs && + NS_STYLE_DIRECTION_RTL == cbrs->mStyleVisibility->mDirection) { + // Ignore the specified value for 'left'. + mComputedOffsets.left += availMarginSpace; + } else { + // Ignore the specified value for 'right'. + mComputedOffsets.right += availMarginSpace; + } + } } } @@ -1392,24 +1410,31 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext, PRBool marginBottomIsAuto = eStyleUnit_Auto == mStyleMargin->mMargin.GetBottomUnit(); - if (availMarginSpace < 0 || (!marginTopIsAuto && !marginBottomIsAuto)) { - // We're over-constrained so ignore the specified value for - // 'bottom'. (And note that the spec says to ignore 'bottom' - // rather than 'margin-bottom'.) - mComputedOffsets.bottom += availMarginSpace; - } else if (marginTopIsAuto) { + if (marginTopIsAuto) { if (marginBottomIsAuto) { - // Both 'margin-top' and 'margin-bottom' are 'auto', so they get - // equal values - mComputedMargin.top = availMarginSpace / 2; - mComputedMargin.bottom = availMarginSpace - mComputedMargin.top; + if (availMarginSpace < 0) { + // FIXME: Note that the spec doesn't actually say we should do this! + mComputedMargin.bottom = availMarginSpace; + } else { + // Both 'margin-top' and 'margin-bottom' are 'auto', so they get + // equal values + mComputedMargin.top = availMarginSpace / 2; + mComputedMargin.bottom = availMarginSpace - mComputedMargin.top; + } } else { // Just 'margin-top' is 'auto' mComputedMargin.top = availMarginSpace; } } else { - // Just 'margin-bottom' is 'auto' - mComputedMargin.bottom = availMarginSpace; + if (marginBottomIsAuto) { + // Just 'margin-bottom' is 'auto' + mComputedMargin.bottom = availMarginSpace; + } else { + // We're over-constrained so ignore the specified value for + // 'bottom'. (And note that the spec says to ignore 'bottom' + // rather than 'margin-bottom'.) + mComputedOffsets.bottom += availMarginSpace; + } } } } diff --git a/layout/reftests/box-properties/abspos-non-replaced-width-offset-margin-ref.html b/layout/reftests/box-properties/abspos-non-replaced-width-offset-margin-ref.html index 54b5f56d5213..ce3348a26a17 100644 --- a/layout/reftests/box-properties/abspos-non-replaced-width-offset-margin-ref.html +++ b/layout/reftests/box-properties/abspos-non-replaced-width-offset-margin-ref.html @@ -11,16 +11,6 @@ div { height: 1px; background: navy; } - - @@ -354,14 +344,13 @@ Differences between CSS 2.1 and this reference:
- -
-
-
-
+
+
+
+
@@ -391,15 +380,14 @@ Differences between CSS 2.1 and this reference:
-
-
-
-
-
+
+
+
+
diff --git a/layout/reftests/box-properties/abspos-replaced-width-offset-margin-ref.html b/layout/reftests/box-properties/abspos-replaced-width-offset-margin-ref.html index 5da4d03d57e9..6427df2f3da2 100644 --- a/layout/reftests/box-properties/abspos-replaced-width-offset-margin-ref.html +++ b/layout/reftests/box-properties/abspos-replaced-width-offset-margin-ref.html @@ -12,16 +12,6 @@ div { height: 1px; background: blue; - - @@ -61,14 +51,13 @@ Differences between CSS 2.1 and this reference:
- -
-
-
-
+
+
+
+
@@ -98,15 +87,14 @@ Differences between CSS 2.1 and this reference:
-
-
-
-
-
+
+
+
+
@@ -504,14 +492,13 @@ Differences between CSS 2.1 and this reference:
- -
-
-
-
+
+
+
+
@@ -541,15 +528,14 @@ Differences between CSS 2.1 and this reference:
-
-
-
-
-
+
+
+
+