Fix places where I missed clamping negative calc() to 0. (Bug 585715) r=bzbarsky a2.0=blocking2.0:beta6
authorL. David Baron <dbaron@dbaron.org>
Thu, 09 Sep 2010 08:21:46 -0700
changeset 52283 3f2ae0cc2cb894e2f3e8af95aede888d3b7713e1
parent 52282 d8e37eb0c77cd85b2c1d58116e72ff76e63969c0
child 52284 1ad67ed26a45194e67cc4e1b6538343558af6f65
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs585715
milestone2.0b6pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Fix places where I missed clamping negative calc() to 0. (Bug 585715) r=bzbarsky a2.0=blocking2.0:beta6
layout/base/nsLayoutUtils.h
layout/generic/nsContainerFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsInlineFrame.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsStyleStruct.cpp
layout/style/test/property_database.js
layout/style/test/test_value_computation.html
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -800,16 +800,28 @@ public:
 
   static PRBool IsPaddingZero(const nsStyleCoord &aCoord)
   {
     return (aCoord.GetUnit() == eStyleUnit_Coord &&
             aCoord.GetCoordValue() == 0) ||
            (aCoord.GetUnit() == eStyleUnit_Percent &&
             aCoord.GetPercentValue() == 0.0) ||
            (aCoord.IsCalcUnit() &&
+            // clamp negative calc() to 0
+            nsRuleNode::ComputeCoordPercentCalc(aCoord, nscoord_MAX) <= 0 &&
+            nsRuleNode::ComputeCoordPercentCalc(aCoord, 0) <= 0);
+  }
+
+  static PRBool IsMarginZero(const nsStyleCoord &aCoord)
+  {
+    return (aCoord.GetUnit() == eStyleUnit_Coord &&
+            aCoord.GetCoordValue() == 0) ||
+           (aCoord.GetUnit() == eStyleUnit_Percent &&
+            aCoord.GetPercentValue() == 0.0) ||
+           (aCoord.IsCalcUnit() &&
             nsRuleNode::ComputeCoordPercentCalc(aCoord, nscoord_MAX) == 0 &&
             nsRuleNode::ComputeCoordPercentCalc(aCoord, 0) == 0);
   }
 
   /*
    * Calculate the used values for 'width' and 'height' for a replaced element.
    *
    *   http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -624,17 +624,18 @@ nsContainerFrame::DoInlineIntrinsicWidth
   // messy the bidi situations are, since per CSS2.1 section 8.6
   // (implemented in bug 328168), the startSide border is always on the
   // first line.
   // This frame is a first-in-flow, but it might have a previous bidi
   // continuation, in which case that continuation should handle the startSide
   // border.
   if (!GetPrevContinuation()) {
     aData->currentLine +=
-      GetCoord(stylePadding->mPadding.Get(startSide), 0) +
+      // clamp negative calc() to 0
+      NS_MAX(GetCoord(stylePadding->mPadding.Get(startSide), 0), 0) +
       styleBorder->GetActualBorderWidth(startSide) +
       GetCoord(styleMargin->mMargin.Get(startSide), 0);
   }
 
   const nsLineList_iterator* savedLine = aData->line;
   nsIFrame* const savedLineContainer = aData->lineContainer;
 
   nsContainerFrame *lastInFlow;
@@ -665,17 +666,18 @@ nsContainerFrame::DoInlineIntrinsicWidth
   // messy the bidi situations are, since per CSS2.1 section 8.6
   // (implemented in bug 328168), the endSide border is always on the
   // last line.
   // We reached the last-in-flow, but it might have a next bidi
   // continuation, in which case that continuation should handle
   // the endSide border.
   if (!lastInFlow->GetNextContinuation()) {
     aData->currentLine +=
-      GetCoord(stylePadding->mPadding.Get(endSide), 0) +
+      // clamp negative calc() to 0
+      NS_MAX(GetCoord(stylePadding->mPadding.Get(endSide), 0), 0) +
       styleBorder->GetActualBorderWidth(endSide) +
       GetCoord(styleMargin->mMargin.Get(endSide), 0);
   }
 }
 
 /* virtual */ nsSize
 nsContainerFrame::ComputeAutoSize(nsIRenderingContext *aRenderingContext,
                                   nsSize aCBSize, nscoord aAvailableWidth,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3244,49 +3244,55 @@ struct LengthPercentPairWithMinMaxCalcOp
   }
 
 };
 
 static void
 AddCoord(const nsStyleCoord& aStyle,
          nsIRenderingContext* aRenderingContext,
          nsIFrame* aFrame,
-         nscoord* aCoord, float* aPercent)
+         nscoord* aCoord, float* aPercent,
+         PRBool aClampNegativeToZero)
 {
   if (!aStyle.IsCoordPercentCalcUnit()) {
     return;
   }
 
   LengthPercentPairWithMinMaxCalcOps ops;
   LengthPercentPairWithMinMaxCalcOps::result_type pair =
     css::ComputeCalc(aStyle, ops);
+  if (aClampNegativeToZero) {
+    // This is far from ideal when one is negative and one is positive.
+    pair.mLength = NS_MAX(pair.mLength, 0);
+    pair.mPercent = NS_MAX(pair.mPercent, 0.0f);
+  }
   *aCoord += pair.mLength;
   *aPercent += pair.mPercent;
 }
 
 /* virtual */ nsIFrame::IntrinsicWidthOffsetData
 nsFrame::IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext)
 {
   IntrinsicWidthOffsetData result;
 
   // FIXME: The handling of calc() with min() and max() by AddCoord
   // is a rough approximation.  It could be improved, but only by
   // changing the IntrinsicWidthOffsets API substantially.  See the
   // comment above LengthPercentPairWithMinMaxCalcOps.
   const nsStyleMargin *styleMargin = GetStyleMargin();
   AddCoord(styleMargin->mMargin.GetLeft(), aRenderingContext, this,
-           &result.hMargin, &result.hPctMargin);
+           &result.hMargin, &result.hPctMargin, PR_FALSE);
   AddCoord(styleMargin->mMargin.GetRight(), aRenderingContext, this,
-           &result.hMargin, &result.hPctMargin);
+           &result.hMargin, &result.hPctMargin, PR_FALSE);
 
   const nsStylePadding *stylePadding = GetStylePadding();
   AddCoord(stylePadding->mPadding.GetLeft(), aRenderingContext, this,
-           &result.hPadding, &result.hPctPadding);
+           &result.hPadding, &result.hPctPadding, PR_TRUE);
   AddCoord(stylePadding->mPadding.GetRight(), aRenderingContext, this,
-           &result.hPadding, &result.hPctPadding);
+           &result.hPadding, &result.hPctPadding, PR_TRUE);
 
   const nsStyleBorder *styleBorder = GetStyleBorder();
   result.hBorder += styleBorder->GetActualBorderWidth(NS_SIDE_LEFT);
   result.hBorder += styleBorder->GetActualBorderWidth(NS_SIDE_RIGHT);
 
   const nsStyleDisplay *disp = GetStyleDisplay();
   if (IsThemed(disp)) {
     nsPresContext *presContext = PresContext();
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -2182,31 +2182,32 @@ nsCSSOffsetState::ComputeMargin(nscoord 
 
 void
 nsCSSOffsetState::ComputePadding(nscoord aContainingBlockWidth)
 {
   // If style can provide us the padding directly, then use it.
   const nsStylePadding *stylePadding = frame->GetStylePadding();
   if (!stylePadding->GetPadding(mComputedPadding)) {
     // We have to compute the value
-    mComputedPadding.left = nsLayoutUtils::
+    // clamp negative calc() results to 0
+    mComputedPadding.left = NS_MAX(0, nsLayoutUtils::
       ComputeWidthDependentValue(aContainingBlockWidth,
-                                 stylePadding->mPadding.GetLeft());
-    mComputedPadding.right = nsLayoutUtils::
+                                 stylePadding->mPadding.GetLeft()));
+    mComputedPadding.right = NS_MAX(0, nsLayoutUtils::
       ComputeWidthDependentValue(aContainingBlockWidth,
-                                 stylePadding->mPadding.GetRight());
+                                 stylePadding->mPadding.GetRight()));
 
     // According to the CSS2 spec, percentages are calculated with respect to
     // containing block width for padding-top and padding-bottom
-    mComputedPadding.top = nsLayoutUtils::
+    mComputedPadding.top = NS_MAX(0, nsLayoutUtils::
       ComputeWidthDependentValue(aContainingBlockWidth,
-                                 stylePadding->mPadding.GetTop());
-    mComputedPadding.bottom = nsLayoutUtils::
+                                 stylePadding->mPadding.GetTop()));
+    mComputedPadding.bottom = NS_MAX(0, nsLayoutUtils::
       ComputeWidthDependentValue(aContainingBlockWidth,
-                                 stylePadding->mPadding.GetBottom());
+                                 stylePadding->mPadding.GetBottom()));
 
     frame->Properties().Set(nsIFrame::UsedPaddingProperty(),
                             new nsMargin(mComputedPadding));
   }
   // a table row/col group, row/col doesn't have padding
   // XXXldb Neither do border-collapse tables.
   nsIAtom* frameType = frame->GetType();
   if (nsGkAtoms::tableRowGroupFrame == frameType ||
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -92,17 +92,17 @@ nsInlineFrame::GetType() const
 {
   return nsGkAtoms::inlineFrame;
 }
 
 static inline PRBool
 IsMarginZero(const nsStyleCoord &aCoord)
 {
   return aCoord.GetUnit() == eStyleUnit_Auto ||
-         nsLayoutUtils::IsPaddingZero(aCoord);
+         nsLayoutUtils::IsMarginZero(aCoord);
 }
 
 /* virtual */ PRBool
 nsInlineFrame::IsSelfEmpty()
 {
 #if 0
   // I used to think inline frames worked this way, but it seems they
   // don't.  At least not in our codebase.
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -757,33 +757,33 @@ nsComputedDOMStyle::DoGetColumnCount(nsI
 nsresult
 nsComputedDOMStyle::DoGetColumnWidth(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
   // XXX fix the auto case. When we actually have a column frame, I think
   // we should return the computed column width.
-  SetValueToCoord(val, GetStyleColumn()->mColumnWidth);
+  SetValueToCoord(val, GetStyleColumn()->mColumnWidth, PR_TRUE);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetColumnGap(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
   const nsStyleColumn* column = GetStyleColumn();
   if (column->mColumnGap.GetUnit() == eStyleUnit_Normal) {
     val->SetAppUnits(GetStyleFont()->mFont.size);
   } else {
-    SetValueToCoord(val, GetStyleColumn()->mColumnGap);
+    SetValueToCoord(val, GetStyleColumn()->mColumnGap, PR_TRUE);
   }
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetColumnRuleWidth(nsIDOMCSSValue** aValue)
@@ -1005,19 +1005,19 @@ nsComputedDOMStyle::DoGetMozTransformOri
    */
   nsRefPtr<nsROCSSPrimitiveValue> width = GetROCSSPrimitiveValue();
   nsRefPtr<nsROCSSPrimitiveValue> height = GetROCSSPrimitiveValue();
   if (!width || !height)
     return NS_ERROR_OUT_OF_MEMORY;
 
   /* Now, get the values. */
   const nsStyleDisplay* display = GetStyleDisplay();
-  SetValueToCoord(width, display->mTransformOrigin[0],
+  SetValueToCoord(width, display->mTransformOrigin[0], PR_FALSE,
                   &nsComputedDOMStyle::GetFrameBoundsWidthForTransform);
-  SetValueToCoord(height, display->mTransformOrigin[1],
+  SetValueToCoord(height, display->mTransformOrigin[1], PR_FALSE,
                   &nsComputedDOMStyle::GetFrameBoundsHeightForTransform);
 
   /* Store things as a value list, fail if we can't get one. */
   nsRefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(PR_FALSE);
   if (!valueList)
     return NS_ERROR_OUT_OF_MEMORY;
 
   /* Chain on width and height, fail if we can't. */
@@ -1565,17 +1565,17 @@ nsComputedDOMStyle::GetImageRectString(n
   // <top>, <right>, <bottom>, <left>
   NS_FOR_CSS_SIDES(side) {
     nsROCSSPrimitiveValue *valSide = GetROCSSPrimitiveValue();
     if (!valSide || !valueList->AppendCSSValue(valSide)) {
       delete valSide;
       delete valueList;
       return NS_ERROR_OUT_OF_MEMORY;
     }
-    SetValueToCoord(valSide, aCropRect.Get(side));
+    SetValueToCoord(valSide, aCropRect.Get(side), PR_FALSE);
   }
 
   nsAutoString argumentString;
   valueList->GetCssText(argumentString);
   delete valueList;
 
   aString = NS_LITERAL_STRING("-moz-image-rect(") +
             argumentString +
@@ -2123,17 +2123,17 @@ nsComputedDOMStyle::DoGetMarginRightWidt
 }
 
 nsresult
 nsComputedDOMStyle::DoGetMarkerOffset(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStyleContent()->mMarkerOffset);
+  SetValueToCoord(val, GetStyleContent()->mMarkerOffset, PR_FALSE);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetOutline(nsIDOMCSSValue** aValue)
 {
@@ -2257,17 +2257,17 @@ nsComputedDOMStyle::GetEllipseRadii(cons
   const nsStyleCoord& radiusY
     = aRadius.Get(NS_FULL_TO_HALF_CORNER(aFullCorner, PR_TRUE));
 
   // for compatibility, return a single value if X and Y are equal
   if (radiusX == radiusY) {
     nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
     NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-    SetValueToCoord(val, radiusX,
+    SetValueToCoord(val, radiusX, PR_TRUE,
                     &nsComputedDOMStyle::GetFrameBorderRectWidth);
 
     NS_ADDREF(*aValue = val);
     return NS_OK;
   } else {
     nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE);
     NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
 
@@ -2281,19 +2281,19 @@ nsComputedDOMStyle::GetEllipseRadii(cons
     nsROCSSPrimitiveValue *valY = GetROCSSPrimitiveValue();
     if (!valY || !valueList->AppendCSSValue(valY)) {
       delete valY;
       // valX deleted by valueList destructor
       delete valueList;
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    SetValueToCoord(valX, radiusX,
+    SetValueToCoord(valX, radiusX, PR_TRUE,
                     &nsComputedDOMStyle::GetFrameBorderRectWidth);
-    SetValueToCoord(valY, radiusY,
+    SetValueToCoord(valY, radiusY, PR_TRUE,
                     &nsComputedDOMStyle::GetFrameBorderRectWidth);
 
     NS_ADDREF(*aValue = valueList);
     return NS_OK;
   }
 }
 
 nsresult
@@ -2398,17 +2398,17 @@ nsComputedDOMStyle::DoGetBoxShadow(nsIDO
 }
 
 nsresult
 nsComputedDOMStyle::DoGetZIndex(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStylePosition()->mZIndex);
+  SetValueToCoord(val, GetStylePosition()->mZIndex, PR_FALSE);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetListStyleImage(nsIDOMCSSValue** aValue)
 {
@@ -2516,31 +2516,31 @@ nsComputedDOMStyle::DoGetLineHeight(nsID
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
   nscoord lineHeight;
   if (GetLineHeightCoord(lineHeight)) {
     val->SetAppUnits(lineHeight);
   } else {
-    SetValueToCoord(val, GetStyleText()->mLineHeight,
+    SetValueToCoord(val, GetStyleText()->mLineHeight, PR_TRUE,
                     nsnull, nsCSSProps::kLineHeightKTable);
   }
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetVerticalAlign(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStyleTextReset()->mVerticalAlign,
+  SetValueToCoord(val, GetStyleTextReset()->mVerticalAlign, PR_FALSE,
                   &nsComputedDOMStyle::GetLineHeightCoord,
                   nsCSSProps::kVerticalAlignKTable);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
@@ -2585,17 +2585,17 @@ nsComputedDOMStyle::DoGetTextDecoration(
 }
 
 nsresult
 nsComputedDOMStyle::DoGetTextIndent(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStyleText()->mTextIndent,
+  SetValueToCoord(val, GetStyleText()->mTextIndent, PR_FALSE,
                   &nsComputedDOMStyle::GetCBContentWidth);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetTextShadow(nsIDOMCSSValue** aValue)
@@ -2632,17 +2632,17 @@ nsComputedDOMStyle::DoGetMozTabSize(nsID
 }
 
 nsresult
 nsComputedDOMStyle::DoGetLetterSpacing(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStyleText()->mLetterSpacing);
+  SetValueToCoord(val, GetStyleText()->mLetterSpacing, PR_FALSE);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetWordSpacing(nsIDOMCSSValue** aValue)
 {
@@ -2955,18 +2955,17 @@ nsComputedDOMStyle::DoGetBorderImage(nsI
   // four split numbers
   NS_FOR_CSS_SIDES(side) {
     nsROCSSPrimitiveValue *valSplit = GetROCSSPrimitiveValue();
     if (!valSplit || !valueList->AppendCSSValue(valSplit)) {
       delete valSplit;
       delete valueList;
       return NS_ERROR_OUT_OF_MEMORY;
     }
-    SetValueToCoord(valSplit, border->mBorderImageSplit.Get(side), nsnull,
-                    nsnull);
+    SetValueToCoord(valSplit, border->mBorderImageSplit.Get(side), PR_TRUE);
   }
 
   // copy of border-width
   if (border->mHaveBorderImageWidth) {
     nsROCSSPrimitiveValue *slash = GetROCSSPrimitiveValue();
     if (!slash || !valueList->AppendCSSValue(slash)) {
       delete slash;
       delete valueList;
@@ -3327,24 +3326,24 @@ nsComputedDOMStyle::DoGetHeight(nsIDOMCS
     AssertFlushedPendingReflows();
 
     val->SetAppUnits(mInnerFrame->GetContentRect().height);
   } else {
     const nsStylePosition *positionData = GetStylePosition();
 
     nscoord minHeight =
       StyleCoordToNSCoord(positionData->mMinHeight,
-                          &nsComputedDOMStyle::GetCBContentHeight, 0);
+                          &nsComputedDOMStyle::GetCBContentHeight, 0, PR_TRUE);
 
     nscoord maxHeight =
       StyleCoordToNSCoord(positionData->mMaxHeight,
                           &nsComputedDOMStyle::GetCBContentHeight,
-                          nscoord_MAX);
-
-    SetValueToCoord(val, positionData->mHeight, nsnull, nsnull,
+                          nscoord_MAX, PR_TRUE);
+
+    SetValueToCoord(val, positionData->mHeight, PR_TRUE, nsnull, nsnull,
                     minHeight, maxHeight);
   }
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
@@ -3369,78 +3368,78 @@ nsComputedDOMStyle::DoGetWidth(nsIDOMCSS
     AssertFlushedPendingReflows();
 
     val->SetAppUnits(mInnerFrame->GetContentRect().width);
   } else {
     const nsStylePosition *positionData = GetStylePosition();
 
     nscoord minWidth =
       StyleCoordToNSCoord(positionData->mMinWidth,
-                          &nsComputedDOMStyle::GetCBContentWidth, 0);
+                          &nsComputedDOMStyle::GetCBContentWidth, 0, PR_TRUE);
 
     nscoord maxWidth =
       StyleCoordToNSCoord(positionData->mMaxWidth,
                           &nsComputedDOMStyle::GetCBContentWidth,
-                          nscoord_MAX);
-
-    SetValueToCoord(val, positionData->mWidth, nsnull,
+                          nscoord_MAX, PR_TRUE);
+
+    SetValueToCoord(val, positionData->mWidth, PR_TRUE, nsnull,
                     nsCSSProps::kWidthKTable, minWidth, maxWidth);
   }
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetMaxHeight(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStylePosition()->mMaxHeight,
+  SetValueToCoord(val, GetStylePosition()->mMaxHeight, PR_TRUE,
                   &nsComputedDOMStyle::GetCBContentHeight);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetMaxWidth(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStylePosition()->mMaxWidth,
+  SetValueToCoord(val, GetStylePosition()->mMaxWidth, PR_TRUE,
                   &nsComputedDOMStyle::GetCBContentWidth,
                   nsCSSProps::kWidthKTable);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetMinHeight(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStylePosition()->mMinHeight,
+  SetValueToCoord(val, GetStylePosition()->mMinHeight, PR_TRUE,
                   &nsComputedDOMStyle::GetCBContentHeight);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetMinWidth(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStylePosition()->mMinWidth,
+  SetValueToCoord(val, GetStylePosition()->mMinWidth, PR_TRUE,
                   &nsComputedDOMStyle::GetCBContentWidth,
                   nsCSSProps::kWidthKTable);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
@@ -3606,43 +3605,43 @@ nsComputedDOMStyle::GetRelativeOffset(mo
   }
   PercentageBaseGetter baseGetter;
   if (aSide == NS_SIDE_LEFT || aSide == NS_SIDE_RIGHT) {
     baseGetter = &nsComputedDOMStyle::GetCBContentWidth;
   } else {
     baseGetter = &nsComputedDOMStyle::GetCBContentHeight;
   }
 
-  val->SetAppUnits(sign * StyleCoordToNSCoord(coord, baseGetter, 0));
+  val->SetAppUnits(sign * StyleCoordToNSCoord(coord, baseGetter, 0, PR_FALSE));
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::GetStaticOffset(mozilla::css::Side aSide, nsIDOMCSSValue** aValue)
 
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStylePosition()->mOffset.Get(aSide));
+  SetValueToCoord(val, GetStylePosition()->mOffset.Get(aSide), PR_FALSE);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::GetPaddingWidthFor(mozilla::css::Side aSide, nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
   if (!mInnerFrame) {
-    SetValueToCoord(val, GetStylePadding()->mPadding.Get(aSide));
+    SetValueToCoord(val, GetStylePadding()->mPadding.Get(aSide), PR_TRUE);
   } else {
     AssertFlushedPendingReflows();
 
     val->SetAppUnits(mInnerFrame->GetUsedPadding().side(aSide));
   }
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
@@ -3773,17 +3772,17 @@ nsComputedDOMStyle::GetBorderColorFor(mo
 
 nsresult
 nsComputedDOMStyle::GetMarginWidthFor(mozilla::css::Side aSide, nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
   if (!mInnerFrame) {
-    SetValueToCoord(val, GetStyleMargin()->mMargin.Get(aSide));
+    SetValueToCoord(val, GetStyleMargin()->mMargin.Get(aSide), PR_FALSE);
   } else {
     AssertFlushedPendingReflows();
 
     val->SetAppUnits(mInnerFrame->GetUsedMargin().side(aSide));
   }
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
@@ -3849,16 +3848,17 @@ struct StyleCoordSerializeCalcOps {
 private:
   nsAString &mResult;
 };
 
 
 void
 nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue* aValue,
                                     const nsStyleCoord& aCoord,
+                                    PRBool aClampNegativeCalc,
                                     PercentageBaseGetter aPercentageBaseGetter,
                                     const PRInt32 aTable[],
                                     nscoord aMinAppUnits,
                                     nscoord aMaxAppUnits)
 {
   NS_PRECONDITION(aValue, "Must have a value to work with");
 
   switch (aCoord.GetUnit()) {
@@ -3909,21 +3909,31 @@ nsComputedDOMStyle::SetValueToCoord(nsRO
       aValue->SetIdent(eCSSKeyword_none);
       break;
 
     default:
       if (aCoord.IsCalcUnit()) {
         nscoord percentageBase;
         if (!aCoord.CalcHasPercent()) {
           nscoord val = nsRuleNode::ComputeCoordPercentCalc(aCoord, 0);
+          if (aClampNegativeCalc && val < 0) {
+            NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(),
+                              "parser should have rejected value");
+            val = 0;
+          }
           aValue->SetAppUnits(NS_MAX(aMinAppUnits, NS_MIN(val, aMaxAppUnits)));
         } else if (aPercentageBaseGetter &&
                    (this->*aPercentageBaseGetter)(percentageBase)) {
           nscoord val =
             nsRuleNode::ComputeCoordPercentCalc(aCoord, percentageBase);
+          if (aClampNegativeCalc && val < 0) {
+            NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(),
+                              "parser should have rejected value");
+            val = 0;
+          }
           aValue->SetAppUnits(NS_MAX(aMinAppUnits, NS_MIN(val, aMaxAppUnits)));
         } else {
           nsAutoString tmp;
           StyleCoordSerializeCalcOps ops(tmp);
           css::SerializeCalc(aCoord, ops);
           aValue->SetString(tmp); // not really SetString
         }
       } else {
@@ -3931,26 +3941,34 @@ nsComputedDOMStyle::SetValueToCoord(nsRO
       }
       break;
   }
 }
 
 nscoord
 nsComputedDOMStyle::StyleCoordToNSCoord(const nsStyleCoord& aCoord,
                                         PercentageBaseGetter aPercentageBaseGetter,
-                                        nscoord aDefaultValue)
+                                        nscoord aDefaultValue,
+                                        PRBool aClampNegativeCalc)
 {
   NS_PRECONDITION(aPercentageBaseGetter, "Must have a percentage base getter");
   if (aCoord.GetUnit() == eStyleUnit_Coord) {
     return aCoord.GetCoordValue();
   }
   if (aCoord.GetUnit() == eStyleUnit_Percent || aCoord.IsCalcUnit()) {
     nscoord percentageBase;
     if ((this->*aPercentageBaseGetter)(percentageBase)) {
-      return nsRuleNode::ComputeCoordPercentCalc(aCoord, percentageBase);
+      nscoord result =
+        nsRuleNode::ComputeCoordPercentCalc(aCoord, percentageBase);
+      if (aClampNegativeCalc && result < 0) {
+        NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(),
+                          "parser should have rejected value");
+        result = 0;
+      }
+      return result;
     }
     // Fall through to returning aDefaultValue if we have no percentage base.
   }
 
   return aDefaultValue;
 }
 
 PRBool
@@ -4186,42 +4204,42 @@ nsComputedDOMStyle::DoGetStrokeDasharray
   for (PRUint32 i = 0; i < svg->mStrokeDasharrayLength; i++) {
     nsROCSSPrimitiveValue* dash = GetROCSSPrimitiveValue();
     if (!dash || !valueList->AppendCSSValue(dash)) {
       delete valueList;
       delete dash;
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    SetValueToCoord(dash, svg->mStrokeDasharray[i]);
+    SetValueToCoord(dash, svg->mStrokeDasharray[i], PR_TRUE);
   }
 
   NS_ADDREF(*aValue = valueList);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetStrokeDashoffset(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStyleSVG()->mStrokeDashoffset);
+  SetValueToCoord(val, GetStyleSVG()->mStrokeDashoffset, PR_FALSE);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetStrokeWidth(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
-  SetValueToCoord(val, GetStyleSVG()->mStrokeWidth);
+  SetValueToCoord(val, GetStyleSVG()->mStrokeWidth, PR_TRUE);
 
   NS_ADDREF(*aValue = val);
   return NS_OK;
 }
 
 nsresult
 nsComputedDOMStyle::DoGetFillOpacity(nsIDOMCSSValue** aValue)
 {
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -423,30 +423,32 @@ private:
    * passed in will be NS_MAX of the value in aMinAppUnits and the NS_MIN of
    * the actual value in aCoord and the value in aMaxAppUnits.
    *
    * XXXbz should caller pass in some sort of bitfield indicating which units
    * can be expected or something?
    */
   void SetValueToCoord(nsROCSSPrimitiveValue* aValue,
                        const nsStyleCoord& aCoord,
+                       PRBool aClampNegativeCalc,
                        PercentageBaseGetter aPercentageBaseGetter = nsnull,
                        const PRInt32 aTable[] = nsnull,
                        nscoord aMinAppUnits = nscoord_MIN,
                        nscoord aMaxAppUnits = nscoord_MAX);
 
   /**
    * If aCoord is a eStyleUnit_Coord returns the nscoord.  If it's
    * eStyleUnit_Percent, attempts to resolve the percentage base and returns
    * the resulting nscoord.  If it's some other unit or a percentge base can't
    * be determined, returns aDefaultValue.
    */
   nscoord StyleCoordToNSCoord(const nsStyleCoord& aCoord,
                               PercentageBaseGetter aPercentageBaseGetter,
-                              nscoord aDefaultValue);
+                              nscoord aDefaultValue,
+                              PRBool aClampNegativeCalc);
 
   PRBool GetCBContentWidth(nscoord& aWidth);
   PRBool GetCBContentHeight(nscoord& aWidth);
   PRBool GetFrameBoundsWidthForTransform(nscoord &aWidth);
   PRBool GetFrameBoundsHeightForTransform(nscoord &aHeight);
   PRBool GetFrameBorderRectWidth(nscoord& aWidth);
 
   struct ComputedStyleMapEntry
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -339,17 +339,19 @@ nsStylePadding::Destroy(nsPresContext* a
   this->~nsStylePadding();
   aContext->FreeToShell(sizeof(nsStylePadding), this);
 }
 
 void nsStylePadding::RecalcData()
 {
   if (IsFixedData(mPadding, PR_FALSE)) {
     NS_FOR_CSS_SIDES(side) {
-      mCachedPadding.side(side) = CalcCoord(mPadding.Get(side), nsnull, 0);
+      // Clamp negative calc() to 0.
+      mCachedPadding.side(side) =
+        NS_MAX(CalcCoord(mPadding.Get(side), nsnull, 0), 0);
     }
     mHasCachedPadding = PR_TRUE;
   }
   else
     mHasCachedPadding = PR_FALSE;
 }
 
 nsChangeHint nsStylePadding::CalcDifference(const nsStylePadding& aOther) const
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -159,17 +159,17 @@ var gCSSProperties = {
 		invalid_values: [ "red none", "red inherit", "red, green", "none red", "inherit red" ]
 	},
 	"-moz-border-radius": {
 		domProp: "MozBorderRadius",
 		inherited: false,
 		type: CSS_TYPE_TRUE_SHORTHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
 		subproperties: [ "-moz-border-radius-bottomleft", "-moz-border-radius-bottomright", "-moz-border-radius-topleft", "-moz-border-radius-topright" ],
-		initial_values: [ "0", "0px", "0px 0 0 0px" ], /* 0% ? */
+		initial_values: [ "0", "0px", "0%", "0px 0 0 0px", "-moz-calc(-2px)", "-moz-calc(-1%)", "-moz-calc(0px) -moz-calc(0pt) -moz-calc(0%) -moz-calc(0em)" ],
 		other_values: [ "3%", "1px", "2em", "3em 2px", "2pt 3% 4em", "2px 2px 2px 2px", // circular
 						"3% / 2%", "1px / 4px", "2em / 1em", "3em 2px / 2px 3em", "2pt 3% 4em / 4pt 1% 5em", "2px 2px 2px 2px / 4px 4px 4px 4px", "1pt / 2pt 3pt", "4pt 5pt / 3pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -181,17 +181,17 @@ var gCSSProperties = {
 					  ],
 		invalid_values: [ "2px -2px", "inherit 2px", "inherit / 2px", "2px inherit", "2px / inherit", "2px 2px 2px 2px 2px", "1px / 2px 2px 2px 2px 2px" ]
 	},
 	"-moz-border-radius-bottomleft": {
 		domProp: "MozBorderRadiusBottomleft",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
-		initial_values: [ "0", "0px" ], /* 0% ? */
+		initial_values: [ "0", "0px", "0%", "-moz-calc(-2px)", "-moz-calc(-1%)" ],
 		other_values: [ "3%", "1px", "2em", // circular
 						"3% 2%", "1px 4px", "2em 2pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -201,17 +201,17 @@ var gCSSProperties = {
 					  ],
 		invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
 	},
 	"-moz-border-radius-bottomright": {
 		domProp: "MozBorderRadiusBottomright",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
-		initial_values: [ "0", "0px" ], /* 0% ? */
+		initial_values: [ "0", "0px", "0%", "-moz-calc(-2px)", "-moz-calc(-1%)" ],
 		other_values: [ "3%", "1px", "2em", // circular
 						"3% 2%", "1px 4px", "2em 2pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -221,17 +221,17 @@ var gCSSProperties = {
 					  ],
 		invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
 	},
 	"-moz-border-radius-topleft": {
 		domProp: "MozBorderRadiusTopleft",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
-		initial_values: [ "0", "0px" ], /* 0% ? */
+		initial_values: [ "0", "0px", "0%", "-moz-calc(-2px)", "-moz-calc(-1%)" ],
 		other_values: [ "3%", "1px", "2em", // circular
 						"3% 2%", "1px 4px", "2em 2pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -241,17 +241,17 @@ var gCSSProperties = {
 					  ],
 		invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
 	},
 	"-moz-border-radius-topright": {
 		domProp: "MozBorderRadiusTopright",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
-		initial_values: [ "0", "0px" ], /* 0% ? */
+		initial_values: [ "0", "0px", "0%", "-moz-calc(-2px)", "-moz-calc(-1%)" ],
 		other_values: [ "3%", "1px", "2em", // circular
 						"3% 2%", "1px 4px", "2em 2pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -372,16 +372,18 @@ var gCSSProperties = {
 		other_values: [ "2px 2px", "2px 2px 1px", "2px 2px 2px 2px", "blue 3px 2px", "2px 2px 1px 5px green", "2px 2px red", "green 2px 2px 1px", "green 2px 2px, blue 1px 3px 4px", "currentColor 3px 3px", "blue 2px 2px, currentColor 1px 2px, 1px 2px 3px 2px orange", "3px 0 0 0", "inset 2px 2px 3px 4px black", "2px -2px green inset, 4px 4px 3px blue, inset 2px 2px",
 			/* calc() values */
 			"2px 2px -moz-calc(-5px)", /* clamped */
 			"-moz-calc(3em - 2px) 2px green",
 			"green -moz-calc(3em - 2px) 2px",
 			"2px -moz-min(2px,0.2em)",
 			"blue 2px -moz-min(2px,0.2em)",
 			"2px -moz-min(2px,0.2em) blue",
+			"-moz-calc(-2px) -moz-calc(-2px)",
+			"-2px -2px",
 			"-moz-calc(2px) -moz-calc(2px)",
 			"-moz-calc(2px) -moz-calc(2px) -moz-calc(2px)",
 			"-moz-calc(2px) -moz-calc(2px) -moz-calc(2px) -moz-calc(2px)"
 		],
 		invalid_values: [ "3% 3%", "1px 1px 1px 1px 1px", "2px 2px, none", "red 2px 2px blue", "inherit, 2px 2px", "2px 2px, inherit", "2px 2px -5px", "inset 4px 4px black inset", "inset inherit", "inset none" ]
 	},
 	"-moz-box-sizing": {
 		domProp: "MozBoxSizing",
@@ -618,52 +620,54 @@ var gCSSProperties = {
 	},
 	"-moz-margin-end": {
 		domProp: "MozMarginEnd",
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		get_computed: logical_box_prop_get_computed,
 		/* no subproperties */
 		/* auto may or may not be initial */
-		initial_values: [ "0", "0px", "0%", "0em", "0ex" ],
+		initial_values: [ "0", "0px", "0%", "0em", "0ex", "-moz-calc(0pt)", "-moz-calc(0% + 0px)" ],
 		other_values: [ "1px", "3em",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: []
 	},
 	"-moz-margin-start": {
 		domProp: "MozMarginStart",
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		get_computed: logical_box_prop_get_computed,
 		/* no subproperties */
 		/* auto may or may not be initial */
-		initial_values: [ "0", "0px", "0%", "0em", "0ex" ],
+		initial_values: [ "0", "0px", "0%", "0em", "0ex", "-moz-calc(0pt)", "-moz-calc(0% + 0px)" ],
 		other_values: [ "1px", "3em",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: []
 	},
 	"-moz-outline-radius": {
 		domProp: "MozOutlineRadius",
 		inherited: false,
 		type: CSS_TYPE_TRUE_SHORTHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
 		subproperties: [ "-moz-outline-radius-bottomleft", "-moz-outline-radius-bottomright", "-moz-outline-radius-topleft", "-moz-outline-radius-topright" ],
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(-2px)", "-moz-calc(-1%)", "-moz-calc(0px) -moz-calc(0pt) -moz-calc(0%) -moz-calc(0em)" ],
 		other_values: [ "3%", "1px", "2em", "3em 2px", "2pt 3% 4em", "2px 2px 2px 2px", // circular
 						"3% / 2%", "1px / 4px", "2em / 1em", "3em 2px / 2px 3em", "2pt 3% 4em / 4pt 1% 5em", "2px 2px 2px 2px / 4px 4px 4px 4px", "1pt / 2pt 3pt", "4pt 5pt / 3pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -675,17 +679,17 @@ var gCSSProperties = {
 					  ],
 		invalid_values: [ "2px -2px", "inherit 2px", "inherit / 2px", "2px inherit", "2px / inherit", "2px 2px 2px 2px 2px", "1px / 2px 2px 2px 2px 2px" ]
 	},
 	"-moz-outline-radius-bottomleft": {
 		domProp: "MozOutlineRadiusBottomleft",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(-2px)", "-moz-calc(-1%)", "-moz-calc(0px)" ],
 		other_values: [ "3%", "1px", "2em", // circular
 						"3% 2%", "1px 4px", "2em 2pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -695,17 +699,17 @@ var gCSSProperties = {
 					  ],
 		invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
 	},
 	"-moz-outline-radius-bottomright": {
 		domProp: "MozOutlineRadiusBottomright",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(-2px)", "-moz-calc(-1%)", "-moz-calc(0px)" ],
 		other_values: [ "3%", "1px", "2em", // circular
 						"3% 2%", "1px 4px", "2em 2pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -715,17 +719,17 @@ var gCSSProperties = {
 					  ],
 		invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
 	},
 	"-moz-outline-radius-topleft": {
 		domProp: "MozOutlineRadiusTopleft",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(-2px)", "-moz-calc(-1%)", "-moz-calc(0px)" ],
 		other_values: [ "3%", "1px", "2em", // circular
 						"3% 2%", "1px 4px", "2em 2pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -735,17 +739,17 @@ var gCSSProperties = {
 					  ],
 		invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
 	},
 	"-moz-outline-radius-topright": {
 		domProp: "MozOutlineRadiusTopright",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "width": "200px", "height": "100px", "display": "inline-block"},
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(-2px)", "-moz-calc(-1%)", "-moz-calc(0px)" ],
 		other_values: [ "3%", "1px", "2em", // circular
 						"3% 2%", "1px 4px", "2em 2pt", // elliptical
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(3*25px) 5px",
 			"5px -moz-calc(3*25px)",
 			"-moz-calc(20%) -moz-calc(3*25px)",
@@ -756,34 +760,34 @@ var gCSSProperties = {
 		invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
 	},
 	"-moz-padding-end": {
 		domProp: "MozPaddingEnd",
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		get_computed: logical_box_prop_get_computed,
 		/* no subproperties */
-		initial_values: [ "0", "0px", "0%", "0em", "0ex" ],
+		initial_values: [ "0", "0px", "0%", "0em", "0ex", "-moz-calc(0pt)", "-moz-calc(0% + 0px)", "-moz-calc(-3px)", "-moz-calc(-1%)" ],
 		other_values: [ "1px", "3em",
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: []
 	},
 	"-moz-padding-start": {
 		domProp: "MozPaddingStart",
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		get_computed: logical_box_prop_get_computed,
 		/* no subproperties */
-		initial_values: [ "0", "0px", "0%", "0em", "0ex" ],
+		initial_values: [ "0", "0px", "0%", "0em", "0ex", "-moz-calc(0pt)", "-moz-calc(0% + 0px)", "-moz-calc(-3px)", "-moz-calc(-1%)" ],
 		other_values: [ "1px", "3em",
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
@@ -1470,16 +1474,17 @@ var gCSSProperties = {
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		/* FIXME: run tests with multiple prerequisites */
 		prerequisites: { "position": "relative" },
 		/* XXX 0 may or may not be equal to auto */
 		initial_values: [ "auto" ],
 		other_values: [ "32px", "-3em", "12%",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: []
 	},
@@ -1715,16 +1720,17 @@ var gCSSProperties = {
 		initial_values: [ "normal", "400" ],
 		other_values: [ "bold", "100", "200", "300", "500", "600", "700", "800", "900", "bolder", "lighter" ],
 		invalid_values: [ "107", "399", "401", "699", "710" ]
 	},
 	"height": {
 		domProp: "height",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
+		/* FIXME: test zero, and test calc clamping */
 		initial_values: [ " auto" ],
 		/* computed value tests for height test more with display:block */
 		prerequisites: { "display": "block" },
 		other_values: [ "15px", "3em", "15%",
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
@@ -1746,16 +1752,17 @@ var gCSSProperties = {
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		/* FIXME: run tests with multiple prerequisites */
 		prerequisites: { "position": "relative" },
 		/* XXX 0 may or may not be equal to auto */
 		initial_values: [ "auto" ],
 		other_values: [ "32px", "-3em", "12%",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: []
 	},
@@ -1850,69 +1857,73 @@ var gCSSProperties = {
 		other_values: [ "3px 0", "2em 4px 2pt", "1em 2em 3px 4px" ],
 		invalid_values: []
 	},
 	"margin-bottom": {
 		domProp: "marginBottom",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		/* XXX testing auto has prerequisites */
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(0pt)", "-moz-calc(0% + 0px)" ],
 		other_values: [ "1px", "2em", "5%",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ ]
 	},
 	"margin-left": {
 		domProp: "marginLeft",
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		/* no subproperties */
 		/* XXX testing auto has prerequisites */
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(0pt)", "-moz-calc(0% + 0px)" ],
 		other_values: [ "1px", "2em", "5%", ".5px", "+32px", "+.789px", "-.328px", "+0.56px", "-0.974px", "237px", "-289px", "-056px", "1987.45px", "-84.32px",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ "..25px", ".+5px", ".px", "-.px", "++5px", "-+4px", "+-3px", "--7px", "+-.6px", "-+.5px", "++.7px", "--.4px" ]
 	},
 	"margin-right": {
 		domProp: "marginRight",
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		/* no subproperties */
 		/* XXX testing auto has prerequisites */
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(0pt)", "-moz-calc(0% + 0px)" ],
 		other_values: [ "1px", "2em", "5%",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ ]
 	},
 	"margin-top": {
 		domProp: "marginTop",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		/* XXX testing auto has prerequisites */
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(0pt)", "-moz-calc(0% + 0px)" ],
 		other_values: [ "1px", "2em", "5%",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ ]
 	},
@@ -1937,62 +1948,66 @@ var gCSSProperties = {
 	"max-height": {
 		domProp: "maxHeight",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "display": "block" },
 		initial_values: [ "none" ],
 		other_values: [ "30px", "50%", "0",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
+			"-moz-calc(0)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ "auto", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available" ]
 	},
 	"max-width": {
 		domProp: "maxWidth",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "display": "block" },
 		initial_values: [ "none" ],
 		other_values: [ "30px", "50%", "0", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
+			"-moz-calc(0)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ "auto" ]
 	},
 	"min-height": {
 		domProp: "minHeight",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "display": "block" },
-		initial_values: [ "0" ],
+		initial_values: [ "0", "-moz-calc(0em)", "-moz-calc(-2px)", "-moz-calc(-1%)" ],
 		other_values: [ "30px", "50%",
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ "auto", "none", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available" ]
 	},
 	"min-width": {
 		domProp: "minWidth",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		prerequisites: { "display": "block" },
-		initial_values: [ "0" ],
+		initial_values: [ "0", "-moz-calc(0em)", "-moz-calc(-2px)", "-moz-calc(-1%)" ],
 		other_values: [ "30px", "50%", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available",
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
@@ -2093,72 +2108,72 @@ var gCSSProperties = {
 		other_values: [ "auto", "scroll", "hidden" ],
 		invalid_values: []
 	},
 	"padding": {
 		domProp: "padding",
 		inherited: false,
 		type: CSS_TYPE_TRUE_SHORTHAND,
 		subproperties: [ "padding-top", "padding-right", "padding-bottom", "padding-left" ],
-		initial_values: [ "0", "0px 0 0em", "0% 0px 0em 0pt" ],
+		initial_values: [ "0", "0px 0 0em", "0% 0px 0em 0pt", "-moz-calc(0) -moz-calc(0em) -moz-calc(-2px) -moz-calc(-1%)" ],
 		other_values: [ "3px 0", "2em 4px 2pt", "1em 2em 3px 4px" ],
 		invalid_values: []
 	},
 	"padding-bottom": {
 		domProp: "paddingBottom",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(0pt)", "-moz-calc(0% + 0px)", "-moz-calc(-3px)", "-moz-calc(-1%)" ],
 		other_values: [ "1px", "2em", "5%",
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ ]
 	},
 	"padding-left": {
 		domProp: "paddingLeft",
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		/* no subproperties */
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(0pt)", "-moz-calc(0% + 0px)", "-moz-calc(-3px)", "-moz-calc(-1%)" ],
 		other_values: [ "1px", "2em", "5%",
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ ]
 	},
 	"padding-right": {
 		domProp: "paddingRight",
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		/* no subproperties */
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(0pt)", "-moz-calc(0% + 0px)", "-moz-calc(-3px)", "-moz-calc(-1%)" ],
 		other_values: [ "1px", "2em", "5%",
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: [ ]
 	},
 	"padding-top": {
 		domProp: "paddingTop",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
-		initial_values: [ "0", "0px", "0%" ],
+		initial_values: [ "0", "0px", "0%", "-moz-calc(0pt)", "-moz-calc(0% + 0px)", "-moz-calc(-3px)", "-moz-calc(-1%)" ],
 		other_values: [ "1px", "2em", "5%",
 			"-moz-calc(2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
@@ -2284,16 +2299,17 @@ var gCSSProperties = {
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		/* FIXME: run tests with multiple prerequisites */
 		prerequisites: { "position": "relative" },
 		/* XXX 0 may or may not be equal to auto */
 		initial_values: [ "auto" ],
 		other_values: [ "32px", "-3em", "12%",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: []
 	},
@@ -2390,19 +2406,20 @@ var gCSSProperties = {
 		initial_values: [ "none" ],
 		other_values: [ "underline", "overline", "line-through", "blink line-through underline", "underline overline line-through blink", "-moz-anchor-decoration", "blink -moz-anchor-decoration" ],
 		invalid_values: [ "underline none", "none underline", "line-through blink line-through" ]
 	},
 	"text-indent": {
 		domProp: "textIndent",
 		inherited: true,
 		type: CSS_TYPE_LONGHAND,
-		initial_values: [ "0" ],
+		initial_values: [ "0", "-moz-calc(3em - 5em + 2px + 2em - 2px)" ],
 		other_values: [ "2em", "5%", "-10px",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: []
 	},
@@ -2415,16 +2432,18 @@ var gCSSProperties = {
 		other_values: [ "2px 2px", "2px 2px 1px", "2px 2px green", "2px 2px 1px green", "green 2px 2px", "green 2px 2px 1px", "green 2px 2px, blue 1px 3px 4px", "currentColor 3px 3px", "blue 2px 2px, currentColor 1px 2px",
 			/* calc() values */
 			"2px 2px -moz-calc(-5px)", /* clamped */
 			"-moz-calc(3em - 2px) 2px green",
 			"green -moz-calc(3em - 2px) 2px",
 			"2px -moz-min(2px,0.2em)",
 			"blue 2px -moz-min(2px,0.2em)",
 			"2px -moz-min(2px,0.2em) blue",
+			"-moz-calc(-2px) -moz-calc(-2px)",
+			"-2px -2px",
 			"-moz-calc(2px) -moz-calc(2px)",
 			"-moz-calc(2px) -moz-calc(2px) -moz-calc(2px)",
 		],
 		invalid_values: [ "3% 3%", "2px 2px 2px 2px", "2px 2px, none", "none, 2px 2px", "inherit, 2px 2px", "2px 2px, inherit",
 			"-moz-calc(2px) -moz-calc(2px) -moz-calc(2px) -moz-calc(2px)"
 		]
 	},
 	"text-transform": {
@@ -2440,16 +2459,17 @@ var gCSSProperties = {
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		/* FIXME: run tests with multiple prerequisites */
 		prerequisites: { "position": "relative" },
 		/* XXX 0 may or may not be equal to auto */
 		initial_values: [ "auto" ],
 		other_values: [ "32px", "-3em", "12%",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: []
 	},
@@ -2504,16 +2524,17 @@ var gCSSProperties = {
 	},
 	"vertical-align": {
 		domProp: "verticalAlign",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "baseline" ],
 		other_values: [ "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "15%", "3px", "0.2em", "-5px", "-3%",
 			"-moz-calc(2px)",
+			"-moz-calc(-2px)",
 			"-moz-calc(50%)",
 			"-moz-calc(3*25px)",
 			"-moz-calc(25px*3)",
 			"-moz-calc(3*25px + 50%)",
 			"-moz-min(30%, 30em,200px, min(500px ,40em))",
 		],
 		invalid_values: []
 	},
--- a/layout/style/test/test_value_computation.html
+++ b/layout/style/test/test_value_computation.html
@@ -42,35 +42,42 @@
 var gBadComputed = {
   // These values are treated as auto.
   "page-break-after": [ "avoid" ],
   "page-break-before": [ "avoid" ],
 };
 
 var gBadComputedNoFrame = {
   // These are probably bogus tests...
-  "-moz-outline-radius": [ "0%" ],
-  "-moz-outline-radius-bottomleft": [ "0%" ],
-  "-moz-outline-radius-bottomright": [ "0%" ],
-  "-moz-outline-radius-topleft": [ "0%" ],
-  "-moz-outline-radius-topright": [ "0%" ],
-  "-moz-margin-end": [ "0%" ],
-  "-moz-margin-start": [ "0%" ],
-  "-moz-padding-end": [ "0%" ],
-  "-moz-padding-start": [ "0%" ],
+  "-moz-border-radius": [ "0%", "-moz-calc(-1%)", "-moz-calc(0px) -moz-calc(0pt) -moz-calc(0%) -moz-calc(0em)" ],
+  "-moz-border-radius-bottomleft": [ "0%", "-moz-calc(-1%)" ],
+  "-moz-border-radius-bottomright": [ "0%", "-moz-calc(-1%)" ],
+  "-moz-border-radius-topleft": [ "0%", "-moz-calc(-1%)" ],
+  "-moz-border-radius-topright": [ "0%", "-moz-calc(-1%)" ],
+  "-moz-margin-end": [ "0%", "-moz-calc(0% + 0px)", "-moz-calc(-1%)" ],
+  "-moz-margin-start": [ "0%", "-moz-calc(0% + 0px)", "-moz-calc(-1%)" ],
+  "-moz-outline-radius": [ "0%", "-moz-calc(-1%)", "-moz-calc(0px) -moz-calc(0pt) -moz-calc(0%) -moz-calc(0em)" ],
+  "-moz-outline-radius-bottomleft": [ "0%", "-moz-calc(-1%)" ],
+  "-moz-outline-radius-bottomright": [ "0%", "-moz-calc(-1%)" ],
+  "-moz-outline-radius-topleft": [ "0%", "-moz-calc(-1%)" ],
+  "-moz-outline-radius-topright": [ "0%", "-moz-calc(-1%)" ],
+  "-moz-padding-end": [ "0%", "-moz-calc(0% + 0px)", "-moz-calc(-1%)" ],
+  "-moz-padding-start": [ "0%", "-moz-calc(0% + 0px)", "-moz-calc(-1%)" ],
   "margin": [ "0% 0px 0em 0pt" ],
-  "margin-bottom": [ "0%" ],
-  "margin-left": [ "0%" ],
-  "margin-right": [ "0%" ],
-  "margin-top": [ "0%" ],
-  "padding": [ "0% 0px 0em 0pt" ],
-  "padding-bottom": [ "0%" ],
-  "padding-left": [ "0%" ],
-  "padding-right": [ "0%" ],
-  "padding-top": [ "0%" ],
+  "margin-bottom": [ "0%", "-moz-calc(0% + 0px)" ],
+  "margin-left": [ "0%", "-moz-calc(0% + 0px)" ],
+  "margin-right": [ "0%", "-moz-calc(0% + 0px)" ],
+  "margin-top": [ "0%", "-moz-calc(0% + 0px)" ],
+  "min-height": [ "-moz-calc(-1%)" ],
+  "min-width": [ "-moz-calc(-1%)" ],
+  "padding": [ "0% 0px 0em 0pt", "-moz-calc(0) -moz-calc(0em) -moz-calc(-2px) -moz-calc(-1%)" ],
+  "padding-bottom": [ "0%", "-moz-calc(0% + 0px)", "-moz-calc(-1%)" ],
+  "padding-left": [ "0%", "-moz-calc(0% + 0px)", "-moz-calc(-1%)" ],
+  "padding-right": [ "0%", "-moz-calc(0% + 0px)", "-moz-calc(-1%)" ],
+  "padding-top": [ "0%", "-moz-calc(0% + 0px)", "-moz-calc(-1%)" ],
 };
 
 function xfail_value(property, value, is_initial, has_frame) {
   if ((property in gBadComputed) &&
       gBadComputed[property].indexOf(value) != -1)
     return true;
 
   if (!has_frame && (property in gBadComputedNoFrame) &&