bug 28811, 29459, 32507 - added flag to reflow state to handle table cells.

changed table min and max width calculations to include percent and proportional cells.
Include border and padding in min table width calc.
This commit is contained in:
karnaze%netscape.com 2000-05-16 22:55:34 +00:00
parent 0d4272baff
commit 854d511d3e
7 changed files with 99 additions and 21 deletions

View File

@ -202,6 +202,12 @@ struct nsHTMLReflowState {
// set it. if false, the reflow sets alignCharOffset
PRPackedBool mUseAlignCharOffset;
// a table cell has a constrained mComputedWidth to accomodate its inner block.
// since it is treated like a containing block for percent calculations, this flag
// indicates not to use mComputedWidth for percent calculations if true.
// it also propogates into descendants whose width is percentage.
PRBool mIsAutoWidthPctBase;
// Cached pointers to the various style structs used during intialization
const nsStyleDisplay* mStyleDisplay;
const nsStylePosition* mStylePosition;

View File

@ -170,6 +170,7 @@ nsHTMLReflowState::Init(nsIPresContext* aPresContext,
mCompactMarginWidth = 0;
mAlignCharOffset = 0;
mUseAlignCharOffset = 0;
mIsAutoWidthPctBase = PR_FALSE;
frame->GetStyleData(eStyleStruct_Position,
(const nsStyleStruct*&)mStylePosition);
@ -1509,15 +1510,13 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
// the containingBlockHeight calcuation.
if (cbrs->parentReflowState) {
nsIFrame* f = cbrs->parentReflowState->frame;
nsIAtom* cbFrameType;
f->GetFrameType(&cbFrameType);
if (nsLayoutAtoms::scrollFrame == cbFrameType) {
nsCOMPtr<nsIAtom> fType;
f->GetFrameType(getter_AddRefs(fType));
if (nsLayoutAtoms::scrollFrame == fType.get()) {
// Use the scroll frame's computed height instead
aContainingBlockHeight =
((nsHTMLReflowState*)cbrs->parentReflowState)->mComputedHeight;
}
NS_IF_RELEASE(cbFrameType);
}
}
@ -1536,14 +1535,33 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
nsStyleUnit widthUnit = mStylePosition->mWidth.GetUnit();
nsStyleUnit heightUnit = mStylePosition->mHeight.GetUnit();
nsCOMPtr<nsIAtom> frameType;
frame->GetFrameType(getter_AddRefs(frameType));
// Check for a percentage based width and an unconstrained containing
// block width
if (eStyleUnit_Percent == widthUnit) {
if (NS_UNCONSTRAINEDSIZE == aContainingBlockWidth) {
if ((NS_UNCONSTRAINEDSIZE == aContainingBlockWidth) ||
((cbrs->mIsAutoWidthPctBase) &&
(nsLayoutAtoms::tableOuterFrame != frameType.get()) &&
(nsLayoutAtoms::tableFrame != frameType.get()))) {
// Interpret the width like 'auto'
widthUnit = eStyleUnit_Auto;
}
}
// if the cbrs is an auto width descendant (non table) from a table cell and
// our width may be determined using it, then propogate the flag.
if (cbrs->mIsAutoWidthPctBase) {
if ((eStyleUnit_Auto == widthUnit) ||
(eStyleUnit_Percent == widthUnit) ||
(eStyleUnit_Inherit == widthUnit)) {
if ((nsLayoutAtoms::tableOuterFrame != frameType.get()) &&
(nsLayoutAtoms::tableFrame != frameType.get())) {
mIsAutoWidthPctBase = PR_TRUE;
}
}
}
// Check for a percentage based height and a containing block height
// that depends on the content height
if (eStyleUnit_Percent == heightUnit) {
@ -1714,6 +1732,11 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
if (eStyleUnit_Inherit == widthUnit) {
mComputedWidth = aContainingBlockWidth;
} else if (eStyleUnit_Auto == widthUnit) {
if (NS_STYLE_DISPLAY_TABLE_CELL == mStyleDisplay->mDisplay) {
// set the flag to ignore mComputedWidth for percent calculations
// when the cell is a containing block.
mIsAutoWidthPctBase = PR_TRUE;
}
mComputedWidth = availableWidth;
if (mComputedWidth != NS_UNCONSTRAINEDSIZE) {

View File

@ -202,6 +202,12 @@ struct nsHTMLReflowState {
// set it. if false, the reflow sets alignCharOffset
PRPackedBool mUseAlignCharOffset;
// a table cell has a constrained mComputedWidth to accomodate its inner block.
// since it is treated like a containing block for percent calculations, this flag
// indicates not to use mComputedWidth for percent calculations if true.
// it also propogates into descendants whose width is percentage.
PRBool mIsAutoWidthPctBase;
// Cached pointers to the various style structs used during intialization
const nsStyleDisplay* mStyleDisplay;
const nsStylePosition* mStylePosition;

View File

@ -170,6 +170,7 @@ nsHTMLReflowState::Init(nsIPresContext* aPresContext,
mCompactMarginWidth = 0;
mAlignCharOffset = 0;
mUseAlignCharOffset = 0;
mIsAutoWidthPctBase = PR_FALSE;
frame->GetStyleData(eStyleStruct_Position,
(const nsStyleStruct*&)mStylePosition);
@ -1509,15 +1510,13 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
// the containingBlockHeight calcuation.
if (cbrs->parentReflowState) {
nsIFrame* f = cbrs->parentReflowState->frame;
nsIAtom* cbFrameType;
f->GetFrameType(&cbFrameType);
if (nsLayoutAtoms::scrollFrame == cbFrameType) {
nsCOMPtr<nsIAtom> fType;
f->GetFrameType(getter_AddRefs(fType));
if (nsLayoutAtoms::scrollFrame == fType.get()) {
// Use the scroll frame's computed height instead
aContainingBlockHeight =
((nsHTMLReflowState*)cbrs->parentReflowState)->mComputedHeight;
}
NS_IF_RELEASE(cbFrameType);
}
}
@ -1536,14 +1535,33 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
nsStyleUnit widthUnit = mStylePosition->mWidth.GetUnit();
nsStyleUnit heightUnit = mStylePosition->mHeight.GetUnit();
nsCOMPtr<nsIAtom> frameType;
frame->GetFrameType(getter_AddRefs(frameType));
// Check for a percentage based width and an unconstrained containing
// block width
if (eStyleUnit_Percent == widthUnit) {
if (NS_UNCONSTRAINEDSIZE == aContainingBlockWidth) {
if ((NS_UNCONSTRAINEDSIZE == aContainingBlockWidth) ||
((cbrs->mIsAutoWidthPctBase) &&
(nsLayoutAtoms::tableOuterFrame != frameType.get()) &&
(nsLayoutAtoms::tableFrame != frameType.get()))) {
// Interpret the width like 'auto'
widthUnit = eStyleUnit_Auto;
}
}
// if the cbrs is an auto width descendant (non table) from a table cell and
// our width may be determined using it, then propogate the flag.
if (cbrs->mIsAutoWidthPctBase) {
if ((eStyleUnit_Auto == widthUnit) ||
(eStyleUnit_Percent == widthUnit) ||
(eStyleUnit_Inherit == widthUnit)) {
if ((nsLayoutAtoms::tableOuterFrame != frameType.get()) &&
(nsLayoutAtoms::tableFrame != frameType.get())) {
mIsAutoWidthPctBase = PR_TRUE;
}
}
}
// Check for a percentage based height and a containing block height
// that depends on the content height
if (eStyleUnit_Percent == heightUnit) {
@ -1714,6 +1732,11 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
if (eStyleUnit_Inherit == widthUnit) {
mComputedWidth = aContainingBlockWidth;
} else if (eStyleUnit_Auto == widthUnit) {
if (NS_STYLE_DISPLAY_TABLE_CELL == mStyleDisplay->mDisplay) {
// set the flag to ignore mComputedWidth for percent calculations
// when the cell is a containing block.
mIsAutoWidthPctBase = PR_TRUE;
}
mComputedWidth = availableWidth;
if (mComputedWidth != NS_UNCONSTRAINEDSIZE) {

View File

@ -1186,6 +1186,9 @@ nscoord BasicTableLayoutStrategy::GetTableMinWidth() const
for (PRInt32 colX = 0; colX < numCols; colX++) {
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
minWidth += PR_MAX(colFrame->GetMinWidth(), colFrame->GetWidth(MIN_ADJ));
if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) {
minWidth += spacingX;
}
}
// if it is not a degenerate table, add the last spacing on the right
if (minWidth > 0) {
@ -1201,10 +1204,17 @@ nscoord BasicTableLayoutStrategy::GetTableMaxWidth() const
nscoord maxWidth = 0;
for (PRInt32 colX = 0; colX < numCols; colX++) {
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
nscoord max = PR_MAX(colFrame->GetDesWidth(), colFrame->GetFixWidth());
max = PR_MAX(max, colFrame->GetPctWidth());
max = PR_MAX(max, colFrame->GetWidth(MIN_PRO));
maxWidth += max;
nscoord width = colFrame->GetPctWidth();
if (width <= 0) {
width = colFrame->GetFixWidth();
if (width <= 0) {
width = colFrame->GetWidth(MIN_PRO);
if (width <= 0) {
width = colFrame->GetDesWidth();
}
}
}
maxWidth += width;
if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) {
maxWidth += spacingX;
}

View File

@ -164,7 +164,7 @@ file:///s|/mozilla/layout/html/tests/table/bugs/bug2997.html
file:///s|/mozilla/layout/html/tests/table/bugs/bug30273.html
file:///s|/mozilla/layout/html/tests/table/bugs/bug30332-1.html
file:///s|/mozilla/layout/html/tests/table/bugs/bug30332-2.html
file:///s|/mozilla/layout/html/tests/table/bugs/bug3037-1.html
#file:///s|/mozilla/layout/html/tests/table/bugs/bug3037-1.html
file:///s|/mozilla/layout/html/tests/table/bugs/bug3037-2.html
file:///s|/mozilla/layout/html/tests/table/bugs/bug30559.html
file:///s|/mozilla/layout/html/tests/table/bugs/bug30985.html

View File

@ -1186,6 +1186,9 @@ nscoord BasicTableLayoutStrategy::GetTableMinWidth() const
for (PRInt32 colX = 0; colX < numCols; colX++) {
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
minWidth += PR_MAX(colFrame->GetMinWidth(), colFrame->GetWidth(MIN_ADJ));
if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) {
minWidth += spacingX;
}
}
// if it is not a degenerate table, add the last spacing on the right
if (minWidth > 0) {
@ -1201,10 +1204,17 @@ nscoord BasicTableLayoutStrategy::GetTableMaxWidth() const
nscoord maxWidth = 0;
for (PRInt32 colX = 0; colX < numCols; colX++) {
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
nscoord max = PR_MAX(colFrame->GetDesWidth(), colFrame->GetFixWidth());
max = PR_MAX(max, colFrame->GetPctWidth());
max = PR_MAX(max, colFrame->GetWidth(MIN_PRO));
maxWidth += max;
nscoord width = colFrame->GetPctWidth();
if (width <= 0) {
width = colFrame->GetFixWidth();
if (width <= 0) {
width = colFrame->GetWidth(MIN_PRO);
if (width <= 0) {
width = colFrame->GetDesWidth();
}
}
}
maxWidth += width;
if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) {
maxWidth += spacingX;
}