mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
incremental cell map, columns. Bugs 12122, 21544. r=troy,hyatt a=hofmann
This commit is contained in:
parent
e6c401cb3e
commit
2eb4655c2e
@ -37,6 +37,7 @@
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIHTMLTableCellElement.h"
|
||||
#include "nsTableColGroupFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleFrameConstruction.h"
|
||||
@ -1175,7 +1176,7 @@ nsCSSFrameConstructor::ConstructAnonymousTableFrame(nsIPresShell* aPresSh
|
||||
nsTableCreator& aTableCreator)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_WARNING("an anonymous table frame was created. \n");
|
||||
//NS_WARNING("an anonymous table frame was created. \n");
|
||||
nsCOMPtr<nsIStyleContext> parentStyleContext;
|
||||
aParentFrame->GetStyleContext(getter_AddRefs(parentStyleContext));
|
||||
const nsStyleDisplay* parentDisplay =
|
||||
@ -1326,7 +1327,7 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresShell* aPres
|
||||
// the caller is responsible for calling SetInitialChildList on the outer, inner frames
|
||||
aNewTopFrame = aNewCaptionFrame;
|
||||
} else { // parent is not a table, need to create a new table
|
||||
NS_WARNING("a non table contains a table caption child. \n");
|
||||
//NS_WARNING("a non table contains a table caption child. \n");
|
||||
nsIFrame* outerFrame;
|
||||
ConstructAnonymousTableFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
||||
aNewTopFrame, outerFrame, innerFrame, aTableCreator);
|
||||
@ -1418,7 +1419,7 @@ nsCSSFrameConstructor::ConstructTableGroupFrame(nsIPresShell* aPresShell,
|
||||
styleContext, aIsRowGroup, aNewTopFrame, aNewGroupFrame,
|
||||
aTableCreator, contentDisplayIsGroup);
|
||||
} else { // construct anonymous frames
|
||||
NS_WARNING("a non table contains a table row or col group child. \n");
|
||||
//NS_WARNING("a non table contains a table row or col group child. \n");
|
||||
nsIFrame* innerFrame;
|
||||
nsIFrame* outerFrame;
|
||||
|
||||
@ -1639,9 +1640,8 @@ nsCSSFrameConstructor::ConstructTableRowFrameOnly(nsIPresShell* aPresShel
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShell,
|
||||
nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShell,
|
||||
nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
@ -1673,6 +1673,7 @@ nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShell,
|
||||
rv = ConstructTableColFrameOnly(aPresShell, aPresContext, aState, aContent, groupFrame,
|
||||
styleContext, aNewColFrame, aTableCreator);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
aState.mFrameManager->SetPrimaryFrameFor(aContent, aNewColFrame);
|
||||
groupFrame->SetInitialChildList(aPresContext, nsnull, aNewColFrame);
|
||||
|
||||
// if an anoymous table got created, then set its initial child list
|
||||
@ -1747,7 +1748,7 @@ nsCSSFrameConstructor::ConstructTableCellFrame(nsIPresShell* aPresShell,
|
||||
aTableCreator, aProcessChildren);
|
||||
aNewTopFrame = aNewCellFrame;
|
||||
} else { // the cell needs some ancestors to be fabricated
|
||||
NS_WARNING("WARNING - a non table row contains a table cell child. \n");
|
||||
//NS_WARNING("WARNING - a non table row contains a table cell child. \n");
|
||||
nsTableList toDo;
|
||||
nsIFrame* rowFrame;
|
||||
rv = ConstructTableRowFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
||||
@ -5484,6 +5485,35 @@ nsCSSFrameConstructor::AppendFrames(nsIPresContext* aPresContext,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
// a col group or col appended to a table may result in an insert rather than an append
|
||||
nsIAtom* parentType;
|
||||
aParentFrame->GetFrameType(&parentType);
|
||||
if (nsLayoutAtoms::tableFrame == parentType) {
|
||||
nsTableFrame* tableFrame = (nsTableFrame *)aParentFrame;
|
||||
nsIAtom* childType;
|
||||
aFrameList->GetFrameType(&childType);
|
||||
if (nsLayoutAtoms::tableColFrame == childType) {
|
||||
nsIFrame* parentFrame = aParentFrame;
|
||||
aFrameList->GetParent(&parentFrame);
|
||||
return aFrameManager->AppendFrames(aPresContext, *aPresShell, parentFrame,
|
||||
nsLayoutAtoms::colGroupList, aFrameList);
|
||||
}
|
||||
else if (nsLayoutAtoms::tableColGroupFrame == childType) {
|
||||
nsIFrame* prevSibling;
|
||||
PRBool doAppend = nsTableColGroupFrame::GetLastRealColGroup(tableFrame, &prevSibling);
|
||||
if (doAppend) {
|
||||
return aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
|
||||
nsLayoutAtoms::colGroupList, aFrameList);
|
||||
}
|
||||
else {
|
||||
return aFrameManager->InsertFrames(aPresContext, *aPresShell, aParentFrame,
|
||||
nsLayoutAtoms::colGroupList, prevSibling, aFrameList);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(childType);
|
||||
}
|
||||
NS_IF_RELEASE(parentType);
|
||||
|
||||
// Append the frames to the end of the parent's child list
|
||||
return aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
|
||||
nsnull, aFrameList);
|
||||
|
@ -675,7 +675,10 @@ nsGfxScrollFrame::GetSkipSides() const
|
||||
NS_IMETHODIMP
|
||||
nsGfxScrollFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
return nsHTMLContainerFrame::GetFrameType(aType);
|
||||
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
|
||||
*aType = nsLayoutAtoms::scrollFrame;
|
||||
NS_ADDREF(*aType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
@ -675,7 +675,10 @@ nsGfxScrollFrame::GetSkipSides() const
|
||||
NS_IMETHODIMP
|
||||
nsGfxScrollFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
return nsHTMLContainerFrame::GetFrameType(aType);
|
||||
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
|
||||
*aType = nsLayoutAtoms::scrollFrame;
|
||||
NS_ADDREF(*aType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIHTMLTableCellElement.h"
|
||||
#include "nsTableColGroupFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleFrameConstruction.h"
|
||||
@ -1175,7 +1176,7 @@ nsCSSFrameConstructor::ConstructAnonymousTableFrame(nsIPresShell* aPresSh
|
||||
nsTableCreator& aTableCreator)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_WARNING("an anonymous table frame was created. \n");
|
||||
//NS_WARNING("an anonymous table frame was created. \n");
|
||||
nsCOMPtr<nsIStyleContext> parentStyleContext;
|
||||
aParentFrame->GetStyleContext(getter_AddRefs(parentStyleContext));
|
||||
const nsStyleDisplay* parentDisplay =
|
||||
@ -1326,7 +1327,7 @@ nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresShell* aPres
|
||||
// the caller is responsible for calling SetInitialChildList on the outer, inner frames
|
||||
aNewTopFrame = aNewCaptionFrame;
|
||||
} else { // parent is not a table, need to create a new table
|
||||
NS_WARNING("a non table contains a table caption child. \n");
|
||||
//NS_WARNING("a non table contains a table caption child. \n");
|
||||
nsIFrame* outerFrame;
|
||||
ConstructAnonymousTableFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
||||
aNewTopFrame, outerFrame, innerFrame, aTableCreator);
|
||||
@ -1418,7 +1419,7 @@ nsCSSFrameConstructor::ConstructTableGroupFrame(nsIPresShell* aPresShell,
|
||||
styleContext, aIsRowGroup, aNewTopFrame, aNewGroupFrame,
|
||||
aTableCreator, contentDisplayIsGroup);
|
||||
} else { // construct anonymous frames
|
||||
NS_WARNING("a non table contains a table row or col group child. \n");
|
||||
//NS_WARNING("a non table contains a table row or col group child. \n");
|
||||
nsIFrame* innerFrame;
|
||||
nsIFrame* outerFrame;
|
||||
|
||||
@ -1639,9 +1640,8 @@ nsCSSFrameConstructor::ConstructTableRowFrameOnly(nsIPresShell* aPresShel
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShell,
|
||||
nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShell,
|
||||
nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
@ -1673,6 +1673,7 @@ nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShell,
|
||||
rv = ConstructTableColFrameOnly(aPresShell, aPresContext, aState, aContent, groupFrame,
|
||||
styleContext, aNewColFrame, aTableCreator);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
aState.mFrameManager->SetPrimaryFrameFor(aContent, aNewColFrame);
|
||||
groupFrame->SetInitialChildList(aPresContext, nsnull, aNewColFrame);
|
||||
|
||||
// if an anoymous table got created, then set its initial child list
|
||||
@ -1747,7 +1748,7 @@ nsCSSFrameConstructor::ConstructTableCellFrame(nsIPresShell* aPresShell,
|
||||
aTableCreator, aProcessChildren);
|
||||
aNewTopFrame = aNewCellFrame;
|
||||
} else { // the cell needs some ancestors to be fabricated
|
||||
NS_WARNING("WARNING - a non table row contains a table cell child. \n");
|
||||
//NS_WARNING("WARNING - a non table row contains a table cell child. \n");
|
||||
nsTableList toDo;
|
||||
nsIFrame* rowFrame;
|
||||
rv = ConstructTableRowFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
||||
@ -5484,6 +5485,35 @@ nsCSSFrameConstructor::AppendFrames(nsIPresContext* aPresContext,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
// a col group or col appended to a table may result in an insert rather than an append
|
||||
nsIAtom* parentType;
|
||||
aParentFrame->GetFrameType(&parentType);
|
||||
if (nsLayoutAtoms::tableFrame == parentType) {
|
||||
nsTableFrame* tableFrame = (nsTableFrame *)aParentFrame;
|
||||
nsIAtom* childType;
|
||||
aFrameList->GetFrameType(&childType);
|
||||
if (nsLayoutAtoms::tableColFrame == childType) {
|
||||
nsIFrame* parentFrame = aParentFrame;
|
||||
aFrameList->GetParent(&parentFrame);
|
||||
return aFrameManager->AppendFrames(aPresContext, *aPresShell, parentFrame,
|
||||
nsLayoutAtoms::colGroupList, aFrameList);
|
||||
}
|
||||
else if (nsLayoutAtoms::tableColGroupFrame == childType) {
|
||||
nsIFrame* prevSibling;
|
||||
PRBool doAppend = nsTableColGroupFrame::GetLastRealColGroup(tableFrame, &prevSibling);
|
||||
if (doAppend) {
|
||||
return aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
|
||||
nsLayoutAtoms::colGroupList, aFrameList);
|
||||
}
|
||||
else {
|
||||
return aFrameManager->InsertFrames(aPresContext, *aPresShell, aParentFrame,
|
||||
nsLayoutAtoms::colGroupList, prevSibling, aFrameList);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(childType);
|
||||
}
|
||||
NS_IF_RELEASE(parentType);
|
||||
|
||||
// Append the frames to the end of the parent's child list
|
||||
return aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
|
||||
nsnull, aFrameList);
|
||||
|
@ -59,17 +59,6 @@ PRBool CanAllocate(PRInt32 aTypeToAllocate,
|
||||
|
||||
/* ---------- BasicTableLayoutStrategy ---------- */
|
||||
|
||||
/* return true if the style indicates that the width is fixed
|
||||
* for the purposes of column width determination
|
||||
*/
|
||||
inline
|
||||
PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosition,
|
||||
const nsStyleTable* aStyleTable)
|
||||
{
|
||||
return PRBool ((eStyleUnit_Coord==aStylePosition->mWidth.GetUnit()) ||
|
||||
(eStyleUnit_Coord==aStyleTable->mSpanWidth.GetUnit()));
|
||||
}
|
||||
|
||||
MOZ_DECL_CTOR_COUNTER(BasicTableLayoutStrategy);
|
||||
|
||||
|
||||
@ -90,8 +79,7 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
|
||||
MOZ_COUNT_DTOR(BasicTableLayoutStrategy);
|
||||
}
|
||||
|
||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||
PRInt32 aNumCols,
|
||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||
nscoord aMaxWidth)
|
||||
{
|
||||
ContinuingFrameCheck();
|
||||
@ -99,12 +87,10 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
// re-init instance variables
|
||||
mNumCols = aNumCols;
|
||||
mMinTableContentWidth = 0;
|
||||
mMaxTableContentWidth = 0;
|
||||
mCellSpacingTotal = 0;
|
||||
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
||||
|
||||
// assign the width of all fixed-width columns
|
||||
AssignPreliminaryColumnWidths(aMaxWidth);
|
||||
|
||||
@ -157,7 +143,7 @@ PRBool BCW_Wrapup(BasicTableLayoutStrategy* aStrategy,
|
||||
{
|
||||
if (aAllocTypes)
|
||||
delete [] aAllocTypes;
|
||||
if (gsDebugBalance) {printf("BalanceColumnWidths ex \n"); aTableFrame->Dump(PR_TRUE, PR_FALSE);}
|
||||
if (gsDebugBalance) {printf("BalanceColumnWidths ex \n"); aTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@ -176,7 +162,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aMaxWidthIn)
|
||||
{
|
||||
if (gsDebugBalance) {printf("BalanceColumnWidths en max=%d\n", aMaxWidthIn); mTableFrame->Dump(PR_TRUE, PR_FALSE);}
|
||||
if (gsDebugBalance) {printf("BalanceColumnWidths en max=%d\n", aMaxWidthIn); mTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);}
|
||||
|
||||
ContinuingFrameCheck();
|
||||
if (!aTableStyle) {
|
||||
@ -184,6 +170,8 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
|
||||
// determine if the table is auto/fixed and get the fixed width if available
|
||||
nscoord maxWidth = aMaxWidthIn;
|
||||
nscoord specifiedTableWidth = 0;
|
||||
@ -204,7 +192,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
}
|
||||
// initialize the col percent and cell percent values to 0.
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
colFrame->SetWidth(PCT, WIDTH_NOT_SET);
|
||||
colFrame->SetWidth(PCT_ADJ, WIDTH_NOT_SET);
|
||||
@ -220,7 +208,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
|
||||
PRBool recomputedAdjMin = RecomputeAdjMinIfNecessary();
|
||||
// set the table's columns to the min width
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord colMinWidth = colFrame->GetMinWidth();
|
||||
mTableFrame->SetColumnWidth(colX, colMinWidth);
|
||||
@ -257,10 +245,10 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
nscoord totalAllocated = totalWidths[MIN_CON] + cellSpacingTotal;
|
||||
|
||||
// allocate and initialize arrays indicating what col gets set
|
||||
PRInt32* allocTypes = new PRInt32[mNumCols];
|
||||
PRInt32* allocTypes = new PRInt32[numCols];
|
||||
if (!allocTypes) return PR_FALSE;
|
||||
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
allocTypes[colX] = -1;
|
||||
}
|
||||
|
||||
@ -330,9 +318,9 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
PRBool skip0Proportional = totalCounts[DES_CON] > num0Proportional;
|
||||
if ( (tableIsAutoWidth && (perAdjTableWidth - totalAllocated > 0)) ||
|
||||
(!tableIsAutoWidth && (totalAllocated < maxWidth)) ) {
|
||||
if (totalCounts[PCT] != mNumCols) {
|
||||
if (totalCounts[PCT] != numCols) {
|
||||
//PRBool onlyAuto = (totalCounts[DES_CON] > 0) && !mIsNavQuirksMode;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (PCT == allocTypes[colX]) {
|
||||
allocTypes[colX] = -1;
|
||||
}
|
||||
@ -350,7 +338,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
}
|
||||
// give the proportional cols the rest up to the max width in quirks mode
|
||||
else if (tableIsAutoWidth && mIsNavQuirksMode && (totalCounts[MIN_PRO] > 0)) {
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (DES_CON != allocTypes[colX]) {
|
||||
allocTypes[colX] = -1;
|
||||
}
|
||||
@ -369,7 +357,8 @@ void BasicTableLayoutStrategy::AllocateFully(nscoord& aTotalAllocated,
|
||||
PRInt32 aWidthType,
|
||||
PRBool aMarkAllocated)
|
||||
{
|
||||
for (PRInt32 colX = 0; colX < mNumCols; colX++) {
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord oldWidth = mTableFrame->GetColumnWidth(colX);
|
||||
nscoord newWidth = colFrame->GetWidth(aWidthType);
|
||||
@ -408,13 +397,14 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
|
||||
PRInt32 numColsAllocated = 0;
|
||||
PRInt32 totalAllocated = 0;
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (-1 != aAllocTypes[colX]) {
|
||||
divisor += mTableFrame->GetColumnWidth(colX);
|
||||
numColsAllocated++;
|
||||
}
|
||||
}
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (-1 != aAllocTypes[colX]) {
|
||||
if (aSkip0Proportional) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
@ -703,9 +693,10 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
|
||||
// and calculate min/max table width
|
||||
PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth)
|
||||
{
|
||||
if (gsDebugAssign) {printf("AssignPrelimColWidths en max=%d\n", aMaxWidth); mTableFrame->Dump(PR_TRUE, PR_FALSE);}
|
||||
if (gsDebugAssign) {printf("AssignPrelimColWidths en max=%d\n", aMaxWidth); mTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);}
|
||||
PRBool rv = PR_FALSE;
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
PRInt32 colX, rowX;
|
||||
mCellSpacingTotal = 0;
|
||||
@ -713,12 +704,12 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
PRInt32 propTotal = 0; // total of numbers of the type 1*, 2*, etc
|
||||
PRInt32 numColsForColsAttr = 0; // Nav Quirks cols attribute for equal width cols
|
||||
if (NS_STYLE_TABLE_COLS_NONE != mCols) {
|
||||
numColsForColsAttr = (NS_STYLE_TABLE_COLS_ALL == mCols) ? mNumCols : mCols;
|
||||
numColsForColsAttr = (NS_STYLE_TABLE_COLS_ALL == mCols) ? numCols : mCols;
|
||||
}
|
||||
|
||||
// For every column, determine it's min and desired width based on cell style
|
||||
// base on cells which do not span cols. Also, determine mCellSpacingTotal
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nscoord minWidth = 0;
|
||||
nscoord desWidth = 0;
|
||||
nscoord fixWidth = WIDTH_NOT_SET;
|
||||
@ -794,6 +785,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
// proportional width on a col or Nav Quirks cols attr
|
||||
if (fixWidth <= 0) {
|
||||
nscoord proportion = WIDTH_NOT_SET;
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)colPosition);
|
||||
if (eStyleUnit_Proportional == colPosition->mWidth.GetUnit()) {
|
||||
@ -806,6 +798,19 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
proportion = WIDTH_NOT_SET;
|
||||
}
|
||||
}
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
if (eStyleUnit_Proportional == colStyleWidth.GetUnit()) {
|
||||
proportion = colStyleWidth.GetIntValue();
|
||||
}
|
||||
else if (colX < numColsForColsAttr) {
|
||||
proportion = 1;
|
||||
if ((eStyleUnit_Percent == colStyleWidth.GetUnit()) &&
|
||||
(colStyleWidth.GetPercentValue() > 0.0f)) {
|
||||
proportion = WIDTH_NOT_SET;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (proportion >= 0) {
|
||||
colFrame->SetWidth(MIN_PRO, proportion);
|
||||
if (proportion > 0) {
|
||||
@ -831,7 +836,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
nscoord minPropTotal = 0;
|
||||
nscoord desPropTotal = 0;
|
||||
// figure the totals of all proportional cols which support every min and desired width
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord colProp = colFrame->GetWidth(MIN_PRO);
|
||||
if (colProp > 0) {
|
||||
@ -846,7 +851,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
mMinToDesProportionRatio = ((float)desPropTotal) / ((float)minPropTotal);
|
||||
}
|
||||
// figure the cols proportional min width based on the new totals
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord colProp = colFrame->GetWidth(MIN_PRO);
|
||||
if (colProp > 0) {
|
||||
@ -861,7 +866,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
// Adjust the cols that each cell spans if necessary. Iterate backwards
|
||||
// so that nested and/or overlaping col spans handle the inner ones first,
|
||||
// ensuring more accurated calculations.
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
for (rowX = 0; rowX < numRows; rowX++) {
|
||||
PRBool originates;
|
||||
PRInt32 colSpan;
|
||||
@ -878,11 +883,12 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
|
||||
// Set the col's fixed width if present
|
||||
// Set the table col width for each col to the content min.
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord fixColWidth = colFrame->GetWidth(FIX);
|
||||
// use the style width of a col only if the col hasn't gotten a fixed width from any cell
|
||||
if (fixColWidth <= 0) {
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)colPosition);
|
||||
if (eStyleUnit_Coord == colPosition->mWidth.GetUnit()) {
|
||||
@ -891,13 +897,22 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
colFrame->SetWidth(FIX, fixColWidth);
|
||||
}
|
||||
}
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
if (eStyleUnit_Coord == colStyleWidth.GetUnit()) {
|
||||
fixColWidth = colStyleWidth.GetCoordValue();
|
||||
if (fixColWidth > 0) {
|
||||
colFrame->SetWidth(FIX, fixColWidth);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
nscoord minWidth = colFrame->GetMinWidth();
|
||||
mTableFrame->SetColumnWidth(colX, minWidth);
|
||||
}
|
||||
SetMinAndMaxTableContentWidths();
|
||||
|
||||
if (gsDebugAssign) {printf("AssignPrelimColWidths ex\n"); mTableFrame->Dump(PR_TRUE, PR_FALSE);}
|
||||
if (gsDebugAssign) {printf("AssignPrelimColWidths ex\n"); mTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -906,6 +921,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
PRBool aTableIsAutoWidth)
|
||||
{
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
PRInt32 colX, rowX;
|
||||
nscoord basis = aBasisIn;
|
||||
@ -918,7 +934,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
PRInt32 numPerCols = 0; // number of colums that have percentage constraints
|
||||
nscoord prefWidthTotal = 0;// total of des/fix widths of cols that don't have percentage constraints
|
||||
basis = 0; // basis to use for percentages, computed considering percentage values
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord colBasis = -1;
|
||||
// Scan the cells in the col
|
||||
@ -950,6 +966,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
}
|
||||
if (-1 == colBasis) {
|
||||
// see if the col has a style percent width specified
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)colPosition);
|
||||
if (eStyleUnit_Percent == colPosition->mWidth.GetUnit()) {
|
||||
@ -960,6 +977,17 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
colBasis = NSToCoordRound((float)desWidth / percent);
|
||||
}
|
||||
}
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
if (eStyleUnit_Percent == colStyleWidth.GetUnit()) {
|
||||
float percent = colStyleWidth.GetPercentValue();
|
||||
colBasis = 0;
|
||||
if (percent > 0.0f) {
|
||||
nscoord desWidth = colFrame->GetDesWidth();
|
||||
colBasis = NSToCoordRound((float)desWidth / percent);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
basis = PR_MAX(basis, colBasis);
|
||||
nscoord fixWidth = colFrame->GetFixWidth();
|
||||
@ -976,7 +1004,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
return 0;
|
||||
}
|
||||
// If there is only one col and it is % based, it won't affect anything
|
||||
if ((1 == mNumCols) && (mNumCols == numPerCols)) {
|
||||
if ((1 == numCols) && (numCols == numPerCols)) {
|
||||
return 0;
|
||||
}
|
||||
// compute a basis considering total percentages and the desired width of everything else
|
||||
@ -995,12 +1023,12 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
}
|
||||
|
||||
nscoord colPctTotal = 0;
|
||||
nscoord* colPcts = new nscoord[mNumCols];
|
||||
nscoord* colPcts = new nscoord[numCols];
|
||||
if (!colPcts) return 0;
|
||||
|
||||
// Determine the percentage contribution for cols and for cells with colspan = 1
|
||||
// Iterate backwards, similarly to the reasoning in AssignPreliminaryColumnWidths
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord maxColPctWidth = WIDTH_NOT_SET;
|
||||
float maxColPct = 0.0f;
|
||||
@ -1039,12 +1067,20 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
}
|
||||
if (WIDTH_NOT_SET == maxColPctWidth) {
|
||||
// see if the col has a style percent width specified
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)colPosition);
|
||||
if (eStyleUnit_Percent == colPosition->mWidth.GetUnit()) {
|
||||
maxColPct = colPosition->mWidth.GetPercentValue();
|
||||
maxColPctWidth = NSToCoordRound( ((float)basis) * maxColPct );
|
||||
}
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
if (eStyleUnit_Percent == colStyleWidth.GetUnit()) {
|
||||
maxColPct = colStyleWidth.GetPercentValue();
|
||||
maxColPctWidth = NSToCoordRound( ((float)basis) * maxColPct );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// conflicting pct/fixed widths are recorded. Nav 4.x may be changing the
|
||||
// fixed width value if it exceeds the pct value and not recording the pct
|
||||
@ -1066,7 +1102,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
|
||||
// For each col, consider the cells originating in it with colspans > 1.
|
||||
// Adjust the cols that each cell spans if necessary.
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
for (rowX = 0; rowX < numRows; rowX++) {
|
||||
PRBool originates;
|
||||
PRInt32 colSpan;
|
||||
@ -1162,7 +1198,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
|
||||
// if the percent total went over 100%, adjustments need to be made to right most cols
|
||||
if (colPctTotal > 100) {
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
if (colPcts[colX] > 0) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord newPct = colPcts[colX] - (colPctTotal - 100);
|
||||
@ -1197,10 +1233,11 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
PRBool BasicTableLayoutStrategy::RecomputeAdjMinIfNecessary()
|
||||
{
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
PRInt32 colX, rowX, spanX;
|
||||
|
||||
PRBool spansPercent = PR_FALSE;
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
for (rowX = 0; rowX < numRows; rowX++) {
|
||||
PRBool originates;
|
||||
PRInt32 colSpan;
|
||||
@ -1233,7 +1270,7 @@ PRBool BasicTableLayoutStrategy::RecomputeAdjMinIfNecessary()
|
||||
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
for (rowX = 0; rowX < numRows; rowX++) {
|
||||
PRBool originates;
|
||||
PRInt32 colSpan;
|
||||
@ -1267,7 +1304,8 @@ void BasicTableLayoutStrategy::SetMinAndMaxTableContentWidths()
|
||||
mMaxTableContentWidth = 0;
|
||||
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
for (PRInt32 colX = 0; colX < mNumCols; colX++) {
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
mMinTableContentWidth += colFrame->GetMinWidth();
|
||||
mMaxTableContentWidth += PR_MAX(colFrame->GetDesWidth(), colFrame->GetFixWidth());
|
||||
@ -1302,7 +1340,8 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing,
|
||||
a0ProportionalCount = 0;
|
||||
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
for (PRInt32 colX = 0; colX < mNumCols; colX++) {
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) {
|
||||
aCellSpacing += spacingX;
|
||||
@ -1387,7 +1426,7 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing,
|
||||
aMinWidths[DES_CON] += minCol;
|
||||
}
|
||||
// if it is not a degenerate table, add the last spacing on the right
|
||||
if (mNumCols > 0) {
|
||||
if (numCols > 0) {
|
||||
aCellSpacing += spacingX;
|
||||
}
|
||||
}
|
||||
@ -1508,11 +1547,12 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth,
|
||||
return;
|
||||
}
|
||||
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
PRInt32 numConstrainedCols = 0;
|
||||
nscoord sumMaxConstraints = 0;
|
||||
PRBool useAdj = PR_TRUE;
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) {
|
||||
if (-1 != aAllocTypes[colX]) {
|
||||
@ -1539,7 +1579,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth,
|
||||
PRInt32 maxMinDiff = 0;
|
||||
PRInt32 constrColX = 0;
|
||||
// set the col info entries for each constrained col
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) {
|
||||
if (-1 != aAllocTypes[colX]) {
|
||||
@ -1810,11 +1850,16 @@ PRBool BasicTableLayoutStrategy::ColIsSpecifiedAsMinimumWidth(PRInt32 aColIndex)
|
||||
PRBool result = PR_FALSE;
|
||||
nsTableColFrame* colFrame;
|
||||
mTableFrame->GetColumnFrame(aColIndex, colFrame);
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)colPosition);
|
||||
switch (colPosition->mWidth.GetUnit()) {
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
switch (colStyleWidth.GetUnit()) {
|
||||
#endif
|
||||
case eStyleUnit_Coord:
|
||||
if (0 == colPosition->mWidth.GetCoordValue()) {
|
||||
if (0 == colStyleWidth.GetCoordValue()) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
@ -1823,14 +1868,14 @@ PRBool BasicTableLayoutStrategy::ColIsSpecifiedAsMinimumWidth(PRInt32 aColIndex)
|
||||
// total hack for now for 0% and 1% specifications
|
||||
// should compare percent to available parent width and see that it is below minimum
|
||||
// for this column
|
||||
float percent = colPosition->mWidth.GetPercentValue();
|
||||
float percent = colStyleWidth.GetPercentValue();
|
||||
if (0.0f == percent || 0.01f == percent) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eStyleUnit_Proportional:
|
||||
if (0 == colPosition->mWidth.GetIntValue()) {
|
||||
if (0 == colStyleWidth.GetIntValue()) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
|
||||
@ -1849,8 +1894,8 @@ void BasicTableLayoutStrategy::Dump(PRInt32 aIndent)
|
||||
}
|
||||
indent[aIndent] = 0;
|
||||
|
||||
printf("%s**START BASIC STRATEGY DUMP** table=%p cols=%X numCols=%d",
|
||||
indent, mTableFrame, mCols, mNumCols);
|
||||
printf("%s**START BASIC STRATEGY DUMP** table=%p cols=%X",
|
||||
indent, mTableFrame, mCols);
|
||||
printf("\n%s minConWidth=%d maxConWidth=%d cellSpacing=%d propRatio=%.2f navQuirks=%d",
|
||||
indent, mMinTableContentWidth, mMaxTableContentWidth, mCellSpacingTotal, mMinToDesProportionRatio, mIsNavQuirksMode);
|
||||
printf(" **END BASIC STRATEGY DUMP** \n");
|
||||
|
@ -57,11 +57,9 @@ public:
|
||||
/** call every time any table thing changes that might effect the width of any column
|
||||
* in the table (content, structure, or style)
|
||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize,
|
||||
PRInt32 aNumCols,
|
||||
nscoord aMaxSize);
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize,
|
||||
nscoord aMaxSize);
|
||||
|
||||
/** compute the max element size of the table.
|
||||
* assumes that Initialize has been called
|
||||
@ -83,7 +81,6 @@ public:
|
||||
nscoord GetTableMinContentWidth() const;
|
||||
nscoord GetTableMaxContentWidth() const;
|
||||
nscoord GetCOLSAttribute() const;
|
||||
nscoord GetNumCols() const;
|
||||
void Dump(PRInt32 aIndent);
|
||||
|
||||
protected:
|
||||
@ -159,13 +156,6 @@ protected:
|
||||
PRInt32* aAllocTypes,
|
||||
PRBool aSkip0Proportional);
|
||||
|
||||
/** return true if the style indicates that the width is a specific width
|
||||
* for the purposes of column width determination.
|
||||
* return false if the width changes based on content, parent size, etc.
|
||||
*/
|
||||
static PRBool IsFixedWidth(const nsStylePosition* aStylePosition,
|
||||
const nsStyleTable* aStyleTable);
|
||||
|
||||
/** return true if the colIndex is in the list of colIndexes */
|
||||
virtual PRBool IsColumnInList(const PRInt32 colIndex,
|
||||
PRInt32 *colIndexes,
|
||||
@ -214,7 +204,6 @@ protected:
|
||||
protected:
|
||||
nsTableFrame * mTableFrame;
|
||||
PRInt32 mCols;
|
||||
PRInt32 mNumCols;
|
||||
// cached data
|
||||
nscoord mMinTableContentWidth; // the smallest size for the table (excluding border and padding)
|
||||
nscoord mMaxTableContentWidth; // the "natural" size for the table, if unconstrained (excluding border and padding)
|
||||
@ -233,9 +222,6 @@ inline nscoord BasicTableLayoutStrategy::GetTableMaxContentWidth() const
|
||||
inline nscoord BasicTableLayoutStrategy::GetCOLSAttribute() const
|
||||
{ return mCols; };
|
||||
|
||||
inline nscoord BasicTableLayoutStrategy::GetNumCols() const
|
||||
{ return mNumCols; };
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -59,7 +59,6 @@ PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aT
|
||||
PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputedWidth)
|
||||
{
|
||||
// NS_ASSERTION(aComputedWidth != NS_UNCONSTRAINEDSIZE, "bad computed width");
|
||||
|
||||
const nsStylePosition* tablePosition;
|
||||
mTableFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)tablePosition);
|
||||
PRBool tableIsFixedWidth = eStyleUnit_Coord == tablePosition->mWidth.GetUnit() ||
|
||||
@ -70,24 +69,25 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
nsMargin borderPadding;
|
||||
tableSpacing->CalcBorderPaddingFor(mTableFrame, borderPadding);
|
||||
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
PRInt32 colX;
|
||||
// availWidth is used as the basis for percentage width columns. It is aComputedWidth
|
||||
// minus table border, padding, & cellspacing
|
||||
nscoord availWidth = aComputedWidth - borderPadding.left - borderPadding.right -
|
||||
((mNumCols + 1) * mTableFrame->GetCellSpacingX());
|
||||
((numCols + 1) * mTableFrame->GetCellSpacingX());
|
||||
|
||||
PRInt32 specifiedCols = 0; // the number of columns whose width is given
|
||||
nscoord totalColWidth = 0; // the sum of the widths of the columns
|
||||
|
||||
nscoord* colWidths = new PRBool[mNumCols];
|
||||
nsCRT::memset(colWidths, WIDTH_NOT_SET, mNumCols*sizeof(nscoord));
|
||||
nscoord* colWidths = new PRBool[numCols];
|
||||
nsCRT::memset(colWidths, WIDTH_NOT_SET, numCols*sizeof(nscoord));
|
||||
|
||||
nscoord* propInfo = new PRBool[mNumCols];
|
||||
nsCRT::memset(propInfo, 0, mNumCols*sizeof(nscoord));
|
||||
nscoord* propInfo = new PRBool[numCols];
|
||||
nsCRT::memset(propInfo, 0, numCols*sizeof(nscoord));
|
||||
nscoord propTotal = 0;
|
||||
|
||||
// for every column, determine its specified width
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
// Get column information
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
if (!colFrame) {
|
||||
@ -115,6 +115,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
propTotal += propInfo[colX];
|
||||
}
|
||||
else { // get width from the cell
|
||||
|
||||
nsTableCellFrame* cellFrame = mTableFrame->GetCellFrameAt(0, colX);
|
||||
if (nsnull != cellFrame) {
|
||||
// Get the cell's style
|
||||
@ -148,7 +149,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
|
||||
if (0 < remainingWidth) {
|
||||
if (propTotal > 0) {
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (propInfo[colX] > 0) {
|
||||
// We're proportional
|
||||
float percent = ((float)propInfo[colX])/((float)propTotal);
|
||||
@ -159,10 +160,10 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
}
|
||||
}
|
||||
else if (tableIsFixedWidth) {
|
||||
if (mNumCols > specifiedCols) {
|
||||
if (numCols > specifiedCols) {
|
||||
// allocate the extra space to the columns which have no width specified
|
||||
nscoord colAlloc = NSToCoordRound( ((float)remainingWidth) / (((float)mNumCols) - ((float)specifiedCols)));
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
nscoord colAlloc = NSToCoordRound( ((float)remainingWidth) / (((float)numCols) - ((float)specifiedCols)));
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (-1 == colWidths[colX]) {
|
||||
colWidths[colX] = colAlloc;
|
||||
totalColWidth += colAlloc;
|
||||
@ -172,7 +173,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
}
|
||||
else { // allocate the extra space to the columns which have width specified
|
||||
float divisor = (float)totalColWidth;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (colWidths[colX] > 0) {
|
||||
nscoord colAlloc = NSToCoordRound(remainingWidth * colWidths[colX] / divisor);
|
||||
colWidths[colX] += colAlloc;
|
||||
@ -187,7 +188,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
nscoord overAllocation = (availWidth >= 0)
|
||||
? totalColWidth - availWidth : 0;
|
||||
// set the column widths
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (colWidths[colX] < 0)
|
||||
colWidths[colX] = 0;
|
||||
// if there was too much allocated due to rounding, remove it from the last col
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,6 +27,22 @@
|
||||
#include "nsVoidArray.h"
|
||||
class nsTableColFrame;
|
||||
class nsTableCellFrame;
|
||||
class nsIPresContext;
|
||||
|
||||
// XXX the collapsing row and col data structures need to be moved
|
||||
// into nsTableFrame. Collapsing cols are broken due to the recent
|
||||
// incremental cell map methods which don't attempt to update
|
||||
// collapsing col info here.
|
||||
|
||||
struct nsColInfo
|
||||
{
|
||||
PRInt32 mNumCellsOrig; // number of cells originating in the col
|
||||
PRInt32 mNumCellsSpan; // number of cells spanning into the col via colspans (not rowspans)
|
||||
|
||||
nsColInfo();
|
||||
nsColInfo(PRInt32 aNumCellsOrig,
|
||||
PRInt32 aNumCellsSpan);
|
||||
};
|
||||
|
||||
/** nsCellMap is a support class for nsTablePart.
|
||||
* It maintains an Rows x Columns grid onto which the cells of the table are mapped.
|
||||
@ -60,23 +76,29 @@ public:
|
||||
CellData* GetCellAt(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex) const;
|
||||
|
||||
/** insert a new row into the map
|
||||
makes a blank row and adjusts spans
|
||||
*/
|
||||
void InsertRowIntoMap(PRInt32 aRowIndex);
|
||||
|
||||
/** removes a row from the map and adjusts spans
|
||||
*/
|
||||
void RemoveRowFromMap(PRInt32 aRowIndex);
|
||||
void AppendCol();
|
||||
|
||||
/** append the cellFrame at the end of the row at aRowIndex and return the col index
|
||||
*/
|
||||
PRInt32 AppendCell(nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary);
|
||||
|
||||
void InsertCells(nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore);
|
||||
|
||||
void RemoveCell(nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
void InsertRows(nsVoidArray& aRows,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
void RemoveRows(PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
PRInt32 GetNextAvailRowIndex();
|
||||
|
||||
PRInt32 GetEffectiveColSpan(nsTableCellFrame* aCell) const;
|
||||
@ -102,17 +124,6 @@ public:
|
||||
/** return the actual number of rows in the table represented by this CellMap */
|
||||
PRInt32 GetRowCount() const;
|
||||
|
||||
/** return the column frame associated with aColIndex */
|
||||
nsTableColFrame* GetColumnFrame(PRInt32 aColIndex) const;
|
||||
|
||||
/** add a column frame to the list of column frames
|
||||
* column frames must be added in order
|
||||
*/
|
||||
void AppendColumnFrame(nsTableColFrame *aColFrame);
|
||||
|
||||
/** empty the column frame cache */
|
||||
void ClearColumnCache();
|
||||
|
||||
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
|
||||
nsTableCellFrame* GetCellFrameOriginatingAt(PRInt32 aRowX,
|
||||
PRInt32 aColX) const;
|
||||
@ -123,6 +134,7 @@ public:
|
||||
PRInt32* aColSpan = nsnull) const;
|
||||
|
||||
void AddColsAtEnd(PRUint32 aNumCols);
|
||||
PRInt32 RemoveUnusedCols(PRInt32 aMaxNumToRemove);
|
||||
|
||||
PRBool RowIsSpannedInto(PRInt32 aRowIndex) const;
|
||||
PRBool RowHasSpanningCells(PRInt32 aRowIndex) const;
|
||||
@ -156,23 +168,48 @@ protected:
|
||||
CellData* GetMapCellAt(PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex) const;
|
||||
|
||||
PRInt32 GetNumCellsIn(PRInt32 aColIndex,
|
||||
PRBool aOriginating) const;
|
||||
PRInt32 GetNumCellsIn(PRInt32 aColIndex) const;
|
||||
|
||||
void ExpandWithRows(nsVoidArray& aRowFrames,
|
||||
PRInt32 aStartRowIndex);
|
||||
|
||||
void ExpandWithCells(nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRInt32 aRowSpan);
|
||||
|
||||
void ShrinkWithoutRows(PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove);
|
||||
|
||||
void ShrinkWithoutCell(nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
void RebuildConsideringRows(PRInt32 aStartRowIndex,
|
||||
nsVoidArray* aRowsToInsert,
|
||||
PRInt32 aNumRowsToRemove = 0);
|
||||
|
||||
void RebuildConsideringCells(nsVoidArray* aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aInsert);
|
||||
|
||||
PRBool CellsSpanOut(nsVoidArray& aNewRows);
|
||||
|
||||
PRBool CellsSpanInOrOut(PRInt32 aStartRowIndex,
|
||||
PRInt32 aEndRowIndex,
|
||||
PRInt32 aStartColIndex,
|
||||
PRInt32 aEndColIndex);
|
||||
|
||||
PRBool CreateEmptyRow(PRInt32 aRowIndex,
|
||||
PRInt32 aNumCols);
|
||||
/** an array containing col array. It can be larger than mRowCount due to
|
||||
* row spans extending beyond the table */
|
||||
nsVoidArray mRows;
|
||||
|
||||
/** an array of col frames. It is as large as mRowCount */
|
||||
nsVoidArray mColFrames;
|
||||
|
||||
/** an array of PRInt32 indexed by row and giving the number of cells originating
|
||||
* in each row. */
|
||||
nsVoidArray mNumCellsOrigInRow;
|
||||
|
||||
/** an array of PRInt32 indexed by col and giving the number of cells originating
|
||||
* in each col. */
|
||||
nsVoidArray mNumCellsOrigInCol;
|
||||
/** an array of nsColInfo indexed by col and giving the number of
|
||||
* cells originating and spanning each col. */
|
||||
nsVoidArray mCols;
|
||||
|
||||
// an array of booleans where the ith element indicates if the ith row is collapsed
|
||||
PRPackedBool* mIsCollapsedRows;
|
||||
@ -196,7 +233,7 @@ inline CellData* nsCellMap::GetCellAt(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex) const
|
||||
{
|
||||
if ((0 > aRowIndex) || (aRowIndex >= mRowCount) ||
|
||||
(0 > aColIndex) || (aColIndex >= mNumCellsOrigInCol.Count())) {
|
||||
(0 > aColIndex) || (aColIndex >= mCols.Count())) {
|
||||
//bug 9024 tickled this
|
||||
//printf("%s \n", "nsCellMap::GetCellAt called with invalid row or col index"); // XXX look at this when bug 10911 get fixed
|
||||
return nsnull;
|
||||
@ -213,7 +250,7 @@ inline CellData* nsCellMap::GetMapCellAt(PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex) const
|
||||
{
|
||||
if ((0 > aMapRowIndex) || (aMapRowIndex >= mRows.Count()) ||
|
||||
(0 > aColIndex) || (aColIndex >= mNumCellsOrigInCol.Count())) {
|
||||
(0 > aColIndex) || (aColIndex >= mCols.Count())) {
|
||||
//see bug 9024 comments above
|
||||
//printf("%s \n", "nsCellMap::GetMapCellAt called with invalid row or col index"); // XXX look at this when bug 10911 get fixed
|
||||
return nsnull;
|
||||
@ -228,7 +265,7 @@ inline CellData* nsCellMap::GetMapCellAt(PRInt32 aMapRowIndex,
|
||||
|
||||
inline PRInt32 nsCellMap::GetColCount() const
|
||||
{
|
||||
return mNumCellsOrigInCol.Count();
|
||||
return mCols.Count();
|
||||
}
|
||||
|
||||
inline PRInt32 nsCellMap::GetRowCount() const
|
||||
@ -236,15 +273,16 @@ inline PRInt32 nsCellMap::GetRowCount() const
|
||||
return mRowCount;
|
||||
}
|
||||
|
||||
inline void nsCellMap::AppendColumnFrame(nsTableColFrame *aColFrame)
|
||||
{
|
||||
mColFrames.AppendElement(aColFrame);
|
||||
}
|
||||
// nsColInfo
|
||||
|
||||
inline void nsCellMap::ClearColumnCache()
|
||||
{
|
||||
mColFrames.Clear();
|
||||
}
|
||||
inline nsColInfo::nsColInfo()
|
||||
:mNumCellsOrig(0), mNumCellsSpan(0)
|
||||
{}
|
||||
|
||||
inline nsColInfo::nsColInfo(PRInt32 aNumCellsOrig,
|
||||
PRInt32 aNumCellsSpan)
|
||||
:mNumCellsOrig(aNumCellsOrig), mNumCellsSpan(aNumCellsSpan)
|
||||
{}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -38,11 +38,9 @@ public:
|
||||
|
||||
/** call once every time any table thing changes (content, structure, or style)
|
||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||
* @param aNumCols the total number of columns in the table
|
||||
* @param aComputedWidth the computed size of the table
|
||||
*/
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize,
|
||||
PRInt32 aNumCols,
|
||||
nscoord aComputedWidth)=0;
|
||||
|
||||
/** compute the max-element-size for the table
|
||||
@ -80,9 +78,6 @@ public:
|
||||
/** return the value of the COLS attribute, used for balancing column widths */
|
||||
virtual nscoord GetCOLSAttribute() const = 0;
|
||||
|
||||
/** return the total number of columns in the table */
|
||||
virtual nscoord GetNumCols() const = 0;
|
||||
|
||||
// see nsTableFrame::ColumnsCanBeInvalidatedBy
|
||||
virtual PRBool ColumnsCanBeInvalidatedBy(nsStyleCoord* aPrevStyleWidth,
|
||||
const nsTableCellFrame& aCellFrame) const = 0;
|
||||
|
@ -146,8 +146,6 @@ void nsTableBorderCollapser::ComputeVerticalBorders(nsIPresContext* aPresContext
|
||||
//if (nsnull == cellMap)
|
||||
// return; // no info yet, so nothing useful to do
|
||||
|
||||
mTableFrame.CacheColFrames(aPresContext); // XXX why here?
|
||||
|
||||
// compute all the collapsing border values for the entire table
|
||||
// XXX: we have to make this more incremental!
|
||||
|
||||
@ -305,7 +303,7 @@ void nsTableBorderCollapser::ComputeRightBorderForEdgeAt(nsIPresContext* aPresCo
|
||||
styles.AppendElement((void*)spacing);
|
||||
}
|
||||
// 2. colgroup //XXX: need to test if we're really on a colgroup border
|
||||
nsTableColFrame* colFrame = cellMap->GetColumnFrame(aColIndex);
|
||||
nsTableColFrame* colFrame = mTableFrame.GetColFrame(aColIndex);
|
||||
nsIFrame* colGroupFrame;
|
||||
colFrame->GetParent(&colGroupFrame);
|
||||
colGroupFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing));
|
||||
@ -402,7 +400,7 @@ void nsTableBorderCollapser::ComputeTopBorderForEdgeAt(nsIPresContext* aPresCont
|
||||
mTableFrame.GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing));
|
||||
styles.AppendElement((void*)spacing);
|
||||
// 2. colgroup
|
||||
nsTableColFrame* colFrame = cellMap->GetColumnFrame(aColIndex);
|
||||
nsTableColFrame* colFrame = mTableFrame.GetColFrame(aColIndex);
|
||||
nsIFrame* colGroupFrame;
|
||||
colFrame->GetParent(&colGroupFrame);
|
||||
colGroupFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing));
|
||||
@ -521,7 +519,7 @@ void nsTableBorderCollapser::ComputeBottomBorderForEdgeAt(nsIPresContext* aPresC
|
||||
styles.AppendElement((void*)spacing);
|
||||
|
||||
// 2. colgroup // XXX: need to deterine if we're on a colgroup boundary
|
||||
nsTableColFrame* colFrame = cellMap->GetColumnFrame(aColIndex);
|
||||
nsTableColFrame* colFrame = mTableFrame.GetColFrame(aColIndex);
|
||||
nsIFrame* colGroupFrame;
|
||||
colFrame->GetParent(&colGroupFrame);
|
||||
colGroupFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing));
|
||||
|
@ -71,10 +71,9 @@ nsTableCellFrame::Init(nsIPresContext* aPresContext,
|
||||
if (aPrevInFlow) {
|
||||
// Set the column index
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aPrevInFlow;
|
||||
PRInt32 baseColIndex;
|
||||
|
||||
cellFrame->GetColIndex(baseColIndex);
|
||||
InitCellFrame(baseColIndex);
|
||||
PRInt32 colIndex;
|
||||
cellFrame->GetColIndex(colIndex);
|
||||
InitCellFrame(colIndex);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -139,29 +138,24 @@ nsTableCellFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
|
||||
void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
|
||||
{
|
||||
NS_PRECONDITION(0<=aColIndex, "bad col index arg");
|
||||
SetColIndex(aColIndex); // this also sets the contents col index
|
||||
nsTableFrame* tableFrame=nsnull; // I should be checking my own style context, but border-collapse isn't inheriting correctly
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
if (NS_STYLE_BORDER_COLLAPSE == tableFrame->GetBorderCollapseStyle())
|
||||
{
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) {
|
||||
SetColIndex(aColIndex);
|
||||
if (NS_STYLE_BORDER_COLLAPSE == tableFrame->GetBorderCollapseStyle()) {
|
||||
mBorderEdges = new nsBorderEdges;
|
||||
mBorderEdges->mOutsideEdge=PR_FALSE;
|
||||
|
||||
PRInt32 rowspan = GetRowSpan();
|
||||
PRInt32 i;
|
||||
for (i=0; i<rowspan; i++)
|
||||
{
|
||||
for (i=0; i<rowspan; i++) {
|
||||
nsBorderEdge *borderToAdd = new nsBorderEdge();
|
||||
mBorderEdges->mEdges[NS_SIDE_LEFT].AppendElement(borderToAdd);
|
||||
borderToAdd = new nsBorderEdge();
|
||||
mBorderEdges->mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd);
|
||||
}
|
||||
PRInt32 colspan = GetColSpan();
|
||||
for (i=0; i<colspan; i++)
|
||||
{
|
||||
for (i=0; i<colspan; i++) {
|
||||
nsBorderEdge *borderToAdd = new nsBorderEdge();
|
||||
mBorderEdges->mEdges[NS_SIDE_TOP].AppendElement(borderToAdd);
|
||||
borderToAdd = new nsBorderEdge();
|
||||
|
@ -19,6 +19,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIReflowCommand.h"
|
||||
@ -30,6 +31,11 @@
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
#define COL_TYPE_CONTENT 0x0
|
||||
#define COL_TYPE_ANONYMOUS_COL 0x1
|
||||
#define COL_TYPE_ANONYMOUS_COLGROUP 0x2
|
||||
#define COL_TYPE_ANONYMOUS_CELL 0x3
|
||||
|
||||
nsTableColFrame::nsTableColFrame()
|
||||
: nsFrame(),
|
||||
mProportion(WIDTH_NOT_SET),
|
||||
@ -38,12 +44,55 @@ nsTableColFrame::nsTableColFrame()
|
||||
{
|
||||
// note that all fields are initialized to 0 by nsFrame::operator new
|
||||
ResetSizingInfo();
|
||||
SetType(eColContent);
|
||||
}
|
||||
|
||||
nsTableColFrame::~nsTableColFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsTableColType nsTableColFrame::GetType() const {
|
||||
switch(mBits.mType) {
|
||||
case COL_TYPE_ANONYMOUS_COL:
|
||||
return eColAnonymousCol;
|
||||
case COL_TYPE_ANONYMOUS_COLGROUP:
|
||||
return eColAnonymousColGroup;
|
||||
case COL_TYPE_ANONYMOUS_CELL:
|
||||
return eColAnonymousCell;
|
||||
default:
|
||||
return eColContent;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableColFrame::SetType(nsTableColType aType) {
|
||||
mBits.mType = aType - eColContent;
|
||||
}
|
||||
|
||||
// XXX what about other style besides width
|
||||
nsStyleCoord nsTableColFrame::GetStyleWidth() const
|
||||
{
|
||||
nsStylePosition* position = nsnull;
|
||||
position = (nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position);
|
||||
nsStyleCoord styleWidth = position->mWidth;
|
||||
// the following should not be necessary since html.css defines table-col and
|
||||
// :table-col to inherit. However, :table-col is not inheriting properly
|
||||
if (eStyleUnit_Auto == styleWidth.GetUnit()) {
|
||||
nsIFrame* parent;
|
||||
GetParent(&parent);
|
||||
nsCOMPtr<nsIStyleContext> styleContext;
|
||||
parent->GetStyleContext(getter_AddRefs(styleContext));
|
||||
if (styleContext) {
|
||||
position = (nsStylePosition*)styleContext->GetStyleData(eStyleStruct_Position);
|
||||
styleWidth = position->mWidth;
|
||||
}
|
||||
}
|
||||
|
||||
nsStyleCoord returnWidth;
|
||||
returnWidth.mUnit = styleWidth.mUnit;
|
||||
returnWidth.mValue = styleWidth.mValue;
|
||||
return returnWidth;
|
||||
}
|
||||
|
||||
void nsTableColFrame::ResetSizingInfo()
|
||||
{
|
||||
nsCRT::memset(mWidths, WIDTH_NOT_SET, NUM_WIDTHS * sizeof(PRInt32));
|
||||
|
@ -55,6 +55,13 @@ enum nsColConstraint {
|
||||
e0ProportionConstraint = 4 // 0*, means to force to min width
|
||||
};
|
||||
|
||||
enum nsTableColType {
|
||||
eColContent = 0, // there is real col content associated
|
||||
eColAnonymousCol = 1, // the result of a span on a col
|
||||
eColAnonymousColGroup = 2, // the result of a span on a col group
|
||||
eColAnonymousCell = 3, // the result of a cell alone
|
||||
};
|
||||
|
||||
class nsTableColFrame : public nsFrame {
|
||||
public:
|
||||
|
||||
@ -63,7 +70,8 @@ public:
|
||||
eWIDTH_SOURCE_CELL_WITH_SPAN=2 // a cell implicitly specified a width via colspan
|
||||
};
|
||||
|
||||
void InitColFrame(PRInt32 aColIndex);
|
||||
nsTableColType GetType() const;
|
||||
void nsTableColFrame::SetType(nsTableColType aType);
|
||||
|
||||
/** instantiate a new instance of nsTableColFrame.
|
||||
* @param aResult the new object is returned in this out-param
|
||||
@ -75,6 +83,12 @@ public:
|
||||
friend nsresult
|
||||
NS_NewTableColFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
|
||||
nsStyleCoord GetStyleWidth() const;
|
||||
|
||||
PRInt32 GetColIndex() const;
|
||||
|
||||
void SetColIndex (PRInt32 aColIndex);
|
||||
|
||||
NS_IMETHOD Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
@ -97,15 +111,9 @@ public:
|
||||
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
||||
#endif
|
||||
|
||||
/** return the index of the column the col represents. always >= 0 */
|
||||
virtual PRInt32 GetColumnIndex ();
|
||||
|
||||
/** return the number of the columns the col represents. always >= 0 */
|
||||
virtual PRInt32 GetSpan ();
|
||||
|
||||
/** set the index of the column this content object represents. must be >= 0 */
|
||||
virtual void SetColumnIndex (int aColIndex);
|
||||
|
||||
/** convenience method, calls into cellmap */
|
||||
nsVoidArray * GetCells();
|
||||
|
||||
@ -138,6 +146,11 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
struct ColBits {
|
||||
unsigned int mType:4;
|
||||
unsigned int mUnused:28;
|
||||
} mBits;
|
||||
|
||||
nsTableColFrame();
|
||||
~nsTableColFrame();
|
||||
|
||||
@ -153,18 +166,11 @@ protected:
|
||||
PRPackedBool mNonPercentSpansPercent;
|
||||
};
|
||||
|
||||
|
||||
inline void nsTableColFrame::InitColFrame(PRInt32 aColIndex)
|
||||
{
|
||||
NS_ASSERTION(0<=aColIndex, "bad col index param");
|
||||
mColIndex = aColIndex;
|
||||
}
|
||||
|
||||
inline PRInt32 nsTableColFrame::GetColumnIndex()
|
||||
inline PRInt32 nsTableColFrame::GetColIndex() const
|
||||
{ return mColIndex; }
|
||||
|
||||
inline void nsTableColFrame::SetColumnIndex (int aColIndex)
|
||||
{ mColIndex = aColIndex;}
|
||||
inline void nsTableColFrame::SetColIndex (PRInt32 aColIndex)
|
||||
{ mColIndex = aColIndex; }
|
||||
|
||||
inline nsColConstraint nsTableColFrame::GetConstraint() const
|
||||
{ return mConstraint; }
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsTableFrame.h"
|
||||
#include "nsIHTMLTableColElement.h"
|
||||
#include "nsIDOMHTMLTableColElement.h"
|
||||
#include "nsIReflowCommand.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
@ -40,101 +41,230 @@
|
||||
NS_DEF_PTR(nsIContent);
|
||||
|
||||
static NS_DEFINE_IID(kIHTMLTableColElementIID, NS_IHTMLTABLECOLELEMENT_IID);
|
||||
static NS_DEFINE_IID(kIDOMHTMLTableColElementIID, NS_IDOMHTMLTABLECOLELEMENT_IID);
|
||||
|
||||
#define COLGROUP_TYPE_CONTENT 0x0
|
||||
#define COLGROUP_TYPE_ANONYMOUS_COL 0x1
|
||||
#define COLGROUP_TYPE_ANONYMOUS_CELL 0x2
|
||||
|
||||
nsTableColGroupType nsTableColGroupFrame::GetType() const {
|
||||
switch(mBits.mType) {
|
||||
case COLGROUP_TYPE_ANONYMOUS_COL:
|
||||
return eColGroupAnonymousCol;
|
||||
case COLGROUP_TYPE_ANONYMOUS_CELL:
|
||||
return eColGroupAnonymousCell;
|
||||
default:
|
||||
return eColGroupContent;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableColGroupFrame::SetType(nsTableColGroupType aType) {
|
||||
mBits.mType = aType - eColGroupContent;
|
||||
}
|
||||
|
||||
void nsTableColGroupFrame::ResetColIndices(nsIFrame* aFirstColGroup,
|
||||
PRInt32 aFirstColIndex,
|
||||
nsIFrame* aStartColFrame)
|
||||
{
|
||||
nsTableColGroupFrame* colGroupFrame = (nsTableColGroupFrame*)aFirstColGroup;
|
||||
PRInt32 colIndex = aFirstColIndex;
|
||||
while (colGroupFrame) {
|
||||
nsIAtom* cgType;
|
||||
colGroupFrame->GetFrameType(&cgType);
|
||||
if (nsLayoutAtoms::tableColGroupFrame == cgType) {
|
||||
colGroupFrame->SetStartColumnIndex(colIndex);
|
||||
nsIFrame* colFrame = aStartColFrame;
|
||||
if (!colFrame || (colIndex != aFirstColIndex)) {
|
||||
colGroupFrame->FirstChild(nsnull, &colFrame);
|
||||
}
|
||||
while (colFrame) {
|
||||
nsIAtom* colType;
|
||||
colFrame->GetFrameType(&colType);
|
||||
if (nsLayoutAtoms::tableColFrame == colType) {
|
||||
((nsTableColFrame*)colFrame)->SetColIndex(colIndex);
|
||||
colIndex++;
|
||||
}
|
||||
NS_IF_RELEASE(colType);
|
||||
colFrame->GetNextSibling(&colFrame);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(cgType);
|
||||
colGroupFrame->GetNextSibling((nsIFrame**)&colGroupFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::InitNewFrames(nsIPresContext* aPresContext, nsIFrame* aChildList)
|
||||
nsTableColGroupFrame::AddColsToTable(nsIPresContext& aPresContext,
|
||||
PRInt32 aFirstColIndex,
|
||||
PRBool aResetSubsequentColIndices,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsresult rv=NS_OK;
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) {
|
||||
// Process the newly added column frames
|
||||
for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
|
||||
const nsStyleDisplay* display;
|
||||
kidFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == display->mDisplay) {
|
||||
// Set the preliminary values for the column frame
|
||||
PRInt32 colIndex = mStartColIndex + mColCount;
|
||||
((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex);
|
||||
PRInt32 repeat = ((nsTableColFrame *)(kidFrame))->GetSpan();
|
||||
mColCount += repeat;
|
||||
for (PRInt32 i=0; i<repeat; i++) {
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
// colgroup's span attribute is how many columns the group represents
|
||||
// in the absence of any COL children
|
||||
// Note that this is the correct, though perhaps unexpected, behavior for the span attribute.
|
||||
// The spec says that if there are any COL children, the colgroup's span is ignored.
|
||||
if (0==mColCount)
|
||||
{
|
||||
nsIFrame *firstImplicitColFrame=nsnull;
|
||||
nsIFrame *prevColFrame=nsnull;
|
||||
nsAutoString colTag;
|
||||
nsHTMLAtoms::col->ToString(colTag);
|
||||
mColCount = GetSpan();
|
||||
for (PRInt32 colIndex=0; colIndex<mColCount; colIndex++)
|
||||
{
|
||||
nsIHTMLContent *col=nsnull;
|
||||
// create an implicit col
|
||||
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
|
||||
//XXX mark the col implicit
|
||||
mContent->AppendChildTo((nsIContent*)col, PR_FALSE);
|
||||
|
||||
// Create a new col frame
|
||||
nsIFrame* colFrame;
|
||||
NS_NewTableColFrame(shell, &colFrame);
|
||||
|
||||
// Set its style context
|
||||
nsCOMPtr<nsIStyleContext> colStyleContext;
|
||||
aPresContext->ResolveStyleContextFor(col, mStyleContext,
|
||||
PR_TRUE,
|
||||
getter_AddRefs(colStyleContext));
|
||||
colFrame->Init(aPresContext, col, this, colStyleContext, nsnull);
|
||||
colFrame->SetInitialChildList(aPresContext, nsnull, nsnull);
|
||||
|
||||
// Set nsColFrame-specific information
|
||||
PRInt32 absColIndex = mStartColIndex + colIndex;
|
||||
((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex);
|
||||
((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)colFrame);
|
||||
|
||||
//hook into list of children
|
||||
if (nsnull==firstImplicitColFrame)
|
||||
firstImplicitColFrame = colFrame;
|
||||
else
|
||||
prevColFrame->SetNextSibling(colFrame);
|
||||
prevColFrame = colFrame;
|
||||
}
|
||||
|
||||
// hook new columns into col group child list
|
||||
mFrames.AppendFrames(nsnull, firstImplicitColFrame);
|
||||
}
|
||||
SetStyleContextForFirstPass(aPresContext);
|
||||
if (!(NS_SUCCEEDED(rv) && tableFrame && aFirstFrame)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// set the col indices of the col frames and and add col info to the table
|
||||
PRInt32 colIndex = aFirstColIndex;
|
||||
nsIFrame* kidFrame = aFirstFrame;
|
||||
PRBool foundLastFrame = PR_FALSE;
|
||||
while (kidFrame) {
|
||||
nsIAtom* kidType;
|
||||
kidFrame->GetFrameType(&kidType);
|
||||
if (nsLayoutAtoms::tableColFrame == kidType) {
|
||||
((nsTableColFrame*)kidFrame)->SetColIndex(colIndex);
|
||||
if (!foundLastFrame) {
|
||||
tableFrame->InsertCol(aPresContext, (nsTableColFrame &)*kidFrame, colIndex);
|
||||
mColCount++;
|
||||
}
|
||||
colIndex++;
|
||||
}
|
||||
NS_IF_RELEASE(kidType);
|
||||
if (kidFrame == aLastFrame) {
|
||||
foundLastFrame = PR_TRUE;
|
||||
}
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
}
|
||||
|
||||
if (aResetSubsequentColIndices) {
|
||||
nsIFrame* nextSibling;
|
||||
GetNextSibling(&nextSibling);
|
||||
if (nextSibling) {
|
||||
ResetColIndices(nextSibling, colIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::AppendNewFrames(nsIPresContext* aPresContext, nsIFrame* aChildList)
|
||||
// this is called when a col frame doesn't have an explicit col group parent.
|
||||
nsTableColGroupFrame*
|
||||
nsTableColGroupFrame::FindParentForAppendedCol(nsTableFrame* aTableFrame,
|
||||
nsTableColType aColType)
|
||||
{
|
||||
if (nsnull!=aChildList)
|
||||
mFrames.AppendFrames(nsnull, aChildList);
|
||||
return NS_OK;
|
||||
nsVoidArray& cols = aTableFrame->GetColCache();
|
||||
PRInt32 numCols = cols.Count();
|
||||
nsIFrame* lastColGroup;
|
||||
nsIFrame* lastCol = (nsIFrame*)cols.ElementAt(numCols - 1);
|
||||
if (!lastCol) return nsnull; // no columns so no colgroups
|
||||
lastCol->GetParent(&lastColGroup);
|
||||
if (!lastColGroup) return nsnull; // shouldn't happen
|
||||
|
||||
nsTableColGroupFrame* relevantColGroup = (nsTableColGroupFrame *)lastColGroup;
|
||||
nsTableColGroupType relevantColGroupType = relevantColGroup->GetType();
|
||||
if (eColGroupAnonymousCell == relevantColGroupType) {
|
||||
if (eColAnonymousCell == aColType) {
|
||||
return relevantColGroup;
|
||||
}
|
||||
else {
|
||||
// find the next to last col group
|
||||
for (PRInt32 colX = numCols - 2; colX >= 0; colX--) {
|
||||
nsTableColFrame* colFrame = (nsTableColFrame*)cols.ElementAt(colX);
|
||||
nsTableColGroupFrame* colGroupFrame;
|
||||
colFrame->GetParent((nsIFrame**)&colGroupFrame);
|
||||
nsTableColGroupType cgType = colGroupFrame->GetType();
|
||||
if (cgType != relevantColGroupType) {
|
||||
relevantColGroup = colGroupFrame;
|
||||
relevantColGroupType = cgType;
|
||||
break;
|
||||
}
|
||||
else if (0 == colX) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eColGroupAnonymousCol == relevantColGroupType) {
|
||||
if ((eColContent == aColType) || (eColAnonymousCol == aColType)) {
|
||||
return relevantColGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTableColGroupFrame::GetLastRealColGroup(nsTableFrame* aTableFrame,
|
||||
nsIFrame** aLastColGroup)
|
||||
{
|
||||
*aLastColGroup = nsnull;
|
||||
nsFrameList colGroups = aTableFrame->GetColGroups();
|
||||
|
||||
nsIFrame* nextToLastColGroup = nsnull;
|
||||
nsIFrame* lastColGroup = colGroups.FirstChild();
|
||||
while(lastColGroup) {
|
||||
nsIFrame* next;
|
||||
lastColGroup->GetNextSibling(&next);
|
||||
if (next) {
|
||||
nextToLastColGroup = lastColGroup;
|
||||
lastColGroup = next;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lastColGroup) return PR_TRUE; // there are no col group frames
|
||||
|
||||
nsTableColGroupType lastColGroupType = ((nsTableColGroupFrame *)lastColGroup)->GetType();
|
||||
if (eColGroupAnonymousCell == lastColGroupType) {
|
||||
*aLastColGroup = nextToLastColGroup;
|
||||
return PR_FALSE;
|
||||
}
|
||||
else {
|
||||
*aLastColGroup = lastColGroup;
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// don't set mColCount here, it is done in AddColsToTable
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
nsresult result = AppendNewFrames(aPresContext, aChildList);
|
||||
if (NS_OK==result)
|
||||
result = InitNewFrames(aPresContext, aChildList);
|
||||
return result;
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (!aChildList) {
|
||||
nsIFrame* firstChild;
|
||||
tableFrame->CreateAnonymousColFrames(*aPresContext, *this, GetSpan(), eColAnonymousColGroup,
|
||||
PR_FALSE, nsnull, &firstChild);
|
||||
if (firstChild) {
|
||||
SetInitialChildList(aPresContext, aListName, firstChild);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame* kidFrame = aChildList;
|
||||
while (kidFrame) {
|
||||
nsIAtom* kidType;
|
||||
kidFrame->GetFrameType(&kidType);
|
||||
if (nsLayoutAtoms::tableColFrame == kidType) {
|
||||
// Set the preliminary values for the column frame
|
||||
PRInt32 span = ((nsTableColFrame*)kidFrame)->GetSpan();
|
||||
if (span > 1) {
|
||||
nsTableColFrame* firstSpannedCol;
|
||||
tableFrame->CreateAnonymousColFrames(*aPresContext, *this, span - 1, eColAnonymousCol,
|
||||
PR_FALSE, (nsTableColFrame*)kidFrame, (nsIFrame **)&firstSpannedCol);
|
||||
nsIFrame* spanner = kidFrame;
|
||||
kidFrame->GetNextSibling(&kidFrame); // need to do this before we insert the new frames
|
||||
nsFrameList newChildren(aChildList); // used as a convience to hook up siblings
|
||||
newChildren.InsertFrames(this, (nsTableColFrame*)spanner, (nsIFrame *)firstSpannedCol);
|
||||
NS_RELEASE(kidType);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(kidType);
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
}
|
||||
|
||||
mFrames.AppendFrames(this, aChildList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Helper function. It marks the table frame as dirty and generates
|
||||
@ -173,35 +303,8 @@ nsTableColGroupFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Append the new frames to our child list
|
||||
mFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
// Reset the starting column index of the col groups that follow
|
||||
PRInt32 startingColIndex = mStartColIndex;
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
|
||||
nsIFrame *nextColGroupFrame=nsnull;
|
||||
GetNextSibling(&nextColGroupFrame);
|
||||
while (nextColGroupFrame)
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
nextColGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)nextColGroupFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
nextColGroupFrame->GetNextSibling(&nextColGroupFrame);
|
||||
}
|
||||
|
||||
// Today we need to rebuild the whole column cache.
|
||||
// If the table frame is ever recoded to build the column cache incrementally,
|
||||
// we could take advantage of that here
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
mFrames.AppendFrames(this, aFrameList);
|
||||
InsertColsReflow(*aPresContext, aPresShell, mColCount, aFrameList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -209,76 +312,121 @@ NS_IMETHODIMP
|
||||
nsTableColGroupFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aPrevFrameIn,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Insert the new frames into our child list
|
||||
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
nsFrameList frames(aFrameList); // convience for getting last frame
|
||||
nsIFrame* lastFrame = frames.LastChild();
|
||||
|
||||
// Reset the starting column index of the col groups that follow
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
mFrames.InsertFrames(this, aPrevFrameIn, aFrameList);
|
||||
nsIFrame* prevFrame = nsTableFrame::GetFrameAtOrBefore(this, aPrevFrameIn,
|
||||
nsLayoutAtoms::tableColFrame);
|
||||
|
||||
nsIFrame *nextColGroupFrame=nsnull;
|
||||
GetNextSibling(&nextColGroupFrame);
|
||||
while (nextColGroupFrame)
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
nextColGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)nextColGroupFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
nextColGroupFrame->GetNextSibling(&nextColGroupFrame);
|
||||
}
|
||||
PRInt32 colIndex = (prevFrame) ? ((nsTableColFrame*)prevFrame)->GetColIndex() + 1 : 0;
|
||||
InsertColsReflow(*aPresContext, aPresShell, colIndex, aFrameList, lastFrame);
|
||||
|
||||
// Today we need to rebuild the whole column cache.
|
||||
// If the table frame is ever recoded to build the column cache incrementally,
|
||||
// we could take advantage of that here.
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsTableColGroupFrame::InsertColsReflow(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
PRInt32 aColIndex,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame)
|
||||
{
|
||||
AddColsToTable(aPresContext, aColIndex, PR_TRUE, aFirstFrame, aLastFrame);
|
||||
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(&aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
|
||||
void
|
||||
nsTableColGroupFrame::RemoveChild(nsIPresContext& aPresContext,
|
||||
nsTableColFrame& aChild,
|
||||
PRBool aResetColIndices)
|
||||
{
|
||||
PRInt32 colIndex = 0;
|
||||
nsIFrame* nextChild = nsnull;
|
||||
if (aResetColIndices) {
|
||||
colIndex = aChild.GetColIndex();
|
||||
aChild.GetNextSibling(&nextChild);
|
||||
}
|
||||
if (mFrames.DestroyFrame(&aPresContext, (nsIFrame*)&aChild)) {
|
||||
mColCount--;
|
||||
if (aResetColIndices) {
|
||||
ResetColIndices(this, colIndex, nextChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this removes children form the last col group (eColGroupAnonymousCell) in the
|
||||
// table only,so there is no need to reset col indices for subsequent col groups.
|
||||
void
|
||||
nsTableColGroupFrame::RemoveChildrenAtEnd(nsIPresContext& aPresContext,
|
||||
PRInt32 aNumChildrenToRemove)
|
||||
{
|
||||
PRInt32 numToRemove = aNumChildrenToRemove;
|
||||
if (numToRemove > mColCount) {
|
||||
NS_ASSERTION(PR_FALSE, "invalid arg to RemoveChildrenAtEnd");
|
||||
numToRemove = mColCount;
|
||||
}
|
||||
PRInt32 offsetOfFirstRemoval = mColCount - numToRemove;
|
||||
PRInt32 offsetX = 0;
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
while(kidFrame) {
|
||||
nsIAtom* kidType;
|
||||
kidFrame->GetFrameType(&kidType);
|
||||
if (nsLayoutAtoms::tableColFrame == kidType) {
|
||||
offsetX++;
|
||||
if (offsetX > offsetOfFirstRemoval) {
|
||||
nsIFrame* byebye = kidFrame;
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
mFrames.DestroyFrame(&aPresContext, byebye);
|
||||
NS_RELEASE(kidType);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(kidType);
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
// Remove the frame from our child list
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
if (!aOldFrame) return NS_OK;
|
||||
|
||||
// Reset the starting column index of the col groups that follow
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
|
||||
nsIFrame *nextColGroupFrame=nsnull;
|
||||
GetNextSibling(&nextColGroupFrame);
|
||||
while (nextColGroupFrame)
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
nextColGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)nextColGroupFrame)->SetStartColumnIndex(startingColIndex);
|
||||
nsIAtom* frameType = nsnull;
|
||||
aOldFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableColFrame == frameType) {
|
||||
nsTableColFrame* colFrame = (nsTableColFrame*)aOldFrame;
|
||||
PRInt32 colIndex = colFrame->GetColIndex();
|
||||
RemoveChild(*aPresContext, *colFrame, PR_TRUE);
|
||||
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
tableFrame->RemoveCol(*aPresContext, this, colIndex, PR_TRUE, PR_TRUE);
|
||||
}
|
||||
nextColGroupFrame->GetNextSibling(&nextColGroupFrame);
|
||||
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
else {
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
|
||||
// Today we need to rebuild the whole column cache.
|
||||
// If the table frame is ever recoded to build the column cache incrementally,
|
||||
// we could take advantage of that here
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -429,11 +577,10 @@ NS_METHOD nsTableColGroupFrame::IR_StyleChanged(nsIPresContext* aPresCo
|
||||
nsresult rv = NS_OK;
|
||||
// we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here
|
||||
// XXX: we can optimize this when we know which style attribute changed
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
tableFrame->InvalidateColumnCache();
|
||||
if ((NS_SUCCEEDED(rv)) && tableFrame) {
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
}
|
||||
return rv;
|
||||
@ -448,7 +595,7 @@ NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext* aPresC
|
||||
nsresult rv;
|
||||
|
||||
// Remember the old col count
|
||||
const PRInt32 oldColCount = GetColumnCount();
|
||||
const PRInt32 oldColCount = GetColCount();
|
||||
|
||||
// Pass along the reflow command
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
@ -462,136 +609,16 @@ NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext* aPresC
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) {
|
||||
// compare the new col count to the old col count.
|
||||
// If they are the same, we just need to rebalance column widths
|
||||
// If they differ, we need to fix up other column groups and the column cache
|
||||
const PRInt32 newColCount = GetColumnCount(); // this will set the new column indexes if necessary
|
||||
if (oldColCount==newColCount)
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
else
|
||||
tableFrame->InvalidateColumnCache();
|
||||
const PRInt32 newColCount = GetColCount();
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Subclass hook for style post processing
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext)
|
||||
{
|
||||
// get the table frame
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
// get the style for the table frame
|
||||
const nsStyleTable *tableStyle;
|
||||
tableFrame->GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
|
||||
|
||||
// if COLS is set, then map it into the COL frames
|
||||
if (NS_STYLE_TABLE_COLS_NONE != tableStyle->mCols)
|
||||
{
|
||||
// set numCols to the number of columns effected by the COLS attribute
|
||||
PRInt32 numCols=0;
|
||||
if (NS_STYLE_TABLE_COLS_ALL == tableStyle->mCols)
|
||||
numCols = mFrames.GetLength();
|
||||
else
|
||||
numCols = tableStyle->mCols;
|
||||
|
||||
// for every column effected, set its width style
|
||||
PRInt32 colIndex=0;
|
||||
nsIFrame *colFrame=mFrames.FirstChild();
|
||||
while (nsnull!=colFrame)
|
||||
{
|
||||
const nsStyleDisplay * colDisplay=nsnull;
|
||||
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
|
||||
{
|
||||
nsCOMPtr<nsIStyleContext> colStyleContext;
|
||||
nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleContext(getter_AddRefs(colStyleContext));
|
||||
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
if (colIndex<numCols)
|
||||
{
|
||||
nsStyleCoord width (1, eStyleUnit_Proportional);
|
||||
colPosition->mWidth = width;
|
||||
}
|
||||
else
|
||||
{
|
||||
colPosition->mWidth.SetCoordValue(0);
|
||||
}
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
colIndex++;
|
||||
}
|
||||
colFrame->GetNextSibling(&colFrame);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// propagate the colgroup width attribute down to the columns if they have no width of their own
|
||||
nsStylePosition* position = (nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position);
|
||||
if (eStyleUnit_Null!=position->mWidth.GetUnit())
|
||||
{
|
||||
// now for every column that doesn't have it's own width, set the width style
|
||||
nsIFrame *colFrame=mFrames.FirstChild();
|
||||
while (nsnull!=colFrame)
|
||||
{
|
||||
const nsStyleDisplay * colDisplay=nsnull;
|
||||
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
|
||||
{
|
||||
nsCOMPtr<nsIStyleContext> colStyleContext;
|
||||
const nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)colPosition); // get a read-only version of the style context
|
||||
//XXX: how do I know this is auto because it's defaulted, vs. set explicitly to "auto"?
|
||||
if (eStyleUnit_Auto==colPosition->mWidth.GetUnit())
|
||||
{
|
||||
// notice how we defer getting a mutable style context until we're sure we really need one
|
||||
colFrame->GetStyleContext(getter_AddRefs(colStyleContext));
|
||||
nsStylePosition * mutableColPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
mutableColPosition->mWidth = position->mWidth;
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
}
|
||||
}
|
||||
colFrame->GetNextSibling(&colFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
//mStyleContext->RecalcAutomaticData(aPresContext);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/** returns the number of columns represented by this group.
|
||||
* if there are col children, count them (taking into account the span of each)
|
||||
* else, check my own span attribute.
|
||||
*/
|
||||
int nsTableColGroupFrame::GetColumnCount ()
|
||||
{
|
||||
mColCount=0;
|
||||
nsIFrame *childFrame = mFrames.FirstChild();
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay)
|
||||
{
|
||||
nsTableColFrame *col = (nsTableColFrame *)childFrame;
|
||||
col->SetColumnIndex (mStartColIndex + mColCount);
|
||||
mColCount += col->GetSpan();
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
if (0==mColCount)
|
||||
{ // there were no children of this colgroup that were columns. So use my span attribute
|
||||
const nsStyleTable *tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
|
||||
mColCount = tableStyle->mSpan;
|
||||
}
|
||||
return mColCount;
|
||||
}
|
||||
|
||||
nsTableColFrame * nsTableColGroupFrame::GetFirstColumn()
|
||||
{
|
||||
return GetNextColumn(nsnull);
|
||||
@ -642,28 +669,26 @@ nsTableColFrame * nsTableColGroupFrame::GetColumnAt (PRInt32 aColIndex)
|
||||
|
||||
PRInt32 nsTableColGroupFrame::GetSpan()
|
||||
{
|
||||
PRInt32 span=1;
|
||||
const nsStyleTable* tableStyle=nsnull;
|
||||
GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
|
||||
if (nsnull!=tableStyle)
|
||||
{
|
||||
span = tableStyle->mSpan;
|
||||
PRInt32 span = 1;
|
||||
nsCOMPtr<nsIContent> iContent;
|
||||
nsresult rv = GetContent(getter_AddRefs(iContent));
|
||||
if (NS_FAILED(rv) || !iContent) return rv;
|
||||
|
||||
// col group element derives from col element
|
||||
nsIDOMHTMLTableColElement* cgContent = nsnull;
|
||||
rv = iContent->QueryInterface(kIDOMHTMLTableColElementIID,
|
||||
(void **)&cgContent);
|
||||
if (cgContent && NS_SUCCEEDED(rv)) {
|
||||
cgContent->GetSpan(&span);
|
||||
// XXX why does this work!!
|
||||
if (span == -1) {
|
||||
span = 1;
|
||||
}
|
||||
NS_RELEASE(cgContent);
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
/* this may be needed when IsSynthetic is properly implemented
|
||||
PRBool nsTableColGroupFrame::IsManufactured()
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
nsIFrame *firstCol = GetFirstColumn();
|
||||
if (nsTableFrame::IsSynthetic(this) &&
|
||||
((nsnull==firstCol) || nsTableFrame::IsSynthetic(firstCol)))
|
||||
result = PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
/** returns colcount because it is frequently used in the context of
|
||||
* shuffling relative colgroup order, and it's convenient to not have to
|
||||
* call GetColumnCount redundantly.
|
||||
@ -671,15 +696,41 @@ PRBool nsTableColGroupFrame::IsManufactured()
|
||||
PRInt32 nsTableColGroupFrame::SetStartColumnIndex (int aIndex)
|
||||
{
|
||||
PRInt32 result = mColCount;
|
||||
if (aIndex != mStartColIndex)
|
||||
{
|
||||
if (aIndex != mStartColIndex) {
|
||||
mStartColIndex = aIndex;
|
||||
mColCount=0;
|
||||
result = GetColumnCount(); // has the side effect of setting each column index based on new start index
|
||||
result = GetColCount();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// this could be optimized by using col group frame starting indicies,
|
||||
// but typically there aren't enough very large col groups for the added complexity.
|
||||
nsTableColGroupFrame*
|
||||
nsTableColGroupFrame::GetColGroupFrameContaining(nsFrameList& aColGroupList,
|
||||
nsTableColFrame& aColFrame)
|
||||
{
|
||||
nsIFrame* childFrame = aColGroupList.FirstChild();
|
||||
while (childFrame) {
|
||||
nsIAtom* frameType = nsnull;
|
||||
childFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableColGroupFrame == frameType) {
|
||||
nsTableColFrame* colFrame = nsnull;
|
||||
childFrame->FirstChild(nsnull, (nsIFrame **)&colFrame);
|
||||
while (colFrame) {
|
||||
if (colFrame = &aColFrame) {
|
||||
NS_RELEASE(frameType);
|
||||
return (nsTableColGroupFrame *)childFrame;
|
||||
}
|
||||
colFrame->GetNextSibling((nsIFrame **)&colFrame);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void nsTableColGroupFrame::DeleteColFrame(nsIPresContext* aPresContext, nsTableColFrame* aColFrame)
|
||||
{
|
||||
mFrames.DestroyFrame(aPresContext, aColFrame);
|
||||
|
@ -26,7 +26,14 @@
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
|
||||
class nsTableColFrame;
|
||||
class nsTableFrame;
|
||||
enum nsTableColType;
|
||||
|
||||
enum nsTableColGroupType {
|
||||
eColGroupContent = 0, // there is real col group content associated
|
||||
eColGroupAnonymousCol = 1, // the result of a col
|
||||
eColGroupAnonymousCell = 2, // the result of a cell alone
|
||||
};
|
||||
|
||||
/**
|
||||
* nsTableColGroupFrame
|
||||
@ -52,6 +59,16 @@ public:
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList);
|
||||
|
||||
nsTableColGroupType GetType() const;
|
||||
|
||||
void SetType(nsTableColGroupType aType);
|
||||
|
||||
static PRBool GetLastRealColGroup(nsTableFrame* aTableFrame,
|
||||
nsIFrame** aLastColGroup);
|
||||
|
||||
static nsTableColGroupFrame* FindParentForAppendedCol(nsTableFrame* aTableFrame,
|
||||
nsTableColType aColType);
|
||||
|
||||
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
@ -66,6 +83,13 @@ public:
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
void RemoveChild(nsIPresContext& aPresContext,
|
||||
nsTableColFrame& aLastChild,
|
||||
PRBool aResetColIndices);
|
||||
|
||||
void RemoveChildrenAtEnd(nsIPresContext& aPresContext,
|
||||
PRInt32 aNumChildrenToRemove);
|
||||
|
||||
NS_IMETHOD Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
@ -89,6 +113,12 @@ public:
|
||||
*/
|
||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||
|
||||
NS_IMETHOD AddColsToTable(nsIPresContext& aPresContext,
|
||||
PRInt32 aFirstColIndex,
|
||||
PRBool aResetSubsequentColIndices,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame = nsnull);
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
||||
@ -98,7 +128,7 @@ public:
|
||||
* if there are col children, count them (taking into account the span of each)
|
||||
* else, check my own span attribute.
|
||||
*/
|
||||
virtual PRInt32 GetColumnCount();
|
||||
virtual PRInt32 GetColCount() const;
|
||||
|
||||
virtual nsTableColFrame * GetFirstColumn();
|
||||
|
||||
@ -124,23 +154,25 @@ public:
|
||||
|
||||
void DeleteColFrame(nsIPresContext* aPresContext, nsTableColFrame* aColFrame);
|
||||
|
||||
protected:
|
||||
static nsTableColGroupFrame* GetColGroupFrameContaining(nsFrameList& aColGroupList,
|
||||
nsTableColFrame& aColFrame);
|
||||
nsFrameList& GetChildList();
|
||||
|
||||
static void ResetColIndices(nsIFrame* aFirstColGroup,
|
||||
PRInt32 aFirstColIndex,
|
||||
nsIFrame* aStartColFrame = nsnull);
|
||||
protected:
|
||||
nsTableColGroupFrame();
|
||||
|
||||
void InsertColsReflow(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
PRInt32 aColIndex,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame = nsnull);
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
/** Hook for style post processing.
|
||||
* Since we need to know the full column structure before the COLS attribute
|
||||
* can be interpreted, we can't just use DidSetStyleContext
|
||||
*/
|
||||
NS_IMETHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext);
|
||||
|
||||
NS_IMETHOD InitNewFrames(nsIPresContext* aPresContext, nsIFrame* aChildList);
|
||||
NS_IMETHOD AppendNewFrames(nsIPresContext* aPresContext, nsIFrame* aChildList);
|
||||
|
||||
|
||||
NS_IMETHOD IncrementalReflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
@ -174,13 +206,33 @@ protected:
|
||||
/** the starting column index this col group represents. Must be >= 0. */
|
||||
PRInt32 mStartColIndex;
|
||||
|
||||
struct ColGroupBits {
|
||||
unsigned int mType:4;
|
||||
unsigned int mUnused:28;
|
||||
} mBits;
|
||||
|
||||
};
|
||||
|
||||
inline nsTableColGroupFrame::nsTableColGroupFrame()
|
||||
: mColCount(0), mStartColIndex(0)
|
||||
{}
|
||||
{
|
||||
mBits.mType = 0;
|
||||
}
|
||||
|
||||
inline int nsTableColGroupFrame::GetStartColumnIndex ()
|
||||
{ return mStartColIndex;}
|
||||
inline PRInt32 nsTableColGroupFrame::GetStartColumnIndex()
|
||||
{
|
||||
return mStartColIndex;
|
||||
}
|
||||
|
||||
inline PRInt32 nsTableColGroupFrame::GetColCount() const
|
||||
{
|
||||
return mColCount;
|
||||
}
|
||||
|
||||
inline nsFrameList& nsTableColGroupFrame::GetChildList()
|
||||
{
|
||||
return mFrames;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -43,6 +43,8 @@ class nsHTMLValue;
|
||||
struct InnerTableReflowState;
|
||||
struct nsStylePosition;
|
||||
struct nsStyleSpacing;
|
||||
enum nsTableColType;
|
||||
enum nsTableColGroupType;
|
||||
|
||||
/**
|
||||
* Child list name indices
|
||||
@ -124,8 +126,14 @@ public:
|
||||
/** helper method to find the table parent of any table frame object */
|
||||
// TODO: today, this depends on display types. This should be changed to rely
|
||||
// on stronger criteria, like an inner table frame atom
|
||||
static NS_METHOD GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aTableFrame);
|
||||
static NS_METHOD GetTableFrame(nsIFrame* aSourceFrame,
|
||||
nsTableFrame*& aTableFrame);
|
||||
|
||||
// Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
|
||||
// of type aChildType.
|
||||
static nsIFrame* nsTableFrame::GetFrameAtOrBefore(nsIFrame* aParentFrame,
|
||||
nsIFrame* aPriorChildFrame,
|
||||
nsIAtom* aChildType);
|
||||
/**
|
||||
* @param aReflowState the context within which we're to determine the table width info
|
||||
* @param aSpecifiedTableWidth [OUT] if the table is not auto-width,
|
||||
@ -143,10 +151,6 @@ public:
|
||||
PRBool IsRowGroup(PRInt32 aDisplayType) const;
|
||||
|
||||
/** Initialize the table frame with a set of children.
|
||||
* Calls DidAppendRowGroup which calls nsTableRowFrame::InitChildren
|
||||
* which finally calls back into this table frame to build the cell map.
|
||||
* Also ensures we have the right number of column frames for the child list.
|
||||
*
|
||||
* @see nsIFrame::SetInitialChildList
|
||||
*/
|
||||
NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext,
|
||||
@ -162,16 +166,6 @@ public:
|
||||
NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex,
|
||||
nsIAtom** aListName) const;
|
||||
|
||||
/** complete the append of aRowGroupFrame to the table
|
||||
* this builds the cell map by calling nsTableRowFrame::InitChildren
|
||||
* which calls back into this table frame to build the cell map.
|
||||
* @param aRowGroupFrame the row group that was appended.
|
||||
* note that this method is optimized for content appended, and doesn't
|
||||
* work for random insertion of row groups. Random insertion must go
|
||||
* through incremental reflow notifications.
|
||||
*/
|
||||
NS_IMETHOD DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFrame);
|
||||
|
||||
/** @see nsIFrame::Paint */
|
||||
NS_IMETHOD Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
@ -221,6 +215,8 @@ public:
|
||||
*/
|
||||
NS_METHOD GetColumnFrame(PRInt32 aColIndex, nsTableColFrame *&aColFrame);
|
||||
|
||||
nsFrameList& GetColGroups();
|
||||
|
||||
/** return PR_TRUE if the column width information has been set */
|
||||
PRBool IsColumnWidthsSet();
|
||||
|
||||
@ -308,14 +304,84 @@ public:
|
||||
*/
|
||||
PRInt32 GetNextAvailRowIndex() const;
|
||||
|
||||
/** build as much of the CellMap as possible from the info we have so far
|
||||
*/
|
||||
virtual PRInt32 AddCellToTable (nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
virtual void RemoveCellFromTable (nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
/** return the column frame associated with aColIndex */
|
||||
nsTableColFrame* GetColFrame(PRInt32 aColIndex) const;
|
||||
|
||||
virtual void AddColumnFrame (nsTableColFrame *aColFrame);
|
||||
void InsertCol(nsIPresContext& aPresContext,
|
||||
nsTableColFrame& aColFrame,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
nsTableColGroupFrame* CreateAnonymousColGroupFrame(nsIPresContext& aPresContext,
|
||||
nsTableColGroupType aType);
|
||||
|
||||
PRInt32 DestroyAnonymousColFrames(nsIPresContext& aPresContext,
|
||||
PRInt32 aNumFrames);
|
||||
|
||||
void CreateAnonymousColFrames(nsIPresContext& aPresContext,
|
||||
PRInt32 aNumColsToAdd,
|
||||
nsTableColType aColType,
|
||||
PRBool aDoAppend,
|
||||
nsIFrame* aPrevCol = nsnull);
|
||||
|
||||
void CreateAnonymousColFrames(nsIPresContext& aPresContext,
|
||||
nsTableColGroupFrame& aColGroupFrame,
|
||||
PRInt32 aNumColsToAdd,
|
||||
nsTableColType aColType,
|
||||
PRBool aAddToColGroupAndTable,
|
||||
nsIFrame* aPrevCol,
|
||||
nsIFrame** aFirstNewFrame);
|
||||
|
||||
/** empty the column frame cache */
|
||||
void ClearColCache();
|
||||
|
||||
virtual PRInt32 AppendCell(nsIPresContext& aPresContext,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
virtual void InsertCells(nsIPresContext& aPresContext,
|
||||
nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore);
|
||||
|
||||
virtual void RemoveCell(nsIPresContext& aPresContext,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
void AppendRows(nsIPresContext& aPresContext,
|
||||
nsVoidArray& aRowFrames);
|
||||
|
||||
PRInt32 InsertRow(nsIPresContext& aPresContext,
|
||||
nsIFrame& aFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
PRInt32 InsertRows(nsIPresContext& aPresContext,
|
||||
nsVoidArray& aFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
virtual void RemoveRows(nsIPresContext& aPresContext,
|
||||
PRInt32 aFirstRowFrame,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
void AppendRowGroups(nsIPresContext& aPresContext,
|
||||
nsIFrame* aFirstRowGroupFrame);
|
||||
|
||||
void InsertRowGroups(nsIPresContext& aPresContext,
|
||||
nsIFrame* aFirstRowGroupFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
void InsertColGroups(nsIPresContext& aPresContext,
|
||||
PRInt32 aColIndex,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame = nsnull);
|
||||
|
||||
virtual void RemoveCol(nsIPresContext& aPresContext,
|
||||
nsTableColGroupFrame* aColGroupFrame,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aRemoveFromCache,
|
||||
PRBool aRemoveFromCellMap);
|
||||
|
||||
static PRBool IsFinalPass(const nsHTMLReflowState& aReflowState);
|
||||
|
||||
@ -323,7 +389,7 @@ public:
|
||||
PRInt32 aColX,
|
||||
PRBool* aOriginates = nsnull,
|
||||
PRInt32* aColSpan = nsnull);
|
||||
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
|
||||
|
||||
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
|
||||
|
||||
NS_METHOD GetBorderPlusMarginPadding(nsMargin& aResult);
|
||||
@ -554,9 +620,6 @@ protected:
|
||||
/** returns PR_TRUE if the cached pass 1 data is still valid */
|
||||
virtual PRBool IsFirstPassValid() const;
|
||||
|
||||
/** returns PR_TRUE if the cached column info is still valid */
|
||||
virtual PRBool IsColumnCacheValid() const;
|
||||
|
||||
/** returns PR_TRUE if the cached column info is still valid */
|
||||
virtual PRBool IsColumnWidthsValid() const;
|
||||
|
||||
@ -612,8 +675,6 @@ public:
|
||||
|
||||
virtual void InvalidateFirstPassCache();
|
||||
|
||||
virtual void InvalidateColumnCache();
|
||||
|
||||
virtual void InvalidateColumnWidths();
|
||||
|
||||
protected:
|
||||
@ -623,38 +684,18 @@ protected:
|
||||
void MapHTMLBorderStyle(nsStyleSpacing& aSpacingStyle, nscoord aBorderWidth);
|
||||
PRBool ConvertToPixelValue(nsHTMLValue& aValue, PRInt32 aDefault, PRInt32& aResult);
|
||||
|
||||
/** returns PR_TRUE if the cached pass 1 data is still valid */
|
||||
virtual PRBool IsCellMapValid() const;
|
||||
|
||||
public:
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
virtual nsCellMap *GetCellMap() const;
|
||||
|
||||
/** ResetCellMap is called when the cell structure of the table is changed.
|
||||
* Call with caution, only when changing the structure of the table such as
|
||||
* inserting or removing rows, changing the rowspan or colspan attribute of a cell, etc.
|
||||
*/
|
||||
virtual void InvalidateCellMap();
|
||||
|
||||
/** sum the columns represented by all nsTableColGroup objects.
|
||||
* if the cell map says there are more columns than this,
|
||||
* add extra implicit columns to the content tree.
|
||||
*
|
||||
* returns whether any implicit column frames were created
|
||||
*/
|
||||
virtual void EnsureColumns (nsIPresContext* aPresContext,
|
||||
PRBool& aCreatedColFrames);
|
||||
|
||||
// These methods are used to incrementally insert and remove rows
|
||||
// from the cell map without having to invalidate the entire map.
|
||||
NS_IMETHOD InsertRowIntoMap(nsTableRowFrame* aRow, PRInt32 aRowIndex);
|
||||
NS_IMETHOD RemoveRowFromMap(nsTableRowFrame* aRow, PRInt32 aRowIndex);
|
||||
void AdjustRowIndices(PRInt32 aRowIndex,
|
||||
PRInt32 aAdjustment);
|
||||
|
||||
NS_IMETHOD AdjustRowIndices(nsIFrame* aRowGroup,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 anAdjustment);
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 anAdjustment);
|
||||
|
||||
// Return PR_TRUE if rules=groups is set for the table content
|
||||
PRBool HasGroupRules() const;
|
||||
@ -662,9 +703,9 @@ public:
|
||||
// Remove cell borders which aren't bordering row and/or col groups
|
||||
void ProcessGroupRules(nsIPresContext* aPresContext);
|
||||
|
||||
nsVoidArray& GetColCache();
|
||||
|
||||
protected:
|
||||
/** iterates all child frames and creates a new cell map */
|
||||
NS_IMETHOD ReBuildCellMap();
|
||||
|
||||
void SetColumnDimensions(nsIPresContext* aPresContext, nscoord aHeight);
|
||||
|
||||
@ -685,7 +726,14 @@ protected:
|
||||
/**
|
||||
* Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
|
||||
*/
|
||||
nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame, const nsStyleDisplay* aDisplay);
|
||||
nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame,
|
||||
const nsStyleDisplay* aDisplay);
|
||||
|
||||
nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
|
||||
nsIAtom* aFrameTypeIn = nsnull);
|
||||
|
||||
void CollectRows(nsIFrame* aFrame,
|
||||
nsVoidArray& aCollection);
|
||||
|
||||
public: /* ----- Cell Map public methods ----- */
|
||||
|
||||
@ -752,14 +800,16 @@ public: /* ----- Cell Map public methods ----- */
|
||||
|
||||
/*------------end of nsITableLayout methods -----------------------*/
|
||||
|
||||
|
||||
virtual void CacheColFrames(nsIPresContext* aPresContext,
|
||||
PRBool aReset = PR_FALSE);
|
||||
public:
|
||||
static nsIAtom* gColGroupAtom;
|
||||
void Dump(PRBool aDumpCols, PRBool aDumpCellMap);
|
||||
void Dump(PRBool aDumpRows,
|
||||
PRBool aDumpCols,
|
||||
PRBool aDumpCellMap);
|
||||
|
||||
nsVoidArray mColFrames; // XXX temporarily public
|
||||
|
||||
protected:
|
||||
void DumpRowGroup(nsIFrame* aChildFrame);
|
||||
void DebugPrintCount() const; // Debugging routine
|
||||
|
||||
// data members
|
||||
@ -770,15 +820,11 @@ protected:
|
||||
unsigned mColumnWidthsSet:1; // PR_TRUE if column widths have been set at least once
|
||||
unsigned mColumnWidthsValid:1; // PR_TRUE if column width data is still legit, PR_FALSE if it needs to be recalculated
|
||||
unsigned mFirstPassValid:1; // PR_TRUE if first pass data is still legit, PR_FALSE if it needs to be recalculated
|
||||
unsigned mColumnCacheValid:1; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated
|
||||
unsigned mCellMapValid:1; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated
|
||||
unsigned mIsInvariantWidth:1; // PR_TRUE if table width cannot change
|
||||
unsigned mHasScrollableRowGroup:1; // PR_TRUE if any section has overflow == "auto" or "scroll"
|
||||
unsigned mNonPercentSpansPercent:1;
|
||||
int : 24; // unused
|
||||
int : 26; // unused
|
||||
} mBits;
|
||||
|
||||
PRInt32 mColCount; // the number of columns in this table
|
||||
nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
|
||||
nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame
|
||||
nsFrameList mColGroups; // the list of colgroup frames
|
||||
@ -811,6 +857,16 @@ inline void nsTableFrame::SetHasNonPercentSpanningPercent(PRBool aValue)
|
||||
mBits.mNonPercentSpansPercent = (unsigned)aValue;
|
||||
}
|
||||
|
||||
inline nsFrameList& nsTableFrame::GetColGroups()
|
||||
{
|
||||
return mColGroups;
|
||||
}
|
||||
|
||||
inline nsVoidArray& nsTableFrame::GetColCache()
|
||||
{
|
||||
return mColFrames;
|
||||
}
|
||||
|
||||
enum nsTableIteration {
|
||||
eTableLTR = 0,
|
||||
eTableRTL = 1,
|
||||
|
@ -56,6 +56,7 @@ nsTableRowFrame::nsTableRowFrame()
|
||||
mAllBits(0)
|
||||
{
|
||||
mBits.mMinRowSpan = 1;
|
||||
mBits.mRowIndex = 0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -129,23 +130,11 @@ nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == display->mDisplay) {
|
||||
// Add the cell to the cell map
|
||||
PRInt32 colIndex = tableFrame->AddCellToTable((nsTableCellFrame*)childFrame,
|
||||
GetRowIndex());
|
||||
|
||||
// Initialize the cell frame and give it its column index
|
||||
((nsTableCellFrame*)childFrame)->InitCellFrame(colIndex);
|
||||
tableFrame->AppendCell(*aPresContext, (nsTableCellFrame&)*childFrame, GetRowIndex());
|
||||
}
|
||||
}
|
||||
|
||||
// See if any implicit column frames need to be created as a result of
|
||||
// adding the new rows
|
||||
PRBool createdColFrames;
|
||||
tableFrame->EnsureColumns(aPresContext, createdColFrames);
|
||||
if (createdColFrames) {
|
||||
// We need to rebuild the column cache
|
||||
// XXX It would be nice if this could be done incrementally
|
||||
tableFrame->InvalidateColumnCache();
|
||||
}
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
@ -160,6 +149,7 @@ nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
@ -171,26 +161,39 @@ nsTableRowFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
// Insert the frames
|
||||
// gather the new frames (only those which are cells) into an array
|
||||
nsTableCellFrame* prevCellFrame = (nsTableCellFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, nsLayoutAtoms::tableCellFrame);
|
||||
nsVoidArray cellChildren;
|
||||
for (nsIFrame* childFrame = aFrameList; childFrame; childFrame->GetNextSibling(&childFrame)) {
|
||||
nsIAtom* frameType;
|
||||
childFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType) {
|
||||
cellChildren.AppendElement(childFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
// insert the cells into the cell map
|
||||
PRInt32 colIndex = -1;
|
||||
if (prevCellFrame) {
|
||||
prevCellFrame->GetColIndex(colIndex);
|
||||
}
|
||||
tableFrame->InsertCells(*aPresContext, cellChildren, GetRowIndex(), colIndex);
|
||||
|
||||
// Insert the frames in the frame list
|
||||
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't insert
|
||||
// new frames except at the end (append)
|
||||
tableFrame->InvalidateCellMap();
|
||||
// Because the number of columns may have changed invalidate the column widths
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// We should try and avoid doing a pass1 reflow on all the cells and just
|
||||
// do it for the newly added frames, but we need to add these frames to the
|
||||
// cell map before we reflow them
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
if (NS_SUCCEEDED(NS_NewHTMLReflowCommand(&reflowCmd, this,
|
||||
nsIReflowCommand::ReflowDirty))) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -203,91 +206,28 @@ nsTableRowFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
nsIAtom* frameType;
|
||||
aOldFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aOldFrame;
|
||||
PRInt32 colIndex;
|
||||
cellFrame->GetColIndex(colIndex);
|
||||
tableFrame->RemoveCell(*aPresContext, cellFrame, GetRowIndex());
|
||||
|
||||
#if 0
|
||||
// XXX Currently we can't incrementally remove cells from the cell map
|
||||
PRInt32 colIndex;
|
||||
aDeletedFrame->GetColIndex(colIndex);
|
||||
tableFrame->RemoveCellFromTable(aOldFrame, GetRowIndex());
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, (nsIFrame*)aOldFrame);
|
||||
// cells have possibly shifted into different columns.
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// XXX Reflow the row
|
||||
|
||||
#else
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't incrementally
|
||||
// remove rows
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Because we haven't added any new frames we don't need to do a pass1
|
||||
// reflow. Just generate a reflow command so we reflow the table itself
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InitChildrenWithIndex(PRInt32 aRowIndex)
|
||||
{
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
// each child cell can only be added to the table one time.
|
||||
// for now, we remember globally whether we've added all or none
|
||||
if (0 == (mState & NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN))
|
||||
{
|
||||
result = nsTableFrame::GetTableFrame(this, table);
|
||||
if ((NS_OK==result) && (table != nsnull))
|
||||
{
|
||||
mState |= NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN;
|
||||
SetRowIndex(aRowIndex);
|
||||
|
||||
for (nsIFrame* kidFrame = mFrames.FirstChild(); nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
|
||||
{
|
||||
const nsStyleDisplay *kidDisplay;
|
||||
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
|
||||
{
|
||||
// add the cell frame to the table's cell map and get its col index
|
||||
PRInt32 colIndex;
|
||||
colIndex = table->AddCellToTable((nsTableCellFrame *)kidFrame, aRowIndex);
|
||||
// what column does this cell belong to?
|
||||
// this sets the frame's notion of its column index
|
||||
((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
|
||||
}
|
||||
}
|
||||
// Because we haven't added any new frames we don't need to do a pass1
|
||||
// reflow. Just generate a reflow command so we reflow the table itself
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InitChildren()
|
||||
{
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
// each child cell can only be added to the table one time.
|
||||
// for now, we remember globally whether we've added all or none
|
||||
if (0 == (mState & NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN))
|
||||
{
|
||||
result = nsTableFrame::GetTableFrame(this, table);
|
||||
if ((NS_OK==result) && (table != nsnull))
|
||||
{
|
||||
PRInt32 rowIndex = table->GetNextAvailRowIndex();
|
||||
InitChildrenWithIndex(rowIndex);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -62,9 +62,6 @@ struct RowReflowState {
|
||||
/**
|
||||
* Additional frame-state bits
|
||||
*/
|
||||
#define NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN 0x80000000 // set if child cells have been
|
||||
// added to the table
|
||||
|
||||
#define NS_TABLE_MAX_ROW_INDEX (1<<19)
|
||||
|
||||
/**
|
||||
@ -100,12 +97,6 @@ public:
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
/** Initialization of data */
|
||||
NS_IMETHOD InitChildren();
|
||||
NS_IMETHOD InitChildrenWithIndex(PRInt32 aRowIndex);
|
||||
|
||||
void ResetInitChildren();
|
||||
|
||||
/** instantiate a new instance of nsTableRowFrame.
|
||||
* @param aResult the new object is returned in this out-param
|
||||
* @param aContent the table object to map
|
||||
@ -322,11 +313,6 @@ inline void nsTableRowFrame::SetRowIndex (int aRowIndex)
|
||||
mBits.mRowIndex = aRowIndex;
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::ResetInitChildren()
|
||||
{
|
||||
mState &= ~NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN;
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::GetMaxElementSize(nsSize& aMaxElementSize) const
|
||||
{
|
||||
aMaxElementSize.width = mMaxElementSize.width;
|
||||
|
@ -565,6 +565,7 @@ NS_METHOD nsTableRowGroupFrame::PullUpAllRowFrames(nsIPresContext* aPresContext)
|
||||
|
||||
void nsTableRowGroupFrame::GetNextRowSibling(nsIFrame** aRowFrame)
|
||||
{
|
||||
if (!*aRowFrame) return;
|
||||
GetNextFrame(*aRowFrame, aRowFrame);
|
||||
while(*aRowFrame) {
|
||||
const nsStyleDisplay *display;
|
||||
@ -596,7 +597,9 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
PRBool hasRowSpanningCell = PR_FALSE;
|
||||
PRInt32 numRows;
|
||||
GetRowCount(numRows, PR_FALSE);
|
||||
if (numRows <= 0) return;
|
||||
nscoord *rowHeights = new nscoord[numRows];
|
||||
if (!rowHeights) return;
|
||||
nsCRT::memset (rowHeights, 0, numRows*sizeof(nscoord));
|
||||
|
||||
/* Step 1: get the height of the tallest cell in the row and save it for
|
||||
@ -747,10 +750,11 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
// If this is pass 2 then resize the row to its final size and move the
|
||||
// row's position if the previous rows have caused a shift
|
||||
if (1 == counter) {
|
||||
nsRect rowBounds;
|
||||
rowFrame->GetRect(rowBounds);
|
||||
PRBool movedFrame = (deltaY != 0);
|
||||
nsRect rowBounds;
|
||||
|
||||
// Move the row to the correct position
|
||||
rowFrame->GetRect(rowBounds); // added
|
||||
rowBounds.y += deltaY;
|
||||
|
||||
// Adjust our running delta
|
||||
@ -759,6 +763,17 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
// Resize the row to its final size and position
|
||||
rowBounds.height = rowHeights[rowIndex];
|
||||
rowFrame->SetRect(aPresContext, rowBounds);
|
||||
|
||||
if (movedFrame) {
|
||||
// Make sure any views are positioned properly
|
||||
nsIView* view;
|
||||
rowFrame->GetView(aPresContext, &view);
|
||||
if (view) {
|
||||
nsContainerFrame::PositionFrameView(aPresContext, rowFrame, view);
|
||||
} else {
|
||||
nsContainerFrame::PositionChildViews(aPresContext, rowFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rowIndex++;
|
||||
@ -1155,45 +1170,47 @@ nsTableRowGroupFrame::AddTableDirtyReflowCommand(nsIPresContext* aPresContext,
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
|
||||
if (NS_SUCCEEDED(NS_NewHTMLReflowCommand(&reflowCmd, this,
|
||||
nsIReflowCommand::ReflowDirty))) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
#endif
|
||||
|
||||
// this does not get called for trees
|
||||
NS_IMETHODIMP
|
||||
nsTableRowGroupFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
// collect the new row frames in an array
|
||||
nsVoidArray rows;
|
||||
for (nsIFrame* rowFrame = aFrameList; rowFrame; rowFrame->GetNextSibling(&rowFrame)) {
|
||||
nsIAtom* frameType;
|
||||
rowFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableRowFrame == frameType) {
|
||||
rows.AppendElement(rowFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
|
||||
// Append the frames
|
||||
// Append the frames to the sibling chain
|
||||
mFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
const nsStyleDisplay *display;
|
||||
aFrameList->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
// See if the newly appended rows are the last rows in the table.
|
||||
// XXX is this the correct code path for nested row groups, considering that whitespace frames may exist currently
|
||||
if ((NS_STYLE_DISPLAY_TABLE_ROW_GROUP != display->mDisplay) && NoRowsFollow()) {
|
||||
// The rows we appended are the last rows in the table so incrementally
|
||||
// add them to the cell map
|
||||
PRBool haveRows = PR_FALSE;
|
||||
for (nsIFrame* rowFrame = aFrameList; rowFrame; rowFrame->GetNextSibling(&rowFrame)) {
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == display->mDisplay) {
|
||||
DidAppendRow((nsTableRowFrame*)rowFrame);
|
||||
haveRows = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (rows.Count() > 0) {
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
tableFrame->AppendRows(*aPresContext, rows);
|
||||
|
||||
if (haveRows) {
|
||||
// See if any implicit column frames need to be created as a result of
|
||||
// adding the new rows
|
||||
PRBool createdColFrames;
|
||||
tableFrame->EnsureColumns(aPresContext, createdColFrames);
|
||||
if (createdColFrames) {
|
||||
// We need to rebuild the column cache
|
||||
// XXX It would be nice if this could be done incrementally
|
||||
tableFrame->InvalidateColumnCache();
|
||||
}
|
||||
// Because the number of columns may have changed invalidate the column widths
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
@ -1205,29 +1222,12 @@ nsTableRowGroupFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We need to rebuild the cell map, because currently we can't insert
|
||||
// new frames except at the end (append)
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// We should try and avoid doing a pass1 reflow on all the cells and just
|
||||
// do it for the newly added frames, but we need to add these frames to the
|
||||
// cell map before we reflow them
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// this does not get called for trees
|
||||
NS_IMETHODIMP
|
||||
nsTableRowGroupFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
@ -1235,65 +1235,76 @@ nsTableRowGroupFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
// collect the new row frames in an array
|
||||
nsVoidArray rows;
|
||||
for (nsIFrame* rowFrame = aFrameList; rowFrame; rowFrame->GetNextSibling(&rowFrame)) {
|
||||
nsIAtom* frameType;
|
||||
rowFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableRowFrame == frameType) {
|
||||
rows.AppendElement(rowFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
|
||||
// Insert the frames
|
||||
// Insert the frames in the sibling chain
|
||||
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't insert
|
||||
// new frames except at the end (append)
|
||||
tableFrame->InvalidateCellMap();
|
||||
if (rows.Count() > 0) {
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
nsTableRowFrame* prevRow = (nsTableRowFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, nsLayoutAtoms::tableRowFrame);
|
||||
PRInt32 rowIndex = (prevRow) ? prevRow->GetRowIndex() : 0;
|
||||
tableFrame->InsertRows(*aPresContext, rows, rowIndex, PR_TRUE);
|
||||
|
||||
// We should try and avoid doing a pass1 reflow on all the cells and just
|
||||
// do it for the newly added frames, but we need to add these frames to the
|
||||
// cell map before we reflow them
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
if (NS_SUCCEEDED(NS_NewHTMLReflowCommand(&reflowCmd, this,
|
||||
nsIReflowCommand::ReflowDirty))) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
|
||||
// Because the number of columns may have changed invalidate the column widths
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// this does not get called for trees
|
||||
NS_IMETHODIMP
|
||||
nsTableRowGroupFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
aOldFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
PRBool validChild = (NS_STYLE_DISPLAY_TABLE_ROW == display->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == display->mDisplay);
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
nsIAtom* frameType;
|
||||
aOldFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableRowFrame == frameType) {
|
||||
PRInt32 firstRowIndex = ((nsTableRowFrame *)aOldFrame)->GetRowIndex();
|
||||
|
||||
// Remove the frame and destroy it
|
||||
if (mFrames.DestroyFrame(aPresContext, aOldFrame)) {
|
||||
if (validChild) {
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't incrementally
|
||||
// remove rows
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
tableFrame->RemoveRows(*aPresContext, firstRowIndex, 1, PR_TRUE);
|
||||
// Because the number of columns may have changed invalidate the column widths
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Because we haven't added any new frames we don't need to do a pass1
|
||||
// reflow. Just generate a reflow command so we reflow the table itself
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1350,54 +1361,6 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext* aPresContext,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
/* need to make space in the cell map. Remeber that row spans can't cross row groups
|
||||
once the space is made, tell the row to initizalize its children.
|
||||
it will automatically find the row to initialize into.
|
||||
but this is tough because a cell in aInsertedFrame could have a rowspan
|
||||
which must be respected if a subsequent row is appended.
|
||||
*/
|
||||
rv = aRowFrame->InitChildren();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// support method that tells us if there are any rows in the table after our rows
|
||||
// returns PR_TRUE if there are no rows after ours
|
||||
PRBool nsTableRowGroupFrame::NoRowsFollow()
|
||||
{
|
||||
// XXX This method doesn't play well with the tree widget.
|
||||
PRBool result = PR_TRUE;
|
||||
nsIFrame *nextSib=nsnull;
|
||||
GetNextSibling(&nextSib);
|
||||
while (nsnull!=nextSib)
|
||||
{
|
||||
const nsStyleDisplay *sibDisplay;
|
||||
nextSib->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)sibDisplay));
|
||||
if ((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == sibDisplay->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == sibDisplay->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == sibDisplay->mDisplay))
|
||||
{
|
||||
nsIFrame *childFrame=nsnull;
|
||||
nextSib->FirstChild(nsnull, &childFrame);
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{ // found a row
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
}
|
||||
nextSib->GetNextSibling(&nextSib);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::GetHeightOfRows(nscoord& aResult)
|
||||
{
|
||||
// the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
|
||||
|
@ -244,10 +244,6 @@ protected:
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD DidAppendRow(nsTableRowFrame *aRowFrame);
|
||||
|
||||
PRBool NoRowsFollow();
|
||||
|
||||
nsresult AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
|
@ -59,17 +59,6 @@ PRBool CanAllocate(PRInt32 aTypeToAllocate,
|
||||
|
||||
/* ---------- BasicTableLayoutStrategy ---------- */
|
||||
|
||||
/* return true if the style indicates that the width is fixed
|
||||
* for the purposes of column width determination
|
||||
*/
|
||||
inline
|
||||
PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosition,
|
||||
const nsStyleTable* aStyleTable)
|
||||
{
|
||||
return PRBool ((eStyleUnit_Coord==aStylePosition->mWidth.GetUnit()) ||
|
||||
(eStyleUnit_Coord==aStyleTable->mSpanWidth.GetUnit()));
|
||||
}
|
||||
|
||||
MOZ_DECL_CTOR_COUNTER(BasicTableLayoutStrategy);
|
||||
|
||||
|
||||
@ -90,8 +79,7 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
|
||||
MOZ_COUNT_DTOR(BasicTableLayoutStrategy);
|
||||
}
|
||||
|
||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||
PRInt32 aNumCols,
|
||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||
nscoord aMaxWidth)
|
||||
{
|
||||
ContinuingFrameCheck();
|
||||
@ -99,12 +87,10 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
// re-init instance variables
|
||||
mNumCols = aNumCols;
|
||||
mMinTableContentWidth = 0;
|
||||
mMaxTableContentWidth = 0;
|
||||
mCellSpacingTotal = 0;
|
||||
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
||||
|
||||
// assign the width of all fixed-width columns
|
||||
AssignPreliminaryColumnWidths(aMaxWidth);
|
||||
|
||||
@ -157,7 +143,7 @@ PRBool BCW_Wrapup(BasicTableLayoutStrategy* aStrategy,
|
||||
{
|
||||
if (aAllocTypes)
|
||||
delete [] aAllocTypes;
|
||||
if (gsDebugBalance) {printf("BalanceColumnWidths ex \n"); aTableFrame->Dump(PR_TRUE, PR_FALSE);}
|
||||
if (gsDebugBalance) {printf("BalanceColumnWidths ex \n"); aTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@ -176,7 +162,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aMaxWidthIn)
|
||||
{
|
||||
if (gsDebugBalance) {printf("BalanceColumnWidths en max=%d\n", aMaxWidthIn); mTableFrame->Dump(PR_TRUE, PR_FALSE);}
|
||||
if (gsDebugBalance) {printf("BalanceColumnWidths en max=%d\n", aMaxWidthIn); mTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);}
|
||||
|
||||
ContinuingFrameCheck();
|
||||
if (!aTableStyle) {
|
||||
@ -184,6 +170,8 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
|
||||
// determine if the table is auto/fixed and get the fixed width if available
|
||||
nscoord maxWidth = aMaxWidthIn;
|
||||
nscoord specifiedTableWidth = 0;
|
||||
@ -204,7 +192,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
}
|
||||
// initialize the col percent and cell percent values to 0.
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
colFrame->SetWidth(PCT, WIDTH_NOT_SET);
|
||||
colFrame->SetWidth(PCT_ADJ, WIDTH_NOT_SET);
|
||||
@ -220,7 +208,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
|
||||
PRBool recomputedAdjMin = RecomputeAdjMinIfNecessary();
|
||||
// set the table's columns to the min width
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord colMinWidth = colFrame->GetMinWidth();
|
||||
mTableFrame->SetColumnWidth(colX, colMinWidth);
|
||||
@ -257,10 +245,10 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
nscoord totalAllocated = totalWidths[MIN_CON] + cellSpacingTotal;
|
||||
|
||||
// allocate and initialize arrays indicating what col gets set
|
||||
PRInt32* allocTypes = new PRInt32[mNumCols];
|
||||
PRInt32* allocTypes = new PRInt32[numCols];
|
||||
if (!allocTypes) return PR_FALSE;
|
||||
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
allocTypes[colX] = -1;
|
||||
}
|
||||
|
||||
@ -330,9 +318,9 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
PRBool skip0Proportional = totalCounts[DES_CON] > num0Proportional;
|
||||
if ( (tableIsAutoWidth && (perAdjTableWidth - totalAllocated > 0)) ||
|
||||
(!tableIsAutoWidth && (totalAllocated < maxWidth)) ) {
|
||||
if (totalCounts[PCT] != mNumCols) {
|
||||
if (totalCounts[PCT] != numCols) {
|
||||
//PRBool onlyAuto = (totalCounts[DES_CON] > 0) && !mIsNavQuirksMode;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (PCT == allocTypes[colX]) {
|
||||
allocTypes[colX] = -1;
|
||||
}
|
||||
@ -350,7 +338,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aTableSty
|
||||
}
|
||||
// give the proportional cols the rest up to the max width in quirks mode
|
||||
else if (tableIsAutoWidth && mIsNavQuirksMode && (totalCounts[MIN_PRO] > 0)) {
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (DES_CON != allocTypes[colX]) {
|
||||
allocTypes[colX] = -1;
|
||||
}
|
||||
@ -369,7 +357,8 @@ void BasicTableLayoutStrategy::AllocateFully(nscoord& aTotalAllocated,
|
||||
PRInt32 aWidthType,
|
||||
PRBool aMarkAllocated)
|
||||
{
|
||||
for (PRInt32 colX = 0; colX < mNumCols; colX++) {
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord oldWidth = mTableFrame->GetColumnWidth(colX);
|
||||
nscoord newWidth = colFrame->GetWidth(aWidthType);
|
||||
@ -408,13 +397,14 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
|
||||
PRInt32 numColsAllocated = 0;
|
||||
PRInt32 totalAllocated = 0;
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (-1 != aAllocTypes[colX]) {
|
||||
divisor += mTableFrame->GetColumnWidth(colX);
|
||||
numColsAllocated++;
|
||||
}
|
||||
}
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (-1 != aAllocTypes[colX]) {
|
||||
if (aSkip0Proportional) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
@ -703,9 +693,10 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
|
||||
// and calculate min/max table width
|
||||
PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth)
|
||||
{
|
||||
if (gsDebugAssign) {printf("AssignPrelimColWidths en max=%d\n", aMaxWidth); mTableFrame->Dump(PR_TRUE, PR_FALSE);}
|
||||
if (gsDebugAssign) {printf("AssignPrelimColWidths en max=%d\n", aMaxWidth); mTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);}
|
||||
PRBool rv = PR_FALSE;
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
PRInt32 colX, rowX;
|
||||
mCellSpacingTotal = 0;
|
||||
@ -713,12 +704,12 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
PRInt32 propTotal = 0; // total of numbers of the type 1*, 2*, etc
|
||||
PRInt32 numColsForColsAttr = 0; // Nav Quirks cols attribute for equal width cols
|
||||
if (NS_STYLE_TABLE_COLS_NONE != mCols) {
|
||||
numColsForColsAttr = (NS_STYLE_TABLE_COLS_ALL == mCols) ? mNumCols : mCols;
|
||||
numColsForColsAttr = (NS_STYLE_TABLE_COLS_ALL == mCols) ? numCols : mCols;
|
||||
}
|
||||
|
||||
// For every column, determine it's min and desired width based on cell style
|
||||
// base on cells which do not span cols. Also, determine mCellSpacingTotal
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nscoord minWidth = 0;
|
||||
nscoord desWidth = 0;
|
||||
nscoord fixWidth = WIDTH_NOT_SET;
|
||||
@ -794,6 +785,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
// proportional width on a col or Nav Quirks cols attr
|
||||
if (fixWidth <= 0) {
|
||||
nscoord proportion = WIDTH_NOT_SET;
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)colPosition);
|
||||
if (eStyleUnit_Proportional == colPosition->mWidth.GetUnit()) {
|
||||
@ -806,6 +798,19 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
proportion = WIDTH_NOT_SET;
|
||||
}
|
||||
}
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
if (eStyleUnit_Proportional == colStyleWidth.GetUnit()) {
|
||||
proportion = colStyleWidth.GetIntValue();
|
||||
}
|
||||
else if (colX < numColsForColsAttr) {
|
||||
proportion = 1;
|
||||
if ((eStyleUnit_Percent == colStyleWidth.GetUnit()) &&
|
||||
(colStyleWidth.GetPercentValue() > 0.0f)) {
|
||||
proportion = WIDTH_NOT_SET;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (proportion >= 0) {
|
||||
colFrame->SetWidth(MIN_PRO, proportion);
|
||||
if (proportion > 0) {
|
||||
@ -831,7 +836,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
nscoord minPropTotal = 0;
|
||||
nscoord desPropTotal = 0;
|
||||
// figure the totals of all proportional cols which support every min and desired width
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord colProp = colFrame->GetWidth(MIN_PRO);
|
||||
if (colProp > 0) {
|
||||
@ -846,7 +851,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
mMinToDesProportionRatio = ((float)desPropTotal) / ((float)minPropTotal);
|
||||
}
|
||||
// figure the cols proportional min width based on the new totals
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord colProp = colFrame->GetWidth(MIN_PRO);
|
||||
if (colProp > 0) {
|
||||
@ -861,7 +866,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
// Adjust the cols that each cell spans if necessary. Iterate backwards
|
||||
// so that nested and/or overlaping col spans handle the inner ones first,
|
||||
// ensuring more accurated calculations.
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
for (rowX = 0; rowX < numRows; rowX++) {
|
||||
PRBool originates;
|
||||
PRInt32 colSpan;
|
||||
@ -878,11 +883,12 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
|
||||
// Set the col's fixed width if present
|
||||
// Set the table col width for each col to the content min.
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord fixColWidth = colFrame->GetWidth(FIX);
|
||||
// use the style width of a col only if the col hasn't gotten a fixed width from any cell
|
||||
if (fixColWidth <= 0) {
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)colPosition);
|
||||
if (eStyleUnit_Coord == colPosition->mWidth.GetUnit()) {
|
||||
@ -891,13 +897,22 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth
|
||||
colFrame->SetWidth(FIX, fixColWidth);
|
||||
}
|
||||
}
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
if (eStyleUnit_Coord == colStyleWidth.GetUnit()) {
|
||||
fixColWidth = colStyleWidth.GetCoordValue();
|
||||
if (fixColWidth > 0) {
|
||||
colFrame->SetWidth(FIX, fixColWidth);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
nscoord minWidth = colFrame->GetMinWidth();
|
||||
mTableFrame->SetColumnWidth(colX, minWidth);
|
||||
}
|
||||
SetMinAndMaxTableContentWidths();
|
||||
|
||||
if (gsDebugAssign) {printf("AssignPrelimColWidths ex\n"); mTableFrame->Dump(PR_TRUE, PR_FALSE);}
|
||||
if (gsDebugAssign) {printf("AssignPrelimColWidths ex\n"); mTableFrame->Dump(PR_FALSE, PR_TRUE, PR_FALSE);}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -906,6 +921,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
PRBool aTableIsAutoWidth)
|
||||
{
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
PRInt32 colX, rowX;
|
||||
nscoord basis = aBasisIn;
|
||||
@ -918,7 +934,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
PRInt32 numPerCols = 0; // number of colums that have percentage constraints
|
||||
nscoord prefWidthTotal = 0;// total of des/fix widths of cols that don't have percentage constraints
|
||||
basis = 0; // basis to use for percentages, computed considering percentage values
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord colBasis = -1;
|
||||
// Scan the cells in the col
|
||||
@ -950,6 +966,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
}
|
||||
if (-1 == colBasis) {
|
||||
// see if the col has a style percent width specified
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)colPosition);
|
||||
if (eStyleUnit_Percent == colPosition->mWidth.GetUnit()) {
|
||||
@ -960,6 +977,17 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
colBasis = NSToCoordRound((float)desWidth / percent);
|
||||
}
|
||||
}
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
if (eStyleUnit_Percent == colStyleWidth.GetUnit()) {
|
||||
float percent = colStyleWidth.GetPercentValue();
|
||||
colBasis = 0;
|
||||
if (percent > 0.0f) {
|
||||
nscoord desWidth = colFrame->GetDesWidth();
|
||||
colBasis = NSToCoordRound((float)desWidth / percent);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
basis = PR_MAX(basis, colBasis);
|
||||
nscoord fixWidth = colFrame->GetFixWidth();
|
||||
@ -976,7 +1004,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
return 0;
|
||||
}
|
||||
// If there is only one col and it is % based, it won't affect anything
|
||||
if ((1 == mNumCols) && (mNumCols == numPerCols)) {
|
||||
if ((1 == numCols) && (numCols == numPerCols)) {
|
||||
return 0;
|
||||
}
|
||||
// compute a basis considering total percentages and the desired width of everything else
|
||||
@ -995,12 +1023,12 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
}
|
||||
|
||||
nscoord colPctTotal = 0;
|
||||
nscoord* colPcts = new nscoord[mNumCols];
|
||||
nscoord* colPcts = new nscoord[numCols];
|
||||
if (!colPcts) return 0;
|
||||
|
||||
// Determine the percentage contribution for cols and for cells with colspan = 1
|
||||
// Iterate backwards, similarly to the reasoning in AssignPreliminaryColumnWidths
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord maxColPctWidth = WIDTH_NOT_SET;
|
||||
float maxColPct = 0.0f;
|
||||
@ -1039,12 +1067,20 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
}
|
||||
if (WIDTH_NOT_SET == maxColPctWidth) {
|
||||
// see if the col has a style percent width specified
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)colPosition);
|
||||
if (eStyleUnit_Percent == colPosition->mWidth.GetUnit()) {
|
||||
maxColPct = colPosition->mWidth.GetPercentValue();
|
||||
maxColPctWidth = NSToCoordRound( ((float)basis) * maxColPct );
|
||||
}
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
if (eStyleUnit_Percent == colStyleWidth.GetUnit()) {
|
||||
maxColPct = colStyleWidth.GetPercentValue();
|
||||
maxColPctWidth = NSToCoordRound( ((float)basis) * maxColPct );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// conflicting pct/fixed widths are recorded. Nav 4.x may be changing the
|
||||
// fixed width value if it exceeds the pct value and not recording the pct
|
||||
@ -1066,7 +1102,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
|
||||
// For each col, consider the cells originating in it with colspans > 1.
|
||||
// Adjust the cols that each cell spans if necessary.
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
for (rowX = 0; rowX < numRows; rowX++) {
|
||||
PRBool originates;
|
||||
PRInt32 colSpan;
|
||||
@ -1162,7 +1198,7 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
|
||||
// if the percent total went over 100%, adjustments need to be made to right most cols
|
||||
if (colPctTotal > 100) {
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
if (colPcts[colX] > 0) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nscoord newPct = colPcts[colX] - (colPctTotal - 100);
|
||||
@ -1197,10 +1233,11 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
|
||||
PRBool BasicTableLayoutStrategy::RecomputeAdjMinIfNecessary()
|
||||
{
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
PRInt32 colX, rowX, spanX;
|
||||
|
||||
PRBool spansPercent = PR_FALSE;
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
for (rowX = 0; rowX < numRows; rowX++) {
|
||||
PRBool originates;
|
||||
PRInt32 colSpan;
|
||||
@ -1233,7 +1270,7 @@ PRBool BasicTableLayoutStrategy::RecomputeAdjMinIfNecessary()
|
||||
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
|
||||
for (colX = mNumCols - 1; colX >= 0; colX--) {
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
for (rowX = 0; rowX < numRows; rowX++) {
|
||||
PRBool originates;
|
||||
PRInt32 colSpan;
|
||||
@ -1267,7 +1304,8 @@ void BasicTableLayoutStrategy::SetMinAndMaxTableContentWidths()
|
||||
mMaxTableContentWidth = 0;
|
||||
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
for (PRInt32 colX = 0; colX < mNumCols; colX++) {
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
mMinTableContentWidth += colFrame->GetMinWidth();
|
||||
mMaxTableContentWidth += PR_MAX(colFrame->GetDesWidth(), colFrame->GetFixWidth());
|
||||
@ -1302,7 +1340,8 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing,
|
||||
a0ProportionalCount = 0;
|
||||
|
||||
nscoord spacingX = mTableFrame->GetCellSpacingX();
|
||||
for (PRInt32 colX = 0; colX < mNumCols; colX++) {
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) {
|
||||
aCellSpacing += spacingX;
|
||||
@ -1387,7 +1426,7 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing,
|
||||
aMinWidths[DES_CON] += minCol;
|
||||
}
|
||||
// if it is not a degenerate table, add the last spacing on the right
|
||||
if (mNumCols > 0) {
|
||||
if (numCols > 0) {
|
||||
aCellSpacing += spacingX;
|
||||
}
|
||||
}
|
||||
@ -1508,11 +1547,12 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth,
|
||||
return;
|
||||
}
|
||||
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
PRInt32 numConstrainedCols = 0;
|
||||
nscoord sumMaxConstraints = 0;
|
||||
PRBool useAdj = PR_TRUE;
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) {
|
||||
if (-1 != aAllocTypes[colX]) {
|
||||
@ -1539,7 +1579,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth,
|
||||
PRInt32 maxMinDiff = 0;
|
||||
PRInt32 constrColX = 0;
|
||||
// set the col info entries for each constrained col
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) {
|
||||
if (-1 != aAllocTypes[colX]) {
|
||||
@ -1810,11 +1850,16 @@ PRBool BasicTableLayoutStrategy::ColIsSpecifiedAsMinimumWidth(PRInt32 aColIndex)
|
||||
PRBool result = PR_FALSE;
|
||||
nsTableColFrame* colFrame;
|
||||
mTableFrame->GetColumnFrame(aColIndex, colFrame);
|
||||
#ifdef foobar
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)colPosition);
|
||||
switch (colPosition->mWidth.GetUnit()) {
|
||||
#else
|
||||
nsStyleCoord colStyleWidth = colFrame->GetStyleWidth();
|
||||
switch (colStyleWidth.GetUnit()) {
|
||||
#endif
|
||||
case eStyleUnit_Coord:
|
||||
if (0 == colPosition->mWidth.GetCoordValue()) {
|
||||
if (0 == colStyleWidth.GetCoordValue()) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
@ -1823,14 +1868,14 @@ PRBool BasicTableLayoutStrategy::ColIsSpecifiedAsMinimumWidth(PRInt32 aColIndex)
|
||||
// total hack for now for 0% and 1% specifications
|
||||
// should compare percent to available parent width and see that it is below minimum
|
||||
// for this column
|
||||
float percent = colPosition->mWidth.GetPercentValue();
|
||||
float percent = colStyleWidth.GetPercentValue();
|
||||
if (0.0f == percent || 0.01f == percent) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eStyleUnit_Proportional:
|
||||
if (0 == colPosition->mWidth.GetIntValue()) {
|
||||
if (0 == colStyleWidth.GetIntValue()) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
|
||||
@ -1849,8 +1894,8 @@ void BasicTableLayoutStrategy::Dump(PRInt32 aIndent)
|
||||
}
|
||||
indent[aIndent] = 0;
|
||||
|
||||
printf("%s**START BASIC STRATEGY DUMP** table=%p cols=%X numCols=%d",
|
||||
indent, mTableFrame, mCols, mNumCols);
|
||||
printf("%s**START BASIC STRATEGY DUMP** table=%p cols=%X",
|
||||
indent, mTableFrame, mCols);
|
||||
printf("\n%s minConWidth=%d maxConWidth=%d cellSpacing=%d propRatio=%.2f navQuirks=%d",
|
||||
indent, mMinTableContentWidth, mMaxTableContentWidth, mCellSpacingTotal, mMinToDesProportionRatio, mIsNavQuirksMode);
|
||||
printf(" **END BASIC STRATEGY DUMP** \n");
|
||||
|
@ -57,11 +57,9 @@ public:
|
||||
/** call every time any table thing changes that might effect the width of any column
|
||||
* in the table (content, structure, or style)
|
||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize,
|
||||
PRInt32 aNumCols,
|
||||
nscoord aMaxSize);
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize,
|
||||
nscoord aMaxSize);
|
||||
|
||||
/** compute the max element size of the table.
|
||||
* assumes that Initialize has been called
|
||||
@ -83,7 +81,6 @@ public:
|
||||
nscoord GetTableMinContentWidth() const;
|
||||
nscoord GetTableMaxContentWidth() const;
|
||||
nscoord GetCOLSAttribute() const;
|
||||
nscoord GetNumCols() const;
|
||||
void Dump(PRInt32 aIndent);
|
||||
|
||||
protected:
|
||||
@ -159,13 +156,6 @@ protected:
|
||||
PRInt32* aAllocTypes,
|
||||
PRBool aSkip0Proportional);
|
||||
|
||||
/** return true if the style indicates that the width is a specific width
|
||||
* for the purposes of column width determination.
|
||||
* return false if the width changes based on content, parent size, etc.
|
||||
*/
|
||||
static PRBool IsFixedWidth(const nsStylePosition* aStylePosition,
|
||||
const nsStyleTable* aStyleTable);
|
||||
|
||||
/** return true if the colIndex is in the list of colIndexes */
|
||||
virtual PRBool IsColumnInList(const PRInt32 colIndex,
|
||||
PRInt32 *colIndexes,
|
||||
@ -214,7 +204,6 @@ protected:
|
||||
protected:
|
||||
nsTableFrame * mTableFrame;
|
||||
PRInt32 mCols;
|
||||
PRInt32 mNumCols;
|
||||
// cached data
|
||||
nscoord mMinTableContentWidth; // the smallest size for the table (excluding border and padding)
|
||||
nscoord mMaxTableContentWidth; // the "natural" size for the table, if unconstrained (excluding border and padding)
|
||||
@ -233,9 +222,6 @@ inline nscoord BasicTableLayoutStrategy::GetTableMaxContentWidth() const
|
||||
inline nscoord BasicTableLayoutStrategy::GetCOLSAttribute() const
|
||||
{ return mCols; };
|
||||
|
||||
inline nscoord BasicTableLayoutStrategy::GetNumCols() const
|
||||
{ return mNumCols; };
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -59,7 +59,6 @@ PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext* aT
|
||||
PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputedWidth)
|
||||
{
|
||||
// NS_ASSERTION(aComputedWidth != NS_UNCONSTRAINEDSIZE, "bad computed width");
|
||||
|
||||
const nsStylePosition* tablePosition;
|
||||
mTableFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)tablePosition);
|
||||
PRBool tableIsFixedWidth = eStyleUnit_Coord == tablePosition->mWidth.GetUnit() ||
|
||||
@ -70,24 +69,25 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
nsMargin borderPadding;
|
||||
tableSpacing->CalcBorderPaddingFor(mTableFrame, borderPadding);
|
||||
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
PRInt32 colX;
|
||||
// availWidth is used as the basis for percentage width columns. It is aComputedWidth
|
||||
// minus table border, padding, & cellspacing
|
||||
nscoord availWidth = aComputedWidth - borderPadding.left - borderPadding.right -
|
||||
((mNumCols + 1) * mTableFrame->GetCellSpacingX());
|
||||
((numCols + 1) * mTableFrame->GetCellSpacingX());
|
||||
|
||||
PRInt32 specifiedCols = 0; // the number of columns whose width is given
|
||||
nscoord totalColWidth = 0; // the sum of the widths of the columns
|
||||
|
||||
nscoord* colWidths = new PRBool[mNumCols];
|
||||
nsCRT::memset(colWidths, WIDTH_NOT_SET, mNumCols*sizeof(nscoord));
|
||||
nscoord* colWidths = new PRBool[numCols];
|
||||
nsCRT::memset(colWidths, WIDTH_NOT_SET, numCols*sizeof(nscoord));
|
||||
|
||||
nscoord* propInfo = new PRBool[mNumCols];
|
||||
nsCRT::memset(propInfo, 0, mNumCols*sizeof(nscoord));
|
||||
nscoord* propInfo = new PRBool[numCols];
|
||||
nsCRT::memset(propInfo, 0, numCols*sizeof(nscoord));
|
||||
nscoord propTotal = 0;
|
||||
|
||||
// for every column, determine its specified width
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
// Get column information
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
if (!colFrame) {
|
||||
@ -115,6 +115,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
propTotal += propInfo[colX];
|
||||
}
|
||||
else { // get width from the cell
|
||||
|
||||
nsTableCellFrame* cellFrame = mTableFrame->GetCellFrameAt(0, colX);
|
||||
if (nsnull != cellFrame) {
|
||||
// Get the cell's style
|
||||
@ -148,7 +149,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
|
||||
if (0 < remainingWidth) {
|
||||
if (propTotal > 0) {
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (propInfo[colX] > 0) {
|
||||
// We're proportional
|
||||
float percent = ((float)propInfo[colX])/((float)propTotal);
|
||||
@ -159,10 +160,10 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
}
|
||||
}
|
||||
else if (tableIsFixedWidth) {
|
||||
if (mNumCols > specifiedCols) {
|
||||
if (numCols > specifiedCols) {
|
||||
// allocate the extra space to the columns which have no width specified
|
||||
nscoord colAlloc = NSToCoordRound( ((float)remainingWidth) / (((float)mNumCols) - ((float)specifiedCols)));
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
nscoord colAlloc = NSToCoordRound( ((float)remainingWidth) / (((float)numCols) - ((float)specifiedCols)));
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (-1 == colWidths[colX]) {
|
||||
colWidths[colX] = colAlloc;
|
||||
totalColWidth += colAlloc;
|
||||
@ -172,7 +173,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
}
|
||||
else { // allocate the extra space to the columns which have width specified
|
||||
float divisor = (float)totalColWidth;
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (colWidths[colX] > 0) {
|
||||
nscoord colAlloc = NSToCoordRound(remainingWidth * colWidths[colX] / divisor);
|
||||
colWidths[colX] += colAlloc;
|
||||
@ -187,7 +188,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputed
|
||||
nscoord overAllocation = (availWidth >= 0)
|
||||
? totalColWidth - availWidth : 0;
|
||||
// set the column widths
|
||||
for (colX = 0; colX < mNumCols; colX++) {
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (colWidths[colX] < 0)
|
||||
colWidths[colX] = 0;
|
||||
// if there was too much allocated due to rounding, remove it from the last col
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,6 +27,22 @@
|
||||
#include "nsVoidArray.h"
|
||||
class nsTableColFrame;
|
||||
class nsTableCellFrame;
|
||||
class nsIPresContext;
|
||||
|
||||
// XXX the collapsing row and col data structures need to be moved
|
||||
// into nsTableFrame. Collapsing cols are broken due to the recent
|
||||
// incremental cell map methods which don't attempt to update
|
||||
// collapsing col info here.
|
||||
|
||||
struct nsColInfo
|
||||
{
|
||||
PRInt32 mNumCellsOrig; // number of cells originating in the col
|
||||
PRInt32 mNumCellsSpan; // number of cells spanning into the col via colspans (not rowspans)
|
||||
|
||||
nsColInfo();
|
||||
nsColInfo(PRInt32 aNumCellsOrig,
|
||||
PRInt32 aNumCellsSpan);
|
||||
};
|
||||
|
||||
/** nsCellMap is a support class for nsTablePart.
|
||||
* It maintains an Rows x Columns grid onto which the cells of the table are mapped.
|
||||
@ -60,23 +76,29 @@ public:
|
||||
CellData* GetCellAt(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex) const;
|
||||
|
||||
/** insert a new row into the map
|
||||
makes a blank row and adjusts spans
|
||||
*/
|
||||
void InsertRowIntoMap(PRInt32 aRowIndex);
|
||||
|
||||
/** removes a row from the map and adjusts spans
|
||||
*/
|
||||
void RemoveRowFromMap(PRInt32 aRowIndex);
|
||||
void AppendCol();
|
||||
|
||||
/** append the cellFrame at the end of the row at aRowIndex and return the col index
|
||||
*/
|
||||
PRInt32 AppendCell(nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary);
|
||||
|
||||
void InsertCells(nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore);
|
||||
|
||||
void RemoveCell(nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
void InsertRows(nsVoidArray& aRows,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
void RemoveRows(PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
PRInt32 GetNextAvailRowIndex();
|
||||
|
||||
PRInt32 GetEffectiveColSpan(nsTableCellFrame* aCell) const;
|
||||
@ -102,17 +124,6 @@ public:
|
||||
/** return the actual number of rows in the table represented by this CellMap */
|
||||
PRInt32 GetRowCount() const;
|
||||
|
||||
/** return the column frame associated with aColIndex */
|
||||
nsTableColFrame* GetColumnFrame(PRInt32 aColIndex) const;
|
||||
|
||||
/** add a column frame to the list of column frames
|
||||
* column frames must be added in order
|
||||
*/
|
||||
void AppendColumnFrame(nsTableColFrame *aColFrame);
|
||||
|
||||
/** empty the column frame cache */
|
||||
void ClearColumnCache();
|
||||
|
||||
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
|
||||
nsTableCellFrame* GetCellFrameOriginatingAt(PRInt32 aRowX,
|
||||
PRInt32 aColX) const;
|
||||
@ -123,6 +134,7 @@ public:
|
||||
PRInt32* aColSpan = nsnull) const;
|
||||
|
||||
void AddColsAtEnd(PRUint32 aNumCols);
|
||||
PRInt32 RemoveUnusedCols(PRInt32 aMaxNumToRemove);
|
||||
|
||||
PRBool RowIsSpannedInto(PRInt32 aRowIndex) const;
|
||||
PRBool RowHasSpanningCells(PRInt32 aRowIndex) const;
|
||||
@ -156,23 +168,48 @@ protected:
|
||||
CellData* GetMapCellAt(PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex) const;
|
||||
|
||||
PRInt32 GetNumCellsIn(PRInt32 aColIndex,
|
||||
PRBool aOriginating) const;
|
||||
PRInt32 GetNumCellsIn(PRInt32 aColIndex) const;
|
||||
|
||||
void ExpandWithRows(nsVoidArray& aRowFrames,
|
||||
PRInt32 aStartRowIndex);
|
||||
|
||||
void ExpandWithCells(nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRInt32 aRowSpan);
|
||||
|
||||
void ShrinkWithoutRows(PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove);
|
||||
|
||||
void ShrinkWithoutCell(nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
void RebuildConsideringRows(PRInt32 aStartRowIndex,
|
||||
nsVoidArray* aRowsToInsert,
|
||||
PRInt32 aNumRowsToRemove = 0);
|
||||
|
||||
void RebuildConsideringCells(nsVoidArray* aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aInsert);
|
||||
|
||||
PRBool CellsSpanOut(nsVoidArray& aNewRows);
|
||||
|
||||
PRBool CellsSpanInOrOut(PRInt32 aStartRowIndex,
|
||||
PRInt32 aEndRowIndex,
|
||||
PRInt32 aStartColIndex,
|
||||
PRInt32 aEndColIndex);
|
||||
|
||||
PRBool CreateEmptyRow(PRInt32 aRowIndex,
|
||||
PRInt32 aNumCols);
|
||||
/** an array containing col array. It can be larger than mRowCount due to
|
||||
* row spans extending beyond the table */
|
||||
nsVoidArray mRows;
|
||||
|
||||
/** an array of col frames. It is as large as mRowCount */
|
||||
nsVoidArray mColFrames;
|
||||
|
||||
/** an array of PRInt32 indexed by row and giving the number of cells originating
|
||||
* in each row. */
|
||||
nsVoidArray mNumCellsOrigInRow;
|
||||
|
||||
/** an array of PRInt32 indexed by col and giving the number of cells originating
|
||||
* in each col. */
|
||||
nsVoidArray mNumCellsOrigInCol;
|
||||
/** an array of nsColInfo indexed by col and giving the number of
|
||||
* cells originating and spanning each col. */
|
||||
nsVoidArray mCols;
|
||||
|
||||
// an array of booleans where the ith element indicates if the ith row is collapsed
|
||||
PRPackedBool* mIsCollapsedRows;
|
||||
@ -196,7 +233,7 @@ inline CellData* nsCellMap::GetCellAt(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex) const
|
||||
{
|
||||
if ((0 > aRowIndex) || (aRowIndex >= mRowCount) ||
|
||||
(0 > aColIndex) || (aColIndex >= mNumCellsOrigInCol.Count())) {
|
||||
(0 > aColIndex) || (aColIndex >= mCols.Count())) {
|
||||
//bug 9024 tickled this
|
||||
//printf("%s \n", "nsCellMap::GetCellAt called with invalid row or col index"); // XXX look at this when bug 10911 get fixed
|
||||
return nsnull;
|
||||
@ -213,7 +250,7 @@ inline CellData* nsCellMap::GetMapCellAt(PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex) const
|
||||
{
|
||||
if ((0 > aMapRowIndex) || (aMapRowIndex >= mRows.Count()) ||
|
||||
(0 > aColIndex) || (aColIndex >= mNumCellsOrigInCol.Count())) {
|
||||
(0 > aColIndex) || (aColIndex >= mCols.Count())) {
|
||||
//see bug 9024 comments above
|
||||
//printf("%s \n", "nsCellMap::GetMapCellAt called with invalid row or col index"); // XXX look at this when bug 10911 get fixed
|
||||
return nsnull;
|
||||
@ -228,7 +265,7 @@ inline CellData* nsCellMap::GetMapCellAt(PRInt32 aMapRowIndex,
|
||||
|
||||
inline PRInt32 nsCellMap::GetColCount() const
|
||||
{
|
||||
return mNumCellsOrigInCol.Count();
|
||||
return mCols.Count();
|
||||
}
|
||||
|
||||
inline PRInt32 nsCellMap::GetRowCount() const
|
||||
@ -236,15 +273,16 @@ inline PRInt32 nsCellMap::GetRowCount() const
|
||||
return mRowCount;
|
||||
}
|
||||
|
||||
inline void nsCellMap::AppendColumnFrame(nsTableColFrame *aColFrame)
|
||||
{
|
||||
mColFrames.AppendElement(aColFrame);
|
||||
}
|
||||
// nsColInfo
|
||||
|
||||
inline void nsCellMap::ClearColumnCache()
|
||||
{
|
||||
mColFrames.Clear();
|
||||
}
|
||||
inline nsColInfo::nsColInfo()
|
||||
:mNumCellsOrig(0), mNumCellsSpan(0)
|
||||
{}
|
||||
|
||||
inline nsColInfo::nsColInfo(PRInt32 aNumCellsOrig,
|
||||
PRInt32 aNumCellsSpan)
|
||||
:mNumCellsOrig(aNumCellsOrig), mNumCellsSpan(aNumCellsSpan)
|
||||
{}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -38,11 +38,9 @@ public:
|
||||
|
||||
/** call once every time any table thing changes (content, structure, or style)
|
||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||
* @param aNumCols the total number of columns in the table
|
||||
* @param aComputedWidth the computed size of the table
|
||||
*/
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize,
|
||||
PRInt32 aNumCols,
|
||||
nscoord aComputedWidth)=0;
|
||||
|
||||
/** compute the max-element-size for the table
|
||||
@ -80,9 +78,6 @@ public:
|
||||
/** return the value of the COLS attribute, used for balancing column widths */
|
||||
virtual nscoord GetCOLSAttribute() const = 0;
|
||||
|
||||
/** return the total number of columns in the table */
|
||||
virtual nscoord GetNumCols() const = 0;
|
||||
|
||||
// see nsTableFrame::ColumnsCanBeInvalidatedBy
|
||||
virtual PRBool ColumnsCanBeInvalidatedBy(nsStyleCoord* aPrevStyleWidth,
|
||||
const nsTableCellFrame& aCellFrame) const = 0;
|
||||
|
@ -71,10 +71,9 @@ nsTableCellFrame::Init(nsIPresContext* aPresContext,
|
||||
if (aPrevInFlow) {
|
||||
// Set the column index
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aPrevInFlow;
|
||||
PRInt32 baseColIndex;
|
||||
|
||||
cellFrame->GetColIndex(baseColIndex);
|
||||
InitCellFrame(baseColIndex);
|
||||
PRInt32 colIndex;
|
||||
cellFrame->GetColIndex(colIndex);
|
||||
InitCellFrame(colIndex);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -139,29 +138,24 @@ nsTableCellFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
|
||||
void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
|
||||
{
|
||||
NS_PRECONDITION(0<=aColIndex, "bad col index arg");
|
||||
SetColIndex(aColIndex); // this also sets the contents col index
|
||||
nsTableFrame* tableFrame=nsnull; // I should be checking my own style context, but border-collapse isn't inheriting correctly
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
if (NS_STYLE_BORDER_COLLAPSE == tableFrame->GetBorderCollapseStyle())
|
||||
{
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) {
|
||||
SetColIndex(aColIndex);
|
||||
if (NS_STYLE_BORDER_COLLAPSE == tableFrame->GetBorderCollapseStyle()) {
|
||||
mBorderEdges = new nsBorderEdges;
|
||||
mBorderEdges->mOutsideEdge=PR_FALSE;
|
||||
|
||||
PRInt32 rowspan = GetRowSpan();
|
||||
PRInt32 i;
|
||||
for (i=0; i<rowspan; i++)
|
||||
{
|
||||
for (i=0; i<rowspan; i++) {
|
||||
nsBorderEdge *borderToAdd = new nsBorderEdge();
|
||||
mBorderEdges->mEdges[NS_SIDE_LEFT].AppendElement(borderToAdd);
|
||||
borderToAdd = new nsBorderEdge();
|
||||
mBorderEdges->mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd);
|
||||
}
|
||||
PRInt32 colspan = GetColSpan();
|
||||
for (i=0; i<colspan; i++)
|
||||
{
|
||||
for (i=0; i<colspan; i++) {
|
||||
nsBorderEdge *borderToAdd = new nsBorderEdge();
|
||||
mBorderEdges->mEdges[NS_SIDE_TOP].AppendElement(borderToAdd);
|
||||
borderToAdd = new nsBorderEdge();
|
||||
|
@ -19,6 +19,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIReflowCommand.h"
|
||||
@ -30,6 +31,11 @@
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
#define COL_TYPE_CONTENT 0x0
|
||||
#define COL_TYPE_ANONYMOUS_COL 0x1
|
||||
#define COL_TYPE_ANONYMOUS_COLGROUP 0x2
|
||||
#define COL_TYPE_ANONYMOUS_CELL 0x3
|
||||
|
||||
nsTableColFrame::nsTableColFrame()
|
||||
: nsFrame(),
|
||||
mProportion(WIDTH_NOT_SET),
|
||||
@ -38,12 +44,55 @@ nsTableColFrame::nsTableColFrame()
|
||||
{
|
||||
// note that all fields are initialized to 0 by nsFrame::operator new
|
||||
ResetSizingInfo();
|
||||
SetType(eColContent);
|
||||
}
|
||||
|
||||
nsTableColFrame::~nsTableColFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsTableColType nsTableColFrame::GetType() const {
|
||||
switch(mBits.mType) {
|
||||
case COL_TYPE_ANONYMOUS_COL:
|
||||
return eColAnonymousCol;
|
||||
case COL_TYPE_ANONYMOUS_COLGROUP:
|
||||
return eColAnonymousColGroup;
|
||||
case COL_TYPE_ANONYMOUS_CELL:
|
||||
return eColAnonymousCell;
|
||||
default:
|
||||
return eColContent;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableColFrame::SetType(nsTableColType aType) {
|
||||
mBits.mType = aType - eColContent;
|
||||
}
|
||||
|
||||
// XXX what about other style besides width
|
||||
nsStyleCoord nsTableColFrame::GetStyleWidth() const
|
||||
{
|
||||
nsStylePosition* position = nsnull;
|
||||
position = (nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position);
|
||||
nsStyleCoord styleWidth = position->mWidth;
|
||||
// the following should not be necessary since html.css defines table-col and
|
||||
// :table-col to inherit. However, :table-col is not inheriting properly
|
||||
if (eStyleUnit_Auto == styleWidth.GetUnit()) {
|
||||
nsIFrame* parent;
|
||||
GetParent(&parent);
|
||||
nsCOMPtr<nsIStyleContext> styleContext;
|
||||
parent->GetStyleContext(getter_AddRefs(styleContext));
|
||||
if (styleContext) {
|
||||
position = (nsStylePosition*)styleContext->GetStyleData(eStyleStruct_Position);
|
||||
styleWidth = position->mWidth;
|
||||
}
|
||||
}
|
||||
|
||||
nsStyleCoord returnWidth;
|
||||
returnWidth.mUnit = styleWidth.mUnit;
|
||||
returnWidth.mValue = styleWidth.mValue;
|
||||
return returnWidth;
|
||||
}
|
||||
|
||||
void nsTableColFrame::ResetSizingInfo()
|
||||
{
|
||||
nsCRT::memset(mWidths, WIDTH_NOT_SET, NUM_WIDTHS * sizeof(PRInt32));
|
||||
|
@ -55,6 +55,13 @@ enum nsColConstraint {
|
||||
e0ProportionConstraint = 4 // 0*, means to force to min width
|
||||
};
|
||||
|
||||
enum nsTableColType {
|
||||
eColContent = 0, // there is real col content associated
|
||||
eColAnonymousCol = 1, // the result of a span on a col
|
||||
eColAnonymousColGroup = 2, // the result of a span on a col group
|
||||
eColAnonymousCell = 3, // the result of a cell alone
|
||||
};
|
||||
|
||||
class nsTableColFrame : public nsFrame {
|
||||
public:
|
||||
|
||||
@ -63,7 +70,8 @@ public:
|
||||
eWIDTH_SOURCE_CELL_WITH_SPAN=2 // a cell implicitly specified a width via colspan
|
||||
};
|
||||
|
||||
void InitColFrame(PRInt32 aColIndex);
|
||||
nsTableColType GetType() const;
|
||||
void nsTableColFrame::SetType(nsTableColType aType);
|
||||
|
||||
/** instantiate a new instance of nsTableColFrame.
|
||||
* @param aResult the new object is returned in this out-param
|
||||
@ -75,6 +83,12 @@ public:
|
||||
friend nsresult
|
||||
NS_NewTableColFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
|
||||
nsStyleCoord GetStyleWidth() const;
|
||||
|
||||
PRInt32 GetColIndex() const;
|
||||
|
||||
void SetColIndex (PRInt32 aColIndex);
|
||||
|
||||
NS_IMETHOD Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
@ -97,15 +111,9 @@ public:
|
||||
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
||||
#endif
|
||||
|
||||
/** return the index of the column the col represents. always >= 0 */
|
||||
virtual PRInt32 GetColumnIndex ();
|
||||
|
||||
/** return the number of the columns the col represents. always >= 0 */
|
||||
virtual PRInt32 GetSpan ();
|
||||
|
||||
/** set the index of the column this content object represents. must be >= 0 */
|
||||
virtual void SetColumnIndex (int aColIndex);
|
||||
|
||||
/** convenience method, calls into cellmap */
|
||||
nsVoidArray * GetCells();
|
||||
|
||||
@ -138,6 +146,11 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
struct ColBits {
|
||||
unsigned int mType:4;
|
||||
unsigned int mUnused:28;
|
||||
} mBits;
|
||||
|
||||
nsTableColFrame();
|
||||
~nsTableColFrame();
|
||||
|
||||
@ -153,18 +166,11 @@ protected:
|
||||
PRPackedBool mNonPercentSpansPercent;
|
||||
};
|
||||
|
||||
|
||||
inline void nsTableColFrame::InitColFrame(PRInt32 aColIndex)
|
||||
{
|
||||
NS_ASSERTION(0<=aColIndex, "bad col index param");
|
||||
mColIndex = aColIndex;
|
||||
}
|
||||
|
||||
inline PRInt32 nsTableColFrame::GetColumnIndex()
|
||||
inline PRInt32 nsTableColFrame::GetColIndex() const
|
||||
{ return mColIndex; }
|
||||
|
||||
inline void nsTableColFrame::SetColumnIndex (int aColIndex)
|
||||
{ mColIndex = aColIndex;}
|
||||
inline void nsTableColFrame::SetColIndex (PRInt32 aColIndex)
|
||||
{ mColIndex = aColIndex; }
|
||||
|
||||
inline nsColConstraint nsTableColFrame::GetConstraint() const
|
||||
{ return mConstraint; }
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsTableFrame.h"
|
||||
#include "nsIHTMLTableColElement.h"
|
||||
#include "nsIDOMHTMLTableColElement.h"
|
||||
#include "nsIReflowCommand.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
@ -40,101 +41,230 @@
|
||||
NS_DEF_PTR(nsIContent);
|
||||
|
||||
static NS_DEFINE_IID(kIHTMLTableColElementIID, NS_IHTMLTABLECOLELEMENT_IID);
|
||||
static NS_DEFINE_IID(kIDOMHTMLTableColElementIID, NS_IDOMHTMLTABLECOLELEMENT_IID);
|
||||
|
||||
#define COLGROUP_TYPE_CONTENT 0x0
|
||||
#define COLGROUP_TYPE_ANONYMOUS_COL 0x1
|
||||
#define COLGROUP_TYPE_ANONYMOUS_CELL 0x2
|
||||
|
||||
nsTableColGroupType nsTableColGroupFrame::GetType() const {
|
||||
switch(mBits.mType) {
|
||||
case COLGROUP_TYPE_ANONYMOUS_COL:
|
||||
return eColGroupAnonymousCol;
|
||||
case COLGROUP_TYPE_ANONYMOUS_CELL:
|
||||
return eColGroupAnonymousCell;
|
||||
default:
|
||||
return eColGroupContent;
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableColGroupFrame::SetType(nsTableColGroupType aType) {
|
||||
mBits.mType = aType - eColGroupContent;
|
||||
}
|
||||
|
||||
void nsTableColGroupFrame::ResetColIndices(nsIFrame* aFirstColGroup,
|
||||
PRInt32 aFirstColIndex,
|
||||
nsIFrame* aStartColFrame)
|
||||
{
|
||||
nsTableColGroupFrame* colGroupFrame = (nsTableColGroupFrame*)aFirstColGroup;
|
||||
PRInt32 colIndex = aFirstColIndex;
|
||||
while (colGroupFrame) {
|
||||
nsIAtom* cgType;
|
||||
colGroupFrame->GetFrameType(&cgType);
|
||||
if (nsLayoutAtoms::tableColGroupFrame == cgType) {
|
||||
colGroupFrame->SetStartColumnIndex(colIndex);
|
||||
nsIFrame* colFrame = aStartColFrame;
|
||||
if (!colFrame || (colIndex != aFirstColIndex)) {
|
||||
colGroupFrame->FirstChild(nsnull, &colFrame);
|
||||
}
|
||||
while (colFrame) {
|
||||
nsIAtom* colType;
|
||||
colFrame->GetFrameType(&colType);
|
||||
if (nsLayoutAtoms::tableColFrame == colType) {
|
||||
((nsTableColFrame*)colFrame)->SetColIndex(colIndex);
|
||||
colIndex++;
|
||||
}
|
||||
NS_IF_RELEASE(colType);
|
||||
colFrame->GetNextSibling(&colFrame);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(cgType);
|
||||
colGroupFrame->GetNextSibling((nsIFrame**)&colGroupFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::InitNewFrames(nsIPresContext* aPresContext, nsIFrame* aChildList)
|
||||
nsTableColGroupFrame::AddColsToTable(nsIPresContext& aPresContext,
|
||||
PRInt32 aFirstColIndex,
|
||||
PRBool aResetSubsequentColIndices,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsresult rv=NS_OK;
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) {
|
||||
// Process the newly added column frames
|
||||
for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
|
||||
const nsStyleDisplay* display;
|
||||
kidFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == display->mDisplay) {
|
||||
// Set the preliminary values for the column frame
|
||||
PRInt32 colIndex = mStartColIndex + mColCount;
|
||||
((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex);
|
||||
PRInt32 repeat = ((nsTableColFrame *)(kidFrame))->GetSpan();
|
||||
mColCount += repeat;
|
||||
for (PRInt32 i=0; i<repeat; i++) {
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
// colgroup's span attribute is how many columns the group represents
|
||||
// in the absence of any COL children
|
||||
// Note that this is the correct, though perhaps unexpected, behavior for the span attribute.
|
||||
// The spec says that if there are any COL children, the colgroup's span is ignored.
|
||||
if (0==mColCount)
|
||||
{
|
||||
nsIFrame *firstImplicitColFrame=nsnull;
|
||||
nsIFrame *prevColFrame=nsnull;
|
||||
nsAutoString colTag;
|
||||
nsHTMLAtoms::col->ToString(colTag);
|
||||
mColCount = GetSpan();
|
||||
for (PRInt32 colIndex=0; colIndex<mColCount; colIndex++)
|
||||
{
|
||||
nsIHTMLContent *col=nsnull;
|
||||
// create an implicit col
|
||||
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
|
||||
//XXX mark the col implicit
|
||||
mContent->AppendChildTo((nsIContent*)col, PR_FALSE);
|
||||
|
||||
// Create a new col frame
|
||||
nsIFrame* colFrame;
|
||||
NS_NewTableColFrame(shell, &colFrame);
|
||||
|
||||
// Set its style context
|
||||
nsCOMPtr<nsIStyleContext> colStyleContext;
|
||||
aPresContext->ResolveStyleContextFor(col, mStyleContext,
|
||||
PR_TRUE,
|
||||
getter_AddRefs(colStyleContext));
|
||||
colFrame->Init(aPresContext, col, this, colStyleContext, nsnull);
|
||||
colFrame->SetInitialChildList(aPresContext, nsnull, nsnull);
|
||||
|
||||
// Set nsColFrame-specific information
|
||||
PRInt32 absColIndex = mStartColIndex + colIndex;
|
||||
((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex);
|
||||
((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)colFrame);
|
||||
|
||||
//hook into list of children
|
||||
if (nsnull==firstImplicitColFrame)
|
||||
firstImplicitColFrame = colFrame;
|
||||
else
|
||||
prevColFrame->SetNextSibling(colFrame);
|
||||
prevColFrame = colFrame;
|
||||
}
|
||||
|
||||
// hook new columns into col group child list
|
||||
mFrames.AppendFrames(nsnull, firstImplicitColFrame);
|
||||
}
|
||||
SetStyleContextForFirstPass(aPresContext);
|
||||
if (!(NS_SUCCEEDED(rv) && tableFrame && aFirstFrame)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// set the col indices of the col frames and and add col info to the table
|
||||
PRInt32 colIndex = aFirstColIndex;
|
||||
nsIFrame* kidFrame = aFirstFrame;
|
||||
PRBool foundLastFrame = PR_FALSE;
|
||||
while (kidFrame) {
|
||||
nsIAtom* kidType;
|
||||
kidFrame->GetFrameType(&kidType);
|
||||
if (nsLayoutAtoms::tableColFrame == kidType) {
|
||||
((nsTableColFrame*)kidFrame)->SetColIndex(colIndex);
|
||||
if (!foundLastFrame) {
|
||||
tableFrame->InsertCol(aPresContext, (nsTableColFrame &)*kidFrame, colIndex);
|
||||
mColCount++;
|
||||
}
|
||||
colIndex++;
|
||||
}
|
||||
NS_IF_RELEASE(kidType);
|
||||
if (kidFrame == aLastFrame) {
|
||||
foundLastFrame = PR_TRUE;
|
||||
}
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
}
|
||||
|
||||
if (aResetSubsequentColIndices) {
|
||||
nsIFrame* nextSibling;
|
||||
GetNextSibling(&nextSibling);
|
||||
if (nextSibling) {
|
||||
ResetColIndices(nextSibling, colIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::AppendNewFrames(nsIPresContext* aPresContext, nsIFrame* aChildList)
|
||||
// this is called when a col frame doesn't have an explicit col group parent.
|
||||
nsTableColGroupFrame*
|
||||
nsTableColGroupFrame::FindParentForAppendedCol(nsTableFrame* aTableFrame,
|
||||
nsTableColType aColType)
|
||||
{
|
||||
if (nsnull!=aChildList)
|
||||
mFrames.AppendFrames(nsnull, aChildList);
|
||||
return NS_OK;
|
||||
nsVoidArray& cols = aTableFrame->GetColCache();
|
||||
PRInt32 numCols = cols.Count();
|
||||
nsIFrame* lastColGroup;
|
||||
nsIFrame* lastCol = (nsIFrame*)cols.ElementAt(numCols - 1);
|
||||
if (!lastCol) return nsnull; // no columns so no colgroups
|
||||
lastCol->GetParent(&lastColGroup);
|
||||
if (!lastColGroup) return nsnull; // shouldn't happen
|
||||
|
||||
nsTableColGroupFrame* relevantColGroup = (nsTableColGroupFrame *)lastColGroup;
|
||||
nsTableColGroupType relevantColGroupType = relevantColGroup->GetType();
|
||||
if (eColGroupAnonymousCell == relevantColGroupType) {
|
||||
if (eColAnonymousCell == aColType) {
|
||||
return relevantColGroup;
|
||||
}
|
||||
else {
|
||||
// find the next to last col group
|
||||
for (PRInt32 colX = numCols - 2; colX >= 0; colX--) {
|
||||
nsTableColFrame* colFrame = (nsTableColFrame*)cols.ElementAt(colX);
|
||||
nsTableColGroupFrame* colGroupFrame;
|
||||
colFrame->GetParent((nsIFrame**)&colGroupFrame);
|
||||
nsTableColGroupType cgType = colGroupFrame->GetType();
|
||||
if (cgType != relevantColGroupType) {
|
||||
relevantColGroup = colGroupFrame;
|
||||
relevantColGroupType = cgType;
|
||||
break;
|
||||
}
|
||||
else if (0 == colX) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eColGroupAnonymousCol == relevantColGroupType) {
|
||||
if ((eColContent == aColType) || (eColAnonymousCol == aColType)) {
|
||||
return relevantColGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTableColGroupFrame::GetLastRealColGroup(nsTableFrame* aTableFrame,
|
||||
nsIFrame** aLastColGroup)
|
||||
{
|
||||
*aLastColGroup = nsnull;
|
||||
nsFrameList colGroups = aTableFrame->GetColGroups();
|
||||
|
||||
nsIFrame* nextToLastColGroup = nsnull;
|
||||
nsIFrame* lastColGroup = colGroups.FirstChild();
|
||||
while(lastColGroup) {
|
||||
nsIFrame* next;
|
||||
lastColGroup->GetNextSibling(&next);
|
||||
if (next) {
|
||||
nextToLastColGroup = lastColGroup;
|
||||
lastColGroup = next;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lastColGroup) return PR_TRUE; // there are no col group frames
|
||||
|
||||
nsTableColGroupType lastColGroupType = ((nsTableColGroupFrame *)lastColGroup)->GetType();
|
||||
if (eColGroupAnonymousCell == lastColGroupType) {
|
||||
*aLastColGroup = nextToLastColGroup;
|
||||
return PR_FALSE;
|
||||
}
|
||||
else {
|
||||
*aLastColGroup = lastColGroup;
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// don't set mColCount here, it is done in AddColsToTable
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
nsresult result = AppendNewFrames(aPresContext, aChildList);
|
||||
if (NS_OK==result)
|
||||
result = InitNewFrames(aPresContext, aChildList);
|
||||
return result;
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (!aChildList) {
|
||||
nsIFrame* firstChild;
|
||||
tableFrame->CreateAnonymousColFrames(*aPresContext, *this, GetSpan(), eColAnonymousColGroup,
|
||||
PR_FALSE, nsnull, &firstChild);
|
||||
if (firstChild) {
|
||||
SetInitialChildList(aPresContext, aListName, firstChild);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame* kidFrame = aChildList;
|
||||
while (kidFrame) {
|
||||
nsIAtom* kidType;
|
||||
kidFrame->GetFrameType(&kidType);
|
||||
if (nsLayoutAtoms::tableColFrame == kidType) {
|
||||
// Set the preliminary values for the column frame
|
||||
PRInt32 span = ((nsTableColFrame*)kidFrame)->GetSpan();
|
||||
if (span > 1) {
|
||||
nsTableColFrame* firstSpannedCol;
|
||||
tableFrame->CreateAnonymousColFrames(*aPresContext, *this, span - 1, eColAnonymousCol,
|
||||
PR_FALSE, (nsTableColFrame*)kidFrame, (nsIFrame **)&firstSpannedCol);
|
||||
nsIFrame* spanner = kidFrame;
|
||||
kidFrame->GetNextSibling(&kidFrame); // need to do this before we insert the new frames
|
||||
nsFrameList newChildren(aChildList); // used as a convience to hook up siblings
|
||||
newChildren.InsertFrames(this, (nsTableColFrame*)spanner, (nsIFrame *)firstSpannedCol);
|
||||
NS_RELEASE(kidType);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(kidType);
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
}
|
||||
|
||||
mFrames.AppendFrames(this, aChildList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Helper function. It marks the table frame as dirty and generates
|
||||
@ -173,35 +303,8 @@ nsTableColGroupFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Append the new frames to our child list
|
||||
mFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
// Reset the starting column index of the col groups that follow
|
||||
PRInt32 startingColIndex = mStartColIndex;
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
|
||||
nsIFrame *nextColGroupFrame=nsnull;
|
||||
GetNextSibling(&nextColGroupFrame);
|
||||
while (nextColGroupFrame)
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
nextColGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)nextColGroupFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
nextColGroupFrame->GetNextSibling(&nextColGroupFrame);
|
||||
}
|
||||
|
||||
// Today we need to rebuild the whole column cache.
|
||||
// If the table frame is ever recoded to build the column cache incrementally,
|
||||
// we could take advantage of that here
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
mFrames.AppendFrames(this, aFrameList);
|
||||
InsertColsReflow(*aPresContext, aPresShell, mColCount, aFrameList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -209,76 +312,121 @@ NS_IMETHODIMP
|
||||
nsTableColGroupFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aPrevFrameIn,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Insert the new frames into our child list
|
||||
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
nsFrameList frames(aFrameList); // convience for getting last frame
|
||||
nsIFrame* lastFrame = frames.LastChild();
|
||||
|
||||
// Reset the starting column index of the col groups that follow
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
mFrames.InsertFrames(this, aPrevFrameIn, aFrameList);
|
||||
nsIFrame* prevFrame = nsTableFrame::GetFrameAtOrBefore(this, aPrevFrameIn,
|
||||
nsLayoutAtoms::tableColFrame);
|
||||
|
||||
nsIFrame *nextColGroupFrame=nsnull;
|
||||
GetNextSibling(&nextColGroupFrame);
|
||||
while (nextColGroupFrame)
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
nextColGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)nextColGroupFrame)->SetStartColumnIndex(startingColIndex);
|
||||
}
|
||||
nextColGroupFrame->GetNextSibling(&nextColGroupFrame);
|
||||
}
|
||||
PRInt32 colIndex = (prevFrame) ? ((nsTableColFrame*)prevFrame)->GetColIndex() + 1 : 0;
|
||||
InsertColsReflow(*aPresContext, aPresShell, colIndex, aFrameList, lastFrame);
|
||||
|
||||
// Today we need to rebuild the whole column cache.
|
||||
// If the table frame is ever recoded to build the column cache incrementally,
|
||||
// we could take advantage of that here.
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsTableColGroupFrame::InsertColsReflow(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
PRInt32 aColIndex,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame)
|
||||
{
|
||||
AddColsToTable(aPresContext, aColIndex, PR_TRUE, aFirstFrame, aLastFrame);
|
||||
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(&aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
|
||||
void
|
||||
nsTableColGroupFrame::RemoveChild(nsIPresContext& aPresContext,
|
||||
nsTableColFrame& aChild,
|
||||
PRBool aResetColIndices)
|
||||
{
|
||||
PRInt32 colIndex = 0;
|
||||
nsIFrame* nextChild = nsnull;
|
||||
if (aResetColIndices) {
|
||||
colIndex = aChild.GetColIndex();
|
||||
aChild.GetNextSibling(&nextChild);
|
||||
}
|
||||
if (mFrames.DestroyFrame(&aPresContext, (nsIFrame*)&aChild)) {
|
||||
mColCount--;
|
||||
if (aResetColIndices) {
|
||||
ResetColIndices(this, colIndex, nextChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this removes children form the last col group (eColGroupAnonymousCell) in the
|
||||
// table only,so there is no need to reset col indices for subsequent col groups.
|
||||
void
|
||||
nsTableColGroupFrame::RemoveChildrenAtEnd(nsIPresContext& aPresContext,
|
||||
PRInt32 aNumChildrenToRemove)
|
||||
{
|
||||
PRInt32 numToRemove = aNumChildrenToRemove;
|
||||
if (numToRemove > mColCount) {
|
||||
NS_ASSERTION(PR_FALSE, "invalid arg to RemoveChildrenAtEnd");
|
||||
numToRemove = mColCount;
|
||||
}
|
||||
PRInt32 offsetOfFirstRemoval = mColCount - numToRemove;
|
||||
PRInt32 offsetX = 0;
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
while(kidFrame) {
|
||||
nsIAtom* kidType;
|
||||
kidFrame->GetFrameType(&kidType);
|
||||
if (nsLayoutAtoms::tableColFrame == kidType) {
|
||||
offsetX++;
|
||||
if (offsetX > offsetOfFirstRemoval) {
|
||||
nsIFrame* byebye = kidFrame;
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
mFrames.DestroyFrame(&aPresContext, byebye);
|
||||
NS_RELEASE(kidType);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(kidType);
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableColGroupFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
// Remove the frame from our child list
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
if (!aOldFrame) return NS_OK;
|
||||
|
||||
// Reset the starting column index of the col groups that follow
|
||||
PRInt32 startingColIndex=mStartColIndex;
|
||||
startingColIndex += GetColumnCount(); // has the side effect of resetting all column indexes
|
||||
|
||||
nsIFrame *nextColGroupFrame=nsnull;
|
||||
GetNextSibling(&nextColGroupFrame);
|
||||
while (nextColGroupFrame)
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
nextColGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
startingColIndex += ((nsTableColGroupFrame *)nextColGroupFrame)->SetStartColumnIndex(startingColIndex);
|
||||
nsIAtom* frameType = nsnull;
|
||||
aOldFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableColFrame == frameType) {
|
||||
nsTableColFrame* colFrame = (nsTableColFrame*)aOldFrame;
|
||||
PRInt32 colIndex = colFrame->GetColIndex();
|
||||
RemoveChild(*aPresContext, *colFrame, PR_TRUE);
|
||||
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
tableFrame->RemoveCol(*aPresContext, this, colIndex, PR_TRUE, PR_TRUE);
|
||||
}
|
||||
nextColGroupFrame->GetNextSibling(&nextColGroupFrame);
|
||||
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
else {
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
|
||||
// Today we need to rebuild the whole column cache.
|
||||
// If the table frame is ever recoded to build the column cache incrementally,
|
||||
// we could take advantage of that here
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -429,11 +577,10 @@ NS_METHOD nsTableColGroupFrame::IR_StyleChanged(nsIPresContext* aPresCo
|
||||
nsresult rv = NS_OK;
|
||||
// we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here
|
||||
// XXX: we can optimize this when we know which style attribute changed
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
tableFrame->InvalidateColumnCache();
|
||||
if ((NS_SUCCEEDED(rv)) && tableFrame) {
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
}
|
||||
return rv;
|
||||
@ -448,7 +595,7 @@ NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext* aPresC
|
||||
nsresult rv;
|
||||
|
||||
// Remember the old col count
|
||||
const PRInt32 oldColCount = GetColumnCount();
|
||||
const PRInt32 oldColCount = GetColCount();
|
||||
|
||||
// Pass along the reflow command
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
@ -462,136 +609,16 @@ NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext* aPresC
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) {
|
||||
// compare the new col count to the old col count.
|
||||
// If they are the same, we just need to rebalance column widths
|
||||
// If they differ, we need to fix up other column groups and the column cache
|
||||
const PRInt32 newColCount = GetColumnCount(); // this will set the new column indexes if necessary
|
||||
if (oldColCount==newColCount)
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
else
|
||||
tableFrame->InvalidateColumnCache();
|
||||
const PRInt32 newColCount = GetColCount();
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Subclass hook for style post processing
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext)
|
||||
{
|
||||
// get the table frame
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
// get the style for the table frame
|
||||
const nsStyleTable *tableStyle;
|
||||
tableFrame->GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
|
||||
|
||||
// if COLS is set, then map it into the COL frames
|
||||
if (NS_STYLE_TABLE_COLS_NONE != tableStyle->mCols)
|
||||
{
|
||||
// set numCols to the number of columns effected by the COLS attribute
|
||||
PRInt32 numCols=0;
|
||||
if (NS_STYLE_TABLE_COLS_ALL == tableStyle->mCols)
|
||||
numCols = mFrames.GetLength();
|
||||
else
|
||||
numCols = tableStyle->mCols;
|
||||
|
||||
// for every column effected, set its width style
|
||||
PRInt32 colIndex=0;
|
||||
nsIFrame *colFrame=mFrames.FirstChild();
|
||||
while (nsnull!=colFrame)
|
||||
{
|
||||
const nsStyleDisplay * colDisplay=nsnull;
|
||||
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
|
||||
{
|
||||
nsCOMPtr<nsIStyleContext> colStyleContext;
|
||||
nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleContext(getter_AddRefs(colStyleContext));
|
||||
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
if (colIndex<numCols)
|
||||
{
|
||||
nsStyleCoord width (1, eStyleUnit_Proportional);
|
||||
colPosition->mWidth = width;
|
||||
}
|
||||
else
|
||||
{
|
||||
colPosition->mWidth.SetCoordValue(0);
|
||||
}
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
colIndex++;
|
||||
}
|
||||
colFrame->GetNextSibling(&colFrame);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// propagate the colgroup width attribute down to the columns if they have no width of their own
|
||||
nsStylePosition* position = (nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position);
|
||||
if (eStyleUnit_Null!=position->mWidth.GetUnit())
|
||||
{
|
||||
// now for every column that doesn't have it's own width, set the width style
|
||||
nsIFrame *colFrame=mFrames.FirstChild();
|
||||
while (nsnull!=colFrame)
|
||||
{
|
||||
const nsStyleDisplay * colDisplay=nsnull;
|
||||
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
|
||||
{
|
||||
nsCOMPtr<nsIStyleContext> colStyleContext;
|
||||
const nsStylePosition * colPosition=nsnull;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)colPosition); // get a read-only version of the style context
|
||||
//XXX: how do I know this is auto because it's defaulted, vs. set explicitly to "auto"?
|
||||
if (eStyleUnit_Auto==colPosition->mWidth.GetUnit())
|
||||
{
|
||||
// notice how we defer getting a mutable style context until we're sure we really need one
|
||||
colFrame->GetStyleContext(getter_AddRefs(colStyleContext));
|
||||
nsStylePosition * mutableColPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
||||
mutableColPosition->mWidth = position->mWidth;
|
||||
colStyleContext->RecalcAutomaticData(aPresContext);
|
||||
}
|
||||
}
|
||||
colFrame->GetNextSibling(&colFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
//mStyleContext->RecalcAutomaticData(aPresContext);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/** returns the number of columns represented by this group.
|
||||
* if there are col children, count them (taking into account the span of each)
|
||||
* else, check my own span attribute.
|
||||
*/
|
||||
int nsTableColGroupFrame::GetColumnCount ()
|
||||
{
|
||||
mColCount=0;
|
||||
nsIFrame *childFrame = mFrames.FirstChild();
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay)
|
||||
{
|
||||
nsTableColFrame *col = (nsTableColFrame *)childFrame;
|
||||
col->SetColumnIndex (mStartColIndex + mColCount);
|
||||
mColCount += col->GetSpan();
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
if (0==mColCount)
|
||||
{ // there were no children of this colgroup that were columns. So use my span attribute
|
||||
const nsStyleTable *tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
|
||||
mColCount = tableStyle->mSpan;
|
||||
}
|
||||
return mColCount;
|
||||
}
|
||||
|
||||
nsTableColFrame * nsTableColGroupFrame::GetFirstColumn()
|
||||
{
|
||||
return GetNextColumn(nsnull);
|
||||
@ -642,28 +669,26 @@ nsTableColFrame * nsTableColGroupFrame::GetColumnAt (PRInt32 aColIndex)
|
||||
|
||||
PRInt32 nsTableColGroupFrame::GetSpan()
|
||||
{
|
||||
PRInt32 span=1;
|
||||
const nsStyleTable* tableStyle=nsnull;
|
||||
GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
|
||||
if (nsnull!=tableStyle)
|
||||
{
|
||||
span = tableStyle->mSpan;
|
||||
PRInt32 span = 1;
|
||||
nsCOMPtr<nsIContent> iContent;
|
||||
nsresult rv = GetContent(getter_AddRefs(iContent));
|
||||
if (NS_FAILED(rv) || !iContent) return rv;
|
||||
|
||||
// col group element derives from col element
|
||||
nsIDOMHTMLTableColElement* cgContent = nsnull;
|
||||
rv = iContent->QueryInterface(kIDOMHTMLTableColElementIID,
|
||||
(void **)&cgContent);
|
||||
if (cgContent && NS_SUCCEEDED(rv)) {
|
||||
cgContent->GetSpan(&span);
|
||||
// XXX why does this work!!
|
||||
if (span == -1) {
|
||||
span = 1;
|
||||
}
|
||||
NS_RELEASE(cgContent);
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
/* this may be needed when IsSynthetic is properly implemented
|
||||
PRBool nsTableColGroupFrame::IsManufactured()
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
nsIFrame *firstCol = GetFirstColumn();
|
||||
if (nsTableFrame::IsSynthetic(this) &&
|
||||
((nsnull==firstCol) || nsTableFrame::IsSynthetic(firstCol)))
|
||||
result = PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
/** returns colcount because it is frequently used in the context of
|
||||
* shuffling relative colgroup order, and it's convenient to not have to
|
||||
* call GetColumnCount redundantly.
|
||||
@ -671,15 +696,41 @@ PRBool nsTableColGroupFrame::IsManufactured()
|
||||
PRInt32 nsTableColGroupFrame::SetStartColumnIndex (int aIndex)
|
||||
{
|
||||
PRInt32 result = mColCount;
|
||||
if (aIndex != mStartColIndex)
|
||||
{
|
||||
if (aIndex != mStartColIndex) {
|
||||
mStartColIndex = aIndex;
|
||||
mColCount=0;
|
||||
result = GetColumnCount(); // has the side effect of setting each column index based on new start index
|
||||
result = GetColCount();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// this could be optimized by using col group frame starting indicies,
|
||||
// but typically there aren't enough very large col groups for the added complexity.
|
||||
nsTableColGroupFrame*
|
||||
nsTableColGroupFrame::GetColGroupFrameContaining(nsFrameList& aColGroupList,
|
||||
nsTableColFrame& aColFrame)
|
||||
{
|
||||
nsIFrame* childFrame = aColGroupList.FirstChild();
|
||||
while (childFrame) {
|
||||
nsIAtom* frameType = nsnull;
|
||||
childFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableColGroupFrame == frameType) {
|
||||
nsTableColFrame* colFrame = nsnull;
|
||||
childFrame->FirstChild(nsnull, (nsIFrame **)&colFrame);
|
||||
while (colFrame) {
|
||||
if (colFrame = &aColFrame) {
|
||||
NS_RELEASE(frameType);
|
||||
return (nsTableColGroupFrame *)childFrame;
|
||||
}
|
||||
colFrame->GetNextSibling((nsIFrame **)&colFrame);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void nsTableColGroupFrame::DeleteColFrame(nsIPresContext* aPresContext, nsTableColFrame* aColFrame)
|
||||
{
|
||||
mFrames.DestroyFrame(aPresContext, aColFrame);
|
||||
|
@ -26,7 +26,14 @@
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
|
||||
class nsTableColFrame;
|
||||
class nsTableFrame;
|
||||
enum nsTableColType;
|
||||
|
||||
enum nsTableColGroupType {
|
||||
eColGroupContent = 0, // there is real col group content associated
|
||||
eColGroupAnonymousCol = 1, // the result of a col
|
||||
eColGroupAnonymousCell = 2, // the result of a cell alone
|
||||
};
|
||||
|
||||
/**
|
||||
* nsTableColGroupFrame
|
||||
@ -52,6 +59,16 @@ public:
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList);
|
||||
|
||||
nsTableColGroupType GetType() const;
|
||||
|
||||
void SetType(nsTableColGroupType aType);
|
||||
|
||||
static PRBool GetLastRealColGroup(nsTableFrame* aTableFrame,
|
||||
nsIFrame** aLastColGroup);
|
||||
|
||||
static nsTableColGroupFrame* FindParentForAppendedCol(nsTableFrame* aTableFrame,
|
||||
nsTableColType aColType);
|
||||
|
||||
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
@ -66,6 +83,13 @@ public:
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
void RemoveChild(nsIPresContext& aPresContext,
|
||||
nsTableColFrame& aLastChild,
|
||||
PRBool aResetColIndices);
|
||||
|
||||
void RemoveChildrenAtEnd(nsIPresContext& aPresContext,
|
||||
PRInt32 aNumChildrenToRemove);
|
||||
|
||||
NS_IMETHOD Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
@ -89,6 +113,12 @@ public:
|
||||
*/
|
||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||
|
||||
NS_IMETHOD AddColsToTable(nsIPresContext& aPresContext,
|
||||
PRInt32 aFirstColIndex,
|
||||
PRBool aResetSubsequentColIndices,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame = nsnull);
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
||||
@ -98,7 +128,7 @@ public:
|
||||
* if there are col children, count them (taking into account the span of each)
|
||||
* else, check my own span attribute.
|
||||
*/
|
||||
virtual PRInt32 GetColumnCount();
|
||||
virtual PRInt32 GetColCount() const;
|
||||
|
||||
virtual nsTableColFrame * GetFirstColumn();
|
||||
|
||||
@ -124,23 +154,25 @@ public:
|
||||
|
||||
void DeleteColFrame(nsIPresContext* aPresContext, nsTableColFrame* aColFrame);
|
||||
|
||||
protected:
|
||||
static nsTableColGroupFrame* GetColGroupFrameContaining(nsFrameList& aColGroupList,
|
||||
nsTableColFrame& aColFrame);
|
||||
nsFrameList& GetChildList();
|
||||
|
||||
static void ResetColIndices(nsIFrame* aFirstColGroup,
|
||||
PRInt32 aFirstColIndex,
|
||||
nsIFrame* aStartColFrame = nsnull);
|
||||
protected:
|
||||
nsTableColGroupFrame();
|
||||
|
||||
void InsertColsReflow(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
PRInt32 aColIndex,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame = nsnull);
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
/** Hook for style post processing.
|
||||
* Since we need to know the full column structure before the COLS attribute
|
||||
* can be interpreted, we can't just use DidSetStyleContext
|
||||
*/
|
||||
NS_IMETHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext);
|
||||
|
||||
NS_IMETHOD InitNewFrames(nsIPresContext* aPresContext, nsIFrame* aChildList);
|
||||
NS_IMETHOD AppendNewFrames(nsIPresContext* aPresContext, nsIFrame* aChildList);
|
||||
|
||||
|
||||
NS_IMETHOD IncrementalReflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
@ -174,13 +206,33 @@ protected:
|
||||
/** the starting column index this col group represents. Must be >= 0. */
|
||||
PRInt32 mStartColIndex;
|
||||
|
||||
struct ColGroupBits {
|
||||
unsigned int mType:4;
|
||||
unsigned int mUnused:28;
|
||||
} mBits;
|
||||
|
||||
};
|
||||
|
||||
inline nsTableColGroupFrame::nsTableColGroupFrame()
|
||||
: mColCount(0), mStartColIndex(0)
|
||||
{}
|
||||
{
|
||||
mBits.mType = 0;
|
||||
}
|
||||
|
||||
inline int nsTableColGroupFrame::GetStartColumnIndex ()
|
||||
{ return mStartColIndex;}
|
||||
inline PRInt32 nsTableColGroupFrame::GetStartColumnIndex()
|
||||
{
|
||||
return mStartColIndex;
|
||||
}
|
||||
|
||||
inline PRInt32 nsTableColGroupFrame::GetColCount() const
|
||||
{
|
||||
return mColCount;
|
||||
}
|
||||
|
||||
inline nsFrameList& nsTableColGroupFrame::GetChildList()
|
||||
{
|
||||
return mFrames;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -43,6 +43,8 @@ class nsHTMLValue;
|
||||
struct InnerTableReflowState;
|
||||
struct nsStylePosition;
|
||||
struct nsStyleSpacing;
|
||||
enum nsTableColType;
|
||||
enum nsTableColGroupType;
|
||||
|
||||
/**
|
||||
* Child list name indices
|
||||
@ -124,8 +126,14 @@ public:
|
||||
/** helper method to find the table parent of any table frame object */
|
||||
// TODO: today, this depends on display types. This should be changed to rely
|
||||
// on stronger criteria, like an inner table frame atom
|
||||
static NS_METHOD GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aTableFrame);
|
||||
static NS_METHOD GetTableFrame(nsIFrame* aSourceFrame,
|
||||
nsTableFrame*& aTableFrame);
|
||||
|
||||
// Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
|
||||
// of type aChildType.
|
||||
static nsIFrame* nsTableFrame::GetFrameAtOrBefore(nsIFrame* aParentFrame,
|
||||
nsIFrame* aPriorChildFrame,
|
||||
nsIAtom* aChildType);
|
||||
/**
|
||||
* @param aReflowState the context within which we're to determine the table width info
|
||||
* @param aSpecifiedTableWidth [OUT] if the table is not auto-width,
|
||||
@ -143,10 +151,6 @@ public:
|
||||
PRBool IsRowGroup(PRInt32 aDisplayType) const;
|
||||
|
||||
/** Initialize the table frame with a set of children.
|
||||
* Calls DidAppendRowGroup which calls nsTableRowFrame::InitChildren
|
||||
* which finally calls back into this table frame to build the cell map.
|
||||
* Also ensures we have the right number of column frames for the child list.
|
||||
*
|
||||
* @see nsIFrame::SetInitialChildList
|
||||
*/
|
||||
NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext,
|
||||
@ -162,16 +166,6 @@ public:
|
||||
NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex,
|
||||
nsIAtom** aListName) const;
|
||||
|
||||
/** complete the append of aRowGroupFrame to the table
|
||||
* this builds the cell map by calling nsTableRowFrame::InitChildren
|
||||
* which calls back into this table frame to build the cell map.
|
||||
* @param aRowGroupFrame the row group that was appended.
|
||||
* note that this method is optimized for content appended, and doesn't
|
||||
* work for random insertion of row groups. Random insertion must go
|
||||
* through incremental reflow notifications.
|
||||
*/
|
||||
NS_IMETHOD DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFrame);
|
||||
|
||||
/** @see nsIFrame::Paint */
|
||||
NS_IMETHOD Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
@ -221,6 +215,8 @@ public:
|
||||
*/
|
||||
NS_METHOD GetColumnFrame(PRInt32 aColIndex, nsTableColFrame *&aColFrame);
|
||||
|
||||
nsFrameList& GetColGroups();
|
||||
|
||||
/** return PR_TRUE if the column width information has been set */
|
||||
PRBool IsColumnWidthsSet();
|
||||
|
||||
@ -308,14 +304,84 @@ public:
|
||||
*/
|
||||
PRInt32 GetNextAvailRowIndex() const;
|
||||
|
||||
/** build as much of the CellMap as possible from the info we have so far
|
||||
*/
|
||||
virtual PRInt32 AddCellToTable (nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
virtual void RemoveCellFromTable (nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
/** return the column frame associated with aColIndex */
|
||||
nsTableColFrame* GetColFrame(PRInt32 aColIndex) const;
|
||||
|
||||
virtual void AddColumnFrame (nsTableColFrame *aColFrame);
|
||||
void InsertCol(nsIPresContext& aPresContext,
|
||||
nsTableColFrame& aColFrame,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
nsTableColGroupFrame* CreateAnonymousColGroupFrame(nsIPresContext& aPresContext,
|
||||
nsTableColGroupType aType);
|
||||
|
||||
PRInt32 DestroyAnonymousColFrames(nsIPresContext& aPresContext,
|
||||
PRInt32 aNumFrames);
|
||||
|
||||
void CreateAnonymousColFrames(nsIPresContext& aPresContext,
|
||||
PRInt32 aNumColsToAdd,
|
||||
nsTableColType aColType,
|
||||
PRBool aDoAppend,
|
||||
nsIFrame* aPrevCol = nsnull);
|
||||
|
||||
void CreateAnonymousColFrames(nsIPresContext& aPresContext,
|
||||
nsTableColGroupFrame& aColGroupFrame,
|
||||
PRInt32 aNumColsToAdd,
|
||||
nsTableColType aColType,
|
||||
PRBool aAddToColGroupAndTable,
|
||||
nsIFrame* aPrevCol,
|
||||
nsIFrame** aFirstNewFrame);
|
||||
|
||||
/** empty the column frame cache */
|
||||
void ClearColCache();
|
||||
|
||||
virtual PRInt32 AppendCell(nsIPresContext& aPresContext,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
virtual void InsertCells(nsIPresContext& aPresContext,
|
||||
nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore);
|
||||
|
||||
virtual void RemoveCell(nsIPresContext& aPresContext,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
void AppendRows(nsIPresContext& aPresContext,
|
||||
nsVoidArray& aRowFrames);
|
||||
|
||||
PRInt32 InsertRow(nsIPresContext& aPresContext,
|
||||
nsIFrame& aFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
PRInt32 InsertRows(nsIPresContext& aPresContext,
|
||||
nsVoidArray& aFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
virtual void RemoveRows(nsIPresContext& aPresContext,
|
||||
PRInt32 aFirstRowFrame,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRBool aConsiderSpans);
|
||||
|
||||
void AppendRowGroups(nsIPresContext& aPresContext,
|
||||
nsIFrame* aFirstRowGroupFrame);
|
||||
|
||||
void InsertRowGroups(nsIPresContext& aPresContext,
|
||||
nsIFrame* aFirstRowGroupFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
void InsertColGroups(nsIPresContext& aPresContext,
|
||||
PRInt32 aColIndex,
|
||||
nsIFrame* aFirstFrame,
|
||||
nsIFrame* aLastFrame = nsnull);
|
||||
|
||||
virtual void RemoveCol(nsIPresContext& aPresContext,
|
||||
nsTableColGroupFrame* aColGroupFrame,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aRemoveFromCache,
|
||||
PRBool aRemoveFromCellMap);
|
||||
|
||||
static PRBool IsFinalPass(const nsHTMLReflowState& aReflowState);
|
||||
|
||||
@ -323,7 +389,7 @@ public:
|
||||
PRInt32 aColX,
|
||||
PRBool* aOriginates = nsnull,
|
||||
PRInt32* aColSpan = nsnull);
|
||||
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
|
||||
|
||||
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
|
||||
|
||||
NS_METHOD GetBorderPlusMarginPadding(nsMargin& aResult);
|
||||
@ -554,9 +620,6 @@ protected:
|
||||
/** returns PR_TRUE if the cached pass 1 data is still valid */
|
||||
virtual PRBool IsFirstPassValid() const;
|
||||
|
||||
/** returns PR_TRUE if the cached column info is still valid */
|
||||
virtual PRBool IsColumnCacheValid() const;
|
||||
|
||||
/** returns PR_TRUE if the cached column info is still valid */
|
||||
virtual PRBool IsColumnWidthsValid() const;
|
||||
|
||||
@ -612,8 +675,6 @@ public:
|
||||
|
||||
virtual void InvalidateFirstPassCache();
|
||||
|
||||
virtual void InvalidateColumnCache();
|
||||
|
||||
virtual void InvalidateColumnWidths();
|
||||
|
||||
protected:
|
||||
@ -623,38 +684,18 @@ protected:
|
||||
void MapHTMLBorderStyle(nsStyleSpacing& aSpacingStyle, nscoord aBorderWidth);
|
||||
PRBool ConvertToPixelValue(nsHTMLValue& aValue, PRInt32 aDefault, PRInt32& aResult);
|
||||
|
||||
/** returns PR_TRUE if the cached pass 1 data is still valid */
|
||||
virtual PRBool IsCellMapValid() const;
|
||||
|
||||
public:
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
virtual nsCellMap *GetCellMap() const;
|
||||
|
||||
/** ResetCellMap is called when the cell structure of the table is changed.
|
||||
* Call with caution, only when changing the structure of the table such as
|
||||
* inserting or removing rows, changing the rowspan or colspan attribute of a cell, etc.
|
||||
*/
|
||||
virtual void InvalidateCellMap();
|
||||
|
||||
/** sum the columns represented by all nsTableColGroup objects.
|
||||
* if the cell map says there are more columns than this,
|
||||
* add extra implicit columns to the content tree.
|
||||
*
|
||||
* returns whether any implicit column frames were created
|
||||
*/
|
||||
virtual void EnsureColumns (nsIPresContext* aPresContext,
|
||||
PRBool& aCreatedColFrames);
|
||||
|
||||
// These methods are used to incrementally insert and remove rows
|
||||
// from the cell map without having to invalidate the entire map.
|
||||
NS_IMETHOD InsertRowIntoMap(nsTableRowFrame* aRow, PRInt32 aRowIndex);
|
||||
NS_IMETHOD RemoveRowFromMap(nsTableRowFrame* aRow, PRInt32 aRowIndex);
|
||||
void AdjustRowIndices(PRInt32 aRowIndex,
|
||||
PRInt32 aAdjustment);
|
||||
|
||||
NS_IMETHOD AdjustRowIndices(nsIFrame* aRowGroup,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 anAdjustment);
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 anAdjustment);
|
||||
|
||||
// Return PR_TRUE if rules=groups is set for the table content
|
||||
PRBool HasGroupRules() const;
|
||||
@ -662,9 +703,9 @@ public:
|
||||
// Remove cell borders which aren't bordering row and/or col groups
|
||||
void ProcessGroupRules(nsIPresContext* aPresContext);
|
||||
|
||||
nsVoidArray& GetColCache();
|
||||
|
||||
protected:
|
||||
/** iterates all child frames and creates a new cell map */
|
||||
NS_IMETHOD ReBuildCellMap();
|
||||
|
||||
void SetColumnDimensions(nsIPresContext* aPresContext, nscoord aHeight);
|
||||
|
||||
@ -685,7 +726,14 @@ protected:
|
||||
/**
|
||||
* Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
|
||||
*/
|
||||
nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame, const nsStyleDisplay* aDisplay);
|
||||
nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame,
|
||||
const nsStyleDisplay* aDisplay);
|
||||
|
||||
nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
|
||||
nsIAtom* aFrameTypeIn = nsnull);
|
||||
|
||||
void CollectRows(nsIFrame* aFrame,
|
||||
nsVoidArray& aCollection);
|
||||
|
||||
public: /* ----- Cell Map public methods ----- */
|
||||
|
||||
@ -752,14 +800,16 @@ public: /* ----- Cell Map public methods ----- */
|
||||
|
||||
/*------------end of nsITableLayout methods -----------------------*/
|
||||
|
||||
|
||||
virtual void CacheColFrames(nsIPresContext* aPresContext,
|
||||
PRBool aReset = PR_FALSE);
|
||||
public:
|
||||
static nsIAtom* gColGroupAtom;
|
||||
void Dump(PRBool aDumpCols, PRBool aDumpCellMap);
|
||||
void Dump(PRBool aDumpRows,
|
||||
PRBool aDumpCols,
|
||||
PRBool aDumpCellMap);
|
||||
|
||||
nsVoidArray mColFrames; // XXX temporarily public
|
||||
|
||||
protected:
|
||||
void DumpRowGroup(nsIFrame* aChildFrame);
|
||||
void DebugPrintCount() const; // Debugging routine
|
||||
|
||||
// data members
|
||||
@ -770,15 +820,11 @@ protected:
|
||||
unsigned mColumnWidthsSet:1; // PR_TRUE if column widths have been set at least once
|
||||
unsigned mColumnWidthsValid:1; // PR_TRUE if column width data is still legit, PR_FALSE if it needs to be recalculated
|
||||
unsigned mFirstPassValid:1; // PR_TRUE if first pass data is still legit, PR_FALSE if it needs to be recalculated
|
||||
unsigned mColumnCacheValid:1; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated
|
||||
unsigned mCellMapValid:1; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated
|
||||
unsigned mIsInvariantWidth:1; // PR_TRUE if table width cannot change
|
||||
unsigned mHasScrollableRowGroup:1; // PR_TRUE if any section has overflow == "auto" or "scroll"
|
||||
unsigned mNonPercentSpansPercent:1;
|
||||
int : 24; // unused
|
||||
int : 26; // unused
|
||||
} mBits;
|
||||
|
||||
PRInt32 mColCount; // the number of columns in this table
|
||||
nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
|
||||
nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame
|
||||
nsFrameList mColGroups; // the list of colgroup frames
|
||||
@ -811,6 +857,16 @@ inline void nsTableFrame::SetHasNonPercentSpanningPercent(PRBool aValue)
|
||||
mBits.mNonPercentSpansPercent = (unsigned)aValue;
|
||||
}
|
||||
|
||||
inline nsFrameList& nsTableFrame::GetColGroups()
|
||||
{
|
||||
return mColGroups;
|
||||
}
|
||||
|
||||
inline nsVoidArray& nsTableFrame::GetColCache()
|
||||
{
|
||||
return mColFrames;
|
||||
}
|
||||
|
||||
enum nsTableIteration {
|
||||
eTableLTR = 0,
|
||||
eTableRTL = 1,
|
||||
|
@ -56,6 +56,7 @@ nsTableRowFrame::nsTableRowFrame()
|
||||
mAllBits(0)
|
||||
{
|
||||
mBits.mMinRowSpan = 1;
|
||||
mBits.mRowIndex = 0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -129,23 +130,11 @@ nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == display->mDisplay) {
|
||||
// Add the cell to the cell map
|
||||
PRInt32 colIndex = tableFrame->AddCellToTable((nsTableCellFrame*)childFrame,
|
||||
GetRowIndex());
|
||||
|
||||
// Initialize the cell frame and give it its column index
|
||||
((nsTableCellFrame*)childFrame)->InitCellFrame(colIndex);
|
||||
tableFrame->AppendCell(*aPresContext, (nsTableCellFrame&)*childFrame, GetRowIndex());
|
||||
}
|
||||
}
|
||||
|
||||
// See if any implicit column frames need to be created as a result of
|
||||
// adding the new rows
|
||||
PRBool createdColFrames;
|
||||
tableFrame->EnsureColumns(aPresContext, createdColFrames);
|
||||
if (createdColFrames) {
|
||||
// We need to rebuild the column cache
|
||||
// XXX It would be nice if this could be done incrementally
|
||||
tableFrame->InvalidateColumnCache();
|
||||
}
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
@ -160,6 +149,7 @@ nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
@ -171,26 +161,39 @@ nsTableRowFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
// Insert the frames
|
||||
// gather the new frames (only those which are cells) into an array
|
||||
nsTableCellFrame* prevCellFrame = (nsTableCellFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, nsLayoutAtoms::tableCellFrame);
|
||||
nsVoidArray cellChildren;
|
||||
for (nsIFrame* childFrame = aFrameList; childFrame; childFrame->GetNextSibling(&childFrame)) {
|
||||
nsIAtom* frameType;
|
||||
childFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType) {
|
||||
cellChildren.AppendElement(childFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
// insert the cells into the cell map
|
||||
PRInt32 colIndex = -1;
|
||||
if (prevCellFrame) {
|
||||
prevCellFrame->GetColIndex(colIndex);
|
||||
}
|
||||
tableFrame->InsertCells(*aPresContext, cellChildren, GetRowIndex(), colIndex);
|
||||
|
||||
// Insert the frames in the frame list
|
||||
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't insert
|
||||
// new frames except at the end (append)
|
||||
tableFrame->InvalidateCellMap();
|
||||
// Because the number of columns may have changed invalidate the column widths
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// We should try and avoid doing a pass1 reflow on all the cells and just
|
||||
// do it for the newly added frames, but we need to add these frames to the
|
||||
// cell map before we reflow them
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
if (NS_SUCCEEDED(NS_NewHTMLReflowCommand(&reflowCmd, this,
|
||||
nsIReflowCommand::ReflowDirty))) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -203,91 +206,28 @@ nsTableRowFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
nsIAtom* frameType;
|
||||
aOldFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aOldFrame;
|
||||
PRInt32 colIndex;
|
||||
cellFrame->GetColIndex(colIndex);
|
||||
tableFrame->RemoveCell(*aPresContext, cellFrame, GetRowIndex());
|
||||
|
||||
#if 0
|
||||
// XXX Currently we can't incrementally remove cells from the cell map
|
||||
PRInt32 colIndex;
|
||||
aDeletedFrame->GetColIndex(colIndex);
|
||||
tableFrame->RemoveCellFromTable(aOldFrame, GetRowIndex());
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, (nsIFrame*)aOldFrame);
|
||||
// cells have possibly shifted into different columns.
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// XXX Reflow the row
|
||||
|
||||
#else
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't incrementally
|
||||
// remove rows
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Because we haven't added any new frames we don't need to do a pass1
|
||||
// reflow. Just generate a reflow command so we reflow the table itself
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InitChildrenWithIndex(PRInt32 aRowIndex)
|
||||
{
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
// each child cell can only be added to the table one time.
|
||||
// for now, we remember globally whether we've added all or none
|
||||
if (0 == (mState & NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN))
|
||||
{
|
||||
result = nsTableFrame::GetTableFrame(this, table);
|
||||
if ((NS_OK==result) && (table != nsnull))
|
||||
{
|
||||
mState |= NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN;
|
||||
SetRowIndex(aRowIndex);
|
||||
|
||||
for (nsIFrame* kidFrame = mFrames.FirstChild(); nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
|
||||
{
|
||||
const nsStyleDisplay *kidDisplay;
|
||||
kidFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
|
||||
{
|
||||
// add the cell frame to the table's cell map and get its col index
|
||||
PRInt32 colIndex;
|
||||
colIndex = table->AddCellToTable((nsTableCellFrame *)kidFrame, aRowIndex);
|
||||
// what column does this cell belong to?
|
||||
// this sets the frame's notion of its column index
|
||||
((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
|
||||
}
|
||||
}
|
||||
// Because we haven't added any new frames we don't need to do a pass1
|
||||
// reflow. Just generate a reflow command so we reflow the table itself
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InitChildren()
|
||||
{
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
// each child cell can only be added to the table one time.
|
||||
// for now, we remember globally whether we've added all or none
|
||||
if (0 == (mState & NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN))
|
||||
{
|
||||
result = nsTableFrame::GetTableFrame(this, table);
|
||||
if ((NS_OK==result) && (table != nsnull))
|
||||
{
|
||||
PRInt32 rowIndex = table->GetNextAvailRowIndex();
|
||||
InitChildrenWithIndex(rowIndex);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -62,9 +62,6 @@ struct RowReflowState {
|
||||
/**
|
||||
* Additional frame-state bits
|
||||
*/
|
||||
#define NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN 0x80000000 // set if child cells have been
|
||||
// added to the table
|
||||
|
||||
#define NS_TABLE_MAX_ROW_INDEX (1<<19)
|
||||
|
||||
/**
|
||||
@ -100,12 +97,6 @@ public:
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
/** Initialization of data */
|
||||
NS_IMETHOD InitChildren();
|
||||
NS_IMETHOD InitChildrenWithIndex(PRInt32 aRowIndex);
|
||||
|
||||
void ResetInitChildren();
|
||||
|
||||
/** instantiate a new instance of nsTableRowFrame.
|
||||
* @param aResult the new object is returned in this out-param
|
||||
* @param aContent the table object to map
|
||||
@ -322,11 +313,6 @@ inline void nsTableRowFrame::SetRowIndex (int aRowIndex)
|
||||
mBits.mRowIndex = aRowIndex;
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::ResetInitChildren()
|
||||
{
|
||||
mState &= ~NS_TABLE_ROW_FRAME_INITIALIZED_CHILDREN;
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::GetMaxElementSize(nsSize& aMaxElementSize) const
|
||||
{
|
||||
aMaxElementSize.width = mMaxElementSize.width;
|
||||
|
@ -565,6 +565,7 @@ NS_METHOD nsTableRowGroupFrame::PullUpAllRowFrames(nsIPresContext* aPresContext)
|
||||
|
||||
void nsTableRowGroupFrame::GetNextRowSibling(nsIFrame** aRowFrame)
|
||||
{
|
||||
if (!*aRowFrame) return;
|
||||
GetNextFrame(*aRowFrame, aRowFrame);
|
||||
while(*aRowFrame) {
|
||||
const nsStyleDisplay *display;
|
||||
@ -596,7 +597,9 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
PRBool hasRowSpanningCell = PR_FALSE;
|
||||
PRInt32 numRows;
|
||||
GetRowCount(numRows, PR_FALSE);
|
||||
if (numRows <= 0) return;
|
||||
nscoord *rowHeights = new nscoord[numRows];
|
||||
if (!rowHeights) return;
|
||||
nsCRT::memset (rowHeights, 0, numRows*sizeof(nscoord));
|
||||
|
||||
/* Step 1: get the height of the tallest cell in the row and save it for
|
||||
@ -747,10 +750,11 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
// If this is pass 2 then resize the row to its final size and move the
|
||||
// row's position if the previous rows have caused a shift
|
||||
if (1 == counter) {
|
||||
nsRect rowBounds;
|
||||
rowFrame->GetRect(rowBounds);
|
||||
PRBool movedFrame = (deltaY != 0);
|
||||
nsRect rowBounds;
|
||||
|
||||
// Move the row to the correct position
|
||||
rowFrame->GetRect(rowBounds); // added
|
||||
rowBounds.y += deltaY;
|
||||
|
||||
// Adjust our running delta
|
||||
@ -759,6 +763,17 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
// Resize the row to its final size and position
|
||||
rowBounds.height = rowHeights[rowIndex];
|
||||
rowFrame->SetRect(aPresContext, rowBounds);
|
||||
|
||||
if (movedFrame) {
|
||||
// Make sure any views are positioned properly
|
||||
nsIView* view;
|
||||
rowFrame->GetView(aPresContext, &view);
|
||||
if (view) {
|
||||
nsContainerFrame::PositionFrameView(aPresContext, rowFrame, view);
|
||||
} else {
|
||||
nsContainerFrame::PositionChildViews(aPresContext, rowFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rowIndex++;
|
||||
@ -1155,45 +1170,47 @@ nsTableRowGroupFrame::AddTableDirtyReflowCommand(nsIPresContext* aPresContext,
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
|
||||
if (NS_SUCCEEDED(NS_NewHTMLReflowCommand(&reflowCmd, this,
|
||||
nsIReflowCommand::ReflowDirty))) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
#endif
|
||||
|
||||
// this does not get called for trees
|
||||
NS_IMETHODIMP
|
||||
nsTableRowGroupFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
// collect the new row frames in an array
|
||||
nsVoidArray rows;
|
||||
for (nsIFrame* rowFrame = aFrameList; rowFrame; rowFrame->GetNextSibling(&rowFrame)) {
|
||||
nsIAtom* frameType;
|
||||
rowFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableRowFrame == frameType) {
|
||||
rows.AppendElement(rowFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
|
||||
// Append the frames
|
||||
// Append the frames to the sibling chain
|
||||
mFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
const nsStyleDisplay *display;
|
||||
aFrameList->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
// See if the newly appended rows are the last rows in the table.
|
||||
// XXX is this the correct code path for nested row groups, considering that whitespace frames may exist currently
|
||||
if ((NS_STYLE_DISPLAY_TABLE_ROW_GROUP != display->mDisplay) && NoRowsFollow()) {
|
||||
// The rows we appended are the last rows in the table so incrementally
|
||||
// add them to the cell map
|
||||
PRBool haveRows = PR_FALSE;
|
||||
for (nsIFrame* rowFrame = aFrameList; rowFrame; rowFrame->GetNextSibling(&rowFrame)) {
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == display->mDisplay) {
|
||||
DidAppendRow((nsTableRowFrame*)rowFrame);
|
||||
haveRows = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (rows.Count() > 0) {
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
tableFrame->AppendRows(*aPresContext, rows);
|
||||
|
||||
if (haveRows) {
|
||||
// See if any implicit column frames need to be created as a result of
|
||||
// adding the new rows
|
||||
PRBool createdColFrames;
|
||||
tableFrame->EnsureColumns(aPresContext, createdColFrames);
|
||||
if (createdColFrames) {
|
||||
// We need to rebuild the column cache
|
||||
// XXX It would be nice if this could be done incrementally
|
||||
tableFrame->InvalidateColumnCache();
|
||||
}
|
||||
// Because the number of columns may have changed invalidate the column widths
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
@ -1205,29 +1222,12 @@ nsTableRowGroupFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We need to rebuild the cell map, because currently we can't insert
|
||||
// new frames except at the end (append)
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// We should try and avoid doing a pass1 reflow on all the cells and just
|
||||
// do it for the newly added frames, but we need to add these frames to the
|
||||
// cell map before we reflow them
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// this does not get called for trees
|
||||
NS_IMETHODIMP
|
||||
nsTableRowGroupFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
@ -1235,65 +1235,76 @@ nsTableRowGroupFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
// collect the new row frames in an array
|
||||
nsVoidArray rows;
|
||||
for (nsIFrame* rowFrame = aFrameList; rowFrame; rowFrame->GetNextSibling(&rowFrame)) {
|
||||
nsIAtom* frameType;
|
||||
rowFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableRowFrame == frameType) {
|
||||
rows.AppendElement(rowFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
|
||||
// Insert the frames
|
||||
// Insert the frames in the sibling chain
|
||||
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't insert
|
||||
// new frames except at the end (append)
|
||||
tableFrame->InvalidateCellMap();
|
||||
if (rows.Count() > 0) {
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
nsTableRowFrame* prevRow = (nsTableRowFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, nsLayoutAtoms::tableRowFrame);
|
||||
PRInt32 rowIndex = (prevRow) ? prevRow->GetRowIndex() : 0;
|
||||
tableFrame->InsertRows(*aPresContext, rows, rowIndex, PR_TRUE);
|
||||
|
||||
// We should try and avoid doing a pass1 reflow on all the cells and just
|
||||
// do it for the newly added frames, but we need to add these frames to the
|
||||
// cell map before we reflow them
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
// Reflow the new frames. They're already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
if (NS_SUCCEEDED(NS_NewHTMLReflowCommand(&reflowCmd, this,
|
||||
nsIReflowCommand::ReflowDirty))) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
|
||||
// Because the number of columns may have changed invalidate the column widths
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a reflow command so we reflow the table itself. This will
|
||||
// do a pass-1 reflow of all the rows including any rows we just added
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// this does not get called for trees
|
||||
NS_IMETHODIMP
|
||||
nsTableRowGroupFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
aOldFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
|
||||
PRBool validChild = (NS_STYLE_DISPLAY_TABLE_ROW == display->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == display->mDisplay);
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (tableFrame) {
|
||||
nsIAtom* frameType;
|
||||
aOldFrame->GetFrameType(&frameType);
|
||||
if (nsLayoutAtoms::tableRowFrame == frameType) {
|
||||
PRInt32 firstRowIndex = ((nsTableRowFrame *)aOldFrame)->GetRowIndex();
|
||||
|
||||
// Remove the frame and destroy it
|
||||
if (mFrames.DestroyFrame(aPresContext, aOldFrame)) {
|
||||
if (validChild) {
|
||||
// Get the table frame
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
// We need to rebuild the cell map, because currently we can't incrementally
|
||||
// remove rows
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// Because the number of columns may have changed invalidate the column
|
||||
// cache. Note that this has the side effect of recomputing the column
|
||||
// widths, so we don't need to call InvalidateColumnWidths()
|
||||
tableFrame->InvalidateColumnCache();
|
||||
tableFrame->RemoveRows(*aPresContext, firstRowIndex, 1, PR_TRUE);
|
||||
// Because the number of columns may have changed invalidate the column widths
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
|
||||
// Because we haven't added any new frames we don't need to do a pass1
|
||||
// reflow. Just generate a reflow command so we reflow the table itself
|
||||
AddTableDirtyReflowCommand(aPresContext, aPresShell, tableFrame);
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
}
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1350,54 +1361,6 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext* aPresContext,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
/* need to make space in the cell map. Remeber that row spans can't cross row groups
|
||||
once the space is made, tell the row to initizalize its children.
|
||||
it will automatically find the row to initialize into.
|
||||
but this is tough because a cell in aInsertedFrame could have a rowspan
|
||||
which must be respected if a subsequent row is appended.
|
||||
*/
|
||||
rv = aRowFrame->InitChildren();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// support method that tells us if there are any rows in the table after our rows
|
||||
// returns PR_TRUE if there are no rows after ours
|
||||
PRBool nsTableRowGroupFrame::NoRowsFollow()
|
||||
{
|
||||
// XXX This method doesn't play well with the tree widget.
|
||||
PRBool result = PR_TRUE;
|
||||
nsIFrame *nextSib=nsnull;
|
||||
GetNextSibling(&nextSib);
|
||||
while (nsnull!=nextSib)
|
||||
{
|
||||
const nsStyleDisplay *sibDisplay;
|
||||
nextSib->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)sibDisplay));
|
||||
if ((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == sibDisplay->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == sibDisplay->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == sibDisplay->mDisplay))
|
||||
{
|
||||
nsIFrame *childFrame=nsnull;
|
||||
nextSib->FirstChild(nsnull, &childFrame);
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{ // found a row
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
}
|
||||
nextSib->GetNextSibling(&nextSib);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::GetHeightOfRows(nscoord& aResult)
|
||||
{
|
||||
// the rows in rowGroupFrame need to be expanded by rowHeightDelta[i]
|
||||
|
@ -244,10 +244,6 @@ protected:
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD DidAppendRow(nsTableRowFrame *aRowFrame);
|
||||
|
||||
PRBool NoRowsFollow();
|
||||
|
||||
nsresult AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
|
@ -498,8 +498,6 @@ NS_IMETHODIMP
|
||||
nsTreeFrame::MarkForDirtyReflow(nsIPresContext* aPresContext)
|
||||
{
|
||||
mSuppressReflow = PR_FALSE;
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
InvalidateFirstPassCache();
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
|
@ -91,7 +91,7 @@ NS_METHOD nsTreeRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -45,6 +45,28 @@
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsTreeItemDragCapturer.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
// I added the following function to improve keeping the frame
|
||||
// chains in synch with the table. repackage as appropriate - karnaze
|
||||
void GetRowStartAndCount(nsIFrame* aFrame,
|
||||
PRInt32& aStartRowIndex,
|
||||
PRInt32& aNumRows)
|
||||
{
|
||||
aStartRowIndex = -1;
|
||||
aNumRows = 0;
|
||||
nsIAtom* fType;
|
||||
aFrame->GetFrameType(&fType);
|
||||
if (nsLayoutAtoms::tableRowFrame == fType) {
|
||||
aStartRowIndex = ((nsTableRowFrame*)aFrame)->GetRowIndex();
|
||||
aNumRows = 0;
|
||||
}
|
||||
else if (nsLayoutAtoms::tableRowGroupFrame == fType) {
|
||||
aStartRowIndex = ((nsTableRowGroupFrame*)aFrame)->GetStartRowIndex();
|
||||
((nsTableRowGroupFrame*)aFrame)->GetRowCount(aNumRows);
|
||||
}
|
||||
NS_IF_RELEASE(fType);
|
||||
}
|
||||
|
||||
static nsILayoutHistoryState*
|
||||
GetStateStorageObject(nsTreeRowGroupFrame* aTreeRowGroupFrame,
|
||||
@ -179,6 +201,7 @@ void nsTreeRowGroupFrame::DestroyRows(nsTableFrame* aTableFrame, nsIPresContext*
|
||||
// reduced. A reflow will then pick up and create the new frames.
|
||||
nsIFrame* childFrame = GetFirstFrame();
|
||||
while (childFrame && rowsToLose > 0) {
|
||||
PRBool rowIndex = -1;
|
||||
if (IsTableRowGroupFrame(childFrame))
|
||||
{
|
||||
PRInt32 rowGroupCount;
|
||||
@ -196,16 +219,18 @@ void nsTreeRowGroupFrame::DestroyRows(nsTableFrame* aTableFrame, nsIPresContext*
|
||||
{
|
||||
// Lost a row.
|
||||
rowsToLose--;
|
||||
|
||||
// Remove this row from our cell map.
|
||||
nsTableRowFrame* rowFrame = (nsTableRowFrame*)childFrame;
|
||||
aTableFrame->RemoveRowFromMap(rowFrame, rowFrame->GetRowIndex());
|
||||
rowIndex = ((nsTableRowFrame*)childFrame)->GetRowIndex();
|
||||
}
|
||||
|
||||
nsIFrame* nextFrame;
|
||||
GetNextFrame(childFrame, &nextFrame);
|
||||
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, childFrame, GetStateStorageObject(this, aTableFrame));
|
||||
mFrames.DestroyFrame(aPresContext, childFrame);
|
||||
// remove the row from the table after it is removed from the sibling chain
|
||||
if (rowIndex >= 0) {
|
||||
aTableFrame->RemoveRows(*aPresContext, rowIndex, 1, PR_FALSE);
|
||||
aTableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
mTopFrame = childFrame = nextFrame;
|
||||
}
|
||||
}
|
||||
@ -216,6 +241,7 @@ void nsTreeRowGroupFrame::ReverseDestroyRows(nsTableFrame* aTableFrame, nsIPresC
|
||||
// reduced. A reflow will then pick up and create the new frames.
|
||||
nsIFrame* childFrame = GetLastFrame();
|
||||
while (childFrame && rowsToLose > 0) {
|
||||
PRInt32 rowIndex = -1;
|
||||
if (IsTableRowGroupFrame(childFrame))
|
||||
{
|
||||
PRInt32 rowGroupCount;
|
||||
@ -233,15 +259,18 @@ void nsTreeRowGroupFrame::ReverseDestroyRows(nsTableFrame* aTableFrame, nsIPresC
|
||||
{
|
||||
// Lost a row.
|
||||
rowsToLose--;
|
||||
// Remove this row from our cell map.
|
||||
nsTableRowFrame* rowFrame = (nsTableRowFrame*)childFrame;
|
||||
aTableFrame->RemoveRowFromMap(rowFrame, rowFrame->GetRowIndex());
|
||||
rowIndex = ((nsTableRowFrame*)childFrame)->GetRowIndex();
|
||||
}
|
||||
|
||||
nsIFrame* prevFrame;
|
||||
prevFrame = mFrames.GetPrevSiblingFor(childFrame);
|
||||
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, childFrame, GetStateStorageObject(this, aTableFrame));
|
||||
mFrames.DestroyFrame(aPresContext, childFrame);
|
||||
// remove the row from the table after it is removed from the sibling chain
|
||||
if (rowIndex >= 0) {
|
||||
aTableFrame->RemoveRows(*aPresContext, rowIndex, 1, PR_FALSE);
|
||||
aTableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
mBottomFrame = childFrame = prevFrame;
|
||||
}
|
||||
}
|
||||
@ -714,9 +743,19 @@ nsTreeRowGroupFrame::PositionChanged(nsIPresContext* aPresContext, PRInt32 aOldI
|
||||
// Just blow away all our frames, but keep a content chain
|
||||
// as a hint to figure out how to build the frames.
|
||||
// Remove the scrollbar first.
|
||||
// get the starting row index and row count
|
||||
PRInt32 startRowIndex, numRows;
|
||||
GetRowStartAndCount(this, startRowIndex, numRows);
|
||||
|
||||
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, this, GetStateStorageObject(this, tableFrame));
|
||||
mFrames.DestroyFrames(aPresContext);
|
||||
tableFrame->InvalidateCellMap();
|
||||
|
||||
// remove the rows from the table after removing from the sibling chain
|
||||
if ((startRowIndex >= 0) && (numRows > 0)) {
|
||||
tableFrame->RemoveRows(*aPresContext, startRowIndex, rowCount, PR_FALSE);
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> topRowContent;
|
||||
FindRowContentAtIndex(aNewIndex, mContent, getter_AddRefs(topRowContent));
|
||||
|
||||
@ -1189,9 +1228,11 @@ nsTreeRowGroupFrame::GetFirstFrameForReflow(nsIPresContext* aPresContext)
|
||||
|
||||
FindPreviousRowContent(delta, rowContent, nsnull, getter_AddRefs(topRowContent));
|
||||
|
||||
AddRowToMap(tableFrame, aPresContext, topRowContent, mTopFrame);
|
||||
|
||||
PostAppendRow(mTopFrame, aPresContext);
|
||||
PRInt32 numColsAdded = AddRowToMap(tableFrame, *aPresContext, topRowContent, mTopFrame);
|
||||
if (numColsAdded > 0) {
|
||||
MarkTreeAsDirty(aPresContext, (nsTreeFrame*) tableFrame);
|
||||
}
|
||||
//PostAppendRow(mTopFrame, aPresContext, aTableFrame->GetColCount());
|
||||
}
|
||||
else if (IsTableRowGroupFrame(mTopFrame) && mContentChain) {
|
||||
// We have just instantiated a row group, and we have a content chain. This
|
||||
@ -1268,8 +1309,11 @@ nsTreeRowGroupFrame::GetNextFrameForReflow(nsIPresContext* aPresContext, nsIFram
|
||||
nsCOMPtr<nsIContent> topRowContent;
|
||||
PRInt32 delta = 1;
|
||||
FindPreviousRowContent(delta, nextContent, nsnull, getter_AddRefs(topRowContent));
|
||||
AddRowToMap(tableFrame, aPresContext, topRowContent, (*aResult));
|
||||
PostAppendRow(*aResult, aPresContext);
|
||||
PRInt32 numColsAdded = AddRowToMap(tableFrame, *aPresContext, topRowContent, (*aResult));
|
||||
if (numColsAdded > 0) {
|
||||
MarkTreeAsDirty(aPresContext, (nsTreeFrame*) tableFrame);
|
||||
}
|
||||
//PostAppendRow(*aResult, aPresContext, tableFrame->GetColCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1296,7 +1340,6 @@ nsTreeRowGroupFrame::TreeAppendFrames(nsIFrame* aFrameList)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
PRBool nsTreeRowGroupFrame::ContinueReflow(nsIPresContext* aPresContext, nscoord y, nscoord height)
|
||||
{
|
||||
//printf("Y is: %d\n", y);
|
||||
@ -1316,10 +1359,23 @@ PRBool nsTreeRowGroupFrame::ContinueReflow(nsIPresContext* aPresContext, nscoord
|
||||
nsIFrame* currFrame;
|
||||
startingPoint->GetNextSibling(&currFrame);
|
||||
while (currFrame) {
|
||||
// get the starting row index and row count
|
||||
PRInt32 startRowIndex, numRows;
|
||||
GetRowStartAndCount(currFrame, startRowIndex, numRows);
|
||||
|
||||
nsIFrame* nextFrame;
|
||||
currFrame->GetNextSibling(&nextFrame);
|
||||
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, currFrame, nsnull);
|
||||
mFrames.DestroyFrame(aPresContext, currFrame);
|
||||
|
||||
// remove the rows from the table after removing from the sibling chain
|
||||
if ((startRowIndex >= 0) && (numRows > 0)) {
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->RemoveRows(*aPresContext, startRowIndex, numRows, PR_FALSE);
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
|
||||
currFrame = nextFrame;
|
||||
//printf("Nuked one off the end.\n");
|
||||
}
|
||||
@ -1368,9 +1424,21 @@ void nsTreeRowGroupFrame::OnContentInserted(nsIPresContext* aPresContext, nsIFra
|
||||
currFrame->GetNextSibling(&nextFrame);
|
||||
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, currFrame,
|
||||
GetStateStorageObject(this, NULL));
|
||||
// get the starting row index and row count
|
||||
PRInt32 startRowIndex, numRows;
|
||||
GetRowStartAndCount(currFrame, startRowIndex, numRows);
|
||||
|
||||
mFrames.DestroyFrame(aPresContext, currFrame);
|
||||
currFrame = nextFrame;
|
||||
//printf("Nuked one off the end.\n");
|
||||
|
||||
// remove the rows from the table after removing from the sibling chain
|
||||
if ((startRowIndex >= 0) && (numRows > 0)) {
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
tableFrame->RemoveRows(*aPresContext, startRowIndex, numRows, PR_FALSE);
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
}
|
||||
OnContentAdded(aPresContext);
|
||||
|
||||
@ -1439,10 +1507,18 @@ void nsTreeRowGroupFrame::OnContentRemoved(nsIPresContext* aPresContext,
|
||||
|
||||
// Go ahead and delete the frame.
|
||||
if (aChildFrame) {
|
||||
// get the starting row index and row count
|
||||
PRInt32 startRowIndex, numRows;
|
||||
GetRowStartAndCount(aChildFrame, startRowIndex, numRows);
|
||||
|
||||
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, aChildFrame, nsnull);
|
||||
mFrames.DestroyFrame(aPresContext, aChildFrame);
|
||||
treeFrame->InvalidateCellMap();
|
||||
treeFrame->InvalidateColumnCache();
|
||||
|
||||
// remove the rows from the table after removing from the sibling chain
|
||||
if ((startRowIndex >= 0) && (numRows > 0)) {
|
||||
treeFrame->RemoveRows(*aPresContext, startRowIndex, numRows, PR_FALSE);
|
||||
treeFrame->InvalidateColumnWidths();
|
||||
}
|
||||
}
|
||||
|
||||
MarkTreeAsDirty(aPresContext, treeFrame);
|
||||
@ -1647,28 +1723,6 @@ nsTreeRowGroupFrame::GetCellFrameAtIndex(PRInt32 aRowIndex, PRInt32 aColIndex,
|
||||
#endif
|
||||
}
|
||||
|
||||
void nsTreeRowGroupFrame::PostAppendRow(nsIFrame* aRowFrame, nsIPresContext* aPresContext)
|
||||
{
|
||||
// shouldn't need this anymore
|
||||
// DidAppendRow((nsTableRowFrame*)aRowFrame);
|
||||
|
||||
// Get the table frame.
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
// See if any implicit column frames need to be created as a result of
|
||||
// adding the new rows
|
||||
PRBool createdColFrames;
|
||||
tableFrame->EnsureColumns(aPresContext, createdColFrames);
|
||||
if (createdColFrames) {
|
||||
// We need to rebuild the column cache
|
||||
// XXX It would be nice if this could be done incrementally
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
MarkTreeAsDirty(aPresContext, (nsTreeFrame*) tableFrame);
|
||||
}
|
||||
}
|
||||
|
||||
void nsTreeRowGroupFrame::ScrollByLines(nsIPresContext* aPresContext,
|
||||
PRInt32 lines)
|
||||
{
|
||||
@ -1726,18 +1780,23 @@ nsTreeRowGroupFrame::MarkTreeAsDirty(nsIPresContext* aPresContext, nsTreeFrame*
|
||||
|
||||
|
||||
// given a content node, insert a row into the cellmap
|
||||
// for wherever it belows in the map
|
||||
void
|
||||
nsTreeRowGroupFrame::AddRowToMap(nsTableFrame *aTableFrame,
|
||||
nsIPresContext* aPresContext,
|
||||
nsIContent *aContent,
|
||||
nsIFrame* aCurrentFrame)
|
||||
// for wherever it belows in the map. Return the number of new colums that were added
|
||||
PRInt32
|
||||
nsTreeRowGroupFrame::AddRowToMap(nsTableFrame* aTableFrame,
|
||||
nsIPresContext& aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aCurrentFrame)
|
||||
{
|
||||
PRInt32 insertionIndex =
|
||||
GetInsertionIndexForContent(aTableFrame, aPresContext, aContent);
|
||||
|
||||
aTableFrame->InsertRowIntoMap((nsTableRowFrame*)aCurrentFrame,
|
||||
insertionIndex);
|
||||
GetInsertionIndexForContent(aTableFrame, &aPresContext, aContent);
|
||||
|
||||
PRInt32 numNewCols = 0;
|
||||
if (aCurrentFrame) {
|
||||
numNewCols = aTableFrame->InsertRow(aPresContext, *aCurrentFrame,
|
||||
insertionIndex, PR_FALSE);
|
||||
}
|
||||
|
||||
return numNewCols;
|
||||
}
|
||||
|
||||
|
||||
|
@ -150,10 +150,6 @@ protected:
|
||||
|
||||
void ComputeTotalRowCount(PRInt32& rowCount, nsIContent* aParent);
|
||||
|
||||
void PostAppendRow(nsIFrame* aRowFrame, nsIPresContext* aPresContext);
|
||||
|
||||
void GetFirstRow(nsTableRowFrame **aRowFrame);
|
||||
|
||||
public:
|
||||
// Helpers that allow access to info. The tree is the primary consumer of this
|
||||
// info.
|
||||
@ -190,9 +186,11 @@ public:
|
||||
nsIPresContext* aPresContext,
|
||||
nsIContent *aContent);
|
||||
|
||||
void AddRowToMap(nsTableFrame *aTableFrame,
|
||||
nsIPresContext* aPresContext,
|
||||
nsIContent *aContent, nsIFrame *aCurrentFrame);
|
||||
// Also returns the number of new columns that were added
|
||||
PRInt32 AddRowToMap(nsTableFrame* aTableFrame,
|
||||
nsIPresContext& aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aCurrentFrame);
|
||||
|
||||
static PRBool IsTableRowGroupFrame(nsIFrame*);
|
||||
static PRBool IsTableRowFrame(nsIFrame*);
|
||||
|
Loading…
Reference in New Issue
Block a user