For fixed-layout tables, leave room for the cell spacing for all columns, whether they have cells originating in them or not, since we don't know if cells for those columns will arrive as the table loads incrementally. (Bug 444928) r=bernd sr=roc

This commit is contained in:
L. David Baron 2008-09-24 10:14:35 -07:00
Родитель 221f663a2d
Коммит 3347434086
13 изменённых файлов: 173 добавлений и 55 удалений

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

@ -0,0 +1,17 @@
<html>
<head>
<style type="text/css">
table{ width: 500px; }
</style>
</head>
<body>
<table class="grid" cellspacing="50" cellpadding="0" border>
<col width="10%"/>
<col width="1" span="2"/>
<tbody>
<tr><th class="top" colspan="3"> Some Text</th></tr>
</tbody>
</table>
</body>
</html>

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

@ -0,0 +1,17 @@
<html>
<head>
<style type="text/css">
table{table-layout: fixed; width: 500px; }
</style>
</head>
<body>
<table class="grid" cellspacing="50" cellpadding="0" border>
<col width="10%"/>
<col width="1" span="2"/>
<tbody>
<tr><th class="top" colspan="3"> Some Text</th></tr>
</tbody>
</table>
</body>
</html>

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

@ -0,0 +1,18 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Examples for bug 444928</title>
</head>
<body>
<table cellspacing="50" cellpadding="0" style="table-layout:fixed" width="652">
<col width="150">
<col width="150">
<col>
<tr><td colspan="2" style="background:yellow">1-2</td><td style="background:fuchsia">3</td></tr>
<tr style="color:transparent"><td>1</td><td>2</td><td>3</td></tr>
</tbody>
</table>
</body>
</html>

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

@ -0,0 +1,17 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Examples for bug 444928</title>
</head>
<body>
<table cellspacing="50" cellpadding="0" style="table-layout:fixed" width="652">
<col width="150">
<col width="150">
<col>
<tr><td colspan="2" style="background:yellow">1-2</td><td style="background:fuchsia">3</td></tr>
</tbody>
</table>
</body>
</html>

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

@ -0,0 +1,18 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Examples for bug 444928</title>
</head>
<body>
<table cellspacing="50" cellpadding="0" width="652">
<col width="150">
<col width="150">
<col>
<tr><td colspan="2" style="background:yellow">1-2</td><td style="background:fuchsia">3</td></tr>
<tr style="color:transparent"><td>1</td><td>2</td><td>3</td></tr>
</tbody>
</table>
</body>
</html>

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

@ -0,0 +1,17 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Examples for bug 444928</title>
</head>
<body>
<table cellspacing="50" cellpadding="0" width="652">
<col width="150">
<col width="150">
<col>
<tr><td colspan="2" style="background:yellow">1-2</td><td style="background:fuchsia">3</td></tr>
</tbody>
</table>
</body>
</html>

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

@ -908,6 +908,9 @@ random == 429849-1.html 429849-1-ref.html # bug 432288
== 441259-1.html 441259-1-ref.html
fails == 441259-2.html 441259-2-ref.html # bug 441400
== 444015-1.html 444015-1-ref.html
== 444928-1.html 444928-1-ref.html
== 444928-2.html 444928-2-ref.html
!= 444928-3.html 444928-3-notref.html
# == 448987.html 448987-ref.html # Disabled for now - it needs privileges
== 449171-1.html 449171-ref.html
== 449519-1.html 449519-1-ref.html
@ -916,4 +919,3 @@ fails == 441259-2.html 441259-2-ref.html # bug 441400
== 451168-1.html 451168-1-ref.html
== 454361.html about:blank
== 455280-1.xhtml 455280-1-ref.xhtml

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

@ -51,7 +51,8 @@
#undef DEBUG_TABLE_STRATEGY
BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aTableFrame)
: mTableFrame(aTableFrame)
: nsITableLayoutStrategy(nsITableLayoutStrategy::Auto)
, mTableFrame(aTableFrame)
{
MarkIntrinsicWidthsDirty();
}
@ -421,7 +422,7 @@ BasicTableLayoutStrategy::ComputeIntrinsicWidths(nsIRenderingContext* aRendering
NS_ERROR("column frames out of sync with cell map");
continue;
}
if (mTableFrame->GetNumCellsOriginatingInCol(col)) {
if (mTableFrame->ColumnHasCellSpacingBefore(col)) {
add += spacing;
}
min += colFrame->GetMinCoord();
@ -630,7 +631,7 @@ BasicTableLayoutStrategy::DistributeWidthToColumns(nscoord aWidth,
// each of the columns. We start at aFirstCol + 1 because the first
// in-between boundary would be at the left edge of column aFirstCol + 1
for (PRInt32 col = aFirstCol + 1; col < aFirstCol + aColCount; ++col) {
if (mTableFrame->GetNumCellsOriginatingInCol(col)) {
if (mTableFrame->ColumnHasCellSpacingBefore(col)) {
subtract += spacing;
}
}
@ -739,7 +740,7 @@ BasicTableLayoutStrategy::DistributeWidthToColumns(nscoord aWidth,
pref_width);
} else if (pref_width == 0) {
if (aWidthType == BTLS_FINAL_WIDTH &&
mTableFrame->GetNumCellsOriginatingInCol(col)) {
mTableFrame->ColumnHasCellSpacingBefore(col)) {
++numNonSpecZeroWidthCols;
}
} else {
@ -937,7 +938,7 @@ BasicTableLayoutStrategy::DistributeWidthToColumns(nscoord aWidth,
"when we're setting final width.");
if (pct == 0.0f &&
!colFrame->GetHasSpecifiedCoord() &&
mTableFrame->GetNumCellsOriginatingInCol(col)) {
mTableFrame->ColumnHasCellSpacingBefore(col)) {
NS_ASSERTION(col_width == 0 &&
colFrame->GetPrefCoord() == 0,

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

@ -47,7 +47,8 @@
#include "nsTableCellFrame.h"
FixedTableLayoutStrategy::FixedTableLayoutStrategy(nsTableFrame *aTableFrame)
: mTableFrame(aTableFrame)
: nsITableLayoutStrategy(nsITableLayoutStrategy::Fixed)
, mTableFrame(aTableFrame)
{
MarkIntrinsicWidthsDirty();
}
@ -65,28 +66,27 @@ FixedTableLayoutStrategy::GetMinWidth(nsIRenderingContext* aRenderingContext)
return mMinWidth;
// It's theoretically possible to do something much better here that
// depends only on the columns and the first row, but it wouldn't be
// compatible with other browsers, or with the use of GetMinWidth by
// nsHTMLReflowState to determine the width of a fixed-layout table,
// since CSS2.1 says:
// depends only on the columns and the first row (where we look at
// intrinsic widths inside the first row and then reverse the
// algorithm to find the narrowest width that would hold all of
// those intrinsic widths), but it wouldn't be compatible with other
// browsers, or with the use of GetMinWidth by
// nsTableFrame::ComputeSize to determine the width of a fixed
// layout table, since CSS2.1 says:
// The width of the table is then the greater of the value of the
// 'width' property for the table element and the sum of the
// column widths (plus cell spacing or borders).
// XXX Should we really ignore 'min-width' and 'max-width'?
// XXX Should we really ignore widths on column groups?
nsTableCellMap *cellMap = mTableFrame->GetCellMap();
PRInt32 colCount = cellMap->GetColCount();
nscoord spacing = mTableFrame->GetCellSpacingX();
// XXX Should this code do any pixel rounding?
nscoord result = 0;
// XXX Consider widths on columns or column groups?
if (colCount > 0) {
// XXX Should only add columns that have cells originating in them!
result += spacing * (colCount + 1);
}
@ -151,8 +151,11 @@ FixedTableLayoutStrategy::GetPrefWidth(nsIRenderingContext* aRenderingContext,
PRBool aComputingSize)
{
// It's theoretically possible to do something much better here that
// depends only on the columns and the first row, but it wouldn't be
// compatible with other browsers.
// depends only on the columns and the first row (where we look at
// intrinsic widths inside the first row and then reverse the
// algorithm to find the narrowest width that would hold all of
// those intrinsic widths), but it wouldn't be compatible with other
// browsers.
nscoord result = nscoord_MAX;
DISPLAY_PREF_WIDTH(mTableFrame, result);
return result;
@ -178,22 +181,18 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
PRInt32 colCount = cellMap->GetColCount();
nscoord spacing = mTableFrame->GetCellSpacingX();
// XXX Should this code do any pixel rounding?
// border-spacing isn't part of the basis for percentages.
if (colCount > 0) {
// XXX Should only add columns that have cells originating in them!
nscoord subtract = spacing * (colCount + 1);
tableWidth -= subtract;
} else {
if (colCount == 0) {
// No Columns - nothing to compute
return;
}
// border-spacing isn't part of the basis for percentages.
tableWidth -= spacing * (colCount + 1);
// XXX This ignores the 'min-width' and 'max-width' properties
// throughout. Then again, that's what the CSS spec says to do.
// XXX Consider widths on columns or column groups?
// XXX Should we really ignore widths on column groups?
PRUint32 unassignedCount = 0;
nscoord unassignedSpace = tableWidth;

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

@ -70,6 +70,18 @@ public:
* the available width.
*/
virtual void ComputeColumnWidths(const nsHTMLReflowState& aReflowState) = 0;
/**
* Return the type of table layout strategy, without the cost of
* a virtual function call
*/
enum Type { Auto, Fixed };
Type GetType() const { return mType; }
protected:
nsITableLayoutStrategy(Type aType) : mType(aType) {}
private:
Type mType;
};
#endif /* !defined(nsITableLayoutStrategy_h_) */

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

@ -430,12 +430,18 @@ void nsTableFrame::AttributeChangedFor(nsIFrame* aFrame,
PRInt32 nsTableFrame::GetEffectiveColCount() const
{
PRInt32 colCount = GetColCount();
// don't count cols at the end that don't have originating cells
for (PRInt32 colX = colCount - 1; colX >= 0; colX--) {
if (GetNumCellsOriginatingInCol(colX) <= 0) {
if (LayoutStrategy()->GetType() == nsITableLayoutStrategy::Auto) {
nsTableCellMap* cellMap = GetCellMap();
if (!cellMap) {
return 0;
}
// don't count cols at the end that don't have originating cells
for (PRInt32 colX = colCount - 1; colX >= 0; colX--) {
if (cellMap->GetNumCellsOriginatingInCol(colX) > 0) {
break;
}
colCount--;
}
else break;
}
return colCount;
}
@ -1613,8 +1619,7 @@ nsTableFrame::ProcessRowInserted(nscoord aNewHeight)
/* virtual */ void
nsTableFrame::MarkIntrinsicWidthsDirty()
{
static_cast<nsTableFrame*>(GetFirstInFlow())->
mTableLayoutStrategy->MarkIntrinsicWidthsDirty();
LayoutStrategy()->MarkIntrinsicWidthsDirty();
// XXXldb Call SetBCDamageArea?
@ -2212,7 +2217,7 @@ nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding)
PRInt32 colWidth = GetColumnWidth(colX);
if (!collapseGroup && !collapseCol) {
width += colWidth;
if (GetNumCellsOriginatingInCol(colX) > 0)
if (ColumnHasCellSpacingBefore(colX))
width += cellSpacingX;
}
}
@ -4017,22 +4022,17 @@ nsTableFrame::GetRowAndColumnByIndex(PRInt32 aIndex,
/*---------------- end of nsITableLayout implementation ------------------*/
PRInt32 nsTableFrame::GetNumCellsOriginatingInCol(PRInt32 aColIndex) const
PRBool
nsTableFrame::ColumnHasCellSpacingBefore(PRInt32 aColIndex) const
{
// Since fixed-layout tables should not have their column sizes change
// as they load, we assume that all columns are significant.
if (LayoutStrategy()->GetType() == nsITableLayoutStrategy::Fixed)
return PR_TRUE;
nsTableCellMap* cellMap = GetCellMap();
if (cellMap)
return cellMap->GetNumCellsOriginatingInCol(aColIndex);
else
return 0;
}
PRInt32 nsTableFrame::GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const
{
nsTableCellMap* cellMap = GetCellMap();
if (cellMap)
return cellMap->GetNumCellsOriginatingInRow(aRowIndex);
else
return 0;
if (!cellMap)
return PR_FALSE;
return cellMap->GetNumCellsOriginatingInCol(aColIndex) > 0;
}
static void

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

@ -530,8 +530,8 @@ public:
NS_IMETHOD GetIndexByRowAndColumn(PRInt32 aRow, PRInt32 aColumn, PRInt32 *aIndex);
NS_IMETHOD GetRowAndColumnByIndex(PRInt32 aIndex, PRInt32 *aRow, PRInt32 *aColumn);
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
PRBool ColumnHasCellSpacingBefore(PRInt32 aColIndex) const;
PRBool HasPctCol() const;
void SetHasPctCol(PRBool aValue);
@ -611,7 +611,7 @@ protected:
void AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
nsMargin aBorderPadding);
nsITableLayoutStrategy* LayoutStrategy() {
nsITableLayoutStrategy* LayoutStrategy() const {
return static_cast<nsTableFrame*>(GetFirstInFlow())->
mTableLayoutStrategy;
}

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

@ -684,7 +684,7 @@ CalcAvailWidth(nsTableFrame& aTableFrame,
else {
aColAvailWidth += colWidth;
}
if ((spanX > 0) && (aTableFrame.GetNumCellsOriginatingInCol(colIndex + spanX) > 0)) {
if ((spanX > 0) && aTableFrame.ColumnHasCellSpacingBefore(colIndex + spanX)) {
cellSpacing += aCellSpacingX;
}
}
@ -723,7 +723,7 @@ GetSpaceBetween(PRInt32 aPrevColIndex,
if (!isCollapsed)
space += aTableFrame.GetColumnWidth(colX);
}
if (!isCollapsed && (aTableFrame.GetNumCellsOriginatingInCol(colX) > 0)) {
if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) {
space += aCellSpacingX;
}
}
@ -747,7 +747,7 @@ GetSpaceBetween(PRInt32 aPrevColIndex,
if (!isCollapsed)
space += aTableFrame.GetColumnWidth(colX);
}
if (!isCollapsed && (aTableFrame.GetNumCellsOriginatingInCol(colX) > 0)) {
if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) {
space += aCellSpacingX;
}
}
@ -1242,7 +1242,7 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
const nsStyleVisibility* nextColVis =
nextColFrame->GetStyleVisibility();
if ( (NS_STYLE_VISIBILITY_COLLAPSE != nextColVis->mVisible) &&
(tableFrame->GetNumCellsOriginatingInCol(colX + colIncrement) > 0)) {
tableFrame->ColumnHasCellSpacingBefore(colX + colIncrement)) {
cRect.width += cellSpacingX;
}
}