diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 7a84b1d34e64..47f70ba385a7 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1594,20 +1594,18 @@ nsComputedDOMStyle::DoGetMozBackgroundSize() NS_ABORT_IF_FALSE(size.mWidthType == nsStyleBackground::Size::eLengthPercentage, "bad mWidthType"); - if (size.mWidth.mLength == 0 && + if (!size.mWidth.mHasPercent && // negative values must have come from calc() - size.mWidth.mPercent > 0.0f) { - valX->SetPercent(size.mWidth.mPercent); - } else if (size.mWidth.mPercent == 0.0f && - // negative values must have come from calc() - size.mWidth.mLength > 0) { + size.mWidth.mLength >= 0) { + NS_ABORT_IF_FALSE(size.mWidth.mPercent == 0.0f, + "Shouldn't have mPercent"); valX->SetAppUnits(size.mWidth.mLength); + } else if (size.mWidth.mLength == 0 && + // negative values must have come from calc() + size.mWidth.mPercent >= 0.0f) { + valX->SetPercent(size.mWidth.mPercent); } else { - nsStyleCoord::Calc calc; - calc.mPercent = size.mWidth.mPercent; - calc.mLength = size.mWidth.mLength; - calc.mHasPercent = PR_TRUE; - SetValueToCalc(&calc, valX); + SetValueToCalc(&size.mWidth, valX); } } @@ -1617,20 +1615,18 @@ nsComputedDOMStyle::DoGetMozBackgroundSize() NS_ABORT_IF_FALSE(size.mHeightType == nsStyleBackground::Size::eLengthPercentage, "bad mHeightType"); - if (size.mHeight.mLength == 0 && + if (!size.mHeight.mHasPercent && // negative values must have come from calc() - size.mHeight.mPercent > 0.0f) { - valY->SetPercent(size.mHeight.mPercent); - } else if (size.mHeight.mPercent == 0.0f && - // negative values must have come from calc() - size.mHeight.mLength > 0) { + size.mHeight.mLength >= 0) { + NS_ABORT_IF_FALSE(size.mHeight.mPercent == 0.0f, + "Shouldn't have mPercent"); valY->SetAppUnits(size.mHeight.mLength); + } else if (size.mHeight.mLength == 0 && + // negative values must have come from calc() + size.mHeight.mPercent >= 0.0f) { + valY->SetPercent(size.mHeight.mPercent); } else { - nsStyleCoord::Calc calc; - calc.mPercent = size.mHeight.mPercent; - calc.mLength = size.mHeight.mLength; - calc.mHasPercent = PR_TRUE; - SetValueToCalc(&calc, valY); + SetValueToCalc(&size.mHeight, valY); } } break; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index e55a016053c5..8b06de84fb18 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -4746,6 +4746,7 @@ struct BackgroundItemComputer else if (eCSSUnit_Percent == specified.GetUnit()) { (size.*(axis->result)).mLength = 0; (size.*(axis->result)).mPercent = specified.GetPercentValue(); + (size.*(axis->result)).mHasPercent = PR_TRUE; size.*(axis->type) = nsStyleBackground::Size::eLengthPercentage; } else if (specified.IsLengthUnit()) { @@ -4753,6 +4754,7 @@ struct BackgroundItemComputer CalcLength(specified, aStyleContext, aStyleContext->PresContext(), aCanStoreInRuleTree); (size.*(axis->result)).mPercent = 0.0f; + (size.*(axis->result)).mHasPercent = PR_FALSE; size.*(axis->type) = nsStyleBackground::Size::eLengthPercentage; } else { NS_ABORT_IF_FALSE(specified.IsCalcUnit(), "unexpected unit"); @@ -4762,6 +4764,7 @@ struct BackgroundItemComputer nsRuleNode::ComputedCalc vals = ComputeCalc(specified, ops); (size.*(axis->result)).mLength = vals.mLength; (size.*(axis->result)).mPercent = vals.mPercent; + (size.*(axis->result)).mHasPercent = ops.mHasPercent; size.*(axis->type) = nsStyleBackground::Size::eLengthPercentage; } } diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 618ef0b85ee9..d83eb9894434 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -378,17 +378,7 @@ struct nsStyleBackground { struct Size; friend struct Size; struct Size { - struct Dimension { - // A 'background-size' can be a linear combination of length - // and percent (thanks to calc(), which can combine them). - nscoord mLength; - float mPercent; - - bool operator==(const Dimension& aOther) const - { return mLength == aOther.mLength && mPercent == aOther.mPercent; } - bool operator!=(const Dimension& aOther) const - { return !(*this == aOther); } - }; + typedef nsStyleCoord::Calc Dimension; Dimension mWidth, mHeight; // Except for eLengthPercentage, Dimension types which might change diff --git a/layout/style/test/test_computed_style.html b/layout/style/test/test_computed_style.html index 4fd97d028a71..55b05dcd95ec 100644 --- a/layout/style/test/test_computed_style.html +++ b/layout/style/test/test_computed_style.html @@ -149,6 +149,40 @@ var noframe_container = document.getElementById("content"); p.parentNode.removeChild(p); })(); +(function test_bug_647885_2() { + // Test that various background-size styles round-trip correctly + var backgroundSizes = [ + [ "0 0", "0px 0px", "unitless 0" ], + [ "0px 0px", "0px 0px", "0 with units" ], + [ "0% 0%", "0% 0%", "0%" ], + [ "-moz-calc(0px) 0", "0px 0px", "0 calc with units horizontal" ], + [ "0 -moz-calc(0px)", "0px 0px", "0 calc with units vertical" ], + [ "-moz-calc(3px - 3px) 0", "0px 0px", "computed 0 calc with units horizontal" ], + [ "0 -moz-calc(3px - 3px)", "0px 0px", "computed 0 calc with units vertical" ], + [ "-moz-calc(0%) 0", "0% 0px", "0% calc horizontal"], + [ "0 -moz-calc(0%)", "0px 0%", "0% calc vertical"], + [ "-moz-calc(3px + 2% - 2%) 0", "-moz-calc(3px + 0%) 0px", + "computed 0% calc horizontal"], + [ "0 -moz-calc(3px + 2% - 2%)", "0px -moz-calc(3px + 0%)", + "computed 0% calc vertical"], + [ "-moz-calc(3px - 5px) -moz-calc(6px - 9px)", + "-moz-calc(-2px) -moz-calc(-3px)", "negative pixel width" ], + [ "", "auto auto", "initial value" ], + ]; + + var p = document.createElement("p"); + var cs = getComputedStyle(p, ""); + frame_container.appendChild(p); + + for (var i = 0; i < backgroundSizes.length; ++i) { + var test = backgroundSizes[i]; + p.style.backgroundSize = test[0]; + is(cs.backgroundSize, test[1], "computed value of " + test[2] + " background-size"); + } + + p.parentNode.removeChild(p); +})(); +