зеркало из https://github.com/mozilla/gecko-dev.git
COLS attribute ignored if any column width info is specified (like <TD width=100>)
fixed lots of COLS related bugs. handle min width spec (<TD width=0 or width=0% or width=0*>) major fix to colspan handling
This commit is contained in:
Родитель
1820e221a5
Коммит
cb77901bc4
|
@ -282,6 +282,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
|
||||
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
|
||||
nscoord cellDesiredWidth = cellDesiredSize.width;
|
||||
nscoord cellMinWidth = cellMinSize.width;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n",
|
||||
rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
|
||||
|
@ -292,15 +293,24 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
// This col has a specified fixed width so set the min and max width to the larger of
|
||||
// (specified width, largest max_element_size of the cells in the column)
|
||||
// factoring in the min width of the prior cells (stored in minColWidth)
|
||||
nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
|
||||
nscoord widthForThisCell = specifiedFixedColWidth;
|
||||
if (0==specifiedFixedColWidth) // set to min
|
||||
specifiedFixedColWidth = cellMinWidth;
|
||||
widthForThisCell = PR_MAX(widthForThisCell, minColWidth);
|
||||
widthForThisCell = widthForThisCell/colSpan;
|
||||
mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
|
||||
maxColWidth = widthForThisCell;
|
||||
if ((1==colSpan) && (effectiveMaxColumnWidth < widthForThisCell))
|
||||
effectiveMaxColumnWidth = widthForThisCell;
|
||||
if (gsDebug)
|
||||
printf (" setting min and max col width to specified fixed width %d\n", widthForThisCell);
|
||||
minColWidth = widthForThisCell;
|
||||
if (1==colSpan)
|
||||
{
|
||||
effectiveMaxColumnWidth = PR_MAX(effectiveMaxColumnWidth, widthForThisCell);
|
||||
if (0==effectiveMinColumnWidth)
|
||||
effectiveMinColumnWidth = widthForThisCell;
|
||||
else
|
||||
effectiveMinColumnWidth = PR_MIN(effectiveMinColumnWidth, widthForThisCell);
|
||||
//above line works for most tables, but it can't be right
|
||||
//effectiveMinColumnWidth = PR_MIN(effectiveMinColumnWidth, cellMinWidth);
|
||||
//above line seems right and works for xT1, but breaks lots of other tables.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -308,6 +318,11 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
maxColWidth = cellDesiredWidth;
|
||||
if ((1==colSpan) && (effectiveMaxColumnWidth < maxColWidth))
|
||||
effectiveMaxColumnWidth = cellDesiredWidth;
|
||||
if (minColWidth < cellMinWidth)
|
||||
minColWidth = cellMinWidth;
|
||||
// effectiveMinColumnWidth is the min width as if no cells with colspans existed
|
||||
if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth))
|
||||
effectiveMinColumnWidth = cellMinWidth;
|
||||
}
|
||||
|
||||
//bookkeeping: is this the cell that gave the column it's fixed width attribute?
|
||||
|
@ -320,13 +335,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
|
||||
}
|
||||
|
||||
// cellMinWidth can override fixed width, so factor it in here
|
||||
nscoord cellMinWidth = cellMinSize.width;
|
||||
if (minColWidth < cellMinWidth)
|
||||
minColWidth = cellMinWidth;
|
||||
// effectiveMinColumnWidth is the min width as if no cells with colspans existed
|
||||
if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth))
|
||||
effectiveMinColumnWidth = cellMinWidth;
|
||||
if (1<colSpan)
|
||||
{
|
||||
// add the column to our list of post-process columns, if all of the intersected columns are auto
|
||||
|
@ -522,6 +530,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
// if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth
|
||||
if (PR_TRUE==hasColsAttribute)
|
||||
{
|
||||
if (gsDebug) printf("has COLS attribute = %d\n", mCols);
|
||||
// for every effected column, subtract out its prior contribution and add back in the new value
|
||||
PRInt32 numColsEffected = mNumCols;
|
||||
if (NS_STYLE_TABLE_COLS_ALL!=mCols)
|
||||
|
@ -554,6 +563,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
mTableFrame->GetColumnFrame(effectedColIndex, colFrame);
|
||||
colFrame->SetMaxColWidth(maxOfMaxColWidths); // cache the new column max width (min width is uneffected)
|
||||
colFrame->SetEffectiveMaxColWidth(maxOfMaxColWidths);
|
||||
if (gsDebug) printf ("col %d now has max col width %d\n", effectedColIndex, maxOfMaxColWidths);
|
||||
}
|
||||
delete [] minColWidthArray;
|
||||
delete [] maxColWidthArray;
|
||||
|
|
|
@ -520,6 +520,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
|
|||
if (nsnull==mCellMap)
|
||||
return; // no info yet, so nothing useful to do
|
||||
|
||||
// make sure we've accounted for the COLS attribute
|
||||
AdjustColumnsForCOLSAttribute();
|
||||
|
||||
PRInt32 actualColumns = 0;
|
||||
nsTableColGroupFrame *lastColGroupFrame = nsnull;
|
||||
nsIFrame * firstRowGroupFrame=nsnull;
|
||||
|
@ -2438,13 +2441,47 @@ void nsTableFrame::VerticallyAlignChildren(nsIPresContext* aPresContext,
|
|||
{
|
||||
}
|
||||
|
||||
void nsTableFrame::AdjustColumnsForCOLSAttribute()
|
||||
{
|
||||
NS_ASSERTION(nsnull!=mCellMap, "bad cell map");
|
||||
|
||||
// any specified-width column turns off COLS attribute
|
||||
nsStyleTable* tableStyle = (nsStyleTable *)mStyleContext->GetMutableStyleData(eStyleStruct_Table);
|
||||
if (tableStyle->mCols != NS_STYLE_TABLE_COLS_NONE)
|
||||
{
|
||||
PRInt32 numCols = GetColCount();
|
||||
PRInt32 numRows = GetRowCount();
|
||||
for (PRInt32 rowIndex=0; rowIndex<numRows; rowIndex++)
|
||||
{
|
||||
for (PRInt32 colIndex=0; colIndex<numCols; colIndex++)
|
||||
{
|
||||
nsTableCellFrame *cellFrame = mCellMap->GetCellFrameAt(rowIndex, colIndex);
|
||||
// get the cell style info
|
||||
const nsStylePosition* cellPosition;
|
||||
if (nsnull!=cellFrame)
|
||||
{
|
||||
cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
|
||||
if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) ||
|
||||
(eStyleUnit_Percent==cellPosition->mWidth.GetUnit()))
|
||||
{
|
||||
tableStyle->mCols = NS_STYLE_TABLE_COLS_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
nsTableRowFrame * aRowFrame)
|
||||
{
|
||||
// if this cell is in the first row, then the width attribute
|
||||
// also acts as the width attribute for the entire column
|
||||
// if this cell is the first non-col-spanning cell to have a width attribute,
|
||||
// then the width attribute also acts as the width attribute for the entire column
|
||||
// if the cell has a colspan, the width is used provisionally, divided equally among
|
||||
// the spanned columns
|
||||
if ((nsnull!=aPresContext) && (nsnull!=aCellFrame) && (nsnull!=aRowFrame))
|
||||
{
|
||||
// get the cell style info
|
||||
|
|
|
@ -123,6 +123,12 @@ public:
|
|||
nsTableCellFrame* aCellFrame,
|
||||
nsTableRowFrame * aRowFrame);
|
||||
|
||||
/** the COLS attribute can be modified by any cell's width attribute.
|
||||
* deal with it here. Must be called before any call to
|
||||
* ColumnInfoCache::AddColumnInfo
|
||||
*/
|
||||
virtual void AdjustColumnsForCOLSAttribute();
|
||||
|
||||
/** return the column frame corresponding to the given column index
|
||||
* there are two ways to do this, depending on whether we have cached
|
||||
* column information yet.
|
||||
|
|
|
@ -574,7 +574,9 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
|||
kidFrame->WillReflow(aPresContext);
|
||||
if (gsDebug1) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width);
|
||||
status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState);
|
||||
if (gsDebug1) printf ("%p InitR: desired=%d\n", this, kidSize.width);
|
||||
if (gsDebug1)
|
||||
printf ("%p InitR: desired=%d, MES=%d\n",
|
||||
this, kidSize.width, kidMaxElementSize.width);
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize);
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
|
||||
NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "unexpected child reflow status");
|
||||
|
|
|
@ -282,6 +282,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
|
||||
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
|
||||
nscoord cellDesiredWidth = cellDesiredSize.width;
|
||||
nscoord cellMinWidth = cellMinSize.width;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n",
|
||||
rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
|
||||
|
@ -292,15 +293,24 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
// This col has a specified fixed width so set the min and max width to the larger of
|
||||
// (specified width, largest max_element_size of the cells in the column)
|
||||
// factoring in the min width of the prior cells (stored in minColWidth)
|
||||
nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
|
||||
nscoord widthForThisCell = specifiedFixedColWidth;
|
||||
if (0==specifiedFixedColWidth) // set to min
|
||||
specifiedFixedColWidth = cellMinWidth;
|
||||
widthForThisCell = PR_MAX(widthForThisCell, minColWidth);
|
||||
widthForThisCell = widthForThisCell/colSpan;
|
||||
mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
|
||||
maxColWidth = widthForThisCell;
|
||||
if ((1==colSpan) && (effectiveMaxColumnWidth < widthForThisCell))
|
||||
effectiveMaxColumnWidth = widthForThisCell;
|
||||
if (gsDebug)
|
||||
printf (" setting min and max col width to specified fixed width %d\n", widthForThisCell);
|
||||
minColWidth = widthForThisCell;
|
||||
if (1==colSpan)
|
||||
{
|
||||
effectiveMaxColumnWidth = PR_MAX(effectiveMaxColumnWidth, widthForThisCell);
|
||||
if (0==effectiveMinColumnWidth)
|
||||
effectiveMinColumnWidth = widthForThisCell;
|
||||
else
|
||||
effectiveMinColumnWidth = PR_MIN(effectiveMinColumnWidth, widthForThisCell);
|
||||
//above line works for most tables, but it can't be right
|
||||
//effectiveMinColumnWidth = PR_MIN(effectiveMinColumnWidth, cellMinWidth);
|
||||
//above line seems right and works for xT1, but breaks lots of other tables.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -308,6 +318,11 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
maxColWidth = cellDesiredWidth;
|
||||
if ((1==colSpan) && (effectiveMaxColumnWidth < maxColWidth))
|
||||
effectiveMaxColumnWidth = cellDesiredWidth;
|
||||
if (minColWidth < cellMinWidth)
|
||||
minColWidth = cellMinWidth;
|
||||
// effectiveMinColumnWidth is the min width as if no cells with colspans existed
|
||||
if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth))
|
||||
effectiveMinColumnWidth = cellMinWidth;
|
||||
}
|
||||
|
||||
//bookkeeping: is this the cell that gave the column it's fixed width attribute?
|
||||
|
@ -320,13 +335,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
|
||||
}
|
||||
|
||||
// cellMinWidth can override fixed width, so factor it in here
|
||||
nscoord cellMinWidth = cellMinSize.width;
|
||||
if (minColWidth < cellMinWidth)
|
||||
minColWidth = cellMinWidth;
|
||||
// effectiveMinColumnWidth is the min width as if no cells with colspans existed
|
||||
if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth))
|
||||
effectiveMinColumnWidth = cellMinWidth;
|
||||
if (1<colSpan)
|
||||
{
|
||||
// add the column to our list of post-process columns, if all of the intersected columns are auto
|
||||
|
@ -522,6 +530,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
// if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth
|
||||
if (PR_TRUE==hasColsAttribute)
|
||||
{
|
||||
if (gsDebug) printf("has COLS attribute = %d\n", mCols);
|
||||
// for every effected column, subtract out its prior contribution and add back in the new value
|
||||
PRInt32 numColsEffected = mNumCols;
|
||||
if (NS_STYLE_TABLE_COLS_ALL!=mCols)
|
||||
|
@ -554,6 +563,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
|||
mTableFrame->GetColumnFrame(effectedColIndex, colFrame);
|
||||
colFrame->SetMaxColWidth(maxOfMaxColWidths); // cache the new column max width (min width is uneffected)
|
||||
colFrame->SetEffectiveMaxColWidth(maxOfMaxColWidths);
|
||||
if (gsDebug) printf ("col %d now has max col width %d\n", effectedColIndex, maxOfMaxColWidths);
|
||||
}
|
||||
delete [] minColWidthArray;
|
||||
delete [] maxColWidthArray;
|
||||
|
|
|
@ -520,6 +520,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
|
|||
if (nsnull==mCellMap)
|
||||
return; // no info yet, so nothing useful to do
|
||||
|
||||
// make sure we've accounted for the COLS attribute
|
||||
AdjustColumnsForCOLSAttribute();
|
||||
|
||||
PRInt32 actualColumns = 0;
|
||||
nsTableColGroupFrame *lastColGroupFrame = nsnull;
|
||||
nsIFrame * firstRowGroupFrame=nsnull;
|
||||
|
@ -2438,13 +2441,47 @@ void nsTableFrame::VerticallyAlignChildren(nsIPresContext* aPresContext,
|
|||
{
|
||||
}
|
||||
|
||||
void nsTableFrame::AdjustColumnsForCOLSAttribute()
|
||||
{
|
||||
NS_ASSERTION(nsnull!=mCellMap, "bad cell map");
|
||||
|
||||
// any specified-width column turns off COLS attribute
|
||||
nsStyleTable* tableStyle = (nsStyleTable *)mStyleContext->GetMutableStyleData(eStyleStruct_Table);
|
||||
if (tableStyle->mCols != NS_STYLE_TABLE_COLS_NONE)
|
||||
{
|
||||
PRInt32 numCols = GetColCount();
|
||||
PRInt32 numRows = GetRowCount();
|
||||
for (PRInt32 rowIndex=0; rowIndex<numRows; rowIndex++)
|
||||
{
|
||||
for (PRInt32 colIndex=0; colIndex<numCols; colIndex++)
|
||||
{
|
||||
nsTableCellFrame *cellFrame = mCellMap->GetCellFrameAt(rowIndex, colIndex);
|
||||
// get the cell style info
|
||||
const nsStylePosition* cellPosition;
|
||||
if (nsnull!=cellFrame)
|
||||
{
|
||||
cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
|
||||
if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) ||
|
||||
(eStyleUnit_Percent==cellPosition->mWidth.GetUnit()))
|
||||
{
|
||||
tableStyle->mCols = NS_STYLE_TABLE_COLS_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
nsTableRowFrame * aRowFrame)
|
||||
{
|
||||
// if this cell is in the first row, then the width attribute
|
||||
// also acts as the width attribute for the entire column
|
||||
// if this cell is the first non-col-spanning cell to have a width attribute,
|
||||
// then the width attribute also acts as the width attribute for the entire column
|
||||
// if the cell has a colspan, the width is used provisionally, divided equally among
|
||||
// the spanned columns
|
||||
if ((nsnull!=aPresContext) && (nsnull!=aCellFrame) && (nsnull!=aRowFrame))
|
||||
{
|
||||
// get the cell style info
|
||||
|
|
|
@ -123,6 +123,12 @@ public:
|
|||
nsTableCellFrame* aCellFrame,
|
||||
nsTableRowFrame * aRowFrame);
|
||||
|
||||
/** the COLS attribute can be modified by any cell's width attribute.
|
||||
* deal with it here. Must be called before any call to
|
||||
* ColumnInfoCache::AddColumnInfo
|
||||
*/
|
||||
virtual void AdjustColumnsForCOLSAttribute();
|
||||
|
||||
/** return the column frame corresponding to the given column index
|
||||
* there are two ways to do this, depending on whether we have cached
|
||||
* column information yet.
|
||||
|
|
|
@ -574,7 +574,9 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
|||
kidFrame->WillReflow(aPresContext);
|
||||
if (gsDebug1) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width);
|
||||
status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState);
|
||||
if (gsDebug1) printf ("%p InitR: desired=%d\n", this, kidSize.width);
|
||||
if (gsDebug1)
|
||||
printf ("%p InitR: desired=%d, MES=%d\n",
|
||||
this, kidSize.width, kidMaxElementSize.width);
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize);
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
|
||||
NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "unexpected child reflow status");
|
||||
|
|
Загрузка…
Ссылка в новой задаче