Add support for calc() to 'vertical-align' and 'text-indent'. (Bug 585715) r=bzbarsky a2.0=blocking:beta6+

This commit is contained in:
L. David Baron 2010-08-31 12:05:12 -04:00
Родитель 73db7cd5c4
Коммит b221c0b0c0
13 изменённых файлов: 335 добавлений и 186 удалений

Просмотреть файл

@ -715,9 +715,12 @@ nsBlockFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
} else { } else {
if (!curFrame->GetPrevContinuation() && if (!curFrame->GetPrevContinuation() &&
line == curFrame->begin_lines()) { line == curFrame->begin_lines()) {
// Only add text-indent if it has no percentages; using a
// percentage basis of 0 unconditionally would give strange
// behavior for calc(10%-3px).
const nsStyleCoord &indent = GetStyleText()->mTextIndent; const nsStyleCoord &indent = GetStyleText()->mTextIndent;
if (indent.GetUnit() == eStyleUnit_Coord) if (indent.ConvertsToLength())
data.currentLine += indent.GetCoordValue(); data.currentLine += nsRuleNode::ComputeCoordPercentCalc(indent, 0);
} }
// XXX Bug NNNNNN Should probably handle percentage text-indent. // XXX Bug NNNNNN Should probably handle percentage text-indent.
@ -790,9 +793,12 @@ nsBlockFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
} else { } else {
if (!curFrame->GetPrevContinuation() && if (!curFrame->GetPrevContinuation() &&
line == curFrame->begin_lines()) { line == curFrame->begin_lines()) {
// Only add text-indent if it has no percentages; using a
// percentage basis of 0 unconditionally would give strange
// behavior for calc(10%-3px).
const nsStyleCoord &indent = GetStyleText()->mTextIndent; const nsStyleCoord &indent = GetStyleText()->mTextIndent;
if (indent.GetUnit() == eStyleUnit_Coord) if (indent.ConvertsToLength())
data.currentLine += indent.GetCoordValue(); data.currentLine += nsRuleNode::ComputeCoordPercentCalc(indent, 0);
} }
// XXX Bug NNNNNN Should probably handle percentage text-indent. // XXX Bug NNNNNN Should probably handle percentage text-indent.
@ -5944,19 +5950,17 @@ nsBlockFrame::AdjustForTextIndent(const nsLineBox* aLine,
if (!GetPrevContinuation() && aLine == begin_lines().get()) { if (!GetPrevContinuation() && aLine == begin_lines().get()) {
// Adjust for the text-indent. See similar code in // Adjust for the text-indent. See similar code in
// nsLineLayout::BeginLineReflow. // nsLineLayout::BeginLineReflow.
nscoord indent = 0; const nsStyleCoord &textIndent = GetStyleText()->mTextIndent;
const nsStyleText* styleText = GetStyleText(); nscoord pctBasis = 0;
nsStyleUnit unit = styleText->mTextIndent.GetUnit(); if (textIndent.HasPercent()) {
if (eStyleUnit_Coord == unit) { // Only work out the percentage basis if we need to.
indent = styleText->mTextIndent.GetCoordValue();
} else if (eStyleUnit_Percent == unit) {
// It's a percentage of the containing block width. // It's a percentage of the containing block width.
nsIFrame* containingBlock = nsIFrame* containingBlock =
nsHTMLReflowState::GetContainingBlockFor(this); nsHTMLReflowState::GetContainingBlockFor(this);
NS_ASSERTION(containingBlock, "Must have containing block!"); NS_ASSERTION(containingBlock, "Must have containing block!");
indent = nscoord(styleText->mTextIndent.GetPercentValue() * pctBasis = containingBlock->GetContentRect().width;
containingBlock->GetContentRect().width);
} }
nscoord indent = nsRuleNode::ComputeCoordPercentCalc(textIndent, pctBasis);
// Adjust the start position and the width of the decoration by the // Adjust the start position and the width of the decoration by the
// value of the indent. Note that indent can be negative; that's OK. // value of the indent. Note that indent can be negative; that's OK.

Просмотреть файл

@ -231,21 +231,17 @@ nsLineLayout::BeginLineReflow(nscoord aX, nscoord aY,
// property amounts to anything. // property amounts to anything.
if (0 == mLineNumber && !HasPrevInFlow(mBlockReflowState->frame)) { if (0 == mLineNumber && !HasPrevInFlow(mBlockReflowState->frame)) {
nscoord indent = 0; const nsStyleCoord &textIndent = mStyleText->mTextIndent;
nsStyleUnit unit = mStyleText->mTextIndent.GetUnit(); nscoord pctBasis = 0;
if (eStyleUnit_Coord == unit) { if (textIndent.HasPercent()) {
indent = mStyleText->mTextIndent.GetCoordValue(); pctBasis =
}
else if (eStyleUnit_Percent == unit) {
nscoord width =
nsHTMLReflowState::GetContainingBlockContentWidth(mBlockReflowState); nsHTMLReflowState::GetContainingBlockContentWidth(mBlockReflowState);
if ((0 != width) && (NS_UNCONSTRAINEDSIZE != width)) {
indent = nscoord(mStyleText->mTextIndent.GetPercentValue() * width);
}
if (GetFlag(LL_GOTLINEBOX)) { if (GetFlag(LL_GOTLINEBOX)) {
mLineBox->DisableResizeReflowOptimization(); mLineBox->DisableResizeReflowOptimization();
} }
} }
nscoord indent = nsRuleNode::ComputeCoordPercentCalc(textIndent, pctBasis);
mTextIndent = indent; mTextIndent = indent;
@ -1783,176 +1779,174 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd)
} }
// Get vertical-align property // Get vertical-align property
const nsStyleTextReset* textStyle = frame->GetStyleTextReset(); const nsStyleCoord& verticalAlign =
nsStyleUnit verticalAlignUnit = textStyle->mVerticalAlign.GetUnit(); frame->GetStyleTextReset()->mVerticalAlign;
#ifdef NOISY_VERTICAL_ALIGN #ifdef NOISY_VERTICAL_ALIGN
printf(" [frame]"); printf(" [frame]");
nsFrame::ListTag(stdout, frame); nsFrame::ListTag(stdout, frame);
printf(": verticalAlignUnit=%d (enum == %d)\n", printf(": verticalAlignUnit=%d (enum == %d)\n",
verticalAlignUnit, verticalAlignUnit,
((eStyleUnit_Enumerated == verticalAlignUnit) ((eStyleUnit_Enumerated == verticalAlign.GetUnit())
? textStyle->mVerticalAlign.GetIntValue() ? verticalAlign.GetIntValue()
: -1)); : -1));
#endif #endif
PRUint8 verticalAlignEnum; if (verticalAlign.GetUnit() == eStyleUnit_Enumerated) {
nscoord parentAscent, parentDescent, parentXHeight; switch (verticalAlign.GetIntValue()) {
nscoord parentSuperscript, parentSubscript; default:
nscoord coordOffset, percentOffset, elementLineHeight; case NS_STYLE_VERTICAL_ALIGN_BASELINE:
nscoord revisedBaselineY; {
switch (verticalAlignUnit) { // The element's baseline is aligned with the baseline of
case eStyleUnit_Enumerated: // the parent.
default: pfd->mBounds.y = baselineY - pfd->mAscent;
if (eStyleUnit_Enumerated == verticalAlignUnit) { pfd->mVerticalAlign = VALIGN_OTHER;
verticalAlignEnum = textStyle->mVerticalAlign.GetIntValue(); break;
} }
else {
verticalAlignEnum = NS_STYLE_VERTICAL_ALIGN_BASELINE; case NS_STYLE_VERTICAL_ALIGN_SUB:
{
// Lower the baseline of the box to the subscript offset
// of the parent's box. This is identical to the baseline
// alignment except for the addition of the subscript
// offset to the baseline Y.
nscoord parentSubscript;
fm->GetSubscriptOffset(parentSubscript);
nscoord revisedBaselineY = baselineY + parentSubscript;
pfd->mBounds.y = revisedBaselineY - pfd->mAscent;
pfd->mVerticalAlign = VALIGN_OTHER;
break;
} }
switch (verticalAlignEnum) {
default:
case NS_STYLE_VERTICAL_ALIGN_BASELINE:
// The elements baseline is aligned with the baseline of
// the parent.
pfd->mBounds.y = baselineY - pfd->mAscent;
pfd->mVerticalAlign = VALIGN_OTHER;
break;
case NS_STYLE_VERTICAL_ALIGN_SUB: case NS_STYLE_VERTICAL_ALIGN_SUPER:
// Lower the baseline of the box to the subscript offset {
// of the parent's box. This is identical to the baseline // Raise the baseline of the box to the superscript offset
// alignment except for the addition of the subscript // of the parent's box. This is identical to the baseline
// offset to the baseline Y. // alignment except for the subtraction of the superscript
fm->GetSubscriptOffset(parentSubscript); // offset to the baseline Y.
revisedBaselineY = baselineY + parentSubscript; nscoord parentSuperscript;
pfd->mBounds.y = revisedBaselineY - pfd->mAscent; fm->GetSuperscriptOffset(parentSuperscript);
pfd->mVerticalAlign = VALIGN_OTHER; nscoord revisedBaselineY = baselineY - parentSuperscript;
break; pfd->mBounds.y = revisedBaselineY - pfd->mAscent;
pfd->mVerticalAlign = VALIGN_OTHER;
break;
}
case NS_STYLE_VERTICAL_ALIGN_SUPER: case NS_STYLE_VERTICAL_ALIGN_TOP:
// Raise the baseline of the box to the superscript offset {
// of the parent's box. This is identical to the baseline pfd->mVerticalAlign = VALIGN_TOP;
// alignment except for the subtraction of the superscript nscoord subtreeHeight = logicalHeight;
// offset to the baseline Y. if (frameSpan) {
fm->GetSuperscriptOffset(parentSuperscript); subtreeHeight = frameSpan->mMaxY - frameSpan->mMinY;
revisedBaselineY = baselineY - parentSuperscript; NS_ASSERTION(subtreeHeight >= logicalHeight,
pfd->mBounds.y = revisedBaselineY - pfd->mAscent; "unexpected subtree height");
pfd->mVerticalAlign = VALIGN_OTHER;
break;
case NS_STYLE_VERTICAL_ALIGN_TOP:
{
pfd->mVerticalAlign = VALIGN_TOP;
nscoord subtreeHeight = logicalHeight;
if (frameSpan) {
subtreeHeight = frameSpan->mMaxY - frameSpan->mMinY;
NS_ASSERTION(subtreeHeight >= logicalHeight,
"unexpected subtree height");
}
if (subtreeHeight > maxTopBoxHeight) {
maxTopBoxHeight = subtreeHeight;
}
break;
} }
if (subtreeHeight > maxTopBoxHeight) {
case NS_STYLE_VERTICAL_ALIGN_BOTTOM: maxTopBoxHeight = subtreeHeight;
{
pfd->mVerticalAlign = VALIGN_BOTTOM;
nscoord subtreeHeight = logicalHeight;
if (frameSpan) {
subtreeHeight = frameSpan->mMaxY - frameSpan->mMinY;
NS_ASSERTION(subtreeHeight >= logicalHeight,
"unexpected subtree height");
}
if (subtreeHeight > maxBottomBoxHeight) {
maxBottomBoxHeight = subtreeHeight;
}
break;
} }
break;
case NS_STYLE_VERTICAL_ALIGN_MIDDLE:
// Align the midpoint of the frame with 1/2 the parents
// x-height above the baseline.
fm->GetXHeight(parentXHeight);
if (frameSpan) {
pfd->mBounds.y = baselineY -
(parentXHeight + pfd->mBounds.height)/2;
}
else {
pfd->mBounds.y = baselineY - (parentXHeight + logicalHeight)/2 +
pfd->mMargin.top;
}
pfd->mVerticalAlign = VALIGN_OTHER;
break;
case NS_STYLE_VERTICAL_ALIGN_TEXT_TOP:
// The top of the logical box is aligned with the top of
// the parent elements text.
fm->GetMaxAscent(parentAscent);
if (frameSpan) {
pfd->mBounds.y = baselineY - parentAscent -
pfd->mBorderPadding.top + frameSpan->mTopLeading;
}
else {
pfd->mBounds.y = baselineY - parentAscent + pfd->mMargin.top;
}
pfd->mVerticalAlign = VALIGN_OTHER;
break;
case NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM:
// The bottom of the logical box is aligned with the
// bottom of the parent elements text.
fm->GetMaxDescent(parentDescent);
if (frameSpan) {
pfd->mBounds.y = baselineY + parentDescent -
pfd->mBounds.height + pfd->mBorderPadding.bottom -
frameSpan->mBottomLeading;
}
else {
pfd->mBounds.y = baselineY + parentDescent -
pfd->mBounds.height - pfd->mMargin.bottom;
}
pfd->mVerticalAlign = VALIGN_OTHER;
break;
case NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE:
// Align the midpoint of the frame with the baseline of the parent.
if (frameSpan) {
pfd->mBounds.y = baselineY - pfd->mBounds.height/2;
}
else {
pfd->mBounds.y = baselineY - logicalHeight/2 + pfd->mMargin.top;
}
pfd->mVerticalAlign = VALIGN_OTHER;
break;
} }
break;
case eStyleUnit_Coord: case NS_STYLE_VERTICAL_ALIGN_BOTTOM:
// According to the CSS2 spec (10.8.1), a positive value {
// "raises" the box by the given distance while a negative value pfd->mVerticalAlign = VALIGN_BOTTOM;
// "lowers" the box by the given distance (with zero being the nscoord subtreeHeight = logicalHeight;
// baseline). Since Y coordinates increase towards the bottom of if (frameSpan) {
// the screen we reverse the sign. subtreeHeight = frameSpan->mMaxY - frameSpan->mMinY;
coordOffset = textStyle->mVerticalAlign.GetCoordValue(); NS_ASSERTION(subtreeHeight >= logicalHeight,
revisedBaselineY = baselineY - coordOffset; "unexpected subtree height");
pfd->mBounds.y = revisedBaselineY - pfd->mAscent; }
pfd->mVerticalAlign = VALIGN_OTHER; if (subtreeHeight > maxBottomBoxHeight) {
break; maxBottomBoxHeight = subtreeHeight;
}
break;
}
case eStyleUnit_Percent: case NS_STYLE_VERTICAL_ALIGN_MIDDLE:
// Similar to a length value (eStyleUnit_Coord) except that the {
// percentage is a function of the elements line-height value. // Align the midpoint of the frame with 1/2 the parents
elementLineHeight = nsHTMLReflowState:: // x-height above the baseline.
CalcLineHeight(frame->GetStyleContext(), nscoord parentXHeight;
mBlockReflowState->ComputedHeight()); fm->GetXHeight(parentXHeight);
percentOffset = nscoord( if (frameSpan) {
textStyle->mVerticalAlign.GetPercentValue() * elementLineHeight pfd->mBounds.y = baselineY -
); (parentXHeight + pfd->mBounds.height)/2;
revisedBaselineY = baselineY - percentOffset; }
pfd->mBounds.y = revisedBaselineY - pfd->mAscent; else {
pfd->mVerticalAlign = VALIGN_OTHER; pfd->mBounds.y = baselineY - (parentXHeight + logicalHeight)/2 +
break; pfd->mMargin.top;
}
pfd->mVerticalAlign = VALIGN_OTHER;
break;
}
case NS_STYLE_VERTICAL_ALIGN_TEXT_TOP:
{
// The top of the logical box is aligned with the top of
// the parent element's text.
nscoord parentAscent;
fm->GetMaxAscent(parentAscent);
if (frameSpan) {
pfd->mBounds.y = baselineY - parentAscent -
pfd->mBorderPadding.top + frameSpan->mTopLeading;
}
else {
pfd->mBounds.y = baselineY - parentAscent + pfd->mMargin.top;
}
pfd->mVerticalAlign = VALIGN_OTHER;
break;
}
case NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM:
{
// The bottom of the logical box is aligned with the
// bottom of the parent elements text.
nscoord parentDescent;
fm->GetMaxDescent(parentDescent);
if (frameSpan) {
pfd->mBounds.y = baselineY + parentDescent -
pfd->mBounds.height + pfd->mBorderPadding.bottom -
frameSpan->mBottomLeading;
}
else {
pfd->mBounds.y = baselineY + parentDescent -
pfd->mBounds.height - pfd->mMargin.bottom;
}
pfd->mVerticalAlign = VALIGN_OTHER;
break;
}
case NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE:
{
// Align the midpoint of the frame with the baseline of the parent.
if (frameSpan) {
pfd->mBounds.y = baselineY - pfd->mBounds.height/2;
}
else {
pfd->mBounds.y = baselineY - logicalHeight/2 + pfd->mMargin.top;
}
pfd->mVerticalAlign = VALIGN_OTHER;
break;
}
}
} else {
// We have either a coord, a percent, or a calc().
nscoord pctBasis = 0;
if (verticalAlign.HasPercent()) {
// Percentages are like lengths, except treated as a percentage
// of the elements line-height value.
pctBasis = nsHTMLReflowState::CalcLineHeight(
frame->GetStyleContext(), mBlockReflowState->ComputedHeight());
}
nscoord offset =
nsRuleNode::ComputeCoordPercentCalc(verticalAlign, pctBasis);
// According to the CSS2 spec (10.8.1), a positive value
// "raises" the box by the given distance while a negative value
// "lowers" the box by the given distance (with zero being the
// baseline). Since Y coordinates increase towards the bottom of
// the screen we reverse the sign.
nscoord revisedBaselineY = baselineY - offset;
pfd->mBounds.y = revisedBaselineY - pfd->mAscent;
pfd->mVerticalAlign = VALIGN_OTHER;
} }
// Update minY/maxY for frames that we just placed. Do not factor // Update minY/maxY for frames that we just placed. Do not factor

Просмотреть файл

@ -16,6 +16,9 @@
== offsets-relative-right-1.html offsets-relative-left-1-ref.html == offsets-relative-right-1.html offsets-relative-left-1-ref.html
== offsets-relative-top-1.html offsets-relative-top-1-ref.html == offsets-relative-top-1.html offsets-relative-top-1-ref.html
== padding-block-1.html padding-block-1-ref.html == padding-block-1.html padding-block-1-ref.html
== text-indent-1.html text-indent-1-ref.html
== text-indent-intrinsic-1.html text-indent-intrinsic-1-ref.html
== vertical-align-1.html vertical-align-1-ref.html
== width-block-1.html width-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-block-intrinsic-1.html width-block-intrinsic-1-ref.html
== width-table-auto-1.html width-table-auto-1-ref.html == width-table-auto-1.html width-table-auto-1-ref.html

Просмотреть файл

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<title>text-indent: calc()</title>
<style>
body { width: 500px }
p { font-size: 10px }
</style>
<p style="text-indent: 247px">50% - 3px</p>
<p style="text-indent: 247px">25% - 3px + 25%</p>
<p style="text-indent: 247px">25% - 3px + 12.5% * 2</p>
<p style="text-indent: 247px">25% - 3px + 12.5%*2</p>
<p style="text-indent: 247px">25% - 3px + 2*12.5%</p>
<p style="text-indent: 247px">25% - 3px + 2 * 12.5%</p>
<p style="text-indent: 125px">min(25%, 150px)</p>
<p style="text-indent: 100px">min(25%, 100px)</p>
<p style="text-indent: 150px">max(25%, 150px)</p>
<p style="text-indent: 125px">max(25%, 100px)</p>
<p style="text-indent: 150px">min(25%, 150px) + 5%</p>
<p style="text-indent: 125px">min(25%, 100px) + 5%</p>
<p style="text-indent: 175px">max(25%, 150px) + 5%</p>
<p style="text-indent: 150px">max(25%, 100px) + 5%</p>
<p style="text-indent: 105px">min(25%, 150px) - 2em</p>
<p style="text-indent: 80px">min(25%, 100px) - 2em</p>
<p style="text-indent: 130px">max(25%, 150px) - 2em</p>
<p style="text-indent: 105px">max(25%, 100px) - 2em</p>
<p style="text-indent: 250px">30% + 20%</p>
<p style="text-indent: 250px">30% + max(20%, 1px)</p>
<p style="text-indent: 250px">max(25%, 50%)</p>
<p style="text-indent: 125px">max(25%, 50%)</p>

Просмотреть файл

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<title>text-indent: calc() on blocks</title>
<style>
body { width: 500px }
p { font-size: 10px }
</style>
<p style="text-indent: -moz-calc(50% - 3px)">50% - 3px</p>
<p style="text-indent: -moz-calc(25% - 3px + 25%)">25% - 3px + 25%</p>
<p style="text-indent: -moz-calc(25% - 3px + 12.5% * 2)">25% - 3px + 12.5% * 2</p>
<p style="text-indent: -moz-calc(25% - 3px + 12.5%*2)">25% - 3px + 12.5%*2</p>
<p style="text-indent: -moz-calc(25% - 3px + 2*12.5%)">25% - 3px + 2*12.5%</p>
<p style="text-indent: -moz-calc(25% - 3px + 2 * 12.5%)">25% - 3px + 2 * 12.5%</p>
<p style="text-indent: -moz-min(25%, 150px)">min(25%, 150px)</p>
<p style="text-indent: -moz-calc(min(25%, 100px))">min(25%, 100px)</p>
<p style="text-indent: -moz-calc(max(25%, 150px))">max(25%, 150px)</p>
<p style="text-indent: -moz-max(25%, 100px)">max(25%, 100px)</p>
<p style="text-indent: -moz-calc(min(25%, 150px) + 5%)">min(25%, 150px) + 5%</p>
<p style="text-indent: -moz-calc(min(25%, 100px) + 5%)">min(25%, 100px) + 5%</p>
<p style="text-indent: -moz-calc(max(25%, 150px) + 5%)">max(25%, 150px) + 5%</p>
<p style="text-indent: -moz-calc(max(25%, 100px) + 5%)">max(25%, 100px) + 5%</p>
<p style="text-indent: -moz-calc(min(25%, 150px) - 2em)">min(25%, 150px) - 2em</p>
<p style="text-indent: -moz-calc(min(25%, 100px) - 2em)">min(25%, 100px) - 2em</p>
<p style="text-indent: -moz-calc(max(25%, 150px) - 2em)">max(25%, 150px) - 2em</p>
<p style="text-indent: -moz-calc(max(25%, 100px) - 2em)">max(25%, 100px) - 2em</p>
<p style="text-indent: -moz-calc(30% + 20%)">30% + 20%</p>
<p style="text-indent: -moz-calc(30% + max(20%, 1px))">30% + max(20%, 1px)</p>
<p style="text-indent: -moz-calc(max(25%, 50%))">max(25%, 50%)</p>
<p style="text-indent: -moz-calc(min(25%, 50%))">max(25%, 50%)</p>

Просмотреть файл

@ -0,0 +1,22 @@
<!DOCTYPE HTML>
<title>intrinsic width of text-indent: calc() on blocks</title>
<style>
body > div { margin: 0 0 1px 0; background: blue; color: white; height: 5px }
</style>
<div style="width: 10px"></div>
<div style="width: 57px"></div>
<div style="width: 57px"></div>
<div style="width: 10px"></div>
<div style="width: 10px"></div>
<div style="width: 60px"></div>
<div style="width: 10px"></div>
<div style="width: 10px"></div>
<div style="width: 60px"></div>
<div style="width: 10px"></div>
<div style="width: 10px"></div>
<div style="width: 10px"></div>
<div style="width: 10px"></div>
<div style="width: 10px"></div>

Просмотреть файл

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<title>intrinsic width of text-indent: calc() on blocks</title>
<style>
body { font-size: 10px }
div { float: left; clear: left;
margin: 0 0 1px 0; background: blue; color: white; height: 5px }
span { display: inline-block; width: 10px }
</style>
<div style="text-indent: -moz-calc(50% - 3px)"><span></span></div>
<div style="text-indent: -moz-calc(5em - 3px)"><span></span></div>
<div style="text-indent: -moz-calc(max(5em, 0) - 3px)"><span></span></div>
<div style="text-indent: -moz-calc(max(5em, 0%) - 3px)"><span></span></div>
<div style="text-indent: -moz-calc(5em - min(3px, 0%))"><span></span></div>
<div style="text-indent: -moz-calc(5em - min(3px, 0))"><span></span></div>
<div style="text-indent: -moz-calc(5em - 0%)"><span></span></div>
<div style="text-indent: -moz-calc(50%)"><span></span></div>
<div style="text-indent: -moz-calc(50px)"><span></span></div>
<div style="text-indent: -moz-calc(25% + 25%)"><span></span></div>
<div style="text-indent: -moz-calc(min(25%, 50%))"><span></span></div>
<div style="text-indent: -moz-calc(max(25%, 50%))"><span></span></div>
<div style="text-indent: -moz-calc(min(25%, 100px))"><span></span></div>
<div style="text-indent: -moz-calc(max(25%, 100px))"><span></span></div>

Просмотреть файл

@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<title>Test for vertical-align:calc()</title>
<div style="line-height: 100px; margin-top: 100px">
<span>x</span>
<span style="vertical-align: 50px">x</span>
<span style="vertical-align: 50px">x</span>
<span style="vertical-align: 75px">x</span>
<span style="vertical-align: 45px">x</span>
<span style="vertical-align: 40px">x</span>
<span style="vertical-align: 30px">x</span>
</div>

Просмотреть файл

@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<title>Test for vertical-align:calc()</title>
<div style="line-height: 100px; margin-top: 100px">
<span>x</span>
<span style="vertical-align: -moz-calc(50px)">x</span>
<span style="vertical-align: -moz-calc(50%)">x</span>
<span style="vertical-align: -moz-calc(25px + 50%)">x</span>
<span style="vertical-align: -moz-calc(150% / 2 - 30px)">x</span>
<span style="vertical-align: -moz-calc(40px + 10% - 20% / 2)">x</span>
<span style="vertical-align: -moz-calc(40px - 10%)">x</span>
</div>

Просмотреть файл

@ -5939,7 +5939,7 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
case eCSSProperty_text_decoration: case eCSSProperty_text_decoration:
return ParseTextDecoration(aValue); return ParseTextDecoration(aValue);
case eCSSProperty_text_indent: case eCSSProperty_text_indent:
return ParseVariant(aValue, VARIANT_HLP, nsnull); return ParseVariant(aValue, VARIANT_HLP | VARIANT_CALC, nsnull);
case eCSSProperty_text_transform: case eCSSProperty_text_transform:
return ParseVariant(aValue, VARIANT_HK, return ParseVariant(aValue, VARIANT_HK,
nsCSSProps::kTextTransformKTable); nsCSSProps::kTextTransformKTable);
@ -5959,7 +5959,7 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
return ParseVariant(aValue, VARIANT_HK, return ParseVariant(aValue, VARIANT_HK,
nsCSSProps::kUserSelectKTable); nsCSSProps::kUserSelectKTable);
case eCSSProperty_vertical_align: case eCSSProperty_vertical_align:
return ParseVariant(aValue, VARIANT_HKLP, return ParseVariant(aValue, VARIANT_HKLP | VARIANT_CALC,
nsCSSProps::kVerticalAlignKTable); nsCSSProps::kVerticalAlignKTable);
case eCSSProperty_visibility: case eCSSProperty_visibility:
return ParseVariant(aValue, VARIANT_HK, return ParseVariant(aValue, VARIANT_HK,

Просмотреть файл

@ -3590,10 +3590,10 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
NS_STYLE_TEXT_ALIGN_DEFAULT, NS_STYLE_TEXT_ALIGN_DEFAULT,
0, 0, 0, 0); 0, 0, 0, 0);
// text-indent: length, percent, inherit, initial // text-indent: length, percent, calc, inherit, initial
SetCoord(textData.mTextIndent, text->mTextIndent, parentText->mTextIndent, SetCoord(textData.mTextIndent, text->mTextIndent, parentText->mTextIndent,
SETCOORD_LPH | SETCOORD_INITIAL_ZERO, aContext, SETCOORD_LPH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC,
mPresContext, canStoreInRuleTree); aContext, mPresContext, canStoreInRuleTree);
// text-transform: enum, inherit, initial // text-transform: enum, inherit, initial
SetDiscrete(textData.mTextTransform, text->mTextTransform, canStoreInRuleTree, SetDiscrete(textData.mTextTransform, text->mTextTransform, canStoreInRuleTree,
@ -3643,9 +3643,10 @@ nsRuleNode::ComputeTextResetData(void* aStartStruct,
{ {
COMPUTE_START_RESET(TextReset, (), text, parentText, Text, textData) COMPUTE_START_RESET(TextReset, (), text, parentText, Text, textData)
// vertical-align: enum, length, percent, inherit // vertical-align: enum, length, percent, calc, inherit
if (!SetCoord(textData.mVerticalAlign, text->mVerticalAlign, if (!SetCoord(textData.mVerticalAlign, text->mVerticalAlign,
parentText->mVerticalAlign, SETCOORD_LPH | SETCOORD_ENUMERATED, parentText->mVerticalAlign,
SETCOORD_LPH | SETCOORD_ENUMERATED | SETCOORD_STORE_CALC,
aContext, mPresContext, canStoreInRuleTree)) { aContext, mPresContext, canStoreInRuleTree)) {
if (eCSSUnit_Initial == textData.mVerticalAlign.GetUnit()) { if (eCSSUnit_Initial == textData.mVerticalAlign.GetUnit()) {
text->mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE, text->mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE,

Просмотреть файл

@ -1151,7 +1151,7 @@ struct nsStyleTextReset {
PRUint8 mTextDecoration; // [reset] see nsStyleConsts.h PRUint8 mTextDecoration; // [reset] see nsStyleConsts.h
PRUint8 mUnicodeBidi; // [reset] see nsStyleConsts.h PRUint8 mUnicodeBidi; // [reset] see nsStyleConsts.h
nsStyleCoord mVerticalAlign; // [reset] coord, percent, enum (see nsStyleConsts.h) nsStyleCoord mVerticalAlign; // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
}; };
struct nsStyleText { struct nsStyleText {
@ -1181,7 +1181,7 @@ struct nsStyleText {
nsStyleCoord mLetterSpacing; // [inherited] coord, normal nsStyleCoord mLetterSpacing; // [inherited] coord, normal
nsStyleCoord mLineHeight; // [inherited] coord, factor, normal nsStyleCoord mLineHeight; // [inherited] coord, factor, normal
nsStyleCoord mTextIndent; // [inherited] coord, percent nsStyleCoord mTextIndent; // [inherited] coord, percent, calc
nscoord mWordSpacing; // [inherited] nscoord mWordSpacing; // [inherited]
nsRefPtr<nsCSSShadowArray> mTextShadow; // [inherited] NULL in case of a zero-length nsRefPtr<nsCSSShadowArray> mTextShadow; // [inherited] NULL in case of a zero-length

Просмотреть файл

@ -2292,7 +2292,14 @@ var gCSSProperties = {
inherited: true, inherited: true,
type: CSS_TYPE_LONGHAND, type: CSS_TYPE_LONGHAND,
initial_values: [ "0" ], initial_values: [ "0" ],
other_values: [ "2em", "5%", "-10px" ], other_values: [ "2em", "5%", "-10px",
"-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: [] invalid_values: []
}, },
"text-shadow": { "text-shadow": {
@ -2396,7 +2403,14 @@ var gCSSProperties = {
inherited: false, inherited: false,
type: CSS_TYPE_LONGHAND, type: CSS_TYPE_LONGHAND,
initial_values: [ "baseline" ], initial_values: [ "baseline" ],
other_values: [ "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "15%", "3px", "0.2em", "-5px", "-3%" ], other_values: [ "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "15%", "3px", "0.2em", "-5px", "-3%",
"-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: [] invalid_values: []
}, },
"visibility": { "visibility": {