diff --git a/layout/base/public/nsHTMLReflowState.h b/layout/base/public/nsHTMLReflowState.h
index 4fce25dc16fd..36e5d2585037 100644
--- a/layout/base/public/nsHTMLReflowState.h
+++ b/layout/base/public/nsHTMLReflowState.h
@@ -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;
diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp
index dd5d753cc638..b718325833b0 100644
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -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 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 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) {
diff --git a/layout/generic/nsHTMLReflowState.h b/layout/generic/nsHTMLReflowState.h
index 4fce25dc16fd..36e5d2585037 100644
--- a/layout/generic/nsHTMLReflowState.h
+++ b/layout/generic/nsHTMLReflowState.h
@@ -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;
diff --git a/layout/html/base/src/nsHTMLReflowState.cpp b/layout/html/base/src/nsHTMLReflowState.cpp
index dd5d753cc638..b718325833b0 100644
--- a/layout/html/base/src/nsHTMLReflowState.cpp
+++ b/layout/html/base/src/nsHTMLReflowState.cpp
@@ -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 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 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) {
diff --git a/layout/html/table/src/BasicTableLayoutStrategy.cpp b/layout/html/table/src/BasicTableLayoutStrategy.cpp
index 09e05353da4b..3666b4d35d43 100644
--- a/layout/html/table/src/BasicTableLayoutStrategy.cpp
+++ b/layout/html/table/src/BasicTableLayoutStrategy.cpp
@@ -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;
}
diff --git a/layout/html/tests/table/bugs/file_list.txt b/layout/html/tests/table/bugs/file_list.txt
index c44d79272762..f498f9d1ecd1 100644
--- a/layout/html/tests/table/bugs/file_list.txt
+++ b/layout/html/tests/table/bugs/file_list.txt
@@ -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
diff --git a/layout/tables/BasicTableLayoutStrategy.cpp b/layout/tables/BasicTableLayoutStrategy.cpp
index 09e05353da4b..3666b4d35d43 100644
--- a/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/layout/tables/BasicTableLayoutStrategy.cpp
@@ -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;
}