Only do special height reflows for percentage-height children of table cells when there is a specified height on the table, row group, row, or cell in the row. b=370525 Patch by Daniel Holbert <dholbert@mozilla.com>. r+sr=dbaron

This commit is contained in:
dbaron@dbaron.org 2007-06-25 13:34:35 -07:00
Родитель d782232066
Коммит 731e0cce6c
29 изменённых файлов: 608 добавлений и 36 удалений

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

@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 370525 Anti-Reference Testcase</title>
</head>
<body>
<table style="border: 2px solid blue;">
<tr><td style="height: 10%">
<table style="height: 100%; border: 1px dotted red;">
<tr><td>Table 1</td></tr>
</table>
<table style="height: 100%; border: 1px dotted red;">
<tr><td>Table 2</td></tr>
</table>
</td></tr>
</table>
</body>
</html>

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

@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 370525 Reference Testcase</title>
</head>
<body>
<table style="border: 2px solid blue;">
<tr><td>
<table style="border: 1px dotted red;">
<tr><td>Table 1</td></tr>
</table>
<table style="border: 1px dotted red;">
<tr><td>Table 2</td></tr>
</table>
</td></tr>
</table>
</body>
</html>

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

@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 370525 Testcase</title>
</head>
<body>
<table style="border: 2px solid blue;">
<tr><td>
<table style="height: 100%; border: 1px dotted red;">
<tr><td>Table 1</td></tr>
</table>
<table style="height: 100%; border: 1px dotted red;">
<tr><td>Table 2</td></tr>
</table>
</td></tr>
</table>
</body>
</html>

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

@ -0,0 +1,17 @@
<html>
<head>
<title>Bug 370525 Anti-Reference Testcase</title>
</head>
<body>
<table style="border: 2px solid blue;">
<tr><td style="height: 10%">
<table style="height: 100%; border: 1px dotted red;">
<tr><td>Table 1</td></tr>
</table>
<table style="height: 100%; border: 1px dotted red;">
<tr><td>Table 2</td></tr>
</table>
</td></tr>
</table>
</body>
</html>

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

@ -0,0 +1,17 @@
<html>
<head>
<title>Bug 370525 Reference Testcase</title>
</head>
<body>
<table style="border: 2px solid blue;">
<tr><td>
<table style="border: 1px dotted red;">
<tr><td>Table 1</td></tr>
</table>
<table style="border: 1px dotted red;">
<tr><td>Table 2</td></tr>
</table>
</td></tr>
</table>
</body>
</html>

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

@ -0,0 +1,17 @@
<html>
<head>
<title>Bug 370525 Testcase</title>
</head>
<body>
<table style="border: 2px solid blue;">
<tr><td>
<table style="height: 100%; border: 1px dotted red;">
<tr><td>Table 1</td></tr>
</table>
<table style="height: 100%; border: 1px dotted red;">
<tr><td>Table 2</td></tr>
</table>
</td></tr>
</table>
</body>
</html>

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

@ -0,0 +1,28 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div,
with specified height on a sibling
<table>
<tr>
<td style="background: lightgreen" rowspan="2">
<div>
height=75% / ignored
</div>
blah
</td>
<td style="background: lightblue" height="200px">
height=200px.
</td>
</tr>
<tr>
<td style="background: orange">
2nd row, 1st column
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,28 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div,
with specified height on a sibling
<table>
<tr>
<td style="background: lightgreen" rowspan="2">
<div style="height: 75%">
height=75% / ignored
</div>
blah
</td>
<td style="background: lightblue" height="200px">
height=200px.
</td>
</tr>
<tr>
<td style="background: orange">
2nd row, 1st column
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,28 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div,
with specified height on a sibling
<table>
<tr>
<td style="background: lightgreen" rowspan="2">
<div>
height=75% / ignored
</div>
blah
</td>
<td style="background: orange">
1st row, 2nd column.
</td>
</tr>
<tr>
<td style="background: lightblue" height="200px">
2nd row, 1st column. height=200px.
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,28 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div,
with specified height on a sibling
<table>
<tr>
<td style="background: lightgreen" rowspan="2">
<div style="height: 75%">
height=75% / ignored
</div>
blah
</td>
<td style="background: orange">
1st row, 2nd column.
</td>
</tr>
<tr>
<td style="background: lightblue" height="200px">
2nd row, 1st column. height=200px.
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,23 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div, with specified
height on a sibling. Also, does not explicitly create 2nd row.
<table>
<tr>
<td style="background: lightgreen" rowspan="2">
<div style="height: 150px">
height=75% / 150px
</div>
blah
</td>
<td style="background: lightblue" height="200px">
height=200px.
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,23 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div, with specified
height on a sibling. Also, does not explicitly create 2nd row.
<table>
<tr>
<td style="background: lightgreen" rowspan="2">
<div style="height: 75%">
height=75% / 150px
</div>
blah
</td>
<td style="background: lightblue" height="200px">
height=200px.
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,28 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 and specified height on a sibling of the cell with percent-height div.
<table>
<tr>
<td style="background: lightgreen">
<div>
height=75% / ignored
</div>
blah
</td>
<td style="background: lightblue" height="200px" rowspan="2">
height=200px.
</td>
</tr>
<tr>
<td style="background: orange">
2nd row, 1st column
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,28 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 and specified height on a sibling of the cell with percent-height div.
<table>
<tr>
<td style="background: lightgreen">
<div style="height: 75%">
height=75% / ignored
</div>
blah
</td>
<td style="background: lightblue" height="200px" rowspan="2">
height=200px.
</td>
</tr>
<tr>
<td style="background: orange">
2nd row, 1st column
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,24 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 and specified height on a sibling of the cell with
percent-height div. Also, does not explicitly create 2nd row.
<table>
<tr>
<td style="background: lightgreen">
<div style="height: 150px">
height=75% / 150px
</div>
blah
</td>
<td style="background: lightblue" height="200px" rowspan="2">
height=200px.
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,24 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 and specified height on a sibling of the cell with
percent-height div. Also, does not explicitly create 2nd row.
<table>
<tr>
<td style="background: lightgreen">
<div style="height: 75%">
height=75% / 150px
</div>
blah
</td>
<td style="background: lightblue" height="200px" rowspan="2">
height=200px.
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,26 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div,
with specified height on table
<table height="200px">
<tr>
<td style="background: lightgreen" rowspan="2">
<div style="height: 150px">
height=75% / 150px
</div>
blah
</td>
<td style="background: lightblue"> first row, second column </td>
</tr>
<tr>
<td style="background: orange">
2nd row, only column
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,26 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div,
with specified height on table
<table height="200px">
<tr>
<td style="background: lightgreen" rowspan="2">
<div style="height: 75%">
height=75% / 150px
</div>
blah
</td>
<td style="background: lightblue"> first row, second column </td>
</tr>
<tr>
<td style="background: orange">
2nd row, only column
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,26 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div,
with specified height on row
<table>
<tr height="160px">
<td style="background: lightgreen" rowspan="2">
<div style="height: 150px;">
height=75% / 150px
</div>
blah
</td>
<td style="background: lightblue"> first row, second column </td>
</tr>
<tr height="40px">
<td style="background: orange">
2nd row, only column
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,26 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
rowspan=2 on the cell with the percent-height div,
with specified height on row
<table>
<tr height="160px">
<td style="background: lightgreen" rowspan="2">
<div style="height: 75%">
height=75% / 150px
</div>
blah
</td>
<td style="background: lightblue"> first row, second column </td>
</tr>
<tr height="40px">
<td style="background: orange">
2nd row, only column
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
Specified height on sibling cell
<table>
<tr>
<td style="background: lightgreen">
<div style="height: 150px">height=75% / 150px</div>
blah
</td>
<td style="height: 200px; background: lightblue">height=200px</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,18 @@
<html>
<head>
<link rel="stylesheet" href="370525-style.css"/>
</head>
<body>
Specified height on sibling cell
<table>
<tr>
<td style="background: lightgreen">
<div style="height: 75%">height=75% / 150px</div>
blah
</td>
<td style="height: 200px; background: lightblue">height=200px</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,13 @@
div {
background: yellow;
}
table {
background: grey;
border-spacing: 0;
border-collapse: collapse;
}
td, th {
padding: 0;
vertical-align: top;
}

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

@ -224,6 +224,19 @@ fails == 368504-1.html 368504-1-ref.html # bug 368504
== 369975-1.html 369975-1.html
== 369882.xul 369882-ref.xul
== 370422-1.html 370422-1-ref.html
== 370525-1.html 370525-1-ref.html
!= 370525-1.html 370525-1-notref.html
== 370525-2.html 370525-2-ref.html
!= 370525-2.html 370525-2-notref.html
!= 370525-2.html 370525-2-notref.html
== 370525-rowspan-1a.html 370525-rowspan-1a-ref.html
== 370525-rowspan-1b.html 370525-rowspan-1b-ref.html
== 370525-rowspan-1c.html 370525-rowspan-1c-ref.html
== 370525-rowspan-2a.html 370525-rowspan-2a-ref.html
== 370525-rowspan-2b.html 370525-rowspan-2b-ref.html
== 370525-rowspan-3.html 370525-rowspan-3-ref.html
== 370525-rowspan-4.html 370525-rowspan-4-ref.html
== 370525-sib.html 370525-sib-ref.html
== 370586-1.xhtml 370586-1-ref.xhtml
== 370629-1.html 370629-1-ref.html
== 370629-2.html 370629-2-ref.html

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

@ -135,13 +135,23 @@ nsTableCellFrame::NotifyPercentHeight(const nsHTMLReflowState& aReflowState)
// are based on the height of the cell, since its containing block
// is the inner cell frame.
for (const nsHTMLReflowState *rs = aReflowState.parentReflowState;
rs != cellRS;
rs = rs->parentReflowState) {
rs->frame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_HEIGHT);
}
// We'll only honor the percent height if sibling-cells/ancestors
// have specified/pct height. (Also, siblings only count for this if
// both this cell and the sibling cell span exactly 1 row.)
nsTableFrame::RequestSpecialHeightReflow(*cellRS);
if (nsTableFrame::AncestorsHaveStyleHeight(*cellRS) ||
(nsTableFrame::GetTableFrame(this)->GetEffectiveRowSpan(*this) == 1 &&
(cellRS->parentReflowState->frame->GetStateBits() &
NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT))) {
for (const nsHTMLReflowState *rs = aReflowState.parentReflowState;
rs != cellRS;
rs = rs->parentReflowState) {
rs->frame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_HEIGHT);
}
nsTableFrame::RequestSpecialHeightReflow(*cellRS);
}
}
}

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

@ -1692,41 +1692,24 @@ nsTableFrame::ComputeAutoSize(nsIRenderingContext *aRenderingContext,
NS_UNCONSTRAINEDSIZE);
}
// Return true if aStylePosition has a pct height
static PRBool
IsPctStyleHeight(const nsStylePosition* aStylePosition)
// Return true if aParentReflowState.frame or any of its ancestors within
// the containing table have non-auto height. (e.g. pct or fixed height)
PRBool
nsTableFrame::AncestorsHaveStyleHeight(const nsHTMLReflowState& aParentReflowState)
{
return (aStylePosition &&
(eStyleUnit_Percent == aStylePosition->mHeight.GetUnit()));
}
// Return true if aStylePosition has a coord height
static PRBool
IsFixedStyleHeight(const nsStylePosition* aStylePosition)
{
return (aStylePosition &&
(eStyleUnit_Coord == aStylePosition->mHeight.GetUnit()));
}
// Return true if any of aReflowState.frame's ancestors within the containing table
// have a pct or fixed height
static PRBool
AncestorsHaveStyleHeight(const nsHTMLReflowState& aReflowState)
{
for (const nsHTMLReflowState* parentRS = aReflowState.parentReflowState;
parentRS && parentRS->frame;
parentRS = parentRS->parentReflowState) {
nsIAtom* frameType = parentRS->frame->GetType();
if (IS_TABLE_CELL(frameType) ||
for (const nsHTMLReflowState* rs = &aParentReflowState;
rs && rs->frame; rs = rs->parentReflowState) {
nsIAtom* frameType = rs->frame->GetType();
if (IS_TABLE_CELL(frameType) ||
(nsGkAtoms::tableRowFrame == frameType) ||
(nsGkAtoms::tableRowGroupFrame == frameType)) {
if (::IsPctStyleHeight(parentRS->mStylePosition) || ::IsFixedStyleHeight(parentRS->mStylePosition)) {
if (rs->mStylePosition->mHeight.GetUnit() != eStyleUnit_Auto) {
return PR_TRUE;
}
}
else if (nsGkAtoms::tableFrame == frameType) {
// we reached the containing table, so always return
if (::IsPctStyleHeight(parentRS->mStylePosition) || ::IsFixedStyleHeight(parentRS->mStylePosition)) {
if (rs->mStylePosition->mHeight.GetUnit() != eStyleUnit_Auto) {
return PR_TRUE;
}
else return PR_FALSE;
@ -1742,8 +1725,8 @@ nsTableFrame::CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowSt
if (!aReflowState.frame->GetPrevInFlow() && // 1st in flow
(NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight || // no computed height
0 == aReflowState.mComputedHeight) &&
::IsPctStyleHeight(aReflowState.mStylePosition) && // pct height
::AncestorsHaveStyleHeight(aReflowState)) {
eStyleUnit_Percent == aReflowState.mStylePosition->mHeight.GetUnit() && // pct height
nsTableFrame::AncestorsHaveStyleHeight(*aReflowState.parentReflowState)) {
nsTableFrame::RequestSpecialHeightReflow(aReflowState);
}
}

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

@ -115,6 +115,10 @@ public:
static float GetTwipsToPixels(nsPresContext* aPresContext);
// Return true if aParentReflowState.frame or any of its ancestors within
// the containing table have non-auto height. (e.g. pct or fixed height)
static PRBool AncestorsHaveStyleHeight(const nsHTMLReflowState& aParentReflowState);
// See if a special height reflow will occur due to having a pct height when
// the pct height basis may not yet be valid.
static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);

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

@ -1034,6 +1034,9 @@ nsTableRowFrame::Reflow(nsPresContext* aPresContext,
// see if a special height reflow needs to occur due to having a pct height
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
// See if we have a cell with specified/pct height
InitHasCellWithStyleHeight(tableFrame);
rv = ReflowChildren(aPresContext, aDesiredSize, aReflowState, *tableFrame,
aStatus);
@ -1333,6 +1336,32 @@ void nsTableRowFrame::SetContinuousBCBorderWidth(PRUint8 aForSide,
}
}
/**
* Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
* this row has any cells that have non-auto-height. (Row-spanning
* cells are ignored.)
*/
void nsTableRowFrame::InitHasCellWithStyleHeight(nsTableFrame* aTableFrame)
{
nsTableIterator iter(*this);
for (nsIFrame* kidFrame = iter.First(); kidFrame; kidFrame = iter.Next()) {
nsIAtom* frameType = kidFrame->GetType();
if (!IS_TABLE_CELL(frameType)) {
NS_NOTREACHED("Table row has a non-cell child.");
continue;
}
nsTableCellFrame* cellFrame = NS_STATIC_CAST(nsTableCellFrame*, kidFrame);
// Ignore row-spanning cells
if (aTableFrame->GetEffectiveRowSpan(*cellFrame) == 1 &&
cellFrame->GetStylePosition()->mHeight.GetUnit() != eStyleUnit_Auto) {
AddStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
return;
}
}
RemoveStateBits(NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT);
}
/* ----- global methods ----- */
nsIFrame*

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

@ -45,10 +45,15 @@ class nsTableFrame;
class nsTableCellFrame;
struct nsTableCellReflowState;
#define NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT 0x40000000
// This is also used on rows, from nsTableRowGroupFrame.h
// #define NS_REPEATED_ROW_OR_ROWGROUP 0x10000000
// Indicates whether this row has any cells that have
// non-auto-height and rowspan=1
#define NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT 0x20000000
#define NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT 0x40000000
/**
* nsTableRowFrame is the frame that maps table rows
* (HTML tag TR). This class cannot be reused
@ -302,6 +307,14 @@ private:
BCPixelSize mRightContBorderWidth;
BCPixelSize mTopContBorderWidth;
BCPixelSize mLeftContBorderWidth;
/**
* Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
* this row has any cells that have non-auto-height. (Row-spanning
* cells are ignored.)
*/
void InitHasCellWithStyleHeight(nsTableFrame* aTableFrame);
};
inline PRInt32 nsTableRowFrame::GetRowIndex() const