зеркало из https://github.com/mozilla/gecko-dev.git
Add support for calc() to the 'height', 'min-height', and 'max-height' properties. (Bug 585715) r=bzbarsky a2.0=blocking+
This commit is contained in:
Родитель
46490e81bb
Коммит
fce97072e6
|
@ -1773,6 +1773,8 @@ static nscoord AddPercents(nsLayoutUtils::IntrinsicWidthType aType,
|
|||
return result;
|
||||
}
|
||||
|
||||
// Use only for widths/heights (or their min/max), since it clamps
|
||||
// negative calc() results to 0.
|
||||
static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle, nscoord& aResult)
|
||||
{
|
||||
if (aStyle.IsCalcUnit()) {
|
||||
|
@ -1781,6 +1783,8 @@ static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle, nscoord& aResult)
|
|||
}
|
||||
// If it has no percents, we can pass 0 for the percentage basis.
|
||||
aResult = nsRuleNode::ComputeComputedCalc(aStyle, 0);
|
||||
if (aResult < 0)
|
||||
aResult = 0;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1788,6 +1792,7 @@ static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle, nscoord& aResult)
|
|||
return PR_FALSE;
|
||||
|
||||
aResult = aStyle.GetCoordValue();
|
||||
NS_ASSERTION(aResult >= 0, "negative widths not allowed");
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1813,7 +1818,7 @@ GetPercentHeight(const nsStyleCoord& aStyle,
|
|||
if (!GetAbsoluteCoord(pos->mHeight, h) &&
|
||||
!GetPercentHeight(pos->mHeight, f, h)) {
|
||||
NS_ASSERTION(pos->mHeight.GetUnit() == eStyleUnit_Auto ||
|
||||
pos->mHeight.GetUnit() == eStyleUnit_Percent,
|
||||
pos->mHeight.HasPercent(),
|
||||
"unknown height unit");
|
||||
nsIAtom* fType = f->GetType();
|
||||
if (fType != nsGkAtoms::viewportFrame && fType != nsGkAtoms::canvasFrame &&
|
||||
|
@ -1844,7 +1849,7 @@ GetPercentHeight(const nsStyleCoord& aStyle,
|
|||
h = maxh;
|
||||
} else {
|
||||
NS_ASSERTION(pos->mMaxHeight.GetUnit() == eStyleUnit_None ||
|
||||
pos->mMaxHeight.GetUnit() == eStyleUnit_Percent,
|
||||
pos->mMaxHeight.HasPercent(),
|
||||
"unknown max-height unit");
|
||||
}
|
||||
|
||||
|
@ -1854,7 +1859,7 @@ GetPercentHeight(const nsStyleCoord& aStyle,
|
|||
if (minh > h)
|
||||
h = minh;
|
||||
} else {
|
||||
NS_ASSERTION(pos->mMinHeight.GetUnit() == eStyleUnit_Percent,
|
||||
NS_ASSERTION(pos->mMinHeight.HasPercent(),
|
||||
"unknown min-height unit");
|
||||
}
|
||||
|
||||
|
@ -2248,8 +2253,7 @@ IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight)
|
|||
nsStyleUnit unit = aCoord.GetUnit();
|
||||
return unit == eStyleUnit_Auto || // only for 'height'
|
||||
unit == eStyleUnit_None || // only for 'max-height'
|
||||
(unit == eStyleUnit_Percent &&
|
||||
aCBHeight == NS_AUTOHEIGHT);
|
||||
(aCBHeight == NS_AUTOHEIGHT && aCoord.HasPercent());
|
||||
}
|
||||
|
||||
#define MULDIV(a,b,c) (nscoord(PRInt64(a) * PRInt64(b) / PRInt64(c)))
|
||||
|
@ -2309,7 +2313,7 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
|
|||
|
||||
if (!isAutoHeight) {
|
||||
height = nsLayoutUtils::
|
||||
ComputeHeightDependentValue(aCBSize.height, stylePos->mHeight) -
|
||||
ComputeHeightValue(aCBSize.height, stylePos->mHeight) -
|
||||
boxSizingAdjust.height;
|
||||
if (height < 0)
|
||||
height = 0;
|
||||
|
@ -2317,7 +2321,7 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
|
|||
|
||||
if (!IsAutoHeight(stylePos->mMaxHeight, aCBSize.height)) {
|
||||
maxHeight = nsLayoutUtils::
|
||||
ComputeHeightDependentValue(aCBSize.height, stylePos->mMaxHeight) -
|
||||
ComputeHeightValue(aCBSize.height, stylePos->mMaxHeight) -
|
||||
boxSizingAdjust.height;
|
||||
if (maxHeight < 0)
|
||||
maxHeight = 0;
|
||||
|
@ -2327,7 +2331,7 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
|
|||
|
||||
if (!IsAutoHeight(stylePos->mMinHeight, aCBSize.height)) {
|
||||
minHeight = nsLayoutUtils::
|
||||
ComputeHeightDependentValue(aCBSize.height, stylePos->mMinHeight) -
|
||||
ComputeHeightValue(aCBSize.height, stylePos->mMinHeight) -
|
||||
boxSizingAdjust.height;
|
||||
if (minHeight < 0)
|
||||
minHeight = 0;
|
||||
|
|
|
@ -776,6 +776,19 @@ public:
|
|||
nscoord aContainingBlockHeight,
|
||||
const nsStyleCoord& aCoord);
|
||||
|
||||
/*
|
||||
* Likewise, but for 'height', 'min-height', or 'max-height'.
|
||||
*/
|
||||
static nscoord ComputeHeightValue(nscoord aContainingBlockHeight,
|
||||
const nsStyleCoord& aCoord)
|
||||
{
|
||||
nscoord result =
|
||||
ComputeHeightDependentValue(aContainingBlockHeight, aCoord);
|
||||
if (result < 0)
|
||||
result = 0; // clamp calc()
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the used values for 'width' and 'height' for a replaced element.
|
||||
*
|
||||
|
|
|
@ -2751,6 +2751,23 @@ IsPaddingZero(nsStyleUnit aUnit, const nsStyleCoord &aCoord)
|
|||
(aUnit == eStyleUnit_Percent && aCoord.GetPercentValue() == 0.0));
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
IsNonAutoNonZeroHeight(const nsStyleCoord& aCoord)
|
||||
{
|
||||
if (aCoord.GetUnit() == eStyleUnit_Auto)
|
||||
return PR_FALSE;
|
||||
if (aCoord.IsCoordPercentCalcUnit()) {
|
||||
// If we evaluate the length/percent/calc at a percentage basis of
|
||||
// both nscoord_MAX and 0, and it's zero both ways, then it's a zero
|
||||
// length, percent, or combination thereof. Test > 0 so we clamp
|
||||
// negative calc() results to 0.
|
||||
return nsRuleNode::ComputeCoordPercentCalc(aCoord, nscoord_MAX) > 0 ||
|
||||
nsRuleNode::ComputeCoordPercentCalc(aCoord, 0) > 0;
|
||||
}
|
||||
NS_ABORT_IF_FALSE(PR_FALSE, "unexpected unit for height or min-height");
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* virtual */ PRBool
|
||||
nsBlockFrame::IsSelfEmpty()
|
||||
{
|
||||
|
@ -2762,33 +2779,9 @@ nsBlockFrame::IsSelfEmpty()
|
|||
|
||||
const nsStylePosition* position = GetStylePosition();
|
||||
|
||||
switch (position->mMinHeight.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
if (position->mMinHeight.GetCoordValue() != 0)
|
||||
return PR_FALSE;
|
||||
break;
|
||||
case eStyleUnit_Percent:
|
||||
if (position->mMinHeight.GetPercentValue() != 0.0f)
|
||||
return PR_FALSE;
|
||||
break;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
switch (position->mHeight.GetUnit()) {
|
||||
case eStyleUnit_Auto:
|
||||
break;
|
||||
case eStyleUnit_Coord:
|
||||
if (position->mHeight.GetCoordValue() != 0)
|
||||
return PR_FALSE;
|
||||
break;
|
||||
case eStyleUnit_Percent:
|
||||
if (position->mHeight.GetPercentValue() != 0.0f)
|
||||
return PR_FALSE;
|
||||
break;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (IsNonAutoNonZeroHeight(position->mMinHeight) ||
|
||||
IsNonAutoNonZeroHeight(position->mHeight))
|
||||
return PR_FALSE;
|
||||
|
||||
const nsStyleBorder* border = GetStyleBorder();
|
||||
const nsStylePadding* padding = GetStylePadding();
|
||||
|
|
|
@ -3102,8 +3102,7 @@ IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight)
|
|||
nsStyleUnit unit = aCoord.GetUnit();
|
||||
return unit == eStyleUnit_Auto || // only for 'height'
|
||||
unit == eStyleUnit_None || // only for 'max-height'
|
||||
(unit == eStyleUnit_Percent &&
|
||||
aCBHeight == NS_AUTOHEIGHT);
|
||||
(aCBHeight == NS_AUTOHEIGHT && aCoord.HasPercent());
|
||||
}
|
||||
|
||||
/* virtual */ nsSize
|
||||
|
@ -3156,16 +3155,14 @@ nsFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
|
|||
|
||||
if (!IsAutoHeight(stylePos->mHeight, aCBSize.height)) {
|
||||
result.height =
|
||||
nsLayoutUtils::ComputeHeightDependentValue(aCBSize.height,
|
||||
stylePos->mHeight) -
|
||||
nsLayoutUtils::ComputeHeightValue(aCBSize.height, stylePos->mHeight) -
|
||||
boxSizingAdjust.height;
|
||||
}
|
||||
|
||||
if (result.height != NS_UNCONSTRAINEDSIZE) {
|
||||
if (!IsAutoHeight(stylePos->mMaxHeight, aCBSize.height)) {
|
||||
nscoord maxHeight =
|
||||
nsLayoutUtils::ComputeHeightDependentValue(aCBSize.height,
|
||||
stylePos->mMaxHeight) -
|
||||
nsLayoutUtils::ComputeHeightValue(aCBSize.height, stylePos->mMaxHeight) -
|
||||
boxSizingAdjust.height;
|
||||
if (maxHeight < result.height)
|
||||
result.height = maxHeight;
|
||||
|
@ -3173,8 +3170,7 @@ nsFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
|
|||
|
||||
if (!IsAutoHeight(stylePos->mMinHeight, aCBSize.height)) {
|
||||
nscoord minHeight =
|
||||
nsLayoutUtils::ComputeHeightDependentValue(aCBSize.height,
|
||||
stylePos->mMinHeight) -
|
||||
nsLayoutUtils::ComputeHeightValue(aCBSize.height, stylePos->mMinHeight) -
|
||||
boxSizingAdjust.height;
|
||||
if (minHeight > result.height)
|
||||
result.height = minHeight;
|
||||
|
@ -3313,10 +3309,9 @@ nsFrame::DidReflow(nsPresContext* aPresContext,
|
|||
// height. This happens in the case where a table cell has no computed
|
||||
// height but can fabricate one when the cell height is known.
|
||||
if (aReflowState && aReflowState->mPercentHeightObserver &&
|
||||
(eStyleUnit_Percent == aReflowState->mStylePosition->mHeight.GetUnit())) {
|
||||
|
||||
nsIFrame* prevInFlow = GetPrevInFlow();
|
||||
if (!prevInFlow) { // 1st in flow
|
||||
!GetPrevInFlow()) {
|
||||
const nsStyleCoord &height = aReflowState->mStylePosition->mHeight;
|
||||
if (height.HasPercent()) {
|
||||
aReflowState->mPercentHeightObserver->NotifyPercentHeight(*aReflowState);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ struct nsHTMLReflowMetrics {
|
|||
// The rect is in the local coordinate space of the frame, and should be at
|
||||
// least as big as the desired size. If there is no content that overflows,
|
||||
// then the overflow area is identical to the desired size and should be
|
||||
// {0, 0, mWidth, mHeight}.
|
||||
// {0, 0, width, height}.
|
||||
nsRect mOverflowArea;
|
||||
|
||||
PRUint32 mFlags;
|
||||
|
|
|
@ -395,9 +395,15 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext)
|
|||
}
|
||||
|
||||
PRBool dependsOnCBHeight =
|
||||
mStylePosition->mHeight.GetUnit() == eStyleUnit_Percent ||
|
||||
mStylePosition->mMinHeight.GetUnit() == eStyleUnit_Percent ||
|
||||
mStylePosition->mMaxHeight.GetUnit() == eStyleUnit_Percent ||
|
||||
(mStylePosition->HeightDependsOnContainer() &&
|
||||
// FIXME: condition this on not-abspos?
|
||||
mStylePosition->mHeight.GetUnit() != eStyleUnit_Auto) ||
|
||||
(mStylePosition->MinHeightDependsOnContainer() &&
|
||||
// FIXME: condition this on not-abspos?
|
||||
mStylePosition->mMinHeight.GetUnit() != eStyleUnit_Auto) ||
|
||||
(mStylePosition->MaxHeightDependsOnContainer() &&
|
||||
// FIXME: condition this on not-abspos?
|
||||
mStylePosition->mMaxHeight.GetUnit() != eStyleUnit_Auto) ||
|
||||
mStylePosition->mOffset.GetTopUnit() == eStyleUnit_Percent ||
|
||||
mStylePosition->mOffset.GetBottomUnit() != eStyleUnit_Auto ||
|
||||
frame->IsBoxFrame() ||
|
||||
|
@ -1579,6 +1585,7 @@ nsHTMLReflowState::ComputeContainingBlockRectangle(nsPresContext* aPres
|
|||
} else {
|
||||
// an element in quirks mode gets a containing block based on looking for a
|
||||
// parent with a non-auto height if the element has a percent height
|
||||
// Note: We don't emulate this quirk for percents in calc().
|
||||
if (NS_AUTOHEIGHT == aContainingBlockHeight) {
|
||||
if (eCompatibility_NavQuirks == aPresContext->CompatibilityMode() &&
|
||||
mStylePosition->mHeight.GetUnit() == eStyleUnit_Percent) {
|
||||
|
@ -1708,12 +1715,14 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
|
|||
|
||||
InitOffsets(aContainingBlockWidth, aBorder, aPadding);
|
||||
|
||||
nsStyleUnit heightUnit = mStylePosition->mHeight.GetUnit();
|
||||
const nsStyleCoord &height = mStylePosition->mHeight;
|
||||
nsStyleUnit heightUnit = height.GetUnit();
|
||||
|
||||
// Check for a percentage based height and a containing block height
|
||||
// that depends on the content height
|
||||
// XXX twiddling heightUnit doesn't help anymore
|
||||
if (eStyleUnit_Percent == heightUnit) {
|
||||
// FIXME Shouldn't we fix that?
|
||||
if (height.HasPercent()) {
|
||||
if (NS_AUTOHEIGHT == aContainingBlockHeight) {
|
||||
// this if clause enables %-height on replaced inline frames,
|
||||
// such as images. See bug 54119. The else clause "heightUnit = eStyleUnit_Auto;"
|
||||
|
@ -1772,7 +1781,8 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
|
|||
// Internal table elements. The rules vary depending on the type.
|
||||
// Calculate the computed width
|
||||
PRBool rowOrRowGroup = PR_FALSE;
|
||||
nsStyleUnit widthUnit = mStylePosition->mWidth.GetUnit();
|
||||
const nsStyleCoord &width = mStylePosition->mWidth;
|
||||
nsStyleUnit widthUnit = width.GetUnit();
|
||||
if ((NS_STYLE_DISPLAY_TABLE_ROW == mStyleDisplay->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == mStyleDisplay->mDisplay)) {
|
||||
// 'width' property doesn't apply to table rows and row groups
|
||||
|
@ -1780,7 +1790,8 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
|
|||
rowOrRowGroup = PR_TRUE;
|
||||
}
|
||||
|
||||
if (eStyleUnit_Auto == widthUnit) {
|
||||
// calc() acts like auto on internal table elements
|
||||
if (eStyleUnit_Auto == widthUnit || width.IsCalcUnit()) {
|
||||
mComputedWidth = availableWidth;
|
||||
|
||||
if ((mComputedWidth != NS_UNCONSTRAINEDSIZE) && !rowOrRowGroup){
|
||||
|
@ -1807,14 +1818,14 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
|
|||
// 'height' property doesn't apply to table columns and column groups
|
||||
heightUnit = eStyleUnit_Auto;
|
||||
}
|
||||
if (eStyleUnit_Auto == heightUnit) {
|
||||
// calc() acts like 'auto' on internal table elements
|
||||
if (eStyleUnit_Auto == heightUnit || height.IsCalcUnit()) {
|
||||
mComputedHeight = NS_AUTOHEIGHT;
|
||||
} else {
|
||||
NS_ASSERTION(heightUnit == mStylePosition->mHeight.GetUnit(),
|
||||
"unexpected height unit change");
|
||||
mComputedHeight = nsLayoutUtils::
|
||||
ComputeHeightDependentValue(aContainingBlockHeight,
|
||||
mStylePosition->mHeight);
|
||||
ComputeHeightValue(aContainingBlockHeight, mStylePosition->mHeight);
|
||||
}
|
||||
|
||||
// Doesn't apply to table elements
|
||||
|
@ -2277,28 +2288,36 @@ nsHTMLReflowState::ComputeMinMaxValues(nscoord aContainingBlockWidth,
|
|||
|
||||
// Check for percentage based values and a containing block height that
|
||||
// depends on the content height. Treat them like 'auto'
|
||||
if ((NS_AUTOHEIGHT == aContainingBlockHeight) &&
|
||||
(eStyleUnit_Percent == mStylePosition->mMinHeight.GetUnit())) {
|
||||
// Likewise, check for calc() on internal table elements; calc() on
|
||||
// such elements is unsupported.
|
||||
const nsStyleCoord &minHeight = mStylePosition->mMinHeight;
|
||||
if ((NS_AUTOHEIGHT == aContainingBlockHeight &&
|
||||
minHeight.HasPercent()) ||
|
||||
(mFrameType == NS_CSS_FRAME_TYPE_INTERNAL_TABLE &&
|
||||
minHeight.IsCalcUnit())) {
|
||||
mComputedMinHeight = 0;
|
||||
} else {
|
||||
mComputedMinHeight = nsLayoutUtils::
|
||||
ComputeHeightDependentValue(aContainingBlockHeight,
|
||||
mStylePosition->mMinHeight);
|
||||
ComputeHeightValue(aContainingBlockHeight, minHeight);
|
||||
}
|
||||
nsStyleUnit maxHeightUnit = mStylePosition->mMaxHeight.GetUnit();
|
||||
const nsStyleCoord &maxHeight = mStylePosition->mMaxHeight;
|
||||
nsStyleUnit maxHeightUnit = maxHeight.GetUnit();
|
||||
if (eStyleUnit_None == maxHeightUnit) {
|
||||
// Specified value of 'none'
|
||||
mComputedMaxHeight = NS_UNCONSTRAINEDSIZE; // no limit
|
||||
} else {
|
||||
// Check for percentage based values and a containing block height that
|
||||
// depends on the content height. Treat them like 'auto'
|
||||
if ((NS_AUTOHEIGHT == aContainingBlockHeight) &&
|
||||
(eStyleUnit_Percent == maxHeightUnit)) {
|
||||
// Likewise, check for calc() on internal table elements; calc() on
|
||||
// such elements is unsupported.
|
||||
if ((NS_AUTOHEIGHT == aContainingBlockHeight &&
|
||||
maxHeight.HasPercent()) ||
|
||||
(mFrameType == NS_CSS_FRAME_TYPE_INTERNAL_TABLE &&
|
||||
maxHeight.IsCalcUnit())) {
|
||||
mComputedMaxHeight = NS_UNCONSTRAINEDSIZE;
|
||||
} else {
|
||||
mComputedMaxHeight = nsLayoutUtils::
|
||||
ComputeHeightDependentValue(aContainingBlockHeight,
|
||||
mStylePosition->mMaxHeight);
|
||||
ComputeHeightValue(aContainingBlockHeight, maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>Test for height:calc() or min-height:calc() on blocks</title>
|
||||
<style>
|
||||
body { margin: 0 }
|
||||
body > div { float: left; width: 1px; background: blue; }
|
||||
</style>
|
||||
|
||||
<!-- tests with a fixed-height container -->
|
||||
<div style="height: 50px"></div>
|
||||
<div style="height: 50px"></div>
|
||||
<div style="height: 75px"></div>
|
||||
<div style="height: 45px"></div>
|
||||
<div style="height: 40px"></div>
|
||||
<div style="height: 30px"></div>
|
||||
|
||||
<!-- tests with an auto-height container -->
|
||||
<div style="height: 50px"></div>
|
||||
<div style="height: 10px"></div>
|
||||
<div style="height: 10px"></div>
|
||||
<div style="height: 10px"></div>
|
||||
<div style="height: 10px"></div>
|
||||
<div style="height: 10px"></div>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>Test for height:calc() on blocks</title>
|
||||
<style>
|
||||
body { margin: 0 }
|
||||
body > div { float: left; height: 100px; width: 1px; }
|
||||
body > div > div { background: blue }
|
||||
|
||||
/* for auto-height tests */
|
||||
body > div > div > div > div { height: 10px }
|
||||
</style>
|
||||
|
||||
<!-- tests with a fixed-height container -->
|
||||
<div><div style="height: -moz-calc(50px)"></div></div>
|
||||
<div><div style="height: -moz-calc(50%)"></div></div>
|
||||
<div><div style="height: -moz-calc(25px + 50%)"></div></div>
|
||||
<div><div style="height: -moz-calc(150% / 2 - 30px)"></div></div>
|
||||
<div><div style="height: -moz-calc(40px + 10% - 20% / 2)"></div></div>
|
||||
<div><div style="height: -moz-calc(40px - 10%)"></div></div>
|
||||
|
||||
<!-- tests with an auto-height container -->
|
||||
<div><div><div style="height: -moz-calc(50px)"><div></div></div></div></div>
|
||||
<div><div><div style="height: -moz-calc(50%)"><div></div></div></div></div>
|
||||
<div><div><div style="height: -moz-calc(25px + 50%)"><div></div></div></div></div>
|
||||
<div><div><div style="height: -moz-calc(150% / 2 - 30px)"><div></div></div></div></div>
|
||||
<div><div><div style="height: -moz-calc(40px + 10% - 20% / 2)"><div></div></div></div></div>
|
||||
<div><div><div style="height: -moz-calc(40px - 10%)"><div></div></div></div></div>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>Test that height:calc() has no effect on inner table elements</title>
|
||||
<table border>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>cell</td>
|
||||
<td>cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cell</td>
|
||||
<td>cell</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>Test that height:calc() has no effect on inner table elements</title>
|
||||
<style>
|
||||
tbody, tr, td {
|
||||
height: -moz-calc(500px);
|
||||
min-height: -moz-calc(1000px);
|
||||
max-height: -moz-calc(2px);
|
||||
}
|
||||
</style>
|
||||
<table border>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>cell</td>
|
||||
<td>cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cell</td>
|
||||
<td>cell</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>Test for max-height:calc() on blocks</title>
|
||||
<style>
|
||||
body { margin: 0 }
|
||||
body > div { float: left; width: 1px; background: blue; }
|
||||
</style>
|
||||
|
||||
<!-- tests with a fixed-height container -->
|
||||
<div style="height: 50px"></div>
|
||||
<div style="height: 50px"></div>
|
||||
<div style="height: 75px"></div>
|
||||
<div style="height: 45px"></div>
|
||||
<div style="height: 40px"></div>
|
||||
<div style="height: 30px"></div>
|
||||
|
||||
<!-- tests with an auto-height container -->
|
||||
<div style="height: 50px"></div>
|
||||
<div style="height: 300px"></div>
|
||||
<div style="height: 300px"></div>
|
||||
<div style="height: 300px"></div>
|
||||
<div style="height: 300px"></div>
|
||||
<div style="height: 300px"></div>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>Test for max-height:calc() on blocks</title>
|
||||
<style>
|
||||
body { margin: 0 }
|
||||
body > div { float: left; height: 100px; width: 1px; }
|
||||
body > div > div { background: blue }
|
||||
|
||||
/* to give the max-height something to restrict */
|
||||
span { display: block; height: 300px }
|
||||
</style>
|
||||
|
||||
<!-- tests with a fixed-height container -->
|
||||
<div><div style="max-height: -moz-calc(50px)"><span></span></div></div>
|
||||
<div><div style="max-height: -moz-calc(50%)"><span></span></div></div>
|
||||
<div><div style="max-height: -moz-calc(25px + 50%)"><span></span></div></div>
|
||||
<div><div style="max-height: -moz-calc(150% / 2 - 30px)"><span></span></div></div>
|
||||
<div><div style="max-height: -moz-calc(40px + 10% - 20% / 2)"><span></span></div></div>
|
||||
<div><div style="max-height: -moz-calc(40px - 10%)"><span></span></div></div>
|
||||
|
||||
<!-- tests with an auto-height container -->
|
||||
<div><div><div style="max-height: -moz-calc(50px)"><span></span></div></div></div>
|
||||
<div><div><div style="max-height: -moz-calc(50%)"><span></span></div></div></div>
|
||||
<div><div><div style="max-height: -moz-calc(25px + 50%)"><span></span></div></div></div>
|
||||
<div><div><div style="max-height: -moz-calc(150% / 2 - 30px)"><span></span></div></div></div>
|
||||
<div><div><div style="max-height: -moz-calc(40px + 10% - 20% / 2)"><span></span></div></div></div>
|
||||
<div><div><div style="max-height: -moz-calc(40px - 10%)"><span></span></div></div></div>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE HTML>
|
||||
<title>Test for min-height:calc() on blocks</title>
|
||||
<style>
|
||||
body { margin: 0 }
|
||||
body > div { float: left; height: 100px; width: 1px; }
|
||||
body > div > div { background: blue }
|
||||
|
||||
/* for auto-height tests */
|
||||
body > div > div > div > div { height: 10px }
|
||||
</style>
|
||||
|
||||
<!-- tests with a fixed-height container -->
|
||||
<div><div style="min-height: -moz-calc(50px)"></div></div>
|
||||
<div><div style="min-height: -moz-calc(50%)"></div></div>
|
||||
<div><div style="min-height: -moz-calc(25px + 50%)"></div></div>
|
||||
<div><div style="min-height: -moz-calc(150% / 2 - 30px)"></div></div>
|
||||
<div><div style="min-height: -moz-calc(40px + 10% - 20% / 2)"></div></div>
|
||||
<div><div style="min-height: -moz-calc(40px - 10%)"></div></div>
|
||||
|
||||
<!-- tests with an auto-height container -->
|
||||
<div><div><div style="min-height: -moz-calc(50px)"><div></div></div></div></div>
|
||||
<div><div><div style="min-height: -moz-calc(50%)"><div></div></div></div></div>
|
||||
<div><div><div style="min-height: -moz-calc(25px + 50%)"><div></div></div></div></div>
|
||||
<div><div><div style="min-height: -moz-calc(150% / 2 - 30px)"><div></div></div></div></div>
|
||||
<div><div><div style="min-height: -moz-calc(40px + 10% - 20% / 2)"><div></div></div></div></div>
|
||||
<div><div><div style="min-height: -moz-calc(40px - 10%)"><div></div></div></div></div>
|
|
@ -1,3 +1,7 @@
|
|||
== height-block-1.html height-block-1-ref.html
|
||||
== height-table-1.html height-table-1-ref.html
|
||||
== max-height-block-1.html max-height-block-1-ref.html
|
||||
== min-height-block-1.html height-block-1-ref.html
|
||||
== width-block-1.html width-block-1-ref.html
|
||||
== width-block-intrinsic-1.html width-block-intrinsic-1-ref.html
|
||||
== width-table-auto-1.html width-table-auto-1-ref.html
|
||||
|
|
|
@ -5731,7 +5731,8 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
|
|||
return ParseVariant(aValue, VARIANT_HK,
|
||||
nsCSSProps::kBoxSizingKTable);
|
||||
case eCSSProperty_height:
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_AHLP, nsnull);
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_AHLP | VARIANT_CALC,
|
||||
nsnull);
|
||||
case eCSSProperty_width:
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_AHKLP | VARIANT_CALC,
|
||||
nsCSSProps::kWidthKTable);
|
||||
|
@ -5830,12 +5831,14 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
|
|||
case eCSSProperty_marks:
|
||||
return ParseMarks(aValue);
|
||||
case eCSSProperty_max_height:
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_HLPO, nsnull);
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_HLPO | VARIANT_CALC,
|
||||
nsnull);
|
||||
case eCSSProperty_max_width:
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_HKLPO,
|
||||
nsCSSProps::kWidthKTable);
|
||||
case eCSSProperty_min_height:
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_HLP, nsnull);
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_HLP | VARIANT_CALC,
|
||||
nsnull);
|
||||
case eCSSProperty_min_width:
|
||||
return ParseNonNegativeVariant(aValue, VARIANT_HKLP,
|
||||
nsCSSProps::kWidthKTable);
|
||||
|
|
|
@ -5548,14 +5548,14 @@ nsRuleNode::ComputePositionData(void* aStartStruct,
|
|||
mPresContext, canStoreInRuleTree);
|
||||
|
||||
SetCoord(posData.mHeight, pos->mHeight, parentPos->mHeight,
|
||||
SETCOORD_LPAH | SETCOORD_INITIAL_AUTO, aContext,
|
||||
mPresContext, canStoreInRuleTree);
|
||||
SETCOORD_LPAH | SETCOORD_INITIAL_AUTO | SETCOORD_STORE_CALC,
|
||||
aContext, mPresContext, canStoreInRuleTree);
|
||||
SetCoord(posData.mMinHeight, pos->mMinHeight, parentPos->mMinHeight,
|
||||
SETCOORD_LPH | SETCOORD_INITIAL_ZERO, aContext,
|
||||
mPresContext, canStoreInRuleTree);
|
||||
SETCOORD_LPH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC,
|
||||
aContext, mPresContext, canStoreInRuleTree);
|
||||
SetCoord(posData.mMaxHeight, pos->mMaxHeight, parentPos->mMaxHeight,
|
||||
SETCOORD_LPOH | SETCOORD_INITIAL_NONE, aContext,
|
||||
mPresContext, canStoreInRuleTree);
|
||||
SETCOORD_LPOH | SETCOORD_INITIAL_NONE | SETCOORD_STORE_CALC,
|
||||
aContext, mPresContext, canStoreInRuleTree);
|
||||
|
||||
// box-sizing: enum, inherit, initial
|
||||
SetDiscrete(posData.mBoxSizing, pos->mBoxSizing, canStoreInRuleTree,
|
||||
|
|
|
@ -1089,9 +1089,9 @@ struct nsStylePosition {
|
|||
nsStyleCoord mWidth; // [reset] coord, percent, enum, auto
|
||||
nsStyleCoord mMinWidth; // [reset] coord, percent, enum
|
||||
nsStyleCoord mMaxWidth; // [reset] coord, percent, enum, none
|
||||
nsStyleCoord mHeight; // [reset] coord, percent, auto
|
||||
nsStyleCoord mMinHeight; // [reset] coord, percent
|
||||
nsStyleCoord mMaxHeight; // [reset] coord, percent, none
|
||||
nsStyleCoord mHeight; // [reset] coord, percent, calc, auto
|
||||
nsStyleCoord mMinHeight; // [reset] coord, percent, calc
|
||||
nsStyleCoord mMaxHeight; // [reset] coord, percent, calc, none
|
||||
PRUint8 mBoxSizing; // [reset] see nsStyleConsts.h
|
||||
nsStyleCoord mZIndex; // [reset] integer, auto
|
||||
|
||||
|
@ -1113,7 +1113,7 @@ private:
|
|||
static PRBool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord)
|
||||
{
|
||||
return aCoord.GetUnit() == eStyleUnit_Auto || // CSS 2.1, 10.6.4, item (5)
|
||||
aCoord.GetUnit() == eStyleUnit_Percent;
|
||||
aCoord.HasPercent();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1584,7 +1584,14 @@ var gCSSProperties = {
|
|||
initial_values: [ " auto" ],
|
||||
/* computed value tests for height test more with display:block */
|
||||
prerequisites: { "display": "block" },
|
||||
other_values: [ "15px", "3em", "15%" ],
|
||||
other_values: [ "15px", "3em", "15%",
|
||||
"-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: [ "none", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available" ]
|
||||
},
|
||||
"ime-mode": {
|
||||
|
@ -1759,7 +1766,14 @@ var gCSSProperties = {
|
|||
type: CSS_TYPE_LONGHAND,
|
||||
prerequisites: { "display": "block" },
|
||||
initial_values: [ "none" ],
|
||||
other_values: [ "30px", "50%", "0" ],
|
||||
other_values: [ "30px", "50%", "0",
|
||||
"-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", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available" ]
|
||||
},
|
||||
"max-width": {
|
||||
|
@ -1777,7 +1791,14 @@ var gCSSProperties = {
|
|||
type: CSS_TYPE_LONGHAND,
|
||||
prerequisites: { "display": "block" },
|
||||
initial_values: [ "0" ],
|
||||
other_values: [ "30px", "50%" ],
|
||||
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": {
|
||||
|
|
|
@ -1589,7 +1589,9 @@ nsTableFrame::AncestorsHaveStyleHeight(const nsHTMLReflowState& aParentReflowSta
|
|||
if (IS_TABLE_CELL(frameType) ||
|
||||
(nsGkAtoms::tableRowFrame == frameType) ||
|
||||
(nsGkAtoms::tableRowGroupFrame == frameType)) {
|
||||
if (rs->mStylePosition->mHeight.GetUnit() != eStyleUnit_Auto) {
|
||||
const nsStyleCoord &height = rs->mStylePosition->mHeight;
|
||||
// calc() treated like 'auto' on internal table elements
|
||||
if (height.GetUnit() != eStyleUnit_Auto && !height.IsCalcUnit()) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -1608,6 +1610,11 @@ nsTableFrame::AncestorsHaveStyleHeight(const nsHTMLReflowState& aParentReflowSta
|
|||
void
|
||||
nsTableFrame::CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
NS_ASSERTION(IS_TABLE_CELL(aReflowState.frame->GetType()) ||
|
||||
aReflowState.frame->GetType() == nsGkAtoms::tableRowFrame ||
|
||||
aReflowState.frame->GetType() == nsGkAtoms::tableRowGroupFrame ||
|
||||
aReflowState.frame->GetType() == nsGkAtoms::tableFrame,
|
||||
"unexpected frame type");
|
||||
if (!aReflowState.frame->GetPrevInFlow() && // 1st in flow
|
||||
(NS_UNCONSTRAINEDSIZE == aReflowState.ComputedHeight() || // no computed height
|
||||
0 == aReflowState.ComputedHeight()) &&
|
||||
|
@ -3349,26 +3356,11 @@ nsTableFrame::GetTableFrame(nsIFrame* aSourceFrame)
|
|||
PRBool
|
||||
nsTableFrame::IsAutoHeight()
|
||||
{
|
||||
PRBool isAuto = PR_TRUE; // the default
|
||||
|
||||
const nsStylePosition* position = GetStylePosition();
|
||||
|
||||
switch (position->mHeight.GetUnit()) {
|
||||
case eStyleUnit_Auto: // specified auto width
|
||||
break;
|
||||
case eStyleUnit_Coord:
|
||||
isAuto = PR_FALSE;
|
||||
break;
|
||||
case eStyleUnit_Percent:
|
||||
if (position->mHeight.GetPercentValue() > 0.0f) {
|
||||
isAuto = PR_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return isAuto;
|
||||
const nsStyleCoord &height = GetStylePosition()->mHeight;
|
||||
// Don't consider calc() here like this quirk for percent.
|
||||
return height.GetUnit() == eStyleUnit_Auto ||
|
||||
(height.GetUnit() == eStyleUnit_Percent &&
|
||||
height.GetPercentValue() <= 0.0f);
|
||||
}
|
||||
|
||||
nscoord
|
||||
|
|
|
@ -547,6 +547,7 @@ nsTableRowFrame::CalcHeight(const nsHTMLReflowState& aReflowState)
|
|||
else if (eStyleUnit_Percent == position->mHeight.GetUnit()) {
|
||||
SetPctHeight(position->mHeight.GetPercentValue());
|
||||
}
|
||||
// calc() is treated like 'auto' on table rows.
|
||||
|
||||
for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame;
|
||||
kidFrame = kidFrame->GetNextSibling()) {
|
||||
|
@ -675,7 +676,7 @@ nsTableRowFrame::CalculateCellActualHeight(nsTableCellFrame* aCellFrame,
|
|||
break;
|
||||
}
|
||||
case eStyleUnit_Auto:
|
||||
default:
|
||||
default: // includes calc(), which we treat like 'auto'
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1405,8 +1406,10 @@ void nsTableRowFrame::InitHasCellWithStyleHeight(nsTableFrame* aTableFrame)
|
|||
continue;
|
||||
}
|
||||
// Ignore row-spanning cells
|
||||
const nsStyleCoord &cellHeight = cellFrame->GetStylePosition()->mHeight;
|
||||
if (aTableFrame->GetEffectiveRowSpan(*cellFrame) == 1 &&
|
||||
cellFrame->GetStylePosition()->mHeight.GetUnit() != eStyleUnit_Auto) {
|
||||
cellHeight.GetUnit() != eStyleUnit_Auto &&
|
||||
!cellHeight.IsCalcUnit() /* calc() treated like 'auto' */) {
|
||||
AddStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -687,15 +687,26 @@ nsIBox::AddCSSPrefSize(nsIBox* aBox, nsSize& aSize, PRBool &aWidthSet, PRBool &a
|
|||
if (!width.CalcHasPercent()) {
|
||||
// pass 0 for percentage basis since we know there are no %s
|
||||
aSize.width = nsRuleNode::ComputeComputedCalc(width, 0);
|
||||
if (aSize.width < 0)
|
||||
aSize.width = 0;
|
||||
aWidthSet = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (position->mHeight.GetUnit() == eStyleUnit_Coord) {
|
||||
aSize.height = position->mHeight.GetCoordValue();
|
||||
const nsStyleCoord &height = position->mHeight;
|
||||
if (height.GetUnit() == eStyleUnit_Coord) {
|
||||
aSize.height = height.GetCoordValue();
|
||||
aHeightSet = PR_TRUE;
|
||||
} else if (height.IsCalcUnit()) {
|
||||
if (!height.CalcHasPercent()) {
|
||||
// pass 0 for percentage basis since we know there are no %s
|
||||
aSize.height = nsRuleNode::ComputeComputedCalc(height, 0);
|
||||
if (aSize.height < 0)
|
||||
aSize.height = 0;
|
||||
aHeightSet = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsIContent* content = aBox->GetContent();
|
||||
// ignore 'height' and 'width' attributes if the actual element is not XUL
|
||||
// For example, we might be magic XUL frames whose primary content is an HTML
|
||||
|
@ -780,18 +791,23 @@ nsIBox::AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize,
|
|||
// GetPrefSize/GetMinSize methods that don't consider
|
||||
// (min-/max-/)(width/height) properties.
|
||||
|
||||
if (position->mMinHeight.GetUnit() == eStyleUnit_Coord) {
|
||||
nscoord min = position->mMinHeight.GetCoordValue();
|
||||
if (min && (!aHeightSet || (min > aSize.height && canOverride))) {
|
||||
const nsStyleCoord &minHeight = position->mMinHeight;
|
||||
if ((minHeight.GetUnit() == eStyleUnit_Coord &&
|
||||
minHeight.GetCoordValue() != 0) ||
|
||||
(minHeight.IsCalcUnit() && !minHeight.CalcHasPercent())) {
|
||||
nscoord min = nsRuleNode::ComputeCoordPercentCalc(minHeight, 0);
|
||||
if (!aHeightSet || (min > aSize.height && canOverride)) {
|
||||
aSize.height = min;
|
||||
aHeightSet = PR_TRUE;
|
||||
}
|
||||
} else if (position->mMinHeight.GetUnit() == eStyleUnit_Percent) {
|
||||
} else if (minHeight.GetUnit() == eStyleUnit_Percent) {
|
||||
NS_ASSERTION(position->mMinHeight.GetPercentValue() == 0.0f,
|
||||
"Non-zero percentage values not currently supported");
|
||||
aSize.height = 0;
|
||||
aHeightSet = PR_TRUE;
|
||||
aHeightSet = PR_TRUE; // FIXME: should we really do this for
|
||||
// nonzero values?
|
||||
}
|
||||
// calc() with percentage is treated like '0' (unset)
|
||||
|
||||
nsIContent* content = aBox->GetContent();
|
||||
if (content) {
|
||||
|
@ -847,10 +863,12 @@ nsIBox::AddCSSMaxSize(nsIBox* aBox, nsSize& aSize, PRBool &aWidthSet, PRBool &aH
|
|||
aWidthSet = PR_TRUE;
|
||||
}
|
||||
|
||||
if (position->mMaxHeight.GetUnit() == eStyleUnit_Coord) {
|
||||
aSize.height = position->mMaxHeight.GetCoordValue();
|
||||
const nsStyleCoord &maxHeight = position->mMaxHeight;
|
||||
if (maxHeight.ConvertsToLength()) {
|
||||
aSize.height = nsRuleNode::ComputeCoordPercentCalc(maxHeight, 0);
|
||||
aHeightSet = PR_TRUE;
|
||||
}
|
||||
// percentages and calc() with percentages are treated like 'none'
|
||||
|
||||
nsIContent* content = aBox->GetContent();
|
||||
if (content) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче